20260911173133

This commit is contained in:
oneao committed 2026-09-11 17:31:34 +08:00
1 parent 3838ed74b1
commit f3ad727f1c
60 files changed
+4971 -6621

No files matched your search

@@ -3,7 +3,7 @@
* FmsModuleEditModal —— 元数据驱动的通用新增/编辑弹窗。
*
* 与 FmsModuleListPage 同族:传 data-code,组件按模块元数据自动渲染编辑表单,
* 字段/分组/校验/控件类型全部来自数据库(s_field_edit + s_field_group + s_field)。
* 字段/分组/校验/控件类型全部来自数据库(s_module_schema.edit JSON + s_field)。
*
* 渲染结构对齐表单设计器的 FormPreview(组内 24 栅格):
* Form(columns=24) → FormGroup(span=整行, 组内 24 栅格) → FormItem(span=b_colspan)
@@ -37,6 +37,7 @@ import { loadDataApi, loadDataBySqlApi, nextIdApi, saveObjectApi } from '@/servi
import { diffRow } from '@/utils/dataChanges'
import { identifierRe, isEmptyValue } from '@/components/fms-module-common/queryUtils'
import { parseOptions } from '@/components/fms-module-common/fieldUtils'
import { loadModuleSchemas, buildEditRender } from '@/components/fms-module-common/schemaRender'
const props = defineProps({
/** 受控打开 */
@@ -65,8 +66,8 @@ const saving = ref(false)
const configError = ref('')
const moduleMeta = ref(null) // s_module 行
const fields = ref([]) // s_field
const groups = ref([]) // s_field_group
const editRows = ref([]) // s_field_edit 可见行(含关联字段引用)
const groups = ref([]) // 编辑分组节点(由 edit JSON 还原)
const editRows = ref([]) // 编辑行(由 edit JSON 还原,含关联字段引用)
const formData = ref({})
const keyField = ref('b_id')
/** 编辑基线(origin):打开弹窗时对 record 深拷贝快照,保存只提交与它的差异;新建模式为 null */
@@ -141,24 +142,18 @@ async function loadConfig() {
if (!module) throw new Error(`未找到编码为 ${code} 的启用数据模块`)
const moduleId = String(module.b_id)
// 字符串业务键:模块与字段/布局行均以编码/列名字符串关联
const [fieldRes, editRes, groupRes] = await Promise.all([
loadDataApi('s_field', `b_module_id = N'${moduleId.replaceAll("'", "''")}'`, 'b_xh ASC, b_field ASC'),
// 字段(s_field)+ 编辑界面配置(s_module_schema.edit JSON)
const [fieldRes, schemas] = await Promise.all([
loadDataApi(
's_field_edit',
's_field',
`b_module_id = N'${moduleId.replaceAll("'", "''")}'`,
'b_xh ASC, b_field ASC',
),
loadDataApi(
's_field_group',
`b_module_id = N'${moduleId.replaceAll("'", "''")}'`,
'b_xh ASC, b_id ASC',
),
loadModuleSchemas(moduleId),
])
moduleMeta.value = module
keyField.value = module.b_keyfield || 'b_id'
groups.value = groupRes.data || []
keyField.value = module.b_key_field || 'b_id'
// 关联字段信息(字段身份 = 字段列名 b_field)
const fieldByField = new Map()
@@ -170,9 +165,11 @@ async function loadConfig() {
}
fields.value = validFields
// 只保留可见行并注入字段对象
// edit JSON → 分组 + 编辑行;只保留可见行并注入字段对象
const render = buildEditRender(schemas.edit)
groups.value = render.groups
const rows = []
for (const row of editRes.data || []) {
for (const row of render.rows) {
if (Number(row.b_visible) !== 1) continue
const field = fieldByField.get(String(row.b_field))
if (!field) continue
@@ -204,10 +201,10 @@ function buildFormData() {
data[fieldName] = existing
} else if (row.field.b_type === 'checkbox') {
data[fieldName] = 0
} else if (isEmptyValue(row.field.b_default_value)) {
} else if (isEmptyValue(row.b_default_value)) {
data[fieldName] = row.field.b_type === 'number' || row.field.b_type === 'money' ? null : ''
} else {
data[fieldName] = row.field.b_default_value
data[fieldName] = row.b_default_value
}
}
formData.value = data
@@ -294,9 +291,9 @@ const resolvedWidth = computed(() => {
/** 保存过程上下文:beforeSave 阶段准备的数据,buildSaveData / afterSave 阶段消费 */
let saveCtx = { isNew: false, row: null, extraUpdates: [] }
/** 模块保存表(s_module.b_savetable 优先,其次 b_viewtable) */
/** 模块保存表(s_module.b_save_table 优先,其次 b_view_table) */
function saveTableName() {
return String(moduleMeta.value?.b_savetable || moduleMeta.value?.b_viewtable || '')
return String(moduleMeta.value?.b_save_table || moduleMeta.value?.b_view_table || '')
}
/** 构造完整合并行(含主键;checkbox→0/1、''→null 归一化),供保存前准备与 diff 使用 */
@@ -321,7 +318,7 @@ function collectRowData() {
/** 保存前校验、数据准备与业务钩子;返回 false 终止保存 */
async function beforeSave() {
// 必填校验:s_field_edit.b_required=1 且值为空 → 提示并定位
// 必填校验:编辑节点 required 且值为空 → 提示并定位
for (const editRow of editableRows.value) {
if (Number(editRow.b_required) !== 1) continue
if (editRow.field.b_type === 'checkbox') continue
@@ -346,7 +343,7 @@ async function beforeSave() {
!Number(row[props.orderField])
) {
try {
const viewTable = String(moduleMeta.value?.b_viewtable || '')
const viewTable = String(moduleMeta.value?.b_view_table || '')
if (viewTable) {
const res = await loadDataBySqlApi(
`SELECT ISNULL(MAX([${props.orderField}]), 0) AS mx FROM [${viewTable}]`,