zhouhui.jiang

update 经销商

...@@ -14,7 +14,6 @@ import java.time.LocalDate; ...@@ -14,7 +14,6 @@ import java.time.LocalDate;
14 public class DealerAddReq { 14 public class DealerAddReq {
15 15
16 @NotBlank(message = "经销商编码不能为空") 16 @NotBlank(message = "经销商编码不能为空")
17 - @Pattern(regexp = "^[A-Z0-9]{6,20}$", message = "经销商编码格式不正确,应为6-20位大写字母和数字")
18 @Schema(description = "经销商编码", required = true) 17 @Schema(description = "经销商编码", required = true)
19 private String dealerCode; 18 private String dealerCode;
20 19
......
...@@ -18,7 +18,6 @@ public class DealerUpdateReq { ...@@ -18,7 +18,6 @@ public class DealerUpdateReq {
18 private Long dealerId; 18 private Long dealerId;
19 19
20 @NotBlank(message = "经销商编码不能为空") 20 @NotBlank(message = "经销商编码不能为空")
21 - @Pattern(regexp = "^[A-Z0-9]{6,20}$", message = "经销商编码格式不正确,应为6-20位大写字母和数字")
22 @Schema(description = "经销商编码", required = true) 21 @Schema(description = "经销商编码", required = true)
23 private String dealerCode; 22 private String dealerCode;
24 23
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
42 <if test="params.rebateEndDate != null and params.rebateEndDate != ''"> 42 <if test="params.rebateEndDate != null and params.rebateEndDate != ''">
43 AND rebate_date &lt;= #{params.rebateEndDate} 43 AND rebate_date &lt;= #{params.rebateEndDate}
44 </if> 44 </if>
45 - ORDER BY create_time DESC 45 + ORDER BY rebate_date DESC
46 </select> 46 </select>
47 47
48 <!-- 根据经销商编码统计返利总金额 --> 48 <!-- 根据经销商编码统计返利总金额 -->
......
...@@ -127,49 +127,49 @@ export interface ApiResponse<T = any> { ...@@ -127,49 +127,49 @@ export interface ApiResponse<T = any> {
127 // 经销商管理API 127 // 经销商管理API
128 export const dealerApi = { 128 export const dealerApi = {
129 // 分页查询经销商列表 129 // 分页查询经销商列表
130 - getDealerList: (params: DealerQueryReq) => { 130 + getDealerList: (params: DealerQueryReq): Promise<ApiResponse<PageData<DealerInfo>>> => {
131 return api.get<ApiResponse<PageData<DealerInfo>>>('/dealer/list', { params }) 131 return api.get<ApiResponse<PageData<DealerInfo>>>('/dealer/list', { params })
132 }, 132 },
133 133
134 // 获取经销商详情 134 // 获取经销商详情
135 - getDealerDetail: (dealerId: number) => { 135 + getDealerDetail: (dealerId: number): Promise<ApiResponse<DealerInfo>> => {
136 return api.get<ApiResponse<DealerInfo>>(`/dealer/${dealerId}`) 136 return api.get<ApiResponse<DealerInfo>>(`/dealer/${dealerId}`)
137 }, 137 },
138 138
139 // 新增经销商 139 // 新增经销商
140 - addDealer: (data: DealerAddReq) => { 140 + addDealer: (data: DealerAddReq): Promise<ApiResponse> => {
141 return api.post<ApiResponse>('/dealer', data) 141 return api.post<ApiResponse>('/dealer', data)
142 }, 142 },
143 143
144 // 修改经销商 144 // 修改经销商
145 - updateDealer: (data: DealerUpdateReq) => { 145 + updateDealer: (data: DealerUpdateReq): Promise<ApiResponse> => {
146 return api.post<ApiResponse>('/dealer/update', data) 146 return api.post<ApiResponse>('/dealer/update', data)
147 }, 147 },
148 148
149 // 删除经销商 149 // 删除经销商
150 - deleteDealer: (dealerId: number) => { 150 + deleteDealer: (dealerId: number): Promise<ApiResponse> => {
151 return api.delete<ApiResponse>(`/dealer/${dealerId}`) 151 return api.delete<ApiResponse>(`/dealer/${dealerId}`)
152 }, 152 },
153 153
154 // 批量删除经销商 154 // 批量删除经销商
155 - batchDeleteDealer: (dealerIds: number[]) => { 155 + batchDeleteDealer: (dealerIds: number[]): Promise<ApiResponse> => {
156 return api.delete<ApiResponse>('/dealer/batch', { data: dealerIds }) 156 return api.delete<ApiResponse>('/dealer/batch', { data: dealerIds })
157 }, 157 },
158 158
159 // 修改经销商合作状态 159 // 修改经销商合作状态
160 - updateCooperateStatus: (dealerId: number, cooperateStatus: number) => { 160 + updateCooperateStatus: (dealerId: number, cooperateStatus: number): Promise<ApiResponse> => {
161 return api.post<ApiResponse>(`/dealer/${dealerId}/cooperateStatus/${cooperateStatus}`) 161 return api.post<ApiResponse>(`/dealer/${dealerId}/cooperateStatus/${cooperateStatus}`)
162 }, 162 },
163 163
164 // 修改经销商资质审核状态 164 // 修改经销商资质审核状态
165 - updateAuditStatus: (dealerId: number, qualificationAuditStatus: number, auditOpinion?: string) => { 165 + updateAuditStatus: (dealerId: number, qualificationAuditStatus: number, auditOpinion?: string): Promise<ApiResponse> => {
166 return api.post<ApiResponse>(`/dealer/${dealerId}/auditStatus`, null, { 166 return api.post<ApiResponse>(`/dealer/${dealerId}/auditStatus`, null, {
167 params: { qualificationAuditStatus, auditOpinion } 167 params: { qualificationAuditStatus, auditOpinion }
168 }) 168 })
169 }, 169 },
170 170
171 // 获取所有经销商(用于下拉选择) 171 // 获取所有经销商(用于下拉选择)
172 - getAllDealers: () => { 172 + getAllDealers: (): Promise<ApiResponse<DealerInfo[]>> => {
173 return api.get<ApiResponse<DealerInfo[]>>('/dealer/all') 173 return api.get<ApiResponse<DealerInfo[]>>('/dealer/all')
174 } 174 }
175 } 175 }
......
1 import request from '@/utils/request' 1 import request from '@/utils/request'
2 2
3 +// API响应接口
4 +export interface ApiResponse<T = any> {
5 + code: number
6 + message: string
7 + data: T
8 +}
9 +
10 +// 分页数据接口
11 +export interface PageData<T> {
12 + records: T[]
13 + total: number
14 + pageNum: number
15 + pageSize: number
16 +}
17 +
3 // 返利台账明细类型定义 18 // 返利台账明细类型定义
4 export interface Rebate { 19 export interface Rebate {
5 rebateId?: number 20 rebateId?: number
...@@ -57,7 +72,7 @@ export interface RebateUpdateParams extends RebateAddParams { ...@@ -57,7 +72,7 @@ export interface RebateUpdateParams extends RebateAddParams {
57 } 72 }
58 73
59 // 分页查询返利列表 74 // 分页查询返利列表
60 -export const getRebatePage = (params: RebateSearchParams) => { 75 +export const getRebatePage = (params: RebateSearchParams): Promise<ApiResponse<PageData<Rebate>>> => {
61 return request({ 76 return request({
62 url: '/api/rebate/page', 77 url: '/api/rebate/page',
63 method: 'post', 78 method: 'post',
......
...@@ -84,7 +84,6 @@ ...@@ -84,7 +84,6 @@
84 <th>统一社会信用代码</th> 84 <th>统一社会信用代码</th>
85 <th>经销商等级</th> 85 <th>经销商等级</th>
86 <th>所在区域</th> 86 <th>所在区域</th>
87 - <th>合作起始日期</th>
88 <th>合作状态</th> 87 <th>合作状态</th>
89 <th>累计应返金额</th> 88 <th>累计应返金额</th>
90 <th>累计已返金额</th> 89 <th>累计已返金额</th>
...@@ -106,7 +105,6 @@ ...@@ -106,7 +105,6 @@
106 <td>{{ dealer.creditCode }}</td> 105 <td>{{ dealer.creditCode }}</td>
107 <td>{{ getDealerLevelText(dealer.dealerLevel) }}</td> 106 <td>{{ getDealerLevelText(dealer.dealerLevel) }}</td>
108 <td>{{ dealer.region }}</td> 107 <td>{{ dealer.region }}</td>
109 - <td>{{ dealer.cooperateStartDate }}</td>
110 <td> 108 <td>
111 <span :class="getCooperateStatusClass(dealer.cooperateStatus)"> 109 <span :class="getCooperateStatusClass(dealer.cooperateStatus)">
112 {{ getCooperateStatusText(dealer.cooperateStatus) }} 110 {{ getCooperateStatusText(dealer.cooperateStatus) }}
...@@ -119,6 +117,7 @@ ...@@ -119,6 +117,7 @@
119 <button @click="handleEdit(dealer)" class="table-btn edit">✏️ 编辑</button> 117 <button @click="handleEdit(dealer)" class="table-btn edit">✏️ 编辑</button>
120 <button @click="handleDelete(dealer)" class="table-btn delete">🗑️ 删除</button> 118 <button @click="handleDelete(dealer)" class="table-btn delete">🗑️ 删除</button>
121 <button @click="handleStatusChange(dealer)" class="table-btn status">🔄 状态</button> 119 <button @click="handleStatusChange(dealer)" class="table-btn status">🔄 状态</button>
120 + <button @click="handleRebateDetail(dealer)" class="table-btn rebate">💰 返利明细</button>
122 </td> 121 </td>
123 </tr> 122 </tr>
124 </tbody> 123 </tbody>
...@@ -185,9 +184,7 @@ ...@@ -185,9 +184,7 @@
185 <input 184 <input
186 v-model="formData.dealerCode" 185 v-model="formData.dealerCode"
187 class="form-input" 186 class="form-input"
188 - placeholder="请输入经销商编码(6-20位大写字母和数字)" 187 + placeholder="请输入经销商编码"
189 - pattern="^[A-Z0-9]{6,20}$"
190 - title="经销商编码应为6-20位大写字母和数字"
191 required 188 required
192 /> 189 />
193 </div> 190 </div>
...@@ -277,7 +274,7 @@ ...@@ -277,7 +274,7 @@
277 </div> 274 </div>
278 </div> 275 </div>
279 <div class="form-row"> 276 <div class="form-row">
280 - <div class="form-item"> 277 + <div class="form-item full-width">
281 <label>合作协议URL:</label> 278 <label>合作协议URL:</label>
282 <input 279 <input
283 v-model="formData.cooperationAgreementUrl" 280 v-model="formData.cooperationAgreementUrl"
...@@ -285,22 +282,14 @@ ...@@ -285,22 +282,14 @@
285 placeholder="请输入合作协议URL" 282 placeholder="请输入合作协议URL"
286 /> 283 />
287 </div> 284 </div>
288 - <div class="form-item">
289 - <label>审核意见:</label>
290 - <input
291 - v-model="formData.auditOpinion"
292 - class="form-input"
293 - placeholder="请输入审核意见"
294 - />
295 - </div>
296 </div> 285 </div>
297 <div class="form-row"> 286 <div class="form-row">
298 <div class="form-item full-width"> 287 <div class="form-item full-width">
299 - <label>备注:</label> 288 + <label>审核意见:</label>
300 <textarea 289 <textarea
301 - v-model="formData.remark" 290 + v-model="formData.auditOpinion"
302 class="form-textarea" 291 class="form-textarea"
303 - placeholder="请输入备注" 292 + placeholder="请输入审核意见"
304 rows="3" 293 rows="3"
305 ></textarea> 294 ></textarea>
306 </div> 295 </div>
...@@ -346,12 +335,103 @@ ...@@ -346,12 +335,103 @@
346 </div> 335 </div>
347 </div> 336 </div>
348 337
338 + <!-- 返利明细对话框 -->
339 + <div v-if="showRebateDialog" class="dialog-overlay" @click="handleRebateDialogClose">
340 + <div class="dialog-content rebate-dialog" @click.stop>
341 + <div class="dialog-header">
342 + <h3>返利明细 - {{ currentDealer.dealerName }} ({{ currentDealer.dealerCode }})</h3>
343 + <button @click="handleRebateDialogClose" class="dialog-close">×</button>
344 + </div>
345 + <div class="dialog-body">
346 + <div v-if="rebateLoading" class="loading-overlay">
347 + <div class="loading-spinner">加载中...</div>
348 + </div>
349 + <div v-else>
350 + <table class="rebate-table">
351 + <thead>
352 + <tr>
353 + <th>返利编号</th>
354 + <th>订单编号</th>
355 + <th>经销商代码</th>
356 + <th>产品编码</th>
357 + <th>返利金额</th>
358 + <th>返利日期</th>
359 + <th>操作类型</th>
360 + <th>计算状态</th>
361 + </tr>
362 + </thead>
363 + <tbody>
364 + <tr v-for="rebate in rebateList" :key="rebate.rebateId">
365 + <td>{{ rebate.rebateNo }}</td>
366 + <td>{{ rebate.orderNo }}</td>
367 + <td>{{ rebate.dealerCode }}</td>
368 + <td>{{ rebate.productCode }}</td>
369 + <td class="amount-cell">{{ formatAmount(rebate.rebateAmount) }}</td>
370 + <td>{{ rebate.rebateDate }}</td>
371 + <td>
372 + <span :class="getOperateTypeClass(rebate.operateType || 0)">
373 + {{ getOperateTypeText(rebate.operateType || 0) }}
374 + </span>
375 + </td>
376 + <td>
377 + <span :class="getCalcFlagClass(rebate.calcFlag || 0)">
378 + {{ getCalcFlagText(rebate.calcFlag || 0) }}
379 + </span>
380 + </td>
381 + </tr>
382 + <tr v-if="rebateList.length === 0">
383 + <td colspan="8" class="no-data">暂无返利明细数据</td>
384 + </tr>
385 + </tbody>
386 + </table>
387 +
388 + <!-- 返利明细分页 -->
389 + <div class="rebate-pagination">
390 + <div class="pagination-info">
391 + 共 {{ rebatePagination.total || 0 }} 条记录,第 {{ rebatePagination.pageNum || 1 }} / {{ rebateTotalPages || 1 }} 页
392 + </div>
393 + <div class="pagination-container">
394 + <button
395 + @click="handleRebatePageChange(rebatePagination.pageNum - 1)"
396 + :disabled="rebatePagination.pageNum <= 1"
397 + class="pagination-btn prev-btn"
398 + >
399 + 上一页
400 + </button>
401 + <div class="pagination-pages">
402 + <button
403 + v-for="page in getRebatePageNumbers()"
404 + :key="page"
405 + @click="handleRebatePageChange(page)"
406 + :class="['page-number', { active: page === rebatePagination.pageNum }]"
407 + >
408 + {{ page }}
409 + </button>
410 + </div>
411 + <button
412 + @click="handleRebatePageChange(rebatePagination.pageNum + 1)"
413 + :disabled="rebatePagination.pageNum >= rebateTotalPages"
414 + class="pagination-btn next-btn"
415 + >
416 + 下一页
417 + </button>
418 + </div>
419 + </div>
420 + </div>
421 + </div>
422 + <div class="dialog-footer">
423 + <button @click="handleRebateDialogClose" class="dialog-btn confirm">关闭</button>
424 + </div>
425 + </div>
426 + </div>
427 +
349 </div> 428 </div>
350 </template> 429 </template>
351 430
352 <script setup lang="ts"> 431 <script setup lang="ts">
353 import { ref, reactive, computed, onMounted } from 'vue' 432 import { ref, reactive, computed, onMounted } from 'vue'
354 import { dealerApi, type DealerInfo, type DealerQueryReq, type DealerAddReq, type DealerUpdateReq } from '../../api/dealer' 433 import { dealerApi, type DealerInfo, type DealerQueryReq, type DealerAddReq, type DealerUpdateReq } from '../../api/dealer'
434 +import { getRebatePage, type Rebate, type RebateSearchParams } from '../../api/rebate'
355 435
356 // 响应式数据 436 // 响应式数据
357 const loading = ref(false) 437 const loading = ref(false)
...@@ -363,6 +443,16 @@ const showStatusDialog = ref(false) ...@@ -363,6 +443,16 @@ const showStatusDialog = ref(false)
363 const currentDealer = ref<DealerInfo>({} as DealerInfo) 443 const currentDealer = ref<DealerInfo>({} as DealerInfo)
364 const newCooperateStatus = ref<number>(1) 444 const newCooperateStatus = ref<number>(1)
365 445
446 +// 返利明细相关数据
447 +const showRebateDialog = ref(false)
448 +const rebateLoading = ref(false)
449 +const rebateList = ref<Rebate[]>([])
450 +const rebatePagination = reactive({
451 + total: 0,
452 + pageNum: 1,
453 + pageSize: 10
454 +})
455 +
366 // 搜索参数 456 // 搜索参数
367 const searchParams = reactive<DealerQueryReq>({ 457 const searchParams = reactive<DealerQueryReq>({
368 dealerCode: '', 458 dealerCode: '',
...@@ -393,6 +483,12 @@ const totalPages = computed(() => { ...@@ -393,6 +483,12 @@ const totalPages = computed(() => {
393 return Math.ceil(pagination.total / pagination.pageSize) || 1 483 return Math.ceil(pagination.total / pagination.pageSize) || 1
394 }) 484 })
395 485
486 +// 返利明细分页计算属性
487 +const rebateTotalPages = computed(() => {
488 + if (rebatePagination.pageSize <= 0) return 1
489 + return Math.ceil(rebatePagination.total / rebatePagination.pageSize) || 1
490 +})
491 +
396 // 表单数据 492 // 表单数据
397 const formData = reactive<DealerAddReq & { dealerId?: number }>({ 493 const formData = reactive<DealerAddReq & { dealerId?: number }>({
398 dealerCode: '', 494 dealerCode: '',
...@@ -455,6 +551,42 @@ const formatAmount = (amount: number | undefined) => { ...@@ -455,6 +551,42 @@ const formatAmount = (amount: number | undefined) => {
455 return `¥${amount.toFixed(2)}` 551 return `¥${amount.toFixed(2)}`
456 } 552 }
457 553
554 +// 获取操作类型文本
555 +const getOperateTypeText = (type: number) => {
556 + const typeMap: { [key: number]: string } = {
557 + 1: '新增',
558 + 2: '扣减'
559 + }
560 + return typeMap[type] || '未知'
561 +}
562 +
563 +// 获取操作类型样式
564 +const getOperateTypeClass = (type: number) => {
565 + const classMap: { [key: number]: string } = {
566 + 1: 'operate-add',
567 + 2: 'operate-subtract'
568 + }
569 + return classMap[type] || ''
570 +}
571 +
572 +// 获取计算状态文本
573 +const getCalcFlagText = (flag: number) => {
574 + const flagMap: { [key: number]: string } = {
575 + 0: '未计算',
576 + 1: '已计算'
577 + }
578 + return flagMap[flag] || '未知'
579 +}
580 +
581 +// 获取计算状态样式
582 +const getCalcFlagClass = (flag: number) => {
583 + const classMap: { [key: number]: string } = {
584 + 0: 'calc-pending',
585 + 1: 'calc-completed'
586 + }
587 + return classMap[flag] || ''
588 +}
589 +
458 590
459 // 获取分页页码数组 591 // 获取分页页码数组
460 const getPageNumbers = () => { 592 const getPageNumbers = () => {
...@@ -471,11 +603,26 @@ const getPageNumbers = () => { ...@@ -471,11 +603,26 @@ const getPageNumbers = () => {
471 return pages 603 return pages
472 } 604 }
473 605
606 +// 获取返利明细分页页码数组
607 +const getRebatePageNumbers = () => {
608 + const pages = []
609 + const totalPagesValue = rebateTotalPages.value
610 + if (totalPagesValue <= 0) return []
611 +
612 + const start = Math.max(1, rebatePagination.pageNum - 2)
613 + const end = Math.min(totalPagesValue, start + 4)
614 +
615 + for (let i = start; i <= end; i++) {
616 + pages.push(i)
617 + }
618 + return pages
619 +}
620 +
474 // 获取经销商列表 621 // 获取经销商列表
475 const fetchDealers = async () => { 622 const fetchDealers = async () => {
476 try { 623 try {
477 loading.value = true 624 loading.value = true
478 - const response = await dealerApi.getDealerList(searchParams) 625 + const response = await dealerApi.getDealerList(searchParams) as any
479 if (response.code === 200) { 626 if (response.code === 200) {
480 dealerList.value = response.data.records 627 dealerList.value = response.data.records
481 pagination.total = response.data.total 628 pagination.total = response.data.total
...@@ -531,30 +678,47 @@ const handleAdd = () => { ...@@ -531,30 +678,47 @@ const handleAdd = () => {
531 } 678 }
532 679
533 // 编辑 680 // 编辑
534 -const handleEdit = (dealer: DealerInfo) => { 681 +const handleEdit = async (dealer: DealerInfo) => {
535 - isEdit.value = true 682 + try {
536 - Object.assign(formData, { 683 + isEdit.value = true
537 - dealerId: dealer.dealerId, 684 + showDialog.value = true
538 - dealerCode: dealer.dealerCode, 685 +
539 - dealerName: dealer.dealerName, 686 + // 获取最新的经销商详情
540 - creditCode: dealer.creditCode, 687 + const response = await dealerApi.getDealerDetail(dealer.dealerId) as any
541 - dealerLevel: dealer.dealerLevel, 688 + if (response.code === 200) {
542 - region: dealer.region, 689 + const dealerDetail = response.data
543 - contactPerson: dealer.contactPerson, 690 + Object.assign(formData, {
544 - contactPhone: dealer.contactPhone, 691 + dealerId: dealerDetail.dealerId,
545 - cooperateStartDate: dealer.cooperateStartDate, 692 + dealerCode: dealerDetail.dealerCode,
546 - cooperateStatus: dealer.cooperateStatus, 693 + dealerName: dealerDetail.dealerName,
547 - businessLicenseUrl: dealer.businessLicenseUrl, 694 + creditCode: dealerDetail.creditCode,
548 - cooperationAgreementUrl: dealer.cooperationAgreementUrl 695 + dealerLevel: dealerDetail.dealerLevel,
549 - }) 696 + region: dealerDetail.region,
550 - showDialog.value = true 697 + contactPerson: dealerDetail.contactPerson,
698 + contactPhone: dealerDetail.contactPhone,
699 + cooperateStartDate: dealerDetail.cooperateStartDate,
700 + cooperateStatus: dealerDetail.cooperateStatus,
701 + businessLicenseUrl: dealerDetail.businessLicenseUrl,
702 + cooperationAgreementUrl: dealerDetail.cooperationAgreementUrl,
703 + qualificationAuditStatus: dealerDetail.qualificationAuditStatus,
704 + auditOpinion: dealerDetail.auditOpinion
705 + })
706 + } else {
707 + alert('获取经销商详情失败')
708 + showDialog.value = false
709 + }
710 + } catch (error: any) {
711 + console.error('获取经销商详情失败:', error)
712 + alert('获取经销商详情失败')
713 + showDialog.value = false
714 + }
551 } 715 }
552 716
553 // 删除 717 // 删除
554 const handleDelete = async (dealer: DealerInfo) => { 718 const handleDelete = async (dealer: DealerInfo) => {
555 if (confirm(`确定要删除经销商"${dealer.dealerName}"吗?`)) { 719 if (confirm(`确定要删除经销商"${dealer.dealerName}"吗?`)) {
556 try { 720 try {
557 - const response = await dealerApi.deleteDealer(dealer.dealerId) 721 + const response = await dealerApi.deleteDealer(dealer.dealerId) as any
558 if (response.code === 200) { 722 if (response.code === 200) {
559 alert('删除成功') 723 alert('删除成功')
560 fetchDealers() 724 fetchDealers()
...@@ -594,7 +758,7 @@ const handleBatchDelete = async () => { ...@@ -594,7 +758,7 @@ const handleBatchDelete = async () => {
594 758
595 if (confirm(`确定要删除选中的 ${selectedDealers.value.length} 个经销商吗?`)) { 759 if (confirm(`确定要删除选中的 ${selectedDealers.value.length} 个经销商吗?`)) {
596 try { 760 try {
597 - const response = await dealerApi.batchDeleteDealer(selectedDealers.value) 761 + const response = await dealerApi.batchDeleteDealer(selectedDealers.value) as any
598 if (response.code === 200) { 762 if (response.code === 200) {
599 alert('批量删除成功') 763 alert('批量删除成功')
600 selectedDealers.value = [] 764 selectedDealers.value = []
...@@ -637,14 +801,7 @@ const handleStatusChange = (dealer: DealerInfo) => { ...@@ -637,14 +801,7 @@ const handleStatusChange = (dealer: DealerInfo) => {
637 // 提交表单 801 // 提交表单
638 const handleSubmit = async () => { 802 const handleSubmit = async () => {
639 try { 803 try {
640 - // 前端验证经销商编码格式 804 + let response: any
641 - const dealerCodePattern = /^[A-Z0-9]{6,20}$/
642 - if (!dealerCodePattern.test(formData.dealerCode)) {
643 - alert('经销商编码格式不正确,应为6-20位大写字母和数字')
644 - return
645 - }
646 -
647 - let response
648 if (isEdit.value) { 805 if (isEdit.value) {
649 response = await dealerApi.updateDealer(formData as DealerUpdateReq) 806 response = await dealerApi.updateDealer(formData as DealerUpdateReq)
650 } else { 807 } else {
...@@ -695,7 +852,7 @@ const handleSubmit = async () => { ...@@ -695,7 +852,7 @@ const handleSubmit = async () => {
695 // 状态提交 852 // 状态提交
696 const handleStatusSubmit = async () => { 853 const handleStatusSubmit = async () => {
697 try { 854 try {
698 - const response = await dealerApi.updateCooperateStatus(currentDealer.value.dealerId, newCooperateStatus.value) 855 + const response = await dealerApi.updateCooperateStatus(currentDealer.value.dealerId, newCooperateStatus.value) as any
699 if (response.code === 200) { 856 if (response.code === 200) {
700 alert('状态修改成功') 857 alert('状态修改成功')
701 showStatusDialog.value = false 858 showStatusDialog.value = false
...@@ -726,6 +883,52 @@ const handleStatusSubmit = async () => { ...@@ -726,6 +883,52 @@ const handleStatusSubmit = async () => {
726 } 883 }
727 } 884 }
728 885
886 +// 返利明细相关方法
887 +const handleRebateDetail = (dealer: DealerInfo) => {
888 + currentDealer.value = dealer
889 + rebatePagination.pageNum = 1
890 + showRebateDialog.value = true
891 + fetchRebateList()
892 +}
893 +
894 +const fetchRebateList = async () => {
895 + try {
896 + rebateLoading.value = true
897 + const params: RebateSearchParams = {
898 + dealerCode: currentDealer.value.dealerCode,
899 + pageNum: rebatePagination.pageNum,
900 + pageSize: rebatePagination.pageSize
901 + }
902 +
903 + const response = await getRebatePage(params) as any
904 + // @/utils/request 的响应拦截器已经返回了 data 部分
905 + rebateList.value = response.records
906 + rebatePagination.total = response.total
907 + rebatePagination.pageNum = response.current
908 + rebatePagination.pageSize = response.size
909 + } catch (error: any) {
910 + console.error('获取返利明细失败:', error)
911 + alert('获取返利明细失败')
912 + } finally {
913 + rebateLoading.value = false
914 + }
915 +}
916 +
917 +const handleRebatePageChange = (page: number) => {
918 + const totalPagesValue = rebateTotalPages.value
919 + if (page >= 1 && page <= totalPagesValue && totalPagesValue > 0) {
920 + rebatePagination.pageNum = page
921 + fetchRebateList()
922 + }
923 +}
924 +
925 +const handleRebateDialogClose = () => {
926 + showRebateDialog.value = false
927 + rebateList.value = []
928 + rebatePagination.total = 0
929 + rebatePagination.pageNum = 1
930 +}
931 +
729 932
730 // 全选 933 // 全选
731 const handleSelectAll = () => { 934 const handleSelectAll = () => {
...@@ -743,8 +946,7 @@ const handlePageChange = (page: number) => { ...@@ -743,8 +946,7 @@ const handlePageChange = (page: number) => {
743 } 946 }
744 947
745 const handlePageSizeChange = () => { 948 const handlePageSizeChange = () => {
746 - pagination.pageSize = pageSize.value 949 + searchParams.pageSize = pagination.pageSize
747 - searchParams.pageSize = pageSize.value
748 pagination.pageNum = 1 950 pagination.pageNum = 1
749 searchParams.pageNum = 1 951 searchParams.pageNum = 1
750 fetchDealers() 952 fetchDealers()
...@@ -1301,4 +1503,106 @@ onMounted(() => { ...@@ -1301,4 +1503,106 @@ onMounted(() => {
1301 color: #1890ff; 1503 color: #1890ff;
1302 font-family: 'Courier New', monospace; 1504 font-family: 'Courier New', monospace;
1303 } 1505 }
1506 +
1507 +/* 返利明细相关样式 */
1508 +.table-btn.rebate {
1509 + background: linear-gradient(135deg, #ffd700, #ffed4e);
1510 + color: #333;
1511 + border: 1px solid #ffd700;
1512 +}
1513 +
1514 +.table-btn.rebate:hover {
1515 + background: linear-gradient(135deg, #ffed4e, #ffd700);
1516 + transform: translateY(-1px);
1517 + box-shadow: 0 4px 8px rgba(255, 215, 0, 0.3);
1518 +}
1519 +
1520 +/* 返利明细对话框样式 */
1521 +.rebate-dialog {
1522 + max-width: 1200px;
1523 + width: 90%;
1524 + max-height: 80vh;
1525 +}
1526 +
1527 +.rebate-table {
1528 + width: 100%;
1529 + border-collapse: collapse;
1530 + margin-bottom: 20px;
1531 + font-size: 14px;
1532 +}
1533 +
1534 +.rebate-table th,
1535 +.rebate-table td {
1536 + padding: 12px 8px;
1537 + text-align: left;
1538 + border-bottom: 1px solid #eee;
1539 +}
1540 +
1541 +.rebate-table th {
1542 + background: #f8f9fa;
1543 + font-weight: 600;
1544 + color: #333;
1545 + position: sticky;
1546 + top: 0;
1547 + z-index: 10;
1548 +}
1549 +
1550 +.rebate-table tbody tr:hover {
1551 + background: #f5f7fa;
1552 +}
1553 +
1554 +.rebate-table .no-data {
1555 + text-align: center;
1556 + color: #999;
1557 + font-style: italic;
1558 + padding: 40px;
1559 +}
1560 +
1561 +/* 返利明细分页样式 */
1562 +.rebate-pagination {
1563 + display: flex;
1564 + justify-content: space-between;
1565 + align-items: center;
1566 + margin-top: 20px;
1567 + padding: 15px 0;
1568 + border-top: 1px solid #eee;
1569 +}
1570 +
1571 +/* 操作类型样式 */
1572 +.operate-add {
1573 + color: #67c23a;
1574 + font-weight: 500;
1575 + background: #f0f9ff;
1576 + padding: 2px 8px;
1577 + border-radius: 4px;
1578 + font-size: 12px;
1579 +}
1580 +
1581 +.operate-subtract {
1582 + color: #f56c6c;
1583 + font-weight: 500;
1584 + background: #fef0f0;
1585 + padding: 2px 8px;
1586 + border-radius: 4px;
1587 + font-size: 12px;
1588 +}
1589 +
1590 +/* 计算状态样式 */
1591 +.calc-pending {
1592 + color: #e6a23c;
1593 + font-weight: 500;
1594 + background: #fdf6ec;
1595 + padding: 2px 8px;
1596 + border-radius: 4px;
1597 + font-size: 12px;
1598 +}
1599 +
1600 +.calc-completed {
1601 + color: #67c23a;
1602 + font-weight: 500;
1603 + background: #f0f9ff;
1604 + padding: 2px 8px;
1605 + border-radius: 4px;
1606 + font-size: 12px;
1607 +}
1304 </style> 1608 </style>
...\ No newline at end of file ...\ No newline at end of file
......