【更新】移动端按钮授权基本完成

pull/84/head
小诺 2023-02-03 01:21:30 +08:00
parent e288a19078
commit ba0ed7978f
7 changed files with 293 additions and 39 deletions

View File

@ -1,32 +0,0 @@
import { baseRequest } from '@/utils/request'
const request = (url, ...arg) => baseRequest(`/mobile/menu/` + url, ...arg)
/**
* 移动端菜单Api接口管理器
*
* @author yubaoshan
* @date 2023/01/28 22:42
**/
export default {
// 获取移动端菜单tree
mobileMenuTree(data) {
return request('tree', data, 'get')
},
// 获取移动端菜单列表
mobileMenuList(data) {
return request('list', data, 'get')
},
// 提交移动端菜单表单 edit为true时为编辑默认为新增
mobileMenuSubmitForm(data, edit = false) {
return request(edit ? 'add' : 'edit', data)
},
// 删除移动端菜单
mobileMenuDelete(data) {
return request('delete', data)
},
// 获取移动端菜单详情
mobileMenuDetail(data) {
return request('detail', data, 'get')
}
}

View File

@ -0,0 +1,37 @@
/**
* Copyright [2022] [https://www.xiaonuo.vip]
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
import { baseRequest } from '@/utils/request'
const request = (url, ...arg) => baseRequest(`/mobile/button/${url}`, ...arg)
/**
* 按钮
*
* @author yubaoshan
* @date 2022-09-22 22:33:20
*/
export default {
// 获取按钮分页
mobileButtonPage(data) {
return request('page', data, 'get')
},
// 提交表单 edit为true时为编辑默认为新增
mobileButtonSubmitForm(data, edit = false) {
return request(edit ? 'add' : 'edit', data)
},
// 删除按钮
mobileButtonDelete(data) {
return request('delete', data)
},
// 获取按钮详情
mobileButtonDetail(data) {
return request('detail', data, 'get')
}
}

View File

