diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs index 45e80bcc..7a838659 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs @@ -1,6 +1,8 @@ using System.Text.RegularExpressions; using Lazy.Captcha.Core; +using Mapster; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.DependencyInjection; @@ -25,6 +27,7 @@ using Yi.Framework.Rbac.Domain.Repositories; using Yi.Framework.Rbac.Domain.Shared.Caches; using Yi.Framework.Rbac.Domain.Shared.Consts; using Yi.Framework.Rbac.Domain.Shared.Dtos; +using Yi.Framework.Rbac.Domain.Shared.Etos; using Yi.Framework.Rbac.Domain.Shared.Options; using Yi.Framework.SqlSugarCore.Abstractions; @@ -40,7 +43,7 @@ namespace Yi.Framework.Rbac.Application.Services private readonly IAliyunManger _aliyunManger; private IDistributedCache _userCache; private UserManager _userManager; - + private IHttpContextAccessor _httpContextAccessor; public AccountService(IUserRepository userRepository, ICurrentUser currentUser, IAccountManager accountManager, @@ -51,7 +54,7 @@ namespace Yi.Framework.Rbac.Application.Services IGuidGenerator guidGenerator, IOptions options, IAliyunManger aliyunManger, - UserManager userManager) + UserManager userManager, IHttpContextAccessor httpContextAccessor) { _userRepository = userRepository; _currentUser = currentUser; @@ -64,6 +67,7 @@ namespace Yi.Framework.Rbac.Application.Services _aliyunManger = aliyunManger; _userCache = userCache; _userManager = userManager; + _httpContextAccessor = httpContextAccessor; } @@ -109,10 +113,21 @@ namespace Yi.Framework.Rbac.Application.Services //校验 await _accountManager.LoginValidationAsync(input.UserName, input.Password, x => user = x); + var userInfo = new UserRoleMenuDto(); //获取token - var accessToken = await _accountManager.GetTokenByUserIdAsync(user.Id); + var accessToken = await _accountManager.GetTokenByUserIdAsync(user.Id, (info) => userInfo = info); var refreshToken = _accountManager.CreateRefreshToken(user.Id); + //这里抛出一个登录的事件,也可以在全部流程走完,在应用层组装 + if (_httpContextAccessor.HttpContext is not null) + { + var loginEntity = new LoginLogAggregateRoot().GetInfoByHttpContext(_httpContextAccessor.HttpContext); + var loginEto = loginEntity.Adapt(); + loginEto.UserName = userInfo.User.UserName; + loginEto.UserId = userInfo.User.Id; + await LocalEventBus.PublishAsync(loginEto); + } + return new { Token = accessToken, RefreshToken = refreshToken }; } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs index b7a58206..233518dd 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs @@ -34,13 +34,11 @@ namespace Yi.Framework.Rbac.Domain.Managers private readonly ILocalEventBus _localEventBus; private readonly JwtOptions _jwtOptions; private readonly RbacOptions _options; - private IHttpContextAccessor _httpContextAccessor; private UserManager _userManager; private ISqlSugarRepository _roleRepository; private RefreshJwtOptions _refreshJwtOptions; public AccountManager(IUserRepository repository - , IHttpContextAccessor httpContextAccessor , IOptions jwtOptions , ILocalEventBus localEventBus , UserManager userManager @@ -49,7 +47,6 @@ namespace Yi.Framework.Rbac.Domain.Managers , IOptions options) { _repository = repository; - _httpContextAccessor = httpContextAccessor; _jwtOptions = jwtOptions.Value; _localEventBus = localEventBus; _userManager = userManager; @@ -62,9 +59,10 @@ namespace Yi.Framework.Rbac.Domain.Managers /// 根据用户id获取token /// /// + /// /// /// - public async Task GetTokenByUserIdAsync(Guid userId) + public async Task GetTokenByUserIdAsync(Guid userId,Action? getUserInfo=null) { //获取用户信息 var userInfo = await _userManager.GetInfoAsync(userId); @@ -79,23 +77,18 @@ namespace Yi.Framework.Rbac.Domain.Managers { throw new UserFriendlyException(UserConst.No_Role); } - if (userInfo.PermissionCodes.Count() == 0) + if (!userInfo.PermissionCodes.Any()) { throw new UserFriendlyException(UserConst.No_Permission); } - //这里抛出一个登录的事件,也可以在全部流程走完,在应用层组装 - if (_httpContextAccessor.HttpContext is not null) + + if (getUserInfo is not null) { - var loginEntity = new LoginLogAggregateRoot().GetInfoByHttpContext(_httpContextAccessor.HttpContext); - var loginEto = loginEntity.Adapt(); - loginEto.UserName = userInfo.User.UserName; - loginEto.UserId = userInfo.User.Id; - await _localEventBus.PublishAsync(loginEto); + getUserInfo(userInfo); } + var accessToken = CreateToken(this.UserInfoToClaim(userInfo)); //将用户信息添加到缓存中,需要考虑的是更改了用户、角色、菜单等整个体系都需要将缓存进行刷新,看具体业务进行选择 - - return accessToken; } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/IAccountManager.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/IAccountManager.cs index c4581d46..cbbf5eb9 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/IAccountManager.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/IAccountManager.cs @@ -5,14 +5,15 @@ using System.Text; using System.Threading.Tasks; using Volo.Abp.Domain.Services; using Yi.Framework.Rbac.Domain.Entities; +using Yi.Framework.Rbac.Domain.Shared.Dtos; namespace Yi.Framework.Rbac.Domain.Managers { public interface IAccountManager : IDomainService { string CreateRefreshToken(Guid userId); - Task GetTokenByUserIdAsync(Guid userId); - Task LoginValidationAsync(string userName, string password, Action userAction = null); + Task GetTokenByUserIdAsync(Guid userId,Action? getUserInfo=null); + Task LoginValidationAsync(string userName, string password, Action? userAction = null); Task RegisterAsync(string userName, string password, long phone); Task RestPasswordAsync(Guid userId, string password); Task UpdatePasswordAsync(Guid userId, string newPassword, string oldPassword); diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs index cfc4d1cc..2e14bbd5 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs @@ -162,14 +162,23 @@ namespace Yi.Framework.Rbac.Domain.Managers } /// - /// 查询用户信息,已缓存 + /// 查询用户信息,取消缓存 /// /// public async Task GetInfoAsync(Guid userId) { - - var output = await GetInfoByCacheAsync(userId); - return output; + var user = await _userRepository.GetUserAllInfoAsync(userId); + var data = EntityMapToDto(user); + //系统用户数据被重置,老前端访问重新授权 + if (data is null) + { + throw new AbpAuthorizationException(); + } + //data.Menus.Clear(); + // output = data; + return data; + // var output = await GetInfoByCacheAsync(userId); + // return output; } private async Task GetInfoByCacheAsync(Guid userId) { diff --git a/Yi.Pure.Vue3/mock/asyncRoutes.ts b/Yi.Pure.Vue3/mock/asyncRoutes.ts index 4ea95364..4fffebed 100644 --- a/Yi.Pure.Vue3/mock/asyncRoutes.ts +++ b/Yi.Pure.Vue3/mock/asyncRoutes.ts @@ -1,6 +1,6 @@ // 模拟后端动态生成路由 import { defineFakeRoute } from "vite-plugin-fake-server/client"; -import { system, monitor, permission, frame, tabs } from "@/router/enums"; +import { system, monitor } from "@/router/enums"; /** * roles:页面级别权限,这里模拟二种 "admin"、"common" @@ -21,7 +21,7 @@ const systemManagementRouter = { name: "SystemUser", meta: { icon: "ri:admin-line", - title: "menus.pureUser", + title: "menus.pureUser" //roles: ["admin"] } }, @@ -30,7 +30,7 @@ const systemManagementRouter = { name: "SystemRole", meta: { icon: "ri:admin-fill", - title: "menus.pureRole", + title: "menus.pureRole" //roles: ["admin"] } }, @@ -39,7 +39,7 @@ const systemManagementRouter = { name: "SystemMenu", meta: { icon: "ep:menu", - title: "menus.pureSystemMenu", + title: "menus.pureSystemMenu" //roles: ["admin"] } }, @@ -48,7 +48,7 @@ const systemManagementRouter = { name: "SystemDept", meta: { icon: "ri:git-branch-line", - title: "menus.pureDept", + title: "menus.pureDept" //roles: ["admin"] } }, @@ -57,7 +57,7 @@ const systemManagementRouter = { name: "SystemPost", meta: { icon: "ant-design:deployment-unit-outlined", - title: "menus.purePost", + title: "menus.purePost" //roles: ["admin"] } } @@ -78,7 +78,7 @@ const systemMonitorRouter = { name: "OnlineUser", meta: { icon: "ri:user-voice-line", - title: "menus.pureOnlineUser", + title: "menus.pureOnlineUser" //roles: ["admin"] } }, @@ -88,7 +88,7 @@ const systemMonitorRouter = { name: "LoginLog", meta: { icon: "ri:window-line", - title: "menus.pureLoginLog", + title: "menus.pureLoginLog" //roles: ["admin"] } }, @@ -98,7 +98,7 @@ const systemMonitorRouter = { name: "OperationLog", meta: { icon: "ri:history-fill", - title: "menus.pureOperationLog", + title: "menus.pureOperationLog" //roles: ["admin"] } } @@ -114,220 +114,220 @@ const systemMonitorRouter = { // } ] }; - -const permissionRouter = { - path: "/permission", - meta: { - title: "menus.purePermission", - icon: "ep:lollipop", - rank: permission - }, - children: [ - { - path: "/permission/page/index", - name: "PermissionPage", - meta: { - title: "menus.purePermissionPage", - //roles: ["admin", "common"] - } - }, - { - path: "/permission/button", - meta: { - title: "menus.purePermissionButton", - //roles: ["admin", "common"] - }, - children: [ - { - path: "/permission/button/router", - component: "permission/button/index", - name: "PermissionButtonRouter", - meta: { - title: "menus.purePermissionButtonRouter", - auths: [ - "permission:btn:add", - "permission:btn:edit", - "permission:btn:delete" - ] - } - }, - { - path: "/permission/button/login", - component: "permission/button/perms", - name: "PermissionButtonLogin", - meta: { - title: "menus.purePermissionButtonLogin" - } - } - ] - } - ] -}; - -const frameRouter = { - path: "/iframe", - meta: { - icon: "ri:links-fill", - title: "menus.pureExternalPage", - rank: frame - }, - children: [ - { - path: "/iframe/embedded", - meta: { - title: "menus.pureEmbeddedDoc" - }, - children: [ - { - path: "/iframe/colorhunt", - name: "FrameColorHunt", - meta: { - title: "menus.pureColorHuntDoc", - frameSrc: "https://colorhunt.co/", - keepAlive: true, - //roles: ["admin", "common"] - } - }, - { - path: "/iframe/uigradients", - name: "FrameUiGradients", - meta: { - title: "menus.pureUiGradients", - frameSrc: "https://uigradients.com/", - keepAlive: true, - //roles: ["admin", "common"] - } - }, - { - path: "/iframe/ep", - name: "FrameEp", - meta: { - title: "menus.pureEpDoc", - frameSrc: "https://element-plus.org/zh-CN/", - keepAlive: true, - //roles: ["admin", "common"] - } - }, - { - path: "/iframe/tailwindcss", - name: "FrameTailwindcss", - meta: { - title: "menus.pureTailwindcssDoc", - frameSrc: "https://tailwindcss.com/docs/installation", - keepAlive: true, - //roles: ["admin", "common"] - } - }, - { - path: "/iframe/vue3", - name: "FrameVue", - meta: { - title: "menus.pureVueDoc", - frameSrc: "https://cn.vuejs.org/", - keepAlive: true, - //roles: ["admin", "common"] - } - }, - { - path: "/iframe/vite", - name: "FrameVite", - meta: { - title: "menus.pureViteDoc", - frameSrc: "https://cn.vitejs.dev/", - keepAlive: true, - //roles: ["admin", "common"] - } - }, - { - path: "/iframe/pinia", - name: "FramePinia", - meta: { - title: "menus.purePiniaDoc", - frameSrc: "https://pinia.vuejs.org/zh/index.html", - keepAlive: true, - //roles: ["admin", "common"] - } - }, - { - path: "/iframe/vue-router", - name: "FrameRouter", - meta: { - title: "menus.pureRouterDoc", - frameSrc: "https://router.vuejs.org/zh/", - keepAlive: true, - //roles: ["admin", "common"] - } - } - ] - }, - { - path: "/iframe/external", - meta: { - title: "menus.pureExternalDoc" - }, - children: [ - { - path: "/external", - name: "https://pure-admin.github.io/pure-admin-doc", - meta: { - title: "menus.pureExternalLink", - //roles: ["admin", "common"] - } - }, - { - path: "/pureUtilsLink", - name: "https://pure-admin-utils.netlify.app/", - meta: { - title: "menus.pureUtilsLink", - //roles: ["admin", "common"] - } - } - ] - } - ] -}; - -const tabsRouter = { - path: "/tabs", - meta: { - icon: "ri:bookmark-2-line", - title: "menus.pureTabs", - rank: tabs - }, - children: [ - { - path: "/tabs/index", - name: "Tabs", - meta: { - title: "menus.pureTabs", - //roles: ["admin", "common"] - } - }, - // query 传参模式 - { - path: "/tabs/query-detail", - name: "TabQueryDetail", - meta: { - // 不在menu菜单中显示 - showLink: false, - activePath: "/tabs/index", - //roles: ["admin", "common"] - } - }, - // params 传参模式 - { - path: "/tabs/params-detail/:id", - component: "params-detail", - name: "TabParamsDetail", - meta: { - // 不在menu菜单中显示 - showLink: false, - activePath: "/tabs/index", - //roles: ["admin", "common"] - } - } - ] -}; +// +// const permissionRouter = { +// path: "/permission", +// meta: { +// title: "menus.purePermission", +// icon: "ep:lollipop", +// rank: permission +// }, +// children: [ +// { +// path: "/permission/page/index", +// name: "PermissionPage", +// meta: { +// title: "menus.purePermissionPage" +// //roles: ["admin", "common"] +// } +// }, +// { +// path: "/permission/button", +// meta: { +// title: "menus.purePermissionButton" +// //roles: ["admin", "common"] +// }, +// children: [ +// { +// path: "/permission/button/router", +// component: "permission/button/index", +// name: "PermissionButtonRouter", +// meta: { +// title: "menus.purePermissionButtonRouter", +// auths: [ +// "permission:btn:add", +// "permission:btn:edit", +// "permission:btn:delete" +// ] +// } +// }, +// { +// path: "/permission/button/login", +// component: "permission/button/perms", +// name: "PermissionButtonLogin", +// meta: { +// title: "menus.purePermissionButtonLogin" +// } +// } +// ] +// } +// ] +// }; +// +// const frameRouter = { +// path: "/iframe", +// meta: { +// icon: "ri:links-fill", +// title: "menus.pureExternalPage", +// rank: frame +// }, +// children: [ +// { +// path: "/iframe/embedded", +// meta: { +// title: "menus.pureEmbeddedDoc" +// }, +// children: [ +// { +// path: "/iframe/colorhunt", +// name: "FrameColorHunt", +// meta: { +// title: "menus.pureColorHuntDoc", +// frameSrc: "https://colorhunt.co/", +// keepAlive: true +// //roles: ["admin", "common"] +// } +// }, +// { +// path: "/iframe/uigradients", +// name: "FrameUiGradients", +// meta: { +// title: "menus.pureUiGradients", +// frameSrc: "https://uigradients.com/", +// keepAlive: true +// //roles: ["admin", "common"] +// } +// }, +// { +// path: "/iframe/ep", +// name: "FrameEp", +// meta: { +// title: "menus.pureEpDoc", +// frameSrc: "https://element-plus.org/zh-CN/", +// keepAlive: true +// //roles: ["admin", "common"] +// } +// }, +// { +// path: "/iframe/tailwindcss", +// name: "FrameTailwindcss", +// meta: { +// title: "menus.pureTailwindcssDoc", +// frameSrc: "https://tailwindcss.com/docs/installation", +// keepAlive: true +// //roles: ["admin", "common"] +// } +// }, +// { +// path: "/iframe/vue3", +// name: "FrameVue", +// meta: { +// title: "menus.pureVueDoc", +// frameSrc: "https://cn.vuejs.org/", +// keepAlive: true +// //roles: ["admin", "common"] +// } +// }, +// { +// path: "/iframe/vite", +// name: "FrameVite", +// meta: { +// title: "menus.pureViteDoc", +// frameSrc: "https://cn.vitejs.dev/", +// keepAlive: true +// //roles: ["admin", "common"] +// } +// }, +// { +// path: "/iframe/pinia", +// name: "FramePinia", +// meta: { +// title: "menus.purePiniaDoc", +// frameSrc: "https://pinia.vuejs.org/zh/index.html", +// keepAlive: true +// //roles: ["admin", "common"] +// } +// }, +// { +// path: "/iframe/vue-router", +// name: "FrameRouter", +// meta: { +// title: "menus.pureRouterDoc", +// frameSrc: "https://router.vuejs.org/zh/", +// keepAlive: true +// //roles: ["admin", "common"] +// } +// } +// ] +// }, +// { +// path: "/iframe/external", +// meta: { +// title: "menus.pureExternalDoc" +// }, +// children: [ +// { +// path: "/external", +// name: "https://pure-admin.github.io/pure-admin-doc", +// meta: { +// title: "menus.pureExternalLink" +// //roles: ["admin", "common"] +// } +// }, +// { +// path: "/pureUtilsLink", +// name: "https://pure-admin-utils.netlify.app/", +// meta: { +// title: "menus.pureUtilsLink" +// //roles: ["admin", "common"] +// } +// } +// ] +// } +// ] +// }; +// +// const tabsRouter = { +// path: "/tabs", +// meta: { +// icon: "ri:bookmark-2-line", +// title: "menus.pureTabs", +// rank: tabs +// }, +// children: [ +// { +// path: "/tabs/index", +// name: "Tabs", +// meta: { +// title: "menus.pureTabs" +// //roles: ["admin", "common"] +// } +// }, +// // query 传参模式 +// { +// path: "/tabs/query-detail", +// name: "TabQueryDetail", +// meta: { +// // 不在menu菜单中显示 +// showLink: false, +// activePath: "/tabs/index" +// //roles: ["admin", "common"] +// } +// }, +// // params 传参模式 +// { +// path: "/tabs/params-detail/:id", +// component: "params-detail", +// name: "TabParamsDetail", +// meta: { +// // 不在menu菜单中显示 +// showLink: false, +// activePath: "/tabs/index" +// //roles: ["admin", "common"] +// } +// } +// ] +// }; export default defineFakeRoute([ { @@ -336,7 +336,7 @@ export default defineFakeRoute([ response: () => { return [ systemManagementRouter, - systemMonitorRouter, + systemMonitorRouter //permissionRouter, // frameRouter, // tabsRouter diff --git a/Yi.Pure.Vue3/src/api/file.ts b/Yi.Pure.Vue3/src/api/file.ts new file mode 100644 index 00000000..d0c43d6d --- /dev/null +++ b/Yi.Pure.Vue3/src/api/file.ts @@ -0,0 +1,12 @@ +import { http } from "@/utils/http"; +import type { ResultFile } from "@/api/result"; + +/** 上传文件*/ +export const uploadFile = (data?: object) => { + return http.request("post", "/file", { + headers: { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + data + }); +}; diff --git a/Yi.Pure.Vue3/src/api/result.ts b/Yi.Pure.Vue3/src/api/result.ts index 8925761f..e359b512 100644 --- a/Yi.Pure.Vue3/src/api/result.ts +++ b/Yi.Pure.Vue3/src/api/result.ts @@ -17,3 +17,10 @@ export type ResultPage = { totalCount?: number; }; }; + +export type ResultFile = { + status: number; + data?: Array<{ + id: string; + }>; +}; diff --git a/Yi.Pure.Vue3/src/api/system/post.ts b/Yi.Pure.Vue3/src/api/system/post.ts index ecef3ffb..57cb3568 100644 --- a/Yi.Pure.Vue3/src/api/system/post.ts +++ b/Yi.Pure.Vue3/src/api/system/post.ts @@ -28,7 +28,7 @@ export const updatePostStatus = (id, state) => { /** 删除岗位 */ export const delPost = ids => { - return http.request("delete", `/post`, { params: { id:ids } }); + return http.request("delete", `/post`, { params: { id: ids } }); }; /** 获取岗位选择框列表 */ diff --git a/Yi.Pure.Vue3/src/api/system/user.ts b/Yi.Pure.Vue3/src/api/system/user.ts index a1c8b9b4..6d7ae78d 100644 --- a/Yi.Pure.Vue3/src/api/system/user.ts +++ b/Yi.Pure.Vue3/src/api/system/user.ts @@ -42,7 +42,7 @@ export const addUser = (data: any) => { /** 查询用户个人信息 */ export const getUserProfile = () => { - return http.request("get", `/account`, {}); + return http.request("get", `/account`, {}); }; /** 修改用户个人信息 */ @@ -63,3 +63,29 @@ export const updateUserPwd = (oldPassword, newPassword) => { }; return http.request("put", `/account/password`, { data }); }; + +export type UserInfoResult = { + status: number; + data: UserInfo; +}; + +export type UserInfo = { + user: { + /** 头像 */ + icon: string; + /** 用户名 */ + userName: string; + /** 昵称 */ + nick: string; + /** 邮箱 */ + email: string; + /** 联系电话 */ + phone: string; + /** 简介 */ + introduction: string; + }; + /** 当前登录用户的角色 */ + roleCodes: Array; + /** 按钮级别权限 */ + permissions: Array; +}; diff --git a/Yi.Pure.Vue3/src/api/user.ts b/Yi.Pure.Vue3/src/api/user.ts index 3464b3fc..c3afcf62 100644 --- a/Yi.Pure.Vue3/src/api/user.ts +++ b/Yi.Pure.Vue3/src/api/user.ts @@ -55,40 +55,6 @@ export type RefreshTokenResult = { }; }; -export type UserInfo = { - /** 头像 */ - avatar: string; - /** 用户名 */ - username: string; - /** 昵称 */ - nickname: string; - /** 邮箱 */ - email: string; - /** 联系电话 */ - phone: string; - /** 简介 */ - description: string; -}; - -export type UserInfoResult = { - success: boolean; - data: UserInfo; -}; - -type ResultTable = { - success: boolean; - data?: { - /** 列表数据 */ - list: Array; - /** 总条目数 */ - total?: number; - /** 每页显示条目个数 */ - pageSize?: number; - /** 当前页数 */ - currentPage?: number; - }; -}; - /** 登录 */ export const getLogin = (data?: object) => { return http.request("post", "/account/login", { data }); @@ -107,13 +73,3 @@ export const getCodeImg = () => { export const refreshTokenApi = (data?: object) => { return http.request("post", "/refresh-token", { data }); }; - -/** 账户设置-个人信息 */ -export const getMine = (data?: object) => { - return http.request("get", "/mine", { data }); -}; - -/** 账户设置-个人安全日志 */ -export const getMineLogs = (data?: object) => { - return http.request("get", "/mine-logs", { data }); -}; diff --git a/Yi.Pure.Vue3/src/layout/hooks/useNav.ts b/Yi.Pure.Vue3/src/layout/hooks/useNav.ts index 5e1f9009..7be7eb62 100644 --- a/Yi.Pure.Vue3/src/layout/hooks/useNav.ts +++ b/Yi.Pure.Vue3/src/layout/hooks/useNav.ts @@ -14,7 +14,7 @@ import { useUserStoreHook } from "@/store/modules/user"; import { useGlobal, isAllEmpty } from "@pureadmin/utils"; import { useEpThemeStoreHook } from "@/store/modules/epTheme"; import { usePermissionStoreHook } from "@/store/modules/permission"; -import {getFileUrl} from "@/utils/file" +import { getFileUrl } from "@/utils/file"; import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill"; import Fullscreen from "@iconify-icons/ri/fullscreen-fill"; @@ -41,7 +41,7 @@ export function useNav() { /** 头像(如果头像为空则使用 src/assets/user.jpg ) */ const userAvatar = computed(() => { - return getFileUrl(useUserStoreHook()?.avatar,Avatar); + return getFileUrl(useUserStoreHook()?.avatar, Avatar); }); /** 昵称(如果昵称为空则显示用户名) */ diff --git a/Yi.Pure.Vue3/src/utils/file.ts b/Yi.Pure.Vue3/src/utils/file.ts index fe6e61cf..1da203f8 100644 --- a/Yi.Pure.Vue3/src/utils/file.ts +++ b/Yi.Pure.Vue3/src/utils/file.ts @@ -1,4 +1,4 @@ -import {isAllEmpty} from "@pureadmin/utils"; +import { isAllEmpty } from "@pureadmin/utils"; export function getFileUrl(fileId: string, tryPath: string): string { if (isAllEmpty(fileId)) { diff --git a/Yi.Pure.Vue3/src/utils/http/index.ts b/Yi.Pure.Vue3/src/utils/http/index.ts index f9f8677b..8f765af6 100644 --- a/Yi.Pure.Vue3/src/utils/http/index.ts +++ b/Yi.Pure.Vue3/src/utils/http/index.ts @@ -3,17 +3,13 @@ import Axios, { type AxiosRequestConfig, type CustomParamsSerializer } from "axios"; -import type { - PureHttpError, - RequestMethods, - PureHttpRequestConfig -} from "./types.d"; +import type { RequestMethods, PureHttpRequestConfig } from "./types.d"; import { stringify } from "qs"; import NProgress from "../progress"; import { getToken, formatToken } from "@/utils/auth"; import { useUserStoreHook } from "@/store/modules/user"; -import {message} from "@/utils/message"; -import { transformI18n } from "@/plugins/i18n"; +import { message } from "@/utils/message"; +// import { transformI18n } from "@/plugins/i18n"; // 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1 const defaultConfig: AxiosRequestConfig = { baseURL: import.meta.env.VITE_APP_BASE_API, @@ -142,7 +138,7 @@ class PureHttp { // 关闭进度条动画 NProgress.done(); // 所有的响应异常 区分来源为取消请求/非取消请求 - return Promise.reject($error); + return Promise.reject($error); } ); } diff --git a/Yi.Pure.Vue3/src/views/account-settings/components/AccountManagement.vue b/Yi.Pure.Vue3/src/views/account-settings/components/AccountManagement.vue index 837f6a7b..f272cb68 100644 --- a/Yi.Pure.Vue3/src/views/account-settings/components/AccountManagement.vue +++ b/Yi.Pure.Vue3/src/views/account-settings/components/AccountManagement.vue @@ -12,27 +12,30 @@ const list = ref([ title: "账户密码", illustrate: "当前密码强度:强", button: "修改" - }, - { - title: "密保手机", - illustrate: "已经绑定手机:158****6789", - button: "修改" - }, - { - title: "密保问题", - illustrate: "未设置密保问题,密保问题可有效保护账户安全", - button: "修改" - }, - { - title: "备用邮箱", - illustrate: "已绑定邮箱:pure***@163.com", - button: "修改" } + // { + // title: "密保手机", + // illustrate: "已经绑定手机:158****6789", + // button: "修改" + // }, + // { + // title: "密保问题", + // illustrate: "未设置密保问题,密保问题可有效保护账户安全", + // button: "修改" + // }, + // { + // title: "备用邮箱", + // illustrate: "已绑定邮箱:pure***@163.com", + // button: "修改" + // } ]); function onClick(item) { - console.log("onClick", item.title); - message("请根据具体业务自行实现", { type: "success" }); + switch (item.title) { + case "账户密码": + message("密码更改成功", { type: "success" }); + break; + } } diff --git a/Yi.Pure.Vue3/src/views/account-settings/components/Profile.vue b/Yi.Pure.Vue3/src/views/account-settings/components/Profile.vue index bde496a2..c5606524 100644 --- a/Yi.Pure.Vue3/src/views/account-settings/components/Profile.vue +++ b/Yi.Pure.Vue3/src/views/account-settings/components/Profile.vue @@ -2,11 +2,19 @@ import { reactive, ref } from "vue"; import { formUpload } from "@/api/mock"; import { message } from "@/utils/message"; -import { type UserInfo, getMine } from "@/api/user"; import type { FormInstance, FormRules } from "element-plus"; import ReCropperPreview from "@/components/ReCropperPreview"; import { createFormData, deviceDetection } from "@pureadmin/utils"; import uploadLine from "@iconify-icons/ri/upload-line"; +import { useUserStoreHook } from "@/store/modules/user"; +import { + getUserProfile, + updateUserIcon, + updateUserProfile +} from "@/api/system/user"; +import userAvatar from "@/assets/user.jpg"; +import { getFileUrl } from "@/utils/file"; +import { uploadFile } from "@/api/file"; defineOptions({ name: "Profile" @@ -20,15 +28,16 @@ const isShow = ref(false); const userInfoFormRef = ref(); const userInfos = reactive({ - avatar: "", - nickname: "", + icon: "", + nick: "", email: "", phone: "", - description: "" + introduction: "" }); -const rules = reactive>({ - nickname: [{ required: true, message: "昵称必填", trigger: "blur" }] +const rules = reactive({ + userName: [{ required: true, message: "用户名必填", trigger: "blur" }], + nick: [{ required: true, message: "昵称必填", trigger: "blur" }] }); function queryEmail(queryString, callback) { @@ -70,11 +79,13 @@ const onCropper = ({ blob }) => (cropperBlob.value = blob); const handleSubmitImage = () => { const formData = createFormData({ - files: new File([cropperBlob.value], "avatar") + files: new File([cropperBlob.value], "file") }); - formUpload(formData) - .then(({ success, data }) => { - if (success) { + uploadFile(formData) + .then(async ({ status, data }) => { + if (status == 200) { + await updateUserIcon(data[0].id); + useUserStoreHook().SET_AVATAR(data[0].id); message("更新头像成功", { type: "success" }); handleClose(); } else { @@ -88,18 +99,17 @@ const handleSubmitImage = () => { // 更新信息 const onSubmit = async (formEl: FormInstance) => { - await formEl.validate((valid, fields) => { + await formEl.validate(async (valid, fields) => { if (valid) { - console.log(userInfos); + await updateUserProfile(userInfos); message("更新信息成功", { type: "success" }); } else { console.log("error submit!", fields); } }); }; - -getMine().then(res => { - Object.assign(userInfos, res.data); +getUserProfile().then(res => { + Object.assign(userInfos, res.data.user); }); @@ -118,7 +128,7 @@ getMine().then(res => { :model="userInfos" > - + { - + { import dayjs from "dayjs"; -import { getMineLogs } from "@/api/user"; +// import { getMineLogs } from "@/api/user"; import { reactive, ref, onMounted } from "vue"; import { deviceDetection } from "@pureadmin/utils"; import type { PaginationProps } from "@pureadmin/table"; @@ -55,11 +55,11 @@ const columns: TableColumnList = [ async function onSearch() { loading.value = true; - const { data } = await getMineLogs(); - dataList.value = data.list; - pagination.total = data.total; - pagination.pageSize = data.pageSize; - pagination.currentPage = data.currentPage; + // const { data } = await getMineLogs(); + // dataList.value = data.list; + // pagination.total = data.total; + // pagination.pageSize = data.pageSize; + // pagination.currentPage = data.currentPage; setTimeout(() => { loading.value = false; diff --git a/Yi.Pure.Vue3/src/views/account-settings/index.vue b/Yi.Pure.Vue3/src/views/account-settings/index.vue index 4a59c3a4..8ff811af 100644 --- a/Yi.Pure.Vue3/src/views/account-settings/index.vue +++ b/Yi.Pure.Vue3/src/views/account-settings/index.vue @@ -1,5 +1,4 @@ @@ -84,13 +86,13 @@ getMine().then(res => {
- +
- {{ userInfo.nickname }} + {{ userInfo.nick }} - {{ userInfo.username }} + {{ userInfo.nick }}
diff --git a/Yi.Pure.Vue3/src/views/login/index.vue b/Yi.Pure.Vue3/src/views/login/index.vue index 3f1039bd..5f0dc784 100644 --- a/Yi.Pure.Vue3/src/views/login/index.vue +++ b/Yi.Pure.Vue3/src/views/login/index.vue @@ -248,7 +248,7 @@ getCode(); :src="codeUrl" width="120" height="40" - style="width: 120px; height: 40px;max-width: none; " + style="width: 120px; height: 40px; max-width: none" class="cursor-pointer" alt="" @click="getCode" diff --git a/Yi.Pure.Vue3/src/views/monitor/logs/login/hook.tsx b/Yi.Pure.Vue3/src/views/monitor/logs/login/hook.tsx index 1d91287b..0d253a80 100644 --- a/Yi.Pure.Vue3/src/views/monitor/logs/login/hook.tsx +++ b/Yi.Pure.Vue3/src/views/monitor/logs/login/hook.tsx @@ -66,7 +66,7 @@ export function useRole(tableRef: Ref) { label: "登录状态", prop: "state", minWidth: 100, - cellRenderer: ({ row, props }) => ( + cellRenderer: ({ props }) => ( {1 === 1 ? "成功" : "失败"} diff --git a/Yi.Pure.Vue3/src/views/monitor/logs/login/index.vue b/Yi.Pure.Vue3/src/views/monitor/logs/login/index.vue index a74448bb..87963543 100644 --- a/Yi.Pure.Vue3/src/views/monitor/logs/login/index.vue +++ b/Yi.Pure.Vue3/src/views/monitor/logs/login/index.vue @@ -85,11 +85,7 @@ const {
- + diff --git a/Yi.Pure.Vue3/src/views/system/post/utils/hook.tsx b/Yi.Pure.Vue3/src/views/system/post/utils/hook.tsx index 0769a5e9..4cb88611 100644 --- a/Yi.Pure.Vue3/src/views/system/post/utils/hook.tsx +++ b/Yi.Pure.Vue3/src/views/system/post/utils/hook.tsx @@ -1,13 +1,13 @@ import dayjs from "dayjs"; import editForm from "../form.vue"; -import {message} from "@/utils/message"; -import {ElMessageBox} from "element-plus"; -import {usePublicHooks} from "../../hooks"; -import {transformI18n} from "@/plugins/i18n"; -import {addDialog} from "@/components/ReDialog"; -import type {FormItemProps} from "../utils/types"; -import type {PaginationProps} from "@pureadmin/table"; -import {getKeyList, deviceDetection} from "@pureadmin/utils"; +import { message } from "@/utils/message"; +import { ElMessageBox } from "element-plus"; +import { usePublicHooks } from "../../hooks"; +import { transformI18n } from "@/plugins/i18n"; +import { addDialog } from "@/components/ReDialog"; +import type { FormItemProps } from "../utils/types"; +import type { PaginationProps } from "@pureadmin/table"; +import { deviceDetection } from "@pureadmin/utils"; import { getPostList, addPost, @@ -15,20 +15,11 @@ import { delPost, getPost, updatePostStatus -} from "@/api/system/post" +} from "@/api/system/post"; -import { - type Ref, - reactive, - ref, - onMounted, - h, - toRaw, - watch, - nextTick -} from "vue"; +import { reactive, ref, onMounted, h, toRaw } from "vue"; -export function usePost(treeRef: Ref) { +export function usePost() { const form = reactive({ postName: "", postCode: "", @@ -39,7 +30,6 @@ export function usePost(treeRef: Ref) { const curRow = ref(); const formRef = ref(); const dataList = ref([]); - const treeIds = ref([]); const treeData = ref([]); const isShow = ref(false); const loading = ref(true); @@ -48,7 +38,7 @@ export function usePost(treeRef: Ref) { const switchLoadMap = ref({}); const isExpandAll = ref(false); const isSelectAll = ref(false); - const {switchStyle} = usePublicHooks(); + const { switchStyle } = usePublicHooks(); const pagination = reactive({ total: 0, pageSize: 10, @@ -86,7 +76,7 @@ export function usePost(treeRef: Ref) { ), minWidth: 90 }, - {label:"排序",prop:"orderNum"}, + { label: "排序", prop: "orderNum" }, { label: "备注", prop: "remark", @@ -96,7 +86,7 @@ export function usePost(treeRef: Ref) { label: "创建时间", prop: "creationTime", minWidth: 160, - formatter: ({creationTime}) => + formatter: ({ creationTime }) => dayjs(creationTime).format("YYYY-MM-DD HH:mm:ss") }, { @@ -107,7 +97,7 @@ export function usePost(treeRef: Ref) { } ]; - async function onChange({row, index}) { + async function onChange({ row, index }) { ElMessageBox.confirm( `确认要${ row.state === false ? "停用" : "启用" @@ -152,7 +142,7 @@ export function usePost(treeRef: Ref) { async function handleDelete(row) { await delPost([row.id]); - message(`您删除了角色名称为${row.roleName}的这条数据`, {type: "success"}); + message(`您删除了角色名称为${row.roleName}的这条数据`, { type: "success" }); onSearch(); } @@ -172,7 +162,7 @@ export function usePost(treeRef: Ref) { async function onSearch() { loading.value = true; - const {data} = await getPostList(toRaw(form)); + const { data } = await getPostList(toRaw(form)); dataList.value = data.items; pagination.total = data.totalCount; loading.value = false; @@ -196,7 +186,7 @@ export function usePost(treeRef: Ref) { postName: row?.postName ?? "", postCode: row?.postCode ?? "", remark: row?.remark ?? "", - orderNum: data?.orderNum ?? 0, + orderNum: data?.orderNum ?? 0 } }, width: "40%", @@ -204,8 +194,8 @@ export function usePost(treeRef: Ref) { fullscreen: deviceDetection(), fullscreenIcon: true, closeOnClickModal: false, - contentRenderer: () => h(editForm, {ref: formRef}), - beforeSure: (done, {options}) => { + contentRenderer: () => h(editForm, { ref: formRef }), + beforeSure: (done, { options }) => { const FormRef = formRef.value.getRef(); const curData = options.props.formInline as FormItemProps; @@ -236,7 +226,7 @@ export function usePost(treeRef: Ref) { } /** 高亮当前权限选中行 */ - function rowStyle({row: {id}}) { + function rowStyle({ row: { id } }) { return { cursor: "pointer", background: id === curRow.value?.id ? "var(--el-fill-color-light)" : "" @@ -244,11 +234,7 @@ export function usePost(treeRef: Ref) { } /** 数据权限 可自行开发 */ - // function handleDatabase() {} - - const onQueryChanged = (query: string) => { - treeRef.value!.filter(query); - }; + // function handleDatabase() {} const filterMethod = (query: string, node) => { return transformI18n(node.title)!.includes(query); @@ -258,18 +244,6 @@ export function usePost(treeRef: Ref) { onSearch(); }); - watch(isExpandAll, val => { - val - ? treeRef.value.setExpandedKeys(treeIds.value) - : treeRef.value.setExpandedKeys([]); - }); - - watch(isSelectAll, val => { - val - ? treeRef.value.setCheckedKeys(treeIds.value) - : treeRef.value.setCheckedKeys([]); - }); - return { form, isShow, @@ -290,7 +264,6 @@ export function usePost(treeRef: Ref) { handleDelete, filterMethod, transformI18n, - onQueryChanged, handleSizeChange, handleCurrentChange, handleSelectionChange diff --git a/Yi.Pure.Vue3/src/views/system/post/utils/types.ts b/Yi.Pure.Vue3/src/views/system/post/utils/types.ts index f0ce33fc..9737f698 100644 --- a/Yi.Pure.Vue3/src/views/system/post/utils/types.ts +++ b/Yi.Pure.Vue3/src/views/system/post/utils/types.ts @@ -9,7 +9,6 @@ interface FormItemProps { /** 备注 */ remark: string; orderNum: number; - } interface FormProps { formInline: FormItemProps; diff --git a/Yi.Pure.Vue3/src/views/system/role/utils/hook.tsx b/Yi.Pure.Vue3/src/views/system/role/utils/hook.tsx index 2ba8af1b..8ea4b233 100644 --- a/Yi.Pure.Vue3/src/views/system/role/utils/hook.tsx +++ b/Yi.Pure.Vue3/src/views/system/role/utils/hook.tsx @@ -16,8 +16,7 @@ import { updateRole, changeRoleStatus, delRole, - getRoleMenuSelect, - updataDataScope + getRoleMenuSelect } from "@/api/system/role"; import { getMenuOption } from "@/api/system/menu"; diff --git a/Yi.Pure.Vue3/src/views/system/user/index.vue b/Yi.Pure.Vue3/src/views/system/user/index.vue index 6f5bcb69..85a897b6 100644 --- a/Yi.Pure.Vue3/src/views/system/user/index.vue +++ b/Yi.Pure.Vue3/src/views/system/user/index.vue @@ -6,7 +6,6 @@ import { PureTableBar } from "@/components/RePureTableBar"; import { useRenderIcon } from "@/components/ReIcon/src/hooks"; import Upload from "@iconify-icons/ri/upload-line"; -import Role from "@iconify-icons/ri/admin-line"; import Password from "@iconify-icons/ri/lock-password-line"; import More from "@iconify-icons/ep/more-filled"; import Delete from "@iconify-icons/ep/delete"; diff --git a/Yi.Pure.Vue3/src/views/system/user/utils/hook.tsx b/Yi.Pure.Vue3/src/views/system/user/utils/hook.tsx index 94b79d35..84292afa 100644 --- a/Yi.Pure.Vue3/src/views/system/user/utils/hook.tsx +++ b/Yi.Pure.Vue3/src/views/system/user/utils/hook.tsx @@ -1,16 +1,16 @@ import "./reset.css"; import dayjs from "dayjs"; import editForm from "../form/index.vue"; -import {zxcvbn} from "@zxcvbn-ts/core"; -import {handleTree} from "@/utils/tree"; -import {message} from "@/utils/message"; +import { zxcvbn } from "@zxcvbn-ts/core"; +import { handleTree } from "@/utils/tree"; +import { message } from "@/utils/message"; import userAvatar from "@/assets/user.jpg"; -import {getFileUrl} from "@/utils/file" -import {usePublicHooks} from "../../hooks"; -import {addDialog} from "@/components/ReDialog"; -import type {PaginationProps} from "@pureadmin/table"; +import { getFileUrl } from "@/utils/file"; +import { usePublicHooks } from "../../hooks"; +import { addDialog } from "@/components/ReDialog"; +import type { PaginationProps } from "@pureadmin/table"; import ReCropperPreview from "@/components/ReCropperPreview"; -import type {FormItemProps} from "../utils/types"; +import type { FormItemProps } from "../utils/types"; import { getKeyList, isAllEmpty, @@ -26,8 +26,8 @@ import { updateUser, getUserList } from "@/api/system/user"; -import {getRoleOption} from "@/api/system/role"; -import {getDeptList} from "@/api/system/dept"; +import { getRoleOption } from "@/api/system/role"; +import { getDeptList } from "@/api/system/dept"; import { ElForm, ElInput, @@ -63,7 +63,7 @@ export function useUser(tableRef: Ref, treeRef: Ref) { // 上传头像信息 const avatarInfo = ref(); const switchLoadMap = ref({}); - const {switchStyle} = usePublicHooks(); + const { switchStyle } = usePublicHooks(); const higherDeptOptions = ref(); const treeData = ref([]); const treeLoading = ref(true); @@ -89,12 +89,12 @@ export function useUser(tableRef: Ref, treeRef: Ref) { { label: "用户头像", prop: "avatar", - cellRenderer: ({row}) => ( + cellRenderer: ({ row }) => ( ), @@ -114,7 +114,7 @@ export function useUser(tableRef: Ref, treeRef: Ref) { label: "性别", prop: "sex", minWidth: 90, - cellRenderer: ({row, props}) => ( + cellRenderer: ({ row, props }) => ( - phone == null ? "-" : hideTextAtIndex(phone, {start: 3, end: 6}) + formatter: ({ phone }) => + phone == null ? "-" : hideTextAtIndex(phone, { start: 3, end: 6 }) }, { label: "状态", @@ -159,7 +159,7 @@ export function useUser(tableRef: Ref, treeRef: Ref) { label: "创建时间", minWidth: 90, prop: "creationTime", - formatter: ({creationTime}) => + formatter: ({ creationTime }) => dayjs(creationTime).format("YYYY-MM-DD HH:mm:ss") }, { @@ -183,17 +183,17 @@ export function useUser(tableRef: Ref, treeRef: Ref) { password: "" }); const pwdProgress = [ - {color: "#e74242", text: "非常弱"}, - {color: "#EFBD47", text: "弱"}, - {color: "#ffa500", text: "一般"}, - {color: "#1bbf1b", text: "强"}, - {color: "#008000", text: "非常强"} + { color: "#e74242", text: "非常弱" }, + { color: "#EFBD47", text: "弱" }, + { color: "#ffa500", text: "一般" }, + { color: "#1bbf1b", text: "强" }, + { color: "#008000", text: "非常强" } ]; // 当前密码强度(0-4) const curScore = ref(); const roleOptions = ref([]); - function onChange({row, index}) { + function onChange({ row, index }) { ElMessageBox.confirm( `确认要${ row.state === 0 ? "停用" : "启用" @@ -242,7 +242,7 @@ export function useUser(tableRef: Ref, treeRef: Ref) { async function handleDelete(row) { await delUser([row.id]); - message(`您删除了用户编号为${row.id}的这条数据`, {type: "success"}); + message(`您删除了用户编号为${row.id}的这条数据`, { type: "success" }); onSearch(); } @@ -286,7 +286,7 @@ export function useUser(tableRef: Ref, treeRef: Ref) { async function onSearch() { loading.value = true; - const {data} = await getUserList(toRaw(form)); + const { data } = await getUserList(toRaw(form)); dataList.value = data.items; pagination.total = data.totalCount; // pagination.pageSize = data.pageSize; @@ -305,7 +305,7 @@ export function useUser(tableRef: Ref, treeRef: Ref) { onSearch(); }; - function onTreeSelect({id, selected}) { + function onTreeSelect({ id, selected }) { form.deptId = selected ? id : ""; onSearch(); } @@ -353,8 +353,8 @@ export function useUser(tableRef: Ref, treeRef: Ref) { fullscreen: deviceDetection(), fullscreenIcon: true, closeOnClickModal: false, - contentRenderer: () => h(editForm, {ref: formRef}), - beforeSure: (done, {options}) => { + contentRenderer: () => h(editForm, { ref: formRef }), + beforeSure: (done, { options }) => { const FormRef = formRef.value.getRef(); const curData = options.props.formInline as FormItemProps; @@ -411,7 +411,7 @@ export function useUser(tableRef: Ref, treeRef: Ref) { watch( pwdForm, - ({password}) => + ({ password }) => (curScore.value = isAllEmpty(password) ? -1 : zxcvbn(password).score) ); @@ -446,10 +446,10 @@ export function useUser(tableRef: Ref, treeRef: Ref) {
- {pwdProgress.map(({color, text}, idx) => ( + {pwdProgress.map(({ color, text }, idx) => (

{text}

@@ -494,7 +494,7 @@ export function useUser(tableRef: Ref, treeRef: Ref) { onSearch(); // 归属部门 - const {data} = await getDeptList(); + const { data } = await getDeptList(); higherDeptOptions.value = handleTree(data.items); treeData.value = handleTree(data.items); treeLoading.value = false;