From a81f177cb6b04344a8a39b847cef4d8eaffdb0da Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Wed, 21 Oct 2026 20:17:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E9=A1=BA=E4=B8=B0?= =?UTF-8?q?=E6=9C=88=E7=BB=93=E5=88=97=E8=A1=A8=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E3=80=81=E7=BB=93=E7=AE=97=E5=92=8C=E8=A1=A5?= =?UTF-8?q?=E5=A1=AB=E8=BF=90=E8=B4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- web-admin/src/api/sf-express-settlement.ts | 38 ++ .../sf-express-settlement-export.test.ts | 17 + .../src/utils/sf-express-settlement-export.ts | 30 ++ .../sf-express-settlement/index.vue | 447 ++++++++++++++++++ 4 files changed, 532 insertions(+) create mode 100644 web-admin/src/api/sf-express-settlement.ts create mode 100644 web-admin/src/utils/sf-express-settlement-export.test.ts create mode 100644 web-admin/src/utils/sf-express-settlement-export.ts create mode 100644 web-admin/src/views/cell-storage/sf-express-settlement/index.vue diff --git a/web-admin/src/api/sf-express-settlement.ts b/web-admin/src/api/sf-express-settlement.ts new file mode 100644 index 00000000..d5e1d9c4 --- /dev/null +++ b/web-admin/src/api/sf-express-settlement.ts @@ -0,0 +1,38 @@ +import request from '@/utils/http' + +export type SfExpressSettlement = { + id: string + waybillNo: string + createByName: string + createTime: string + settleStatus: string + settleStatusLabel: string + freightAmount: number | null + freightAmountLabel: string + settleTime: string +} + +export function fetchSfExpressSettlements(params: Record) { + return request.get<{ list: SfExpressSettlement[]; total: number }>({ + url: '/web/admin/sample-freights/sf-settlements', + params + }) +} + +export function fetchSfExpressSettlementExport(params: Record) { + return request.get<{ list: SfExpressSettlement[] }>({ + url: '/web/admin/sample-freights/sf-settlements/export', + params + }) +} + +export function settleSfExpressSettlements(data: { ids: string[]; freightAmount?: number }) { + return request.post({ url: '/web/admin/sample-freights/sf-settlements/settle', data }) +} + +export function fillSfExpressSettlementAmount(id: string, freightAmount: number) { + return request.post({ + url: `/web/admin/sample-freights/sf-settlements/${id}/fill-amount`, + data: { freightAmount } + }) +} diff --git a/web-admin/src/utils/sf-express-settlement-export.test.ts b/web-admin/src/utils/sf-express-settlement-export.test.ts new file mode 100644 index 00000000..04d1b096 --- /dev/null +++ b/web-admin/src/utils/sf-express-settlement-export.test.ts @@ -0,0 +1,17 @@ +import assert from 'node:assert/strict' +import test from 'node:test' +import { buildSfExpressExportRows } from './sf-express-settlement-export.ts' + +test('export rows match the settlement list columns', () => { + const rows = buildSfExpressExportRows([ + { + waybillNo: '', + createByName: '张三', + createTime: '2026-10-21 09:00:00', + settleStatusLabel: '未结算', + freightAmountLabel: '月结', + settleTime: '' + } + ]) + assert.deepEqual(rows[0], ['—', '张三', '2026-10-21 09:00:00', '未结算', '月结', '—']) +}) diff --git a/web-admin/src/utils/sf-express-settlement-export.ts b/web-admin/src/utils/sf-express-settlement-export.ts new file mode 100644 index 00000000..f08bf02c --- /dev/null +++ b/web-admin/src/utils/sf-express-settlement-export.ts @@ -0,0 +1,30 @@ +import ExcelJS from 'exceljs' +import FileSaver from 'file-saver' + +const HEADERS = ['顺丰单号', '创建人', '创建时间', '结算状态', '运费', '结算时间'] + +export function buildSfExpressExportRows(list: Array>) { + return list.map((row) => [ + row.waybillNo || '—', + row.createByName || '—', + row.createTime || '—', + row.settleStatusLabel || '—', + row.freightAmountLabel || '—', + row.settleTime || '—' + ]) +} + +export async function saveSfExpressSettlementWorkbook(list: Array>) { + const workbook = new ExcelJS.Workbook() + const sheet = workbook.addWorksheet('顺丰月结') + sheet.addRow(HEADERS) + buildSfExpressExportRows(list).forEach((line) => sheet.addRow(line)) + const buffer = await workbook.xlsx.writeBuffer() + const blob = new Blob([buffer], { + type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + }) + const stamp = new Date() + const pad = (value: number) => String(value).padStart(2, '0') + const name = `顺丰月结-${stamp.getFullYear()}${pad(stamp.getMonth() + 1)}${pad(stamp.getDate())}${pad(stamp.getHours())}${pad(stamp.getMinutes())}${pad(stamp.getSeconds())}.xlsx` + FileSaver.saveAs(blob, name) +} diff --git a/web-admin/src/views/cell-storage/sf-express-settlement/index.vue b/web-admin/src/views/cell-storage/sf-express-settlement/index.vue new file mode 100644 index 00000000..ae108a36 --- /dev/null +++ b/web-admin/src/views/cell-storage/sf-express-settlement/index.vue @@ -0,0 +1,447 @@ + + + + +