Commit b6c7d8685cb9ce98e96eb887d96659cae3a9dd86
1 parent
abb94eae
perf: refresh token && delete console
Showing
10 changed files
with
100 additions
and
63 deletions
yudao-ui-admin-vue3/src/api/system/user/profile/index.ts
| @@ -24,6 +24,6 @@ export const updateUserPwdApi = (oldPassword: string, newPassword: string) => { | @@ -24,6 +24,6 @@ export const updateUserPwdApi = (oldPassword: string, newPassword: string) => { | ||
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | // 用户头像上传 | 26 | // 用户头像上传 |
| 27 | -export const uploadAvatarApi = (params) => { | ||
| 28 | - return request.upload({ url: '/system/user/profile/update-avatar', params }) | 27 | +export const uploadAvatarApi = (data) => { |
| 28 | + return request.upload({ url: '/system/user/profile/update-avatar', data: data }) | ||
| 29 | } | 29 | } |
yudao-ui-admin-vue3/src/components/Verifition/src/Verify.vue
| @@ -102,7 +102,6 @@ export default { | @@ -102,7 +102,6 @@ export default { | ||
| 102 | * @description 刷新 | 102 | * @description 刷新 |
| 103 | * */ | 103 | * */ |
| 104 | const refresh = () => { | 104 | const refresh = () => { |
| 105 | - console.log(instance.value) | ||
| 106 | if (instance.value.refresh) { | 105 | if (instance.value.refresh) { |
| 107 | instance.value.refresh() | 106 | instance.value.refresh() |
| 108 | } | 107 | } |
| @@ -271,7 +270,6 @@ export default { | @@ -271,7 +270,6 @@ export default { | ||
| 271 | -moz-box-sizing: content-box; | 270 | -moz-box-sizing: content-box; |
| 272 | box-sizing: content-box; | 271 | box-sizing: content-box; |
| 273 | border: 1px solid #ddd; | 272 | border: 1px solid #ddd; |
| 274 | - -webkit-border-radius: 4px; | ||
| 275 | } | 273 | } |
| 276 | 274 | ||
| 277 | .verify-bar-area .verify-move-block { | 275 | .verify-bar-area .verify-move-block { |
| @@ -284,7 +282,6 @@ export default { | @@ -284,7 +282,6 @@ export default { | ||
| 284 | -moz-box-sizing: content-box; | 282 | -moz-box-sizing: content-box; |
| 285 | box-sizing: content-box; | 283 | box-sizing: content-box; |
| 286 | box-shadow: 0 0 2px #888888; | 284 | box-shadow: 0 0 2px #888888; |
| 287 | - -webkit-border-radius: 1px; | ||
| 288 | } | 285 | } |
| 289 | 286 | ||
| 290 | .verify-bar-area .verify-move-block:hover { | 287 | .verify-bar-area .verify-move-block:hover { |
yudao-ui-admin-vue3/src/components/Verifition/src/Verify/VerifySlide.vue
| @@ -242,7 +242,6 @@ export default { | @@ -242,7 +242,6 @@ export default { | ||
| 242 | //兼容移动端 | 242 | //兼容移动端 |
| 243 | var x = e.touches[0].pageX | 243 | var x = e.touches[0].pageX |
| 244 | } | 244 | } |
| 245 | - console.log(barArea) | ||
| 246 | startLeft.value = Math.floor(x - barArea.value.getBoundingClientRect().left) | 245 | startLeft.value = Math.floor(x - barArea.value.getBoundingClientRect().left) |
| 247 | startMoveTime.value = +new Date() //开始滑动的时间 | 246 | startMoveTime.value = +new Date() //开始滑动的时间 |
| 248 | if (isEnd.value == false) { | 247 | if (isEnd.value == false) { |
yudao-ui-admin-vue3/src/config/axios/index.ts
| 1 | import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios' | 1 | import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios' |
| 2 | -import { ElMessage, ElNotification } from 'element-plus' | 2 | +import { ElMessage, ElMessageBox, ElNotification } from 'element-plus' |
| 3 | import qs from 'qs' | 3 | import qs from 'qs' |
| 4 | import { config } from '@/config/axios/config' | 4 | import { config } from '@/config/axios/config' |
| 5 | -import { getAccessToken, getTenantId, removeToken } from '@/utils/auth' | 5 | +import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth' |
| 6 | import errorCode from './errorCode' | 6 | import errorCode from './errorCode' |
| 7 | import { useI18n } from '@/hooks/web/useI18n' | 7 | import { useI18n } from '@/hooks/web/useI18n' |
| 8 | +import { resetRouter } from '@/router' | ||
| 8 | 9 | ||
| 9 | const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE | 10 | const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE |
| 10 | const BASE_URL = import.meta.env.VITE_BASE_URL | 11 | const BASE_URL = import.meta.env.VITE_BASE_URL |
| @@ -20,9 +21,9 @@ const ignoreMsgs = [ | @@ -20,9 +21,9 @@ const ignoreMsgs = [ | ||
| 20 | export const isRelogin = { show: false } | 21 | export const isRelogin = { show: false } |
| 21 | // Axios 无感知刷新令牌,参考 https://www.dashingdog.cn/article/11 与 https://segmentfault.com/a/1190000020210980 实现 | 22 | // Axios 无感知刷新令牌,参考 https://www.dashingdog.cn/article/11 与 https://segmentfault.com/a/1190000020210980 实现 |
| 22 | // 请求队列 | 23 | // 请求队列 |
| 23 | -// const requestList = [] | 24 | +let requestList: any[] = [] |
| 24 | // 是否正在刷新中 | 25 | // 是否正在刷新中 |
| 25 | -// const isRefreshToken = false | 26 | +let isRefreshToken = false |
| 26 | 27 | ||
| 27 | export const PATH_URL = base_url[import.meta.env.VITE_API_BASEPATH] | 28 | export const PATH_URL = base_url[import.meta.env.VITE_API_BASEPATH] |
| 28 | 29 | ||
| @@ -91,6 +92,7 @@ service.interceptors.request.use( | @@ -91,6 +92,7 @@ service.interceptors.request.use( | ||
| 91 | service.interceptors.response.use( | 92 | service.interceptors.response.use( |
| 92 | async (response: AxiosResponse<Recordable>) => { | 93 | async (response: AxiosResponse<Recordable>) => { |
| 93 | const { data } = response | 94 | const { data } = response |
| 95 | + console.info(data) | ||
| 94 | if (!data) { | 96 | if (!data) { |
| 95 | // 返回“[HTTP]请求没有返回值”; | 97 | // 返回“[HTTP]请求没有返回值”; |
| 96 | throw new Error() | 98 | throw new Error() |
| @@ -112,16 +114,38 @@ service.interceptors.response.use( | @@ -112,16 +114,38 @@ service.interceptors.response.use( | ||
| 112 | return Promise.reject(msg) | 114 | return Promise.reject(msg) |
| 113 | } else if (code === 401) { | 115 | } else if (code === 401) { |
| 114 | // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了 | 116 | // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了 |
| 115 | - return handleAuthorized() | ||
| 116 | - // if (!isRefreshToken) { | ||
| 117 | - // isRefreshToken = true | ||
| 118 | - // // 1. 如果获取不到刷新令牌,则只能执行登出操作 | ||
| 119 | - // if (!getRefreshToken()) { | ||
| 120 | - // return handleAuthorized() | ||
| 121 | - // } | ||
| 122 | - // // 2. 进行刷新访问令牌 | ||
| 123 | - // // TODO: 引入refreshToken会循环依赖报错 | ||
| 124 | - // } | 117 | + if (!isRefreshToken) { |
| 118 | + isRefreshToken = true | ||
| 119 | + // 1. 如果获取不到刷新令牌,则只能执行登出操作 | ||
| 120 | + if (!getRefreshToken()) { | ||
| 121 | + return handleAuthorized() | ||
| 122 | + } | ||
| 123 | + // 2. 进行刷新访问令牌 | ||
| 124 | + try { | ||
| 125 | + const refreshTokenRes = await refreshToken() | ||
| 126 | + // 2.1 刷新成功,则回放队列的请求 + 当前请求 | ||
| 127 | + setToken(refreshTokenRes.data) | ||
| 128 | + requestList.forEach((cb: any) => cb()) | ||
| 129 | + return service(response.config) | ||
| 130 | + } catch (e) { | ||
| 131 | + // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。 | ||
| 132 | + // 2.2 刷新失败,只回放队列的请求 | ||
| 133 | + requestList.forEach((cb: any) => cb()) | ||
| 134 | + // 提示是否要登出。即不回放当前请求!不然会形成递归 | ||
| 135 | + return handleAuthorized() | ||
| 136 | + } finally { | ||
| 137 | + requestList = [] | ||
| 138 | + isRefreshToken = false | ||
| 139 | + } | ||
| 140 | + } else { | ||
| 141 | + // 添加到队列,等待刷新获取到新的令牌 | ||
| 142 | + return new Promise((resolve) => { | ||
| 143 | + requestList.push(() => { | ||
| 144 | + ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改 | ||
| 145 | + resolve(service(response.config)) | ||
| 146 | + }) | ||
| 147 | + }) | ||
| 148 | + } | ||
| 125 | } else if (code === 500) { | 149 | } else if (code === 500) { |
| 126 | ElMessage.error(t('sys.api.errMsg500')) | 150 | ElMessage.error(t('sys.api.errMsg500')) |
| 127 | return Promise.reject(new Error(msg)) | 151 | return Promise.reject(new Error(msg)) |
| @@ -165,14 +189,32 @@ service.interceptors.response.use( | @@ -165,14 +189,32 @@ service.interceptors.response.use( | ||
| 165 | return Promise.reject(error) | 189 | return Promise.reject(error) |
| 166 | } | 190 | } |
| 167 | ) | 191 | ) |
| 192 | + | ||
| 193 | +const refreshToken = async () => { | ||
| 194 | + return await service({ | ||
| 195 | + url: '/system/auth/refresh-token?refreshToken=' + getRefreshToken(), | ||
| 196 | + method: 'post' | ||
| 197 | + }) | ||
| 198 | +} | ||
| 168 | const handleAuthorized = () => { | 199 | const handleAuthorized = () => { |
| 169 | const { t } = useI18n() | 200 | const { t } = useI18n() |
| 170 | if (!isRelogin.show) { | 201 | if (!isRelogin.show) { |
| 171 | - removeToken() | ||
| 172 | isRelogin.show = true | 202 | isRelogin.show = true |
| 173 | - ElNotification.error(t('sys.api.timeoutMessage')) | 203 | + ElMessageBox.confirm(t('sys.api.timeoutMessage'), t('common.confirmTitle'), { |
| 204 | + confirmButtonText: t('login.relogin'), | ||
| 205 | + cancelButtonText: t('common.cancel'), | ||
| 206 | + type: 'warning' | ||
| 207 | + }) | ||
| 208 | + .then(() => { | ||
| 209 | + removeToken() | ||
| 210 | + resetRouter() // 重置静态路由表 | ||
| 211 | + isRelogin.show = false | ||
| 212 | + location.href = '/' | ||
| 213 | + }) | ||
| 214 | + .catch(() => { | ||
| 215 | + isRelogin.show = false | ||
| 216 | + }) | ||
| 174 | } | 217 | } |
| 175 | - location.href = '/' | ||
| 176 | return Promise.reject(t('sys.api.timeoutMessage')) | 218 | return Promise.reject(t('sys.api.timeoutMessage')) |
| 177 | } | 219 | } |
| 178 | export { service } | 220 | export { service } |
yudao-ui-admin-vue3/src/router/index.ts
| @@ -10,6 +10,7 @@ import { createRouter, createWebHashHistory } from 'vue-router' | @@ -10,6 +10,7 @@ import { createRouter, createWebHashHistory } from 'vue-router' | ||
| 10 | import { usePermissionStoreWithOut } from '@/store/modules/permission' | 10 | import { usePermissionStoreWithOut } from '@/store/modules/permission' |
| 11 | import { useDictStoreWithOut } from '@/store/modules/dict' | 11 | import { useDictStoreWithOut } from '@/store/modules/dict' |
| 12 | import { listSimpleDictDataApi } from '@/api/system/dict/dict.data' | 12 | import { listSimpleDictDataApi } from '@/api/system/dict/dict.data' |
| 13 | +import { isRelogin } from '@/config/axios' | ||
| 13 | 14 | ||
| 14 | const permissionStore = usePermissionStoreWithOut() | 15 | const permissionStore = usePermissionStoreWithOut() |
| 15 | 16 | ||
| @@ -48,14 +49,14 @@ router.beforeEach(async (to, from, next) => { | @@ -48,14 +49,14 @@ router.beforeEach(async (to, from, next) => { | ||
| 48 | next({ path: '/' }) | 49 | next({ path: '/' }) |
| 49 | } else { | 50 | } else { |
| 50 | if (!dictStore.getIsSetDict) { | 51 | if (!dictStore.getIsSetDict) { |
| 52 | + isRelogin.show = true | ||
| 51 | // 获取所有字典 | 53 | // 获取所有字典 |
| 52 | const res = await listSimpleDictDataApi() | 54 | const res = await listSimpleDictDataApi() |
| 53 | - if (res) { | ||
| 54 | - dictStore.setDictMap(res) | ||
| 55 | - dictStore.setIsSetDict(true) | ||
| 56 | - } | 55 | + dictStore.setDictMap(res) |
| 56 | + dictStore.setIsSetDict(true) | ||
| 57 | } | 57 | } |
| 58 | if (permissionStore.getIsAddRouters) { | 58 | if (permissionStore.getIsAddRouters) { |
| 59 | + isRelogin.show = false | ||
| 59 | next() | 60 | next() |
| 60 | return | 61 | return |
| 61 | } | 62 | } |
| @@ -77,7 +78,7 @@ router.beforeEach(async (to, from, next) => { | @@ -77,7 +78,7 @@ router.beforeEach(async (to, from, next) => { | ||
| 77 | if (whiteList.indexOf(to.path) !== -1) { | 78 | if (whiteList.indexOf(to.path) !== -1) { |
| 78 | next() | 79 | next() |
| 79 | } else { | 80 | } else { |
| 80 | - next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页 | 81 | + next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 |
| 81 | } | 82 | } |
| 82 | } | 83 | } |
| 83 | }) | 84 | }) |
yudao-ui-admin-vue3/src/views/Profile/components/UserAvatar.vue
| @@ -6,12 +6,12 @@ import { ElRow, ElCol, ElUpload, ElMessage, ElDialog } from 'element-plus' | @@ -6,12 +6,12 @@ import { ElRow, ElCol, ElUpload, ElMessage, ElDialog } from 'element-plus' | ||
| 6 | import { propTypes } from '@/utils/propTypes' | 6 | import { propTypes } from '@/utils/propTypes' |
| 7 | import { uploadAvatarApi } from '@/api/system/user/profile' | 7 | import { uploadAvatarApi } from '@/api/system/user/profile' |
| 8 | const cropper = ref() | 8 | const cropper = ref() |
| 9 | +const dialogVisible = ref(false) | ||
| 10 | +const cropperVisible = ref(false) | ||
| 9 | const props = defineProps({ | 11 | const props = defineProps({ |
| 10 | img: propTypes.string.def('') | 12 | img: propTypes.string.def('') |
| 11 | }) | 13 | }) |
| 12 | -const state = reactive({ | ||
| 13 | - dialogVisible: false, | ||
| 14 | - cropperVisible: false, | 14 | +const options = reactive({ |
| 15 | dialogTitle: '编辑头像', | 15 | dialogTitle: '编辑头像', |
| 16 | options: { | 16 | options: { |
| 17 | img: props.img, //裁剪图片的地址 | 17 | img: props.img, //裁剪图片的地址 |
| @@ -27,8 +27,11 @@ const state = reactive({ | @@ -27,8 +27,11 @@ const state = reactive({ | ||
| 27 | }) | 27 | }) |
| 28 | /** 编辑头像 */ | 28 | /** 编辑头像 */ |
| 29 | const editCropper = () => { | 29 | const editCropper = () => { |
| 30 | - state.dialogVisible = true | ||
| 31 | - state.cropperVisible = true | 30 | + dialogVisible.value = true |
| 31 | +} | ||
| 32 | +// 打开弹出层结束时的回调 | ||
| 33 | +const modalOpened = () => { | ||
| 34 | + cropperVisible.value = true | ||
| 32 | } | 35 | } |
| 33 | /** 向左旋转 */ | 36 | /** 向左旋转 */ |
| 34 | const rotateLeft = () => { | 37 | const rotateLeft = () => { |
| @@ -44,7 +47,7 @@ const changeScale = (num: number) => { | @@ -44,7 +47,7 @@ const changeScale = (num: number) => { | ||
| 44 | cropper.value.changeScale(num) | 47 | cropper.value.changeScale(num) |
| 45 | } | 48 | } |
| 46 | // 覆盖默认的上传行为 | 49 | // 覆盖默认的上传行为 |
| 47 | -const requestUpload = () => {} | 50 | +const requestUpload: any = () => {} |
| 48 | /** 上传预处理 */ | 51 | /** 上传预处理 */ |
| 49 | const beforeUpload = (file: Blob) => { | 52 | const beforeUpload = (file: Blob) => { |
| 50 | if (file.type.indexOf('image/') == -1) { | 53 | if (file.type.indexOf('image/') == -1) { |
| @@ -54,64 +57,65 @@ const beforeUpload = (file: Blob) => { | @@ -54,64 +57,65 @@ const beforeUpload = (file: Blob) => { | ||
| 54 | reader.readAsDataURL(file) | 57 | reader.readAsDataURL(file) |
| 55 | reader.onload = () => { | 58 | reader.onload = () => { |
| 56 | if (reader.result) { | 59 | if (reader.result) { |
| 57 | - state.options.img = reader.result as string | 60 | + options.options.img = reader.result as string |
| 58 | } | 61 | } |
| 59 | } | 62 | } |
| 60 | } | 63 | } |
| 61 | } | 64 | } |
| 62 | /** 上传图片 */ | 65 | /** 上传图片 */ |
| 63 | const uploadImg = () => { | 66 | const uploadImg = () => { |
| 64 | - cropper.value.getCropBlob((data) => { | 67 | + cropper.value.getCropBlob((data: any) => { |
| 65 | let formData = new FormData() | 68 | let formData = new FormData() |
| 66 | formData.append('avatarfile', data) | 69 | formData.append('avatarfile', data) |
| 67 | uploadAvatarApi(formData) | 70 | uploadAvatarApi(formData) |
| 68 | }) | 71 | }) |
| 69 | } | 72 | } |
| 70 | /** 实时预览 */ | 73 | /** 实时预览 */ |
| 71 | -const realTime = (data) => { | ||
| 72 | - state.previews = data | 74 | +const realTime = (data: any) => { |
| 75 | + options.previews = data | ||
| 73 | } | 76 | } |
| 74 | watch( | 77 | watch( |
| 75 | () => props.img, | 78 | () => props.img, |
| 76 | () => { | 79 | () => { |
| 77 | if (props.img) { | 80 | if (props.img) { |
| 78 | - state.options.img = props.img | ||
| 79 | - state.previews.img = props.img | ||
| 80 | - state.previews.url = props.img | 81 | + options.options.img = props.img |
| 82 | + options.previews.img = props.img | ||
| 83 | + options.previews.url = props.img | ||
| 81 | } | 84 | } |
| 82 | } | 85 | } |
| 83 | ) | 86 | ) |
| 84 | </script> | 87 | </script> |
| 85 | <template> | 88 | <template> |
| 86 | <div class="user-info-head" @click="editCropper()"> | 89 | <div class="user-info-head" @click="editCropper()"> |
| 87 | - <img :src="state.options.img" title="点击上传头像" class="img-circle img-lg" alt="" /> | 90 | + <img :src="options.options.img" title="点击上传头像" class="img-circle img-lg" alt="" /> |
| 88 | </div> | 91 | </div> |
| 89 | <el-dialog | 92 | <el-dialog |
| 90 | - v-model="state.dialogVisible" | ||
| 91 | - :title="state.dialogTitle" | ||
| 92 | - width="50%" | ||
| 93 | - :maxHeight="350" | 93 | + v-model="dialogVisible" |
| 94 | + :title="options.dialogTitle" | ||
| 95 | + width="800px" | ||
| 96 | + append-to-body | ||
| 94 | style="padding: 30px 20px" | 97 | style="padding: 30px 20px" |
| 98 | + @opened="modalOpened" | ||
| 95 | > | 99 | > |
| 96 | <el-row> | 100 | <el-row> |
| 97 | <el-col :xs="24" :md="12" style="height: 350px"> | 101 | <el-col :xs="24" :md="12" style="height: 350px"> |
| 98 | <VueCropper | 102 | <VueCropper |
| 99 | ref="cropper" | 103 | ref="cropper" |
| 100 | - :img="state.options.img" | 104 | + :img="options.options.img" |
| 101 | :info="true" | 105 | :info="true" |
| 102 | - :autoCrop="state.options.autoCrop" | ||
| 103 | - :autoCropWidth="state.options.autoCropWidth" | ||
| 104 | - :autoCropHeight="state.options.autoCropHeight" | ||
| 105 | - :fixedBox="state.options.fixedBox" | 106 | + :autoCrop="options.options.autoCrop" |
| 107 | + :autoCropWidth="options.options.autoCropWidth" | ||
| 108 | + :autoCropHeight="options.options.autoCropHeight" | ||
| 109 | + :fixedBox="options.options.fixedBox" | ||
| 106 | @real-time="realTime" | 110 | @real-time="realTime" |
| 107 | - v-if="state.cropperVisible" | 111 | + v-if="cropperVisible" |
| 108 | /> | 112 | /> |
| 109 | </el-col> | 113 | </el-col> |
| 110 | <el-col :xs="24" :md="12" style="height: 350px"> | 114 | <el-col :xs="24" :md="12" style="height: 350px"> |
| 111 | <div class="avatar-upload-preview"> | 115 | <div class="avatar-upload-preview"> |
| 112 | <img | 116 | <img |
| 113 | - :src="state.previews.url" | ||
| 114 | - :style="state.previews.img" | 117 | + :src="options.previews.url" |
| 118 | + :style="options.previews.img" | ||
| 115 | style="!max-width: 100%" | 119 | style="!max-width: 100%" |
| 116 | alt="" | 120 | alt="" |
| 117 | /> | 121 | /> |
yudao-ui-admin-vue3/src/views/system/menu/index.vue
| @@ -47,7 +47,6 @@ const getTree = async () => { | @@ -47,7 +47,6 @@ const getTree = async () => { | ||
| 47 | const res = await MenuApi.listSimpleMenusApi() | 47 | const res = await MenuApi.listSimpleMenusApi() |
| 48 | const menu = { id: 0, name: '主类目', children: [] as any[] } | 48 | const menu = { id: 0, name: '主类目', children: [] as any[] } |
| 49 | menu.children = handleTree(res) | 49 | menu.children = handleTree(res) |
| 50 | - console.info(menu) | ||
| 51 | menuOptions.value = menu | 50 | menuOptions.value = menu |
| 52 | } | 51 | } |
| 53 | // ========== 查询 ========== | 52 | // ========== 查询 ========== |
yudao-ui-admin-vue3/src/views/system/oauth2/client/index.vue
| @@ -155,7 +155,7 @@ getList() | @@ -155,7 +155,7 @@ getList() | ||
| 155 | </Table> | 155 | </Table> |
| 156 | </ContentWrap> | 156 | </ContentWrap> |
| 157 | 157 | ||
| 158 | - <Dialog v-model="dialogVisible" :title="dialogTitle"> | 158 | + <Dialog v-model="dialogVisible" :title="dialogTitle" width="60%" maxHeight="420px"> |
| 159 | <!-- 对话框(添加 / 修改) --> | 159 | <!-- 对话框(添加 / 修改) --> |
| 160 | <Form | 160 | <Form |
| 161 | v-if="['create', 'update'].includes(actionType)" | 161 | v-if="['create', 'update'].includes(actionType)" |
yudao-ui-admin-vue3/src/views/system/role/index.vue
| @@ -110,7 +110,7 @@ const defaultProps = { | @@ -110,7 +110,7 @@ const defaultProps = { | ||
| 110 | label: 'name', | 110 | label: 'name', |
| 111 | value: 'id' | 111 | value: 'id' |
| 112 | } | 112 | } |
| 113 | -const treeOptions = ref([]) // 菜单树形结构 | 113 | +const treeOptions = ref<any[]>([]) // 菜单树形结构 |
| 114 | const treeRef = ref<InstanceType<typeof ElTree>>() | 114 | const treeRef = ref<InstanceType<typeof ElTree>>() |
| 115 | const dialogScopeVisible = ref(false) | 115 | const dialogScopeVisible = ref(false) |
| 116 | const dialogScopeTitle = ref('数据权限') | 116 | const dialogScopeTitle = ref('数据权限') |
| @@ -133,7 +133,6 @@ const handleScope = async (type: string, row: RoleVO) => { | @@ -133,7 +133,6 @@ const handleScope = async (type: string, row: RoleVO) => { | ||
| 133 | const menuRes = await listSimpleMenusApi() | 133 | const menuRes = await listSimpleMenusApi() |
| 134 | treeOptions.value = handleTree(menuRes) | 134 | treeOptions.value = handleTree(menuRes) |
| 135 | const role = await PermissionApi.listRoleMenusApi(row.id) | 135 | const role = await PermissionApi.listRoleMenusApi(row.id) |
| 136 | - console.info(role) | ||
| 137 | if (role) { | 136 | if (role) { |
| 138 | // treeRef.value!.setCheckedKeys(role as unknown as Array<number>) | 137 | // treeRef.value!.setCheckedKeys(role as unknown as Array<number>) |
| 139 | defaultCheckedKeys.value = role | 138 | defaultCheckedKeys.value = role |
| @@ -142,7 +141,6 @@ const handleScope = async (type: string, row: RoleVO) => { | @@ -142,7 +141,6 @@ const handleScope = async (type: string, row: RoleVO) => { | ||
| 142 | const deptRes = await listSimpleDeptApi() | 141 | const deptRes = await listSimpleDeptApi() |
| 143 | treeOptions.value = handleTree(deptRes) | 142 | treeOptions.value = handleTree(deptRes) |
| 144 | const role = await RoleApi.getRoleApi(row.id) | 143 | const role = await RoleApi.getRoleApi(row.id) |
| 145 | - console.info(role) | ||
| 146 | dataScopeForm.dataScope = role.dataScope | 144 | dataScopeForm.dataScope = role.dataScope |
| 147 | if (role.dataScopeDeptIds) { | 145 | if (role.dataScopeDeptIds) { |
| 148 | // treeRef.value!.setCheckedKeys(role.dataScopeDeptIds as unknown as Array<number>, false) | 146 | // treeRef.value!.setCheckedKeys(role.dataScopeDeptIds as unknown as Array<number>, false) |
| @@ -155,7 +153,6 @@ const handleScope = async (type: string, row: RoleVO) => { | @@ -155,7 +153,6 @@ const handleScope = async (type: string, row: RoleVO) => { | ||
| 155 | // 保存权限 | 153 | // 保存权限 |
| 156 | const submitScope = async () => { | 154 | const submitScope = async () => { |
| 157 | const keys = treeRef.value!.getCheckedKeys(false) as unknown as Array<number> | 155 | const keys = treeRef.value!.getCheckedKeys(false) as unknown as Array<number> |
| 158 | - console.info(keys) | ||
| 159 | if ('data' === actionScopeType.value) { | 156 | if ('data' === actionScopeType.value) { |
| 160 | const data = ref<PermissionAssignRoleDataScopeReqVO>({ | 157 | const data = ref<PermissionAssignRoleDataScopeReqVO>({ |
| 161 | roleId: dataScopeForm.id, | 158 | roleId: dataScopeForm.id, |
yudao-ui-admin-vue3/src/views/system/tenantPackage/index.vue
| @@ -19,7 +19,7 @@ const defaultProps = { | @@ -19,7 +19,7 @@ const defaultProps = { | ||
| 19 | value: 'id' | 19 | value: 'id' |
| 20 | } | 20 | } |
| 21 | // ========== 创建菜单树结构 ========== | 21 | // ========== 创建菜单树结构 ========== |
| 22 | -const menuOptions = ref([]) // 树形结构 | 22 | +const menuOptions = ref<any[]>([]) // 树形结构 |
| 23 | const treeRef = ref<InstanceType<typeof ElTree>>() | 23 | const treeRef = ref<InstanceType<typeof ElTree>>() |
| 24 | const treeNodeAll = ref(false) | 24 | const treeNodeAll = ref(false) |
| 25 | // 全选/全不选 | 25 | // 全选/全不选 |
| @@ -84,11 +84,9 @@ const submitForm = async () => { | @@ -84,11 +84,9 @@ const submitForm = async () => { | ||
| 84 | if (actionType.value === 'create') { | 84 | if (actionType.value === 'create') { |
| 85 | await TenantPackageApi.createTenantPackageTypeApi(data) | 85 | await TenantPackageApi.createTenantPackageTypeApi(data) |
| 86 | ElMessage.success(t('common.createSuccess')) | 86 | ElMessage.success(t('common.createSuccess')) |
| 87 | - console.log('new data') | ||
| 88 | } else { | 87 | } else { |
| 89 | await TenantPackageApi.updateTenantPackageTypeApi(data) | 88 | await TenantPackageApi.updateTenantPackageTypeApi(data) |
| 90 | ElMessage.success(t('common.updateSuccess')) | 89 | ElMessage.success(t('common.updateSuccess')) |
| 91 | - console.log('edit data') | ||
| 92 | } | 90 | } |
| 93 | // 操作成功,重新加载列表 | 91 | // 操作成功,重新加载列表 |
| 94 | dialogVisible.value = false | 92 | dialogVisible.value = false |