基础资料优化处理

main
GaoF 2024-08-12 09:13:47 +08:00
parent af997e65b1
commit be3e482df7
22 changed files with 447 additions and 602 deletions

View File

@ -0,0 +1,81 @@
<template>
<a-card :bordered="false">
<a-form ref="formRef" :model="formState" class="ant-advanced-search-form">
<a-row :gutter="24">
<a-col v-for="field in visibleFields" :key="field.name" :span="6" v-show="field.visible !== false">
<a-form-item :label="field.label" :name="field.name">
<component :is="field.component" v-model:value="formState[field.name]" v-bind="field.props" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-button type="primary" @click="onSearch"></a-button>
<a-button style="margin: 0 8px" @click="onReset"></a-button>
<a @click="toggleAdvanced" style="margin-left: 8px" v-if="formFields.length > 3">
{{ advanced ? '收起' : '展开' }}
<component :is="advanced ? 'up-outlined' : 'down-outlined'" />
</a>
</a-col>
</a-row>
</a-form>
</a-card>
</template>
<script setup>
import { ref, defineProps, defineEmits, computed } from 'vue'
const props = defineProps({
formState: {
type: Object,
required: true
},
formFields: {
type: Array,
required: true
}
})
const emit = defineEmits(['search', 'reset', 'toggleAdvanced'])
const formRef = ref(null)
const advanced = ref(false)
const visibleFields = ref([])
watch(
() => props.formFields,
(newValue) => {
visibleFields.value = newValue
},
{
immediate: true
}
)
const onSearch = () => {
emit('search')
}
const onReset = () => {
formRef.value.resetFields()
emit('reset')
}
const toggleAdvanced = () => {
advanced.value = !advanced.value
if (advanced.value) {
visibleFields.value.forEach((item) => {
if (item.visible === false) {
item.visible = true
}
})
} else {
visibleFields.value.forEach((item) => {
if (item.visible !== false && item.isShowVisible) {
item.visible = false
}
})
}
emit('toggleAdvanced', advanced.value)
}
</script>

View File

@ -1,56 +0,0 @@
<template>
<a-form :model="model" :rules="rules" layout="vertical" ref="searchFormRef">
<a-row :gutter="16">
<a-col :span="6" v-for="(item, index) in formItems" :key="index">
<a-form-item :label="item.label" :name="item.name" :rules="item.rules">
<component
style="width: 100%"
:is="item.type"
v-model:value="model[item.name]"
:disabled="allDisabled"
v-bind="item.attrs"
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-button type="primary">查询</a-button>
<a-button style="margin: 0 8px">重置</a-button>
</a-col>
</a-row>
</a-form>
</template>
<script setup>
import { ref, watch } from 'vue'
const props = defineProps({
formItems: {
type: Array,
required: true
},
model: {
type: Object,
required: true
},
rules: {
type: Object,
default: () => ({})
},
allDisabled: {
type: Boolean,
default: false
}
})
const searchFormRef = ref(null)
// Expose validate method
defineExpose({
validate: () => searchFormRef.value.validate(),
resetFields: () => searchFormRef.value.resetFields()
})
</script>
<style scoped>
/* Add your styles here */
</style>

View File

@ -1,145 +0,0 @@
<template>
<div class="table-wrapper">
<!-- 工具栏 -->
<div class="table-tool">
<a-button @click="addRow" type="primary">新增</a-button>
<a-button @click="addRow" type="primary">删除</a-button>
</div>
<!-- 表格 -->
<a-table
size="middle"
:dataSource="dataSource"
:columns="computedColumns"
:rowKey="rowKey"
@change="handleTableChange"
:scroll="{ x: 'max-content' }"
:row-selection="rowSelection"
>
<template #bodyCell="{ column, record }">
<template v-if="column.editable">
<component
style="width: 100%"
:is="getComponent(column.dataType)"
v-model:value="record[column.dataIndex]"
:options="column.options"
v-bind="column.attrs"
/>
</template>
<template v-else>
<span>{{ record[column.dataIndex] }}</span>
</template>
</template>
<template #actions="{ record }">
<a-button @click="edit(record[props.rowKey])" size="small">编辑</a-button>
<a-popconfirm title="确定删除吗?" @confirm="() => deleteRow(record[props.rowKey])">
<a-button type="danger" size="small">删除</a-button>
</a-popconfirm>
</template>
</a-table>
</div>
</template>
<script setup>
import { ref, reactive, computed, defineProps } from 'vue'
// defineProps
const props = defineProps({
initialData: {
type: Array,
default: () => []
},
columns: {
type: Array,
default: () => []
},
rowKey: {
type: String,
default: 'key'
}
})
//
const dataSource = ref([...props.initialData])
const editingKey = ref(null)
//
const getComponent = (dataType) => {
switch (dataType) {
case 'number':
return 'a-input-number'
case 'select':
return 'a-select'
default:
return 'a-input'
}
}
//
const computedColumns = computed(() => {
return props.columns.map((col) => ({
...col,
editable: col.editable
}))
})
const addRow = () => {
const newRow = {
[props.rowKey]: Date.now().toString(),
...props.columns.reduce((acc, col) => {
if (col.dataIndex) acc[col.dataIndex] = ''
return acc
}, {})
}
dataSource.value = [...dataSource.value, newRow]
edit(newRow[props.rowKey])
}
const deleteRow = (key) => {
dataSource.value = dataSource.value.filter((item) => item[props.rowKey] !== key)
}
const handleFieldChange = (key, field, value) => {
dataSource.value = dataSource.value.map((item) => (item[props.rowKey] === key ? { ...item, [field]: value } : item))
}
const isEditing = (record) => record[props.rowKey] === editingKey.value
const edit = (key) => {
editingKey.value = key
}
const save = () => {
editingKey.value = null
}
const cancel = () => {
editingKey.value = null
}
const handleTableChange = (pagination, filters, sorter) => {
console.log('Table changed:', pagination, filters, sorter)
}
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
},
onSelect: (record, selected, selectedRows) => {
console.log(record, selected, selectedRows)
},
onSelectAll: (selected, selectedRows, changeRows) => {
console.log(selected, selectedRows, changeRows)
}
}
</script>
<style scoped>
.table-wrapper {
margin: 16px;
}
.table-tool {
margin-bottom: 16px;
}
</style>

