【更新】完善移动端菜的跟模块的管理

pull/84/head
小诺 2023-02-01 01:10:30 +08:00
parent b5f005613b
commit a2ac82a1e8
4 changed files with 214 additions and 66 deletions

View File

@ -21,6 +21,10 @@ export default {
mobileMenuSubmitForm(data, edit = false) { mobileMenuSubmitForm(data, edit = false) {
return request(edit ? 'add' : 'edit', data) return request(edit ? 'add' : 'edit', data)
}, },
// 更改菜单所属模块
mobileMenuChangeModule(data) {
return request('changeModule', data)
},
// 删除移动端菜单 // 删除移动端菜单
mobileMenuDelete(data) { mobileMenuDelete(data) {
return request('delete', data) return request('delete', data)

View File

@ -0,0 +1,92 @@
<template>
<a-drawer
title="更改模块"
:width="500"
:visible="visible"
:destroy-on-close="true"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
@close="onClose"
>
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
<a-form-item label="显示名称:" name="title">
<span>{{formData.title}}</span>
</a-form-item>
<a-form-item label="所属目录:" name="module" v-if="formData.parentId === '0'" >
<a-radio-group v-model:value="formData.module" button-style="solid">
<a-radio-button
v-for="module in moduleTypeList"
:key="module.id"
:value="module.id"
>
<component :is="module.icon" />
{{ module.title }}</a-radio-button
>
</a-radio-group>
</a-form-item>
</a-form>
<template #footer>
<a-button style="margin-right: 8px" @click="onClose"></a-button>
<a-button type="primary" :loading="submitLoading" @click="onSubmit"></a-button>
</template>
</a-drawer>
</template>
<script setup>
import { required } from '@/utils/formRules'
import tool from '@/utils/tool'
import mobileMenuApi from '@/api/mobile/resource/menuApi'
import { getCurrentInstance } from 'vue'
//
let visible = $ref(false)
const emit = defineEmits({ successful: null })
const formRef = ref()
//
const formData = ref({})
const submitLoading = ref(false)
const moduleTypeList = ref([])
//
const onOpen = (record) => {
visible = true
if (record) {
formData.value = Object.assign({}, record)
}
//
mobileMenuApi.mobileMenuModuleSelector().then((data) => {
moduleTypeList.value = data
})
}
//
const onClose = () => {
formRef.value.resetFields()
visible = false
}
//
const formRules = {
module: [required('请选择所属目录')],
}
//
const onSubmit = () => {
formRef.value
.validate()
.then(() => {
const param = {
id: formData.value.id,
module: formData.value.module
}
submitLoading.value = true
mobileMenuApi.mobileMenuChangeModule(param).then(() => {
submitLoading.value = false
emit('successful')
}).finally(() => {
visible = false
})
})
}
//
defineExpose({
onOpen
})
</script>

View File

@ -1,68 +1,70 @@
<template> <template>
<a-drawer <a-drawer
:title="formData.id ? '编辑移动端菜单' : '增加移动端菜单'" :title="formData.id ? '编辑移动端菜单' : '增加移动端菜单'"
:width="600" :width="500"
:visible="visible" :visible="visible"
:destroy-on-close="true" :destroy-on-close="true"
:footer-style="{ textAlign: 'right' }" :footer-style="{ textAlign: 'right' }"
@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-form-item label="上级菜单:" name="parentId">
<a-col :span="12"> <a-tree-select
<a-form-item label="上级菜单:" name="parentId"> v-model:value="formData.parentId"
<a-tree-select v-model:treeExpandedKeys="defaultExpandedKeys"
v-model:value="formData.parentId" style="width: 100%"
v-model:treeExpandedKeys="defaultExpandedKeys" :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
style="width: 100%" placeholder="请选择上级菜单"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" allow-clear
placeholder="请选择上级菜单" tree-default-expand-all
allow-clear :tree-data="treeData"
tree-default-expand-all :field-names="{
:tree-data="treeData"
:field-names="{
children: 'children', children: 'children',
label: 'title', label: 'title',
value: 'id' value: 'id'
}" }"
selectable="false" selectable="false"
tree-line tree-line
@change="parentChange(formData.parentId)" @change="parentChange(formData.parentId)"
></a-tree-select> ></a-tree-select>
</a-form-item> </a-form-item>
</a-col> <a-form-item label="名称:" name="title">
<a-col :span="12"> <a-input v-model:value="formData.title" placeholder="请输入名称" allow-clear />
<a-form-item label="名称:" name="title"> </a-form-item>
<a-input v-model:value="formData.title" placeholder="请输入名称" allow-clear /> <a-form-item label="菜单类型:" name="menuType">
</a-form-item> <a-radio-group
</a-col> v-model:value="formData.menuType"
<a-col :span="12"> button-style="solid"
<a-form-item label="界面路径:" name="pages"> :options="menuTypeOptions"
<a-input v-model:value="formData.pages" placeholder="请输入界面路径" allow-clear /> option-type="button"
</a-form-item> >
</a-col> </a-radio-group>
<a-col :span="12"> </a-form-item>
<a-form-item label="图标:" name="icon"> <a-form-item v-if="formData.menuType !== 'CATALOG'" name="path">
<a-input v-model:value="formData.icon" style="width: calc(100% - 70px)" placeholder="请选择图标" allow-clear /> <template #label>
<a-button type="primary" @click="iconSelector.showIconModal(formData.icon)"></a-button> <a-tooltip>
</a-form-item> <template #title>
</a-col> 类型为内外链条时输入https开头的链接即可https://xiaonuo.vip
<a-col :span="12"> </template>
<a-form-item label="颜色:" name="color"> <question-circle-outlined />
<color-picker v-model:value="formData.color" /> </a-tooltip>
</a-form-item> &nbsp {{ formData.menuType === 'MENU' || formData.menuType === 'CATALOG' ? '界面地址' : 'https链接地址' }}
</a-col> </template>
<a-col :span="12"> <a-input v-model:value="formData.path" placeholder="请输入" allow-clear />
<a-form-item label="是否正规则:" name="regType"> </a-form-item>
<a-radio-group v-model:value="formData.regType" placeholder="请选择正规则" :options="regTypeOptions" /> <a-form-item label="图标:" name="icon">
</a-form-item> <a-input v-model:value="formData.icon" style="width: calc(100% - 70px)" placeholder="请选择图标" allow-clear />
</a-col> <a-button type="primary" @click="iconSelector.showIconModal(formData.icon)"></a-button>
<a-col :span="12"> </a-form-item>
<a-form-item label="可用状态:" name="status"> <a-form-item label="颜色:" name="color">
<a-radio-group v-model:value="formData.status" placeholder="请选择可用状态" :options="statusOptions" /> <color-picker v-model:value="formData.color" />
</a-form-item> </a-form-item>
</a-col> <a-form-item label="是否正规则:" name="regType">
</a-row> <a-radio-group v-model:value="formData.regType" placeholder="请选择正规则" :options="regTypeOptions" />
</a-form-item>
<a-form-item label="可用状态:" name="status">
<a-radio-group v-model:value="formData.status" placeholder="请选择可用状态" :options="statusOptions" />
</a-form-item>
<a-form-item label="排序码:" name="sortCode"> <a-form-item label="排序码:" name="sortCode">
<a-slider v-model:value="formData.sortCode" :max="1000" style="width: 100%" /> <a-slider v-model:value="formData.sortCode" :max="1000" style="width: 100%" />
</a-form-item> </a-form-item>
@ -77,6 +79,7 @@
<script setup name="mobileMenuForm"> <script setup name="mobileMenuForm">
import tool from '@/utils/tool' import tool from '@/utils/tool'
import SnowflakeId from 'snowflake-id'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import { required } from '@/utils/formRules' import { required } from '@/utils/formRules'
import mobileMenuApi from '@/api/mobile/resource/menuApi' import mobileMenuApi from '@/api/mobile/resource/menuApi'
@ -96,6 +99,24 @@
const submitLoading = ref(false) const submitLoading = ref(false)
const regTypeOptions = ref([]) const regTypeOptions = ref([])
const statusOptions = ref([]) const statusOptions = ref([])
const menuTypeOptions = [
{
label: '目录',
value: 'CATALOG'
},
{
label: '菜单',
value: 'MENU'
},
{
label: '内链',
value: 'IFRAME'
},
{
label: '外链',
value: 'LINK'
}
]
// //
const onOpen = (record, module) => { const onOpen = (record, module) => {
@ -105,7 +126,8 @@
formData.value = { formData.value = {
regType: 'YES', regType: 'YES',
status: 'ENABLE', status: 'ENABLE',
category: 'MENU' category: 'MENU',
menuType: 'MENU'
} }
if (record) { if (record) {
let recordData = cloneDeep(record) let recordData = cloneDeep(record)
@ -156,7 +178,7 @@
const formRules = { const formRules = {
parentId: [required('请选择上级')], parentId: [required('请选择上级')],
title: [required('请输入名称')], title: [required('请输入名称')],
pages: [required('请输入界面路径')], path: [required('请输入界面路径')],
icon: [required('请选择图标')], icon: [required('请选择图标')],
color: [required('请选择颜色')], color: [required('请选择颜色')],
regType: [required('请选择规则类型')], regType: [required('请选择规则类型')],
@ -168,8 +190,7 @@
.validate() .validate()
.then(() => { .then(() => {
submitLoading.value = true submitLoading.value = true
const formDataParam = cloneDeep(formData.value) const formDataParam = parameterChanges(cloneDeep(formData.value))
formDataParam.module = moduleId.value
mobileMenuApi mobileMenuApi
.mobileMenuSubmitForm(formDataParam, !formDataParam.id) .mobileMenuSubmitForm(formDataParam, !formDataParam.id)
.then(() => { .then(() => {
@ -181,6 +202,17 @@
}) })
}) })
} }
//
const parameterChanges = (data) => {
data.module = moduleId.value
if (data.menuType === 'CATALOG') {
const snowflake = new SnowflakeId()
if (!data.path) {
data.path = snowflake.generate()
}
}
return data
}
// //
defineExpose({ defineExpose({
onOpen onOpen

View File

@ -42,6 +42,13 @@
</a-space> </a-space>
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'path'">
<span v-if="record.menuType === 'CATALOG'">-</span>
<span v-else>{{record.path}}</span>
</template>
<template v-if="column.dataIndex === 'icon'">
<component :is="record.icon" />
</template>
<template v-if="column.dataIndex === 'regType'"> <template v-if="column.dataIndex === 'regType'">
{{ $TOOL.dictTypeData('MOBILE_REG_TYPE', record.regType) }} {{ $TOOL.dictTypeData('MOBILE_REG_TYPE', record.regType) }}
</template> </template>
@ -55,17 +62,35 @@
<a-popconfirm title="确定要删除吗?" @confirm="deleteMobileMenu(record)"> <a-popconfirm title="确定要删除吗?" @confirm="deleteMobileMenu(record)">
<a-button type="link" danger size="small">删除</a-button> <a-button type="link" danger size="small">删除</a-button>
</a-popconfirm> </a-popconfirm>
<div v-if="record.parentId === '0'">
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link">
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item v-if="record.parentId === '0'">
<a @click="changeModuleFormRef.onOpen(record)"></a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</div>
</a-space> </a-space>
</template> </template>
</template> </template>
</s-table> </s-table>
</a-card> </a-card>
<Form ref="formRef" @successful="table.refresh(true)" /> <Form ref="formRef" @successful="table.refresh(true)" />
<changeModuleForm ref="changeModuleFormRef" @successful="table.refresh(true)"/>
</template> </template>
<script setup name="mobileMenuIndex"> <script setup name="mobileMenuIndex">
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
import Form from './form.vue' import Form from './form.vue'
import changeModuleForm from './changeModuleForm.vue'
import mobileMenuApi from '@/api/mobile/resource/menuApi' import mobileMenuApi from '@/api/mobile/resource/menuApi'
let searchFormState = reactive({}) let searchFormState = reactive({})
let moduleList = ref([]) let moduleList = ref([])
@ -73,6 +98,7 @@
const searchFormRef = ref() const searchFormRef = ref()
const table = ref() const table = ref()
const formRef = ref() const formRef = ref()
const changeModuleFormRef = ref()
const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false } const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
const columns = [ const columns = [
{ {
@ -81,12 +107,13 @@
}, },
{ {
title: '界面路径', title: '界面路径',
dataIndex: 'pages', dataIndex: 'path',
ellipsis: true ellipsis: true
}, },
{ {
title: '图标', title: '图标',
dataIndex: 'icon' dataIndex: 'icon',
width: 80
}, },
{ {
title: '正规则', title: '正规则',
@ -105,7 +132,7 @@
title: '操作', title: '操作',
dataIndex: 'action', dataIndex: 'action',
align: 'center', align: 'center',
width: '150px' width: 200
} }
] ]
let selectedRowKeys = ref([]) let selectedRowKeys = ref([])
@ -144,13 +171,6 @@
return [] return []
}) })
} }
/*const searchFormParam = JSON.parse(JSON.stringify(searchFormState))
return mobileMenuApi.mobileMenuTree(Object.assign(parameter, searchFormParam)).then((data) => {
if (data) {
return data
}
return []
})*/
} }
// //
const moduleClock = (value) => { const moduleClock = (value) => {