diff --git a/.env.base b/.env.base index 9c6f2ee..c4e5a4a 100644 --- a/.env.base +++ b/.env.base @@ -4,9 +4,9 @@ VITE_NODE_ENV=development VITE_DEV=true # 请求路径 -VITE_BASE_URL='http://47.98.161.246:48080' +# VITE_BASE_URL='http://47.98.161.246:48080' # VITE_BASE_URL='http://114.215.207.150:48080' -# VITE_BASE_URL='http://localhost:48080' +VITE_BASE_URL='http://localhost:48080' # 高德地图key密钥 # 1寻驾 diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index 3b55792..d41bcce 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -59,7 +59,8 @@ const remainingRouter: AppRouteRecordRaw[] = [ title: '首页', hidden: true } - // ,children: [ + // , + // children: [ // { // path: '/index', // component: () => import('@/views/Basic/Menu/index.vue'), diff --git a/src/utils/index.ts b/src/utils/index.ts index db00de1..7e775ed 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -247,3 +247,56 @@ export const exportTableWithVue = (domId: any, fileName: String) => { return wbout // }); } + +/** + * 数组数据导出为 Excel + * @param {Array} data 要导出的数组数据(对象数组,如 [{name: '张三', age: 18}, ...]) + * @param {String} fileName 导出的文件名(不含 .xlsx 后缀) + * @param {Array} header 自定义表头映射(可选,格式:[{key: 'name', title: '姓名'}, ...]) + * 若不传入,默认使用数据对象的 key 作为表头 + */ +export const exportArrayToExcel = function (data: any[], fileName: String, header: any) { + // 处理表头映射 + const worksheetData = [] + let headerKeys = [] // 数据对象的 key 集合 + let headerTitles = [] // 表头显示文本 + + if (header && header.length > 0) { + // 使用自定义表头 + headerKeys = header.map((item) => item.key) + headerTitles = header.map((item) => item.title) + worksheetData.push(headerTitles) // 加入表头行 + } else { + // 自动生成表头(使用数据中第一个对象的 key) + if (data.length === 0) { + console.warn('导出数据为空') + return + } + headerKeys = Object.keys(data[0]) + headerTitles = headerKeys // 表头默认用 key + worksheetData.push(headerTitles) // 加入表头行 + } + + // 处理数据行(按表头 key 顺序提取数据) + data.forEach((item) => { + const row = headerKeys.map((key) => { + // 处理特殊类型(如日期对象转为字符串) + if (item[key] instanceof Date) { + return item[key].toLocaleString() + } + // 其他类型直接转为字符串(避免 undefined 显示) + return item[key] !== undefined ? String(item[key]) : '' + }) + worksheetData.push(row) + }) + + // 创建工作簿和工作表 + const ws = XLSX.utils.aoa_to_sheet(worksheetData) // 数组转工作表 + const wb = XLSX.utils.book_new() // 创建工作簿 + XLSX.utils.book_append_sheet(wb, ws, 'Sheet1') // 工作表命名为 Sheet1 + + // 生成二进制文件并下载 + const excelBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' }) + const blob = new Blob([excelBuffer], { type: 'application/octet-stream' }) + saveAs(blob, `${fileName}.xlsx`) // 保存文件 +} diff --git a/src/views/Clue/Order/Comp/AfterSales.vue b/src/views/Clue/Order/Comp/AfterSales.vue index 66176f1..44679b1 100644 --- a/src/views/Clue/Order/Comp/AfterSales.vue +++ b/src/views/Clue/Order/Comp/AfterSales.vue @@ -251,6 +251,7 @@ import DialogBatchAudit from './DialogBatchAudit.vue' import { removeNullField } from '@/utils' import { dateFormatter } from '@/utils/formatTime' import { useAppStore } from '@/store/modules/app' +import { exportArrayToExcel } from '@/utils/index' const afterSaleAuditDialog = ref() @@ -366,8 +367,37 @@ async function afterSalesUpload(data) { const fd = new FormData() fd.append('file', data.file) try { - await AfterSaleApi.importAfterSales(fd) - message.success('导入成功') + const resp = await AfterSaleApi.importAfterSales(fd) + debugger + if (resp && resp.data && resp.data.length) { + const succList = resp.data.filter((item) => item.success) + const failList = resp.data.filter((item) => !item.success) + let msg = `导入完成!成功 ${succList.length} 条,失败 ${failList.length} 条。` + if (failList.length) { + // 如果有失败,提示下载失败文件 + msg += '\n请点击消息下载失败明细进行查看。' + } + ElNotification({ + title: '导入结果', + message: msg, + type: 'info', + duration: 0, + onClick: () => { + if (failList.length) { + // 将failList生成文件,使用前端下载 + exportArrayToExcel(failList, `售后导入失败明细${new Date().getTime()}`, [ + { title: '手机号', key: 'phone' }, + { title: '售后原因', key: 'reason' }, + { title: '退款金额', key: 'refundAmount' }, + { title: '提成扣款', key: 'percentageDeductAmount' }, + { title: '解决方案', key: 'solution' }, + { title: '备注', key: 'remark' }, + { title: '失败原因', key: 'message' } + ]) + } + } + }) + } } finally { uploading.value = false getList()