Commit 7250e23df37b40749bce454da1ac614312bd28ed

Authored by xingyu4j
1 parent bdc988e5

refactor: oauth2 vxe

yudao-ui-admin-vue3/src/api/system/oauth2/client.ts
1 import request from '@/config/axios' 1 import request from '@/config/axios'
2 -import { OAuth2ClientVo } from './client.types' 2 +export interface OAuth2ClientVO {
  3 + id: number
  4 + clientId: string
  5 + secret: string
  6 + name: string
  7 + logo: string
  8 + description: string
  9 + status: number
  10 + accessTokenValiditySeconds: number
  11 + refreshTokenValiditySeconds: number
  12 + redirectUris: string[]
  13 + autoApprove: boolean
  14 + authorizedGrantTypes: string[]
  15 + scopes: string[]
  16 + authorities: string[]
  17 + resourceIds: string[]
  18 + additionalInformation: string
  19 + isAdditionalInformationJson: boolean
  20 + createTime: string
  21 +}
3 22
4 // 查询 OAuth2列表 23 // 查询 OAuth2列表
5 export const getOAuth2ClientPageApi = (params) => { 24 export const getOAuth2ClientPageApi = (params) => {
@@ -12,12 +31,12 @@ export const getOAuth2ClientApi = (id: number) => { @@ -12,12 +31,12 @@ export const getOAuth2ClientApi = (id: number) => {
12 } 31 }
13 32
14 // 新增 OAuth2 33 // 新增 OAuth2
15 -export const createOAuth2ClientApi = (data: OAuth2ClientVo) => { 34 +export const createOAuth2ClientApi = (data: OAuth2ClientVO) => {
16 return request.post({ url: '/system/oauth2-client/create', data }) 35 return request.post({ url: '/system/oauth2-client/create', data })
17 } 36 }
18 37
19 // 修改 OAuth2 38 // 修改 OAuth2
20 -export const updateOAuth2ClientApi = (data: OAuth2ClientVo) => { 39 +export const updateOAuth2ClientApi = (data: OAuth2ClientVO) => {
21 return request.put({ url: '/system/oauth2-client/update', data }) 40 return request.put({ url: '/system/oauth2-client/update', data })
22 } 41 }
23 42
yudao-ui-admin-vue3/src/api/system/oauth2/client.types.ts deleted
1 -export type OAuth2ClientVo = {  
2 - id: number  
3 - clientId: string  
4 - secret: string  
5 - name: string  
6 - logo: string  
7 - description: string  
8 - status: number  
9 - accessTokenValiditySeconds: number  
10 - refreshTokenValiditySeconds: number  
11 - redirectUris: string[]  
12 - autoApprove: boolean  
13 - authorizedGrantTypes: string[]  
14 - scopes: string[]  
15 - authorities: string[]  
16 - resourceIds: string[]  
17 - additionalInformation: string  
18 - isAdditionalInformationJson: boolean  
19 - createTime: string  
20 -}  
yudao-ui-admin-vue3/src/api/system/oauth2/token.ts
1 import request from '@/config/axios' 1 import request from '@/config/axios'
2 2
  3 +export interface OAuth2TokenVO {
  4 + id: number
  5 + accessToken: string
  6 + refreshToken: string
  7 + userId: number
  8 + userType: number
  9 + clientId: string
  10 + createTime: string
  11 + expiresTime: string
  12 +}
  13 +
  14 +export interface OAuth2TokenPageReqVO extends BasePage {
  15 + code?: string
  16 + name?: string
  17 + status?: number
  18 +}
  19 +
3 // 查询 token列表 20 // 查询 token列表
4 -export const getAccessTokenPageApi = (params) => { 21 +export const getAccessTokenPageApi = (params: OAuth2TokenPageReqVO) => {
5 return request.get({ url: '/system/oauth2-token/page', params }) 22 return request.get({ url: '/system/oauth2-token/page', params })
6 } 23 }
7 24
yudao-ui-admin-vue3/src/api/system/oauth2/token.types.ts deleted
1 -export type OAuth2TokenVo = {  
2 - id: number  
3 - accessToken: string  
4 - refreshToken: string  
5 - userId: number  
6 - userType: number  
7 - clientId: string  
8 - createTime: string  
9 - expiresTime: string  
10 -}  
yudao-ui-admin-vue3/src/hooks/web/useVxeGrid.ts
@@ -45,13 +45,13 @@ export const useVxeGrid = <T = any>(config?: UseVxeGridConfig<T>) => { @@ -45,13 +45,13 @@ export const useVxeGrid = <T = any>(config?: UseVxeGridConfig<T>) => {
45 isHover: true // 当鼠标移到行时,是否要高亮当前行 45 isHover: true // 当鼠标移到行时,是否要高亮当前行
46 }, 46 },
47 toolbarConfig: { 47 toolbarConfig: {
48 - custom: true,  
49 slots: { buttons: 'toolbar_buttons' } 48 slots: { buttons: 'toolbar_buttons' }
50 }, 49 },
51 printConfig: { 50 printConfig: {
52 columns: config?.allSchemas.printSchema 51 columns: config?.allSchemas.printSchema
53 }, 52 },
54 formConfig: { 53 formConfig: {
  54 + enabled: true,
55 titleWidth: 100, 55 titleWidth: 100,
56 titleAlign: 'right', 56 titleAlign: 'right',
57 items: config?.allSchemas.searchSchema 57 items: config?.allSchemas.searchSchema
@@ -120,6 +120,7 @@ export const useVxeGrid = <T = any>(config?: UseVxeGridConfig<T>) => { @@ -120,6 +120,7 @@ export const useVxeGrid = <T = any>(config?: UseVxeGridConfig<T>) => {
120 }) 120 })
121 }) 121 })
122 } 122 }
  123 +
