基础资料模块优化

main
GaoF 2024-07-31 17:33:54 +08:00
parent 36d9d228e6
commit c565f0acbf
16 changed files with 723 additions and 263 deletions

View File

@ -20,5 +20,9 @@ export default {
// 获取扩展字段配置详情 // 获取扩展字段配置详情
extendFieldDetail(data) { extendFieldDetail(data) {
return request('detail', data, 'get') return request('detail', data, 'get')
},
// 获取扩展字段配置列表(根据分类)
extendFieldTypeList(data) {
return request('typeList', data, 'get')
} }
} }

View File

@ -1,43 +1,50 @@
<template> <template>
<div> <div>
<div class="s-table-tool"> <a-spin :spinning="localLoading">
<div class="s-table-tool-left">{{ treeTitle }}</div> <div class="s-table-tool">
<div class="layout-items-center s-table-tool-right"> <div class="s-table-tool-left">{{ treeTitle }}</div>
<span v-for="item in tool" :key="item.name"> <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 :title="item.title" class="s-tool-item" v-if="item.name === 'plus' && props.toolConfig.plus">
</a-tooltip> <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 :title="item.title" class="s-tool-item" v-if="item.name === 'edit' && props.toolConfig.edit">
</a-tooltip> <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"> <a-tooltip :title="item.title" class="s-tool-item" v-if="item.name === 'delete' && props.toolConfig.delete">
<component class="icons" :is="item.icon"></component> <a-popconfirm title="确定要删除吗?" ok-text="" cancel-text="" @confirm="handleDelTree">
</a-popconfirm> <component class="icons" :is="item.icon"></component>
</a-tooltip> </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
</a-tooltip> :title="item.title"
</span> 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> </div>
</div> <a-directory-tree
<a-directory-tree :loading="localLoading"
show-line show-line
v-model:expandedKeys="expandedKeys" v-model:expandedKeys="expandedKeys"
v-model:selectedKeys="selectedKeys" v-model:selectedKeys="selectedKeys"
multiple multiple
:fieldNames="{ :fieldNames="{
children: 'children', children: 'children',
title: 'name', title: 'name',
key: 'id' key: 'id'
}" }"
:tree-data="treeData" :tree-data="treeData"
@select="handleTreeClick" @select="handleTreeClick"
></a-directory-tree> ></a-directory-tree>
</a-spin>
</div> </div>
</template> </template>
@ -84,7 +91,7 @@
} }
}) })
const emits = defineEmits('selectTree', 'delTree') const emit = defineEmits(['selectTree', 'delTree'])
const tool = [ const tool = [
{ {
@ -112,12 +119,20 @@
// //
const expandedKeys = ref() const expandedKeys = ref()
const selectedKeys = ref([]) const selectedKeys = ref([])
const treeData = ref([]) const localLoading = ref(false)
const treeData = ref([
{
id: 0,
parentId: '-1',
name: '顶级',
children: ''
}
])
let treeRow = {} let treeRow = {}
const handleTreeClick = (selectedKeys, event) => { const handleTreeClick = (selectedKeys, event) => {
treeRow = event.node treeRow = event.node
emits('selectTree', treeRow) emit('selectTree', treeRow)
} }
const handleAddTree = () => { const handleAddTree = () => {
@ -141,11 +156,13 @@
const loadTreeData = async () => { const loadTreeData = async () => {
try { try {
localLoading.value = true
const treeRes = await props.apiModel.getTree() const treeRes = await props.apiModel.getTree()
console.log(treeRes, 'treeRes')
if (Array.isArray(treeRes)) { if (Array.isArray(treeRes)) {
treeData.value = treeRes treeData.value[0].children = treeRes
} else { } else {
treeData.value = [] treeData.value[0].children = []
} }
if (selectedKeys.value.length > 0) { if (selectedKeys.value.length > 0) {
@ -157,7 +174,12 @@
if (treeRow.id) { if (treeRow.id) {
treeRow = [] treeRow = []
} }
setTimeout(() => {
localLoading.value = false
}, 800)
} catch (e) { } catch (e) {
localLoading.value = false
message.error('获取树结构数据失败:' + e) message.error('获取树结构数据失败:' + e)
console.error('获取树结构数据失败:' + e) console.error('获取树结构数据失败:' + e)
} }

View File

@ -62,7 +62,8 @@
detailDataProps.value = props.detailData detailDataProps.value = props.detailData
}, },
{ {
immediate: true immediate: true,
deep: true
} }
) )
</script> </script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

View File

@ -13,6 +13,7 @@ export default function useFormHandler(formItems, api) {
const state = reactive({ const state = reactive({
PAGE_TYPE: '' PAGE_TYPE: ''
}) })
let detailData = reactive({})
// 初始化表单数据对象 // 初始化表单数据对象
let formData = reactive({}) let formData = reactive({})
@ -84,8 +85,8 @@ export default function useFormHandler(formItems, api) {
* 处理返回操作返回上一级页面并关闭当前标签页 * 处理返回操作返回上一级页面并关闭当前标签页
*/ */
const handleBack = () => { const handleBack = () => {
useTabs.close(route)
router.go(-1) // 优化为通用的返回上一页操作 router.go(-1) // 优化为通用的返回上一页操作
useTabs.close()
} }
/** /**
@ -98,6 +99,7 @@ export default function useFormHandler(formItems, api) {
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 })
// 根据返回的详情数据初始化表单数据 // 根据返回的详情数据初始化表单数据
for (let key in formData) { for (let key in formData) {
if (res[key] !== undefined) { if (res[key] !== undefined) {
@ -117,6 +119,7 @@ export default function useFormHandler(formItems, api) {
formData, formData,
submitLoading, submitLoading,
formRefs, formRefs,
detailData,
onSubmit, onSubmit,
handleBack, handleBack,
fetchData fetchData

View File

@ -52,7 +52,7 @@
<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.path" :tab="tag.meta.title" :closable="!tag.meta.affix">
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</div> </div>
@ -94,7 +94,7 @@
}) })
watch(route, (to) => { watch(route, (to) => {
addViewTags(to) addViewTags(to)
activeKey.value = to.fullPath activeKey.value = to.path
}) })
watch(layoutTagsOpen, () => { watch(layoutTagsOpen, () => {
// closeOtherCacheTabs() // closeOtherCacheTabs()
@ -107,10 +107,10 @@
}) })
// tag // tag
const addViewTags = (to) => { const addViewTags = (to) => {
activeKey.value = to.fullPath activeKey.value = to.path
if (to.name && !to.meta.fullpage) { if (to.name) {
vStore.pushViewTags(to) vStore.pushViewTags(to)
kStore.pushKeepLive(to.name) // kStore.pushKeepLive(to.name)
} }
if (tagList.value.length - 1 > maxTabs.value) { if (tagList.value.length - 1 > maxTabs.value) {
const firstTag = tagList.value[1] const firstTag = tagList.value[1]
@ -158,9 +158,9 @@
const nowTag = getCurrentTag() const nowTag = getCurrentTag()
// //
// eslint-disable-next-line eqeqeq // eslint-disable-next-line eqeqeq
if (route.fullPath !== nowTag.fullPath) { if (route.path !== nowTag.path) {
router.push({ router.push({
path: nowTag.fullPath, path: nowTag.path,
query: nowTag.query query: nowTag.query
}) })
} }
@ -189,16 +189,16 @@
const nowTag = getCurrentTag() const nowTag = getCurrentTag()
// //
// eslint-disable-next-line eqeqeq // eslint-disable-next-line eqeqeq
if (route.fullPath !== nowTag.fullPath) { if (route.path !== nowTag.path) {
router.push({ router.push({
path: nowTag.fullPath, path: nowTag.path,
query: nowTag.query query: nowTag.query
}) })
} }
const tags = [...tagList.value] const tags = [...tagList.value]
tags.forEach((tag) => { tags.forEach((tag) => {
// eslint-disable-next-line eqeqeq // eslint-disable-next-line eqeqeq
if ((tag.meta && tag.meta.affix) || nowTag.fullPath === tag.fullPath) { if ((tag.meta && tag.meta.affix) || nowTag.path === tag.path) {
return true return true
} else { } else {
closeSelectedTag(tag, false) closeSelectedTag(tag, false)
@ -219,9 +219,9 @@
const nowTag = getCurrentTag() const nowTag = getCurrentTag()
// //
// eslint-disable-next-line eqeqeq // eslint-disable-next-line eqeqeq
if (route.fullPath !== nowTag.fullPath) { if (route.path !== nowTag.path) {
router.push({ router.push({
path: nowTag.fullPath, path: nowTag.path,
query: nowTag.query query: nowTag.query
}) })
} }
@ -265,7 +265,7 @@
const onTabRemove = (tabKey, action) => { const onTabRemove = (tabKey, action) => {
if (action === 'remove') { if (action === 'remove') {
const tag = tagList.value.find((tag) => tag.fullPath === tabKey) const tag = tagList.value.find((tag) => tag.path === tabKey)
closeSelectedTag(tag) closeSelectedTag(tag)
} }
} }
@ -319,9 +319,7 @@
background: none; background: none;
height: 40px; height: 40px;
line-height: 40px; line-height: 40px;
transition: transition: background-color 0.3s, color 0.3s;
background-color 0.3s,
color 0.3s;
padding: 0 16px; padding: 0 16px;
border-radius: 0; border-radius: 0;
border: none; border: none;
@ -442,9 +440,7 @@
position: relative; position: relative;
z-index: 1; z-index: 1;
border-radius: 10px 10px 0 0 !important; border-radius: 10px 10px 0 0 !important;
box-shadow: box-shadow: 12px 15px 0 0 var(--primary-1), -12px 15px 0 0 var(--primary-1);
12px 15px 0 0 var(--primary-1),
-12px 15px 0 0 var(--primary-1);
} }
.snowy-radius .ant-tabs-tab-active::before { .snowy-radius .ant-tabs-tab-active::before {
content: ''; content: '';

View File

@ -70,6 +70,9 @@
</template> </template>
</a-table> </a-table>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="3" tab="操作信息" v-if="route.query.type !== 'ADD'">
<OperationalInformation :detailData="detailData" :colSpan="12"></OperationalInformation>
</a-tab-pane>
</a-tabs> </a-tabs>
</a-card> </a-card>
</template> </template>
@ -83,8 +86,8 @@
import useFormHandler from '@/hook/useFormHandler' import useFormHandler from '@/hook/useFormHandler'
import tool from '@/utils/tool' import tool from '@/utils/tool'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
const route = useRoute()
import cityOptions from '@/utils/cityOptions' import cityOptions from '@/utils/cityOptions'
const route = useRoute()
const formRules = { const formRules = {
name: [required('请输入名称')], name: [required('请输入名称')],
@ -92,6 +95,7 @@
appid: [required('请输入AppID')], appid: [required('请输入AppID')],
secret: [required('请输入AppSecret')] secret: [required('请输入AppSecret')]
} }
let detailData = reactive({})
// //
const onCascaderChange = (value) => { const onCascaderChange = (value) => {
@ -321,9 +325,12 @@
} }
onMounted(async () => { onMounted(async () => {
console.log(1)
formRefs.value = [formRef1.value, formRef2.value] formRefs.value = [formRef1.value, formRef2.value]
fetchData(route.query.type).then((res) => { fetchData(route.query.type).then((res) => {
if (res) { if (res) {
detailData = res
formData.provinceName = [res.province, res.city, res.county] formData.provinceName = [res.province, res.city, res.county]
customerApi customerApi
@ -350,7 +357,6 @@
}) })
// //
customerCategoryApi customerCategoryApi
.customerCategoryTree({ .customerCategoryTree({
enabledState: 'ENABLE' enabledState: 'ENABLE'

View File

@ -0,0 +1,95 @@
import tool from '@/utils/tool'
import { required } from '@/utils/formRules'
export const officialAccountFormItems = [
{
label: '类型:',
name: 'type',
type: 'a-select',
span: 8,
attrs: {
placeholder: '请选择类型',
options: tool.dictList('OFFICIAL_ACCOUNT_TYPE')
}
},
{
label: '名称:',
name: 'name',
type: 'a-input',
span: 8,
rules: [required('请输入名称')],
attrs: {
placeholder: '请输入名称',
allowClear: true
}
},
{
label: '可用状态:',
name: 'enabledState',
type: 'a-select',
span: 8,
attrs: {
placeholder: '请选择可用状态',
options: tool.dictList('COMMON_STATUS')
},
defaultValue: 'ENABLE'
},
{
label: '备注:',
name: 'remarks',
type: 'a-textarea',
span: 24,
attrs: {
placeholder: '请输入备注',
allowClear: true
}
}
]
export const basicInfoFormItems = [
{
label: 'AppID',
name: 'appid',
type: 'a-input',
attrs: {
placeholder: '请输入AppID',
allowClear: true
}
},
{
label: 'AppSecret',
name: 'secret',
type: 'a-input',
attrs: {
placeholder: '请输入AppSecret',
allowClear: true
}
},
{
label: '字符串编码格式:',
name: 'encodingFormat',
type: 'a-input',
attrs: {
placeholder: '请输入字符串编码格式',
allowClear: true
}
},
{
label: '校验码:',
name: 'token',
type: 'a-input',
attrs: {
placeholder: '请输入校验码',
allowClear: true
}
},
{
label: '签名方式:',
name: 'aesKey',
type: 'a-input',
attrs: {
placeholder: '请输入签名方式',
allowClear: true
}
}
]

View File

@ -129,7 +129,6 @@
<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')">
<DeleteOutlined /> <DeleteOutlined />
<!-- 删除-->
</a-button> </a-button>
</a-popconfirm> </a-popconfirm>
</a-space> </a-space>
@ -142,7 +141,7 @@
</a-card> </a-card>
</template> </template>
<script setup name="client"> <script setup name="basicDataClient">
import customerApi from '@/api/base/customer/customerApi' import customerApi from '@/api/base/customer/customerApi'
import customerCategoryApi from '@/api/base/customer/customerCategoryApi' import customerCategoryApi from '@/api/base/customer/customerCategoryApi'
import { useTableManagement } from '@/hook/useTableManagement' import { useTableManagement } from '@/hook/useTableManagement'

View File

@ -106,6 +106,17 @@
</a-form-item> </a-form-item>
</a-form> </a-form>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="5" tab="扩展字段" force-render>
<a-form layout="vertical">
<a-row :gutter="16">
<a-col :span="item.span || 6" v-for="(item, index) in extendData" :key="index">
<a-form-item :label="item.label" :name="item.name" :rules="item.rules">
<component style="width: 100%" :is="item.type" v-model:value="item.defaultValue" v-bind="item.attrs" />
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-tab-pane>
</a-tabs> </a-tabs>
</a-card> </a-card>
</template> </template>
@ -113,6 +124,7 @@
<script setup name="materielDetail"> <script setup name="materielDetail">
import unitGroupsApi from '@/api/base/unit/unitGroupsApi' import unitGroupsApi from '@/api/base/unit/unitGroupsApi'
import unitApi from '@/api/base/unit/unitApi' import unitApi from '@/api/base/unit/unitApi'
import extendFieldApi from '@/api/base/extendfield/extendFieldApi'
import { required } from '@/utils/formRules' import { required } from '@/utils/formRules'
import useFormHandler from '@/hook/useFormHandler' import useFormHandler from '@/hook/useFormHandler'
@ -133,6 +145,7 @@
let productFormData = ref({ let productFormData = ref({
promoteEnabledState: 'ENABLE' promoteEnabledState: 'ENABLE'
}) })
let extendData = ref([]) //
onMounted(async () => { onMounted(async () => {
formRefs.value = [formRef1.value, formRef2.value, formRef3.value] formRefs.value = [formRef1.value, formRef2.value, formRef3.value]
@ -209,6 +222,33 @@
item.attrs.options = brandList item.attrs.options = brandList
} }
}) })
//
extendFieldApi
.extendFieldTypeList({
enabledState: 'ENABLE',
model: 'MATERIAL'
})
.then((res) => {
if (res) {
res.forEach((item) => {
extendData.value.push({
label: item.fieldName,
name: item.fieldName,
type: 'ASelect',
span: 6,
attrs: {
placeholder: '请输入内容',
options: [],
fieldNames: {
label: 'name',
value: 'id'
}
}
})
})
}
})
}) })
let activeKey = ref('1') let activeKey = ref('1')
@ -651,7 +691,7 @@
} }
] ]
const { state, formData, submitLoading, formRefs, onSubmit, handleBack, fetchData } = useFormHandler( const { formData, formRefs, onSubmit, handleBack, fetchData } = useFormHandler(
[...materialFormItems, ...baseFormItems, ...unitFormItems], [...materialFormItems, ...baseFormItems, ...unitFormItems],
{ {
submitForm: materialApi.materialSubmitForm, submitForm: materialApi.materialSubmitForm,

View File

@ -24,13 +24,17 @@
ref="formRef2" ref="formRef2"
/> />
</a-card> </a-card>
<a-card :bordered="false" title="操作信息" class="mt-4" v-if="route.query.type !== 'ADD'">
<OperationalInformation :detailData="detailData" :colSpan="12"></OperationalInformation>
</a-card>
</template> </template>
<script setup name="publicAccountDetail"> <script setup name="publicAccountDetail">
import { required } from '@/utils/formRules' import { required } from '@/utils/formRules'
import officialAccountApi from '@/api/base/wx/officialAccountApi' import officialAccountApi from '@/api/base/wx/officialAccountApi'
import useFormHandler from '@/hook/useFormHandler' import useFormHandler from '@/hook/useFormHandler'
import tool from '@/utils/tool' import { basicInfoFormItems, officialAccountFormItems } from '@/views/basicData/client/formItems'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
const route = useRoute() const route = useRoute()
@ -41,103 +45,11 @@
secret: [required('请输入AppSecret')] secret: [required('请输入AppSecret')]
} }
const officialAccountFormItems = [
{
label: '类型:',
name: 'type',
type: 'a-select',
span: 8,
attrs: {
placeholder: '请选择类型',
options: tool.dictList('OFFICIAL_ACCOUNT_TYPE')
}
},
{
label: '名称:',
name: 'name',
type: 'a-input',
span: 8,
rules: [required('请输入名称')],
attrs: {
placeholder: '请输入名称',
allowClear: true
}
},
{
label: '可用状态:',
name: 'enabledState',
type: 'a-select',
span: 8,
attrs: {
placeholder: '请选择可用状态',
options: tool.dictList('COMMON_STATUS')
},
defaultValue: 'ENABLE'
},
{
label: '备注:',
name: 'remarks',
type: 'a-textarea',
span: 24,
attrs: {
placeholder: '请输入备注',
allowClear: true
}
}
]
const basicInfoFormItems = [
{
label: 'AppID',
name: 'appid',
type: 'a-input',
attrs: {
placeholder: '请输入AppID',
allowClear: true
}
},
{
label: 'AppSecret',
name: 'secret',
type: 'a-input',
attrs: {
placeholder: '请输入AppSecret',
allowClear: true
}
},
{
label: '字符串编码格式:',
name: 'encodingFormat',
type: 'a-input',
attrs: {
placeholder: '请输入字符串编码格式',
allowClear: true
}
},
{
label: '校验码:',
name: 'token',
type: 'a-input',
attrs: {
placeholder: '请输入校验码',
allowClear: true
}
},
{
label: '签名方式:',
name: 'aesKey',
type: 'a-input',
attrs: {
placeholder: '请输入签名方式',
allowClear: true
}
}
]
const formRef1 = ref(null) const formRef1 = ref(null)
const formRef2 = ref(null) const formRef2 = ref(null)
let detailData = ref({})
const { state, formData, submitLoading, formRefs, onSubmit, handleBack, fetchData } = useFormHandler( const { formData, formRefs, onSubmit, handleBack, fetchData } = useFormHandler(
[...officialAccountFormItems, ...basicInfoFormItems], [...officialAccountFormItems, ...basicInfoFormItems],
{ {
submitForm: officialAccountApi.officialAccountSubmitForm, submitForm: officialAccountApi.officialAccountSubmitForm,
@ -147,6 +59,10 @@
onMounted(async () => { onMounted(async () => {
formRefs.value = [formRef1.value, formRef2.value] formRefs.value = [formRef1.value, formRef2.value]
await fetchData(route.query.type) fetchData(route.query.type).then((res) => {
if (res) {
detailData.value = res
}
})
}) })
</script> </script>

View File

@ -152,7 +152,7 @@
span: 6, span: 6,
attrs: { attrs: {
placeholder: '请选择上游仓库', placeholder: '请选择上游仓库',
options: [], treeData: [],
fieldNames: { fieldNames: {
children: 'children', children: 'children',
label: 'name', label: 'name',
@ -236,13 +236,18 @@
}) })
const sysStoreTreeList = await sysStoreApi.sysStoreTree() const sysStoreTreeList = await sysStoreApi.sysStoreTree()
if (Array.isArray(sysStoreTreeList)) { officialAccountFormItems.forEach((item) => {
officialAccountFormItems.forEach((item) => { if (item.name === 'parentId') {
if (item.name === 'parentId') { item.attrs.treeData = [
item.attrs.options = sysStoreTreeList {
} id: 0,
}) parentId: '-1',
} name: '顶级',
children: sysStoreTreeList || []
}
]
}
})
}) })
let activeKey = ref('1') let activeKey = ref('1')

View File

@ -30,93 +30,115 @@
</a-card> </a-card>
<a-card :bordered="false" class="mt-4" style="height: 100%"> <a-card :bordered="false" class="mt-4" style="height: 100%">
<s-table <a-row :gutter="24">
ref="tableRef" <a-col :span="6">
:columns="columns" <dynamic-tree
:data="loadData" ref="dynamicTreeRef"
:alert="options.alert.show" treeTitle="生产组织"
bordered :tableRef="tableRef"
:row-key="(record) => record.id" :apiModel="{
:tool-config="options.toolConfig" getTree: sysStoreApi.sysStoreTree,
:row-selection="options.rowSelection" delTree: sysStoreApi.productionOrganizationDelete
:scroll="{ }"
x: 100, @selectTree="onSelectTree"
y: 'calc(100vh - 300px)' :toolConfig="{
}" plus: false,
> edit: false,
<template #operator> delete: false,
<a-space> refresh: true
<a-button }"
type="primary" ></dynamic-tree>
@click=" </a-col>
navigateTo('/basicData/stash/detail', { <a-col :span="18">
type: 'ADD' <s-table
}) ref="tableRef"
" :columns="columns"
v-if="hasPerm('sysStoreAdd')" :data="loadData"
> :alert="options.alert.show"
<template #icon><plus-outlined /></template> bordered
新增 :row-key="(record) => record.id"
</a-button> :tool-config="options.toolConfig"
<xn-batch-delete :row-selection="options.rowSelection"
v-if="hasPerm('deleteBatchSysStore')" :scroll="{
:selectedRowKeys="selectedRowKeys" x: 100,
@batchDelete="deleteBatchRecords" y: 'calc(100vh - 300px)'
/> }"
</a-space> >
</template> <template #operator>
<template #bodyCell="{ column, record }"> <a-space>
<template v-if="column.dataIndex === 'number'"> <a-button
<a href="#">{{ record.number }}</a> type="primary"
</template>
<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-tooltip title="查看">
<a
@click=" @click="
navigateTo('/basicData/stash/detail', { navigateTo('/basicData/stash/detail', {
type: 'SEARCH', type: 'ADD'
id: record.id
}) })
" "
v-if="hasPerm('customerEdit')" v-if="hasPerm('sysStoreAdd')"
> >
<EyeOutlined /> <template #icon><plus-outlined /></template>
<!-- 查看--> 新增
</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('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button> </a-button>
</a-popconfirm> <xn-batch-delete
</a-space> v-if="hasPerm('deleteBatchSysStore')"
</template> :selectedRowKeys="selectedRowKeys"
</template> @batchDelete="deleteBatchRecords"
</s-table> />
</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-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-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('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button>
</a-popconfirm>
</a-space>
</template>
</template>
</s-table>
</a-col>
</a-row>
</a-card> </a-card>
</template> </template>
@ -192,4 +214,15 @@
stashColumn, stashColumn,
['sysStoreEdit', 'sysStoreDelete'] ['sysStoreEdit', 'sysStoreDelete']
) )
const dynamicTreeRef = ref(null)
const onSelectTree = (value) => {
searchFormState.value.parentId = value.id
tableRef.value.refresh()
}
onMounted(() => {
dynamicTreeRef.value.loadTreeData()
})
</script> </script>

View File

@ -1,14 +1,14 @@
<template> <template>
<xn-form-container <xn-form-container
:title="pageType === 'EDIT' ? '编辑生产组织' : pageType === 'ADD' ? '增加生产组织' : '查看生产组织'" :title="pageType === 'EDIT' ? '编辑生产组织' : pageType === 'ADD' ? '增加生产组织' : '查看生产组织'"
:width="700" width="50%"
:visible="visible" :visible="visible"
:destroy-on-close="true" :destroy-on-close="true"
@close="onClose" @close="onClose"
> >
<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="24"> <a-col :span="12">
<a-form-item label="编码:" name="number"> <a-form-item label="编码:" name="number">
<a-input <a-input
:disabled="pageType === 'SEARCH'" :disabled="pageType === 'SEARCH'"
@ -18,7 +18,7 @@
/> />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="24"> <a-col :span="12">
<a-form-item label="类型:" name="type"> <a-form-item label="类型:" name="type">
<a-select <a-select
:disabled="pageType !== 'ADD'" :disabled="pageType !== 'ADD'"
@ -28,7 +28,7 @@
/> />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="24"> <a-col :span="12">
<a-form-item label="工厂名称:" name="name"> <a-form-item label="工厂名称:" name="name">
<a-input <a-input
:disabled="pageType === 'SEARCH'" :disabled="pageType === 'SEARCH'"
@ -38,7 +38,7 @@
/> />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="24"> <a-col :span="12">
<a-form-item label="仓库:" name="storeId"> <a-form-item label="仓库:" name="storeId">
<a-tree-select <a-tree-select
:disabled="pageType === 'SEARCH'" :disabled="pageType === 'SEARCH'"
@ -56,8 +56,8 @@
</a-tree-select> </a-tree-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="24"> <a-col :span="12" v-if="formData.type !== 'FACTORY'">
<a-form-item label="上级组织:" name="parentId" v-if="formData.type !== 'FACTORY'"> <a-form-item label="上级组织:" name="parentId">
<a-tree-select <a-tree-select
:disabled="pageType === 'SEARCH'" :disabled="pageType === 'SEARCH'"
v-model:value="formData.parentId" v-model:value="formData.parentId"
@ -74,7 +74,7 @@
</a-tree-select> </a-tree-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="24"> <a-col :span="12">
<a-form-item label="厂家名称:" name="manufacturer" v-if="formData.type === 'FACTORY'"> <a-form-item label="厂家名称:" name="manufacturer" v-if="formData.type === 'FACTORY'">
<a-input <a-input
:disabled="pageType === 'SEARCH'" :disabled="pageType === 'SEARCH'"
@ -84,7 +84,7 @@
/> />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="24"> <a-col :span="12">
<a-form-item label="启用状态:" name="enabledState"> <a-form-item label="启用状态:" name="enabledState">
<a-select <a-select
:disabled="pageType === 'SEARCH'" :disabled="pageType === 'SEARCH'"
@ -96,7 +96,7 @@
</a-col> </a-col>
</a-row> </a-row>
<OperationalInformation :detailData="detailData" v-if="pageType !== 'ADD'"></OperationalInformation> <OperationalInformation :detailData="detailData" v-if="pageType !== 'ADD'" :colSpan="12"></OperationalInformation>
</a-form> </a-form>
<template #footer> <template #footer>
<a-button style="margin-right: 8px" @click="onClose"></a-button> <a-button style="margin-right: 8px" @click="onClose"></a-button>

View File

@ -0,0 +1,180 @@
<template>
<xn-form-container
:title="formData.id ? '编辑扩展字段配置' : '增加扩展字段配置'"
width="50%"
:visible="visible"
:destroy-on-close="true"
@close="onClose"
>
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
<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="model">
<a-select
v-model:value="formData.model"
placeholder="请选择所属模块"
:options="tool.dictList('EXTEND_FIELD_MODEL')"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="字段名:" name="fieldName">
<a-input v-model:value="formData.fieldName" placeholder="请输入字段名" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="字段名:" name="fieldType">
<a-input v-model:value="formData.fieldType" placeholder="请输入字段名" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="展示形式:" name="showType">
<a-select
v-model:value="formData.showType"
placeholder="请选择展示形式"
:options="tool.dictList('EXTEND_FIELD_SHOW_TYPE')"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="启用状态:" name="enabledState">
<a-select
v-model:value="formData.enabledState"
placeholder="请选择启用状态"
:options="enabledStateOptions"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="备注:" name="remarks">
<a-textarea v-model:value="formData.remarks" placeholder="请输入备注" allow-clear />
</a-form-item>
</a-col>
<a-col
:span="24"
v-if="formData.showType && formData.showType !== 'input' && formData.showType !== 'inputNumber'"
>
<h3>扩展数据</h3>
<div v-for="(item, index) in selectableData" :key="index" class="mb-2">
<a-space>
<a-button type="primary" @click="addSelectableData" v-if="index === 0">
<PlusOutlined />
</a-button>
<a-button type="primary" danger @click="delSelectableData(index)" v-if="index !== 0">
<MinusOutlined />
</a-button>
<a-input style="width: 100%" v-model:value="item.filedName" placeholder="请输入内容"></a-input>
</a-space>
</div>
</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="extendFieldForm">
import tool from '@/utils/tool'
import { cloneDeep } from 'lodash-es'
import { required } from '@/utils/formRules'
import extendFieldApi from '@/api/base/extendfield/extendFieldApi'
import { message } from 'ant-design-vue'
//
const visible = ref(false)
const emit = defineEmits({ successful: null })
const formRef = ref()
//
const formData = ref({})
const submitLoading = ref(false)
const enabledStateOptions = ref([])
//
let selectableData = ref([
{
filedName: ''
}
])
const addSelectableData = () => {
selectableData.value.push({
filedName: ''
})
}
const delSelectableData = (index) => {
selectableData.value.splice(index, 1)
}
//
const onOpen = (record) => {
visible.value = true
if (record) {
let recordData = cloneDeep(record)
formData.value = Object.assign({}, recordData)
if (recordData.showValues) {
selectableData.value = JSON.parse(recordData.showValues)
} else {
selectableData.value = [
{
filedName: ''
}
]
}
}
enabledStateOptions.value = tool.dictList('COMMON_STATUS')
}
//
const onClose = () => {
formRef.value.resetFields()
formData.value = {}
visible.value = false
}
//
const formRules = {}
//
const onSubmit = () => {
if (
formData.value.showType === 'select' &&
formData.value.showType === 'radio' &&
formData.value.showType === 'checkbox' &&
selectableData.value.length === 0
) {
return message.error('请添加选项要展示的数据')
}
formRef.value.validate().then(() => {
submitLoading.value = true
const formDataParam = cloneDeep(formData.value)
if (formDataParam.showType === 'input' || formDataParam.showType === 'inputNumber') {
formDataParam.showValues = ''
} else {
formDataParam.showValues = JSON.stringify(selectableData.value)
}
extendFieldApi
.extendFieldSubmitForm(formDataParam, formDataParam.id)
.then(() => {
onClose()
emit('successful')
})
.finally(() => {
submitLoading.value = false
})
})
}
//
defineExpose({
onOpen
})
</script>

View File

@ -0,0 +1,160 @@
<template>
<a-card :bordered="false">
<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState">
<a-row :gutter="24">
<a-col :span="6">
<a-form-item label="所属类型" name="type">
<a-input v-model:value="searchFormState.type" 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="enabledStateOptions"
/>
</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" style="height: 100%" class="mt-4">
<s-table
ref="tableRef"
:columns="columns"
:data="loadData"
:alert="options.alert.show"
bordered
:row-key="(record) => record.id"
:tool-config="toolConfig"
:row-selection="options.rowSelection"
>
<template #operator>
<a-space>
<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('extendFieldAdd')">
<template #icon><plus-outlined /></template>
新增
</a-button>
<xn-batch-delete
v-if="hasPerm('extendFieldBatchDelete')"
:selectedRowKeys="selectedRowKeys"
@batchDelete="deleteBatchExtendField"
/>
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'enabledState'">
{{ $TOOL.dictTypeData('COMMON_STATUS', record.enabledState) }}
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a @click="formRef.onOpen(record)" v-if="hasPerm('extendFieldEdit')"></a>
<a-divider type="vertical" v-if="hasPerm(['extendFieldEdit', 'extendFieldDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteExtendField(record)">
<a-button type="link" danger size="small" v-if="hasPerm('extendFieldDelete')"></a-button>
</a-popconfirm>
</a-space>
</template>
</template>
</s-table>
</a-card>
<Form ref="formRef" @successful="tableRef.refresh()" />
</template>
<script setup name="extendfield">
import tool from '@/utils/tool'
import { cloneDeep } from 'lodash-es'
import Form from './detail/form.vue'
import extendFieldApi from '@/api/base/extendfield/extendFieldApi'
const searchFormState = ref({})
const searchFormRef = ref()
const tableRef = ref()
const formRef = ref()
const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
const columns = [
{
title: '名称',
dataIndex: 'name'
},
{
title: '所属类型',
dataIndex: 'type'
},
{
title: '字段名',
dataIndex: 'fieldName'
},
{
title: '字段类型',
dataIndex: 'fieldType'
},
{
title: '备注',
dataIndex: 'remarks'
},
{
title: '启用状态',
dataIndex: 'enabledState'
}
]
//
if (hasPerm(['extendFieldEdit', 'extendFieldDelete'])) {
columns.push({
title: '操作',
dataIndex: 'action',
align: 'center',
width: 150
})
}
const selectedRowKeys = ref([])
//
const options = {
// columns needTotal: true
alert: {
show: true,
clear: () => {
selectedRowKeys.value = ref([])
}
},
rowSelection: {
onChange: (selectedRowKey, selectedRows) => {
selectedRowKeys.value = selectedRowKey
}
}
}
const loadData = (parameter) => {
const searchFormParam = cloneDeep(searchFormState.value)
return extendFieldApi.extendFieldPage(Object.assign(parameter, searchFormParam)).then((data) => {
return data
})
}
//
const reset = () => {
searchFormRef.value.resetFields()
tableRef.value.refresh(true)
}
//
const deleteExtendField = (record) => {
let params = [
{
id: record.id
}
]
extendFieldApi.extendFieldDelete(params).then(() => {
tableRef.value.refresh(true)
})
}
//
const deleteBatchExtendField = (params) => {
extendFieldApi.extendFieldDelete(params).then(() => {
tableRef.value.clearRefreshSelected()
})
}
const enabledStateOptions = tool.dictList('COMMON_STATUS')
</script>