View File

@ -204,6 +204,7 @@
visible.value = true visible.value = true
nextTick(() => { nextTick(() => {
searchFormState.value.enabledState = 'ENABLE'
// 线 // 线
dynamicTreeRef.value.loadTreeData() dynamicTreeRef.value.loadTreeData()

View File

@ -337,6 +337,7 @@
// //
const refresh = (bool = false) => { const refresh = (bool = false) => {
console.log(123131)
bool && bool &&
(data.localPagination = Object.assign( (data.localPagination = Object.assign(
{}, {},

View File

@ -3,190 +3,154 @@ import { cloneDeep } from 'lodash-es'
import useTabs from '@/utils/useTabs' import useTabs from '@/utils/useTabs'
import extendFieldApi from '@/api/base/extendfield/extendFieldApi' import extendFieldApi from '@/api/base/extendfield/extendFieldApi'
/**
* 使用表单处理程序封装表单的提交初始化和回退逻辑
* @param {Array} formItems 表单项配置包含表单字段名默认值等信息
* @param {Object} api 包含表单提交和获取详情方法的对象
* @param backRouter
* @returns {Object} 返回包含表单数据提交加载状态表单引用提交函数等的对象
*/
export default function useFormHandler(formItems, api, backRouter) { export default function useFormHandler(formItems, api, backRouter) {
// 初始化页面类型状态
const state = reactive({ const state = reactive({
PAGE_TYPE: '' PAGE_TYPE: ''
}) })
let extendFormData = ref({})
// 操作信息 const extendFormData = ref({})
let inform = reactive({ const inform = reactive({
createUserName: '', createUserName: '',
createTime: '', createTime: '',
updateUserName: '', updateUserName: '',
updateTime: '' updateTime: ''
}) })
// 初始化表单数据对象 const formData = reactive({})
let formData = reactive({})
// 初始化提交加载状态
const submitLoading = ref(false) const submitLoading = ref(false)
// 初始化表单引用数组
const formRefs = ref([]) const formRefs = ref([])
// 使用vue-router的useRoute钩子获取当前路由信息
const route = useRoute() const route = useRoute()
// 使用vue-router的useRouter钩子获取路由管理对象
const router = useRouter() const router = useRouter()
/** // 初始化表单数据
* 根据表单项配置初始化表单数据 const initializeFormData = () => {
* @param {Array} formItems 表单项配置数组
* @param {Object} formData 初始化后的表单数据对象
*/
const initializeFormData = (formItems, formData) => {
formItems.forEach((item) => { formItems.forEach((item) => {
formData[item.name] = item.defaultValue || null formData[item.name] = item.defaultValue || null
}) })
} }
/** // 提交表单
* 处理表单提交逻辑 const onSubmit = async (params = {}) => {
* @param {Object} params 提交时额外的参数配置包含是否深度克隆formData的标志 submitLoading.value = true
*/
const onSubmit = async (params) => {
try { try {
// 验证所有表单字段 await validateForms()
await Promise.all(formRefs.value.map((form) => form.validate()))
submitLoading.value = true
// 根据参数配置决定是否深度克隆formData const formDataParam = params.isDeep ? cloneDeep(params) : formData
let formDataParam = params.isDeep ? cloneDeep(params) : formData const safeId = validateAndCleanId(route.query.id || params.id)
// 安全地处理路由查询参数
const safeId = validateAndCleanId(route.query.id)
if (safeId) { if (safeId) {
formDataParam.id = safeId formDataParam.id = safeId
} }
// 调用api提交表单数据 const res = await api.submitForm(formDataParam, safeId)
await api.submitForm(formDataParam, safeId)
// 提交成功后返回上一页,并关闭当前标签页 if (params.isEnable) return res
handleBack(backRouter)
handleBack()
} catch (error) { } catch (error) {
console.error('Validation error:', error) console.error('Validation or submission error:', error)
throw error
} finally { } finally {
submitLoading.value = false submitLoading.value = false
} }
} }
/** // 验证表单
* 校验并清洁ID确保其安全使用 const validateForms = () => {
* @param {string} id 待校验的ID return Promise.all(formRefs.value.map((form) => form.validate()))
* @returns {string|undefined} 校验通过后返回清洁的ID否则返回undefined }
*/
// 校验并清洁ID
const validateAndCleanId = (id) => { const validateAndCleanId = (id) => {
if (id && /^[a-zA-Z0-9\-_]+$/.test(id)) { return id && /^[a-zA-Z0-9\-_]+$/.test(id) ? id : undefined
return id
}
console.warn('Invalid ID:', id)
return undefined
} }
/** // 返回并关闭当前标签页
* 处理返回操作返回上一级页面并关闭当前标签页 const handleBack = () => {
*/ useTabs.close('', backRouter)
const handleBack = (routerPath) => {
// useTabs.close(route)
useTabs.close('', routerPath)
} }
/** // 根据页面类型加载表单数据
* 根据页面类型加载表单数据
* @param {String} pageType 页面类型用于区分新增和编辑等不同场景
* @returns {Promise<Object>} 返回获取的详情数据
*/
const fetchData = async (pageType) => { const fetchData = async (pageType) => {
initializeFormData(formItems, formData) initializeFormData()
if (pageType && pageType !== 'ADD') { if (pageType && pageType !== 'ADD') {
try { try {
const res = await api.getDetail({ id: route.query.id }) const res = await api.getDetail({ id: route.query.id })
populateFormData(res)
// 根据返回的详情数据初始化表单数据
for (let key in formData) {
if (res[key] !== undefined) {
formData[key] = res[key]
}
}
// 操作信息
for (let key in inform) {
if (res[key] !== undefined) {
inform[key] = res[key]
}
}
// 扩展字段
if (res.extJson) { if (res.extJson) {
extendFormData.value = JSON.parse(res.extJson) extendFormData.value = JSON.parse(res.extJson)
} }
return res return res
} catch (error) { } catch (error) {
console.error('API request failed:', error) console.error('Failed to fetch data:', error)
} }
} }
} }
/** // 填充表单数据
* 扩展字段 const populateFormData = (data) => {
*/ Object.keys(formData).forEach((key) => {
const getExtendField = async (model) => { if (data[key] !== undefined) formData[key] = data[key]
let extendData = []
// 字段扩展
const resExtendField = await extendFieldApi.extendFieldTypeList({
enabledState: 'ENABLE',
model
}) })
console.log(resExtendField, 'resExtendField') Object.keys(inform).forEach((key) => {
if (data[key] !== undefined) inform[key] = data[key]
})
}
if (resExtendField) { // 获取扩展字段
resExtendField.forEach((item) => { const getExtendField = async (model) => {
if (item.showValues) { try {
const showValues = JSON.parse(item.showValues) const resExtendField = await extendFieldApi.extendFieldTypeList({
let options = [] enabledState: 'ENABLE',
showValues.forEach((value) => { model
options.push({
value: value.name,
label: value.name
})
})
extendData.push({
label: item.name,
name: item.fieldName,
type: item.showType,
span: 6,
attrs: {
placeholder: '请输入内容',
options
}
})
}
}) })
console.log(resExtendField, 'resExtendField')
const extendData =
resExtendField?.map((item) => {
if (item.enabledState === 'ENABLE') {
const options = item.showValues
? JSON.parse(item.showValues).map((value) => ({
value: value.name,
label: value.name
}))
: []
return {
label: item.name,
name: item.fieldName,
type: item.showType,
span: 6,
attrs: {
placeholder: '请输入内容',
options
}
}
}
}) || []
extendData.forEach((item) => { extendData.forEach((item) => {
if (item.fieldName) extendFormData.value[item.fieldName] = null if (item && item.fieldName) extendFormData.value[item.fieldName] = null
}) })
return extendData
} else { console.log(extendData.length, 'extendData')
if (extendData) {
return extendData
} else {
return []
}
} catch (error) {
console.error('Failed to get extend fields:', error)
return [] return []
} }
} }
// 返回包含各种处理函数和状态的对象
return { return {
formData, formData,
submitLoading, submitLoading,
formRefs, formRefs,
inform, inform,
extendFormData, extendFormData,
populateFormData,
getExtendField, getExtendField,
onSubmit, onSubmit,
handleBack, handleBack,

View File

@ -13,9 +13,7 @@ import useTabs from '@/utils/useTabs'
*/ */
export function useTableManagement(apiModule = {}, tableColumns, hasPermData, isShowAction = true) { export function useTableManagement(apiModule = {}, tableColumns, hasPermData, isShowAction = true) {
const searchFormState = ref({}) const searchFormState = ref({})
const searchFormRef = ref(null)
const selectedRowKeys = ref([]) const selectedRowKeys = ref([])
let advanced = ref(false)
const router = useRouter() const router = useRouter()
@ -62,14 +60,6 @@ export function useTableManagement(apiModule = {}, tableColumns, hasPermData, is
}) })
} }
// 重置
const reset = () => {
if (tableRef.value) {
searchFormRef.value.resetFields()
tableRef.value.refresh(true)
}
}
// 删除 // 删除
const deleteRecord = (record) => { const deleteRecord = (record) => {
let params = [{ id: record.id }] let params = [{ id: record.id }]
@ -97,24 +87,17 @@ export function useTableManagement(apiModule = {}, tableColumns, hasPermData, is
}) })
} }
const toggleAdvanced = () => {
advanced.value = !advanced.value
}
// 返回Hook的值 // 返回Hook的值
return { return {
searchFormState, searchFormState,
searchFormRef,
tableRef, tableRef,
selectedRowKeys, selectedRowKeys,
columns, columns,
options, options,
advanced,
loadData, loadData,
reset,
deleteRecord, deleteRecord,
deleteBatchRecords, deleteBatchRecords,
navigateTo, navigateTo
toggleAdvanced
} }
} }

View File

@ -292,12 +292,13 @@
} }
const onSubmitForm = () => { const onSubmitForm = () => {
console.log(dataSource.value, 'dataSource.value')
onSubmit({ onSubmit({
isDeep: true, isDeep: true,
materialPackageList: dataSource.value,
...formData, ...formData,
...productFormData.value, ...productFormData.value,
extJson: JSON.stringify(extendFormData.value) || '' extJson: JSON.stringify(extendFormData.value) || '',
materialPackageList: dataSource.value
}) })
} }
@ -790,7 +791,9 @@
packageProportionCount.push(item.productQty * item.unitRate) packageProportionCount.push(item.productQty * item.unitRate)
}) })
formData.packageProportion = calculateRatios(packageProportionCount).join(':') formData.packageProportion = calculateRatios(packageProportionCount)
? calculateRatios(packageProportionCount).join(':')
: null
} }
} }
@ -806,6 +809,16 @@
ratios.push(arr[i] / arr[i - 1]) ratios.push(arr[i] / arr[i - 1])
} }
for (let i = 0; i < ratios.length; i++) {
//
if (!Number.isInteger(ratios[i])) {
return notification.error({
message: `包装比例转换提示`,
description: `结果不能有小数,请重新填写`
})
}
}
return ratios return ratios
} }