@ -33,7 +33,7 @@ export default {
mobileMenuDetail(data) {
return request('detail', data, 'get')
},
// 获取类别选择器
// 获取模块选择器
mobileMenuModuleSelector(data) {
return request('moduleSelector', data, 'get')
},

View File

@ -0,0 +1,80 @@
<template>
<a-modal
v-model:visible="visible"
:title="formData.id ? '编辑按钮' : '增加按钮'"
:width="500"
:mask-closable="false"
:destroy-on-close="true"
@ok="onSubmit"
@cancel="onClose"
>
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
<a-form-item label="显示名称:" name="title">
<a-input v-model:value="formData.title" placeholder="请输入显示名称" allow-clear />
</a-form-item>
<a-form-item label="编码:" name="code">
<a-input v-model:value="formData.code" placeholder="请输入按钮编码" allow-clear />
</a-form-item>
<a-form-item label="排序:" name="sortCode">
<a-slider v-model:value="formData.sortCode" :max="100" :min="0" />
</a-form-item>
</a-form>
</a-modal>
</template>
<script setup>
import { required } from '@/utils/formRules'
import buttonApi from '@/api/mobile/resource/buttonApi'
//
let visible = $ref(false)
const emit = defineEmits({ successful: null })
const formRef = ref()
//
const formData = ref({})
const recordData = ref()
//
const onOpen = (record, buttonData) => {
visible = true
recordData.value = record
formData.value = {
sortCode: 99
}
if (buttonData) {
formData.value = Object.assign({}, buttonData)
}
}
//
const onClose = () => {
formRef.value.resetFields()
visible = false
}
//
const formRules = {
title: [required('请输入按钮名称')],
code: [required('请输入按钮编码')]
}
//
const onSubmit = () => {
formRef.value
.validate()
.then(() => {
const defParam = {
category: 'BUTTON',
// module: recordData.value.module,
parentId: recordData.value.id
}
const param = Object.assign(defParam, formData.value)
buttonApi.mobileButtonSubmitForm(param, !formData.value.id).then(() => {
onClose()
emit('successful')
})
})
}
//
defineExpose({
onOpen
})
</script>

View File

@ -0,0 +1,107 @@
<template>
<a-drawer
title="按钮权限"
:width="650"
:visible="visible"
:destroy-on-close="true"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
@close="onClose"
>
<s-table
ref="table"
:columns="columns"
:data="loadData"
:alert="false"
:row-key="(record) => record.id"
:tool-config="toolConfig"
>
<template #operator class="table-operator">
<a-button type="primary" @click="buttonForm.onOpen(recordData)">
<template #icon>
<plus-outlined />
</template>
<span>新增按钮</span>
</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<a @click="buttonForm.onOpen(recordData, record)">编辑</a>
<a-divider type="vertical" />
<a-popconfirm title="确定要删除此按钮吗?" @confirm="removeButton(record)">
<a-button type="link" danger size="small">删除</a-button>
</a-popconfirm>
</template>
</template>
</s-table>
</a-drawer>
<Form ref="buttonForm" @successful="table.refresh(true)" />
</template>
<script setup>
import buttonApi from '@/api/mobile/resource/buttonApi'
import Form from './form.vue'
const columns = [
{
title: '名称',
dataIndex: 'title'
},
{
title: '编码',
dataIndex: 'code'
},
{
title: '排序',
dataIndex: 'sortCode',
sorter: true
},
{
title: '操作',
key: 'action',
align: 'center',
scopedSlots: { customRender: 'action' }
}
]
const toolConfig = { refresh: true, height: false, columnSetting: false, striped: false }
//
let visible = $ref(false)
const searchFormState = ref()
const buttonForm = ref()
const recordData = ref()
const table = ref()
//
const onOpen = (record) => {
recordData.value = record
searchFormState.value = {
parentId: record.id,
category: 'BUTTON'
}
visible = true
}
//
const onClose = () => {
visible = false
}
//
const loadData = (parameter) => {
return buttonApi.mobileButtonPage(Object.assign(parameter, searchFormState.value)).then((res) => {
return res
})
}
//
const removeButton = (record) => {
let params = [
{
id: record.id
}
]
buttonApi.mobileButtonDelete(params).then((res) => {
table.value.refresh(true)
})
}
//
defineExpose({
onOpen
})
</script>

View File

@ -62,7 +62,7 @@
<a-popconfirm title="确定要删除吗?" @confirm="deleteMobileMenu(record)">
<a-button type="link" danger size="small">删除</a-button>
</a-popconfirm>
<div v-if="record.parentId === '0'">
<div v-if="record.parentId === '0' || record.menuType === 'MENU'">
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link">
@ -74,6 +74,9 @@
<a-menu-item v-if="record.parentId === '0'">
<a @click="changeModuleFormRef.onOpen(record)"></a>
</a-menu-item>
<a-menu-item v-if="record.menuType === 'MENU'">
<a @click="button.onOpen(record)"></a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
@ -85,12 +88,14 @@
</a-card>
<Form ref="formRef" @successful="table.refresh(true)" />
<changeModuleForm ref="changeModuleFormRef" @successful="table.refresh(true)"/>
<Button ref="button" />
</template>
<script setup name="mobileMenuIndex">
import { message } from 'ant-design-vue'
import Form from './form.vue'
import changeModuleForm from './changeModuleForm.vue'
import Button from '../button/index.vue'
import mobileMenuApi from '@/api/mobile/resource/menuApi'
let searchFormState = reactive({})
let moduleList = ref([])
@ -99,6 +104,7 @@
const table = ref()
const formRef = ref()
const changeModuleFormRef = ref()
const button = ref()
const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
const columns = [
{

View File

@ -29,10 +29,22 @@
{{ record.parentName }}
</a-checkbox>
</template>
<template v-if="column.dataIndex === 'title'">
<a-checkbox :checked="record.nameCheck" @update:checked="(val) => changeSub(record, val)">{{
record.title
}}</a-checkbox>
record.title
}}</a-checkbox>
</template>
<template v-if="column.dataIndex === 'button'">
<template v-if="record.button.length > 0">
<template v-for="(item, index) in record.button" :key="item.id">
<a-checkbox v-model:checked="item.check" @change="(evt) => changeChildCheckBox(record, evt)">{{
item.title
}}</a-checkbox>
<br v-if="(index + 1) % 5 === 0" />
</template>
</template>
</template>
</template>
</a-table>
@ -45,14 +57,13 @@
</template>
<script setup name="grantMobileResourceForm">
import tool from '@/utils/tool'
import roleApi from '@/api/sys/roleApi'
const spinningLoading = ref(false)
let firstShowMap = $ref({})
const emit = defineEmits({ successful: null })
const submitLoading = ref(false)
//
const drawerWidth = 600
const drawerWidth = 1000
// 90%
//(window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) * 0.9
@ -76,6 +87,11 @@
title: '菜单',
dataIndex: 'title',
width: 200
},
{
key: 'button',
title: '按钮授权',
dataIndex: 'button'
}
]
const echoDatalist = ref([])
@ -104,6 +120,7 @@
loadDatas.value = echoDatalist.value[0].menu
}
}
const checkFieldKeys = ['button']
let visible = $ref(false)
//
let resultDataModel = {
@ -129,6 +146,16 @@
resEcho.grantInfoList.forEach((grant) => {
if (item.id === grant.menuId) {
menueCheck.value++
//
if (grant.buttonInfo) {
grant.buttonInfo.forEach((button) => {
item.button.forEach((itemButton) => {
if (button === itemButton.id) {
itemButton.check = true
}
})
})
}
}
})
}
@ -169,10 +196,33 @@
item.check = val
})
}
const checkAllChildNotChecked = (record) => {
const allChecked = checkFieldKeys.every((key) => {
//
const child = record[key]
return child.every((field) => !field.check)
})
return allChecked
}
const changeChildCheckBox = (record, evt) => {
let checked = evt.target.checked
if (!checked && checkAllChildNotChecked(record)) {
//
/*record.nameCheck = false
record.parentCheck = false*/
} else if (checked) {
record.nameCheck = checked
record.parentCheck = checked
}
}
//
const changeSub = (record, val) => {
//
record.nameCheck = val
checkFieldKeys.forEach((key) => {
//
handleOnlySelf(record, key, val)
})
}
//
const changeParent = (record, val) => {
@ -205,10 +255,16 @@
if (table.menu) {
table.menu.forEach((item) => {
const grantInfo = {
menuId: ''
menuId: '',
buttonInfo: []
}
if (item.nameCheck) {
grantInfo.menuId = item.id
item.button.forEach((button) => {
if (button.check) {
grantInfo.buttonInfo.push(button.id)
}
})
resultDataModel.grantInfoList.push(grantInfo)
}
})