基础资料模块优化

main
GaoF 2024-07-30 17:47:29 +08:00
parent efd984fe17
commit 1a68eb4423
21 changed files with 1103 additions and 686 deletions

View File

@ -3,7 +3,13 @@
<a-row :gutter="16">
<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">
<component style="width: 100%" :is="item.type" v-model:value="model[item.name]" :disabled="allDisabled" v-bind="item.attrs" />
<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-row>

View File

@ -0,0 +1,56 @@
<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

@ -23,6 +23,7 @@
:is="getComponent(column.dataType)"
v-model:value="record[column.dataIndex]"
:options="column.options"
v-bind="column.attrs"
/>
</template>
<template v-else>

View File

@ -0,0 +1,186 @@
<template>
<div>
<div class="s-table-tool">
<div class="s-table-tool-left">{{ treeTitle }}</div>
<div class="layout-items-center s-table-tool-right">
<span v-for="item in tool" :key="item.name">
<!-- 新增 -->
<a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'plus' && props.toolConfig.plus">
<component class="icons" :is="item.icon" @click="handleAddTree"></component>
</a-tooltip>
<!-- 修改 -->
<a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'edit' && props.toolConfig.edit">
<component class="icons" :is="item.icon" @click="handleEditTree"></component>
</a-tooltip>
<!-- 删除 -->
<a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'delete' && props.toolConfig.delete">
<a-popconfirm title="确定要删除吗?" ok-text="" cancel-text="" @confirm="handleDelTree">
<component class="icons" :is="item.icon"></component>
</a-popconfirm>
</a-tooltip>
<!-- 刷新 -->
<a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'refresh' && props.toolConfig.refresh">
<component class="icons" :is="item.icon" @click="loadTreeData()"></component>
</a-tooltip>
</span>
</div>
</div>
<a-directory-tree
show-line
v-model:expandedKeys="expandedKeys"
v-model:selectedKeys="selectedKeys"
multiple
:fieldNames="{
children: 'children',
title: 'name',
key: 'id'
}"
:tree-data="treeData"
@select="handleTreeClick"
></a-directory-tree>
</div>
</template>
<script setup>
import { message } from 'ant-design-vue'
const props = defineProps({
// data
treeData: {
type: Array,
default: () => []
},
treeTitle: {
type: String,
default: ''
},
//
toolConfig: {
type: Object,
default: () => ({
plus: true,
edit: true,
delete: true,
refresh: true
})
},
apiModel: {
type: Object,
default: () => {
return {
getTree: () => {},
addTree: () => {},
delTree: () => {}
}
}
},
openFormRef: {
type: Object,
default: () => {}
},
tableRef: {
type: Object,
default: () => {}
}
})
const emit = defineEmits('selectTree', 'delTree')
const tool = [
{
name: 'plus',
icon: 'plus-outlined',
title: '新增'
},
{
name: 'edit',
icon: 'edit-outlined',
title: '编辑'
},
{
name: 'delete',
icon: 'delete-outlined',
title: '删除'
},
{
name: 'refresh',
icon: 'ReloadOutlined',
title: '刷新'
}
]
//
const expandedKeys = ref()
const selectedKeys = ref([])
const treeData = ref([])
let treeRow = {}
const handleTreeClick = (selectedKeys, event) => {
treeRow = event.node
emit('selectTree', treeRow)
}
const handleAddTree = () => {
props.openFormRef.onOpen()
}
const handleEditTree = () => {
if (!treeRow.id) return message.error('!请选择要编辑的数据')
props.openFormRef.onOpen(treeRow)
}
const handleDelTree = () => {
if (!treeRow.id) return message.error('!请选择要删除的数据')
props.apiModel.delTree([{ id: treeRow.id }]).then((res) => {
selectedKeys.value = []
treeRow = {}
emit('delTree', treeRow)
loadTreeData()
})
}
const loadTreeData = async () => {
try {
const treeRes = await props.apiModel.getTree()
if (Array.isArray(treeRes)) {
treeData.value = treeRes
} else {
treeData.value = []
}
if (selectedKeys.value.length > 0) {
selectedKeys.value = []
props.tableRef.refresh()
}
if (treeRow.id) {
treeRow = []
}
} catch (e) {
message.error('获取树结构数据失败:' + e)
console.error('获取树结构数据失败:' + e)
}
}
defineExpose({
loadTreeData
})
</script>
<style lang="less" scoped>
.s-table-tool {
display: flex;
margin-bottom: 16px;
.s-table-tool-left {
flex: 1;
}
.s-table-tool-right {
.s-tool-item {
font-size: 16px;
@apply ml-4;
cursor: pointer;
}
}
}
</style>

View File

@ -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, // sizea-tablecompSize
columns: data.columnsSetting.filter((value) => value.checked === undefined || value.checked),
...data.localSettings,
...data.localSettings
}
// undefined null tableprops
renderTableProps.value = Object.entries(renderProps).reduce((x, [y, z]) => (z == null ? x : ((x[y] = z), x)), {})

View File

