基础资料模块

main
GaoF 2024-07-27 13:28:17 +08:00
parent 11e6f17532
commit 59d9d4e4c1
8 changed files with 475 additions and 58 deletions

View File

@ -1,9 +1,9 @@
<template> <template>
<a-form :model="model" :rules="rules" layout="vertical" ref="formRef"> <a-form :model="model" :rules="rules" layout="vertical" ref="formRef">
<a-row :gutter="16"> <a-row :gutter="16">
<a-col :span="col.span || 24" v-for="(item, index) in formItems" :key="index"> <a-col :span="item.span || 6" v-for="(item, index) in formItems" :key="index">
<a-form-item :label="item.label" :name="item.name" :rules="item.rules"> <a-form-item :label="item.label" :name="item.name" :rules="item.rules">
<component :is="item.type" v-model:value="model[item.name]" v-bind="item.attrs" /> <component :is="item.type" v-model:value="model[item.name]" v-bind="item.attrs" :disabled="allDisabled" />
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
@ -26,9 +26,9 @@
type: Object, type: Object,
default: () => ({}) default: () => ({})
}, },
col: { allDisabled: {
type: Object, type: Boolean,
default: () => ({ span: 8 }) default: false
} }
}) })
@ -36,7 +36,8 @@
// Expose validate method // Expose validate method
defineExpose({ defineExpose({
validate: () => formRef.value.validate() validate: () => formRef.value.validate(),
resetFields: () => formRef.value.resetFields()
}) })
</script> </script>

View File

@ -0,0 +1,144 @@
<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"
/>
</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

@ -38,17 +38,20 @@
<component class="icons" :is="item.icon"></component> <component class="icons" :is="item.icon"></component>
</a-tooltip> </a-tooltip>
<!-- 删除 --> <!-- 删除 -->
<a-tooltip <a-tooltip v-if="item.name === 'delete' && props.toolConfig.delete" :title="item.title" class="s-tool-item">
<a-popconfirm
v-if="item.name === 'delete' && props.toolConfig.delete" v-if="item.name === 'delete' && props.toolConfig.delete"
:title="item.title" title="确认删除?"
class="s-tool-item" ok-text="Yes"
@click=" cancel-text="No"
@confirm="
() => { () => {
emit('deleteRowData') emit('deleteRowData')
} }
" "
> >
<component class="icons" :is="item.icon"></component> <component class="icons" :is="item.icon"></component>
</a-popconfirm>
</a-tooltip> </a-tooltip>
<!-- 刷新 --> <!-- 刷新 -->
<a-tooltip <a-tooltip
@ -575,7 +578,6 @@
size: data.customSize, // sizea-tablecompSize size: data.customSize, // sizea-tablecompSize
columns: data.columnsSetting.filter((value) => value.checked === undefined || value.checked), columns: data.columnsSetting.filter((value) => value.checked === undefined || value.checked),
...data.localSettings, ...data.localSettings,
scroll: { x: 100 }
} }
// undefined null tableprops // undefined null tableprops
renderTableProps.value = Object.entries(renderProps).reduce((x, [y, z]) => (z == null ? x : ((x[y] = z), x)), {}) renderTableProps.value = Object.entries(renderProps).reduce((x, [y, z]) => (z == null ? x : ((x[y] = z), x)), {})

View File

@ -52,7 +52,6 @@
<right-outlined /> <right-outlined />
</div> </div>
</template> </template>
<a-tab-pane v-for="tag in tagList" :key="tag.fullPath" :tab="tag.meta.title" :closable="!tag.meta.affix"> <a-tab-pane v-for="tag in tagList" :key="tag.fullPath" :tab="tag.meta.title" :closable="!tag.meta.affix">
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>

View File

