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

@@ -68,9 +68,54 @@ alwaysApply: true
## 表单校验
- 必填用字符串规则 `rules: 'required'`(选择项用 `'selectRequired'`),规则定义在 `#/adapter/form.ts` 的 `defineRules`
- 校验调用统一用 `formApi.validate().then(e => { if (e.valid) {...} })`
- 必填用字符串规则 `rules: 'required'`(选择项用 `'selectRequired'`),规则定义在 `#/adapter/form.ts` 的 `rules`
- 必填字段在 schema 中加 `rules: 'required'`,禁止散落 `validator` 写法
- 校验调用统一用 **单次 await**(禁止 `.then` 与 `validateAndSubmitForm` 并用):
```ts
const e = await formApi.validate();
if (!e.valid) return;
const values = await formApi.getValues();
```
## 弹窗 onConfirm强制防「点确定无反应」
弹窗内提交必须按下列写法,**禁止**复制旧模板:
```ts
onConfirm: async () => {
const e = await formApi.validate();
if (!e.valid) return;
const values = await formApi.getValues();
modalApi.setState({ loading: true, confirmLoading: true });
try {
await submitApi(values);
message.success('保存成功');
gridApi.value?.reload?.();
modalApi.close();
} catch (err) {
console.error(err);
} finally {
modalApi.setState({ loading: false, confirmLoading: false });
}
};
```
- **禁止** `formApi.validate().then(...)` 后再 `await formApi.validateAndSubmitForm()`(并发二次校验,表现为点确定无提交)
- **禁止**无 `handleSubmit` 时调用 `validateAndSubmitForm` / `validateAndSubmit`
- 参考:`product-order/components/refund.vue`、`audit-prescription/components/modal.vue`、`delivery-warehouse-order/components/modal.vue`
## 表单 Divider / 分区标题
- `component: 'Divider'` 仅作分区展示,**禁止**加 `rules: 'required'`(无业务值,必失败)
- **禁止**用占位 `label: 'x'`会渲染成校验文案「请输入x」
- `fieldName` 用唯一占位如 `_section_basic`,不要空字符串
## 敏感字段展示SensitiveText
- 模板使用 `<SensitiveText>` 时,**必须**显式:`import SensitiveText from '#/components/sensitive-text/SensitiveText.vue'`
- 该组件**未**全局注册;表单选择器(`form/components/*-picker.vue`)同样要 import对齐 `doctor-picker` / `store-picker`
- **禁止**只写模板标签不写 import会报 `Failed to resolve component: SensitiveText`
## 字典/枚举管理
@@ -177,10 +222,10 @@ alwaysApply: true
- 表单必须用 `useVbenForm`,禁止直接 `<form>` 或 antd `Form`
- 动态修改 schema 必须用 `formApi.updateSchema([...])`**vben form 没有 `setComponentProps` 这个方法**(这是已踩过的坑)
- 重置表单用 `formApi.resetForm()`**严禁 `formApi.resetFields()`**(那是 antd Form 的 APIVben Form 没有,会报 `resetFields is not a function`;已踩过坑)
- 重置表单用 `formApi.reset()``resetForm` 已弃用);**严禁 `formApi.resetFields()`**(那是 antd Form 的 APIVben Form 没有,会报 `resetFields is not a function`;已踩过坑)
- 取值/赋值用 `formApi.getValues()` / `formApi.setValues(obj)`,禁止自己 `v-model` 收集
- 校验用 `formApi.validate().then(e => { if (e.valid) {...} })` `formApi.validateAndSubmitForm()`
- 必填规则用字符串 `'required'` / `'selectRequired'`,规则在 `#/adapter/form.ts` 的 `defineRules` 注册
- 校验用 `const e = await formApi.validate(); if (!e.valid) return;`**禁止** `validate().then` `validateAndSubmitForm` 并用(见上文「弹窗 onConfirm」
- 必填规则用字符串 `'required'` / `'selectRequired'`,规则在 `#/adapter/form.ts` 的 `rules` 注册
- schema 中字段名(`fieldName`)必须与后端字段 snake_case 对齐,禁止前端 camelCase
- 密码/敏感字段用 `VbenInputPassword` 组件,禁止用 `VbenInput` 配 `type="password"`
- 单选/多选选项来自接口时,必须在弹窗/页面 `onMounted` 或 `onOpenChange` 里拉取后通过 `updateSchema` 注入,禁止写死常量