feat: 管理端公账支付与确认、锁店遮罩及表单提交修复

新增公账账单/到账确认页与全局锁店组件;系统配置补公账参数面板;
统一弹窗 onConfirm 校验提交,并完善订单详情与门店相关交互。
This commit is contained in:
李琦
2026-08-21 12:51:42 +08:00
parent 66e666754a
commit 879efb8f29
145 changed files with 7326 additions and 884 deletions

View File

@@ -9,13 +9,34 @@ import type { ComponentPropsMap, ComponentType } from './component';
import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';
/**
* 判断表单值是否「空」(必填校验共用)
* 为什么不写 value.length===0:InputNumber 是 number,.length 为 undefined,会误判/漏判
* 数字 0 视为有值(比例、金额等合法)
*/
function isEmptyFormValue(value: unknown): boolean {
if (value === undefined || value === null) return true;
if (typeof value === 'string') return value.trim() === '';
if (Array.isArray(value)) return value.length === 0;
return false;
}
/** 校验文案用的字段名:优先 label,避免 i18n {0} 裸露成「请输入x」 */
function ruleLabel(ctx: { label?: string; name?: string }): string {
return (ctx.label || ctx.name || '该项').trim() || '该项';
}
async function initSetupVbenForm() {
setupVbenForm<ComponentType>({
config: {
// ant design vue组件库默认都是 v-model:value
baseModelPropName: 'value',
// antd Input 的 onChange 带的是 event,打开回退后表单能从 event.target.value 取值
// (与 v-model:value 双通道写入,避免包装层漏绑时查询条件一直是空)
changeEventFallback: true,
// 一些组件是 v-model:checked 或者 v-model:fileList
// Vben* 走 modelValue,避免被 baseModelPropName=value 误绑后把 Event 写进字段
modelPropNameMap: {
Checkbox: 'checked',
Radio: 'checked',
@@ -23,20 +44,23 @@ async function initSetupVbenForm() {
Upload: 'fileList',
UploadImage: 'modelValue',
UploadOssFile: 'modelValue',
VbenInput: 'modelValue',
VbenInputPassword: 'modelValue',
VbenPinInput: 'modelValue',
},
},
rules: {
// 输入项目必填国际化适配
// 输入项目必填国际化适配(兼容 InputNumber number)
required: (value, _params, ctx) => {
if (value === undefined || value === null || value.length === 0) {
return $t('ui.formRules.required', [ctx.label]);
if (isEmptyFormValue(value)) {
return $t('ui.formRules.required', [ruleLabel(ctx)]);
}
return true;
},
// 选择项目必填国际化适配
selectRequired: (value, _params, ctx) => {
if (value === undefined || value === null) {
return $t('ui.formRules.selectRequired', [ctx.label]);
if (isEmptyFormValue(value)) {
return $t('ui.formRules.selectRequired', [ruleLabel(ctx)]);
}
return true;
},
@@ -46,11 +70,11 @@ async function initSetupVbenForm() {
*/
mobile: (value, _params, ctx) => {
const phone = typeof value === 'string' ? value.trim() : value;
if (phone === undefined || phone === null || phone === '') {
return $t('ui.formRules.required', [ctx.label]);
if (isEmptyFormValue(phone)) {
return $t('ui.formRules.required', [ruleLabel(ctx)]);
}
if (!/^1[3456789]\d{9}$/.test(String(phone))) {
return $t('ui.formRules.mobile', [ctx.label]);
return $t('ui.formRules.mobile', [ruleLabel(ctx)]);
}
return true;
},