@ -31,6 +31,7 @@ export default {
close(tag) { close(tag) {
const route = tag || router.currentRoute.value const route = tag || router.currentRoute.value
const store = viewTagsStore() const store = viewTagsStore()
console.log(route, 'route')
store.removeViewTags(route) store.removeViewTags(route)
iframeStore().removeIframeList(route) iframeStore().removeIframeList(route)
keepAliveStore().removeKeepLive(route.name) keepAliveStore().removeKeepLive(route.name)

View File

@ -0,0 +1,170 @@
<template>
<xn-form-container
:title="formData.id ? '编辑客户' : '增加客户'"
:width="700"
:visible="visible"
:destroy-on-close="true"
@close="onClose"
>
<a-form ref="formRef" :model="formData" :rules="formRules" layout="horizontal">
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="名称:" name="name">
<a-input v-model:value="formData.name" placeholder="请输入名称" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="编码:" name="number">
<a-input v-model:value="formData.number" placeholder="请输入编码" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="简称:" name="shortName">
<a-input v-model:value="formData.shortName" placeholder="请输入简称" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="客户分类ID" name="categoryId">
<a-input v-model:value="formData.categoryId" placeholder="请输入客户分类ID" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="品牌:" name="brandId">
<a-input v-model:value="formData.brandId" placeholder="请输入品牌" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="省:" name="province">
<a-input v-model:value="formData.province" placeholder="请输入省" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="市:" name="city">
<a-input v-model:value="formData.city" placeholder="请输入市" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="县:" name="county">
<a-input v-model:value="formData.county" placeholder="请输入县" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="详细地址 " name="address">
<a-input v-model:value="formData.address" placeholder="请输入详细地址 " allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="启用状态:" name="enabledState">
<a-radio-group
v-model:value="formData.enabledState"
placeholder="请选择启用状态"
:options="enabledStateOptions"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="联系人:" name="contacts">
<a-input v-model:value="formData.contacts" placeholder="请输入联系人" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="手机:" name="phone">
<a-input v-model:value="formData.phone" placeholder="请输入手机" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="固话:" name="tel">
<a-input v-model:value="formData.tel" placeholder="请输入固话" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="传真:" name="fax">
<a-input v-model:value="formData.fax" placeholder="请输入传真" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="电子邮箱:" name="email">
<a-input v-model:value="formData.email" placeholder="请输入电子邮箱" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="qq" name="qq">
<a-input v-model:value="formData.qq" placeholder="请输入qq" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="微信号:" name="wechat">
<a-input v-model:value="formData.wechat" placeholder="请输入微信号" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="联系地址:" name="contactAddress">
<a-input v-model:value="formData.contactAddress" placeholder="请输入联系地址" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="扩展信息:" name="extJson">
<a-input v-model:value="formData.extJson" placeholder="请输入扩展信息" allow-clear />
</a-form-item>
</a-col>
</a-row>
</a-form>
<template #footer>
<a-button style="margin-right: 8px" @click="onClose"></a-button>
<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
</template>
</xn-form-container>
</template>
<script setup name="customerForm">
import tool from '@/utils/tool'
import { cloneDeep } from 'lodash-es'
import { required } from '@/utils/formRules'
import customerCategoryApi from '@/api/base/customer/customerCategoryApi'
//
const visible = ref(false)
const emit = defineEmits({ successful: null })
const formRef = ref()
//
const formData = ref({})
const submitLoading = ref(false)
const enabledStateOptions = ref([])
//
const onOpen = (record) => {
visible.value = true
if (record) {
let recordData = cloneDeep(record)
formData.value = Object.assign({}, recordData)
}
enabledStateOptions.value = tool.dictList('COMMON_STATUS')
}
//
const onClose = () => {
formRef.value.resetFields()
formData.value = {}
visible.value = false
}
//
const formRules = {}
//
const onSubmit = () => {
formRef.value.validate().then(() => {
submitLoading.value = true
const formDataParam = cloneDeep(formData.value)
customerCategoryApi
.customerSubmitForm(formDataParam, formDataParam.id)
.then(() => {
onClose()
emit('successful')
})
.finally(() => {
submitLoading.value = false
})
})
}
//
defineExpose({
onOpen
})
</script>

View File

@ -11,8 +11,16 @@
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical"> <a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
<a-row :gutter="16"> <a-row :gutter="16">
<a-col :span="6"> <a-col :span="6">
<a-form-item label="单位组:" name="name"> <a-form-item label="单位组:" name="unitGroupId">
<a-input v-model:value="formData.name" placeholder="请输入名称" allow-clear /> <a-select
v-model:value="formData.unitGroupId"
placeholder="请选择单位组"
:options="unitGroupList"
:fieldNames="{
label: 'name',
value: 'id'
}"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
@ -26,9 +34,9 @@
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<a-form-item label="可用状态:" name="code"> <a-form-item label="可用状态:">
<a-select <a-select
v-model:value="formData.code" v-model:value="formData.enabledState"
placeholder="请选择可用状态" placeholder="请选择可用状态"
:options="tool.dictList('COMMON_STATUS')" :options="tool.dictList('COMMON_STATUS')"
/> />
@ -42,9 +50,9 @@
<a-col :span="6"> <a-col :span="6">
<a-form-item label="是否基本单位:" name="isBase"> <a-form-item label="是否基本单位:" name="isBase">
<a-select <a-select
v-model:value="formData.code" v-model:value="formData.isBase"
placeholder="请选择是否基本单位" placeholder="请选择是否基本单位"
:options="tool.dictList('COMMON_STATUS')" :options="tool.dictList('YES_NO')"
/> />
</a-form-item> </a-form-item>
</a-col> </a-col>
@ -64,30 +72,38 @@
import { required } from '@/utils/formRules' import { required } from '@/utils/formRules'
import useTabs from '@/utils/useTabs' import useTabs from '@/utils/useTabs'
import router from '@/router' import router from '@/router'
import unitGroupsApi from '@/api/base/unit/unitGroupsApi'
import unitApi from '@/api/base/unit/unitApi'
import { useRoute } from 'vue-router'
const useRouter = useRoute()
// //
const visible = ref(false) const visible = ref(false)
const emit = defineEmits({ successful: null }) const emit = defineEmits({ successful: null })
const formRef = ref() const formRef = ref()
// //
const formData = ref({}) const formData = ref({
enabledState: 'ENABLE',
isBase: 'NO'
})
const submitLoading = ref(false) const submitLoading = ref(false)
const stateOptions = ref([])
const isBaseOptions = ref([])
// //
const formRules = { const formRules = {
unitGroupId: [required('请选择单位')],
name: [required('请输入名称')], name: [required('请输入名称')],
unitGroupId: [required('请输入单位组id')] isBase: [required('请选择是否基本单位')]
} }
// //
const onSubmit = () => { const onSubmit = () => {
formRef.value.validate().then(() => { formRef.value.validate().then(() => {
submitLoading.value = true submitLoading.value = true
const formDataParam = cloneDeep(formData.value) const formDataParam = cloneDeep(formData.value)
sysUnitApi unitApi
.sysUnitSubmitForm(formDataParam, formDataParam.id) .sysUnitSubmitForm(formDataParam, formDataParam.id)
.then(() => { .then(() => {
emit('successful') // emit('successful')
handleBack()
}) })
.finally(() => { .finally(() => {
submitLoading.value = false submitLoading.value = false
@ -96,7 +112,34 @@
} }
// //
const handleBack = () => { const handleBack = () => {
router.go(-1) router.replace('/basicData/unit')
useTabs.close() useTabs.close()
} }
let state = reactive({
PAGE_TYPE: ''
})
let unitGroupList = ref([])
onMounted(() => {
//
unitGroupsApi
.sysUnitGroupList({
enabledState: 'ENABLE'
})
.then((res) => {
unitGroupList.value = res
})
state.PAGE_TYPE = useRouter.query.type
if (state.PAGE_TYPE && state.PAGE_TYPE !== 'ADD') {
state.detailId = useRouter.query.id
unitApi
.sysUnitDetail({
id: useRouter.query.id
})
.then((res) => {
formData.value = res
})
}
})
</script> </script>

View File

@ -44,36 +44,42 @@
</a-card> </a-card>
<a-card class="mt-4" :border="false"> <a-card class="mt-4" :border="false">
<a-row :gutter="20"> <a-row :gutter="30">
<a-col :span="8"> <a-col :span="6">
<s-table <s-table
ref="unitTableRef" ref="unitGroupTableRef"
:columns="unitGroupColumns" :columns="unitGroupColumns"
:data="loadGroupsData" :data="loadGroupsData"
bordered bordered
:row-key="(record) => record.id" :row-key="(record) => record.id"
:tool-config="unitGroupToolConfig" :tool-config="unitGroupToolConfig"
:row-selection="options.rowSelection"
@plusRowData="handlePlusRowData" @plusRowData="handlePlusRowData"
@editRowData="handleEditRowData" @editRowData="handleEditRowData"
@deleteRowData="handleDeleteRowData" @deleteRowData="handleDeleteRowData"
:rowSelection="{
type: 'radio',
onChange: unitGroupOnChange
}"
> >
<template #operator class="table-operator"> <template #operator class="table-operator">
<span>单位组</span> <span>单位组</span>
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'state'"> <template v-if="column.dataIndex === 'enabledState'">
{{ $TOOL.dictTypeData('COMMON_STATUS', record.state) }} <a-switch
</template> checkedValue="ENABLE"
<template v-if="column.dataIndex === 'isBase'"> unCheckedValue="DISABLED"
{{ $TOOL.dictTypeData('YES_NO', record.isBase) }} checked-children="启用"
un-checked-children="停用"
v-model:checked="record.enabledState"
/>
</template> </template>
</template> </template>
</s-table> </s-table>
</a-col> </a-col>
<a-col :span="16"> <a-col :span="18">
<s-table <s-table
ref="unitGroupTableRef" ref="unitTableRef"
:columns="unitColumns" :columns="unitColumns"
:data="loadData" :data="loadData"
:alert="options.alert.show" :alert="options.alert.show"
@ -104,15 +110,40 @@
</a-space> </a-space>
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'state'"> <template v-if="column.dataIndex === 'enabledState'">
{{ $TOOL.dictTypeData('COMMON_STATUS', record.state) }} <a-switch
checkedValue="ENABLE"
unCheckedValue="DISABLED"
checked-children="启用"
un-checked-children="停用"
v-model:checked="record.enabledState"
/>
</template> </template>
<template v-if="column.dataIndex === 'isBase'"> <template v-if="column.dataIndex === 'isBase'">
{{ $TOOL.dictTypeData('YES_NO', record.isBase) }} {{ $TOOL.dictTypeData('YES_NO', record.isBase) }}
</template> </template>
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
<a-space> <a-space>
<a @click="formRef.onOpen(record)" v-if="hasPerm('sysUnitEdit')"></a> <a
@click="
navigateTo('/basicData/unit/detail', {
type: 'SEARCH',
id: record.id
})
"
>查看</a
>
<a-divider type="vertical" />
<a
@click="
navigateTo('/basicData/unit/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('sysUnitEdit')"
>编辑</a
>
<a-divider type="vertical" v-if="hasPerm(['sysUnitEdit', 'sysUnitDelete'], 'and')" /> <a-divider type="vertical" v-if="hasPerm(['sysUnitEdit', 'sysUnitDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteSysUnit(record)"> <a-popconfirm title="确定要删除吗?" @confirm="deleteSysUnit(record)">
<a-button type="link" danger size="small" v-if="hasPerm('sysUnitDelete')"></a-button> <a-button type="link" danger size="small" v-if="hasPerm('sysUnitDelete')"></a-button>
@ -125,7 +156,7 @@
</a-row> </a-row>
</a-card> </a-card>
<!-- <Form ref="formRef" @successful="tableRef.refresh()" />--> <!-- <Form ref="formRef" @successful="tableRef.refresh()" />-->
<unit-group-form ref="UnitGroupFormRef"></unit-group-form> <unit-group-form ref="UnitGroupFormRef" @successful="successful"></unit-group-form>
</template> </template>
<script setup name="sysunit"> <script setup name="sysunit">
@ -137,6 +168,7 @@
// import Form from './form.vue' // import Form from './form.vue'
import sysUnitApi from '@/api/base/unit/unitApi' import sysUnitApi from '@/api/base/unit/unitApi'
import sysUnitGroupsApi from '@/api/base/unit/unitGroupsApi' import sysUnitGroupsApi from '@/api/base/unit/unitGroupsApi'
import { message } from 'ant-design-vue'
const searchFormState = ref({}) const searchFormState = ref({})
const searchFormRef = ref() const searchFormRef = ref()
@ -160,6 +192,8 @@
} }
// //
if (hasPerm(['sysUnitEdit', 'sysUnitDelete'])) { if (hasPerm(['sysUnitEdit', 'sysUnitDelete'])) {
const columnsFilter = unitColumns.filter((item) => item.dataIndex === 'action')
if (columnsFilter.length === 0)
unitColumns.push({ unitColumns.push({
title: '操作', title: '操作',
dataIndex: 'action', dataIndex: 'action',
@ -225,13 +259,36 @@
const { navigateTo } = useNavigation() const { navigateTo } = useNavigation()
// //
let unitGroupRecord = ''
const handlePlusRowData = () => { const handlePlusRowData = () => {
UnitGroupFormRef.value.onOpen() UnitGroupFormRef.value.onOpen()
} }
const handleEditRowData = () => { const handleEditRowData = () => {
UnitGroupFormRef.value.onOpen() if (!unitGroupRecord) return message.error('请选择单位组数据')
UnitGroupFormRef.value.onOpen(unitGroupRecord)
} }
const handleDeleteRowData = () => {} const handleDeleteRowData = () => {
if (!unitGroupRecord) return message.error('请选择单位组数据')
sysUnitGroupsApi
.sysUnitGroupDelete([
{
id: unitGroupRecord.id
}
])
.then(() => {
unitGroupTableRef.value.refresh()
})
}
const successful = () => {
unitGroupTableRef.value.refresh()
}
const unitGroupOnChange = (value, selectedOptions) => {
unitGroupRecord = selectedOptions[0]
searchFormState.value.unitGroupId = value[0]
unitTableRef.value.refresh()
}
</script> </script>