From dded2ab332686be9e9cec2b1c19105fb10ca17ae Mon Sep 17 00:00:00 2001 From: zjf <1799650030@qq.com> Date: Mon, 17 Aug 2026 13:47:15 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A3=9F=E5=A0=82=E6=BC=94=E7=A4=BA=E6=8A=A5?= =?UTF-8?q?=E8=A1=A8=EF=BC=8C=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86=E5=A7=93?= =?UTF-8?q?=E5=90=8D=E6=94=AF=E6=8C=81=E6=95=B0=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/canteen/canteenReport.ts | 43 ++ src/utils/validate.ts | 11 +- .../canteen/canteenReportFaceImport/index.vue | 519 ++++++++++++++++++ .../canteen/canteenReportSettlePark/index.vue | 174 ++++++ .../canteen/canteenReportSwipe/index.vue | 9 +- 5 files changed, 751 insertions(+), 5 deletions(-) create mode 100644 src/views/canteen/canteenReportFaceImport/index.vue create mode 100644 src/views/canteen/canteenReportSettlePark/index.vue diff --git a/src/api/canteen/canteenReport.ts b/src/api/canteen/canteenReport.ts index fe87a55f..d2648f4b 100644 --- a/src/api/canteen/canteenReport.ts +++ b/src/api/canteen/canteenReport.ts @@ -1,5 +1,48 @@ import request from "/@/utils/request" +/** 人脸消费导入 */ +export function fetchFaceImportLogPage(query?: Object) { + return request({ url: "/canteen/canteenReport/faceImport/log/page", method: "get", params: query }) +} +export function fetchFaceDetailPage(query?: Object) { + return request({ url: "/canteen/canteenReport/faceImport/detail/page", method: "get", params: query }) +} +export function importFaceExcel(data: FormData, params: Object) { + return request({ + url: "/canteen/canteenReport/faceImport/import", + method: "post", + params, + data, + headers: { "Content-Type": "multipart/form-data" }, + timeout: 600000, + }) +} +export function aggregateFaceToSwipe(params: Object) { + return request({ + url: "/canteen/canteenReport/faceImport/aggregate", + method: "post", + params, + timeout: 600000, + }) +} + +/** 结算台厂区 */ +export function fetchSettleParkPage(query?: Object) { + return request({ url: "/canteen/canteenReport/settlePark/page", method: "get", params: query }) +} +export function fetchSettleParks() { + return request({ url: "/canteen/canteenReport/settlePark/parks", method: "get" }) +} +export function addSettlePark(obj?: Object) { + return request({ url: "/canteen/canteenReport/settlePark", method: "post", data: obj }) +} +export function putSettlePark(obj?: Object) { + return request({ url: "/canteen/canteenReport/settlePark", method: "put", data: obj }) +} +export function delSettlePark(ids?: Object) { + return request({ url: "/canteen/canteenReport/settlePark", method: "delete", data: ids }) +} + /** 刷卡明细 */ export function fetchSwipePage(query?: Object) { return request({ url: "/canteen/canteenReport/swipe/page", method: "get", params: query }) diff --git a/src/utils/validate.ts b/src/utils/validate.ts index f0a377ea..61b7ee6e 100644 --- a/src/utils/validate.ts +++ b/src/utils/validate.ts @@ -47,15 +47,18 @@ export const rule = { } }, /** - * 姓名/昵称:中文,或英文(单词间可空格,如 John Smith) + * 姓名/昵称:中文、英文、数字(单词间可空格,如 John Smith、张三1) */ validatorPersonName(rule: any, value: any, callback: any) { - const pattern = - /^(?:[\u4e00-\u9fa5]{1,32}|[A-Za-z]+(?:\s[A-Za-z]+){0,8}|[\u4e00-\u9fa5A-Za-z]+(?:\s[\u4e00-\u9fa5A-Za-z]+){0,8})$/; + const pattern = /^[\u4e00-\u9fa5A-Za-z0-9]+(?:\s[\u4e00-\u9fa5A-Za-z0-9]+){0,8}$/; if (value) { const normalized = String(value).trim().replace(/\s+/g, ' '); + if (normalized.length > 32) { + callback(new Error('不能超过32个字符')); + return; + } if (!pattern.test(normalized)) { - callback(new Error('仅支持中文,或英文(单词间可用空格,如 John Smith)')); + callback(new Error('仅支持中文、英文、数字(单词间可用空格)')); return; } } diff --git a/src/views/canteen/canteenReportFaceImport/index.vue b/src/views/canteen/canteenReportFaceImport/index.vue new file mode 100644 index 00000000..b370d26e --- /dev/null +++ b/src/views/canteen/canteenReportFaceImport/index.vue @@ -0,0 +1,519 @@ + + + + + + + + + + + + + + + + + 查询 + 重置 + + + + + + 导入人脸消费 Excel + + 统计汇总到刷卡明细 + + 查看逐笔明细 + 结算台厂区 + 刷卡明细 + + + + + + + + + + + + {{ row.dateStart || "-" }} ~ {{ row.dateEnd || "-" }} + - + + + + + + + + 成功 + 失败 + {{ row.status || "-" }} + + + + + 已汇总{{ row.aggRows ? `(${row.aggRows})` : "" }} + 未汇总 + + + + + {{ row.costMs != null ? (row.costMs / 1000).toFixed(1) + "s" : "-" }} + + + + + + + Excel + 明细 + 汇总 + + + + + + + + + + + + + 正在导入,请勿关闭页面或重复点击。 + 数据量较大时(如十几万~几十万行)后台仍在处理,前端可能看起来「没反应」,请耐心等候,通常几分钟内完成。 + 已等待 {{ importElapsedSec }} 秒… + + + + + + + 报表归属月:数据算进哪个月的报表(看板按这个月查)。 + 本文件日期段:这份 Excel 实际覆盖哪几天(如同月拆成 1–15、16–31 两份时必填)。 + 大文件(几十万行)导入较慢,提交后请耐心等候,不要刷新页面。 + + + + + + + 一般与下面日期段同一月,例如 2026-08 + + + + 例:上半月填 2026-08-01~2026-08-15;下半月再导一份填 16~31 + + + + 开启后只替换「本文件日期段」内已有明细,不会清掉同月其它日期段 + + + + 选择文件 + + {{ importFileHint }} + + + + + 取消 + + {{ importLoading ? "导入中,请稍候…" : "开始导入" }} + + + + + + + + + + + + + 先清空该月已汇总的人脸刷卡行再写入 + + + + 取消 + 开始汇总 + + + + + + + + + + + + + + 查询 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/views/canteen/canteenReportSettlePark/index.vue b/src/views/canteen/canteenReportSettlePark/index.vue new file mode 100644 index 00000000..cb39932a --- /dev/null +++ b/src/views/canteen/canteenReportSettlePark/index.vue @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + 查询 + 重置 + + + + + + 新增 + + 删除 + + + + + + + + + + + + + + + 编辑 + 删除 + + + + + + + + + + + + + + + + + + + + + + 取消 + 保存 + + + + + + diff --git a/src/views/canteen/canteenReportSwipe/index.vue b/src/views/canteen/canteenReportSwipe/index.vue index c3f21d16..a9aa766e 100644 --- a/src/views/canteen/canteenReportSwipe/index.vue +++ b/src/views/canteen/canteenReportSwipe/index.vue @@ -56,6 +56,7 @@ + @@ -66,6 +67,7 @@ + @@ -130,7 +132,9 @@ import { BasicTableProps, useTable } from "/@/hooks/table" import { fetchSwipePage, delSwipe, clearSwipeMonth } from "/@/api/canteen/canteenReport" import { useMessage, useMessageBox } from "/@/hooks/message" import request from "/@/utils/request" +import { useRoute } from "vue-router" +const route = useRoute() const incomeTypes = ["员工刷卡", "支付宝", "包厢收入", "其他收入", "利润调整", "开票结算", "无法收回"] const queryRef = ref() @@ -139,7 +143,10 @@ const selectObjs = ref([]) as any const multiple = ref(true) const state: BasicTableProps = reactive({ - queryForm: { bizMonth: "2026-07" }, + queryForm: { + bizMonth: (route.query.bizMonth as string) || "2026-07", + ...(route.query.importLogId ? { importLogId: route.query.importLogId } : {}), + }, pageList: fetchSwipePage, })