20260917212907

This commit is contained in:
oneao committed 2026-09-17 21:29:08 +08:00
1 parent 6fa3d8535e
commit 5cbf745bbf
115 files changed
+4104 -85

No files matched your search

@@ -12,6 +12,83 @@
全套 10 个用例通过;oxlint 干净(oxfmt 全仓库既有 format issues,未动)。
- 已核对仓库内另 3 处 `pageDataApi` 调用(FileListPanel / useLookupOptions / FmsModuleListPage)都传了 orderBy。
## 新增:UI 组件库全局配置(uiConfig)
- 背景:组件库此前**没有任何全局配置层**(`ui/index.js` 只是具名导出,无 `install`/`app.use`;
组件间只有 form/form-group/radio-group/tree/dropdown 五个局部 provide)。Form 的
`layout` 等默认值硬编码在 prop 里,想改只能逐处传。
- 新增 `fms-vue/src/components/ui/config.js`:`uiConfig`(reactive)+ `setUIConfig(patch)`(按组件维度浅合并)
+ `resetUIConfig()`;三者也从 `@/components/ui` 具名导出。
- 回落顺序统一为 **自身 prop > 全局配置 > 组件内置默认**。凡要支持全局覆盖的 prop,
`default` 必须改成 `undefined` 且 validator 放行 `undefined`(Vue 会校验 default 值)。
- Form(`form/form.vue`):`layout`/`labelAlign`/`labelWidth`/`validateTrigger` 改为经
`resolvedXxx` computed 回落,provide 下发的是**回落后的最终值**,FormItem 不用再管全局配置;
FormItem 独立使用(无 Form 包裹)时也读一次 `uiConfig`。
- 语言联动写在 `src/App.vue`:`watch(() => i18nStore.locale)` → `layout = /^zh/i.test(locale) ? 'horizontal' : 'vertical'`
(中文横排、其他语言竖排),`immediate: true` 覆盖持久化 locale 的刷新场景。
- 存量 8 处 `layout="vertical"` 已全部删除(login、base/othercompany、system/user、
menu-management/MenuBasicPanel、module-management 的 Basic/AutoCode/FormPreview、FmsModuleEditModal),
统一跟随语言;`ui/demo/form.vue` 保留(它是组件展示页,故意演示各布局)。
风险点:FmsModuleEditModal(columns=24 网格)与 FormPreview(columns=48)在中文下变横排可能拥挤,待目测。
- 测试:`tests/components/form.spec.js` 新增 5 例(全局默认、prop 覆盖、局部合并、validateTrigger、独立 FormItem),
15 例全通过;oxlint `--deny-warnings` 干净;`vite build` 通过。
- 已知非本次引入:`tests/views/login.spec.js` 套件级失败(favicon.svg URL 解析,环境问题,收集 0 用例);
`module-list-components.spec.js` 的 `.filter-joiner`/`.filter-row` 断言是过期基线。
## 修复:顶栏语言切换不生效(i18n 只有 locale,没有译文)
- 根因:`setMessages` 在 `src/` 下**从无调用点** → `messagesRef` 永远为空,`t(key, fallback)` 恒返回中文兜底;
顶栏按钮只是把 `locale` 在 zh-CN/en-US 间翻一下,界面毫无变化。
另查库:`s_i18n_type` 有 zh-CN(默认)/en-US;`s_i18n` **134 行全是 zh-CN,en-US 为 0 行**。
- 改动:
- `stores/i18n.js` 新增 `loadMessages(locale, force)`:查 `s_i18n`(`b_canuse = 1 and b_locale = N'..'`,
`sqlQuote` 转义单引号),按 locale 缓存 + 并发 Promise 复用 + 失败静默;`applyMessages` 只认**当前** locale
(防止请求回来时语言已被切走导致串台),合并顺序 **前端内置 < 库表译文**;`clearMessages` 顺带清缓存。
- 新增 `src/i18n/builtin-messages.js`:内置 en-US 的 `common.*`(45 条,代码里已用 `t('common.x','中文')` 约定)。
中文不内置(fallback 即中文)。库里登记同名 key 可覆盖内置。
- `App.vue` 的 locale watcher 增加 `i18nStore.loadMessages(locale)`;`router/index.js` 守卫在
`loadLanguages()` 后再 `loadMessages()` 兜首次进入。
- 顶栏:按钮改为 Dropdown,语种取自 `s_i18n_type` 清单(不再硬编码互切),当前项用 `shortcut: '✓'` 标出
(Dropdown item 没有 active 态)。
- 测试新增 12 例:`tests/stores/i18n-messages.spec.js`(7)、`tests/components/app-topbar-language.spec.js`(3)、
`tests/unit/app-locale-sync.spec.js`(2)。全量 497 通过 / 13 失败(**均为既有基线**:
login 套件 + router-auth 3 例都是 `favicon.svg` 环境问题——`views/login/index.vue:98` 的 `<img src="/favicon.svg">`;
其余 9 例是查询面板改版后的过期断言)。
- 注:`vite build` 冒烟本次被用户拒绝执行(含 find -delete),改用 vitest 挂载 App/AppTopbar 验证编译与行为。
## 查询区改用 Form/FormItem(跟随语言布局)
- 现象:切中文后查询条件区仍是上下结构。原因:`FmsQueryToolbar.vue` **没用 Form**,是自己写的
`<div class="query-field"><label class="query-field__label">`,CSS 写死 `flex-direction: column`。
`fms-module-list/` 下完全没有 `<Form>`(高级查询面板也是自绘 `.filter-*`)。
- 改法:字段网格改成 `<Form class="query-fields" :model="filters" label-width="72px">` + `<FormItem class="query-field" :name :label>`。
关键:**`.query-fields { display: contents }`** —— 让 Form 根透明化,FormItem 才能直接成为 `.query-grid`
(`repeat(n, minmax(0,200px))`)的网格单元,保持原有列宽与 gap 不变。
另加 `.query-field{margin-bottom:0}`(去掉 FormItem 自带 6px)与 `:deep(.fms-form-item-label)`
次要色/单行省略(对齐原 `.query-field__label` 观感)。label-width 取 72px:200px 列宽下比全局 88px 更省地方。
- 微调(横向间距过大):Form 改 `label-width="auto" label-align="left"`,标签按内容收缩;
只在横向态加 `.query-fields.fms-form-horizontal .query-field :deep(.fms-form-item-label){max-width:72px;padding-right:6px}`
(组件库默认 label padding-right 12px;纵向态不设 max-width,标签占满列宽)。
若嫌**字段之间**的列间距大,改 `.query-grid { gap: 8px 16px }` 的第二个值。
- 测试:`module-list-components.spec.js` 新增 1 例(横排/竖排跟随 uiConfig + 标签 width:auto);
`fms-module-list-page.spec.js` 里断言旧标签 `.query-field__label` 的用例改为 `.query-field .fms-form-item-label`。
全量回到 13 失败 / 498 通过(均为既有基线)。
## 修复:自动编码面板拨「启用」报错 + 控件被压扁
- 报错 `Cannot set properties of undefined (setting 'b_canuse')`(ModuleAutoCodePanel.toggleEnabled):
**与语言/布局无关,是既有 bug**。`ensureRow()` 里 `autoCode.value = [row]` 之后立刻回读
`autoCode.value[0]`——`defineModel` 写了只 emit,prop 要下一轮才回传,此刻读到的仍是空数组。
修法:先 `const rows = reactive([createDraft(...)])` 再 `autoCode.value = rows`,返回 `rows[0]`(代理行)。
注意已有行时是**就地改属性、不 emit 整个数组**(父级 ref 深度响应式),测试要按这个预期写。
- 控件宽度:该面板是 `columns=5 + max-width 720px`(每列约 130px),横排时 88px 标签 + 12px 内边距把控件压到
~30px。已给这个 Form 固定 `layout="vertical"`(prop 优先于全局配置)。
**结论:多列紧凑网格的表单不适合横排,要显式钉 layout。**
同类待观察:`ModuleBasicPanel`(columns=3,单列项控件约 140px)、`FormPreview`(columns=48)、
`FmsModuleEditModal`(columns=24,b_colspan 默认 24 即整行,多数不受影响)。
- 新增 `tests/unit/module-auto-code-panel.spec.js` 3 例(惰性建行写回、已有行就地改、固定竖排)。
全量 528 通过 / 13 失败(仍是既有基线)。
## 维护
- `MEMORY.md` 超限被截断,已按主题重写精简(合并重复项、删掉过期与可推导内容)。
+27
View File
@@ -83,6 +83,33 @@
描边 `color-mix(primary 40%, #fff)`;「浅底+白字」对比度只有 1.4~2.7:1,不可用。
- Teleport 到 body 的浮层(如 `.fms-team-menu-*`)不在侧栏内,保持全局浅色 token。
## UI 组件库全局配置
- 唯一入口 `fms-vue/src/components/ui/config.js`:`uiConfig`(reactive)+ `setUIConfig(patch)`(按组件维度浅合并)
+ `resetUIConfig()`,也从 `@/components/ui` 具名导出。**没有 ConfigProvider、没有 app.use 插件**。
- 回落顺序固定 **自身 prop > uiConfig > 组件内置默认**;要支持全局覆盖的 prop,`default` 必须写 `undefined`
且 validator 要放行 `undefined`(Vue 会拿 default 跑校验)。
- Form 的 `layout`/`labelAlign`/`labelWidth`/`validateTrigger` 已接入;provide 下发回落后的最终值。
语言联动在 `src/App.vue`:中文 `horizontal`、其他语言 `vertical`(判定 `/^zh/i`)。
- **多列紧凑网格的表单必须显式 `layout="vertical"`**(如自动编码面板 columns=5),
否则横排的 88px 标签会把控件压到几十像素。prop 优先于全局配置。
- `defineModel` 写完**不能立刻回读**:写了只 emit,prop 下一轮才回来;要取刚写入的值就自己先
`reactive()` 包一层再赋值,返回其中的代理对象。
## i18n 运行时
- 语言清单 `s_i18n_type`(`b_id` 即语种编码,zh-CN 默认 / en-US);译文 `s_i18n(b_key, b_locale, b_value)`。
- store `stores/i18n.js`:`loadLanguages()` 拉清单、**`loadMessages(locale)` 拉译文**(按语种缓存 + 并发去重 +
失败静默;只把「当前语种」的译文写进运行时)。**别只看 locale——不调 loadMessages 界面不会变。**
- 合并顺序 **前端内置 < 库表译文**:内置只有 en-US 的 `common.*`(`src/i18n/builtin-messages.js`,
代码约定 `t('common.x', '中文兜底')`);业务文案/字段名/菜单名的译文一律进 `s_i18n` 由实施维护。
- 现状:`s_i18n` 只登记了 zh-CN(约 134 条),en-US 尚无数据 → 英文界面只有框架按钮/提示是英文,
字段名等仍回落中文,需要补录。
- 顶栏语种下拉取自 `s_i18n_type` 清单,不要硬编码语言编码。
- 查询区(`FmsQueryToolbar`)已改用 Form/FormItem,因此也跟随该配置;Form 根靠 `display: contents`
透明化,让 FormItem 直接参与 `.query-grid`(`minmax(0,200px)`)布局,label 宽局部 72px。
高级查询面板(`FmsAdvancedQueryPanel`)仍是自绘 `.filter-*`,**不受**表单布局配置影响。
## 导出(P0 已落地,摘要)
`POST /api/export/list` 返回文件流:`SqlPermissionService` → `ExportSchemaService`(列与列表同源推导)