diff --git a/src/components/DynamicForm/index.vue b/src/components/DynamicForm/index.vue
index 5fb3952..9104749 100644
--- a/src/components/DynamicForm/index.vue
+++ b/src/components/DynamicForm/index.vue
@@ -3,7 +3,13 @@
-
+
diff --git a/src/components/DynamicSearchForm/index.vue b/src/components/DynamicSearchForm/index.vue
new file mode 100644
index 0000000..a9d0503
--- /dev/null
+++ b/src/components/DynamicSearchForm/index.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+
+
+
+
+
+
+
+
diff --git a/src/components/DynamicTable/index.vue b/src/components/DynamicTable/index.vue
index 5c88cf4..d9b6479 100644
--- a/src/components/DynamicTable/index.vue
+++ b/src/components/DynamicTable/index.vue
@@ -23,6 +23,7 @@
:is="getComponent(column.dataType)"
v-model:value="record[column.dataIndex]"
:options="column.options"
+ v-bind="column.attrs"
/>
diff --git a/src/components/DynamicTree/index.vue b/src/components/DynamicTree/index.vue
new file mode 100644
index 0000000..11a7d5f
--- /dev/null
+++ b/src/components/DynamicTree/index.vue
@@ -0,0 +1,186 @@
+
+
+
+
+
+
+
diff --git a/src/components/Table/index.vue b/src/components/Table/index.vue
index 18f6582..83c369c 100644
--- a/src/components/Table/index.vue
+++ b/src/components/Table/index.vue
@@ -121,8 +121,8 @@
typeof props.alert === 'boolean' && props.alert
? clearSelected()
: props.alert.clear && typeof props.alert.clear === 'function'
- ? props.alert.clear()
- : null
+ ? props.alert.clear()
+ : null
)
"
>
@@ -143,6 +143,7 @@
emit('expand', expanded, record)
}
"
+ tableLayout="fixed"
@resizeColumn="handleResizeColumn"
:rowClassName="
(record, index) => (data.localSettings.rowClassNameSwitch ? ((index + 1) % 2 == 0 ? 'odd' : '') : null)
@@ -240,6 +241,10 @@
columnSetting: false,
striped: false
})
+ },
+ scroll: {
+ type: Object,
+ default: () => {}
}
})
)
@@ -577,7 +582,7 @@
...renderProps,
size: data.customSize, // 注意这个size是a-table组件需要的,这里不能跟别的地方成为compSize
columns: data.columnsSetting.filter((value) => value.checked === undefined || value.checked),
- ...data.localSettings,
+ ...data.localSettings
}
// 将值为 undefined 或者 null 的 table里props属性进行一个过滤
renderTableProps.value = Object.entries(renderProps).reduce((x, [y, z]) => (z == null ? x : ((x[y] = z), x)), {})
diff --git a/src/hook/useFormHandler.js b/src/hook/useFormHandler.js
index a434eab..2b5c466 100644
--- a/src/hook/useFormHandler.js
+++ b/src/hook/useFormHandler.js
@@ -2,57 +2,103 @@ import { useRoute, useRouter } from 'vue-router'
import { cloneDeep } from 'lodash-es'
import useTabs from '@/utils/useTabs'
+/**
+ * 使用表单处理程序封装表单的提交、初始化和回退逻辑。
+ * @param {Array} formItems 表单项配置,包含表单字段名、默认值等信息。
+ * @param {Object} api 包含表单提交和获取详情方法的对象。
+ * @returns {Object} 返回包含表单数据、提交加载状态、表单引用、提交函数等的对象。
+ */
export default function useFormHandler(formItems, api) {
+ // 初始化页面类型状态
const state = reactive({
PAGE_TYPE: ''
})
+ // 初始化表单数据对象
let formData = reactive({})
+ // 初始化提交加载状态
const submitLoading = ref(false)
+ // 初始化表单引用数组
const formRefs = ref([])
+
+ // 使用vue-router的useRoute钩子获取当前路由信息
const route = useRoute()
+ // 使用vue-router的useRouter钩子获取路由管理对象
const router = useRouter()
+ /**
+ * 根据表单项配置初始化表单数据。
+ * @param {Array} formItems 表单项配置数组。
+ * @param {Object} formData 初始化后的表单数据对象。
+ */
const initializeFormData = (formItems, formData) => {
formItems.forEach((item) => {
formData[item.name] = item.defaultValue || null
})
}
+ /**
+ * 处理表单提交逻辑。
+ * @param {Object} params 提交时额外的参数配置,包含是否深度克隆formData的标志。
+ */
const onSubmit = async (params) => {
- Promise.all(formRefs.value.map((form) => form.validate()))
- .then(() => {
- submitLoading.value = true
- let formDataParam = params.isDeep ? cloneDeep(params) : cloneDeep(formData)
+ try {
+ // 验证所有表单字段
+ await Promise.all(formRefs.value.map((form) => form.validate()))
+ submitLoading.value = true
- if (route.query.id) {
- formDataParam = { ...formDataParam, id: route.query.id }
- }
- api
- .submitForm(formDataParam, route.query.id)
- .then(() => {
- router.go(-1)
- useTabs.close()
- })
- .finally(() => {
- submitLoading.value = false
- })
- })
- .catch((error) => {
- console.error('Validation error:', error)
- })
+ // 根据参数配置决定是否深度克隆formData
+ let formDataParam = params.isDeep ? cloneDeep(params) : formData
+
+ // 安全地处理路由查询参数
+ const safeId = validateAndCleanId(route.query.id)
+ if (safeId) {
+ formDataParam.id = safeId
+ }
+
+ // 调用api提交表单数据
+ await api.submitForm(formDataParam, safeId)
+ // 提交成功后返回上一页,并关闭当前标签页
+ handleBack()
+ } catch (error) {
+ console.error('Validation error:', error)
+ } finally {
+ submitLoading.value = false
+ }
}
+ /**
+ * 校验并清洁ID,确保其安全使用。
+ * @param {string} id 待校验的ID。
+ * @returns {string|undefined} 校验通过后返回清洁的ID,否则返回undefined。
+ */
+ const validateAndCleanId = (id) => {
+ if (id && /^[a-zA-Z0-9\-_]+$/.test(id)) {
+ return id
+ }
+ console.warn('Invalid ID:', id)
+ return undefined
+ }
+
+ /**
+ * 处理返回操作,返回上一级页面并关闭当前标签页。
+ */
const handleBack = () => {
- router.replace('/basicData/publicAccount')
+ router.go(-1) // 优化为通用的返回上一页操作
useTabs.close()
}
+ /**
+ * 根据页面类型加载表单数据。
+ * @param {String} pageType 页面类型,用于区分新增和编辑等不同场景。
+ * @returns {Promise
-
-
diff --git a/src/views/basicData/publicAccount/columns/publicAccountColumn.js b/src/views/basicData/publicAccount/columns/publicAccountColumn.js
new file mode 100644
index 0000000..0dc43e1
--- /dev/null
+++ b/src/views/basicData/publicAccount/columns/publicAccountColumn.js
@@ -0,0 +1,38 @@
+export const publicAccountColumn = [
+ {
+ title: '编码',
+ dataIndex: '',
+ sorter: (a, b) => a.address.length - b.address.length,
+ sortDirections: ['descend', 'ascend'],
+ align: 'center',
+ resizable: true,
+ width: 100
+ },
+ {
+ title: '名称',
+ dataIndex: 'name',
+ sorter: (a, b) => a.address.length - b.address.length,
+ sortDirections: ['descend', 'ascend'],
+ align: 'center',
+ resizable: true,
+ width: 100
+ },
+ {
+ title: '可用状态',
+ dataIndex: '',
+ sorter: (a, b) => a.address.length - b.address.length,
+ sortDirections: ['descend', 'ascend'],
+ align: 'center',
+ resizable: true,
+ width: 100
+ },
+ {
+ title: '创建时间',
+ dataIndex: 'remarks',
+ sorter: (a, b) => a.address.length - b.address.length,
+ sortDirections: ['descend', 'ascend'],
+ align: 'center',
+ resizable: true,
+ width: 100
+ }
+]
diff --git a/src/views/basicData/publicAccount/index.vue b/src/views/basicData/publicAccount/index.vue
index 734d915..0587975 100644
--- a/src/views/basicData/publicAccount/index.vue
+++ b/src/views/basicData/publicAccount/index.vue
@@ -24,7 +24,7 @@
-
+
-
+
-
-
- {{ $TOOL.dictTypeData('COMMON_STATUS', record.enabledState) }}
+
+ {{ record.number }}
-
- {{ $TOOL.dictTypeData('OFFICIAL_ACCOUNT_TYPE', record.type) }}
+
+ 启用
+ 停用
- 查看
-
- 编辑
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- 删除
+
+
+
+
@@ -114,32 +125,36 @@
dataIndex: 'type',
align: 'center',
resizable: true,
- width: 100
+ width: 300,
+ ellipsis: true,
+ sorter: true,
+ sortDirections: ['descend', 'ascend']
},
{
title: '名称',
dataIndex: 'name',
- sorter: (a, b) => a.address.length - b.address.length,
- sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
- width: 100
+ width: 300,
+ ellipsis: true
},
{
title: '可用状态',
dataIndex: 'enabledState',
align: 'center',
resizable: true,
- width: 100
+ width: 100,
+ ellipsis: true
},
{
title: '创建时间',
dataIndex: 'createTime',
- sorter: (a, b) => a.address.length - b.address.length,
+ sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
- width: 100
+ width: 300,
+ ellipsis: true
}
]
diff --git a/src/views/basicData/stash/columns/brandColumns.js b/src/views/basicData/stash/columns/brandColumns.js
new file mode 100644
index 0000000..2f5b3fa
--- /dev/null
+++ b/src/views/basicData/stash/columns/brandColumns.js
@@ -0,0 +1,18 @@
+export const brandColumns = [
+ {
+ title: '编码',
+ dataIndex: 'number'
+ },
+ {
+ title: '名称',
+ dataIndex: 'name'
+ },
+ {
+ title: '可用状态',
+ dataIndex: 'enabledState'
+ },
+ {
+ title: '创建时间',
+ dataIndex: 'createTime'
+ }
+]
diff --git a/src/views/basicData/stash/index.vue b/src/views/basicData/stash/index.vue
index 6cb34b1..bcedb0c 100644
--- a/src/views/basicData/stash/index.vue
+++ b/src/views/basicData/stash/index.vue
@@ -29,7 +29,7 @@
-
+
-
+
+
+ {{ record.number }}
+
-
- {{ $TOOL.dictTypeData('COMMON_STATUS', record.enabledState) }}
+ 启用
+ 停用
- 查看
-
- 编辑
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- 删除
+
+
+
+
@@ -114,43 +128,46 @@
{
title: '编码',
dataIndex: 'number',
- sorter: (a, b) => a.address.length - b.address.length,
+ sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
- width: 100
+ width: 200,
+ ellipsis: true
},
{
title: '名称',
dataIndex: 'name',
- sorter: (a, b) => a.address.length - b.address.length,
- sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
- width: 100
+ width: 200,
+ ellipsis: true
},
{
title: '可用状态',
dataIndex: 'enabledState',
align: 'center',
resizable: true,
- width: 100
+ width: 100,
+ ellipsis: true
},
{
title: '仓库条码',
dataIndex: 'barcode',
align: 'center',
resizable: true,
- width: 100
+ width: 200,
+ ellipsis: true
},
{
title: '创建时间',
dataIndex: 'createTime',
- sorter: (a, b) => a.address.length - b.address.length,
+ sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
- width: 100
+ width: 150,
+ ellipsis: true
}
]
diff --git a/src/views/basicData/tissue/index.vue b/src/views/basicData/tissue/index.vue
index 4d979ba..5cd2c58 100644
--- a/src/views/basicData/tissue/index.vue
+++ b/src/views/basicData/tissue/index.vue
@@ -42,23 +42,29 @@
-
+
-
-
+
+ @selectTree="selectTree"
+ @delTree="delTree"
+ :toolConfig="{
+ plus: false,
+ edit: false,
+ delete: false,
+ refresh: true
+ }"
+ >
-
+
-
+
@@ -83,33 +93,36 @@
+
+ {{ record.number }}
+
-
- {{ $TOOL.dictTypeData('COMMON_STATUS', record.enabledState) }}
+ 启用
+ 停用
{{ $TOOL.dictTypeData('PRODUCTION_ORGANIZATION_TYPE', record.type) }}
- 查看
-
- 编辑
-
-
- 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -132,11 +145,12 @@
{
title: '编码',
dataIndex: 'number',
- sorter: (a, b) => a.address.length - b.address.length,
+ sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
- width: 100
+ width: 300,
+ ellipsis: true
},
{
title: '类型',
@@ -148,27 +162,28 @@
{
title: '名称',
dataIndex: 'name',
- sorter: (a, b) => a.address.length - b.address.length,
- sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
- width: 100
+ width: 300,
+ ellipsis: true
},
{
title: '可用状态',
dataIndex: 'enabledState',
align: 'center',
resizable: true,
- width: 100
+ width: 100,
+ ellipsis: true
},
{
title: '创建时间',
dataIndex: 'createTime',
- sorter: (a, b) => a.address.length - b.address.length,
+ sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
- width: 100
+ width: 300,
+ ellipsis: true
}
]
@@ -179,11 +194,9 @@
columns,
loadData,
reset,
- deleteRecord,
deleteBatchRecords,
options,
searchFormRef,
- toolConfig,
navigateTo,
toggleAdvanced,
advanced
@@ -197,36 +210,26 @@
)
const TissueFormRef = ref(null)
+ const dynamicTreeRef = ref(null)
- // 树级结构
- const expandedKeys = ref(['0-0', '0-1'])
- const selectedKeys = ref([])
- let treeData = ref([])
+ const selectTree = (value) => {
+ searchFormState.value.parentId = value.id
+ tableRef.value.refresh()
+ }
- onMounted(() => {
- getProductionOrganizationTree()
- })
+ const delTree = () => {
+ searchFormState.value.parentId = null
+ tableRef.value.refresh()
+ }
const successful = () => {
+ searchFormState.value.parentId = null
tableRef.value.refresh()
- selectedKeys.value = []
- getProductionOrganizationTree()
+
+ dynamicTreeRef.value.loadTreeData()
}
- const getProductionOrganizationTree = () => {
- productionOrganizationApi.productionOrganizationTree().then((res) => {
- treeData.value = res || []
- })
- }
-
- const deleteRecordRestTRee = (record) => {
- deleteRecord(record).then(() => {
- getProductionOrganizationTree()
- })
- }
-
- const handleSelectTree = (value) => {
- searchFormState.value.parentId = value[0]
- tableRef.value.refresh()
- }
+ onMounted(() => {
+ dynamicTreeRef.value.loadTreeData()
+ })
diff --git a/src/views/basicData/unit/detail/index.vue b/src/views/basicData/unit/detail/index.vue
index 1d4a933..25f8553 100644
--- a/src/views/basicData/unit/detail/index.vue
+++ b/src/views/basicData/unit/detail/index.vue
@@ -63,7 +63,7 @@
-