Files
2026-09-17 21:29:08 +08:00

8.2 KiB
Raw Permalink Blame History

2026-09-17

修复:合作伙伴分类删除报「order_by 不能为空」

  • 现象:base/othercompany 删除分类 → 「分类数据检查失败:order_by 不能为空」。
  • 根因:onCategoryDelete 的守卫查询调 pageDataApi(/data/page)漏传 orderBy; 后端 DataService.page 用 getRequiredString(params,"order_by"),DbUtils.buildPageOrderBy 对空值抛「order_by 不能为空」。/data/loaddata 的 order_by 是可选的,/data/page 是必填 (分页需要确定性排序),所以同类守卫在 views/system/user 用 loaddata 没问题、这里用 page 就炸。
  • 改动:src/views/base/othercompany/index.vue 守卫查询加 orderBy: 'b_id ASC'; tests/views/othercompany.spec.js 新增回归用例断言 pageDataApi 的入参(含 orderBy)。 全套 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 超限被截断,已按主题重写精简(合并重复项、删掉过期与可推导内容)。