Merge pull request 'zh' (#1) from zh into main

Reviewed-on: #1
This commit is contained in:
2026-02-09 00:39:20 +08:00
6 changed files with 506 additions and 26 deletions

View File

@@ -135,6 +135,7 @@ const amountObj=ref<any>({})
const crudRef = ref() const crudRef = ref()
const dimensionFields=ref<any>({}) const dimensionFields=ref<any>({})
const exportLoading = ref(false) const exportLoading = ref(false)
const fieldList = ref<any[]>([]) // 添加fieldList引用
const permissions = const permissions =
wsCache.get(CACHE_KEY.USER).lideeYunjipermissions?.[route.meta.menuDataId as string] || false wsCache.get(CACHE_KEY.USER).lideeYunjipermissions?.[route.meta.menuDataId as string] || false
const selectIds = computed(() => { const selectIds = computed(() => {
@@ -167,7 +168,11 @@ const summaryMethod1=({columns,data})=>{
const initTable = async () => { const initTable = async () => {
isInit.value = false isInit.value = false
loading.value = true loading.value = true
const { fieldList, reportVo } = await ReportApi.getWebConfig(props.reportCode) const { fieldList: apiFieldList, reportVo } = await ReportApi.getWebConfig(props.reportCode)
// 存储字段列表到响应式引用
fieldList.value = apiFieldList
const isHeight = reportVo.tableConfig?.includes('height') const isHeight = reportVo.tableConfig?.includes('height')
const isPage = reportVo.dataConfig?.includes('page') const isPage = reportVo.dataConfig?.includes('page')
const isPermi = reportVo.dataConfig?.includes('authTrue') const isPermi = reportVo.dataConfig?.includes('authTrue')
@@ -188,12 +193,37 @@ const initTable = async () => {
column: {} column: {}
} }
//国际化处理 //国际化处理
const fieldLengObj = assembleLengObj(fieldList, 'labelI18n', 'fieldCode', 'fieldName') const fieldLengObj = assembleLengObj(apiFieldList, 'labelI18n', 'fieldCode', 'fieldName')
for (const key in fieldLengObj) { for (const key in fieldLengObj) {
mergeLocaleMessage(key, { [props.reportCode]: fieldLengObj[key] }) mergeLocaleMessage(key, { [props.reportCode]: fieldLengObj[key] })
} }
//字段处理
fieldList.forEach((item,index) => { // 根据parentFieldCode判断表头结构
const hasSubFields = Array.isArray(apiFieldList) && apiFieldList.some(field => field.parentFieldCode && field.parentFieldCode !== '')
// 构建父子关系映射
const parentChildMap = new Map()
const childParentMap = new Map()
// 建立映射关系
apiFieldList.forEach(field => {
if (field.parentFieldCode && field.parentFieldCode !== '') {
// 这是子字段
childParentMap.set(field.fieldCode, field.parentFieldCode)
if (!parentChildMap.has(field.parentFieldCode)) {
parentChildMap.set(field.parentFieldCode, [])
}
parentChildMap.get(field.parentFieldCode).push(field.fieldCode)
}
})
//字段处理 - 构建正确的表头结构
apiFieldList.forEach((item, index) => {
// 跳过子字段,子字段会在父字段中处理
if (item.parentFieldCode && item.parentFieldCode !== '') {
return
}
const config: any = { const config: any = {
prop: item.fieldCode, prop: item.fieldCode,
label: t(`${props.reportCode}.${item.fieldCode}`), label: t(`${props.reportCode}.${item.fieldCode}`),
@@ -203,6 +233,24 @@ const initTable = async () => {
sortable: item.isShowSort == 'Y' ? 'custom' : false, sortable: item.isShowSort == 'Y' ? 'custom' : false,
search: item.queryIsWeb == 'Y', search: item.queryIsWeb == 'Y',
} }
// 如果该字段有子字段,添加子列配置
if (parentChildMap.has(item.fieldCode)) {
const childFields = parentChildMap.get(item.fieldCode)
config.children = childFields.map(childFieldCode => {
const childField = apiFieldList.find(f => f.fieldCode === childFieldCode)
return {
prop: childField.fieldCode,
label: t(`${props.reportCode}.${childField.fieldCode}`),
type: 'input',
overHidden: true,
isExport: childField.isExport == 'Y',
sortable: childField.isShowSort == 'Y' ? 'custom' : false,
search: childField.queryIsWeb == 'Y'
}
})
}
if(!!item.isAmount){ if(!!item.isAmount){
index==0?amountFieds.value.fistField=config.prop:'' index==0?amountFieds.value.fistField=config.prop:''
amountFieds.value[item.isAmount]=config amountFieds.value[item.isAmount]=config
@@ -320,7 +368,31 @@ const getTableData = async (isLoading = true) => {
try { try {
const data = await ReportApi.getTableList(props.reportCode, searchObj) const data = await ReportApi.getTableList(props.reportCode, searchObj)
if (tablePage.value) tablePage.value['total'] = data.total if (tablePage.value) tablePage.value['total'] = data.total
tableData.value = data.records
// 处理包含子字段的数据
let processedData = data.records
// 根据字段配置判断是否需要处理子字段
const hasSubFields = Array.isArray(fieldList.value) && fieldList.value.length > 0 &&
fieldList.value.some(field => field.parentFieldCode && field.parentFieldCode !== '')
if (hasSubFields) {
processedData = data.records.map(record => {
const flatRecord = { ...record }
// 处理子字段数据
fieldList.value.forEach(field => {
if (field.parentFieldCode && field.parentFieldCode !== '') {
// 这是子字段,从父字段中提取数据
const parentData = record[field.parentFieldCode]
if (parentData && typeof parentData === 'object') {
flatRecord[field.fieldCode] = parentData[field.fieldCode]
}
}
})
return flatRecord
})
}
tableData.value = processedData
// amountFieds.value={ // amountFieds.value={
// 'thissaqty_s':{ // 'thissaqty_s':{
// prop:'thissaqty', // prop:'thissaqty',

View File

@@ -164,7 +164,21 @@ export const useRenderVxeColumn = (useType = 'table') => {
multiple={multiple} multiple={multiple}
filterable={filterable} filterable={filterable}
allowCreate={allowCreate} allowCreate={allowCreate}
onChange={() => renderOpts.events ? renderOpts.events.change(row, column.field, rowIndex) : ''} clearable={true}
onChange={(value) => {
// 先更新行数据
row[column.field] = value
// 再触发自定义事件
if (renderOpts.events && renderOpts.events.change) {
renderOpts.events.change(row, column.field, rowIndex)
}
}}
onClear={() => {
// 触发清空事件
if (renderOpts.events && renderOpts.events.clear) {
renderOpts.events.clear(row, column.field, rowIndex)
}
}}
/> />
) )
} }

View File

@@ -45,7 +45,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { SqlOption, InfoVxeTable, InfoVxeTopBtn } from '../../tableDesign/components' import { SqlOption, InfoVxeTable, InfoVxeTopBtn } from '../../tableDesign/components'
import { MonacoEditor } from '@/components/MonacoEditor/index' import { MonacoEditor } from '@/components/MonacoEditor/index'
import { tableInfoOption } from '../designData' import { tableInfoOption, dicObj } from '../designData'
import { formattingLengStr } from '@/utils/lowDesign' import { formattingLengStr } from '@/utils/lowDesign'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import * as DictDataApi from '@/api/system/dict/dict.type' import * as DictDataApi from '@/api/system/dict/dict.type'
@@ -83,6 +83,9 @@ const optionComponents = markRaw({
const optionRef = ref({}) const optionRef = ref({})
const tabsRef = ref() const tabsRef = ref()
// 父字段引用
const parentFieldMap = ref(new Map())
const fieldList = computed(() => { const fieldList = computed(() => {
let dicData: Array<{ label: string; value: string; type: string }> = [] let dicData: Array<{ label: string; value: string; type: string }> = []
infoData.value.basics.forEach((item) => { infoData.value.basics.forEach((item) => {
@@ -113,6 +116,7 @@ const dorpdownHandleCommand = (command) => {
nextTick(() => infoData.value[dataKey].splice(type == 'up' ? index - 1 : index + 1, 0, delItem)) nextTick(() => infoData.value[dataKey].splice(type == 'up' ? index - 1 : index + 1, 0, delItem))
} else if (type == 'add') cellAddData(index + 1) } else if (type == 'add') cellAddData(index + 1)
} }
const setInfoOrder = () => { const setInfoOrder = () => {
let { dataKey } = tabsValue.value let { dataKey } = tabsValue.value
if (!dataKey) return if (!dataKey) return
@@ -182,16 +186,82 @@ const tableScrollIndex = (key, index, addIndex?) => {
const cellClick = ({ rowIndex }) => { const cellClick = ({ rowIndex }) => {
let { prop } = tabsValue.value let { prop } = tabsValue.value
// 普通行点击进入编辑状态
tableRefObj.value[prop].vxeTableRef.setEditRow( tableRefObj.value[prop].vxeTableRef.setEditRow(
tableRefObj.value[prop].vxeTableRef.getData(rowIndex) tableRefObj.value[prop].vxeTableRef.getData(rowIndex)
) )
} }
// 添加子字段行
const addSubFieldRow = (parentField, parentRowIndex) => {
let { key, dataKey } = tabsValue.value
if (!dataKey) return
// 创建子字段数据
let subFieldData = cloneDeep(tableInfoOption.infoDefaultData[dataKey]) || {}
subFieldData.parentFieldId = parentField._X_ROW_KEY
subFieldData.isSubField = true
subFieldData.parentFieldName = parentField.fieldName
parentField.hasChildren = 'Y'
// 确保子字段不能包含子字段
subFieldData.hasChildren = 'N'
// 在父字段下方插入子字段行
let insertIndex = parentRowIndex + 1
infoData.value[dataKey].splice(insertIndex, 0, subFieldData)
// 记录父子关系
parentFieldMap.value.set(subFieldData._X_ROW_KEY, parentField._X_ROW_KEY)
// 滚动到新添加的行并设置为编辑状态
tableScrollIndex(key, insertIndex, insertIndex)
// 给出成功提示
nextTick(() => {
message.success(`已为字段 "${parentField.fieldName}" 添加子字段`)
})
}
const initEditInfoData = () => { const initEditInfoData = () => {
const data = tableInfoOption.formattingInitData(props.editInfoData) const data = tableInfoOption.formattingInitData(props.editInfoData)
const fieldList: any[] = [] const fieldList: any[] = []
// 重建父子字段关系
const fieldCodeMap = new Map()
// 第一遍遍历:建立字段编码映射
data.infoData.forEach((item, index) => {
if (item.fieldCode) {
fieldCodeMap.set(item.fieldCode, { ...item, originalIndex: index })
}
})
// 第二遍遍历:处理子字段关系
data.infoData.forEach((item) => {
const fieldItem = cloneDeep(item)
// 如果是子字段且有父字段编码
if (fieldItem.parentFieldCode && fieldCodeMap.has(fieldItem.parentFieldCode)) {
fieldItem.isSubField = true
fieldItem.parentFieldId = fieldCodeMap.get(fieldItem.parentFieldCode)._X_ROW_KEY
// 设置父字段显示名称(只显示字段名称)
const parentField = fieldCodeMap.get(fieldItem.parentFieldCode)
fieldItem.parentFieldName = parentField.fieldName
// 记录父子关系
parentFieldMap.value.set(fieldItem._X_ROW_KEY, fieldItem.parentFieldId)
}
// 如果字段包含子字段,设置相应标识
if (fieldItem.hasChildren === 'Y') {
fieldItem.hasChildren = 'Y'
}
fieldList.push(fieldItem)
})
tableInfoDefault.value = data.infoData.filter((item) => { tableInfoDefault.value = data.infoData.filter((item) => {
fieldList.push(cloneDeep(item))
return false return false
}) })
infoData.value.basics = fieldList infoData.value.basics = fieldList
@@ -201,8 +271,9 @@ onMounted(() => {
tableInfoDefault.value = [] tableInfoDefault.value = []
infoData.value.basics = [] infoData.value.basics = []
if (props.formType != 'add') initEditInfoData() if (props.formType != 'add') initEditInfoData()
const { fieldColumn } = tableInfoOption.infoColumn
fieldColumn.labelI18n.editRender.events = { // 设置字段国际化配置的点击事件
tableInfoOption.infoColumn.fieldColumn.labelI18n.editRender.events = {
click: (row) => { click: (row) => {
nextTick(() => { nextTick(() => {
tableRefObj.value['tab_field'].vxeTableRef.setRow(row, { tableRefObj.value['tab_field'].vxeTableRef.setRow(row, {
@@ -211,14 +282,216 @@ onMounted(() => {
}) })
} }
} }
// 设置父字段下拉选项
const updateParentFieldOptions = () => {
// 获取所有parentFieldCode为空的字段作为可选父字段
const parentFieldOptions = infoData.value.basics
.filter(field => !field.parentFieldCode && field.fieldCode && field.fieldName)
.map(field => ({
label: `${field.fieldName}`,
value: field.fieldCode
}))
// 更新父字段列的下拉选项
tableInfoOption.infoColumn.fieldColumn.parentFieldName.editRender.dicData = parentFieldOptions
}
// 用于跟踪上次选中的值,避免重复触发
let _lastSelectedValue = ''
// 父字段选择事件处理
tableInfoOption.infoColumn.fieldColumn.parentFieldName.editRender.events = {
// 简化的change事件处理
change: (row) => {
console.log('父字段选择change事件触发:', row.parentFieldName);
const selectdItem = row.parentFieldName.item;
if(!selectdItem) return;
// 获取选中的字段编码
let selectedParentCode = selectdItem.value;
console.log('选中的值:', selectedParentCode);
_lastSelectedValue = selectedParentCode;
if (selectedParentCode && selectedParentCode.trim() !== '') {
// 检查是否在有效选项中
const isValidOption = infoData.value.basics.some(field =>
field.fieldCode === selectedParentCode && !field.parentFieldCode
);
if (isValidOption) {
handleParentFieldSelection(row, selectedParentCode);
} else {
console.log('无效的选项:', selectedParentCode);
// 重置无效选择
row.parentFieldName = '';
row.parentFieldCode = '';
row.parentFieldId = '';
row.isSubField = false;
_lastSelectedValue = '';
}
} else {
// 清空选择
handleParentFieldClear(row);
_lastSelectedValue = '';
}
// 更新父字段选项
updateParentFieldOptions();
},
// 添加clear事件专门处理清空操作
clear: (row) => {
console.log('父字段清空事件触发');
handleParentFieldClear(row);
_lastSelectedValue = '';
updateParentFieldOptions();
}
}
// 处理父字段选择
const handleParentFieldSelection = (row, selectedParentCode) => {
// 找到选中的父字段
const parentField = infoData.value.basics.find(field => field.fieldCode === selectedParentCode);
if (!parentField) return;
// 检查是否形成循环引用
if (checkCircularReference(row, parentField)) {
message.warning('不能形成循环引用!');
// 先清空显示值再x用清空处理函数
handleParentFieldClear(row);
// 强制刷新表格以确保UI更新
nextTick(() => {
if (tableRefObj.value && tableRefObj.value['tab_field'] && tableRefObj.value['tab_field'].vxeTableRef) {
tableRefObj.value['tab_field'].vxeTableRef.refreshColumn();
}
});
return;
}
// 保存旧的父字段信息用于清理
const oldParentFieldCode = row.parentFieldCode;
// 设置当前字段的父子关系
row.parentFieldCode = selectedParentCode;
row.parentFieldId = parentField._X_ROW_KEY;
row.isSubField = true;
row.parentFieldName = parentField.fieldName; // 显示选中的字段名称
// 设置父字段的hasChildren为'Y'
parentField.hasChildren = 'Y';
// 清理旧父字段的关系
if (oldParentFieldCode && oldParentFieldCode !== selectedParentCode) {
const oldParentField = infoData.value.basics.find(field => field.fieldCode === oldParentFieldCode);
if (oldParentField) {
const hasOtherChildren = infoData.value.basics.some(child =>
child.parentFieldCode === oldParentFieldCode && child !== row
);
if (!hasOtherChildren) {
oldParentField.hasChildren = 'N';
}
}
}
message.success(`已将 "${row.fieldName}" 设置为 "${parentField.fieldName}" 的子字段`);
};
// 处理父字段清空
const handleParentFieldClear = (row) => {
const oldParentFieldCode = row.parentFieldCode;
// 清空所有父子关系相关字段
row.parentFieldCode = '';
row.parentFieldId = '';
row.parentFieldName = '';
row.isSubField = false;
// 清理旧父字段的关系
if (oldParentFieldCode) {
const oldParentField = infoData.value.basics.find(field => field.fieldCode === oldParentFieldCode);
if (oldParentField) {
const hasOtherChildren = infoData.value.basics.some(child =>
child.parentFieldCode === oldParentFieldCode && child !== row
);
if (!hasOtherChildren) {
oldParentField.hasChildren = 'N';
}
}
}
};
// 检查循环引用
const checkCircularReference = (childField, parentField) => {
// 如果子字段本身就是父字段,则不允许
if (childField.fieldCode === parentField.fieldCode) {
return true
}
// 检查父字段是否已经是该子字段的子字段
let currentParent = parentField
while (currentParent && currentParent.parentFieldCode) {
if (currentParent.parentFieldCode === childField.fieldCode) {
return true
}
currentParent = infoData.value.basics.find(field => field.fieldCode === currentParent.parentFieldCode)
}
return false
}
// 监听数据变化,更新父字段选项
watch(() => infoData.value.basics, updateParentFieldOptions, { deep: true })
// 监听字段名称变化,同步更新父字段显示
watch(() => infoData.value.basics, (newBasics) => {
newBasics.forEach(field => {
if (field.parentFieldCode) {
const parentField = newBasics.find(f => f.fieldCode === field.parentFieldCode)
if (parentField) {
// 更新为被选择字段的fieldName
field.parentFieldName = parentField.fieldName
}
}
})
updateParentFieldOptions()
}, { deep: true })
// 初始化父字段选项
updateParentFieldOptions()
// 设置字典Code的下拉选项
DictDataApi.getSimpleDictTypeList().then((dicData) => { DictDataApi.getSimpleDictTypeList().then((dicData) => {
const dicObj = {} const dicObj = {}
dicData = dicData.map(({ type, name }) => { dicData = dicData.map(({ type, name }) => {
dicObj[type] = `${type}${name}` dicObj[type] = `${type}${name}`
return { label: dicObj[type], value: type } return { label: dicObj[type], value: type }
}) })
Object.assign(fieldColumn.dictCode.editRender, { dicData, dicObj }) Object.assign(tableInfoOption.infoColumn.fieldColumn.dictCode.editRender, { dicData, dicObj })
}) })
// 为主字段列添加点击事件处理添加子字段按钮
tableInfoOption.infoColumn.fieldColumn.hasChildren.editRender.events = {
click: (row) => {
// 子字段不显示按钮,这个检查主要是保险
if (row.isSubField === true) {
return
}
// 获取当前行的索引
const currentIndex = infoData.value.basics.findIndex(item => item._X_ROW_KEY === row._X_ROW_KEY)
if (currentIndex !== -1) {
addSubFieldRow(row, currentIndex)
}
}
}
// 动态控制包含子字段选项的禁用状态
tableInfoOption.infoColumn.fieldColumn.hasChildren.editRender.disabled = (row) => {
// 子字段不能包含子字段
return row.isSubField === true
}
}) })
defineExpose({ defineExpose({
@@ -228,7 +501,8 @@ defineExpose({
tableRefObj, tableRefObj,
setTabsValue, setTabsValue,
tableScrollIndex, tableScrollIndex,
initEditInfoData initEditInfoData,
parentFieldMap
}) })
</script> </script>
@@ -238,6 +512,22 @@ defineExpose({
left: 20px !important; left: 20px !important;
} }
} }
// 为子字段的子字段列添加特殊样式
::v-deep(.field-vxe-table) {
.vxe-body--column {
&[field="hasChildren"] {
.vxe-cell {
// 为子字段添加视觉提示
.is-sub-field {
text-align: center;
color: #909399;
font-size: 14px;
}
}
}
}
}
</style> </style>
<style lang="scss" scoped> <style lang="scss" scoped>
::v-deep(.virtual-hide-row) { ::v-deep(.virtual-hide-row) {

View File

@@ -149,6 +149,7 @@ const infoColumn = {
fieldColumn: { fieldColumn: {
fieldCode: { title: '字段编码', minWidth: 120, editRender: { name: 'LowInput', verifyEdit: true } }, fieldCode: { title: '字段编码', minWidth: 120, editRender: { name: 'LowInput', verifyEdit: true } },
fieldName: { title: '字段名称', minWidth: 120, editRender: { name: 'LowInput' } }, fieldName: { title: '字段名称', minWidth: 120, editRender: { name: 'LowInput' } },
parentFieldName: { title: '父字段名称', width: 120, editRender: { name: 'LowSelect', dicData: [], filterable: true, clearable: true } },
labelI18n: { title: '国际化配置', width: 140, editRender: { name: 'LowMonacoEditorInput', events: {} } }, labelI18n: { title: '国际化配置', width: 140, editRender: { name: 'LowMonacoEditorInput', events: {} } },
fieldType: { title: '字段类型', minWidth: 100, editRender: { name: 'LowSelect', verifyEdit: true, dicData: dicObj.fieldType, dicObj: getDicObj('fieldType') } }, fieldType: { title: '字段类型', minWidth: 100, editRender: { name: 'LowSelect', verifyEdit: true, dicData: dicObj.fieldType, dicObj: getDicObj('fieldType') } },
queryIsDb: { title: '接口查询', width: 75, align: "center", editRender: { name: 'LowCheckbox' } }, queryIsDb: { title: '接口查询', width: 75, align: "center", editRender: { name: 'LowCheckbox' } },
@@ -160,6 +161,7 @@ const infoColumn = {
isDimension: { title: '是否维度', width: 75, align: "center", editRender: { name: 'LowCheckbox' } }, isDimension: { title: '是否维度', width: 75, align: "center", editRender: { name: 'LowCheckbox' } },
isShowSort: { title: '是否排序', width: 75, align: "center", editRender: { name: 'LowCheckbox' } }, isShowSort: { title: '是否排序', width: 75, align: "center", editRender: { name: 'LowCheckbox' } },
hasChildren: { title: '子字段', width: 90, align: "center", editRender: { name: 'LowButton', disabled: (row) => row.isSubField === true, buttonText: '添加子字段', buttonType: 'primary', buttonSize: 'small' } },
}, },
} }
@@ -168,7 +170,16 @@ const apiKey = { fieldColumn: 'fieldList' }
for (const key in infoColumn) { for (const key in infoColumn) {
if (apiKey[key]) { if (apiKey[key]) {
const keys = Object.keys(infoColumn[key]) const keys = Object.keys(infoColumn[key])
if (key == 'fieldColumn') keys.push('sortNum') if (key == 'fieldColumn') {
keys.push('sortNum')
// 确保父子关系字段被包含
if (!keys.includes('parentFieldCode')) {
keys.push('parentFieldCode')
}
if (!keys.includes('hasChildren')) {
keys.push('hasChildren')
}
}
infoApiKey[apiKey[key]] = keys infoApiKey[apiKey[key]] = keys
} }
} }
@@ -176,7 +187,7 @@ for (const key in infoColumn) {
//默认值 //默认值
const infoDefaultData = { const infoDefaultData = {
basics: { basics: {
fieldCode: '', fieldName: '', labelI18n: '', fieldType: 'String', queryIsDb: 'N', queryIsWeb: 'N', queryMode: 'LIKE', dictCode: '', isExport: 'Y', isShowSort: 'N',isAmount:'',isDimension:'' fieldCode: '', fieldName: '', parentFieldName: '', labelI18n: '', fieldType: 'String', queryIsDb: 'N', queryIsWeb: 'N', queryMode: 'LIKE', dictCode: '', isExport: 'Y', isShowSort: 'N', isAmount: '', isDimension: '', hasChildren: 'N', isSubField: false, parentFieldId: '', parentFieldCode: '',
}, },
} }

View File

@@ -330,6 +330,21 @@ const tableFormVerify = (type) => {
filedData.splice(item.sortNum || 999, 0, item) filedData.splice(item.sortNum || 999, 0, item)
}) })
// 先进行hasChildren一致性检查
filedData.forEach(currentItem => {
if (currentItem.hasChildren === 'Y') {
// 检查是否存在子字段parentFieldCode等于当前字段的fieldCode
const hasChildFields = filedData.some(childItem =>
childItem.parentFieldCode === currentItem.fieldCode
)
// 如果没有子字段则将hasChildren设为'N'
if (!hasChildFields) {
currentItem.hasChildren = 'N'
}
}
})
for (const i in filedData) { for (const i in filedData) {
const index = Number(i) const index = Number(i)
const item = filedData[index] const item = filedData[index]
@@ -337,12 +352,31 @@ const tableFormVerify = (type) => {
let messageText = '' let messageText = ''
let tabKey = 'mysql' let tabKey = 'mysql'
if (!item.fieldCode || !item.fieldName) { // 子字段不能再包含子字段
if (item.isSubField && item.hasChildren === 'Y') {
debugger
messageText = `<div style="line-height:24px"> messageText = `<div style="line-height:24px">
<div>${!item.fieldCode ? '字段编码' : '字段名称'}必须填写</div> <div>子字段不能包含子字段</div>
<div>序号:${index + 1}</div> <div>序号:${index + 1}</div>
</div>` </div>`
} }
// 当不包含子字段时,字段编码和字段名称必须填写
else if (item.hasChildren !== 'Y') {
if (!item.fieldCode || !item.fieldName) {
messageText = `<div style="line-height:24px">
<div>${!item.fieldCode ? '字段编码' : '字段名称'}必须填写</div>
<div>序号:${index + 1}</div>
</div>`
}
} else {
// 包含子字段时,字段名称必须填写
if (!item.fieldName) {
messageText = `<div style="line-height:24px">
<div>字段名称必须填写</div>
<div>序号:${index + 1}</div>
</div>`
}
}
if (fieldCodeArr.includes(item.fieldCode)) { if (fieldCodeArr.includes(item.fieldCode)) {
messageText = `<div style="line-height:24px"> messageText = `<div style="line-height:24px">
<div> <div>
@@ -353,15 +387,18 @@ const tableFormVerify = (type) => {
</div>` </div>`
} }
fieldCodeArr.push(item.fieldCode) fieldCodeArr.push(item.fieldCode)
if (!/(^[a-zA-Z]{2}(_?[a-zA-Z0-9])*_?$)/.test(item.fieldCode)) { // 当不包含子字段时才验证字段编码格式
messageText = `<div style="line-height:24px"> if (item.hasChildren !== 'Y' && item.fieldCode) {
<div> if (!/(^[a-zA-Z]{2}(_?[a-zA-Z0-9])*_?$)/.test(item.fieldCode)) {
<span>字段编码不符合规范</span> messageText = `<div style="line-height:24px">
<span style="color:red">${item.fieldCode}</span> <div>
</div> <span>字段编码不符合规范</span>
<div>命名规则:只能由字母、数字、下划线组成;必须以字母开头;不能以单个字母加下滑线开头</div> <span style="color:red">${item.fieldCode}</span>
<div>序号:${index + 1}</div> </div>
</div>` <div>命名规则:只能由字母、数字、下划线组成;必须以字母开头;不能以单个字母加下滑线开头</div>
<div>序号:${index + 1}</div>
</div>`
}
} }
if (messageText) { if (messageText) {
@@ -379,6 +416,20 @@ const tableFormVerify = (type) => {
}) })
if (key == 'fieldList') { if (key == 'fieldList') {
itemObj.labelI18n = formattingLengStr(itemObj.labelI18n, itemObj.fieldName) itemObj.labelI18n = formattingLengStr(itemObj.labelI18n, itemObj.fieldName)
// 为子字段添加父字段编码信息
if (item.isSubField && item.parentFieldId) {
// 查找父字段的编码
const parentField = filedData.find(field => field._X_ROW_KEY === item.parentFieldId)
if (parentField && parentField.fieldCode) {
itemObj.parentFieldCode = parentField.fieldCode
}
}
// 为父字段添加是否包含子字段的标识
if (item.hasChildren === 'Y') {
itemObj.hasChildren = 'Y'
} else {
itemObj.hasChildren = 'N'
}
} }
if (type == 'edit' && item[`${key}_id`]) itemObj['id'] = item[`${key}_id`] if (type == 'edit' && item[`${key}_id`]) itemObj['id'] = item[`${key}_id`]
infoData[key].push(itemObj) infoData[key].push(itemObj)

View File

@@ -46,7 +46,22 @@
</el-dropdown> </el-dropdown>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column v-for="(item, key) in column" :key="key" :field="key" v-bind="item"></vxe-column> <vxe-column v-for="(item, key) in column" :key="key" :field="key" v-bind="item">
<template #default="{ row }" v-if="key === 'hasChildren'">
<div :class="{ 'is-sub-field': row.isSubField }">
<el-button
v-if="!row.isSubField"
:type="item.editRender?.buttonType || 'primary'"
:size="item.editRender?.buttonSize || 'small'"
:disabled="item.editRender?.disabled ? item.editRender.disabled(row) : false"
@click.stop="handleButtonClick(item, row)"
>
{{ item.editRender?.buttonText || '添加子字段' }}
</el-button>
<span v-else>-</span>
</div>
</template>
</vxe-column>
</vxe-table> </vxe-table>
</template> </template>
@@ -65,6 +80,33 @@ const emit = defineEmits(['selection-change', 'cell-click', 'dropdown-command'])
const vxeTableRef = ref() const vxeTableRef = ref()
// 处理按钮点击事件
const handleButtonClick = (item, row) => {
// 检查editRender是否存在
if (!item.editRender) {
return
}
// 检查events是否存在
if (!item.editRender.events) {
return
}
// 检查click事件是否存在
if (!item.editRender.events.click) {
return
}
// 执行自定义点击事件
item.editRender.events.click(row)
}
// 测试点击方法
const testClick = (row) => {
console.log('测试按钮被点击:', row)
alert('测试按钮工作正常!')
}
defineExpose({ vxeTableRef }) defineExpose({ vxeTableRef })
</script> </script>