View File

@ -0,0 +1,12 @@
import tool from '@/utils/tool'
export const searchFields = [
{ name: 'name', label: '名称', component: 'a-input', props: { placeholder: '请输入名称' } },
{
name: 'enabledState',
label: '可用状态',
component: 'a-select',
props: { placeholder: '请选择状态', options: tool.dictList('COMMON_STATUS') }
},
{ name: 'number', label: '编码', component: 'a-input', props: { placeholder: '请输入编码' } }
]

View File

@ -1,33 +1,10 @@
<template> <template>
<a-card :bordered="false"> <AdvancedSearchForm
<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form"> :formState="searchFormState"
<a-row :gutter="24"> :formFields="searchFields"
<a-col :span="6"> @search="tableRef.refresh()"
<a-form-item label="名称" name="name"> @reset="tableRef.refresh()"
<a-input v-model:value="searchFormState.name" placeholder="请输入名称" /> />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="编码" name="number">
<a-input v-model:value="searchFormState.number" placeholder="请输入编码" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="可用状态" name="enabledState">
<a-select
v-model:value="searchFormState.enabledState"
placeholder="请选择可用状态"
:options="$TOOL.dictList('COMMON_STATUS')"
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-button type="primary" @click="tableRef.refresh()"></a-button>
<a-button style="margin: 0 8px" @click="reset"></a-button>
</a-col>
</a-row>
</a-form>
</a-card>
<a-card :bordered="false" class="mt-4" style="height: 100%"> <a-card :bordered="false" class="mt-4" style="height: 100%">
<a-row :gutter="24"> <a-row :gutter="24">
@ -146,9 +123,12 @@
<script setup name="materiel"> <script setup name="materiel">
import materialApi from '@/api/base/material/materialApi' import materialApi from '@/api/base/material/materialApi'
import materialCategoryApi from '@/api/base/material/materialCategoryApi' import materialCategoryApi from '@/api/base/material/materialCategoryApi'
import MaterialCategoryForm from '@/views/productionBusiness/basicData/materiel/detail/materialCategoryForm.vue' import MaterialCategoryForm from '@/views/productionBusiness/basicData/materiel/detail/materialCategoryForm.vue'
import { useTableManagement } from '@/hook/useTableManagement' import { useTableManagement } from '@/hook/useTableManagement'
import { materielColumn } from '@/views/productionBusiness/basicData/materiel/column/materiel-column' import { materielColumn } from '@/views/productionBusiness/basicData/materiel/column/materiel-column'
import { searchFields } from '@/views/productionBusiness/basicData/materiel/formFields/searchFields'
const materialCategoryFormRef = ref(null) const materialCategoryFormRef = ref(null)
const dynamicTreeRef = ref(null) const dynamicTreeRef = ref(null)
@ -159,12 +139,10 @@
selectedRowKeys, selectedRowKeys,
columns, columns,
loadData, loadData,
reset,
deleteRecord,
deleteBatchRecords, deleteBatchRecords,
options, options,
searchFormRef, navigateTo,
navigateTo deleteRecord
} = useTableManagement( } = useTableManagement(
{ {
page: materialApi.materialPage, page: materialApi.materialPage,

View File

@ -6,83 +6,62 @@
:destroy-on-close="true" :destroy-on-close="true"
@close="onClose" @close="onClose"
> >
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical"> <DynamicForm :formItems="drawerForm" :model="formData" :rules="formRules" ref="formRef1" />
<a-form-item label="编码:"> <OperationalInformation :detailData="recordData" :colSpan="12" v-if="recordData.id"></OperationalInformation>
<a-input v-model:value="formData.number" placeholder="不输入自动生成" allow-clear />
</a-form-item>
<a-form-item label="名称:" name="name" props="name">
<a-input v-model:value="formData.name" placeholder="请输入名称" allow-clear />
</a-form-item>
<a-form-item label="状态:" name="enabledState" props="enabledState">
<a-select
v-model:value="formData.enabledState"
placeholder="请选择状态"
:options="tool.dictList('COMMON_STATUS')"
/>
</a-form-item>
</a-form>
<OperationalInformation :detailData="formData" :colSpan="12" v-if="formData.id"></OperationalInformation>
<template #footer> <template #footer>
<a-button style="margin-right: 8px" @click="onClose"></a-button> <a-button style="margin-right: 8px" @click="onClose"></a-button>
<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button> <a-button type="primary" @click="onSubmitForm"></a-button>
</template> </template>
</xn-form-container> </xn-form-container>
</template> </template>
<script setup name="sysUnitGroupForm"> <script setup name="sysUnitGroupForm">
import tool from '@/utils/tool'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import { required } from '@/utils/formRules'
import sysUnitGroupApi from '@/api/base/unit/unitGroupsApi' import sysUnitGroupApi from '@/api/base/unit/unitGroupsApi'
import { drawerForm, formRules } from '@/views/productionBusiness/basicData/unit/formFields/drawerForm'
import useFormHandler from '@/hook/useFormHandler'
// //
const visible = ref(false) const visible = ref(false)
const emit = defineEmits({ successful: null }) const emit = defineEmits({ successful: null })
const formRef = ref() const formRef1 = ref(null)
// let recordData = reactive({})
const formData = ref({
number: '',
name: '',
enabledState: 'ENABLE'
})
const submitLoading = ref(false)
const enabledStateOptions = ref([])
// //
const onOpen = (record) => { const onOpen = (record) => {
visible.value = true visible.value = true
formRules.value = [formRef1.value]
if (record) { if (record) {
let recordData = cloneDeep(record) recordData = cloneDeep(record)
formData.value = Object.assign({}, recordData) fetchData().then(() => {
populateFormData(recordData)
})
} else { } else {
formData.value = { name: '', number: '', enabledState: 'ENABLE' } fetchData()
recordData = {}
} }
} }
// //
const onClose = () => { const onClose = () => {
formRef.value.resetFields()
visible.value = false visible.value = false
} }
//
const formRules = {
name: [required('请输入名称')],
enabledState: [required('请输入状态')]
}
// //
const onSubmit = () => { const onSubmitForm = () => {
formRef.value.validate().then(() => { onSubmit({
submitLoading.value = true isEnable: true,
const formDataParam = cloneDeep(formData.value) id: recordData.id
sysUnitGroupApi }).then(() => {
.sysUnitGroupSubmitForm(formDataParam, formDataParam.id) onClose()
.then(() => { emit('successful')
onClose()
emit('successful')
})
.finally(() => {
submitLoading.value = false
})
}) })
} }
let { formData, onSubmit, populateFormData, fetchData } = useFormHandler([...drawerForm], {
submitForm: sysUnitGroupApi.sysUnitGroupSubmitForm
})
// //
defineExpose({ defineExpose({
onOpen onOpen

View File

@ -14,9 +14,17 @@
/> />
</a-card> </a-card>
<a-card :bordered="false" class="mt-4" style="height: 100%"> <a-card
:bordered="false"
class="mt-4"
style="height: 100%"
v-if="extendData.length > 0 || route.query.type !== 'ADD'"
>
<a-tabs v-model:activeKey="activeKey"> <a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="扩展字段" forceRender v-if="extendData.length > 0"> <a-tab-pane key="1" tab="操作信息" forceRender v-if="route.query.type !== 'ADD'">
<OperationalInformation :detailData="inform" :colSpan="6"></OperationalInformation>
</a-tab-pane>
<a-tab-pane key="2" tab="扩展字段" forceRender v-if="extendData.length > 0">
<DynamicForm <DynamicForm
:allDisabled="route.query.type === 'SEARCH'" :allDisabled="route.query.type === 'SEARCH'"
:formItems="extendData" :formItems="extendData"
@ -24,38 +32,24 @@
:rules="formRules" :rules="formRules"
v-if="extendData.length > 0" v-if="extendData.length > 0"
/> />
<a-empty v-else /> <a-empty v-else />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="操作信息" v-if="route.query.type !== 'ADD'">
<OperationalInformation :detailData="inform" :colSpan="6"></OperationalInformation>
</a-tab-pane>
</a-tabs> </a-tabs>
</a-card> </a-card>
</template> </template>
<script setup name="basicDataUnitDetail"> <script setup name="basicDataUnitDetail">
import tool from '@/utils/tool'
import { required } from '@/utils/formRules'
import unitGroupsApi from '@/api/base/unit/unitGroupsApi' import unitGroupsApi from '@/api/base/unit/unitGroupsApi'
import useFormHandler from '@/hook/useFormHandler' import useFormHandler from '@/hook/useFormHandler'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import unitApi from '@/api/base/unit/unitApi' import unitApi from '@/api/base/unit/unitApi'
import { formRules, unitFormItems } from '@/views/productionBusiness/basicData/unit/formFields/detailFields'
const route = useRoute() const route = useRoute()
const formRef1 = ref() const formRef1 = ref()
let activeKey = ref('1') let activeKey = ref('1')
let extendData = ref([]) let extendData = ref([])
//
const formRules = {
unitGroupId: [required('请选择单位')],
name: [required('请输入名称')],
rate: [required('请输入换算率')],
isBase: [required('请选择是否基本单位')]
}
let unitGroupList = ref([])
onMounted(async () => { onMounted(async () => {
formRefs.value = [formRef1.value] formRefs.value = [formRef1.value]
await fetchData(route.query.type) await fetchData(route.query.type)
@ -83,89 +77,6 @@
}) })
} }
const unitFormItems = reactive([
{
label: '名称:',
name: 'name',
type: 'a-input',
span: 6,
rules: [required('请输入名称')],
attrs: {
placeholder: '请输入名称',
allowClear: true
}
},
{
label: '编码:',
name: 'number',
type: 'a-input-number',
span: 6,
attrs: {
placeholder: '请输入编码',
allowClear: true
}
},
{
label: '单位组:',
name: 'unitGroupId',
type: 'a-select',
span: 6,
attrs: {
placeholder: '请选择可用状态',
options: [],
fieldNames: {
label: 'name',
value: 'id'
}
},
defaultValue: ''
},
{
label: '换算率:',
name: 'rate',
type: 'a-input-number',
span: 6,
attrs: {
placeholder: '请输入换算率',
allowClear: true,
min: 1,
precision: 0
}
},
{
label: '是否基本单位:',
name: 'isBase',
type: 'a-select',
span: 6,
attrs: {
placeholder: '请选择是否基本单位',
options: tool.dictList('YES_NO')
},
defaultValue: 'NO'
},
{
label: '可用状态:',
name: 'enabledState',
type: 'a-select',
span: 6,
attrs: {
placeholder: '请选择可用状态',
options: tool.dictList('COMMON_STATUS')
},
defaultValue: 'ENABLE'
},
{
label: '备注:',
name: 'remarks',
type: 'a-textarea',
span: 24,
attrs: {
placeholder: '请输入备注',
allowClear: true
}
}
])
const { formData, formRefs, inform, extendFormData, onSubmit, handleBack, fetchData, getExtendField } = const { formData, formRefs, inform, extendFormData, onSubmit, handleBack, fetchData, getExtendField } =
useFormHandler( useFormHandler(
[...unitFormItems], [...unitFormItems],

View File

@ -0,0 +1,91 @@
import { required } from '@/utils/formRules'
import tool from '@/utils/tool'
export const unitFormItems = reactive([
{
label: '名称:',
name: 'name',
type: 'a-input',
span: 6,
attrs: {
placeholder: '请输入名称',
allowClear: true
}
},
{
label: '编码:',
name: 'number',
type: 'a-input-number',
span: 6,
attrs: {
placeholder: '请输入编码',
allowClear: true
}
},
{
label: '单位组:',
name: 'unitGroupId',
type: 'a-select',
span: 6,
attrs: {
placeholder: '请选择可用状态',
options: [],
fieldNames: {
label: 'name',
value: 'id'
}
},
defaultValue: ''
},
{
label: '换算率:',
name: 'rate',
type: 'a-input-number',
span: 6,
attrs: {
placeholder: '请输入换算率',
allowClear: true,
min: 1,
precision: 0
}
},
{
label: '是否基本单位:',
name: 'isBase',
type: 'a-select',
span: 6,
attrs: {
placeholder: '请选择是否基本单位',
options: tool.dictList('YES_NO')
},
defaultValue: 'NO'
},
{
label: '可用状态:',
name: 'enabledState',
type: 'a-select',
span: 6,
attrs: {
placeholder: '请选择可用状态',
options: tool.dictList('COMMON_STATUS')
},
defaultValue: 'ENABLE'
},
{
label: '备注:',
name: 'remarks',
type: 'a-textarea',
span: 24,
attrs: {
placeholder: '请输入备注',
allowClear: true
}
}
])
export const formRules = {
unitGroupId: [required('请选择单位')],
name: [required('请输入名称')],
rate: [required('请输入换算率')],
isBase: [required('请选择是否基本单位')]
}

View File

@ -0,0 +1,41 @@
import tool from '@/utils/tool'
import { required } from '@/utils/formRules'
export const drawerForm = reactive([
{
label: '编码:',
name: 'number',
type: 'a-input-number',
span: 12,
attrs: {
placeholder: '请输入编码',
allowClear: true
}
},
{
label: '名称:',
name: 'name',
type: 'a-input',
span: 12,
attrs: {
placeholder: '请输入名称',
allowClear: true
}
},
{
label: '可用状态:',
name: 'enabledState',
type: 'a-select',
span: 12,
attrs: {
placeholder: '请选择可用状态',
options: tool.dictList('COMMON_STATUS')
},
defaultValue: 'ENABLE'
}
])
export const formRules = {
name: [required('请输入名称')],
enabledState: [required('请输入状态')]
}

View File

@ -0,0 +1,20 @@
import tool from '@/utils/tool'
export const searchFields = [
{ name: 'name', label: '名称', component: 'a-input', props: { placeholder: '请输入名称' } },
{
name: 'enabledState',
label: '可用状态',
component: 'a-select',
props: { placeholder: '请选择状态', options: tool.dictList('COMMON_STATUS') }
},
{ name: 'number', label: '编码', component: 'a-input', props: { placeholder: '请输入编码' } },
{
name: 'isBase',
label: '是否基本单位',
component: 'a-select',
props: { placeholder: '请选择是否基本单位', options: tool.dictList('YES_NO') },
visible: false,
isShowVisible: true
}
]

View File

@ -1,46 +1,10 @@
<template> <template>
<a-card :bordered="false"> <AdvancedSearchForm
<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form"> :formState="searchFormState"
<a-row :gutter="24"> :formFields="searchFields"
<a-col :span="6"> @search="tableRef.refresh()"
<a-form-item label="名称" name="name"> @reset="tableRef.refresh()"
<a-input v-model:value="searchFormState.name" placeholder="请输入名称" /> />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="可用状态" name="enabledState">
<a-select
v-model:value="searchFormState.enabledState"
placeholder="请选择状态"
:options="tool.dictList('COMMON_STATUS')"
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="编码" name="number">
<a-input v-model:value="searchFormState.number" placeholder="请输入编码" />
</a-form-item>
</a-col>
<a-col :span="6" v-show="advanced">
<a-form-item label="是否基本单位" name="isBase">
<a-select
v-model:value="searchFormState.isBase"
placeholder="请选择是否基本单位"
:options="tool.dictList('YES_NO')"
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-button type="primary" @click="tableRef.refresh()"></a-button>
<a-button style="margin: 0 8px" @click="reset"></a-button>
<a @click="toggleAdvanced" style="margin-left: 8px">
{{ advanced ? '收起' : '展开' }}
<component :is="advanced ? 'up-outlined' : 'down-outlined'" />
</a>
</a-col>
</a-row>
</a-form>
</a-card>
<a-card class="mt-4" :border="false" style="height: 100%"> <a-card class="mt-4" :border="false" style="height: 100%">
<a-row :gutter="24"> <a-row :gutter="24">
@ -58,19 +22,15 @@
@deleteRowData="handleDeleteRowData" @deleteRowData="handleDeleteRowData"
@refresh="handleRefresh" @refresh="handleRefresh"
:rowSelection="unitGroupRowSelection" :rowSelection="unitGroupRowSelection"
:scroll="{
y: 500
}"
> >
<template #operator class="table-operator"> <template #operator>
<span>单位组</span> <span>单位组</span>
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'enabledState'"> <template v-if="column.dataIndex === 'enabledState'">
<!-- <a-switch
checkedValue="ENABLE"
unCheckedValue="DISABLED"
checked-children="启用"
un-checked-children="停用"
v-model:checked="record.enabledState"
/>-->
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag> <a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
<a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag> <a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag>
</template> </template>
@ -88,7 +48,8 @@
:tool-config="options.toolConfig" :tool-config="options.toolConfig"
:row-selection="options.rowSelection" :row-selection="options.rowSelection"
:scroll="{ :scroll="{
x: 100 x: 100,
y: 500
}" }"
> >
<template #operator> <template #operator>
@ -100,13 +61,13 @@
type: 'ADD' type: 'ADD'
}) })
" "
v-if="hasPerm('customerAdd')" v-if="hasPerm('sysUnitAdd')"
> >
<template #icon><plus-outlined /></template> <template #icon><plus-outlined /></template>
新增 新增
</a-button> </a-button>
<xn-batch-delete <xn-batch-delete
v-if="hasPerm('customerBatchDelete')" v-if="hasPerm('sysUnitBatchDelete')"
:selectedRowKeys="selectedRowKeys" :selectedRowKeys="selectedRowKeys"
@batchDelete="deleteBatchRecords" @batchDelete="deleteBatchRecords"
/> />
@ -114,7 +75,7 @@
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'number'"> <template v-if="column.dataIndex === 'number'">
<a href="#">{{ record.number }}</a> <span style="color: #0d84ff">{{ record.number }}</span>
</template> </template>
<template v-if="column.dataIndex === 'enabledState'"> <template v-if="column.dataIndex === 'enabledState'">
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag> <a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
@ -133,15 +94,14 @@
id: record.id id: record.id
}) })
" "
v-if="hasPerm('customerEdit')" v-if="hasPerm('sysUnitEdit')"
> >
<EyeOutlined /> <EyeOutlined />
<!-- 查看--> <!-- 查看-->
</a> </a>
</a-tooltip> </a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['sysUnitEdit', 'sysUnitDelete'], 'and')" />
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" /> <a-tooltip title="编辑">
<a-tooltip title="查看">
<a <a
@click=" @click="
navigateTo('/basicData/unit/detail', { navigateTo('/basicData/unit/detail', {
@ -149,16 +109,15 @@
id: record.id id: record.id
}) })
" "
v-if="hasPerm('customerEdit')" v-if="hasPerm('sysUnitEdit')"
> >
<FormOutlined /> <FormOutlined />
<!-- 编辑--> <!-- 编辑-->
</a> </a>
</a-tooltip> </a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['sysUnitEdit', 'sysUnitDelete'], 'and')" />
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)"> <a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')"> <a-button type="link" danger size="small" v-if="hasPerm('sysUnitDelete')">
<DeleteOutlined /> <DeleteOutlined />
<!-- 删除--> <!-- 删除-->
</a-button> </a-button>
@ -182,7 +141,7 @@
import { unitColumns, unitGroupColumns } from '@/views/productionBusiness/basicData/unit/columns/unitColumns' import { unitColumns, unitGroupColumns } from '@/views/productionBusiness/basicData/unit/columns/unitColumns'
import UnitGroupForm from '@/views/productionBusiness/basicData/unit/detail/UnitGroupForm.vue' import UnitGroupForm from '@/views/productionBusiness/basicData/unit/detail/UnitGroupForm.vue'
import { useTableManagement } from '@/hook/useTableManagement' import { useTableManagement } from '@/hook/useTableManagement'
import tool from '@/utils/tool' import { searchFields } from '@/views/productionBusiness/basicData/unit/formFields/searchFields'
// ------------------------------ REF ------------------------------ // // ------------------------------ REF ------------------------------ //
const { const {
@ -191,13 +150,9 @@
selectedRowKeys, selectedRowKeys,
columns, columns,
loadData, loadData,
reset,
deleteBatchRecords, deleteBatchRecords,
options, options,
searchFormRef,
navigateTo, navigateTo,
toggleAdvanced,
advanced,
deleteRecord deleteRecord
} = useTableManagement( } = useTableManagement(
{ {
@ -216,9 +171,9 @@
height: true, height: true,
columnSetting: true, columnSetting: true,
striped: false, striped: false,
plus: true, plus: hasPerm('sysUnitGroupAdd'),
edit: true, edit: hasPerm('sysUnitGroupEdit'),
delete: true delete: hasPerm('sysUnitGroupDelete')
} }
let unitGroupRecord = '' let unitGroupRecord = ''
let unitGroupSelectedRowKeys = ref([]) let unitGroupSelectedRowKeys = ref([])
@ -258,10 +213,10 @@
]) ])
.then(() => { .then(() => {
searchFormState.value.unitGroupId = '' searchFormState.value.unitGroupId = ''
tableRef.value.clearSelected()
tableRef.value.refresh() tableRef.value.refresh()
unitGroupTableRef.value.refresh() unitGroupTableRef.value.refresh()
tableRef.value.clearSelected()
unitGroupTableRef.value.clearSelected() unitGroupTableRef.value.clearSelected()
}) })
} }

