提交 8bccdd5c 作者: 郁骅焌

角色修改

上级 bf0864e6
...@@ -21,6 +21,7 @@ declare module 'vue' { ...@@ -21,6 +21,7 @@ declare module 'vue' {
CarouselVertical: typeof import('./../../../src/views/vab/carousel/vabAutoComponents/CarouselVertical.vue')['default'] CarouselVertical: typeof import('./../../../src/views/vab/carousel/vabAutoComponents/CarouselVertical.vue')['default']
CommonProperty: typeof import('./../../../src/views/other/workflow/vabAutoComponents/propertySetting/CommonProperty.vue')['default'] CommonProperty: typeof import('./../../../src/views/other/workflow/vabAutoComponents/propertySetting/CommonProperty.vue')['default']
Control: typeof import('./../../../src/views/other/workflow/vabAutoComponents/lFComponents/Control.vue')['default'] Control: typeof import('./../../../src/views/other/workflow/vabAutoComponents/lFComponents/Control.vue')['default']
copy: typeof import('./../../../src/views/system/roleManagement/vabAutoComponents/RoleManagementEdit2 copy.vue')['default']
DataDialog: typeof import('./../../../src/views/other/workflow/vabAutoComponents/lFComponents/DataDialog.vue')['default'] DataDialog: typeof import('./../../../src/views/other/workflow/vabAutoComponents/lFComponents/DataDialog.vue')['default']
DataScreenBottom: typeof import('./../../../src/views/index/vabAutoComponents/DataScreenBottom.vue')['default'] DataScreenBottom: typeof import('./../../../src/views/index/vabAutoComponents/DataScreenBottom.vue')['default']
DataScreenHeader: typeof import('./../../../src/views/index/vabAutoComponents/DataScreenHeader.vue')['default'] DataScreenHeader: typeof import('./../../../src/views/index/vabAutoComponents/DataScreenHeader.vue')['default']
...@@ -161,6 +162,7 @@ declare module 'vue' { ...@@ -161,6 +162,7 @@ declare module 'vue' {
Rank: typeof import('./../../../src/views/index/vabAutoComponents/Rank.vue')['default'] Rank: typeof import('./../../../src/views/index/vabAutoComponents/Rank.vue')['default']
RankList: typeof import('./../../../src/views/index/vabAutoComponents/RankList.vue')['default'] RankList: typeof import('./../../../src/views/index/vabAutoComponents/RankList.vue')['default']
Recommendation: typeof import('./../../../src/views/index/vabAutoComponents/Recommendation.vue')['default'] Recommendation: typeof import('./../../../src/views/index/vabAutoComponents/Recommendation.vue')['default']
RoleManagementAuth: typeof import('./../../../src/views/system/roleManagement/vabAutoComponents/RoleManagementAuth.vue')['default']
RoleManagementEdit: typeof import('./../../../src/views/setting/roleManagement/vabAutoComponents/RoleManagementEdit.vue')['default'] RoleManagementEdit: typeof import('./../../../src/views/setting/roleManagement/vabAutoComponents/RoleManagementEdit.vue')['default']
RoleManagementEdit2: typeof import('./../../../src/views/system/roleManagement/vabAutoComponents/RoleManagementEdit2.vue')['default'] RoleManagementEdit2: typeof import('./../../../src/views/system/roleManagement/vabAutoComponents/RoleManagementEdit2.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
......
...@@ -3,3 +3,12 @@ ...@@ -3,3 +3,12 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
/* tree border */
.tree-border {
width: 100%;
margin-top: 5px;
background: var(--el-bg-color, #ffffff) none;
border: 1px solid var(--el-border-color-light, #e5e6e7);
border-radius: 4px;
}
...@@ -50,3 +50,19 @@ export function getMenu(menuId: any) { ...@@ -50,3 +50,19 @@ export function getMenu(menuId: any) {
method: 'get', method: 'get',
}) })
} }
// 查询菜单下拉树结构
export function treeselect() {
return request({
url: '/system/menu/treeselect',
method: 'get',
})
}
// 根据角色ID查询菜单下拉树结构
export function roleMenuTreeselect(roleId: any) {
return request({
url: `/system/menu/roleMenuTreeselect/${roleId}`,
method: 'get',
})
}
...@@ -34,3 +34,28 @@ export const doDelete = (roleId: any) => { ...@@ -34,3 +34,28 @@ export const doDelete = (roleId: any) => {
method: 'delete', method: 'delete',
}) })
} }
// 查询角色详细
export function getRole(roleId: any) {
return request({
url: `/system/role/${roleId}`,
method: 'get',
})
}
// 根据角色ID查询部门树结构
export function deptTreeSelect(roleId: any) {
return request({
url: `/system/role/deptTree/${roleId}`,
method: 'get',
})
}
// 角色数据权限
export function dataScope(data: any) {
return request({
url: '/system/role/dataScope',
method: 'put',
data,
})
}
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
</el-row> </el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button type="primary" @click="save">确定</el-button> <el-button type="primary" @click="save"> </el-button>
<el-button @click="cancel">取 消</el-button> <el-button @click="cancel">取 消</el-button>
</template> </template>
</vab-dialog> </vab-dialog>
......
...@@ -187,7 +187,7 @@ ...@@ -187,7 +187,7 @@
</el-row> </el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button type="primary" @click="save">确定</el-button> <el-button type="primary" @click="save"> </el-button>
<el-button @click="cancel">取 消</el-button> <el-button @click="cancel">取 消</el-button>
</template> </template>
</vab-dialog> </vab-dialog>
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button type="primary" @click="save">确定</el-button> <el-button type="primary" @click="save"> </el-button>
<el-button @click="cancel">取 消</el-button> <el-button @click="cancel">取 消</el-button>
</template> </template>
</vab-dialog> </vab-dialog>
......
...@@ -92,10 +92,14 @@ ...@@ -92,10 +92,14 @@
<span v-else>{{ scope.row[item.prop] }}</span> <span v-else>{{ scope.row[item.prop] }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" fixed="right" label="操作" min-width="160"> <el-table-column align="center" fixed="right" label="操作" width="360">
<template #default="scope"> <template #default="scope">
<el-button icon="Edit" link type="primary" @click="handleUpdate(scope.row)">修改</el-button> <div v-if="scope.row.roleId !== 1" class="table-operation-button">
<el-button icon="Delete" link type="primary" @click="handleDelete(scope.row)">删除</el-button> <el-button icon="Edit" link type="primary" @click="handleUpdate(scope.row)">修改</el-button>
<el-button icon="Delete" link type="primary" @click="handleDelete(scope.row)">删除</el-button>
<el-button icon="CircleCheck" link type="primary" @click="handleDataScope(scope.row)">数据权限</el-button>
<el-button icon="User" link type="primary" @click="handleAuthUser(scope.row)">分配用户</el-button>
</div>
</template> </template>
</el-table-column> </el-table-column>
<template #empty> <template #empty>
...@@ -110,6 +114,7 @@ ...@@ -110,6 +114,7 @@
@size-change="handleSizeChange" @size-change="handleSizeChange"
/> />
<role-management-edit2 ref="editRef" @fetch-data="fetchData" /> <role-management-edit2 ref="editRef" @fetch-data="fetchData" />
<role-management-auth ref="authRef" @fetch-data="fetchData" />
</div> </div>
</template> </template>
...@@ -130,6 +135,7 @@ const isFullscreen = ref<boolean>(false) ...@@ -130,6 +135,7 @@ const isFullscreen = ref<boolean>(false)
const fold = ref<boolean>(true) const fold = ref<boolean>(true)
const tableRef = ref<TableInstance>() const tableRef = ref<TableInstance>()
const editRef = ref<any>(null) const editRef = ref<any>(null)
const authRef = ref<any>(null)
const list = ref<any>([]) const list = ref<any>([])
const listLoading = ref<boolean>(true) const listLoading = ref<boolean>(true)
...@@ -237,7 +243,7 @@ function handleUpdate(row: any) { ...@@ -237,7 +243,7 @@ function handleUpdate(row: any) {
/** 删除按钮操作 */ /** 删除按钮操作 */
const handleDelete = (row: any = {}) => { const handleDelete = (row: any = {}) => {
if (row.roleId) { if (row.roleId) {
$baseConfirm('您确定要删除当前项吗', null, async () => { $baseConfirm(`您确定要删除角色名称为“${row.roleName}”的数据项吗`, null, async () => {
const { msg }: any = await doDelete(row.roleId) const { msg }: any = await doDelete(row.roleId)
$baseMessage(msg, 'success', 'hey') $baseMessage(msg, 'success', 'hey')
await fetchData() await fetchData()
...@@ -266,4 +272,14 @@ function handleExport() { ...@@ -266,4 +272,14 @@ function handleExport() {
`role_${Date.now()}.xlsx` `role_${Date.now()}.xlsx`
) )
} }
/** 分配数据权限操作 */
function handleDataScope(row: any) {
authRef.value.showEdit(row)
}
/** 分配用户 */
function handleAuthUser(row) {
// router.push("/system/role-auth/user/" + row.roleId);
}
</script> </script>
<template>
<vab-dialog v-model="dialogFormVisible" append-to-body :title="title" width="500px" @close="close">
<el-form ref="formRef" label-width="100px" :model="form">
<el-form-item label="角色名称">
<el-input v-model="form.roleName" :disabled="true" />
</el-form-item>
<el-form-item label="权限字符">
<el-input v-model="form.roleKey" :disabled="true" />
</el-form-item>
<el-form-item label="权限范围">
<el-select v-model="form.dataScope" @change="dataScopeSelectChange">
<el-option v-for="item in dataScopeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item v-show="form.dataScope == 2" label="数据权限">
<el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event)">展开/折叠</el-checkbox>
<el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event)">全选/全不选</el-checkbox>
<el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event)">父子联动</el-checkbox>
<el-tree
ref="deptRef"
:check-strictly="!form.deptCheckStrictly"
class="tree-border"
:data="deptOptions"
default-expand-all
empty-text="加载中,请稍候"
node-key="id"
:props="{ label: 'label', children: 'children' }"
show-checkbox
/>
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" @click="save">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</template>
</vab-dialog>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import { dataScope, deptTreeSelect, getRole } from '/@/api/roleManagement'
defineOptions({
name: 'RoleManagementAuth',
})
const { proxy } = getCurrentInstance() as any
const emit = defineEmits(['fetch-data'])
const menuRef = ref<any>(null)
const menuExpand = ref(false)
const menuNodeAll = ref(false)
const deptRef = ref<any>(null)
const deptExpand = ref(true)
const deptNodeAll = ref(false)
const deptOptions = ref<any>([])
/** 数据范围选项*/
const dataScopeOptions = ref([
{ value: '1', label: '全部数据权限' },
{ value: '2', label: '自定数据权限' },
{ value: '3', label: '本部门数据权限' },
{ value: '4', label: '本部门及以下数据权限' },
{ value: '5', label: '仅本人数据权限' },
])
const formRef = ref<FormInstance>()
const form = ref<any>({
roleId: undefined,
roleName: undefined,
roleKey: undefined,
roleSort: 0,
status: '0',
menuIds: [],
deptIds: [],
menuCheckStrictly: true,
deptCheckStrictly: true,
remark: undefined,
})
const title = ref<string>('')
const dialogFormVisible = ref<boolean>(false)
const showEdit = (row?: any) => {
reset()
title.value = '分配数据权限'
const deptTreeSelect = getDeptTree(row.roleId)
getRole(row.roleId).then((response) => {
form.value = response.data
dialogFormVisible.value = true
nextTick(() => {
deptTreeSelect.then((res: any) => {
nextTick(() => {
if (deptRef.value) {
deptRef.value.setCheckedKeys(res.checkedKeys)
}
})
})
})
})
}
/** 根据角色ID查询部门树结构 */
function getDeptTree(roleId: any) {
return deptTreeSelect(roleId).then((response: any) => {
deptOptions.value = response.depts
return response
})
}
/** 选择角色权限范围触发 */
function dataScopeSelectChange(value: any) {
if (value !== '2') {
deptRef.value.setCheckedKeys([])
}
}
/** 树权限(展开/折叠)*/
function handleCheckedTreeExpand(value: any) {
let treeList = deptOptions.value
for (const treeItem of treeList) {
deptRef.value.store.nodesMap[treeItem.id].expanded = value
}
}
/** 树权限(全选/全不选) */
function handleCheckedTreeNodeAll(value: any) {
deptRef.value.setCheckedNodes(value ? deptOptions.value : [])
}
/** 树权限(父子联动) */
function handleCheckedTreeConnect(value: any) {
form.value.deptCheckStrictly = value ? true : false
}
/** 所有部门节点数据 */
function getDeptAllCheckedKeys() {
// 目前被选中的部门节点
let checkedKeys = deptRef.value.getCheckedKeys()
// 半选中的部门节点
let halfCheckedKeys = deptRef.value.getHalfCheckedKeys()
checkedKeys.unshift(...halfCheckedKeys)
return checkedKeys
}
/** 重置新增的表单以及其他数据 */
function reset() {
if (menuRef.value != undefined) {
menuRef.value.setCheckedKeys([])
}
menuExpand.value = false
menuNodeAll.value = false
deptExpand.value = true
deptNodeAll.value = false
form.value = {
roleId: undefined,
roleName: undefined,
roleKey: undefined,
roleSort: 0,
status: '0',
menuIds: [],
deptIds: [],
menuCheckStrictly: true,
deptCheckStrictly: true,
remark: undefined,
}
proxy.resetForm('formRef')
}
const close = () => {
formRef.value?.clearValidate()
formRef.value?.resetFields()
emit('fetch-data')
}
const cancel = () => {
close()
dialogFormVisible.value = false
}
const save = () => {
formRef.value?.validate(async (valid: any) => {
if (valid) {
form.value.deptIds = getDeptAllCheckedKeys()
dataScope(form.value)
await $baseMessage('修改成功', 'success', 'hey')
cancel()
}
})
}
onBeforeMount(() => {})
defineExpose({
showEdit,
})
</script>
<style lang="scss" scoped>
.vab-tree-border {
width: 100%;
height: 250px;
padding: var(--el-padding);
overflow-y: auto;
border: 1px solid var(--el-border-color);
border-radius: var(--el-border-radius-base);
}
</style>
<template> <template>
<vab-dialog v-model="dialogFormVisible" append-to-body :title="title" width="500px" @close="close"> <vab-dialog v-model="dialogFormVisible" append-to-body :title="title" width="500px" @close="close">
<el-form ref="formRef" label-width="80px" :model="form" :rules="rules"> <el-form ref="formRef" label-width="100px" :model="form" :rules="rules">
<el-form-item label="角色码" prop="role"> <el-form-item label="角色名称" prop="roleName">
<el-input v-model="form.role" clearable /> <el-input v-model="form.roleName" placeholder="请输入角色名称" />
</el-form-item> </el-form-item>
<el-form-item label="菜单"> <el-form-item prop="roleKey">
<div class="vab-tree-border"> <template #label>
<el-tree <span>
ref="treeRef" <el-tooltip content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasRole('admin')`)" placement="top">
:data="list" <el-icon><question-filled /></el-icon>
:default-checked-keys="form.menuCheckedList" </el-tooltip>
:default-expanded-keys="[]" 权限字符
node-key="path" </span>
show-checkbox </template>
> <el-input v-model="form.roleKey" placeholder="请输入权限字符" />
<template #default="{ data }">
<span>{{ data.meta.title }}</span>
</template>
</el-tree>
</div>
</el-form-item> </el-form-item>
<el-form-item label="按钮权限"> <el-form-item label="角色顺序" prop="roleSort">
<el-input v-model="form.btnRolesCheckedList" clearable :rows="3" type="textarea" /> <el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="菜单权限">
<el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event)">展开/折叠</el-checkbox>
<el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event)">全选/全不选</el-checkbox>
<el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event)">父子联动</el-checkbox>
<el-tree
ref="menuRef"
:check-strictly="!form.menuCheckStrictly"
class="tree-border"
:data="menuOptions"
empty-text="加载中,请稍候"
node-key="id"
:props="{ label: 'label', children: 'children' }"
show-checkbox
/>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="form.remark" placeholder="请输入内容" type="textarea" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button type="primary" @click="save">保存</el-button> <el-button type="primary" @click="save">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</template> </template>
</vab-dialog> </vab-dialog>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import { doEdit } from '/@/api/roleManagement' import { treeselect as menuTreeselect, roleMenuTreeselect } from '/@/api/menuManagement'
import { getList } from '/@/api/router' import { doAdd, doEdit, getRole } from '/@/api/roleManagement'
defineOptions({ defineOptions({
name: 'RoleManagementEdit', name: 'RoleManagementEdit',
}) })
const { proxy } = getCurrentInstance() as any
const { sys_normal_disable } = proxy.useDict('sys_normal_disable')
const emit = defineEmits(['fetch-data']) const emit = defineEmits(['fetch-data'])
const menuRef = ref<any>(null)
const menuExpand = ref(false)
const menuNodeAll = ref(false)
const deptExpand = ref(true)
const deptNodeAll = ref(false)
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const treeRef = ref<any>(null) const form = ref<any>({
const form = reactive<any>({ roleId: undefined,
role: '', roleName: undefined,
btnRolesCheckedList: [ roleKey: undefined,
'read:system', roleSort: 0,
'write:system', status: '0',
'delete:system', menuIds: [],
'read:index', deptIds: [],
'write:index', menuCheckStrictly: true,
'delete:index', deptCheckStrictly: true,
'read:index', remark: undefined,
'write:index',
'delete:index',
],
}) })
const rules = reactive<any>({ const rules = reactive<any>({
role: [{ required: true, trigger: 'blur', message: '请输入角色码' }], roleName: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
roleKey: [{ required: true, message: '权限字符不能为空', trigger: 'blur' }],
roleSort: [{ required: true, message: '角色顺序不能为空', trigger: 'blur' }],
}) })
const title = ref<string>('') const title = ref<string>('')
const dialogFormVisible = ref<boolean>(false) const dialogFormVisible = ref<boolean>(false)
const list = ref<any>([]) const menuOptions = ref<any>([])
const showEdit = (row: any) => { const showEdit = (row?: any) => {
dialogFormVisible.value = true reset()
nextTick(() => { if (row && row.roleId) {
if (row) { title.value = '编辑'
title.value = '编辑' const roleMenu = getRoleMenuTreeselect(row.roleId)
Object.assign(form, row) getRole(row.roleId).then((response) => {
} else { form.value = response.data
title.value = '添加' form.value.roleSort = Number(form.value.roleSort)
form.btnRolesCheckedList = [ dialogFormVisible.value = true
'read:system', nextTick(() => {
'write:system', roleMenu.then((res: any) => {
'delete:system', let checkedKeys = res.checkedKeys
'read:index', checkedKeys.forEach((v: any) => {
'write:index', nextTick(() => {
'delete:index', menuRef.value.setChecked(v, true, false)
'read:index', })
'write:index', })
'delete:index', })
] })
} })
} else {
getMenuTreeselect()
title.value = '添加'
dialogFormVisible.value = true
}
}
/** 根据角色ID查询菜单树结构 */
function getRoleMenuTreeselect(roleId: any) {
return roleMenuTreeselect(roleId).then((response: any) => {
menuOptions.value = response.menus
return response
}) })
} }
defineExpose({ /** 查询菜单树结构 */
showEdit, function getMenuTreeselect() {
}) menuTreeselect().then((response) => {
menuOptions.value = response.data
})
}
/** 树权限(展开/折叠)*/
function handleCheckedTreeExpand(value: any) {
let treeList = menuOptions.value
for (const treeItem of treeList) {
menuRef.value.store.nodesMap[treeItem.id].expanded = value
}
}
/** 树权限(全选/全不选) */
function handleCheckedTreeNodeAll(value: any) {
menuRef.value.setCheckedNodes(value ? menuOptions.value : [])
}
/** 树权限(父子联动) */
function handleCheckedTreeConnect(value: any) {
form.value.menuCheckStrictly = value ? true : false
}
/** 所有菜单节点数据 */
function getMenuAllCheckedKeys() {
// 目前被选中的菜单节点
let checkedKeys = menuRef.value.getCheckedKeys()
// 半选中的菜单节点
let halfCheckedKeys = menuRef.value.getHalfCheckedKeys()
checkedKeys.unshift(...halfCheckedKeys)
return checkedKeys
}
/** 重置新增的表单以及其他数据 */
function reset() {
if (menuRef.value != undefined) {
menuRef.value.setCheckedKeys([])
}
menuExpand.value = false
menuNodeAll.value = false
deptExpand.value = true
deptNodeAll.value = false
form.value = {
roleId: undefined,
roleName: undefined,
roleKey: undefined,
roleSort: 0,
status: '0',
menuIds: [],
deptIds: [],
menuCheckStrictly: true,
deptCheckStrictly: true,
remark: undefined,
}
proxy.resetForm('formRef')
}
const close = () => { const close = () => {
formRef.value?.clearValidate() formRef.value?.clearValidate()
...@@ -97,29 +191,32 @@ const close = () => { ...@@ -97,29 +191,32 @@ const close = () => {
emit('fetch-data') emit('fetch-data')
} }
const fetchData = async () => { const cancel = () => {
const { data } = await getList() close()
list.value = data.list dialogFormVisible.value = false
} }
const save = () => { const save = () => {
formRef.value?.validate(async (valid: any) => { formRef.value?.validate(async (valid: any) => {
if (valid) { if (valid) {
const tree = treeRef.value.getCheckedKeys() if (form.value.roleId) {
const treeObject = { 'treeArray:': tree } form.value.menuIds = getMenuAllCheckedKeys()
const { msg }: any = await doEdit({ await doEdit(form.value)
...form, await $baseMessage('修改成功', 'success', 'hey')
...treeObject, } else {
}) form.value.menuIds = getMenuAllCheckedKeys()
await $baseMessage(msg, 'success', 'hey') await doAdd(form.value)
await close() await $baseMessage('添加成功', 'success', 'hey')
dialogFormVisible.value = false }
cancel()
} }
}) })
} }
onBeforeMount(() => { onBeforeMount(() => {})
fetchData()
defineExpose({
showEdit,
}) })
</script> </script>
......
...@@ -97,7 +97,7 @@ ...@@ -97,7 +97,7 @@
</el-row> </el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button type="primary" @click="save">确定</el-button> <el-button type="primary" @click="save"> </el-button>
<el-button @click="cancel">取 消</el-button> <el-button @click="cancel">取 消</el-button>
</template> </template>
</vab-dialog> </vab-dialog>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论