-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -220,7 +285,7 @@ function onAdvancedReset() {
color: var(--fms-text);
}
-/* ---- demo 卡片:工具栏 + 高级搜索 + 表格 + 分页(灰底画布上的白卡,靠阴影分层,无边框线) ---- */
+/* ---- 列表卡:操作工具栏 + 表格 + 分页(灰底画布上的白卡,靠阴影分层,无边框线) ---- */
.demo-card {
display: flex;
flex-direction: column;
@@ -232,80 +297,102 @@ function onAdvancedReset() {
box-shadow: var(--fms-shadow);
}
-/* ---- 工具栏:左侧搜索 + 高级搜索,右侧更多操作 + 新增 ---- */
+/* ---- 操作工具栏:主操作靠左,更多操作靠右(白底,靠 padding 与上下分区) ---- */
.demo-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
+ /* 换行时整组掉下去,避免左右两组元素交错堆叠 */
flex-wrap: wrap;
padding: 10px 12px;
- border-bottom: 1px solid var(--fms-border);
}
+/* 组内不换行:窄屏由外层整组换行兜底 */
.toolbar-left,
.toolbar-right {
display: flex;
align-items: center;
gap: 8px;
- flex-wrap: wrap;
}
-.toolbar-search {
- width: 240px;
-}
-
-/* 高级搜索按钮:展开面板时高亮 */
-.toolbar-toggle-active {
- color: var(--fms-primary);
- background: color-mix(in srgb, var(--fms-primary) 10%, var(--fms-card));
-}
-
-/* ---- 高级搜索面板:label 在上、控件等宽网格。
- * 多语言下标签长度不一,label 置顶 + 控件铺满网格单元即可保证各列对齐;
- * 查询/重置独立一行、靠右。 ---- */
-.demo-advanced {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
- gap: 12px 16px;
- padding: 12px;
- border-bottom: 1px solid var(--fms-border);
- background: color-mix(in srgb, var(--fms-background) 30%, var(--fms-card));
-}
-
-.advanced-field {
+/* ---- 搜索卡(独立白卡):行堆叠,每行固定 4 个等宽字段格。
+ * 格内 label 行内居左、控件占满剩余宽度。
+ * 回车提交:表单 submit + 首字段尾部的内嵌查询按钮。 ---- */
+.search-card {
display: flex;
flex-direction: column;
- gap: 6px;
+ gap: 10px;
+ padding: 12px;
+ border-radius: 8px;
+ background: var(--fms-card);
+ box-shadow: var(--fms-shadow);
+}
+
+.search-row {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ column-gap: 16px;
+ row-gap: 10px;
+}
+
+.search-field {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ /* 控件自适应内容宽度,不撑满整行 */
+ flex: 0 1 auto;
min-width: 0;
}
-.advanced-label {
+.search-label {
font-size: 12px;
color: var(--fms-text-secondary);
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
+ /* 多语言下 label 可能很长:不强制单行,允许换行,防溢出 */
+ white-space: normal;
+ word-break: break-word;
+ line-height: 1.4;
}
-/* 控件统一铺满所在网格单元(Input / Select / RangePicker 根节点) */
-.advanced-field :deep(.input-wrapper),
-.advanced-field :deep(.select),
-.advanced-field :deep(.fms-range-picker) {
- width: 100%;
- min-width: 0;
+/* 控件按内容自适应宽度(Input / Select / RangePicker 根节点),带保底宽度 */
+.search-field :deep(.input-wrapper),
+.search-field :deep(.select),
+.search-field :deep(.fms-range-picker) {
+ width: auto;
+ min-width: 160px;
+ max-width: 260px;
}
-.advanced-actions {
- grid-column: 1 / -1;
+/* 内嵌在首字段尾部的小查询按钮(原生 button,避免触发表单内嵌套问题) */
+.search-submit {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border: none;
+ background: none;
+ padding: 2px;
+ color: var(--fms-text-secondary);
+ cursor: pointer;
+}
+
+.search-submit:hover {
+ color: var(--fms-primary);
+}
+
+.search-actions {
display: flex;
- justify-content: flex-end;
+ align-items: center;
gap: 8px;
+ /* 右对齐:按钮落在表单末行右下角,与字段的阅读终点衔接 */
+ margin-left: auto;
}
.demo-table {
flex: 1;
min-height: 0;
+ /* 表头文字对齐 12px 轴线:4px 容器 padding + 表格单元格自带 8px 水平 padding */
+ padding: 0 4px;
/* 行级特殊样式:rowClassName 返回的 class 落在 stk-table 的 tr 上,
这里通过 :deep() 跨过组件边界设置字体颜色与背景色 */
@@ -334,7 +421,8 @@ function onAdvancedReset() {
}
}
-/* ---- 底部分页条:总数靠左,分页靠右 ---- */
+/* ---- 底部分页条:白底,靠 padding 与表格分区(列表卡整体纯白);
+ * 总数靠左,分页靠右 ---- */
.demo-pagination {
display: flex;
align-items: center;
diff --git a/code/fms/fms-vue/src/views/module/i18n-type/index.vue b/code/fms/fms-vue/src/views/module/i18n-type/index.vue
new file mode 100644
index 00000000..0ae35ada
--- /dev/null
+++ b/code/fms/fms-vue/src/views/module/i18n-type/index.vue
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code/fms/fms-vue/src/views/system/menu-management/index.vue b/code/fms/fms-vue/src/views/module/menu-management/index.vue
similarity index 95%
rename from code/fms/fms-vue/src/views/system/menu-management/index.vue
rename to code/fms/fms-vue/src/views/module/menu-management/index.vue
index c94f707f..4f2baa0a 100644
--- a/code/fms/fms-vue/src/views/system/menu-management/index.vue
+++ b/code/fms/fms-vue/src/views/module/menu-management/index.vue
@@ -49,14 +49,38 @@ import { cloneData } from '@/utils/dataChanges'
import { createTempId } from '@/utils/tempId'
import UnsavedChangesModal from '@/components/UnsavedChangesModal.vue'
import I18nNameModal from '@/components/I18nNameModal.vue'
+import { useLanguagesStore } from '@/stores/languages'
-/* ================= 多语言配置 ================= */
-// 菜单多语言:默认语言(简体中文)直接存 b_name;其他语言存 s_i18n(b_key=menu.编码)
-const I18N_LANGUAGES = [
- { code: 'zh-CN', name: '简体中文', default: true },
- { code: 'en-US', name: 'English', default: false },
-]
-const nonDefaultLanguages = I18N_LANGUAGES.filter((l) => !l.default)
+/* ================= 多语言配置(s_i18n_type 驱动) ================= */
+// 菜单多语言:默认语言(b_default=1)名称直接存 b_name;其余语言存 s_i18n(b_key=menu.编码)。
+// 语言清单来自数据库(stores/languages),不再写死 zh-CN/en-US。
+const langStore = useLanguagesStore()
+
+/** 默认语言 code(b_default=1;数据异常时回退第一个启用语言,均为数据库配置) */
+const defaultLocale = computed(() => {
+ const def = langStore.defaultLanguage?.b_code
+ if (def) return def
+ return langStore.languages[0]?.b_code || ''
+})
+
+/** 给 I18nNameModal 的语言列表({ code, name, default }) */
+const I18N_LANGUAGES = computed(() =>
+ langStore.languages.map((l) => ({
+ code: l.b_code,
+ name: l.b_name,
+ default: Number(l.b_default) === 1,
+ })),
+)
+
+/** 非默认语言(走 s_i18n 表,{ code, name }) */
+const nonDefaultLanguages = computed(() =>
+ langStore.nonDefaultLanguages.map((l) => ({ code: l.b_code, name: l.b_name })),
+)
+
+/** 默认语言名称(hint 文案用,动态取自语言配置) */
+const defaultLocaleName = computed(
+ () => langStore.defaultLanguage?.b_name || defaultLocale.value || '',
+)
/* ================= 类型映射 ================= */
const menuTypeOptions = [
@@ -65,12 +89,6 @@ const menuTypeOptions = [
{ label: '外链', value: 'external' },
]
-const menuTypeLabel = {
- directory: '目录',
- page: '页面',
- external: '外链',
-}
-
const menuTypeIconMap = {
directory: Folder,
page: FileText,
@@ -106,11 +124,6 @@ const selectedMenu = computed(() =>
const busy = computed(() => configLoading.value || configSaving.value)
-const parentMenuName = computed(() => {
- if (!selectedMenu.value?.b_parent_id) return ''
- return findTreeNode(menuTreeData.value, selectedMenu.value.b_parent_id)?.b_name || ''
-})
-
const menuType = computed(() => selectedMenu.value?.b_menu_type || null)
const isDirectory = computed(() => menuType.value === 'directory')
const isPage = computed(() => menuType.value === 'page')
@@ -196,7 +209,7 @@ const toolbarAddOptions = [
{ key: 'external', label: '新增外链', icon: ExternalLink },
]
-function onToolbarAdd(key) {
+function onToolbarAdd({ key }) {
const parentId = selectedMenu.value ? String(selectedMenu.value.b_id) : null
void addMenu(parentId, key)
}
@@ -348,8 +361,8 @@ async function addMenu(parentId, menuTypeValue = 'page') {
await nextTick()
drafts.value = cloneData({ menu: newMenu })
originals.value = cloneData(drafts.value)
- i18nValues.value = { 'zh-CN': '' }
- originalI18nValues.value = { 'zh-CN': '' }
+ i18nValues.value = { [defaultLocale.value]: '' }
+ originalI18nValues.value = { [defaultLocale.value]: '' }
powers.value = []
powersBaseline.value = '[]'
loadedMenuId.value = newId
@@ -416,11 +429,12 @@ async function loadMenuConfig(menuId) {
originals.value = { menu: menu ? { ...menu } : null }
drafts.value = cloneData(originals.value)
// 多语言:默认语言复用 b_name,其余读 s_i18n(按 b_module_id 关联)
- const i18nValuesInit = { 'zh-CN': menu?.b_name || '' }
+ const i18nValuesInit = { [defaultLocale.value]: menu?.b_name || '' }
if (menu) {
const i18nRes = await loadDataApi('s_i18n', `b_module_id = ${id}`, 'b_key ASC, b_locale ASC')
for (const row of i18nRes.data || []) {
- if (row.b_locale && row.b_locale !== 'zh-CN') i18nValuesInit[row.b_locale] = row.b_value
+ if (row.b_locale && row.b_locale !== defaultLocale.value)
+ i18nValuesInit[row.b_locale] = row.b_value
}
}
i18nValues.value = i18nValuesInit
@@ -485,7 +499,7 @@ watch(menuSelectedId, (id) => {
}
drafts.value = cloneData({ menu: menuRowOf(node) })
originals.value = cloneData(drafts.value)
- i18nValues.value = { 'zh-CN': node.b_name || '' }
+ i18nValues.value = { [defaultLocale.value]: node.b_name || '' }
originalI18nValues.value = { ...i18nValues.value }
powers.value = []
powersBaseline.value = '[]'
@@ -506,7 +520,9 @@ function hasUnsavedChanges() {
if (JSON.stringify(drafts.value.menu) !== JSON.stringify(originals.value.menu)) return true
// 多语言非默认语言变化视为未保存
if (
- nonDefaultLanguages.some((l) => i18nValues.value[l.code] !== originalI18nValues.value[l.code])
+ nonDefaultLanguages.value.some(
+ (l) => i18nValues.value[l.code] !== originalI18nValues.value[l.code],
+ )
)
return true
// 操作/按钮权限点变化视为未保存
@@ -607,10 +623,7 @@ async function saveMenu() {
)
return false
}
- if (typeRule.module && !menuData.b_module_id) {
- Message.warning('页面菜单必须绑定模块')
- return false
- }
+ // 绑定模块非必填:页面菜单可不绑定业务模块,留空即保存为空
if (!typeRule.route && menuData.b_route) menuData.b_route = null
if (!typeRule.module && menuData.b_module_id) menuData.b_module_id = null
@@ -639,7 +652,7 @@ async function saveMenu() {
// 多语言:先删后插(同表请求内按 del→upd→ins 顺序执行)
const i18nRows = []
- for (const lang of nonDefaultLanguages) {
+ for (const lang of nonDefaultLanguages.value) {
const value = (i18nValues.value[lang.code] || '').trim()
if (!value) continue
i18nRows.push({
@@ -825,7 +838,7 @@ async function saveMenu() {
/* ================= 表单字段更新 ================= */
function setField(field, value) {
if (!drafts.value?.menu) return
- drafts.value.menu[field] = value === '' ? null : value
+ drafts.value.menu[field] = value === '' || value == null ? null : value
}
/** 设置非默认语言的多语言名称 */
@@ -836,15 +849,16 @@ function setI18nValue(locale, value) {
/** 多语言弹窗值对象(默认语言=菜单名称,其余=各语言) */
const i18nModalModel = computed(() => {
const menu = drafts.value?.menu
- const values = { 'zh-CN': menu?.b_name || '' }
- for (const lang of nonDefaultLanguages) values[lang.code] = i18nValues.value[lang.code] || ''
+ const values = { [defaultLocale.value]: menu?.b_name || '' }
+ for (const lang of nonDefaultLanguages.value)
+ values[lang.code] = i18nValues.value[lang.code] || ''
return values
})
/** 多语言弹窗确定时写回草稿与 i18nValues */
function onI18nModalChange(values) {
- if (drafts.value?.menu) setField('b_name', values['zh-CN'] ?? '')
- for (const lang of nonDefaultLanguages) setI18nValue(lang.code, values[lang.code] || '')
+ if (drafts.value?.menu) setField('b_name', values[defaultLocale.value] ?? '')
+ for (const lang of nonDefaultLanguages.value) setI18nValue(lang.code, values[lang.code] || '')
}
function onMenuTypeChange(v) {
@@ -1162,9 +1176,6 @@ loadPowerLibrary()
>
{{ node.b_name || node.b_code || '(未命名)' }}
-
- {{ menuTypeLabel[node.b_menu_type] || '' }}
-
-
-
-
setField('b_route', v)"
/>
-
-
+
+
@@ -1426,7 +1435,7 @@ loadPowerLibrary()
:open="i18nModalVisible"
:languages="I18N_LANGUAGES"
:model-value="i18nModalModel"
- hint="简体中文即「菜单名称」;其余语言保存到多语言表(s_i18n,键 menu.编码)。"
+ :hint="`${defaultLocaleName}即「菜单名称」;其余语言保存到多语言表(s_i18n,键 menu.编码)。`"
@update:model-value="onI18nModalChange"
@update:open="(v) => (i18nModalVisible = v)"
/>
@@ -1579,16 +1588,6 @@ loadPowerLibrary()
}
}
-.mm-tree-node__tag {
- flex-shrink: 0;
- padding: 0 6px;
- border-radius: 3px;
- background: var(--fms-secondary);
- color: var(--fms-text-secondary);
- font-size: 11px;
- line-height: 18px;
-}
-
/* 树节点启用勾选框:靠右、不随文字缩放 */
.mm-tree-node__enable {
flex-shrink: 0;
diff --git a/code/fms/fms-vue/src/views/system/module-management/ModuleAutoCodePanel.vue b/code/fms/fms-vue/src/views/module/module-management/ModuleAutoCodePanel.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/ModuleAutoCodePanel.vue
rename to code/fms/fms-vue/src/views/module/module-management/ModuleAutoCodePanel.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/ModuleBasicPanel.vue b/code/fms/fms-vue/src/views/module/module-management/ModuleBasicPanel.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/ModuleBasicPanel.vue
rename to code/fms/fms-vue/src/views/module/module-management/ModuleBasicPanel.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/ModuleEditPanel.vue b/code/fms/fms-vue/src/views/module/module-management/ModuleEditPanel.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/ModuleEditPanel.vue
rename to code/fms/fms-vue/src/views/module/module-management/ModuleEditPanel.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/ModuleFieldsPanel.vue b/code/fms/fms-vue/src/views/module/module-management/ModuleFieldsPanel.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/ModuleFieldsPanel.vue
rename to code/fms/fms-vue/src/views/module/module-management/ModuleFieldsPanel.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/ModuleI18nPanel.vue b/code/fms/fms-vue/src/views/module/module-management/ModuleI18nPanel.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/ModuleI18nPanel.vue
rename to code/fms/fms-vue/src/views/module/module-management/ModuleI18nPanel.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/ModuleListConfigPanel.vue b/code/fms/fms-vue/src/views/module/module-management/ModuleListConfigPanel.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/ModuleListConfigPanel.vue
rename to code/fms/fms-vue/src/views/module/module-management/ModuleListConfigPanel.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/ModuleQueryConfigPanel.vue b/code/fms/fms-vue/src/views/module/module-management/ModuleQueryConfigPanel.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/ModuleQueryConfigPanel.vue
rename to code/fms/fms-vue/src/views/module/module-management/ModuleQueryConfigPanel.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/FormDesignEditor.vue b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/FormDesignEditor.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/FormDesignEditor.vue
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/FormDesignEditor.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/TableDesignEditor.vue b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/TableDesignEditor.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/TableDesignEditor.vue
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/TableDesignEditor.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/common/EditDataView.vue b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/common/EditDataView.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/common/EditDataView.vue
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/common/EditDataView.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/common/FieldLibrary.vue b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/common/FieldLibrary.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/common/FieldLibrary.vue
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/common/FieldLibrary.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/common/useStructureEditing.js b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/common/useStructureEditing.js
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/common/useStructureEditing.js
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/common/useStructureEditing.js
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/form/FormInspector.vue b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/form/FormInspector.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/form/FormInspector.vue
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/form/FormInspector.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/form/FormPreview.vue b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/form/FormPreview.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/form/FormPreview.vue
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/form/FormPreview.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/form/useFormGrid.js b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/form/useFormGrid.js
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/form/useFormGrid.js
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/form/useFormGrid.js
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/table/StructureTree.vue b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/table/StructureTree.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/table/StructureTree.vue
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/table/StructureTree.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/table/StructureTreeNode.vue b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/table/StructureTreeNode.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/table/StructureTreeNode.vue
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/table/StructureTreeNode.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/table/TableInspector.vue b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/table/TableInspector.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/table/TableInspector.vue
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/table/TableInspector.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/design-editor/table/TablePreview.vue b/code/fms/fms-vue/src/views/module/module-management/components/design-editor/table/TablePreview.vue
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/design-editor/table/TablePreview.vue
rename to code/fms/fms-vue/src/views/module/module-management/components/design-editor/table/TablePreview.vue
diff --git a/code/fms/fms-vue/src/views/system/module-management/components/fieldDefaults.js b/code/fms/fms-vue/src/views/module/module-management/components/fieldDefaults.js
similarity index 100%
rename from code/fms/fms-vue/src/views/system/module-management/components/fieldDefaults.js
rename to code/fms/fms-vue/src/views/module/module-management/components/fieldDefaults.js
diff --git a/code/fms/fms-vue/src/views/system/module-management/index.vue b/code/fms/fms-vue/src/views/module/module-management/index.vue
similarity index 98%
rename from code/fms/fms-vue/src/views/system/module-management/index.vue
rename to code/fms/fms-vue/src/views/module/module-management/index.vue
index 81f7818d..9b639638 100644
--- a/code/fms/fms-vue/src/views/system/module-management/index.vue
+++ b/code/fms/fms-vue/src/views/module/module-management/index.vue
@@ -66,6 +66,7 @@ import ModuleEditPanel from './ModuleEditPanel.vue'
import ModuleQueryConfigPanel from './ModuleQueryConfigPanel.vue'
import ModuleAutoCodePanel from './ModuleAutoCodePanel.vue'
import ModuleI18nPanel from './ModuleI18nPanel.vue'
+import { useLanguagesStore } from '@/stores/languages'
/* ================= 共享状态(index.vue 组装后传入各 composable) ================= */
const moduleTreeData = ref([])
@@ -90,6 +91,18 @@ const rawI18nRows = ref([])
// 新建模块时跳过 watch(moduleSelectedId) 的自动加载;非响应式 holder,跨 composable 共享
const skipModuleLoad = { value: false }
+/* ================= 多语言配置(s_i18n_type 驱动) ================= */
+// ModuleI18nPanel 的语言列表:由 languages store 提供,不再写死 zh-CN/en-US
+const langStore = useLanguagesStore()
+/** 语言列表({ code, name, default },供 ModuleI18nPanel) */
+const i18nLangOptions = computed(() =>
+ langStore.languages.map((l) => ({
+ code: l.b_code,
+ name: l.b_name,
+ default: Number(l.b_default) === 1,
+ })),
+)
+
/* ================= 派生状态(index.vue 组装) ================= */
const selectedModule = computed(() =>
moduleSelectedId.value ? findTreeNode(moduleTreeData.value, moduleSelectedId.value) : null,
@@ -1186,6 +1199,7 @@ loadModuleTree()
:fields="drafts?.fields"
:groups="drafts?.groups"
:raw-rows="rawI18nRows"
+ :languages="i18nLangOptions"
:loading="busy"
/>
diff --git a/code/fms/fms-vue/src/views/tmp-dnd-panel.vue b/code/fms/fms-vue/src/views/tmp-dnd-panel.vue
index 41f65a3b..120df10d 100644
--- a/code/fms/fms-vue/src/views/tmp-dnd-panel.vue
+++ b/code/fms/fms-vue/src/views/tmp-dnd-panel.vue
@@ -1,6 +1,6 @@