From 92a2421a9b7e38707e38dbac64f1202f027c1114 Mon Sep 17 00:00:00 2001 From: daxiongok <571115139@qq.com> Date: Sat, 17 Aug 2024 22:53:19 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=E5=89=8D=E7=AB=AFto?= =?UTF-8?q?ken=E6=97=A0=E6=84=9F=E5=88=B7=E6=96=B0=E5=8A=9F=E8=83=BD=20fix?= =?UTF-8?q?:=E5=89=8D=E7=AB=AF=E6=9D=83=E9=99=90=E7=A0=81=E5=A4=AA?= =?UTF-8?q?=E5=A4=9A=E6=97=B6=EF=BC=8Ccookie=E5=A4=AA=E5=A4=A7=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E5=BC=82=E5=B8=B8=E9=97=AE=E9=A2=98=E3=80=82=E6=94=B9?= =?UTF-8?q?=E4=B8=BAlocalstage=E5=AD=98=E5=82=A8token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: daxiongok <571115139@qq.com> --- Yi.RuoYi.Vue3/src/utils/auth.js | 26 ++++++- Yi.RuoYi.Vue3/src/utils/refreshToken.js | 19 +++++ Yi.RuoYi.Vue3/src/utils/request.js | 98 +++++++++++++++++++------ 3 files changed, 118 insertions(+), 25 deletions(-) create mode 100644 Yi.RuoYi.Vue3/src/utils/refreshToken.js diff --git a/Yi.RuoYi.Vue3/src/utils/auth.js b/Yi.RuoYi.Vue3/src/utils/auth.js index ca2c6e4f..56ab71df 100644 --- a/Yi.RuoYi.Vue3/src/utils/auth.js +++ b/Yi.RuoYi.Vue3/src/utils/auth.js @@ -1,18 +1,38 @@ import Cookies from 'js-cookie' const TokenKey = 'Admin-Token' +const RefreshTokenKey = 'Refresh-Token' const TenantIdKey='Tenant-Id' export function getToken() { - return Cookies.get(TokenKey) + return localStorage.getItem(TokenKey) + // return Cookies.get(TokenKey) } export function setToken(token) { - return Cookies.set(TokenKey, token) + return localStorage.setItem(TokenKey, token) + // return Cookies.set(TokenKey, token) } export function removeToken() { - return Cookies.remove(TokenKey) + return localStorage.removeItem(TokenKey) + // return Cookies.remove(TokenKey) } + +export function getRefreshToken() { + return localStorage.getItem(RefreshTokenKey) + // return Cookies.get(RefreshTokenKey) +} + +export function setRefreshToken(token) { + return localStorage.setItem(RefreshTokenKey, token) + // return Cookies.set(RefreshTokenKey, token) +} + +export function removeRefreshToken() { + return localStorage.removeItem(RefreshTokenKey) + // return Cookies.remove(RefreshTokenKey) +} + export function getTenantId() { return Cookies.get(TenantIdKey) } diff --git a/Yi.RuoYi.Vue3/src/utils/refreshToken.js b/Yi.RuoYi.Vue3/src/utils/refreshToken.js new file mode 100644 index 00000000..33dc0e7f --- /dev/null +++ b/Yi.RuoYi.Vue3/src/utils/refreshToken.js @@ -0,0 +1,19 @@ +import { getRefreshToken } from './auth' +import request from './request' + +export function refreshToken() { + return request({ + url: '/account/refresh', + method: 'post', + headers: { + 'Content-Type': 'application/json;charset=utf-8', + 'Authorization': 'Bearer ' + getRefreshToken(), + 'isToken' :false + }, + __isRefreshToken: true + }) +} + +export function isRefreshRequest(config) { + return !!config.__isRefreshToken +} diff --git a/Yi.RuoYi.Vue3/src/utils/request.js b/Yi.RuoYi.Vue3/src/utils/request.js index 7d755f7b..b5c3b6fb 100644 --- a/Yi.RuoYi.Vue3/src/utils/request.js +++ b/Yi.RuoYi.Vue3/src/utils/request.js @@ -1,6 +1,7 @@ import axios from 'axios' import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus' import { getToken,getTenantId } from '@/utils/auth' +import { refreshToken, isRefreshRequest } from './refreshToken.js' import errorCode from '@/utils/errorCode' import { tansParams, blobValidate } from '@/utils/ruoyi' import cache from '@/plugins/cache' @@ -126,16 +127,69 @@ service.interceptors.response.use(res => { // handler(code, msg); return Promise.resolve(res); -}, - error => { +}, async function(error) { + console.log(error.response, "error") + const errorRes = error.response; + console.log('isRefreshingbefore',isRefreshing) - console.log(error.response,"error") - const errorRes=error.response; - const code = errorRes.status || 200; - const msg = `${errorRes.data?.error?.message}` ; + if (errorRes?.status == '401' && !isRefreshRequest(errorRes.config)){ // 如果没有权限且不是刷新token的请求 + console.log('isRefreshing',isRefreshing,new Date()) + if (!isRefreshing) { + isRefreshing = true + let newToken = '' + // 刷新token + try { + const res = await refreshToken() + // 保存新的token + newToken = res.data.token + setToken(newToken) + setRefreshToken(res.data.refreshToken) + + } catch(e) { + console.log("触发重新登录",e) + ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { + confirmButtonText: '重新登录', + cancelButtonText: '取消', + type: 'warning' + }) + .then(() => { + isRelogin.show = false; + useUserStore().logOut().then(() => { + location.href = '/index'; + }) + }).catch(() => { + isRelogin.show = false; + }); + return Promise.reject(error) + } + // 有新token后再重新请求 + errorRes.config.headers['Authorization'] = 'Bearer ' + newToken // 新token + // token 刷新后将数组的方法重新执行 + waitRequests.forEach((cb) => cb(newToken)) + waitRequests = [] // 重新请求完清空 + const resp = await service.request(errorRes.config) + isRefreshing = false + console.log('closseRefreshing',isRefreshing) + return Promise.resolve(resp); + } else { + // 返回未执行 resolve 的 Promise + return new Promise(resolve => { + // 用函数形式将 resolve 存入,等待刷新后再执行 + waitRequests.push(token => { + errorRes.config.headers['Authorization'] = 'Bearer ' + `${token}` + resolve(service(errorRes.config)) + }) + }) + } + } + else + { + const code = errorRes && errorRes.status || 200; + const msg = `${errorRes?.data?.error?.message}`; handler(code, msg); return Promise.reject(error) } +} ) // 通用下载方法 @@ -180,22 +234,22 @@ const handler = (code, msg) => { title: msg }) break; - //未授权 - case 401: - ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - }) - .then(() => { - isRelogin.show = false; - useUserStore().logOut().then(() => { - location.href = '/index'; - }) - }).catch(() => { - isRelogin.show = false; - }); - break; + // //未授权 + // case 401: + // ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // }) + // .then(() => { + // isRelogin.show = false; + // useUserStore().logOut().then(() => { + // location.href = '/index'; + // }) + // }).catch(() => { + // isRelogin.show = false; + // }); + // break; case 404: ElMessage({ message: "404未找到资源", From f67b60dd822a43ebc076777fc3308ead4b7ecfdd Mon Sep 17 00:00:00 2001 From: daxiongok <12421064+tirisfalcn@user.noreply.gitee.com> Date: Sat, 17 Aug 2024 15:08:17 +0000 Subject: [PATCH 2/5] update Yi.RuoYi.Vue3/src/utils/request.js. Signed-off-by: daxiongok <12421064+tirisfalcn@user.noreply.gitee.com> --- Yi.RuoYi.Vue3/src/utils/request.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Yi.RuoYi.Vue3/src/utils/request.js b/Yi.RuoYi.Vue3/src/utils/request.js index b5c3b6fb..0c1cda23 100644 --- a/Yi.RuoYi.Vue3/src/utils/request.js +++ b/Yi.RuoYi.Vue3/src/utils/request.js @@ -11,6 +11,8 @@ import JsonBig from 'json-bigint' import qs from 'qs' let downloadLoadingInstance; +let isRefreshing = false; +let waitRequests = [] // 请求队列 // 是否显示重新登录 export let isRelogin = { show: false }; @@ -132,7 +134,7 @@ service.interceptors.response.use(res => { const errorRes = error.response; console.log('isRefreshingbefore',isRefreshing) - if (errorRes?.status == '401' && !isRefreshRequest(errorRes.config)){ // 如果没有权限且不是刷新token的请求 + if (errorRes?.status == '401' && !isRefreshRequest(errorRes.config)) { // 如果没有权限且不是刷新token的请求 console.log('isRefreshing',isRefreshing,new Date()) if (!isRefreshing) { isRefreshing = true From 187885fdb9ba646a4062c399609ca57676211a9c Mon Sep 17 00:00:00 2001 From: daxiongok <571115139@qq.com> Date: Sun, 18 Aug 2024 10:05:26 +0800 Subject: [PATCH 3/5] =?UTF-8?q?fix:=E6=9C=AA=E5=BC=95=E7=94=A8=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: daxiongok <571115139@qq.com> --- Yi.RuoYi.Vue3/src/utils/request.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Yi.RuoYi.Vue3/src/utils/request.js b/Yi.RuoYi.Vue3/src/utils/request.js index b5c3b6fb..5524e021 100644 --- a/Yi.RuoYi.Vue3/src/utils/request.js +++ b/Yi.RuoYi.Vue3/src/utils/request.js @@ -1,6 +1,6 @@ import axios from 'axios' import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus' -import { getToken,getTenantId } from '@/utils/auth' +import { getToken,setToken,setRefreshToken,getTenantId } from '@/utils/auth' import { refreshToken, isRefreshRequest } from './refreshToken.js' import errorCode from '@/utils/errorCode' import { tansParams, blobValidate } from '@/utils/ruoyi' From 0656e3f536de3a8930c772b806772d6a11ef5206 Mon Sep 17 00:00:00 2001 From: daxiongok <571115139@qq.com> Date: Sun, 18 Aug 2024 10:20:23 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat:=E9=BB=98=E8=AE=A4=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E5=80=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: daxiongok <571115139@qq.com> --- .../Services/RecordLog/LoginLogService.cs | 1 + .../Services/RecordLog/OperationLogService.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/LoginLogService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/LoginLogService.cs index e0944033..9286316e 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/LoginLogService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/LoginLogService.cs @@ -24,6 +24,7 @@ namespace Yi.Framework.Rbac.Application.Services.RecordLog var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.LoginIp), x => x.LoginIp.Contains(input.LoginIp!)) .WhereIF(!string.IsNullOrEmpty(input.LoginUser), x => x.LoginUser!.Contains(input.LoginUser!)) .WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime) + .OrderByDescending(x => x.CreationTime) .ToPageListAsync(input.SkipCount, input.MaxResultCount, total); return new PagedResultDto(total, await MapToGetListOutputDtosAsync(entities)); } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/OperationLogService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/OperationLogService.cs index 3bcd6d37..d386b3d3 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/OperationLogService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/OperationLogService.cs @@ -27,6 +27,7 @@ namespace Yi.Framework.Rbac.Application.Services.RecordLog var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.OperUser), x => x.OperUser.Contains(input.OperUser!)) .WhereIF(input.OperType is not null, x => x.OperType == input.OperType) .WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime) + .OrderByDescending(x => x.CreationTime) .ToPageListAsync(input.SkipCount, input.MaxResultCount, total); return new PagedResultDto(total, await MapToGetListOutputDtosAsync(entities)); } From dc242420f8017f90bbbd27c69c140664517391ec Mon Sep 17 00:00:00 2001 From: daxiongok <571115139@qq.com> Date: Sun, 18 Aug 2024 10:48:54 +0800 Subject: [PATCH 5/5] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E6=94=AF=E6=8C=81=E5=92=8C=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: daxiongok <571115139@qq.com> --- .../PagedAllResultRequestDto.cs | 32 ++++++++++++++++++- .../Services/RecordLog/LoginLogService.cs | 5 +-- .../Services/RecordLog/OperationLogService.cs | 4 ++- .../src/views/monitor/logininfor/index.vue | 10 ++++-- .../src/views/monitor/operlog/index.vue | 11 +++++-- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application.Contracts/PagedAllResultRequestDto.cs b/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application.Contracts/PagedAllResultRequestDto.cs index a4e90f33..494caceb 100644 --- a/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application.Contracts/PagedAllResultRequestDto.cs +++ b/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application.Contracts/PagedAllResultRequestDto.cs @@ -13,5 +13,35 @@ namespace Yi.Framework.Ddd.Application.Contracts /// 查询结束时间条件 /// public DateTime? EndTime { get; set; } + + /// + /// 排序列名,字段名对应前端 + /// + public string? OrderByColumn { get; set; } + /// + /// 是否顺序,字段名对应前端 + /// + public string? IsAsc { get; set; } + + /// + /// 是否顺序 + /// + public bool CanAsc => IsAsc?.ToLower() == "ascending" ? true : false; + private string _sorting; + //排序引用 + public new string? Sorting + { + get + { + if (!OrderByColumn.IsNullOrWhiteSpace()) + { + return $"{OrderByColumn} {(CanAsc ? "ASC" : "DESC")}"; + } + else + { + return _sorting; + } + } + set => _sorting = value; + } } -} diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/LoginLogService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/LoginLogService.cs index 9286316e..8a30b299 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/LoginLogService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/LoginLogService.cs @@ -20,11 +20,12 @@ namespace Yi.Framework.Rbac.Application.Services.RecordLog public override async Task> GetListAsync(LoginLogGetListInputVo input) { RefAsync total = 0; - + if (input.Sorting.IsNullOrWhiteSpace()) + input.Sorting = $"{nameof(LoginLogAggregateRoot.CreationTime)} Desc"; var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.LoginIp), x => x.LoginIp.Contains(input.LoginIp!)) .WhereIF(!string.IsNullOrEmpty(input.LoginUser), x => x.LoginUser!.Contains(input.LoginUser!)) .WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime) - .OrderByDescending(x => x.CreationTime) + .OrderBy(input.Sorting) .ToPageListAsync(input.SkipCount, input.MaxResultCount, total); return new PagedResultDto(total, await MapToGetListOutputDtosAsync(entities)); } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/OperationLogService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/OperationLogService.cs index d386b3d3..4e70b58a 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/OperationLogService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/RecordLog/OperationLogService.cs @@ -24,10 +24,12 @@ namespace Yi.Framework.Rbac.Application.Services.RecordLog public override async Task> GetListAsync(OperationLogGetListInputVo input) { RefAsync total = 0; + if (input.Sorting.IsNullOrWhiteSpace()) + input.Sorting = $"{nameof(OperationLogEntity.CreationTime)} Desc"; var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.OperUser), x => x.OperUser.Contains(input.OperUser!)) .WhereIF(input.OperType is not null, x => x.OperType == input.OperType) .WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime) - .OrderByDescending(x => x.CreationTime) + .OrderBy(input.Sorting) .ToPageListAsync(input.SkipCount, input.MaxResultCount, total); return new PagedResultDto(total, await MapToGetListOutputDtosAsync(entities)); } diff --git a/Yi.RuoYi.Vue3/src/views/monitor/logininfor/index.vue b/Yi.RuoYi.Vue3/src/views/monitor/logininfor/index.vue index 382e1801..ef08d825 100644 --- a/Yi.RuoYi.Vue3/src/views/monitor/logininfor/index.vue +++ b/Yi.RuoYi.Vue3/src/views/monitor/logininfor/index.vue @@ -181,9 +181,13 @@ function handleSelectionChange(selection) { } /** 排序触发事件 */ function handleSortChange(column, prop, order) { - queryParams.value.orderByColumn = column.prop; - queryParams.value.isAsc = column.order; - getList(); + if (!column.order) { + queryParams.value.orderByColumn = null; + } else { + queryParams.value.orderByColumn = column.prop; + } + queryParams.value.isAsc = column.order; + getList(); } /** 删除按钮操作 */ function handleDelete(row) { diff --git a/Yi.RuoYi.Vue3/src/views/monitor/operlog/index.vue b/Yi.RuoYi.Vue3/src/views/monitor/operlog/index.vue index e19e663d..c8829d7c 100644 --- a/Yi.RuoYi.Vue3/src/views/monitor/operlog/index.vue +++ b/Yi.RuoYi.Vue3/src/views/monitor/operlog/index.vue @@ -202,7 +202,8 @@ const data = reactive({ title: undefined, operUser: undefined, operType: undefined, - state: undefined + state: undefined, + orderByColumn: undefined } }); @@ -240,8 +241,12 @@ function handleSelectionChange(selection) { } /** 排序触发事件 */ function handleSortChange(column, prop, order) { - queryParams.value.orderByColumn = column.prop; - queryParams.value.isAsc = column.order; + if (!column.order) { + queryParams.value.orderByColumn = null; + } else { + queryParams.value.orderByColumn = column.prop; + } + queryParams.value.isAsc = column.order; getList(); } /** 详细按钮操作 */