diff --git a/src/api/modules/card.ts b/src/api/modules/card.ts index a274863..241b707 100644 --- a/src/api/modules/card.ts +++ b/src/api/modules/card.ts @@ -19,7 +19,9 @@ import type { BaseResponse, PaginationResponse, ListResponse, - GatewayRealnameLinkResponse + GatewayRealnameLinkResponse, + ImportIotCardRequest, + ImportIotCardResponse } from '@/types/api' export class CardService extends BaseService { @@ -286,15 +288,8 @@ export class CardService extends BaseService { * 批量导入ICCID(新版:使用 JSON 格式) * @param data 导入请求参数 */ - static importIotCards(data: { - carrier_id: number - file_key: string - batch_no?: string - }): Promise> { - return this.post>( - '/api/admin/iot-cards/import', - data - ) + static importIotCards(data: ImportIotCardRequest): Promise> { + return this.post>('/api/admin/iot-cards/import', data) } /** diff --git a/src/api/modules/commission.ts b/src/api/modules/commission.ts index c53a791..61df223 100644 --- a/src/api/modules/commission.ts +++ b/src/api/modules/commission.ts @@ -93,82 +93,6 @@ export class CommissionService extends BaseService { ) } - // ==================== 我的佣金(已废弃,仅保留用于向后兼容) ==================== - - /** - * @deprecated 使用 getShopCommissionRecords 代替 - * 获取我的佣金明细 - * GET /api/admin/my/commission-records - */ - static getMyCommissionRecords( - params?: CommissionRecordQueryParams - ): Promise> { - return this.get>( - '/api/admin/my/commission-records', - params - ) - } - - /** - * @deprecated 使用 getShopFundSummary 代替 - * 获取我的佣金概览 - * GET /api/admin/my/commission-summary - */ - static getMyCommissionSummary(): Promise> { - return this.get>('/api/admin/my/commission-summary') - } - - /** - * @deprecated 使用 getShopWithdrawalRequests 代替 - * 获取我的提现记录 - * GET /api/admin/my/withdrawal-requests - */ - static getMyWithdrawalRequests( - params?: WithdrawalRequestQueryParams - ): Promise> { - return this.get>( - '/api/admin/my/withdrawal-requests', - params - ) - } - - /** - * @deprecated 使用 submitShopWithdrawalRequest 代替 - * 发起提现申请 - * POST /api/admin/my/withdrawal-requests - */ - static submitWithdrawalRequest(params: SubmitWithdrawalParams): Promise { - return this.post('/api/admin/my/withdrawal-requests', params) - } - - /** - * @deprecated 使用 getShopCommissionStats 代替 - * 获取我的佣金统计 - * GET /api/admin/my/commission-stats - */ - static getMyCommissionStats( - params?: ShopCommissionStatsQueryParams - ): Promise> { - return this.get>( - '/api/admin/my/commission-stats', - params - ) - } - - /** - * @deprecated 使用 getShopDailyCommissionStats 代替 - * 获取我的每日佣金统计 - * GET /api/admin/my/commission-daily-stats - */ - static getMyDailyCommissionStats( - params?: DailyCommissionStatsQueryParams - ): Promise> { - return this.get>( - '/api/admin/my/commission-daily-stats', - params - ) - } - // ==================== 代理商佣金管理 ==================== /** @@ -212,17 +136,6 @@ export class CommissionService extends BaseService { ) } - /** - * @deprecated 使用 getShopFundSummary 代替 - * 获取代理商佣金汇总列表 - * GET /api/admin/shops/commission-summary - */ - static getShopCommissionSummary( - params?: ShopFundSummaryQueryParams - ): Promise> { - return this.getShopFundSummary(params) - } - /** * 获取代理商佣金统计 * GET /api/admin/shops/{shop_id}/commission-stats diff --git a/src/types/api/card.ts b/src/types/api/card.ts index db7c530..7ed4c09 100644 --- a/src/types/api/card.ts +++ b/src/types/api/card.ts @@ -42,6 +42,12 @@ export enum CardType { FLOW = 'flow' // 流量卡 } +// 卡业务类型 +export enum CardCategory { + NORMAL = 'normal', // 普通卡 + INDUSTRY = 'industry' // 行业卡 +} + // 号卡商品实体 export interface SimCardProduct { id: string | number @@ -107,6 +113,21 @@ export interface CardQueryParams extends PaginationParams { importTimeRange?: [string, string] } +// IoT 卡导入请求 +export interface ImportIotCardRequest { + carrier_id: number // 运营商ID + file_key: string // 对象存储文件路径 + batch_no?: string // 批次号 + card_category?: CardCategory // 卡业务类型(新增,可选,默认 normal) +} + +// IoT 卡导入响应 +export interface ImportIotCardResponse { + task_id: number // 导入任务ID + task_no: string // 任务编号 + message: string // 提示信息 +} + // 网卡导入批次信息 export interface CardImportBatch extends ImportTask { importBatch: string // 导入批次号 @@ -118,6 +139,7 @@ export interface CardImportBatch extends ImportTask { cardCompanyName?: string operator: Operator cardType: CardType + cardCategory?: CardCategory // 卡业务类型(新增) operatorUser?: string // 操作人 } diff --git a/src/types/api/commission.ts b/src/types/api/commission.ts index a462736..482dfbc 100644 --- a/src/types/api/commission.ts +++ b/src/types/api/commission.ts @@ -151,6 +151,7 @@ export interface CommissionRecordQueryParams extends PaginationParams { * 我的佣金概览 */ export interface MyCommissionSummary { + main_balance: number // 预充值余额(分) total_commission: number // 总佣金(分) available_commission: number // 可提现佣金(分) frozen_commission: number // 冻结中佣金(分) diff --git a/src/types/api/order.ts b/src/types/api/order.ts index d90f1a0..039d237 100644 --- a/src/types/api/order.ts +++ b/src/types/api/order.ts @@ -92,7 +92,7 @@ export interface CreateOrderRequest { iot_card_id?: number | null // IoT卡ID device_id?: number | null // 设备ID identifier?: string // 资产标识符(ICCID 或 VirtualNo) - package_id: number // 套餐ID(单选) + package_ids: number[] // 套餐ID列表(前端限制单选,后端支持1-10个) payment_method: OrderPaymentMethod // 支付方式 payment_voucher_key?: string // 线下支付凭证(仅 offline 必填) } diff --git a/src/views/asset-management/asset-information/index.vue b/src/views/asset-management/asset-information/index.vue index be015ca..0b5c13d 100644 --- a/src/views/asset-management/asset-information/index.vue +++ b/src/views/asset-management/asset-information/index.vue @@ -1498,7 +1498,7 @@ const rechargeLoading = ref(false) const rechargeFormRef = ref() const rechargeForm = reactive({ - package_id: 0, + package_id: undefined as number | undefined, // 前端使用单选 payment_method: 'wallet' as 'wallet' | 'offline' }) const rechargeRules: FormRules = { @@ -2658,14 +2658,20 @@ if (valid) { rechargeLoading.value = true try { + // 验证必填字段 + if (!rechargeForm.package_id) { + ElMessage.error('请选择套餐') + return + } + // 获取资产标识符 const identifier = cardInfo.value.asset_type === 'card' ? cardInfo.value.iccid : cardInfo.value.virtual_no - // 创建订单 + // 创建订单(后端接收数组,前端单选转为单元素数组) const data: CreateOrderRequest = { identifier, - package_id: rechargeForm.package_id, + package_ids: [rechargeForm.package_id], payment_method: rechargeForm.payment_method } @@ -2701,7 +2707,7 @@ // 关闭充值对话框 const handleRechargeDialogClosed = () => { rechargeFormRef.value?.resetFields() - rechargeForm.package_id = 0 + rechargeForm.package_id = undefined rechargeForm.payment_method = 'wallet' packageOptions.value = [] } diff --git a/src/views/asset-management/task-management/device-task/index.vue b/src/views/asset-management/task-management/device-task/index.vue index bf65c43..52c4150 100644 --- a/src/views/asset-management/task-management/device-task/index.vue +++ b/src/views/asset-management/task-management/device-task/index.vue @@ -60,13 +60,10 @@

1. 请先下载 Excel 模板文件,按照模板格式填写设备信息

2. 仅支持 Excel 格式(.xlsx),单次最多导入 1000 条

3. 列格式请设置为文本格式,避免长数字被转为科学计数法

+

4. 重要:列顺序固定,不可调整。系统按位置读取,不识别列名

+

5. 必填列:虚拟号(第1列)

4. - 必填列:virtual_no(虚拟号)、device_name(设备名称)、device_model(设备型号)、device_type(设备类型)、imei(设备IMEI号)

-

5. 可选列:manufacturer(制造商)、max_sim_slots(最大插槽数,默认4)、iccid_1 ~ - iccid_4(绑定的卡ICCID)

6. 可选列:设备名称、设备型号、设备类型、IMEI、制造商、最大SIM槽数(默认4,有效范围1-4)、卡1~卡4 ICCID

@@ -89,7 +86,7 @@
将 Excel 文件拖到此处,或点击选择
@@ -411,33 +408,33 @@ // 动态导入 xlsx 库 const XLSX = await import('xlsx') - // 创建示例数据 + // 创建示例数据(按固定列顺序) const templateData = [ { - virtual_no: '862639070731999', - device_name: '智能水表01', - device_model: 'WM-2000', - device_type: '智能水表', - imei: '860123456789012', - manufacturer: '华为', - max_sim_slots: 4, - iccid_1: '89860123456789012345', - iccid_2: '', - iccid_3: '', - iccid_4: '' + 虚拟号: '862639070731999', + 设备名称: '智能水表01', + 设备型号: 'WM-2000', + 设备类型: '智能水表', + IMEI: '860123456789012', + 制造商: '华为', + 最大SIM槽数: 4, + '卡1 ICCID': '89860123456789012345', + '卡2 ICCID': '', + '卡3 ICCID': '', + '卡4 ICCID': '' }, { - virtual_no: '862639070750932', - device_name: 'GPS定位器01', - device_model: 'GPS-3000', - device_type: '定位设备', - imei: '860123456789013', - manufacturer: '小米', - max_sim_slots: 2, - iccid_1: '89860123456789012346', - iccid_2: '89860123456789012347', - iccid_3: '', - iccid_4: '' + 虚拟号: '862639070750932', + 设备名称: 'GPS定位器01', + 设备型号: 'GPS-3000', + 设备类型: '定位设备', + IMEI: '860123456789013', + 制造商: '小米', + 最大SIM槽数: 2, + '卡1 ICCID': '89860123456789012346', + '卡2 ICCID': '89860123456789012347', + '卡3 ICCID': '', + '卡4 ICCID': '' } ] @@ -447,17 +444,17 @@ // 设置列宽 ws['!cols'] = [ - { wch: 20 }, // virtual_no - { wch: 20 }, // device_name - { wch: 15 }, // device_model - { wch: 15 }, // device_type - { wch: 18 }, // imei - { wch: 15 }, // manufacturer - { wch: 15 }, // max_sim_slots - { wch: 22 }, // iccid_1 - { wch: 22 }, // iccid_2 - { wch: 22 }, // iccid_3 - { wch: 22 } // iccid_4 + { wch: 20 }, // 虚拟号 + { wch: 15 }, // 设备名称 + { wch: 15 }, // 设备型号 + { wch: 15 }, // 设备类型 + { wch: 18 }, // IMEI + { wch: 12 }, // 制造商 + { wch: 15 }, // 最大SIM槽数 + { wch: 25 }, // 卡1 ICCID + { wch: 25 }, // 卡2 ICCID + { wch: 25 }, // 卡3 ICCID + { wch: 25 } // 卡4 ICCID ] // 将所有单元格设置为文本格式 @@ -484,9 +481,9 @@ // 文件选择变化 const handleFileChange = (uploadFile: any) => { - const maxSize = 10 * 1024 * 1024 + const maxSize = 300 * 1024 * 1024 if (uploadFile.raw && uploadFile.raw.size > maxSize) { - ElMessage.error('文件大小不能超过 10MB') + ElMessage.error('文件大小不能超过 300MB') uploadRef.value?.clearFiles() fileList.value = [] return diff --git a/src/views/asset-management/task-management/iot-card-task/index.vue b/src/views/asset-management/task-management/iot-card-task/index.vue index ae6410a..a94d3a4 100644 --- a/src/views/asset-management/task-management/iot-card-task/index.vue +++ b/src/views/asset-management/task-management/iot-card-task/index.vue @@ -139,6 +139,16 @@ + + + + + +
+ 默认为普通卡,可选择行业卡 +
+
+
将 Excel 文件拖到此处,或点击选择
@@ -207,6 +217,7 @@ const uploading = ref(false) const importDialogVisible = ref(false) const selectedCarrierId = ref() + const selectedCardCategory = ref<'normal' | 'industry'>('normal') // 默认普通卡 const carrierList = ref([]) const carrierLoading = ref(false) const failDataDialogVisible = ref(false) @@ -292,6 +303,7 @@ { label: '任务编号', prop: 'task_no' }, { label: '任务状态', prop: 'status' }, { label: '运营商', prop: 'carrier_name' }, + { label: '卡业务类型', prop: 'card_category' }, { label: '文件名', prop: 'file_name' }, { label: '总数', prop: 'total_count' }, { label: '成功数', prop: 'success_count' }, @@ -374,6 +386,19 @@ label: '运营商', width: 120 }, + { + prop: 'card_category', + label: '卡业务类型', + width: 110, + formatter: (row: IotCardImportTask) => { + if (!row.card_category) return '-' + return row.card_category === 'normal' + ? '普通卡' + : row.card_category === 'industry' + ? '行业卡' + : row.card_category + } + }, { prop: 'file_name', label: '文件名', @@ -577,22 +602,22 @@ // 动态导入 xlsx 库 const XLSX = await import('xlsx') - // 创建示例数据 + // 创建示例数据(按固定列顺序:ICCID、MSISDN、虚拟号) const templateData = [ { ICCID: '89860123456789012345', - MSISDN: '13800138000', - virtual_no: 'V001' + 'MSISDN(接入号)': '13800138000', + 虚拟号: 'V001' }, { ICCID: '89860123456789012346', - MSISDN: '13800138001', - virtual_no: 'V002' + 'MSISDN(接入号)': '13800138001', + 虚拟号: 'V002' }, { ICCID: '89860123456789012347', - MSISDN: '13800138002', - virtual_no: 'V003' + 'MSISDN(接入号)': '13800138002', + 虚拟号: 'V003' } ] @@ -603,8 +628,8 @@ // 设置列宽 ws['!cols'] = [ { wch: 25 }, // ICCID - { wch: 15 }, // MSISDN - { wch: 15 } // virtual_no + { wch: 20 }, // MSISDN(接入号) + { wch: 15 } // 虚拟号 ] // 将所有单元格设置为文本格式,防止科学计数法 @@ -631,9 +656,9 @@ // 文件选择变化 const handleFileChange = (uploadFile: any) => { - const maxSize = 10 * 1024 * 1024 + const maxSize = 300 * 1024 * 1024 if (uploadFile.raw && uploadFile.raw.size > maxSize) { - ElMessage.error('文件大小不能超过 10MB') + ElMessage.error('文件大小不能超过 300MB') uploadRef.value?.clearFiles() fileList.value = [] return @@ -659,6 +684,7 @@ // 取消导入 const handleCancelImport = () => { clearFiles() + selectedCardCategory.value = 'normal' // 重置为默认值 importDialogVisible.value = false } @@ -728,7 +754,8 @@ const importRes = await CardService.importIotCards({ carrier_id: selectedCarrierId.value, file_key, - batch_no: `IOT-${Date.now()}` + batch_no: `IOT-${Date.now()}`, + card_category: selectedCardCategory.value // 新增卡业务类型 }) if (importRes.code !== 0) { diff --git a/src/views/asset-management/task-management/task-detail/index.vue b/src/views/asset-management/task-management/task-detail/index.vue index c131e48..5ecc363 100644 --- a/src/views/asset-management/task-management/task-detail/index.vue +++ b/src/views/asset-management/task-management/task-detail/index.vue @@ -119,6 +119,17 @@ label: '运营商', prop: 'carrier_name', formatter: (value: any) => value || '-' + }, + { + label: '卡业务类型', + render: (data: any) => { + if (!data.card_category) return h('span', '-') + return h( + ElTag, + { type: data.card_category === 'industry' ? 'warning' : 'success', size: 'small' }, + () => (data.card_category === 'normal' ? '普通卡' : data.card_category === 'industry' ? '行业卡' : data.card_category) + ) + } } ] : []), diff --git a/src/views/dashboard/analysis/widget/CommissionSummary.vue b/src/views/dashboard/analysis/widget/CommissionSummary.vue index ffd3211..af6407f 100644 --- a/src/views/dashboard/analysis/widget/CommissionSummary.vue +++ b/src/views/dashboard/analysis/widget/CommissionSummary.vue @@ -10,6 +10,20 @@
+ +
+
+ +
+
+
预充值余额
+
{{ formatMoney(summary.main_balance) }}
+
+
+
({ + main_balance: 0, total_commission: 0, available_commission: 0, frozen_commission: 0, @@ -127,6 +142,7 @@ const myShopData = res.data.items.find(item => item.shop_id === currentShopId.value) if (myShopData) { summary.value = { + main_balance: myShopData.main_balance || 0, total_commission: myShopData.total_commission, available_commission: myShopData.available_commission, frozen_commission: myShopData.frozen_commission, diff --git a/src/views/order-management/order-list/index.vue b/src/views/order-management/order-list/index.vue index 940532d..c1ba116 100644 --- a/src/views/order-management/order-list/index.vue +++ b/src/views/order-management/order-list/index.vue @@ -527,13 +527,13 @@ return baseRules }) - const createForm = reactive({ - order_type: 'single_card', - package_id: 0, - iot_card_id: null, - device_id: null, - payment_method: 'wallet', // 默认使用钱包支付 - payment_voucher_key: undefined // 线下支付凭证 + const createForm = reactive({ + order_type: 'single_card' as OrderType, + package_id: undefined as number | undefined, // 前端使用单选 + iot_card_id: null as number | null, + device_id: null as number | null, + payment_method: 'wallet' as OrderPaymentMethod, // 默认使用钱包支付 + payment_voucher_key: undefined as string | undefined // 线下支付凭证 }) const orderList = ref([]) @@ -975,7 +975,7 @@ // 重置表单数据到初始值 createForm.order_type = 'single_card' - createForm.package_id = 0 + createForm.package_id = undefined createForm.iot_card_id = null createForm.device_id = null createForm.payment_method = 'wallet' @@ -1028,10 +1028,16 @@ identifier = selectedDevice.virtual_no } - // 创建订单 + // 验证必填字段 + if (!createForm.package_id) { + ElMessage.error('请选择套餐') + return + } + + // 创建订单(后端接收数组,前端单选转为单元素数组) const data: CreateOrderRequest = { identifier, - package_id: createForm.package_id, + package_ids: [createForm.package_id], payment_method: createForm.payment_method } diff --git a/src/views/polling-management/config/index.vue b/src/views/polling-management/config/index.vue index 9250a84..67ab014 100644 --- a/src/views/polling-management/config/index.vue +++ b/src/views/polling-management/config/index.vue @@ -490,7 +490,7 @@ page_size: 20, carrier_name: carrierName }) - carrierList.value = data.items || data.list || [] + carrierList.value = data.items || [] } catch (error) { console.error('加载运营商列表失败', error) } diff --git a/src/views/polling-management/manual-trigger/index.vue b/src/views/polling-management/manual-trigger/index.vue index 0814eb5..c716239 100644 --- a/src/views/polling-management/manual-trigger/index.vue +++ b/src/views/polling-management/manual-trigger/index.vue @@ -709,7 +709,7 @@ page_size: 20, carrier_name: carrierName }) - carrierList.value = data.items || data.list || [] + carrierList.value = data.items || [] } catch (error) { console.error('加载运营商列表失败', error) } @@ -727,7 +727,7 @@ const loadShops = async () => { try { const { data } = await ShopService.getShops() - shopTreeData.value = data.items || data.list || [] + shopTreeData.value = data.items || [] } catch (error) { console.error('加载店铺列表失败', error) } @@ -741,7 +741,7 @@ page_size: 20, iccid: iccid }) - cardList.value = data.items || data.list || [] + cardList.value = data.items || [] } catch (error) { console.error('加载卡列表失败', error) }