@ -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<Object>} 返回获取的详情数据
*/
const fetchData = async (pageType) => {
initializeFormData(formItems, formData)
if (pageType && pageType !== 'ADD') {
try {
const res = await api.getDetail({ id: route.query.id })
// 根据返回的详情数据初始化表单数据
for (let key in formData) {
if (res[key] !== undefined) {
formData[key] = res[key]
@ -66,6 +112,7 @@ export default function useFormHandler(formItems, api) {
}
}
// 返回包含各种处理函数和状态的对象
return {
formData,
submitLoading,

View File

@ -7,33 +7,49 @@ import useTabs from '@/utils/useTabs'
* 列表页面表格信息 hook 封装数据操作
* @param apiModule 调用接口
* @param tableColumns 表格头部信息
* @param hasPermData
* @returns {{searchFormRef: Ref<UnwrapRef<{}>>, toolConfig: {columnSetting: boolean, striped: boolean, refresh: boolean, height: boolean}, searchFormState: Ref<UnwrapRef<{}>>, tableRef: Ref<UnwrapRef<null>>, selectedRowKeys: Ref<UnwrapRef<*[]>>, columns: Ref<UnwrapRef<unknown>>, options: {rowSelection: {onChange: options.rowSelection.onChange}, alert: {show: boolean, clear: options.alert.clear}}, reset: reset, loadData: (function(*): *), deleteBatchRecords: deleteBatchRecords, deleteRecord: deleteRecord}}
*/
export function useTableManagement(apiModule = {}, tableColumns, hasPermData) {
const searchFormState = ref({})
const searchFormRef = ref(null)
const tableRef = ref(null)
const selectedRowKeys = ref([])
const router = useRouter()
let advanced = ref(false)
const router = useRouter()
const tableRef = ref(null)
// 动态列配置
const columns = ref(tableColumns)
const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
// 选择配置
const options = {
alert: {
show: true,
clear: () => {
selectedRowKeys.value = []
}
},
rowSelection: {
onChange: (selectedRowKey, selectedRows) => {
selectedRowKeys.value = selectedRowKey
}
},
toolConfig: { refresh: true, height: true, columnSetting: true, striped: false }
}
// 根据权限添加操作列
if (hasPerm(hasPermData)) {
// 判断columns 是否有操作
const columnsFilter = columns.value.filter((item) => item.dataIndex === 'action')
if (columnsFilter.length === 0)
columns.value.push({
columns.value.unshift({
title: '操作',
dataIndex: 'action',
align: 'center',
width: 200,
fixed: 'right',
max_width: 100
width: 150,
fixed: 'left'
})
}
@ -72,21 +88,6 @@ export function useTableManagement(apiModule = {}, tableColumns, hasPermData) {
})
}
// 选择配置
const options = {
alert: {
show: true,
clear: () => {
selectedRowKeys.value = []
}
},
rowSelection: {
onChange: (selectedRowKey, selectedRows) => {
selectedRowKeys.value = selectedRowKey
}
}
}
// 页面跳转
const navigateTo = (to, params) => {
router.push({
@ -106,14 +107,13 @@ export function useTableManagement(apiModule = {}, tableColumns, hasPermData) {
tableRef,
selectedRowKeys,
columns,
options,
advanced,
loadData,
reset,
deleteRecord,
deleteBatchRecords,
options,
toolConfig,
navigateTo,
toggleAdvanced,
advanced
toggleAdvanced
}
}

View File

@ -0,0 +1,18 @@
export const brandColumns = [
{
title: '编码',
dataIndex: 'number'
},
{
title: '名称',
dataIndex: 'name'
},
{
title: '可用状态',
dataIndex: 'enabledState'
},
{
title: '创建时间',
dataIndex: 'createTime'
}
]

View File

@ -129,7 +129,7 @@
const formRef1 = ref(null)
let { state, formData, formRefs, onSubmit, handleBack, fetchData } = useFormHandler(brandFormItems, {
let { formData, formRefs, onSubmit, handleBack, fetchData } = useFormHandler(brandFormItems, {
submitForm: sysBrandApi.sysBrandSubmitForm,
getDetail: sysBrandApi.sysBrandDetail
})

View File

@ -29,7 +29,7 @@
</a-form>
</a-card>
<a-card :bordered="false" class="mt-4">
<a-card :bordered="false" class="mt-4" style="height: 100%">
<s-table
ref="tableRef"
:columns="columns"
@ -37,10 +37,14 @@
:alert="options.alert.show"
bordered
:row-key="(record) => record.id"
:tool-config="toolConfig"
:tool-config="options.toolConfig"
:row-selection="options.rowSelection"
:scroll="{
x: 100,
y: 'calc(100vh - 300px)'
}"
>
<template #operator class="table-operator">
<template #operator>
<a-space>
<a-button
type="primary"
@ -62,42 +66,52 @@
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'number'">
<a href="#">{{ record.number }}</a>
</template>
<template v-if="column.dataIndex === 'enabledState'">
<!-- <a-switch
checkedValue="ENABLE"
unCheckedValue="DISABLED"
checked-children="启用"
un-checked-children="停用"
v-model:checked="record.enabledState"
/>-->
{{ $TOOL.dictTypeData('COMMON_STATUS', record.enabledState) }}
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
<a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag>
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a
@click="
navigateTo('/basicData/brand/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('sysBrandEdit')"
>查看</a
>
<a-divider type="vertical" v-if="hasPerm(['sysBrandEdit', 'sysBrandDelete'], 'and')" />
<a
@click="
navigateTo('/basicData/brand/detail', {
type: 'EDIT',
id: record.id
})
"
v-if="hasPerm('sysBrandEdit')"
>编辑</a
>
<a-divider type="vertical" v-if="hasPerm(['sysBrandEdit', 'sysBrandDelete'], 'and')" />
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/brand/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<EyeOutlined />
<!-- 查看-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/brand/detail', {
type: 'EDIT',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<FormOutlined />
<!-- 编辑-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('sysBrandDelete')"></a-button>
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button>
</a-popconfirm>
</a-space>
</template>
@ -114,7 +128,7 @@
{
title: '编码',
dataIndex: 'number',
sorter: (a, b) => a.number.length - b.number.length,
sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
@ -124,8 +138,6 @@
{
title: '名称',
dataIndex: 'name',
sorter: (a, b) => a.name.length - b.name.length,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
width: 300,
@ -142,7 +154,7 @@
{
title: '创建时间',
dataIndex: 'createTime',
sorter: (a, b) => a.createTime.length - b.createTime.length,
sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,

View File

@ -1,7 +1,7 @@
<template>
<a-page-header style="padding: 10px; font-size: 20px" @back="handleBack">
<template #extra>
<a-button v-if="route.query.type !== 'SEARCH'" key="1" type="primary" @click="onSubmit"></a-button>
<a-button v-if="route.query.type !== 'SEARCH'" key="1" type="primary" @click="onSubmitForm"></a-button>
</template>
</a-page-header>
@ -27,7 +27,48 @@
/>
</a-tab-pane>
<a-tab-pane key="2" tab="销售区域管理" force-render>
<DynamicTable :initialData="data" :columns="columns" rowKey="id"></DynamicTable>
<a-space>
<a-button v-if="route.query.type !== 'SEARCH'" key="1" type="primary" @click="addRow"></a-button>
<xn-batch-delete
v-if="hasPerm('customerBatchDelete')"
:selectedRowKeys="selectedListRowKeys"
@batchDelete="deleteBatchRecords"
/>
</a-space>
<a-table ref="tableRef" :dataSource="dataSource" :columns="columns" :row-selection="rowSelection" row-key="id">
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'province'">
<a-select
style="width: 100%"
:options="cityOptions"
v-model:value="record.province"
@change="
(value, options) => {
provinceChange(value, options, record)
}
"
></a-select>
</template>
<template v-if="column.dataIndex === 'city'">
<a-select
style="width: 100%"
:options="record.cityOptions"
v-model:value="record.city"
@change="
(value, options) => {
cityChange(value, options, record)
}
"
></a-select>
</template>
<template v-if="column.dataIndex === 'county'">
<a-select style="width: 100%" :options="record.countyOptions" v-model:value="record.county"></a-select>
</template>
<template v-if="column.dataIndex === 'remarks'">
<a-textarea style="width: 100%" v-model:value="record.remarks"></a-textarea>
</template>
</template>
</a-table>
</a-tab-pane>
</a-tabs>
</a-card>
@ -43,7 +84,6 @@
import tool from '@/utils/tool'
import { useRoute } from 'vue-router'
const route = useRoute()
import DynamicTable from '@/components/DynamicTable/index.vue'
import cityOptions from '@/utils/cityOptions'
const formRules = {
@ -254,7 +294,7 @@
const formRef1 = ref(null)
const formRef2 = ref(null)
const { state, formData, submitLoading, formRefs, onSubmit, handleBack, fetchData } = useFormHandler(
const { formData, formRefs, onSubmit, handleBack, fetchData } = useFormHandler(
[...clientFormItems, ...baseFormItems],
{
submitForm: customerApi.customerSubmitForm,
@ -262,11 +302,37 @@
}
)
const onSubmitForm = () => {
const dataSourceList = dataSource.value.map((item) => {
return {
id: item.id || '',
customerId: item.customerId || '',
province: item.province || '',
city: item.city || '',
county: item.county || '',
remarks: item.remarks || ''
}
})
onSubmit({
isDeep: true,
...formData,
saleAreaList: dataSourceList
})
}
onMounted(async () => {
formRefs.value = [formRef1.value, formRef2.value]
fetchData(route.query.type).then((res) => {
if (res) {
formData.provinceName = [res.province, res.city, res.county]
customerApi
.customerSaleAreaList({
customerId: res.id
})
.then((list) => {
dataSource.value = list || []
})
}
})
@ -300,23 +366,70 @@
let activeKey = ref('1')
const data = ref([
{ id: '1', name: 'John', age: 28 },
{ id: '2', name: 'Jane', age: 22 }
])
const dataSource = ref([])
let selectedListRowKeys = ref([])
let tableRef = ref(null)
const provinceChange = (event, options, record) => {
record.cityOptions = options.children
}
const cityChange = (event, options, record) => {
record.countyOptions = options.children
}
const addRow = () => {
const newRow = {
id: Date.now().toString(),
...columns.reduce((acc, col) => {
if (col.dataIndex) acc[col.dataIndex] = ''
return acc
}, {})
}
dataSource.value = [...dataSource.value, newRow]
}
const deleteBatchRecords = (value) => {
dataSource.value = dataSource.value.filter((item) => {
return !value.some((itemValue) => itemValue.id === item.id)
})
}
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
selectedListRowKeys.value = selectedRowKeys
}
}
const columns = [
{
title: '上游仓库代码',
dataIndex: 'name',
title: '',
dataIndex: 'province',
editable: true,
dataType: 'text' // 'number', 'select'
dataType: 'select', // 'number', 'select'
attrs: {
options: cityOptions,
onChange: provinceChange,
fliedNames: {
label: 'label',
value: 'code'
}
}
},
{
title: '上游仓库名称',
dataIndex: 'age',
editable: true,
dataType: 'number'
title: '市',
dataIndex: 'city',
editable: true
},
{
title: '区/县',
dataIndex: 'county',
editable: true
},
{
title: '备注',
dataIndex: 'remarks',
editable: true
}
]
</script>

View File

@ -29,48 +29,21 @@
</a-form>
</a-card>
<a-card :bordered="false" class="mt-4">
<a-row :gutter="16">
<a-card :bordered="false" class="mt-4" style="height: 100%">
<a-row :gutter="24">
<a-col :span="6">
<div className="s-table-tool">
<div className="s-table-tool-left">分类</div>
<!-- 斑马纹 -->
<div className="layout-items-center s-table-tool-right">
<span v-for="item in tool" :key="item.name">
<!-- 新增 -->
<a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'plus'" @click="handleAddTree">
<component class="icons" :is="item.icon"></component>
</a-tooltip>
<!-- 修改 -->
<a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'edit'" @click="handleEditTree">
<component class="icons" :is="item.icon"></component>
</a-tooltip>
<!-- 删除 -->
<a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'delete'">
<a-popconfirm title="确定要删除吗?" ok-text="" cancel-text="" @confirm="handleDelTree">
<component class="icons" :is="item.icon"></component>
</a-popconfirm>
</a-tooltip>
<!-- 刷新 -->
<!-- <a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'refresh'">
<component class="icons" :is="item.icon"></component>
</a-tooltip>-->
</span>
</div>
</div>
<a-directory-tree
v-model:expandedKeys="expandedKeys"
v-model:selectedKeys="selectedKeys"
multiple
:tree-data="treeData"
:fieldNames="{
children: 'children',
title: 'name',
key: 'id'
<dynamic-tree
ref="dynamicTreeRef"
treeTitle="客户分类"
:tableRef="tableRef"
:openFormRef="CustomerCategoryFormRef"
:apiModel="{
getTree: customerCategoryApi.customerCategoryTree,
delTree: customerCategoryApi.customerCategoryDelete
}"
@select="handleTreeClick"
></a-directory-tree>
@selectTree="selectTree"
@delTree="delTree"
></dynamic-tree>
</a-col>
<a-col :span="18">
<s-table
@ -80,10 +53,14 @@
:alert="options.alert.show"
bordered
:row-key="(record) => record.id"
:tool-config="toolConfig"
:tool-config="options.toolConfig"
:row-selection="options.rowSelection"
:scroll="{
x: 100,
y: 'calc(100vh - 300px)'
}"
>
<template #operator class="table-operator">
<template #operator>
<a-space>
<a-button
type="primary"
@ -105,42 +82,55 @@
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'number'">
<a href="#">{{ record.number }}</a>
</template>
<template v-if="column.dataIndex === 'enabledState'">
<!-- <a-switch
checkedValue="ENABLE"
unCheckedValue="DISABLED"
checked-children="启用"
un-checked-children="停用"
v-model:checked="record.enabledState"
/>-->
{{ $TOOL.dictTypeData('COMMON_STATUS', record.enabledState) }}
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
<a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag>
</template>
<template v-if="column.dataIndex === 'type'">
{{ $TOOL.dictTypeData('OFFICIAL_ACCOUNT_TYPE', record.type) }}
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a
@click="
navigateTo('/basicData/client/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>查看</a
>
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/client/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<EyeOutlined />
<!-- 查看-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a
@click="
navigateTo('/basicData/client/detail', {
type: 'EDIT',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>编辑</a
>
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/client/detail', {
type: 'EDIT',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<FormOutlined />
<!-- 编辑-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')"></a-button>
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button>
</a-popconfirm>
</a-space>
</template>
@ -157,49 +147,51 @@
import customerCategoryApi from '@/api/base/customer/customerCategoryApi'
import { useTableManagement } from '@/hook/useTableManagement'
import CustomerCategoryForm from '@/views/basicData/client/detail/CustomerCategoryForm.vue'
import { message } from 'ant-design-vue'
const clientColumn = [
{
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: '名称',
dataIndex: 'name',
align: 'center',
resizable: true,
width: 100
width: 300,
ellipsis: true
},
{
title: '分类',
dataIndex: 'categoryName',
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
}
]
@ -214,7 +206,6 @@
deleteBatchRecords,
options,
searchFormRef,
toolConfig,
navigateTo
} = useTableManagement(
{
@ -225,80 +216,28 @@
['customerEdit', 'customerDelete']
)
const tool = [
{
name: 'plus',
icon: 'plus-outlined',
title: '新增'
},
{
name: 'edit',
icon: 'edit-outlined',
title: '编辑'
},
{
name: 'delete',
icon: 'delete-outlined',
title: '删除'
},
{
name: 'refresh',
icon: 'sync-outlined',
title: '刷新'
}
]
//
const expandedKeys = ref(['0-0', '0-1'])
const selectedKeys = ref([])
const treeData = ref([])
const dynamicTreeRef = ref(null)
const CustomerCategoryFormRef = ref(null)
let treeRow = {}
const handleTreeClick = (selectedKeys, event) => {
treeRow = event.node
searchFormState.value.categoryId = selectedKeys[0]
const selectTree = (value) => {
searchFormState.value.categoryId = value.id
tableRef.value.refresh()
}
const handleAddTree = () => {
CustomerCategoryFormRef.value.onOpen()
}
const handleEditTree = () => {
if (!treeRow.id) return message.error('!请选择要编辑的数据')
CustomerCategoryFormRef.value.onOpen(treeRow)
}
const handleDelTree = () => {
if (!treeRow.id) return message.error('!请选择要删除的数据')
customerCategoryApi.customerCategoryDelete([{ id: treeRow.id }]).then((res) => {
selectedKeys.value = []
searchFormState.value.categoryId = null
treeRow = {}
tableRef.value.refresh()
customerCategoryApi.customerCategoryTree().then((res) => {
treeData.value = res
})
})
const delTree = () => {
searchFormState.value.categoryId = null
tableRef.value.refresh()
}
const successful = () => {
selectedKeys.value = []
searchFormState.value.categoryId = null
treeRow = {}
tableRef.value.refresh()
customerCategoryApi.customerCategoryTree().then((res) => {
treeData.value = res
})
dynamicTreeRef.value.loadTreeData()
}
onMounted(() => {
customerCategoryApi.customerCategoryTree().then((res) => {
treeData.value = res
})
dynamicTreeRef.value.loadTreeData()
})
</script>

View File

@ -0,0 +1,93 @@
export const materielColumn = [
{
title: '编码',
dataIndex: 'number',
sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '名称',
dataIndex: 'name',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '可用状态',
dataIndex: 'enabledState',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '规格型号',
dataIndex: 'specification',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
// {
// title: '分类',
// dataIndex: 'name',
// align: 'center',
// resizable: true,
// width: 150
// },
{
title: '品牌',
dataIndex: 'brandName',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '保质期',
dataIndex: 'shelfLifeUnit',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '基本单位',
dataIndex: 'baseUnitName',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '生产单位',
dataIndex: 'produceUnitName',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '采购单位',
dataIndex: 'purchaseUnitName',
align: 'center',
resizable: true,
width: 150
},
{
title: '创建时间',
dataIndex: 'createTime',
sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
width: 150,
ellipsis: true
}
]

View File

@ -29,47 +29,21 @@
</a-form>
</a-card>
<a-card :bordered="false" class="mt-4">
<a-row :gutter="16">
<a-card :bordered="false" class="mt-4" style="height: 100%">
<a-row :gutter="24">
<a-col :span="6">
<div className="s-table-tool">
<div className="s-table-tool-left">分类</div>
<!-- 斑马纹 -->
<div className="layout-items-center s-table-tool-right">
<span v-for="item in tool" :key="item.name">
<!-- 新增 -->
<a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'plus'" @click="handleAddTree">
<component class="icons" :is="item.icon"></component>
</a-tooltip>
<!-- 修改 -->
<a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'edit'" @click="handleEditTree">
<component class="icons" :is="item.icon"></component>
</a-tooltip>
<!-- 删除 -->
<a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'delete'">
<a-popconfirm title="确定要删除吗?" ok-text="" cancel-text="" @confirm="handleDelTree">
<component class="icons" :is="item.icon"></component>
</a-popconfirm>
</a-tooltip>
<!-- 刷新 -->
<!-- <a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'refresh'">
<component class="icons" :is="item.icon"></component>
</a-tooltip>-->
</span>
</div>
</div>
<a-directory-tree
v-model:expandedKeys="expandedKeys"
v-model:selectedKeys="selectedKeys"
multiple
:fieldNames="{
children: 'children',
title: 'name',
key: 'id'
<dynamic-tree
ref="dynamicTreeRef"
treeTitle="物料分类"
:tableRef="tableRef"
:openFormRef="materialCategoryFormRef"
:apiModel="{
getTree: materialCategoryApi.materialCategoryTree,
delTree: materialCategoryApi.materialCategoryDelete
}"
:tree-data="treeData"
@select="handleTreeClick"
></a-directory-tree>
@selectTree="selectTree"
@delTree="delTree"
></dynamic-tree>
</a-col>
<a-col :span="18">
<s-table
@ -79,8 +53,12 @@
:alert="options.alert.show"
bordered
:row-key="(record) => record.id"
:tool-config="toolConfig"
:tool-config="options.toolConfig"
:row-selection="options.rowSelection"
:scroll="{
x: 100,
y: 'calc(100vh - 300px)'
}"
>
<template #operator class="table-operator">
<a-space>
@ -104,44 +82,55 @@
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'number'">
<a href="#">{{ record.number }}</a>
</template>
<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="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag>
</template>
<template v-if="column.dataIndex === 'type'">
{{ $TOOL.dictTypeData('OFFICIAL_ACCOUNT_TYPE', record.type) }}
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a
@click="
navigateTo('/basicData/materiel/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>查看</a
>
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/materiel/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<EyeOutlined />
<!-- 查看-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a
@click="
navigateTo('/basicData/materiel/detail', {
type: 'EDIT',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>编辑</a
>
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/materiel/detail', {
type: 'EDIT',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<FormOutlined />
<!-- 编辑-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')"></a-button>
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button>
</a-popconfirm>
</a-space>
</template>
@ -150,100 +139,18 @@
</a-col>
</a-row>
</a-card>
<materialCategoryForm ref="materialCategoryFormRef" @successful="successful"></materialCategoryForm>
<material-category-form ref="materialCategoryFormRef" @successful="successful"></material-category-form>
</template>
<script setup name="materiel">
import materialApi from '@/api/base/material/materialApi'
import materialCategoryApi from '@/api/base/material/materialCategoryApi'
import { useTableManagement } from '@/hook/useTableManagement'
import MaterialCategoryForm from '@/views/basicData/materiel/detail/materialCategoryForm.vue'
import { message } from 'ant-design-vue'
import customerCategoryApi from '@/api/base/customer/customerCategoryApi'
import { useTableManagement } from '@/hook/useTableManagement'
import { materielColumn } from '@/views/basicData/materiel/column/materiel-column'
const materielColumn = [
{
title: '编码',
dataIndex: 'number',
sorter: (a, b) => a.address.length - b.address.length,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
width: 100
},
{
title: '名称',
dataIndex: 'name',
align: 'center',
resizable: true,
width: 100
},
{
title: '规格型号',
dataIndex: 'specification',
align: 'center',
resizable: true,
width: 100
},
// {
// title: '',
// dataIndex: 'name',
// align: 'center',
// resizable: true,
// width: 100
// },
{
title: '品牌',
dataIndex: 'brandName',
align: 'center',
resizable: true,
width: 100
},
{
title: '保质期',
dataIndex: 'shelfLifeUnit',
align: 'center',
resizable: true,
width: 100
},
{
title: '基本单位',
dataIndex: 'baseUnitName',
align: 'center',
resizable: true,
width: 100
},
{
title: '生产单位',
dataIndex: 'produceUnitName',
align: 'center',
resizable: true,
width: 100
},
{
title: '采购单位',
dataIndex: 'purchaseUnitName',
align: 'center',
resizable: true,
width: 100
},
{
title: '可用状态',
dataIndex: 'enabledState',
align: 'center',
resizable: true,
width: 100
},
{
title: '创建时间',
dataIndex: 'createTime',
sorter: (a, b) => a.address.length - b.address.length,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
width: 100
}
]
const materialCategoryFormRef = ref(null)
const dynamicTreeRef = ref(null)
const {
searchFormState,
@ -256,7 +163,6 @@
deleteBatchRecords,
options,
searchFormRef,
toolConfig,
navigateTo
} = useTableManagement(
{
@ -267,96 +173,24 @@
['customerEdit', 'customerDelete']
)
const tool = [
{
name: 'plus',
icon: 'plus-outlined',
title: '新增'
},
{
name: 'edit',
icon: 'edit-outlined',
title: '编辑'
},
{
name: 'delete',
icon: 'delete-outlined',
title: '删除'
},
{
name: 'refresh',
icon: 'sync-outlined',
title: '刷新'
}
]
//
const expandedKeys = ref(['0-0', '0-1'])
const selectedKeys = ref([])
const treeData = ref([])
const materialCategoryFormRef = ref(null)
let treeRow = {}
const handleTreeClick = (selectedKeys, event) => {
treeRow = event.node
searchFormState.value.categoryId = selectedKeys[0]
const selectTree = (value) => {
searchFormState.value.categoryId = value.id
tableRef.value.refresh()
}
const handleAddTree = () => {
materialCategoryFormRef.value.onOpen()
}
const handleEditTree = () => {
if (!treeRow.id) return message.error('!请选择要编辑的数据')
materialCategoryFormRef.value.onOpen(treeRow)
}
const handleDelTree = () => {
if (!treeRow.id) return message.error('!请选择要删除的数据')
materialCategoryApi.materialCategoryDelete([{ id: treeRow.id }]).then((res) => {
selectedKeys.value = []
searchFormState.value.categoryId = null
treeRow = {}
tableRef.value.refresh()
materialCategoryApi.materialCategoryTree().then((res) => {
treeData.value = res || []
})
})
const delTree = () => {
searchFormState.value.categoryId = null
tableRef.value.refresh()
}
const successful = () => {
selectedKeys.value = []
searchFormState.value.categoryId = null
treeRow = {}
tableRef.value.refresh()
materialCategoryApi.materialCategoryTree().then((res) => {
treeData.value = res
})
dynamicTreeRef.value.loadTreeData()
}
onMounted(() => {
materialCategoryApi.materialCategoryTree().then((res) => {
treeData.value = res || []
})
dynamicTreeRef.value.loadTreeData()
})
</script>
<style lang="less" scoped>
.s-table-tool {
display: flex;
margin-bottom: 16px;
.s-table-tool-left {
flex: 1;
}
.s-table-tool-right {
.s-tool-item {
font-size: 16px;
@apply ml-4;
cursor: pointer;
}
}
}
</style>

View File

@ -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
}
]

View File

@ -24,7 +24,7 @@
</a-form>
</a-card>
<a-card :bordered="false" class="mt-4">
<a-card :bordered="false" class="mt-4" style="height: 100%">
<s-table
ref="tableRef"
:columns="columns"
@ -32,10 +32,14 @@
:alert="options.alert.show"
bordered
:row-key="(record) => record.id"
:tool-config="toolConfig"
:tool-config="options.toolConfig"
:row-selection="options.rowSelection"
:scroll="{
x: 100,
y: 'calc(100vh - 300px)'
}"
>
<template #operator class="table-operator">
<template #operator>
<a-space>
<a-button
type="primary"
@ -57,45 +61,52 @@
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'enabledState'">
<!-- <a-switch
checkedValue="ENABLE"
unCheckedValue="DISABLED"
checked-children="启用"
un-checked-children="停用"
v-model:checked="record.enabledState"
/>-->
{{ $TOOL.dictTypeData('COMMON_STATUS', record.enabledState) }}
<template v-if="column.dataIndex === 'number'">
<a href="#">{{ record.number }}</a>
</template>
<template v-if="column.dataIndex === 'type'">
{{ $TOOL.dictTypeData('OFFICIAL_ACCOUNT_TYPE', record.type) }}
<template v-if="column.dataIndex === 'enabledState'">
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
<a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag>
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a
@click="
navigateTo('/basicData/publicAccount/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('officialAccountEdit')"
>查看</a
>
<a-divider type="vertical" v-if="hasPerm(['officialAccountEdit', 'officialAccountDelete'], 'and')" />
<a
@click="
navigateTo('/basicData/publicAccount/detail', {
type: 'EDIT',
id: record.id
})
"
v-if="hasPerm('officialAccountEdit')"
>编辑</a
>
<a-divider type="vertical" v-if="hasPerm(['officialAccountEdit', 'officialAccountDelete'], 'and')" />
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/publicAccount/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<EyeOutlined />
<!-- 查看-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/publicAccount/detail', {
type: 'EDIT',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<FormOutlined />
<!-- 编辑-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('officialAccountDelete')"></a-button>
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button>
</a-popconfirm>
</a-space>
</template>
@ -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
}
]

View File

@ -0,0 +1,18 @@
export const brandColumns = [
{
title: '编码',
dataIndex: 'number'
},
{
title: '名称',
dataIndex: 'name'
},
{
title: '可用状态',
dataIndex: 'enabledState'
},
{
title: '创建时间',
dataIndex: 'createTime'
}
]

View File

@ -29,7 +29,7 @@
</a-form>
</a-card>
<a-card :bordered="false" class="mt-4">
<a-card :bordered="false" class="mt-4" style="height: 100%">
<s-table
ref="tableRef"
:columns="columns"
@ -37,10 +37,14 @@
:alert="options.alert.show"
bordered
:row-key="(record) => record.id"
:tool-config="toolConfig"
:tool-config="options.toolConfig"
:row-selection="options.rowSelection"
:scroll="{
x: 100,
y: 'calc(100vh - 300px)'
}"
>
<template #operator class="table-operator">
<template #operator>
<a-space>
<a-button
type="primary"
@ -62,42 +66,52 @@
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'number'">
<a href="#">{{ record.number }}</a>
</template>
<template v-if="column.dataIndex === 'enabledState'">
<!-- <a-switch
checkedValue="ENABLE"
unCheckedValue="DISABLED"
checked-children="启用"
un-checked-children="停用"
v-model:checked="record.enabledState"
/>-->
{{ $TOOL.dictTypeData('COMMON_STATUS', record.enabledState) }}
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
<a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag>
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a
@click="
navigateTo('/basicData/stash/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('sysStoreEdit')"
>查看</a
>
<a-divider type="vertical" v-if="hasPerm(['sysStoreEdit', 'sysStoreDelete'], 'and')" />
<a
@click="
navigateTo('/basicData/stash/detail', {
type: 'EDIT',
id: record.id
})
"
v-if="hasPerm('sysStoreEdit')"
>编辑</a
>
<a-divider type="vertical" v-if="hasPerm(['sysStoreEdit', 'sysStoreDelete'], 'and')" />
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/stash/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<EyeOutlined />
<!-- 查看-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/stash/detail', {
type: 'EDIT',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<FormOutlined />
<!-- 编辑-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('sysStoreDelete')"></a-button>
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button>
</a-popconfirm>
</a-space>
</template>
@ -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
}
]

View File

@ -42,23 +42,29 @@
</a-form>
</a-card>
<a-card :bordered="false" class="mt-4">
<a-card :bordered="false" class="mt-4" style="height: 100%">
<a-row :gutter="24">
<a-col :span="4">
<a-directory-tree
v-model:expandedKeys="expandedKeys"
v-model:selectedKeys="selectedKeys"
multiple
:fieldNames="{
children: 'children',
title: 'name',
key: 'id'
<a-col :span="6">
<dynamic-tree
ref="dynamicTreeRef"
treeTitle="生产组织"
:tableRef="tableRef"
:openFormRef="TissueFormRef"
:apiModel="{
getTree: productionOrganizationApi.productionOrganizationTree,
delTree: productionOrganizationApi.productionOrganizationDelete
}"
:tree-data="treeData"
@select="handleSelectTree"
></a-directory-tree>
@selectTree="selectTree"
@delTree="delTree"
:toolConfig="{
plus: false,
edit: false,
delete: false,
refresh: true
}"
></dynamic-tree>
</a-col>
<a-col :span="20">
<a-col :span="18">
<s-table
ref="tableRef"
:columns="columns"
@ -66,10 +72,14 @@
:alert="options.alert.show"
bordered
:row-key="(record) => record.id"
:tool-config="toolConfig"
:tool-config="options.toolConfig"
:row-selection="options.rowSelection"
:scroll="{
x: 100,
y: 'calc(100vh - 300px)'
}"
>
<template #operator class="table-operator">
<template #operator>
<a-space>
<a-button type="primary" @click="TissueFormRef.onOpen()" v-if="hasPerm('officialAccountAdd')">
<template #icon><plus-outlined /></template>
@ -83,33 +93,36 @@
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'number'">
<a href="#">{{ record.number }}</a>
</template>
<template v-if="column.dataIndex === 'enabledState'">
<!-- <a-switch
checkedValue="ENABLE"
unCheckedValue="DISABLED"
checked-children="启用"
un-checked-children="停用"
v-model:checked="record.enabledState"
/>-->
{{ $TOOL.dictTypeData('COMMON_STATUS', record.enabledState) }}
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
<a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag>
</template>
<template v-if="column.dataIndex === 'type'">
{{ $TOOL.dictTypeData('PRODUCTION_ORGANIZATION_TYPE', record.type) }}
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a
@click="TissueFormRef.onOpen({ ...record, pageType: 'SEARCH' })"
v-if="hasPerm('officialAccountEdit')"
>查看</a
>
<a-divider type="vertical" v-if="hasPerm(['officialAccountEdit', 'officialAccountDelete'], 'and')" />
<a @click="TissueFormRef.onOpen({ ...record, pageType: 'EDIT' })" v-if="hasPerm('officialAccountEdit')"
>编辑</a
>
<a-divider type="vertical" v-if="hasPerm(['officialAccountEdit', 'officialAccountDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecordRestTRee(record)">
<a-button type="link" danger size="small" v-if="hasPerm('officialAccountDelete')"></a-button>
<a-tooltip title="查看">
<a @click="TissueFormRef.onOpen({ ...record, pageType: 'SEARCH' })" v-if="hasPerm('customerEdit')">
<EyeOutlined />
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-tooltip title="查看">
<a @click="TissueFormRef.onOpen({ ...record, pageType: 'EDIT' })" v-if="hasPerm('customerEdit')">
<FormOutlined />
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
</a-button>
</a-popconfirm>
</a-space>
</template>
@ -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()
})
</script>

View File

@ -63,7 +63,7 @@
</a-card>
</template>
<script setup name="sysUnitForm">
<script setup name="basicDataUnitDetail">
import tool from '@/utils/tool'
import { cloneDeep } from 'lodash-es'
import { required } from '@/utils/formRules'

View File

@ -80,6 +80,10 @@
:row-key="(record) => record.id"
:tool-config="unitToolConfig"
:row-selection="options.rowSelection"
:scroll="{
x: 100,
y: 'calc(100vh - 300px)'
}"
>
<template #operator class="table-operator">
<a-space>
@ -90,57 +94,68 @@
type: 'ADD'
})
"
v-if="hasPerm('sysUnitAdd')"
v-if="hasPerm('customerAdd')"
>
<template #icon><plus-outlined /></template>
新增
</a-button>
<xn-batch-delete
v-if="hasPerm('sysUnitBatchDelete')"
v-if="hasPerm('customerBatchDelete')"
:selectedRowKeys="selectedRowKeys"
@batchDelete="deleteBatchSysUnit"
@batchDelete="deleteBatchRecords"
/>
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'enabledState'">
<!-- <a-switch
checkedValue="ENABLE"
unCheckedValue="DISABLED"
checked-children="启用"
un-checked-children="停用"
v-model:checked="record.enabledState"
/>-->
{{ $TOOL.dictTypeData('COMMON_STATUS', record.enabledState) }}
<template v-if="column.dataIndex === 'number'">
<a href="#">{{ record.number }}</a>
</template>
<template v-if="column.dataIndex === 'isBase'">
{{ $TOOL.dictTypeData('YES_NO', record.isBase) }}
<template v-if="column.dataIndex === 'enabledState'">
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
<a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag>
</template>
<template v-if="column.dataIndex === 'type'">
{{ $TOOL.dictTypeData('OFFICIAL_ACCOUNT_TYPE', record.type) }}
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<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-popconfirm title="确定要删除吗?" @confirm="deleteSysUnit(record)">
<a-button type="link" danger size="small" v-if="hasPerm('sysUnitDelete')"></a-button>
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/unit/detail', {
type: 'SEARCH',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<EyeOutlined />
<!-- 查看-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-tooltip title="查看">
<a
@click="
navigateTo('/basicData/unit/detail', {
type: 'EDIT',
id: record.id
})
"
v-if="hasPerm('customerEdit')"
>
<FormOutlined />
<!-- 编辑-->
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button>
</a-popconfirm>
</a-space>
</template>
@ -153,19 +168,20 @@
<unit-group-form ref="UnitGroupFormRef" @successful="successful"></unit-group-form>
</template>
<script setup name="sysunit">
<script setup name="basicDataUnit">
import sysUnitApi from '@/api/base/unit/unitApi'
import sysUnitGroupsApi from '@/api/base/unit/unitGroupsApi'
import tool from '@/utils/tool'
import { cloneDeep } from 'lodash-es'
import { useNavigation } from '@/hook/useNavigation'
import { message } from 'ant-design-vue'
import { unitColumns, unitGroupColumns } from '@/views/basicData/unit/columns/unitColumns'
import UnitGroupForm from '@/views/basicData/unit/detail/UnitGroupForm.vue'
// import Form from './form.vue'
import sysUnitApi from '@/api/base/unit/unitApi'
import sysUnitGroupsApi from '@/api/base/unit/unitGroupsApi'
import { message } from 'ant-design-vue'
// ------------------------------ REF ------------------------------ //
const searchFormRef = ref()
const searchFormState = ref({})
const searchFormRef = ref()
const UnitGroupFormRef = ref()
const unitTableRef = ref()
const unitToolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
@ -188,11 +204,11 @@
if (hasPerm(['sysUnitEdit', 'sysUnitDelete'])) {
const columnsFilter = unitColumns.filter((item) => item.dataIndex === 'action')
if (columnsFilter.length === 0)
unitColumns.push({
unitColumns.unshift({
title: '操作',
dataIndex: 'action',
align: 'center',
fixed: 'right',
fixed: 'left',
width: 150
})
}