123 return { 124 return {
124 gridOptions, 125 gridOptions,
125 delList 126 delList
yudao-ui-admin-vue3/src/views/system/oauth2/client/client.data.ts
1 import { reactive } from 'vue' 1 import { reactive } from 'vue'
2 import { useI18n } from '@/hooks/web/useI18n' 2 import { useI18n } from '@/hooks/web/useI18n'
3 import { required } from '@/utils/formRules' 3 import { required } from '@/utils/formRules'
4 -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'  
5 import { DICT_TYPE } from '@/utils/dict' 4 import { DICT_TYPE } from '@/utils/dict'
6 -const { t } = useI18n()  
7 -// 国际化 5 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
  6 +const { t } = useI18n() // 国际化
8 7
9 // 表单校验 8 // 表单校验
10 export const rules = reactive({ 9 export const rules = reactive({
@@ -20,122 +19,92 @@ export const rules = reactive({ @@ -20,122 +19,92 @@ export const rules = reactive({
20 }) 19 })
21 20
22 // CrudSchema 21 // CrudSchema
23 -const crudSchemas = reactive<CrudSchema[]>([  
24 - {  
25 - label: '客户端编号',  
26 - field: 'clientId',  
27 - form: {  
28 - show: false 22 +const crudSchemas = reactive<VxeCrudSchema>({
  23 + primaryKey: 'clientId',
  24 + primaryType: 'seq',
  25 + action: true,
  26 + columns: [
  27 + {
  28 + title: '客户端密钥',
  29 + field: 'secret'
29 }, 30 },
30 - detail: {  
31 - show: false  
32 - }  
33 - },  
34 - {  
35 - label: '客户端密钥',  
36 - field: 'secret'  
37 - },  
38 - {  
39 - label: '应用名',  
40 - field: 'name',  
41 - search: {  
42 - show: true  
43 - }  
44 - },  
45 - {  
46 - label: '应用图标',  
47 - field: 'logo'  
48 - },  
49 - {  
50 - label: t('common.status'),  
51 - field: 'status',  
52 - dictType: DICT_TYPE.COMMON_STATUS,  
53 - search: {  
54 - show: true  
55 - }  
56 - },  
57 - {  
58 - label: '访问令牌的有效期',  
59 - field: 'accessTokenValiditySeconds'  
60 - },  
61 - {  
62 - label: '刷新令牌的有效期',  
63 - field: 'refreshTokenValiditySeconds'  
64 - },  
65 - {  
66 - label: '授权类型',  
67 - field: 'authorizedGrantTypes',  
68 - dictType: DICT_TYPE.SYSTEM_OAUTH2_GRANT_TYPE  
69 - },  
70 - {  
71 - label: '授权范围',  
72 - field: 'scopes',  
73 - table: {  
74 - show: false  
75 - }  
76 - },  
77 - {  
78 - label: '自动授权范围',  
79 - field: 'autoApproveScopes',  
80 - table: {  
81 - show: false  
82 - }  
83 - },  
84 - {  
85 - label: '可重定向的 URI 地址',  
86 - field: 'redirectUris',  
87 - table: {  
88 - show: false  
89 - }  
90 - },  
91 - {  
92 - label: '权限',  
93 - field: 'authorities',  
94 - table: {  
95 - show: false  
96 - }  
97 - },  
98 - {  
99 - label: '资源',  
100 - field: 'resourceIds',  
101 - table: {  
102 - show: false  
103 - }  
104 - },  
105 - {  
106 - label: '附加信息',  
107 - field: 'additionalInformation',  
108 - table: {  
109 - show: false 31 + {
  32 + title: '应用名',
  33 + field: 'name',
  34 + isSearch: true
  35 + },
  36 + {
  37 + title: '应用图标',
  38 + field: 'logo'
  39 + },
  40 + {
  41 + title: t('common.status'),
  42 + field: 'status',
  43 + dictType: DICT_TYPE.COMMON_STATUS,
  44 + isSearch: true
  45 + },
  46 + {
  47 + title: '访问令牌的有效期',
  48 + field: 'accessTokenValiditySeconds'
110 }, 49 },
111 - form: {  
112 - component: 'Input',  
113 - componentProps: {  
114 - type: 'textarea',  
115 - rows: 4  
116 - },  
117 - colProps: {  
118 - span: 24 50 + {
  51 + title: '刷新令牌的有效期',
  52 + field: 'refreshTokenValiditySeconds'
  53 + },
  54 + {
  55 + title: '授权类型',
  56 + field: 'authorizedGrantTypes',
  57 + dictType: DICT_TYPE.SYSTEM_OAUTH2_GRANT_TYPE,
  58 + form: {
  59 + component: 'Select'
119 } 60 }
120 - }  
121 - },  
122 - {  
123 - label: t('common.createTime'),  
124 - field: 'createTime',  
125 - form: {  
126 - show: false  
127 - }  
128 - },  
129 - {  
130 - label: t('table.action'),  
131 - field: 'action',  
132 - width: '240px',  
133 - form: {  
134 - show: false  
135 }, 61 },
136 - detail: {  
137 - show: false 62 + {
  63 + title: '授权范围',
  64 + field: 'scopes',
  65 + isTable: false
  66 + },
  67 + {
  68 + title: '自动授权范围',
  69 + field: 'autoApproveScopes',
  70 + isTable: false
  71 + },
  72 + {
  73 + title: '可重定向的 URI 地址',
  74 + field: 'redirectUris',
  75 + isTable: false
  76 + },
  77 + {
  78 + title: '权限',
  79 + field: 'authorities',
  80 + isTable: false
  81 + },
  82 + {
  83 + title: '资源',
  84 + field: 'resourceIds',
  85 + isTable: false
  86 + },
  87 + {
  88 + title: '附加信息',
  89 + field: 'additionalInformation',
  90 + isTable: false,
  91 + form: {
  92 + component: 'Input',
  93 + componentProps: {
  94 + type: 'textarea',
  95 + rows: 4
  96 + },
  97 + colProps: {
  98 + span: 24
  99 + }
  100 + }
  101 + },
  102 + {
  103 + title: t('common.createTime'),
  104 + field: 'createTime',
  105 + formatter: 'formatDate',
  106 + isForm: false
138 } 107 }
139 - }  
140 -])  
141 -export const { allSchemas } = useCrudSchemas(crudSchemas) 108 + ]
  109 +})
  110 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
yudao-ui-admin-vue3/src/views/system/oauth2/client/index.vue
  1 +<template>
  2 + <ContentWrap>
  3 + <!-- 列表 -->
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <!-- 操作:新增 -->
  6 + <template #toolbar_buttons>
  7 + <XButton
  8 + type="primary"
  9 + preIcon="ep:zoom-in"
  10 + :title="t('action.add')"
  11 + v-hasPermi="['system:oauth2-client:create']"
  12 + @click="handleCreate()"
  13 + />
  14 + </template>
  15 + <template #authorizedGrantTypes="{ row }">
  16 + <el-tag
  17 + :disable-transitions="true"
  18 + :key="index"
  19 + v-for="(authorizedGrantType, index) in row.authorizedGrantTypes"
  20 + :index="index"
  21 + >
  22 + {{ authorizedGrantType }}
  23 + </el-tag>
  24 + </template>
  25 + <template #actionbtns_default="{ row }">
  26 + <!-- 操作:修改 -->
  27 + <XTextButton
  28 + preIcon="ep:edit"
  29 + :title="t('action.edit')"
  30 + v-hasPermi="['system:oauth2-client:update']"
  31 + @click="handleUpdate(row.id)"
  32 + />
  33 + <!-- 操作:详情 -->
  34 + <XTextButton
  35 + preIcon="ep:view"
  36 + :title="t('action.detail')"
  37 + v-hasPermi="['system:oauth2-client:update']"
  38 + @click="handleDetail(row.id)"
  39 + />
  40 + <!-- 操作:删除 -->
  41 + <XTextButton
  42 + preIcon="ep:delete"
  43 + :title="t('action.del')"
  44 + v-hasPermi="['system:oauth2-client:delete']"
  45 + @click="handleDelete(row.id)"
  46 + />
  47 + </template>
  48 + </vxe-grid>
  49 + </ContentWrap>
  50 + <!-- 弹窗 -->
  51 + <XModal id="postModel" v-model="dialogVisible" :title="dialogTitle">
  52 + <template #default>
  53 + <!-- 表单:添加/修改 -->
  54 + <Form
  55 + ref="formRef"
  56 + v-if="['create', 'update'].includes(actionType)"
  57 + :schema="allSchemas.formSchema"
  58 + :rules="rules"
  59 + />
  60 + <!-- 表单:详情 -->
  61 + <Descriptions
  62 + v-if="actionType === 'detail'"
  63 + :schema="allSchemas.detailSchema"
  64 + :data="detailRef"
  65 + />
  66 + </template>
  67 + <template #footer>
  68 + <!-- 按钮:保存 -->
  69 + <XButton
  70 + v-if="['create', 'update'].includes(actionType)"
  71 + type="primary"
  72 + :title="t('action.save')"
  73 + :loading="actionLoading"
  74 + @click="submitForm"
  75 + />
  76 + <!-- 按钮:关闭 -->
  77 + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
  78 + </template>
  79 + </XModal>
  80 +</template>
1 <script setup lang="ts"> 81 <script setup lang="ts">
  82 +// 全局相关的 import
2 import { ref, unref } from 'vue' 83 import { ref, unref } from 'vue'
3 -import dayjs from 'dayjs'  
4 -import { ElMessage, ElImage, ElTag } from 'element-plus'  
5 -import { DICT_TYPE } from '@/utils/dict'  
6 -import { useTable } from '@/hooks/web/useTable' 84 +import { ElTag } from 'element-plus'
7 import { useI18n } from '@/hooks/web/useI18n' 85 import { useI18n } from '@/hooks/web/useI18n'
  86 +import { useMessage } from '@/hooks/web/useMessage'
  87 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  88 +import { VxeGridInstance } from 'vxe-table'
8 import { FormExpose } from '@/components/Form' 89 import { FormExpose } from '@/components/Form'
9 -import type { OAuth2ClientVo } from '@/api/system/oauth2/client.types'  
10 -import { rules, allSchemas } from './client.data' 90 +// 业务相关的 import
11 import * as ClientApi from '@/api/system/oauth2/client' 91 import * as ClientApi from '@/api/system/oauth2/client'
  92 +import { rules, allSchemas } from './client.data'
  93 +
12 const { t } = useI18n() // 国际化 94 const { t } = useI18n() // 国际化
  95 +const message = useMessage() // 消息弹窗
13 96
14 -// ========== 列表相关 ==========  
15 -const { register, tableObject, methods } = useTable<OAuth2ClientVo>({  
16 - getListApi: ClientApi.getOAuth2ClientPageApi,  
17 - delListApi: ClientApi.deleteOAuth2ClientApi 97 +// 列表相关的变量
  98 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  99 +const { gridOptions } = useVxeGrid<ClientApi.OAuth2ClientVO>({
  100 + allSchemas: allSchemas,
  101 + getListApi: ClientApi.getOAuth2ClientPageApi
18 }) 102 })
19 -const { getList, setSearchParams, delList } = methods  
20 -  
21 -// ========== CRUD 相关 ==========  
22 -const actionLoading = ref(false) // 遮罩层  
23 -const actionType = ref('') // 操作按钮的类型 103 +// 弹窗相关的变量
24 const dialogVisible = ref(false) // 是否显示弹出层 104 const dialogVisible = ref(false) // 是否显示弹出层
25 const dialogTitle = ref('edit') // 弹出层标题 105 const dialogTitle = ref('edit') // 弹出层标题
  106 +const actionType = ref('') // 操作按钮的类型
  107 +const actionLoading = ref(false) // 按钮 Loading
26 const formRef = ref<FormExpose>() // 表单 Ref 108 const formRef = ref<FormExpose>() // 表单 Ref
  109 +const detailRef = ref() // 详情 Ref
27 110
28 // 设置标题 111 // 设置标题
29 const setDialogTile = (type: string) => { 112 const setDialogTile = (type: string) => {
@@ -40,14 +123,35 @@ const handleCreate = () =&gt; { @@ -40,14 +123,35 @@ const handleCreate = () =&gt; {
40 } 123 }
41 124
42 // 修改操作 125 // 修改操作
43 -const handleUpdate = async (row: OAuth2ClientVo) => { 126 +const handleUpdate = async (rowId: number) => {
44 setDialogTile('update') 127 setDialogTile('update')
45 // 设置数据 128 // 设置数据
46 - const res = await ClientApi.getOAuth2ClientApi(row.id) 129 + const res = await ClientApi.getOAuth2ClientApi(rowId)
47 unref(formRef)?.setValues(res) 130 unref(formRef)?.setValues(res)
48 } 131 }
49 132
50 -// 提交按钮 133 +// 详情操作
  134 +const handleDetail = async (rowId: number) => {
  135 + setDialogTile('detail')
  136 + const res = await ClientApi.getOAuth2ClientApi(rowId)
  137 + detailRef.value = res
  138 +}
  139 +
  140 +// 删除操作
  141 +const handleDelete = async (rowId: number) => {
  142 + message
  143 + .delConfirm()
  144 + .then(async () => {
  145 + await ClientApi.deleteOAuth2ClientApi(rowId)
  146 + message.success(t('common.delSuccess'))
  147 + })
  148 + .finally(() => {
  149 + // 刷新列表
  150 + xGrid.value?.commitProxy('query')
  151 + })
  152 +}
  153 +
  154 +// 提交新增/修改的表单
51 const submitForm = async () => { 155 const submitForm = async () => {
52 const elForm = unref(formRef)?.getElFormRef() 156 const elForm = unref(formRef)?.getElFormRef()
53 if (!elForm) return 157 if (!elForm) return
@@ -56,143 +160,21 @@ const submitForm = async () =&gt; { @@ -56,143 +160,21 @@ const submitForm = async () =&gt; {
56 actionLoading.value = true 160 actionLoading.value = true
57 // 提交请求 161 // 提交请求
58 try { 162 try {
59 - const data = unref(formRef)?.formModel as OAuth2ClientVo 163 + const data = unref(formRef)?.formModel as ClientApi.OAuth2ClientVO
60 if (actionType.value === 'create') { 164 if (actionType.value === 'create') {
61 await ClientApi.createOAuth2ClientApi(data) 165 await ClientApi.createOAuth2ClientApi(data)
62 - ElMessage.success(t('common.createSuccess')) 166 + message.success(t('common.createSuccess'))
63 } else { 167 } else {
64 await ClientApi.updateOAuth2ClientApi(data) 168 await ClientApi.updateOAuth2ClientApi(data)
65 - ElMessage.success(t('common.updateSuccess')) 169 + message.success(t('common.updateSuccess'))
66 } 170 }
67 - // 操作成功,重新加载列表  
68 dialogVisible.value = false 171 dialogVisible.value = false
69 - await getList()  
70 } finally { 172 } finally {
71 actionLoading.value = false 173 actionLoading.value = false
  174 + // 刷新列表
  175 + xGrid.value?.commitProxy('query')
72 } 176 }
73 } 177 }
74 }) 178 })
75 } 179 }
76 -  
77 -// ========== 详情相关 ==========  
78 -const detailRef = ref() // 详情 Ref  
79 -  
80 -// 详情操作  
81 -const handleDetail = async (row: OAuth2ClientVo) => {  
82 - // 设置数据  
83 - detailRef.value = row  
84 - setDialogTile('detail')  
85 -}  
86 -  
87 -// ========== 初始化 ==========  
88 -getList()  
89 </script> 180 </script>
90 -  
91 -<template>  
92 - <!-- 搜索工作区 -->  
93 - <ContentWrap>  
94 - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />  
95 - </ContentWrap>  
96 - <ContentWrap>  
97 - <!-- 操作工具栏 -->  
98 - <div class="mb-10px">  
99 - <el-button type="primary" v-hasPermi="['system:oauth2-client:create']" @click="handleCreate">  
100 - <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}  
101 - </el-button>  
102 - </div>  
103 - <!-- 列表 -->  
104 - <Table  
105 - :columns="allSchemas.tableColumns"  
106 - :selection="false"  
107 - :data="tableObject.tableList"  
108 - :loading="tableObject.loading"  
109 - :pagination="{  
110 - total: tableObject.total  
111 - }"  
112 - v-model:pageSize="tableObject.pageSize"  
113 - v-model:currentPage="tableObject.currentPage"  
114 - @register="register"  
115 - >  
116 - <template #logo="{ row }">  
117 - <el-image :src="row.logo" :preview-src-list="[row.logo]" />  
118 - </template>  
119 - <template #status="{ row }">  
120 - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />  
121 - </template>  
122 - <template #authorizedGrantTypes="{ row }">  
123 - <el-tag  
124 - :disable-transitions="true"  
125 - :key="index"  
126 - v-for="(authorizedGrantType, index) in row.authorizedGrantTypes"  
127 - :index="index"  
128 - >  
129 - {{ authorizedGrantType }}  
130 - </el-tag>  
131 - </template>  
132 - <template #createTime="{ row }">  
133 - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>  
134 - </template>  
135 - <template #action="{ row }">  
136 - <el-button  
137 - link  
138 - type="primary"  
139 - v-hasPermi="['system:oauth2-client:update']"  
140 - @click="handleUpdate(row)"  
141 - >  
142 - <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}  
143 - </el-button>  
144 - <el-button  
145 - link  
146 - type="primary"  
147 - v-hasPermi="['system:oauth2-client:update']"  
148 - @click="handleDetail(row)"  
149 - >  
150 - <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}  
151 - </el-button>  
152 - <el-button  
153 - link  
154 - type="primary"  
155 - v-hasPermi="['system:oauth2-client:delete']"  
156 - @click="delList(row.id, false)"  
157 - >  
158 - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}  
159 - </el-button>  
160 - </template>  
161 - </Table>  
162 - </ContentWrap>  
163 -  
164 - <Dialog v-model="dialogVisible" :title="dialogTitle" width="60%" maxHeight="420px">  
165 - <!-- 对话框(添加 / 修改) -->  
166 - <Form  
167 - v-if="['create', 'update'].includes(actionType)"  
168 - :schema="allSchemas.formSchema"  
169 - :rules="rules"  
170 - ref="formRef"  
171 - />  
172 - <!-- 对话框(详情) -->  
173 - <Descriptions  
174 - v-if="actionType === 'detail'"  
175 - :schema="allSchemas.detailSchema"  
176 - :data="detailRef"  
177 - >  
178 - <template #status="{ row }">  
179 - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />  
180 - </template>  
181 - <template #createTime="{ row }">  
182 - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>  
183 - </template>  
184 - </Descriptions>  
185 - <!-- 操作按钮 -->  
186 - <template #footer>  
187 - <el-button  
188 - v-if="['create', 'update'].includes(actionType)"  
189 - type="primary"  
190 - :loading="actionLoading"  
191 - @click="submitForm"  
192 - >  
193 - {{ t('action.save') }}  
194 - </el-button>  
195 - <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>  
196 - </template>  
197 - </Dialog>  
198 -</template>  
yudao-ui-admin-vue3/src/views/system/oauth2/token/index.vue
  1 +<template>
  2 + <ContentWrap>
  3 + <!-- 列表 -->
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <template #actionbtns_default="{ row }">
  6 + <!-- 操作:详情 -->
  7 + <XTextButton preIcon="ep:view" :title="t('action.detail')" @click="handleDetail(row)" />
  8 + <!-- 操作:删除 -->
  9 + <XTextButton
  10 + preIcon="ep:delete"
  11 + :title="t('action.logout')"
  12 + v-hasPermi="['system:oauth2-token:delete']"
  13 + @click="handleForceLogout(row.id)"
  14 + />
  15 + </template>
  16 + </vxe-grid>
  17 + </ContentWrap>
  18 + <Dialog v-model="dialogVisible" :title="dialogTitle">
  19 + <!-- 对话框(详情) -->
  20 + <Descriptions :schema="allSchemas.detailSchema" :data="detailRef" />
  21 + <!-- 操作按钮 -->
  22 + <template #footer>
  23 + <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
  24 + </template>
  25 + </Dialog>
  26 +</template>
  27 +
