Browse Source

feat: 细粒度权限控制

main
刘凯 1 year ago
parent
commit
2b61c11088
  1. 1
      src/store/modules/user.ts
  2. 3
      src/views/base/login/LoginForm.vue
  3. 7
      src/views/device-manage/device/components/DeviceInfo.vue
  4. 5
      src/views/device-manage/device/components/composables/useDeviceInfo.ts
  5. 5
      src/views/device-manage/device/detail.vue
  6. 9
      src/views/device-manage/device/index.vue
  7. 13
      src/views/product/components/Model.vue
  8. 8
      src/views/product/components/TopicManage.vue
  9. 1
      src/views/product/components/composables/useModelAttribute.ts
  10. 9
      src/views/product/detail.vue
  11. 9
      src/views/product/index.vue
  12. 1
      src/views/subscription/consumer/components/Product.vue
  13. 9
      src/views/subscription/consumer/detail.vue
  14. 8
      src/views/subscription/consumer/index.vue
  15. 8
      src/views/subscription/list/index.vue
  16. 8
      src/views/system/dept/index.vue
  17. 40
      src/views/system/menu/index.vue
  18. 9
      src/views/system/role/index.vue
  19. 9
      src/views/system/tenant/index.vue
  20. 8
      src/views/system/user/index.vue

1
src/store/modules/user.ts