View File

@ -80,6 +80,7 @@
pageType.value = record.pageType pageType.value = record.pageType
let recordData = cloneDeep(record) let recordData = cloneDeep(record)
formData.value = Object.assign({}, recordData) formData.value = Object.assign({}, recordData)
console.log(formData.value)
} else { } else {
pageType.value = 'ADD' pageType.value = 'ADD'
formData.value = formData_enum formData.value = formData_enum
@ -104,7 +105,6 @@
formRef.value.validate().then(() => { formRef.value.validate().then(() => {
submitLoading.value = true submitLoading.value = true
const formDataParam = cloneDeep(formData.value) const formDataParam = cloneDeep(formData.value)
employeeCategoryApi employeeCategoryApi
.employeeCategorySubmitForm(formDataParam, formDataParam.id) .employeeCategorySubmitForm(formDataParam, formDataParam.id)
.then(() => { .then(() => {

View File

@ -128,16 +128,24 @@
import LineSelectorPlus from '@/components/Selector/lineSelectorPlus.vue' import LineSelectorPlus from '@/components/Selector/lineSelectorPlus.vue'
import EmployeeSelectorPlus from '@/components/Selector/employeeSelectorPlus.vue' import EmployeeSelectorPlus from '@/components/Selector/employeeSelectorPlus.vue'
import PersonnelForm from '@/views/productionBusiness/employee/personnelReport/detail/personnelForm.vue' import PersonnelForm from '@/views/productionBusiness/employee/personnelReport/detail/personnelForm.vue'
import AddPersonnelItem from '@/views/productionBusiness/employee/personnelReport/detail/addPersonnelItem.vue'
import tool from '@/utils/tool' import tool from '@/utils/tool'
import useFormHandler from '@/hook/useFormHandler' import useFormHandler from '@/hook/useFormHandler'
import { required } from '@/utils/formRules' import { required } from '@/utils/formRules'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
import AddPersonnelItem from '@/views/productionBusiness/employee/personnelReport/detail/addPersonnelItem.vue' import dayjs from 'dayjs'
const route = useRoute() const route = useRoute()
const currentDay = dayjs().format('YYYY-MM-DD')
//
const disabledDate = (current) => {
//
return current && current > dayjs().endOf('day')
}
const basicInfoFormItems = [ const basicInfoFormItems = [
{ {
label: '单号:', label: '单号:',
@ -157,8 +165,10 @@
placeholder: '请输入开工日期', placeholder: '请输入开工日期',
allowClear: true, allowClear: true,
valueFormat: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'YYYY-MM-DD HH:mm:ss',
disabled: route.query.type !== 'ADD' disabled: route.query.type !== 'ADD',
} disabledDate: disabledDate
},
defaultValue: dayjs(currentDay, 'YYYY-MM-DD')
}, },
{ {
label: '产品(物料)', label: '产品(物料)',

View File

@ -155,7 +155,7 @@
ellipsis: true ellipsis: true
}, },
{ {
title: '任务单名称', title: '产线名称',
dataIndex: 'productionLineName', dataIndex: 'productionLineName',
align: 'center', align: 'center',
resizable: true, resizable: true,

View File

@ -93,7 +93,10 @@
</a> </a>
</a-tooltip> </a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" /> <a-divider
type="vertical"
v-if="hasPerm(['customerEdit', 'customerDelete'], 'and') && record.state !== '2'"
/>
<a-tooltip title="查看"> <a-tooltip title="查看">
<a <a
@click=" @click="
@ -102,16 +105,19 @@
id: record.id id: record.id
}) })
" "
v-if="hasPerm('customerEdit')" v-if="hasPerm('customerEdit') && record.state !== '2'"
> >
<FormOutlined /> <FormOutlined />
<!-- 编辑--> <!-- 编辑-->
</a> </a>
</a-tooltip> </a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" /> <a-divider
type="vertical"
v-if="hasPerm(['customerEdit', 'customerDelete'], 'and') && record.state !== '2'"
/>
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)"> <a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')"> <a-button type="link" danger size="small" v-if="hasPerm('customerDelete') && record.state !== '2'">
<DeleteOutlined /> <DeleteOutlined />
<!-- 删除--> <!-- 删除-->
</a-button> </a-button>