1 <script setup lang="ts"> 28 <script setup lang="ts">
2 -import dayjs from 'dayjs'  
3 -import { useTable } from '@/hooks/web/useTable'  
4 -import { allSchemas } from './token.data'  
5 -import { DICT_TYPE } from '@/utils/dict' 29 +import { ref } from 'vue'
6 import { useI18n } from '@/hooks/web/useI18n' 30 import { useI18n } from '@/hooks/web/useI18n'
7 -import type { OAuth2TokenVo } from '@/api/system/oauth2/token.types' 31 +import { useMessage } from '@/hooks/web/useMessage'
  32 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  33 +import { VxeGridInstance } from 'vxe-table'
  34 +
  35 +import { allSchemas } from './token.data'
8 import * as TokenApi from '@/api/system/oauth2/token' 36 import * as TokenApi from '@/api/system/oauth2/token'
9 -import { ref } from 'vue' 37 +
10 const { t } = useI18n() // 国际化 38 const { t } = useI18n() // 国际化
11 -// ========== 列表相关 ==========  
12 -const { register, tableObject, methods } = useTable<OAuth2TokenVo>({  
13 - getListApi: TokenApi.getAccessTokenPageApi,  
14 - delListApi: TokenApi.deleteAccessTokenApi 39 +const message = useMessage() // 消息弹窗
  40 +// 列表相关的变量
  41 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  42 +const { gridOptions } = useVxeGrid<TokenApi.OAuth2TokenVO>({
  43 + allSchemas: allSchemas,
  44 + getListApi: TokenApi.getAccessTokenPageApi
15 }) 45 })
16 // ========== 详情相关 ========== 46 // ========== 详情相关 ==========
17 const detailRef = ref() // 详情 Ref 47 const detailRef = ref() // 详情 Ref
18 const dialogVisible = ref(false) // 是否显示弹出层 48 const dialogVisible = ref(false) // 是否显示弹出层
19 const dialogTitle = ref(t('action.detail')) // 弹出层标题 49 const dialogTitle = ref(t('action.detail')) // 弹出层标题
20 -const { getList, setSearchParams, delList } = methods  
21 // 详情 50 // 详情
22 -const handleDetail = (row: OAuth2TokenVo) => { 51 +const handleDetail = async (row: TokenApi.OAuth2TokenVO) => {
23 // 设置数据 52 // 设置数据
24 detailRef.value = row 53 detailRef.value = row
25 dialogVisible.value = true 54 dialogVisible.value = true
26 } 55 }
27 // 强退操作 56 // 强退操作
28 -const handleForceLogout = (row: OAuth2TokenVo) => {  
29 - delList(row.id, false) 57 +const handleForceLogout = (rowId: number) => {
  58 + message
  59 + .delConfirm()
  60 + .then(async () => {
  61 + await TokenApi.deleteAccessTokenApi(rowId)
  62 + message.success(t('common.delSuccess'))
  63 + })
  64 + .finally(() => {
  65 + // 刷新列表
  66 + xGrid.value?.commitProxy('query')
  67 + })
30 } 68 }
31 -getList()  
32 </script> 69 </script>
33 -<template>  
34 - <ContentWrap>  
35 - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />  
36 - </ContentWrap>  
37 - <ContentWrap>  
38 - <Table  
39 - :columns="allSchemas.tableColumns"  
40 - :selection="false"  
41 - :data="tableObject.tableList"  
42 - :loading="tableObject.loading"  
43 - :pagination="{  
44 - total: tableObject.total  
45 - }"  
46 - v-model:pageSize="tableObject.pageSize"  
47 - v-model:currentPage="tableObject.currentPage"  
48 - @register="register"  
49 - >  
50 - <template #userType="{ row }">  
51 - <DictTag :type="DICT_TYPE.USER_TYPE" :value="row.userType" />  
52 - </template>  
53 - <template #createTime="{ row }">  
54 - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>  
55 - </template>  
56 - <template #expiresTime="{ row }">  
57 - <span>{{ dayjs(row.expiresTime).format('YYYY-MM-DD HH:mm:ss') }}</span>  
58 - </template>  
59 - <template #action="{ row }">  
60 - <el-button link type="primary" @click="handleDetail(row)">  
61 - <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}  
62 - </el-button>  
63 - <el-button  
64 - link  
65 - type="primary"  
66 - v-hasPermi="['system:oauth2-token:delete']"  
67 - @click="handleForceLogout(row)"  
68 - >  
69 - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.logout') }}  
70 - </el-button>  
71 - </template>  
72 - </Table>  
73 - </ContentWrap>  
74 - <Dialog v-model="dialogVisible" :title="dialogTitle">  
75 - <!-- 对话框(详情) -->  
76 - <Descriptions :schema="allSchemas.detailSchema" :data="detailRef">  
77 - <template #userType="{ row }">  
78 - <DictTag :type="DICT_TYPE.USER_TYPE" :value="row.userType" />  
79 - </template>  
80 - <template #createTime="{ row }">  
81 - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>  
82 - </template>  
83 - <template #expiresTime="{ row }">  
84 - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>  
85 - </template>  
86 - </Descriptions>  
87 - <!-- 操作按钮 -->  
88 - <template #footer>  
89 - <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>  
90 - </template>  
91 - </Dialog>  
92 -</template>  
yudao-ui-admin-vue3/src/views/system/oauth2/token/token.data.ts
1 import { reactive } from 'vue' 1 import { reactive } from 'vue'
2 import { useI18n } from '@/hooks/web/useI18n' 2 import { useI18n } from '@/hooks/web/useI18n'
3 -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'  
4 import { DICT_TYPE } from '@/utils/dict' 3 import { DICT_TYPE } from '@/utils/dict'
  4 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