@ -142,6 +142,7 @@ export const useUserStore = defineStore('app-user', {
const userInfo = await getUserInfo()
setTenantId(userInfo.user.tenantId)
usePermissionStore().changePermissionCode(userInfo.buttons)
this.setUserInfo(userInfo)
return userInfo
},

3
src/views/base/login/LoginForm.vue

@ -6,7 +6,6 @@ import { LoginStateEnum, useFormRules, useFormValid, useLoginState } from './use
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { useUserStore } from '@/store/modules/user'
import { usePermissionStore } from '@/store/modules/permission'
import { useDesign } from '@/hooks/web/useDesign'
const FormItem = Form.Item
@ -16,7 +15,6 @@ const { t } = useI18n()
const { notification, createErrorModal } = useMessage()
const { prefixCls } = useDesign('login')
const userStore = useUserStore()
const permissionStore = usePermissionStore()
const { setLoginState, getLoginState } = useLoginState()
const { getFormRules } = useFormRules()
@ -44,7 +42,6 @@ async function handleLogin() {
mode: 'none', //
})
if (userInfo) {
permissionStore.changePermissionCode(userInfo.buttons)
notification.success({
message: t('sys.login.loginSuccessTitle'),
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.user.realName}`,

7
src/views/device-manage/device/components/DeviceInfo.vue

@ -5,6 +5,7 @@ import { useDeviceInfo } from './composables/useDeviceInfo'
import { useDeviceProperties } from './composables/useDeviceProperties'
import { Description } from '@/components/Description'
import { useModelService } from '@/views/product/components/composables/useModelService'
import { usePermission } from '@/hooks/web/usePermission'
const { data, scheam } = useDeviceInfo()
@ -19,13 +20,15 @@ const {
deviceProperties,
reloadReviceProperties,
} = useDeviceProperties(() => selectedModelId.value, () => data.value?.deviceSn)
const { hasPermission } = usePermission()
</script>
<template>
<div>
<Description :schema="scheam" :data="data" :column="2" :label-style="{ width: '130px' }" />
<Card mt="15px">
<Card v-if="hasPermission('device_report_view')" mt="15px">
<div flex="~ items-center justify-between">
<div font-bold>
最新上报数据
@ -87,7 +90,7 @@ const {
"{{ item.unit || 'null' }}"
</div>
<div text="right gray-500 hover:gray-800">
<span class="cursor-pointer">
<span v-if="hasPermission('product_report_history')" class="cursor-pointer">
<FieldTimeOutlined />
历史
</span>

5
src/views/device-manage/device/components/composables/useDeviceInfo.ts

@ -5,8 +5,11 @@ import { useRoute } from 'vue-router'
import { useAsyncState } from '@vueuse/core'
import type { DescItem } from '@/components/Description'
import { getDeviceDetail } from '@/api/device-manage/device'
import { usePermission } from '@/hooks/web/usePermission'
export function useDeviceInfo() {
const { hasPermission } = usePermission()
const scheam: DescItem[] = [
{
field: 'productName',
@ -57,6 +60,7 @@ export function useDeviceInfo() {
{
field: 'mqtt',
label: 'MQTT连接参数',
show: () => hasPermission('device_mqtt_params'),
render: () => h(Button, {
size: 'small',
onClick: openMqttParamsModal,
@ -65,6 +69,7 @@ export function useDeviceInfo() {
{
field: 'report',
label: '上报示例',
show: () => hasPermission('device_report_example'),
render: () => h(Button, {
size: 'small',
onClick: openReportExampleModal,

5
src/views/device-manage/device/detail.vue

@ -1,8 +1,11 @@
<script lang='ts' setup>
import { Card, Tabs } from 'ant-design-vue'
import { DeviceInfo, TopicList } from './components'
import { usePermission } from '@/hooks/web/usePermission'
defineOptions({ name: 'DeviceDetail' })
const { hasPermission } = usePermission()
</script>
<template>
@ -12,7 +15,7 @@ defineOptions({ name: 'DeviceDetail' })
<Tabs.TabPane key="1" tab="设备信息">
<DeviceInfo />
</Tabs.TabPane>
<Tabs.TabPane key="2" tab="已订阅 Topic">
<Tabs.TabPane v-if="hasPermission('device_topic_view')" key="2" tab="已订阅 Topic">
<TopicList />
</Tabs.TabPane>
<Tabs.TabPane key="3" tab="云端下发">

9
src/views/device-manage/device/index.vue

@ -7,11 +7,14 @@ import { BasicTable, TableAction, useTable } from '@/components/Table'
import { deleteDevice, getDeviceList } from '@/api/device-manage/device'
import type { Device } from '@/api/device-manage/device/types'
import { useMessage } from '@/hooks/web/useMessage'
import { usePermission } from '@/hooks/web/usePermission'
defineOptions({ name: 'Device' })
const [registerModal, { openModal }] = useModal<Device>()
const { hasPermission } = usePermission()
const [register, { reload }] = useTable({
api: getDeviceList,
columns,
@ -27,6 +30,7 @@ const [register, { reload }] = useTable({
title: '操作',
dataIndex: 'action',
fixed: 'right',
auth: ['view', 'edit', 'delete'].map(code => `device_${code}`),
},
})
@ -43,7 +47,7 @@ async function handleDelete(id: string) {
<template>
<div>
<BasicTable :api="async () => ([] as Device[])" @register="register">
<template #tableTitle>
<template v-if="hasPermission('device_add')" #tableTitle>
<a-button type="primary" @click="openModal(true)">
<PlusOutlined />
新建
@ -57,17 +61,20 @@ async function handleDelete(id: string) {
{
icon: 'i-ant-design:file-search-outlined',
label: '详情',
auth: 'device_view',
onClick: () => $router.push(`/device-manage/device/detail/${record.id}`),
},
{
icon: 'i-ant-design:edit-outlined',
label: '编辑',
auth: 'device_edit',
onClick: () => openModal(true, record),
},
{
icon: 'i-ant-design:delete-outlined',
danger: true,
label: '删除',
auth: 'device_delete',
popConfirm: {
title: '是否要删除数据?',
placement: 'left',

13
src/views/product/components/Model.vue

@ -9,6 +9,7 @@ import ModelAttributeFormModal from './ModelAttributeFormModal.vue'
import { BasicTable, TableAction } from '@/components/Table'
import type { ModelAttribute } from '@/api/product/types'
import JsonPreviewModal from '@/components/JsonPreviewModal'
import { usePermission } from '@/hooks/web/usePermission'
defineProps<{ tsl?: string }>()
@ -30,6 +31,8 @@ const {
reloadModalAttribute,
handleDeleteModelAttribute,
} = useModelAttribute(route.params.id as string, selectedModelId)
const { hasPermission } = usePermission()
</script>
<template>
@ -50,7 +53,7 @@ const {
<div font-bold>
服务列表
</div>
<div class="i-ant-design:plus-outlined cursor-pointer text-20px" @click="openModelServiceModal()" />
<div v-if="hasPermission('product_model_service_add')" class="i-ant-design:plus-outlined cursor-pointer text-20px" @click="openModelServiceModal()" />
</div>
<div
@ -70,10 +73,10 @@ const {
</div>
</div>
<div v-if="item.serviceId !== 'DEFAULT'">
<a-button type="link" size="small" @click="openModelServiceModal(true, item)">
<a-button v-if="hasPermission('product_model_service_edit')" type="link" size="small" @click="openModelServiceModal(true, item)">
<span class="i-ant-design:edit-outlined" />
</a-button>
<Popconfirm title="是否要删除数据?" @confirm="handleDeleteModelService(item.id)">
<Popconfirm v-if="hasPermission('product_model_service_delete')" title="是否要删除数据?" @confirm="handleDeleteModelService(item.id)">
<a-button type="link" size="small" danger>
<span class="i-ant-design:delete-outlined" />
</a-button>
@ -84,7 +87,7 @@ const {
<div w-0 flex-1>
<BasicTable :api="async () => ([] as ModelAttribute[])" @register="registerModelAttributeTable">
<template #tableTitle>
<template v-if="hasPermission('product_model_attr_add')" #tableTitle>
<a-button type="primary" @click="openModelAttributeModal">
<PlusOutlined />
新增属性
@ -107,12 +110,14 @@ const {
{
icon: 'i-ant-design:edit-outlined',
label: '编辑',
auth: 'product_model_attr_edit',
onClick: () => openModelAttributeModal(true, record),
},
{
icon: 'i-ant-design:delete-outlined',
danger: true,
label: '删除',
auth: 'product_model_attr_delete',
popConfirm: {
title: '是否要删除数据?',
placement: 'left',

8
src/views/product/components/TopicManage.vue

@ -11,6 +11,7 @@ import { deleteTopic, getTopicList } from '@/api/product/topic'
import { useSystemEnumStore } from '@/store/modules/systemEnum'
import { useModal } from '@/components/Modal'
import { useMessage } from '@/hooks/web/useMessage'
import { usePermission } from '@/hooks/web/usePermission'
const route = useRoute()
const { getSystemEnumLabel } = useSystemEnumStore()
@ -25,6 +26,8 @@ const alertMessage = computed(
: '以下是系统Topic,设备侧通过系统预设的topic接收数据时,无需提前订阅。',
)
const { hasPermission } = usePermission()
const [register, { reload, setTableData }] = useTable({
api(params) {
return getTopicList({
@ -62,6 +65,7 @@ const [register, { reload, setTableData }] = useTable({
dataIndex: 'action',
fixed: 'right',
ifShow: () => isCustomTopic.value,
auth: ['product_topic_edit', 'product_topic_delete'],
},
})
watch(topicType, () => {
@ -88,7 +92,7 @@ async function handleDelete(id: string) {
:options="[{ label: '系统 Topic', value: TopicType.System }, { label: '自定义 Topic', value: TopicType.Custom }]"
/>
<a-button v-if="isCustomTopic" type="primary" @click="openModal">
<a-button v-if="isCustomTopic && hasPermission('product_topic_add')" type="primary" @click="openModal">
<PlusOutlined />
新增 Topic
</a-button>
@ -114,12 +118,14 @@ async function handleDelete(id: string) {
{
icon: 'i-ant-design:edit-outlined',
label: '编辑',
auth: 'product_topic_edit',
onClick: () => openModal(true, record),
},
{
icon: 'i-ant-design:delete-outlined',
danger: true,
label: '删除',
auth: 'product_topic_delete',
popConfirm: {
title: '是否要删除数据?',
placement: 'left',

1
src/views/product/components/composables/useModelAttribute.ts

@ -45,6 +45,7 @@ export function useModelAttribute(productId: MaybeRef<string>, modelId: Ref<stri
title: '操作',
dataIndex: 'action',
fixed: 'right',
auth: ['product_model_attr_delete', 'product_model_attr_edit'],
},
})
watch(modelId, () => {

9
src/views/product/detail.vue

@ -7,6 +7,7 @@ import { Description } from '@/components/Description'
import { getProductDetail } from '@/api/product'
import type { DescItem } from '@/components/Description'
import { useSystemEnumStore } from '@/store/modules/systemEnum'
import { usePermission } from '@/hooks/web/usePermission'
const route = useRoute()
const { getSystemEnumLabel } = useSystemEnumStore()
@ -64,6 +65,8 @@ const schema: DescItem[] = [
field: 'productDesc',
},
]
const { hasPermission } = usePermission()
</script>
<template>
@ -74,13 +77,13 @@ const schema: DescItem[] = [
<Card mt="12px">
<Tabs>
<Tabs.TabPane key="1" tab="Topic 管理">
<Tabs.TabPane v-if="hasPermission('product_topic_view')" key="1" tab="Topic 管理">
<TopicManage />
</Tabs.TabPane>
<Tabs.TabPane key="2" tab="物模型">
<Tabs.TabPane v-if="hasPermission('product_model_view')" key="2" tab="物模型">
<Model :tsl="state?.tsl" />
</Tabs.TabPane>
<Tabs.TabPane key="3" tab="服务端订阅">
<Tabs.TabPane v-if="hasPermission('product_subscription_view')" key="3" tab="服务端订阅">
<Subscription :data="state?.subscribe" />
</Tabs.TabPane>
</Tabs>

9
src/views/product/index.vue

@ -7,11 +7,14 @@ import { deleteProduct, getProductList } from '@/api/product'
import { useModal } from '@/components/Modal'
import type { Product } from '@/api/product/types'
import { useMessage } from '@/hooks/web/useMessage'
import { usePermission } from '@/hooks/web/usePermission'
defineOptions({ name: 'Product' })
const [registerModal, { openModal }] = useModal<Product>()
const { hasPermission } = usePermission()
const [register, { reload }] = useTable({
api: getProductList,
columns,
@ -27,6 +30,7 @@ const [register, { reload }] = useTable({
title: '操作',
dataIndex: 'action',
fixed: 'right',
auth: ['view', 'edit', 'delete'].map(code => `product_${code}`),
},
})
@ -43,7 +47,7 @@ async function handleDelete(id: string) {
<template>
<div>
<BasicTable :api="async () => ([] as Product[])" @register="register">
<template #tableTitle>
<template v-if="hasPermission('product_add')" #tableTitle>
<a-button type="primary" @click="openModal">
<PlusOutlined />
新建
@ -57,17 +61,20 @@ async function handleDelete(id: string) {
{
icon: 'i-ant-design:file-search-outlined',
label: '详情',
auth: 'product_view',
onClick: () => $router.push(`/product/detail/${record.id}`),
},
{
icon: 'i-ant-design:edit-outlined',
label: '编辑',
auth: 'product_edit',
onClick: () => openModal(true, record),
},
{
icon: 'i-ant-design:delete-outlined',
danger: true,
label: '删除',
auth: 'product_delete',
popConfirm: {
title: '是否要删除数据?',
placement: 'left',

1
src/views/subscription/consumer/components/Product.vue

@ -52,6 +52,7 @@ const [register, { reload }] = useTable({
title: '操作',
dataIndex: 'action',
fixed: 'right',
auth: ['consumer_disconnect'],
},
})

9
src/views/subscription/consumer/detail.vue

@ -9,6 +9,7 @@ import { getConsumerDetail } from '@/api/subscription/consumer'
import type { DescItem } from '@/components/Description'
import { Description } from '@/components/Description'
import { copyText } from '@/utils/copyTextToClipboard'
import { usePermission } from '@/hooks/web/usePermission'
const route = useRoute()
const { state } = useAsyncState(() => getConsumerDetail(route.params.id as string), undefined)
@ -74,6 +75,8 @@ const schema: DescItem[] = [
label: '创建时间',
},
]
const { hasPermission } = usePermission()
</script>
<template>
@ -82,12 +85,12 @@ const schema: DescItem[] = [
<Description :data="state" :schema="schema" :column="1" :label-style="{ width: '140px' }" />
</Card>
<Card mt="12px">
<Card v-if="hasPermission(['consumer_client_view', 'consumer_product_view'])" mt="12px">
<Tabs>
<Tabs.TabPane key="1" tab="在线客户端">
<Tabs.TabPane v-if="hasPermission('consumer_client_view')" key="1" tab="在线客户端">
<OnlineClient v-if="state" :consumer-token="state.consumerToken" />
</Tabs.TabPane>
<Tabs.TabPane key="2" tab="订阅产品">
<Tabs.TabPane v-if="hasPermission('consumer_product_view')" key="2" tab="订阅产品">
<Product v-if="state" :consumer-id="state.id" />
</Tabs.TabPane>
</Tabs>

8
src/views/subscription/consumer/index.vue

@ -7,11 +7,14 @@ import { deleteConsumer, getConsumerList } from '@/api/subscription/consumer'
import { useModal } from '@/components/Modal'
import type { Consumer } from '@/api/subscription/consumer/types'
import { useMessage } from '@/hooks/web/useMessage'
import { usePermission } from '@/hooks/web/usePermission'
defineOptions({ name: 'Consumer' })
const [registerModal, { openModal }] = useModal<string>()
const { hasPermission } = usePermission()
const [register, { reload }] = useTable({
api: getConsumerList,
columns,
@ -44,7 +47,7 @@ async function handleDelete(id: string) {
<template>
<div>
<BasicTable :api="async () => ([] as Consumer[])" @register="register">
<template #tableTitle>
<template v-if="hasPermission('consumer_add')" #tableTitle>
<a-button type="primary" @click="openModal()">
<PlusOutlined />
创建
@ -58,17 +61,20 @@ async function handleDelete(id: string) {
{
icon: 'i-ant-design:file-search-outlined',
label: '详情',
auth: 'consumer_view',
onClick: () => $router.push(`/subscription/consumer/detail/${record.id}`),
},
{
icon: 'i-ant-design:edit-outlined',
label: '修改',
auth: 'consumer_edit',
onClick: () => openModal(true, record.id),
},
{
icon: 'i-ant-design:delete-outlined',
danger: true,
label: '删除',
auth: 'consumer_delete',
popConfirm: {
title: '确定要删除数据吗?',
placement: 'left',

8
src/views/subscription/list/index.vue

@ -7,11 +7,14 @@ import { deleteSubscription, getSubscriptionList } from '@/api/subscription/list
import { useModal } from '@/components/Modal'
import type { SubScription } from '@/api/subscription/list/types'
import { useMessage } from '@/hooks/web/useMessage'
import { usePermission } from '@/hooks/web/usePermission'
defineOptions({ name: 'Subscription' })
const [registerModal, { openModal }] = useModal<SubScription>()
const { hasPermission } = usePermission()
const [register, { reload }] = useTable({
api: getSubscriptionList,
columns,
@ -28,6 +31,7 @@ const [register, { reload }] = useTable({
title: '操作',
dataIndex: 'action',
fixed: 'right',
auth: ['subscribe_edit', 'subscribe_delete'],
},
})
@ -44,7 +48,7 @@ async function handleDelete(id: string) {
<template>
<div>
<BasicTable :api="async () => ([] as SubScription[])" @register="register">
<template #tableTitle>
<template v-if="hasPermission('subscribe_add')" #tableTitle>
<a-button type="primary" @click="openModal()">
<PlusOutlined />
创建
@ -58,12 +62,14 @@ async function handleDelete(id: string) {
{
icon: 'i-ant-design:edit-outlined',
label: '修改',
auth: 'subscribe_edit',
onClick: () => openModal(true, record),
},
{
icon: 'i-ant-design:delete-outlined',
danger: true,
label: '删除',
auth: 'subscribe_delete',
popConfirm: {
title: '确定要删除数据吗?',
placement: 'left',

8
src/views/system/dept/index.vue

@ -9,6 +9,7 @@ import { IconEnum } from '@/enums/appEnum'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { deleteDept, lazyGetDeptList } from '@/api/system/dept'
import type { Department } from '@/api/system/dept/types'
import { usePermission } from '@/hooks/web/usePermission'
defineOptions({ name: 'SystemDept' })
@ -16,6 +17,8 @@ const { t } = useI18n()
const [registerModal, { openModal }] = useModal<Department>()
const { hasPermission } = usePermission()
const [register, { reload }] = useTable({
async api(params) {
const list = await lazyGetDeptList(params)
@ -48,6 +51,7 @@ const [register, { reload }] = useTable({
title: t('common.action'),
dataIndex: 'action',
fixed: 'right',
auth: ['dept_delete', 'dept_edit'],
},
})
@ -64,7 +68,7 @@ async function handleDelete(id: string) {
<template>
<div>
<BasicTable :api="async () => ([] as Department[])" @register="register">
<template #tableTitle>
<template v-if="hasPermission('dept_add')" #tableTitle>
<a-button type="primary" @click="openModal">
<PlusOutlined />
{{ t('action.create') }}
@ -78,12 +82,14 @@ async function handleDelete(id: string) {
{
icon: IconEnum.EDIT,
label: t('action.edit'),
auth: 'dept_edit',
onClick: () => openModal(true, record),
},
{
icon: IconEnum.DELETE,
danger: true,
label: t('action.delete'),
auth: 'dept_delete',
popConfirm: {
title: t('common.delMessage'),
placement: 'left',

40
src/views/system/menu/index.vue

@ -1,5 +1,4 @@
<script lang="ts" setup>
import { Space } from 'ant-design-vue'
import { PlusOutlined } from '@ant-design/icons-vue'
import MenuFormModal from './MenuFormModal.vue'
import { columns, searchFormSchema } from './data'
@ -14,6 +13,8 @@ defineOptions({ name: 'SystemMenu' })
const [registerModal, { openModal }] = useModal<MenuItem>()
const { hasPermission } = usePermission()
const [register, { reload }] = useTable<MenuItem>({
columns,
api: getMenuList,
@ -33,10 +34,11 @@ const [register, { reload }] = useTable<MenuItem>({
title: '操作',
dataIndex: 'action',
fixed: 'right',
auth: ['menu_edit', 'menu_delete'],
},
})
const { createMessage, createConfirm } = useMessage()
const { createMessage } = useMessage()
async function handleDelete(id: string) {
try {
await deleteMenu(id)
@ -45,38 +47,16 @@ async function handleDelete(id: string) {
}
catch {}
}
function refreshMenu() {
createConfirm({
title: '刷新菜单',
iconType: 'warning',
content: '即将更新缓存刷新浏览器',
async onOk() {
const { refreshMenu } = usePermission()
await refreshMenu()
createMessage.success('刷新成功')
location.reload()
},
})
}
</script>
<template>
<div>
<BasicTable :api="async () => ([] as MenuItem[])" @register="register">
<template #tableTitle>
<Space>
<a-button type="primary" @click="openModal">
<PlusOutlined />
新增
</a-button>
<a-button type="primary" danger @click="refreshMenu">
<template #icon>
<span class="i-ant-design:sync-outlined align-text-top" />
</template>
缓存刷新
</a-button>
</Space>
<template v-if="hasPermission('menu_add')" #tableTitle>
<a-button type="primary" @click="openModal">
<PlusOutlined />
新增
</a-button>
</template>
<template #bodyCell="{ column, record }">
@ -86,12 +66,14 @@ function refreshMenu() {
{
icon: 'i-ant-design:edit-outlined',
label: '修改',
auth: 'menu_edit',
onClick: () => openModal(true, record),
},
{
icon: 'i-ant-design:delete-outlined',
label: '删除',
danger: true,
auth: 'menu_delete',
popConfirm: {
title: '确定要删除数据吗?',
placement: 'left',

9
src/views/system/role/index.vue

@ -8,6 +8,7 @@ import { useModal } from '@/components/Modal'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { deleteRole, lazyGetRoleList } from '@/api/system/role'
import type { Role } from '@/api/system/role/types'
import { usePermission } from '@/hooks/web/usePermission'
defineOptions({ name: 'SystemRole' })
@ -15,6 +16,8 @@ const { createMessage } = useMessage()
const [registerFormModal, { openModal: openFormModal }] = useModal<Role>()
const [registerMenuModal, { openModal: openMenuModal }] = useModal<string>()
const { hasPermission } = usePermission()
const [registerTable, { reload }] = useTable({
async api(params) {
try {
@ -51,6 +54,7 @@ const [registerTable, { reload }] = useTable({
title: '操作',
dataIndex: 'action',
fixed: 'right',
auth: ['edit', 'menu', 'delete'].map(code => `role_${code}`),
},
})
@ -67,7 +71,7 @@ async function handleDelete(id: string) {
<template>
<div>
<BasicTable :api="async () => ([] as Role[])" @register="registerTable">
<template #tableTitle>
<template v-if="hasPermission('role_add')" #tableTitle>
<a-button type="primary" @click="openFormModal">
<PlusOutlined />
新建
@ -81,17 +85,20 @@ async function handleDelete(id: string) {
{
icon: 'i-ant-design:edit-outlined',
label: '编辑',
auth: 'role_edit',
onClick: () => openFormModal(true, record),
},
{
icon: 'i-ant-design:appstore-outlined',
label: '菜单权限',
auth: 'role_menu',
onClick: () => openMenuModal(true, record.id),
},
{
icon: 'i-ant-design:delete-outlined',
label: '删除',
danger: true,
auth: 'role_delete',
popConfirm: {
title: '确定要删除数据吗?',
placement: 'left',

9
src/views/system/tenant/index.vue

@ -7,10 +7,14 @@ import { deleteTenant, getTenantList } from '@/api/system/tenant'
import type { Tenant } from '@/api/system/tenant/types'
import { useModal } from '@/components/Modal'
import { useMessage } from '@/hooks/web/useMessage'
import { usePermission } from '@/hooks/web/usePermission'
defineOptions({ name: 'SystemTenant' })
const [registerModal, { openModal }] = useModal<Tenant>()
const { hasPermission } = usePermission()
const [registerTable, { reload }] = useTable({
api: getTenantList,
columns,
@ -27,6 +31,7 @@ const [registerTable, { reload }] = useTable({
title: '操作',
dataIndex: 'action',
fixed: 'right',
auth: ['tenant_delete', 'tenant_edit'],
},
})
@ -43,7 +48,7 @@ async function handleDelete(id: string) {
<template>
<div>
<BasicTable :api="async () => ([] as Tenant[])" @register="registerTable">
<template #tableTitle>
<template v-if="hasPermission('tenant_add')" #tableTitle>
<a-button type="primary" @click="openModal">
<PlusOutlined />
新建
@ -57,12 +62,14 @@ async function handleDelete(id: string) {
{
icon: 'i-ant-design:edit-outlined',
label: '编辑',
auth: 'tenant_edit',
onClick: () => openModal(true, record),
},
{
icon: 'i-ant-design:delete-outlined',
label: '删除',
danger: true,
auth: 'tenant_delete',
popConfirm: {
title: '确定要删除数据吗?',
placement: 'left',

8
src/views/system/user/index.vue

@ -8,6 +8,7 @@ import { useModal } from '@/components/Modal'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { deleteUser, getUserList } from '@/api/system/user'
import type { SystemUser } from '@/api/system/user/types'
import { usePermission } from '@/hooks/web/usePermission'
defineOptions({ name: 'SystemUser' })
@ -15,6 +16,8 @@ const { t } = useI18n()
const { createMessage } = useMessage()
const [registerModal, { openModal }] = useModal<SystemUser>()
const { hasPermission } = usePermission()
const [registerTable, { reload }] = useTable({
api(params) {
return getUserList(params)
@ -33,6 +36,7 @@ const [registerTable, { reload }] = useTable({
title: t('common.action'),
dataIndex: 'action',
fixed: 'right',
auth: ['user_edit', 'user_delete'],
},
})
@ -49,7 +53,7 @@ async function handleDelete(id: string) {
<template>
<div>
<BasicTable :api="async () => ([] as SystemUser[])" @register="registerTable">
<template #tableTitle>
<template v-if="hasPermission('user_add')" #tableTitle>
<a-button type="primary" @click="openModal">
<PlusOutlined />
{{ t('action.create') }}
@ -64,11 +68,13 @@ async function handleDelete(id: string) {
icon: 'i-ant-design:edit-outlined',
label: t('action.edit'),
onClick: () => openModal(true, record),
auth: 'user_edit',
},
{
icon: 'i-ant-design:delete-outlined',
danger: true,
label: t('action.delete'),
auth: 'user_delete',
popConfirm: {
title: t('common.delMessage'),
placement: 'left',

Loading…
Cancel
Save