5 const { t } = useI18n() // 国际化 5 const { t } = useI18n() // 国际化
6 // CrudSchema 6 // CrudSchema
7 -const crudSchemas = reactive<CrudSchema[]>([  
8 - {  
9 - label: t('common.index'),  
10 - field: 'id',  
11 - type: 'index',  
12 - form: {  
13 - show: false 7 +const crudSchemas = reactive<VxeCrudSchema>({
  8 + primaryKey: 'id',
  9 + primaryType: 'seq',
  10 + action: true,
  11 + columns: [
  12 + {
  13 + title: '用户编号',
  14 + field: 'userId',
  15 + isSearch: true
14 }, 16 },
15 - detail: {  
16 - show: false  
17 - }  
18 - },  
19 - {  
20 - label: '用户编号',  
21 - field: 'userId',  
22 - search: {  
23 - show: true  
24 - }  
25 - },  
26 - {  
27 - label: '访问令牌',  
28 - field: 'accessToken'  
29 - },  
30 - {  
31 - label: '刷新令牌',  
32 - field: 'refreshToken'  
33 - },  
34 - {  
35 - label: '用户类型',  
36 - field: 'userType',  
37 - dictType: DICT_TYPE.USER_TYPE,  
38 - search: {  
39 - show: true  
40 - }  
41 - },  
42 - {  
43 - label: t('common.createTime'),  
44 - field: 'createTime',  
45 - form: {  
46 - show: false  
47 - }  
48 - },  
49 - {  
50 - label: '过期时间',  
51 - field: 'expiresTime',  
52 - form: {  
53 - show: false  
54 - }  
55 - },  
56 - {  
57 - label: t('table.action'),  
58 - field: 'action',  
59 - width: '200px',  
60 - form: {  
61 - show: false 17 + {
  18 + title: '访问令牌',
  19 + field: 'accessToken'
  20 + },
  21 + {
  22 + title: '刷新令牌',
  23 + field: 'refreshToken'
  24 + },
  25 + {
  26 + title: '用户类型',
  27 + field: 'userType',
  28 + dictType: DICT_TYPE.USER_TYPE,
  29 + isSearch: true
  30 + },
  31 + {
  32 + title: t('common.createTime'),
  33 + field: 'createTime',
  34 + formatter: 'formatDate',
  35 + isForm: false
62 }, 36 },
63 - detail: {  
64 - show: false 37 + {
  38 + title: '过期时间',
  39 + field: 'expiresTime',
  40 + formatter: 'formatDate',
  41 + isForm: false
65 } 42 }
66 - }  
67 -])  
68 -export const { allSchemas } = useCrudSchemas(crudSchemas) 43 + ]
  44 +})
  45 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)