page: 📄 用户修改账户信息页面
This commit is contained in:
parent
6ef4e73842
commit
a9a2a140fb
|
@ -29,17 +29,12 @@ export interface RefreshTokenResult {
|
||||||
expires: Date;
|
expires: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 登录 */
|
||||||
* 登录
|
|
||||||
*/
|
|
||||||
export const fetchLogin = (data?: object) => {
|
export const fetchLogin = (data?: object) => {
|
||||||
return http.request<BaseResult<UserResult>>('post', '/login', { data });
|
return http.request<BaseResult<UserResult>>('post', '/login', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 发送邮件 */
|
||||||
* * 发送邮件
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export const fetchPostEmailCode = (data: any) => {
|
export const fetchPostEmailCode = (data: any) => {
|
||||||
return http.request<BaseResult<any>>('post', '/user/noAuth/sendLoginEmail', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
return http.request<BaseResult<any>>('post', '/user/noAuth/sendLoginEmail', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
||||||
};
|
};
|
||||||
|
@ -49,90 +44,67 @@ export const refreshTokenApi = (data?: object) => {
|
||||||
return http.request<BaseResult<RefreshTokenResult>>('post', 'user/noAuth/refreshToken', { data });
|
return http.request<BaseResult<RefreshTokenResult>>('post', 'user/noAuth/refreshToken', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 退出账户 */
|
||||||
* * 退出内容
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export const fetchLogout = (data?: object) => {
|
export const fetchLogout = (data?: object) => {
|
||||||
return http.request<BaseResult<any>>('post', 'user/logout', { data });
|
return http.request<BaseResult<any>>('post', 'user/noManage/logout', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 获取用户信息,根据当前token获取 */
|
||||||
* 用户信息---获取用户信息列表
|
export const fetchGetUserinfo = () => {
|
||||||
*/
|
return http.request<BaseResult<any>>('get', 'user/noManage/getUserinfo');
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 用户信息---获取用户信息列表 */
|
||||||
export const fetchGetAdminUserList = (data: any) => {
|
export const fetchGetAdminUserList = (data: any) => {
|
||||||
return http.request<BaseResult<ResultTable>>('get', `user/getAdminUserList/${data.currentPage}/${data.pageSize}`, { params: data });
|
return http.request<BaseResult<ResultTable>>('get', `user/getAdminUserList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 用户信息---查询用户 */
|
||||||
* 查询用户
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export const fetchQueryUser = (data: any) => {
|
export const fetchQueryUser = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('get', 'user/queryUser', { params: data });
|
return http.request<BaseResult<object>>('get', 'user/noManage/queryUser', { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 用户信息---添加用户信息 */
|
||||||
* 用户信息---添加用户信息
|
|
||||||
*/
|
|
||||||
export const fetchAddAdminUser = (data: any) => {
|
export const fetchAddAdminUser = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('post', 'user/addAdminUser', { data });
|
return http.request<BaseResult<object>>('post', 'user/addAdminUser', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 用户信息---更新用户信息 */
|
||||||
* 用户信息---更新用户信息
|
|
||||||
*/
|
|
||||||
export const fetchUpdateAdminUser = (data: any) => {
|
export const fetchUpdateAdminUser = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('put', 'user/updateAdminUser', { data });
|
return http.request<BaseResult<object>>('put', 'user/updateAdminUser', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 用户信息---删除用户信息 */
|
||||||
* 用户信息---删除用户信息
|
|
||||||
*/
|
|
||||||
export const fetchDeleteAdminUser = (data: any) => {
|
export const fetchDeleteAdminUser = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('delete', 'user/deleteAdminUser', { data });
|
return http.request<BaseResult<object>>('delete', 'user/deleteAdminUser', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 用户管理---获取用户信息 */
|
||||||
* 获取用户信息
|
|
||||||
*/
|
|
||||||
export const fetchGetUserinfoById = (data?: object) => {
|
export const fetchGetUserinfoById = (data?: object) => {
|
||||||
return http.request<BaseResult<UserResult>>('get', 'user/getUserinfoById', { params: data });
|
return http.request<BaseResult<UserResult>>('get', 'user/getUserinfoById', { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 修改用户状态 */
|
/** 用户管理---修改用户状态 */
|
||||||
export const fetchUpdateUserStatusByAdmin = (data?: object) => {
|
export const fetchUpdateUserStatusByAdmin = (data?: object) => {
|
||||||
return http.request<BaseResult<UserResult>>('put', 'user/updateUserStatusByAdmin', { data });
|
return http.request<BaseResult<UserResult>>('put', 'user/updateUserStatusByAdmin', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 用户管理---管理员修改管理员用户密码 */
|
||||||
* 管理员修改管理员用户密码
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export const fetchUpdateUserPasswordByAdmin = (data: any) => {
|
export const fetchUpdateUserPasswordByAdmin = (data: any) => {
|
||||||
return http.request<BaseResult<UserResult>>('put', 'user/updateUserPasswordByAdmin', { data });
|
return http.request<BaseResult<UserResult>>('put', 'user/updateUserPasswordByAdmin', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 用户管理---管理员修改管理员用户头像 */
|
||||||
* 管理员修改管理员用户头像
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export const fetchUploadAvatarByAdmin = (data: any) => {
|
export const fetchUploadAvatarByAdmin = (data: any) => {
|
||||||
return http.request<BaseResult<UserResult>>('put', 'user/uploadAvatarByAdmin', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
return http.request<BaseResult<UserResult>>('put', 'user/uploadAvatarByAdmin', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 用户管理---强制用户下线 */
|
||||||
* 强制用户下线
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export const fetchForcedOffline = (data: any) => {
|
export const fetchForcedOffline = (data: any) => {
|
||||||
return http.request<BaseResult<UserResult>>('put', 'user/forcedOffline', { data });
|
return http.request<BaseResult<UserResult>>('put', 'user/forcedOffline', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 用户管理---为用户分配角色 */
|
||||||
* 为用户分配角色
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export const fetchAssignRolesToUsers = (data: object) => {
|
export const fetchAssignRolesToUsers = (data: object) => {
|
||||||
return http.request<BaseResult<any>>('post', 'userRole/assignRolesToUsers', { data });
|
return http.request<BaseResult<any>>('post', 'userRole/assignRolesToUsers', { data });
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,37 +1,27 @@
|
||||||
import { http } from '@/api/service/request';
|
import { http } from '@/api/service/request';
|
||||||
import type { BaseResult, ResultTable } from '@/api/service/types';
|
import type { BaseResult, ResultTable } from '@/api/service/types';
|
||||||
|
|
||||||
/**
|
/** 部门管理---获取部门管理列表 */
|
||||||
* 部门管理---获取部门管理列表
|
|
||||||
*/
|
|
||||||
export const fetchGetDeptList = (data: any) => {
|
export const fetchGetDeptList = (data: any) => {
|
||||||
return http.request<BaseResult<ResultTable>>('get', `dept/getDeptList/${data.currentPage}/${data.pageSize}`, { params: data });
|
return http.request<BaseResult<ResultTable>>('get', `dept/getDeptList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 部门管理---获取所有部门管理列表 */
|
||||||
* 部门管理---获取所有部门管理列表
|
|
||||||
*/
|
|
||||||
export const fetchGetAllDeptList = () => {
|
export const fetchGetAllDeptList = () => {
|
||||||
return http.request<BaseResult<object>>('get', 'dept/getAllDeptList');
|
return http.request<BaseResult<object>>('get', 'dept/getAllDeptList');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 部门管理---添加部门管理 */
|
||||||
* 部门管理---添加部门管理
|
|
||||||
*/
|
|
||||||
export const fetchAddDept = (data: any) => {
|
export const fetchAddDept = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('post', 'dept/addDept', { data });
|
return http.request<BaseResult<object>>('post', 'dept/addDept', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 部门管理---更新部门管理 */
|
||||||
* 部门管理---更新部门管理
|
|
||||||
*/
|
|
||||||
export const fetchUpdateDept = (data: any) => {
|
export const fetchUpdateDept = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('put', 'dept/updateDept', { data });
|
return http.request<BaseResult<object>>('put', 'dept/updateDept', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 部门管理---删除部门管理 */
|
||||||
* 部门管理---删除部门管理
|
|
||||||
*/
|
|
||||||
export const fetchDeleteDept = (data: any) => {
|
export const fetchDeleteDept = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('delete', 'dept/deleteDept', { data });
|
return http.request<BaseResult<object>>('delete', 'dept/deleteDept', { data });
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@ export const fetchGetEmailUsersList = (data: any) => {
|
||||||
|
|
||||||
/** 邮箱用户发送配置管理---获取所有邮箱配置用户 */
|
/** 邮箱用户发送配置管理---获取所有邮箱配置用户 */
|
||||||
export const fetchGetAllMailboxConfigurationUsers = () => {
|
export const fetchGetAllMailboxConfigurationUsers = () => {
|
||||||
return http.request<BaseResult<any>>('get', 'emailUsers/getAllMailboxConfigurationUsers');
|
return http.request<BaseResult<any>>('get', 'emailUsers/noManage/getAllMailboxConfigurationUsers');
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 邮箱用户发送配置管理---添加邮箱用户发送配置管理 */
|
/** 邮箱用户发送配置管理---添加邮箱用户发送配置管理 */
|
||||||
|
|
|
@ -18,10 +18,10 @@ export const downloadFilesByFilepath = (data: any) => {
|
||||||
|
|
||||||
/** 系统文件管理---获取所有文件类型 */
|
/** 系统文件管理---获取所有文件类型 */
|
||||||
export const fetchGetAllMediaTypes = () => {
|
export const fetchGetAllMediaTypes = () => {
|
||||||
return http.request<BaseResult<any>>('get', `files/getAllMediaTypes`);
|
return http.request<BaseResult<any>>('get', `files/noManage/getAllMediaTypes`);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 系统文件管理---获取所有文件类型 */
|
/** 系统文件管理---获取所有文件存储基础路径 */
|
||||||
export const fetchGetAllFilesStoragePath = () => {
|
export const fetchGetAllFilesStoragePath = () => {
|
||||||
return http.request<BaseResult<any>>('get', `files/getAllFilesStoragePath`);
|
return http.request<BaseResult<any>>('get', `files/getAllFilesStoragePath`);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,65 +1,47 @@
|
||||||
import { http } from '@/api/service/request';
|
import { http } from '@/api/service/request';
|
||||||
import type { BaseResult, ResultTable } from '@/api/service/types';
|
import type { BaseResult, ResultTable } from '@/api/service/types';
|
||||||
|
|
||||||
/**
|
/** 多语言类型管理---获取多语言内容 */
|
||||||
* * 获取多语言内容
|
|
||||||
*/
|
|
||||||
export const fetchGetI18n = () => {
|
export const fetchGetI18n = () => {
|
||||||
return http.request<BaseResult<object>>('get', 'i18n/getI18n');
|
return http.request<BaseResult<object>>('get', 'i18n/getI18n');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 多语言类型管理---获取多语言列表 */
|
||||||
* 多语言管理---获取多语言列表
|
|
||||||
*/
|
|
||||||
export const fetchGetI18nList = (data: any) => {
|
export const fetchGetI18nList = (data: any) => {
|
||||||
return http.request<BaseResult<ResultTable>>('get', `i18n/getI18nList/${data.currentPage}/${data.pageSize}`, { params: data });
|
return http.request<BaseResult<ResultTable>>('get', `i18n/getI18nList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 多语言类型管理---添加多语言 */
|
||||||
* 多语言管理---添加多语言
|
|
||||||
*/
|
|
||||||
export const fetchAddI18n = (data: any) => {
|
export const fetchAddI18n = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('post', 'i18n/addI18n', { data });
|
return http.request<BaseResult<object>>('post', 'i18n/addI18n', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 多语言类型管理---更新多语言 */
|
||||||
* 多语言管理---更新多语言
|
|
||||||
*/
|
|
||||||
export const fetchUpdateI18n = (data: any) => {
|
export const fetchUpdateI18n = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('put', 'i18n/updateI18n', { data });
|
return http.request<BaseResult<object>>('put', 'i18n/updateI18n', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 多语言类型管理---删除多语言 */
|
||||||
* 多语言管理---删除多语言
|
|
||||||
*/
|
|
||||||
export const fetchDeleteI18n = (data: any) => {
|
export const fetchDeleteI18n = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('delete', 'i18n/deleteI18n', { data });
|
return http.request<BaseResult<object>>('delete', 'i18n/deleteI18n', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 多语言类型管理---获取多语言类型列表 */
|
||||||
* 多语言类型管理---获取多语言类型列表
|
|
||||||
*/
|
|
||||||
export const fetchGetI18nTypeList = () => {
|
export const fetchGetI18nTypeList = () => {
|
||||||
return http.request<BaseResult<ResultTable>>('get', 'i18nType/noAuth/getI18nTypeList');
|
return http.request<BaseResult<ResultTable>>('get', 'i18nType/noAuth/getI18nTypeList');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 多语言类型管理---添加多语言类型 */
|
||||||
* 多语言类型管理---添加多语言类型
|
|
||||||
*/
|
|
||||||
export const fetchAddI18nType = (data: any) => {
|
export const fetchAddI18nType = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('post', 'i18nType/addI18nType', { data });
|
return http.request<BaseResult<object>>('post', 'i18nType/addI18nType', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 多语言类型管理---更新多语言类型 */
|
||||||
* 多语言类型管理---更新多语言类型
|
|
||||||
*/
|
|
||||||
export const fetchUpdateI18nType = (data: any) => {
|
export const fetchUpdateI18nType = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('put', 'i18nType/updateI18nType', { data });
|
return http.request<BaseResult<object>>('put', 'i18nType/updateI18nType', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 多语言类型管理---删除多语言类型 */
|
||||||
* 多语言类型管理---删除多语言类型
|
|
||||||
*/
|
|
||||||
export const fetchDeleteI18nType = (data: any) => {
|
export const fetchDeleteI18nType = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('delete', 'i18nType/deleteI18nType', { data });
|
return http.request<BaseResult<object>>('delete', 'i18nType/deleteI18nType', { data });
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,38 +1,27 @@
|
||||||
import { http } from '@/api/service/request';
|
import { http } from '@/api/service/request';
|
||||||
import type { BaseResult, ResultTable } from '@/api/service/types';
|
import type { BaseResult, ResultTable } from '@/api/service/types';
|
||||||
|
|
||||||
/**
|
/** 系统菜单图标---获取多语言列表 */
|
||||||
* 系统菜单图标---获取多语言列表
|
|
||||||
*/
|
|
||||||
export const fetchGetMenuIconList = (data: any) => {
|
export const fetchGetMenuIconList = (data: any) => {
|
||||||
return http.request<BaseResult<ResultTable>>('get', `menuIcon/getMenuIconList/${data.currentPage}/${data.pageSize}`, { params: data });
|
return http.request<BaseResult<ResultTable>>('get', `menuIcon/getMenuIconList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 系统菜单图标---添加多语言 */
|
||||||
* 系统菜单图标---添加多语言
|
|
||||||
*/
|
|
||||||
export const fetchAddMenuIcon = (data: any) => {
|
export const fetchAddMenuIcon = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('post', 'menuIcon/addMenuIcon', { data });
|
return http.request<BaseResult<object>>('post', 'menuIcon/addMenuIcon', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 系统菜单图标---更新多语言 */
|
||||||
* 系统菜单图标---更新多语言
|
|
||||||
*/
|
|
||||||
export const fetchUpdateMenuIcon = (data: any) => {
|
export const fetchUpdateMenuIcon = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('put', 'menuIcon/updateMenuIcon', { data });
|
return http.request<BaseResult<object>>('put', 'menuIcon/updateMenuIcon', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 系统菜单图标---删除多语言 */
|
||||||
* 系统菜单图标---删除多语言
|
|
||||||
*/
|
|
||||||
export const fetchDeleteMenuIcon = (data: any) => {
|
export const fetchDeleteMenuIcon = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('delete', 'menuIcon/deleteMenuIcon', { data });
|
return http.request<BaseResult<object>>('delete', 'menuIcon/deleteMenuIcon', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 系统菜单图标---根据iconName搜索menuIc */
|
||||||
* 系统菜单图标---根据iconName搜索menuIc
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
export const fetchGetIconNameList = (data: any) => {
|
export const fetchGetIconNameList = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('get', 'menuIcon/getIconNameList', { params: data });
|
return http.request<BaseResult<object>>('get', 'menuIcon/noManage/getIconNameList', { params: data });
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,10 +8,10 @@ export const fetchGetPowerList = (data: any) => {
|
||||||
|
|
||||||
/** 权限---根据角色id获取权限内容 */
|
/** 权限---根据角色id获取权限内容 */
|
||||||
export const fetchGetPowerListByRoleId = (data: any) => {
|
export const fetchGetPowerListByRoleId = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('get', 'rolePower/getPowerListByRoleId', { params: data });
|
return http.request<BaseResult<object>>('get', 'rolePower/noManage/getPowerListByRoleId', { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 获取所有权限 */
|
/** 权限---获取所有权限 */
|
||||||
export const fetchGetAllPowers = () => {
|
export const fetchGetAllPowers = () => {
|
||||||
return http.request<BaseResult<any>>('get', `power/getAllPowers`);
|
return http.request<BaseResult<any>>('get', `power/getAllPowers`);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,51 +1,37 @@
|
||||||
import { http } from '@/api/service/request';
|
import { http } from '@/api/service/request';
|
||||||
import type { BaseResult, ResultTable } from '@/api/service/types';
|
import type { BaseResult, ResultTable } from '@/api/service/types';
|
||||||
|
|
||||||
/**
|
/** 角色---获取角色列表 */
|
||||||
* 角色---获取角色列表
|
|
||||||
*/
|
|
||||||
export const fetchGetRoleList = (data: any) => {
|
export const fetchGetRoleList = (data: any) => {
|
||||||
return http.request<BaseResult<ResultTable>>('get', `role/getRoleList/${data.currentPage}/${data.pageSize}`, { params: data });
|
return http.request<BaseResult<ResultTable>>('get', `role/getRoleList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 角色---获取所有角色 */
|
||||||
* 获取所有角色
|
|
||||||
*/
|
|
||||||
export const fetchGetAllRoles = () => {
|
export const fetchGetAllRoles = () => {
|
||||||
return http.request<BaseResult<any>>('get', `role/getAllRoles`);
|
return http.request<BaseResult<any>>('get', `role/noManage/getAllRoles`);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 角色---根据用户id获取所有角色 */
|
||||||
* 根据用户id获取所有角色
|
|
||||||
*/
|
|
||||||
export const fetchGetRoleListByUserId = data => {
|
export const fetchGetRoleListByUserId = data => {
|
||||||
return http.request<BaseResult<any>>('get', `userRole/getRoleListByUserId`, { params: data });
|
return http.request<BaseResult<any>>('get', `userRole/getRoleListByUserId`, { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 角色---添加角色 */
|
||||||
* 角色---添加角色
|
|
||||||
*/
|
|
||||||
export const fetchAddRole = (data: any) => {
|
export const fetchAddRole = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('post', 'role/addRole', { data });
|
return http.request<BaseResult<object>>('post', 'role/addRole', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 角色---为角色分配权限 */
|
||||||
* 角色---为角色分配权限
|
|
||||||
*/
|
|
||||||
export const fetchAssignPowersToRole = (data: any) => {
|
export const fetchAssignPowersToRole = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('post', 'rolePower/assignPowersToRole', { data });
|
return http.request<BaseResult<object>>('post', 'rolePower/assignPowersToRole', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 角色---更新角色 */
|
||||||
* 角色---更新角色
|
|
||||||
*/
|
|
||||||
export const fetchUpdateRole = (data: any) => {
|
export const fetchUpdateRole = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('put', 'role/updateRole', { data });
|
return http.request<BaseResult<object>>('put', 'role/updateRole', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** 角色---删除角色 */
|
||||||
* 角色---删除角色
|
|
||||||
*/
|
|
||||||
export const fetchDeleteRole = (data: any) => {
|
export const fetchDeleteRole = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('delete', 'role/deleteRole', { data });
|
return http.request<BaseResult<object>>('delete', 'role/deleteRole', { data });
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@ export const fetchGetSchedulersList = (data: any) => {
|
||||||
|
|
||||||
/** Schedulers视图---获取所有可用调度任务 */
|
/** Schedulers视图---获取所有可用调度任务 */
|
||||||
export const fetchGetAllScheduleJobList = () => {
|
export const fetchGetAllScheduleJobList = () => {
|
||||||
return http.request<BaseResult<ResultTable>>('get', 'schedulers/getAllScheduleJobList');
|
return http.request<BaseResult<ResultTable>>('get', 'schedulers/noManage/getAllScheduleJobList');
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Schedulers视图---添加Schedulers视图 */
|
/** Schedulers视图---添加Schedulers视图 */
|
||||||
|
|
|
@ -3,7 +3,7 @@ import type { BaseResult } from '@/api/service/types';
|
||||||
|
|
||||||
/** 系统管理-用户路由获取 */
|
/** 系统管理-用户路由获取 */
|
||||||
export const getRouterAsync = () => {
|
export const getRouterAsync = () => {
|
||||||
return http.request<BaseResult<any>>('get', 'router/getRouterAsync');
|
return http.request<BaseResult<any>>('get', 'router/noManage/getRouterAsync');
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 上传文件 */
|
/** 上传文件 */
|
||||||
|
|
|
@ -6,6 +6,11 @@ export const fetchGetUserLoginLogList = (data: any) => {
|
||||||
return http.request<BaseResult<ResultTable>>('get', `userLoginLog/getUserLoginLogList/${data.currentPage}/${data.pageSize}`, { params: data });
|
return http.request<BaseResult<ResultTable>>('get', `userLoginLog/getUserLoginLogList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 用户登录日志---获取用户登录日志列表 */
|
||||||
|
export const fetchGetUserLoginLogListByLocalUser = (data: any) => {
|
||||||
|
return http.request<BaseResult<ResultTable>>('get', `userLoginLog/noManage/getUserLoginLogListByLocalUser/${data.currentPage}/${data.pageSize}`);
|
||||||
|
};
|
||||||
|
|
||||||
/** 用户登录日志---删除用户登录日志 */
|
/** 用户登录日志---删除用户登录日志 */
|
||||||
export const fetchDeleteUserLoginLog = (data: any) => {
|
export const fetchDeleteUserLoginLog = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('delete', 'userLoginLog/deleteUserLoginLog', { data });
|
return http.request<BaseResult<object>>('delete', 'userLoginLog/deleteUserLoginLog', { data });
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import reText from "./src/index.vue";
|
import reText from './src/index.vue';
|
||||||
import { withInstall } from "@pureadmin/utils";
|
import { withInstall } from '@pureadmin/utils';
|
||||||
|
|
||||||
/** 支持`Tooltip`提示的文本省略组件 */
|
/** 支持`Tooltip`提示的文本省略组件 */
|
||||||
export const ReText = withInstall(reText);
|
export const Text = withInstall(reText);
|
||||||
|
|
||||||
export default ReText;
|
export default Text;
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useNav } from '@/layout/hooks/useNav';
|
||||||
|
import LogoutCircleRLine from '@iconify-icons/ri/logout-circle-r-line';
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
const { logout, username, userAvatar, avatarsStyle } = useNav();
|
||||||
|
const router = useRouter();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-dropdown trigger="click">
|
||||||
|
<span class="el-dropdown-link navbar-bg-hover select-none">
|
||||||
|
<img :src="userAvatar" :style="avatarsStyle" alt="" />
|
||||||
|
<p v-if="username" class="dark:text-white">{{ username }}</p>
|
||||||
|
</span>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-item @click="router.push({ name: 'AccountSettings' })">
|
||||||
|
<IconifyIconOffline :icon="LogoutCircleRLine" style="margin: 5px" />
|
||||||
|
账户设置
|
||||||
|
<!--{{ $t('buttons.pureLoginOut') }}-->
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-menu class="logout">
|
||||||
|
<el-dropdown-item @click="logout">
|
||||||
|
<IconifyIconOffline :icon="LogoutCircleRLine" style="margin: 5px" />
|
||||||
|
{{ $t('buttons.pureLoginOut') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-dropdown-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
height: 48px;
|
||||||
|
padding: 10px;
|
||||||
|
color: #000000d9;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -9,12 +9,12 @@ import LaySidebarBreadCrumb from '../lay-sidebar/components/SidebarBreadCrumb.vu
|
||||||
import LaySidebarTopCollapse from '../lay-sidebar/components/SidebarTopCollapse.vue';
|
import LaySidebarTopCollapse from '../lay-sidebar/components/SidebarTopCollapse.vue';
|
||||||
|
|
||||||
import GlobalizationIcon from '@/assets/svg/globalization.svg?component';
|
import GlobalizationIcon from '@/assets/svg/globalization.svg?component';
|
||||||
import LogoutCircleRLine from '@iconify-icons/ri/logout-circle-r-line';
|
|
||||||
import Setting from '@iconify-icons/ri/settings-3-line';
|
import Setting from '@iconify-icons/ri/settings-3-line';
|
||||||
import Check from '@iconify-icons/ep/check';
|
import Check from '@iconify-icons/ep/check';
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
import { userI18nTypeStore } from '@/store/i18n/i18nType';
|
import { userI18nTypeStore } from '@/store/i18n/i18nType';
|
||||||
import { onMounted } from 'vue';
|
import { onMounted } from 'vue';
|
||||||
|
import DropdownMenu from '@/layout/components/lay-navbar/dropdown-menu.vue';
|
||||||
|
|
||||||
const { layout, device, logout, onPanel, pureApp, username, userAvatar, avatarsStyle, toggleSideBar, getDropdownItemStyle, getDropdownItemClass } = useNav();
|
const { layout, device, logout, onPanel, pureApp, username, userAvatar, avatarsStyle, toggleSideBar, getDropdownItemStyle, getDropdownItemClass } = useNav();
|
||||||
|
|
||||||
|
@ -63,20 +63,8 @@ onMounted(() => {
|
||||||
<!-- 消息通知 -->
|
<!-- 消息通知 -->
|
||||||
<LayNotice id="header-notice" />
|
<LayNotice id="header-notice" />
|
||||||
<!-- 退出登录 -->
|
<!-- 退出登录 -->
|
||||||
<el-dropdown trigger="click">
|
<dropdown-menu />
|
||||||
<span class="el-dropdown-link navbar-bg-hover select-none">
|
<!-- 打开设置 -->
|
||||||
<img :src="userAvatar" :style="avatarsStyle" alt="" />
|
|
||||||
<p v-if="username" class="dark:text-white">{{ username }}</p>
|
|
||||||
</span>
|
|
||||||
<template #dropdown>
|
|
||||||
<el-dropdown-menu class="logout">
|
|
||||||
<el-dropdown-item @click="logout">
|
|
||||||
<IconifyIconOffline :icon="LogoutCircleRLine" style="margin: 5px" />
|
|
||||||
{{ $t('buttons.pureLoginOut') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
<span :title="$t('buttons.pureOpenSystemSet')" class="set-icon navbar-bg-hover" @click="onPanel">
|
<span :title="$t('buttons.pureOpenSystemSet')" class="set-icon navbar-bg-hover" @click="onPanel">
|
||||||
<IconifyIconOffline :icon="Setting" />
|
<IconifyIconOffline :icon="Setting" />
|
||||||
</span>
|
</span>
|
||||||
|
@ -104,26 +92,6 @@ onMounted(() => {
|
||||||
min-width: 280px;
|
min-width: 280px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
color: #000000d9;
|
color: #000000d9;
|
||||||
|
|
||||||
.el-dropdown-link {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-around;
|
|
||||||
height: 48px;
|
|
||||||
padding: 10px;
|
|
||||||
color: #000000d9;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 22px;
|
|
||||||
height: 22px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumb-container {
|
.breadcrumb-container {
|
||||||
|
|
|
@ -64,7 +64,7 @@ const getThemeColorStyle = computed(() => {
|
||||||
/** 当网页整体为暗色风格时不显示亮白色主题配色切换选项 */
|
/** 当网页整体为暗色风格时不显示亮白色主题配色切换选项 */
|
||||||
const showThemeColors = computed(() => {
|
const showThemeColors = computed(() => {
|
||||||
return themeColor => {
|
return themeColor => {
|
||||||
return themeColor === 'light' && isDark.value ? false : true;
|
return !(themeColor === 'light' && isDark.value);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,223 +1,150 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useRenderIcon } from "@/components/CommonIcon/src/hooks";
|
import { useRenderIcon } from '@/components/CommonIcon/src/hooks';
|
||||||
import { ReText } from "@/components/Text";
|
import { Text } from '@/components/Text';
|
||||||
import { getConfig } from "@/config";
|
import { getConfig } from '@/config';
|
||||||
import { useNav } from "@/layout/hooks/useNav";
|
import { useNav } from '@/layout/hooks/useNav';
|
||||||
import { menuType } from "@/layout/types";
|
import { menuType } from '@/layout/types';
|
||||||
import path from "path";
|
import path from 'path';
|
||||||
import {
|
import { computed, type CSSProperties, type PropType, ref, toRaw, useAttrs } from 'vue';
|
||||||
computed,
|
import SidebarExtraIcon from './SidebarExtraIcon.vue';
|
||||||
type CSSProperties,
|
import SidebarLinkItem from './SidebarLinkItem.vue';
|
||||||
type PropType,
|
|
||||||
ref,
|
|
||||||
toRaw,
|
|
||||||
useAttrs
|
|
||||||
} from "vue";
|
|
||||||
import SidebarExtraIcon from "./SidebarExtraIcon.vue";
|
|
||||||
import SidebarLinkItem from "./SidebarLinkItem.vue";
|
|
||||||
|
|
||||||
import { $t } from "@/plugins/i18n";
|
import { $t } from '@/plugins/i18n';
|
||||||
import EpArrowDown from "@iconify-icons/ep/arrow-down-bold";
|
import EpArrowDown from '@iconify-icons/ep/arrow-down-bold';
|
||||||
import ArrowLeft from "@iconify-icons/ep/arrow-left-bold";
|
import ArrowLeft from '@iconify-icons/ep/arrow-left-bold';
|
||||||
import ArrowRight from "@iconify-icons/ep/arrow-right-bold";
|
import ArrowRight from '@iconify-icons/ep/arrow-right-bold';
|
||||||
import ArrowUp from "@iconify-icons/ep/arrow-up-bold";
|
import ArrowUp from '@iconify-icons/ep/arrow-up-bold';
|
||||||
|
|
||||||
const attrs = useAttrs();
|
const attrs = useAttrs();
|
||||||
const { layout, isCollapse, tooltipEffect, getDivStyle } = useNav();
|
const { layout, isCollapse, tooltipEffect, getDivStyle } = useNav();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
item: {
|
item: {
|
||||||
type: Object as PropType<menuType>
|
type: Object as PropType<menuType>,
|
||||||
},
|
},
|
||||||
isNest: {
|
isNest: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
basePath: {
|
basePath: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: '',
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const getNoDropdownStyle = computed((): CSSProperties => {
|
const getNoDropdownStyle = computed((): CSSProperties => {
|
||||||
return {
|
return {
|
||||||
width: "100%",
|
width: '100%',
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
alignItems: "center"
|
alignItems: 'center',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const getSubMenuIconStyle = computed((): CSSProperties => {
|
const getSubMenuIconStyle = computed((): CSSProperties => {
|
||||||
return {
|
return {
|
||||||
display: "flex",
|
display: 'flex',
|
||||||
justifyContent: "center",
|
justifyContent: 'center',
|
||||||
alignItems: "center",
|
alignItems: 'center',
|
||||||
margin:
|
margin: layout.value === 'horizontal' ? '0 5px 0 0' : isCollapse.value ? '0 auto' : '0 5px 0 0',
|
||||||
layout.value === "horizontal"
|
};
|
||||||
? "0 5px 0 0"
|
|
||||||
: isCollapse.value
|
|
||||||
? "0 auto"
|
|
||||||
: "0 5px 0 0"
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const expandCloseIcon = computed(() => {
|
const expandCloseIcon = computed(() => {
|
||||||
if (!getConfig()?.MenuArrowIconNoTransition) return "";
|
if (!getConfig()?.MenuArrowIconNoTransition) return '';
|
||||||
return {
|
return {
|
||||||
"expand-close-icon": useRenderIcon(EpArrowDown),
|
'expand-close-icon': useRenderIcon(EpArrowDown),
|
||||||
"expand-open-icon": useRenderIcon(ArrowUp),
|
'expand-open-icon': useRenderIcon(ArrowUp),
|
||||||
"collapse-close-icon": useRenderIcon(ArrowRight),
|
'collapse-close-icon': useRenderIcon(ArrowRight),
|
||||||
"collapse-open-icon": useRenderIcon(ArrowLeft)
|
'collapse-open-icon': useRenderIcon(ArrowLeft),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const onlyOneChild: menuType = ref(null);
|
const onlyOneChild: menuType = ref(null);
|
||||||
|
|
||||||
function hasOneShowingChild(children: menuType[] = [], parent: menuType) {
|
function hasOneShowingChild(children: menuType[] = [], parent: menuType) {
|
||||||
const showingChildren = children.filter((item: any) => {
|
const showingChildren = children.filter((item: any) => {
|
||||||
onlyOneChild.value = item;
|
onlyOneChild.value = item;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (showingChildren[0]?.meta?.showParent) {
|
if (showingChildren[0]?.meta?.showParent) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showingChildren.length === 1) {
|
if (showingChildren.length === 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showingChildren.length === 0) {
|
if (showingChildren.length === 0) {
|
||||||
onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
|
onlyOneChild.value = { ...parent, path: '', noShowingChildren: true };
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolvePath(routePath) {
|
function resolvePath(routePath) {
|
||||||
const httpReg = /^http(s?):\/\//;
|
const httpReg = /^http(s?):\/\//;
|
||||||
if (httpReg.test(routePath) || httpReg.test(props.basePath)) {
|
if (httpReg.test(routePath) || httpReg.test(props.basePath)) {
|
||||||
return routePath || props.basePath;
|
return routePath || props.basePath;
|
||||||
} else {
|
} else {
|
||||||
// 使用path.posix.resolve替代path.resolve 避免windows环境下使用electron出现盘符问题
|
// 使用path.posix.resolve替代path.resolve 避免windows环境下使用electron出现盘符问题
|
||||||
return path.posix.resolve(props.basePath, routePath);
|
return path.posix.resolve(props.basePath, routePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<SidebarLinkItem
|
<SidebarLinkItem v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren)" :to="item">
|
||||||
v-if="
|
<el-menu-item :class="{ 'submenu-title-noDropdown': !isNest }" :index="resolvePath(onlyOneChild.path)" :style="getNoDropdownStyle" v-bind="attrs">
|
||||||
hasOneShowingChild(item.children, item) &&
|
<div v-if="toRaw(item.meta.icon)" :style="getSubMenuIconStyle" class="sub-menu-icon">
|
||||||
(!onlyOneChild.children || onlyOneChild.noShowingChildren)
|
<component :is="useRenderIcon(toRaw(onlyOneChild.meta.icon) || (item.meta && toRaw(item.meta.icon)))" />
|
||||||
"
|
</div>
|
||||||
:to="item"
|
<el-text
|
||||||
>
|
v-if="(!item?.meta.icon && isCollapse && layout === 'vertical' && item?.pathList?.length === 1) || (!onlyOneChild.meta.icon && isCollapse && layout === 'mix' && item?.pathList?.length === 2)"
|
||||||
<el-menu-item
|
class="!w-full !pl-4 !text-inherit"
|
||||||
:class="{ 'submenu-title-noDropdown': !isNest }"
|
truncated
|
||||||
:index="resolvePath(onlyOneChild.path)"
|
>
|
||||||
:style="getNoDropdownStyle"
|
{{ $t(onlyOneChild.meta.title) }}
|
||||||
v-bind="attrs"
|
</el-text>
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-if="toRaw(item.meta.icon)"
|
|
||||||
:style="getSubMenuIconStyle"
|
|
||||||
class="sub-menu-icon"
|
|
||||||
>
|
|
||||||
<component
|
|
||||||
:is="
|
|
||||||
useRenderIcon(
|
|
||||||
toRaw(onlyOneChild.meta.icon) ||
|
|
||||||
(item.meta && toRaw(item.meta.icon))
|
|
||||||
)
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<el-text
|
|
||||||
v-if="
|
|
||||||
(!item?.meta.icon &&
|
|
||||||
isCollapse &&
|
|
||||||
layout === 'vertical' &&
|
|
||||||
item?.pathList?.length === 1) ||
|
|
||||||
(!onlyOneChild.meta.icon &&
|
|
||||||
isCollapse &&
|
|
||||||
layout === 'mix' &&
|
|
||||||
item?.pathList?.length === 2)
|
|
||||||
"
|
|
||||||
class="!w-full !pl-4 !text-inherit"
|
|
||||||
truncated
|
|
||||||
>
|
|
||||||
{{ $t(onlyOneChild.meta.title) }}
|
|
||||||
</el-text>
|
|
||||||
|
|
||||||
<template #title>
|
<template #title>
|
||||||
<div :style="getDivStyle">
|
<div :style="getDivStyle">
|
||||||
<ReText
|
<Text
|
||||||
:tippyProps="{
|
:tippyProps="{
|
||||||
offset: [0, -10],
|
offset: [0, -10],
|
||||||
theme: tooltipEffect
|
theme: tooltipEffect,
|
||||||
}"
|
}"
|
||||||
class="!w-full !text-inherit"
|
class="!w-full !text-inherit"
|
||||||
>
|
>
|
||||||
{{ $t(onlyOneChild.meta.title) }}
|
{{ $t(onlyOneChild.meta.title) }}
|
||||||
</ReText>
|
</Text>
|
||||||
<SidebarExtraIcon :extraIcon="onlyOneChild.meta.extraIcon" />
|
<SidebarExtraIcon :extraIcon="onlyOneChild.meta.extraIcon" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</SidebarLinkItem>
|
</SidebarLinkItem>
|
||||||
<el-sub-menu
|
<el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported v-bind="expandCloseIcon">
|
||||||
v-else
|
<template #title>
|
||||||
ref="subMenu"
|
<div v-if="toRaw(item.meta.icon)" :style="getSubMenuIconStyle" class="sub-menu-icon">
|
||||||
:index="resolvePath(item.path)"
|
<component :is="useRenderIcon(item.meta && toRaw(item.meta.icon))" />
|
||||||
teleported
|
</div>
|
||||||
v-bind="expandCloseIcon"
|
<Text
|
||||||
>
|
v-if="layout === 'mix' && toRaw(item.meta.icon) ? !isCollapse || item?.pathList?.length !== 2 : !(layout === 'vertical' && isCollapse && toRaw(item.meta.icon) && item.parentId === null)"
|
||||||
<template #title>
|
:class="{
|
||||||
<div
|
'!w-full': true,
|
||||||
v-if="toRaw(item.meta.icon)"
|
'!text-inherit': true,
|
||||||
:style="getSubMenuIconStyle"
|
'!pl-4': layout !== 'horizontal' && isCollapse && !toRaw(item.meta.icon) && item.parentId === null,
|
||||||
class="sub-menu-icon"
|
}"
|
||||||
>
|
:tippyProps="{
|
||||||
<component :is="useRenderIcon(item.meta && toRaw(item.meta.icon))" />
|
offset: [0, -10],
|
||||||
</div>
|
theme: tooltipEffect,
|
||||||
<ReText
|
}"
|
||||||
v-if="
|
>
|
||||||
layout === 'mix' && toRaw(item.meta.icon)
|
{{ $t(item.meta.title) }}
|
||||||
? !isCollapse || item?.pathList?.length !== 2
|
</Text>
|
||||||
: !(
|
<SidebarExtraIcon v-if="!isCollapse" :extraIcon="item.meta.extraIcon" />
|
||||||
layout === 'vertical' &&
|
</template>
|
||||||
isCollapse &&
|
|
||||||
toRaw(item.meta.icon) &&
|
|
||||||
item.parentId === null
|
|
||||||
)
|
|
||||||
"
|
|
||||||
:class="{
|
|
||||||
'!w-full': true,
|
|
||||||
'!text-inherit': true,
|
|
||||||
'!pl-4':
|
|
||||||
layout !== 'horizontal' &&
|
|
||||||
isCollapse &&
|
|
||||||
!toRaw(item.meta.icon) &&
|
|
||||||
item.parentId === null
|
|
||||||
}"
|
|
||||||
:tippyProps="{
|
|
||||||
offset: [0, -10],
|
|
||||||
theme: tooltipEffect
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
{{ $t(item.meta.title) }}
|
|
||||||
</ReText>
|
|
||||||
<SidebarExtraIcon v-if="!isCollapse" :extraIcon="item.meta.extraIcon" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<sidebar-item
|
<sidebar-item v-for="child in item.children" :key="child.path" :base-path="resolvePath(child.path)" :is-nest="true" :item="child" class="nest-menu" />
|
||||||
v-for="child in item.children"
|
</el-sub-menu>
|
||||||
:key="child.path"
|
|
||||||
:base-path="resolvePath(child.path)"
|
|
||||||
:is-nest="true"
|
|
||||||
:item="child"
|
|
||||||
class="nest-menu"
|
|
||||||
/>
|
|
||||||
</el-sub-menu>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -102,11 +102,11 @@ router.beforeEach((to: ToRouteType, _from, next) => {
|
||||||
if (Cookies.get(multipleTabsKey) && userInfo) {
|
if (Cookies.get(multipleTabsKey) && userInfo) {
|
||||||
// 无权限跳转403页面
|
// 无权限跳转403页面
|
||||||
if (to.meta?.roles && !isOneOfArray(to.meta?.roles, userInfo?.roles)) {
|
if (to.meta?.roles && !isOneOfArray(to.meta?.roles, userInfo?.roles)) {
|
||||||
next({ path: '/error/403' });
|
next({ path: '/Error/403' });
|
||||||
}
|
}
|
||||||
// 开启隐藏首页后在浏览器地址栏手动输入首页welcome路由则跳转到404页面
|
// 开启隐藏首页后在浏览器地址栏手动输入首页welcome路由则跳转到404页面
|
||||||
if (VITE_HIDE_HOME === 'true' && to.fullPath === '/welcome') {
|
if (VITE_HIDE_HOME === 'true' && to.fullPath === '/welcome') {
|
||||||
next({ path: '/error/404' });
|
next({ path: '/Error/404' });
|
||||||
}
|
}
|
||||||
if (_from?.name) {
|
if (_from?.name) {
|
||||||
// name为超链接
|
// name为超链接
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
path: '/error',
|
path: '/Error',
|
||||||
redirect: '/error/403',
|
redirect: '/Error/403',
|
||||||
meta: {
|
meta: {
|
||||||
icon: 'ri:information-line',
|
icon: 'ri:information-line',
|
||||||
showLink: false,
|
showLink: false,
|
||||||
|
@ -11,25 +11,25 @@ export default {
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/error/403',
|
path: '/Error/403',
|
||||||
name: '403',
|
name: '403',
|
||||||
component: () => import('@/components/error/403.vue'),
|
component: () => import('@/components/Error/403.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: $t('menus.pureFourZeroOne'),
|
title: $t('menus.pureFourZeroOne'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/error/404',
|
path: '/Error/404',
|
||||||
name: '404',
|
name: '404',
|
||||||
component: () => import('@/components/error/404.vue'),
|
component: () => import('@/components/Error/404.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: $t('menus.pureFourZeroFour'),
|
title: $t('menus.pureFourZeroFour'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/error/500',
|
path: '/Error/500',
|
||||||
name: '500',
|
name: '500',
|
||||||
component: () => import('@/components/error/500.vue'),
|
component: () => import('@/components/Error/500.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: $t('menus.pureFive'),
|
title: $t('menus.pureFive'),
|
||||||
},
|
},
|
||||||
|
|
|
@ -27,4 +27,14 @@ export default [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/account-settings',
|
||||||
|
name: 'AccountSettings',
|
||||||
|
component: () => import('@/views/account-settings/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'buttons.accountSettings',
|
||||||
|
showLink: false,
|
||||||
|
rank: 104,
|
||||||
|
},
|
||||||
|
},
|
||||||
] satisfies Array<RouteConfigsTable>;
|
] satisfies Array<RouteConfigsTable>;
|
||||||
|
|
|
@ -107,7 +107,7 @@ function addPathMatch() {
|
||||||
router.addRoute({
|
router.addRoute({
|
||||||
path: '/:pathMatch(.*)',
|
path: '/:pathMatch(.*)',
|
||||||
name: 'pathMatch',
|
name: 'pathMatch',
|
||||||
redirect: '/error/404',
|
redirect: '/Error/404',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { fetchDeleteUserLoginLog, fetchGetUserLoginLogList } from '@/api/v1/userLoginLog';
|
import { fetchDeleteUserLoginLog, fetchGetUserLoginLogList, fetchGetUserLoginLogListByLocalUser } from '@/api/v1/userLoginLog';
|
||||||
import { pageSizes } from '@/enums/baseConstant';
|
import { pageSizes } from '@/enums/baseConstant';
|
||||||
import { storeMessage } from '@/utils/message';
|
import { storeMessage } from '@/utils/message';
|
||||||
import { storePagination } from '@/store/useStorePagination';
|
import { storePagination } from '@/store/useStorePagination';
|
||||||
|
@ -66,6 +66,14 @@ export const useUserLoginLogStore = defineStore('userLoginLogStore', {
|
||||||
return pagination(result);
|
return pagination(result);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** 分页查询根据用户Id用户登录日志内容 */
|
||||||
|
async getUserLoginLogListByLocalUser(data: any) {
|
||||||
|
const baseResult = await fetchGetUserLoginLogListByLocalUser(data);
|
||||||
|
if (baseResult.code === 200) {
|
||||||
|
return baseResult.data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/** 删除用户登录日志 */
|
/** 删除用户登录日志 */
|
||||||
async deleteUserLoginLog(data: any) {
|
async deleteUserLoginLog(data: any) {
|
||||||
const result = await fetchDeleteUserLoginLog(data);
|
const result = await fetchDeleteUserLoginLog(data);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { resetRouter, router, routerArrays, storageLocal, store, type userType } from '../utils';
|
import { resetRouter, router, routerArrays, storageLocal, store, type userType } from '../utils';
|
||||||
import { fetchAssignRolesToUsers, fetchLogin, fetchLogout, fetchPostEmailCode, refreshTokenApi } from '@/api/v1/adminUser';
|
import { fetchAssignRolesToUsers, fetchGetUserinfo, fetchLogin, fetchLogout, fetchPostEmailCode, refreshTokenApi } from '@/api/v1/adminUser';
|
||||||
import { useMultiTagsStoreHook } from '../multiTags';
|
import { useMultiTagsStoreHook } from '../multiTags';
|
||||||
import { type DataInfo, removeToken, setToken, userKey } from '@/utils/auth';
|
import { type DataInfo, removeToken, setToken, userKey } from '@/utils/auth';
|
||||||
import { message, storeMessage } from '@/utils/message';
|
import { message, storeMessage } from '@/utils/message';
|
||||||
|
@ -79,6 +79,15 @@ export const useUserStore = defineStore({
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** 获取用户信息 */
|
||||||
|
async getUserinfo() {
|
||||||
|
const result = await fetchGetUserinfo();
|
||||||
|
if (result.code === 200) {
|
||||||
|
return result.data;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
|
||||||
/** 根据用户id获取角色列表 */
|
/** 根据用户id获取角色列表 */
|
||||||
async getRoleListByUserId(data: any) {
|
async getRoleListByUserId(data: any) {
|
||||||
const result = await fetchGetRoleListByUserId(data);
|
const result = await fetchGetRoleListByUserId(data);
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { message } from '@/utils/message';
|
||||||
|
import { deviceDetection } from '@pureadmin/utils';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'AccountManagement',
|
||||||
|
});
|
||||||
|
|
||||||
|
const list = ref([
|
||||||
|
{
|
||||||
|
title: '账户密码',
|
||||||
|
illustrate: '当前密码强度:强',
|
||||||
|
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' });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="['min-w-[180px]', deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]']">
|
||||||
|
<h3 class="my-8">账户管理</h3>
|
||||||
|
<div v-for="(item, index) in list" :key="index">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="flex-1">
|
||||||
|
<p>{{ item.title }}</p>
|
||||||
|
<el-text class="mx-1" type="info">{{ item.illustrate }}</el-text>
|
||||||
|
</div>
|
||||||
|
<el-button text type="primary" @click="onClick(item)">
|
||||||
|
{{ item.button }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-divider />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-divider--horizontal {
|
||||||
|
border-top: 0.1px var(--el-border-color) var(--el-border-style);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,162 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { onBeforeMount, ref } from 'vue';
|
||||||
|
import { Text } from '@/components/Text';
|
||||||
|
import Profile from './profile.vue';
|
||||||
|
import Preferences from './references.vue';
|
||||||
|
import SecurityLog from './security-log.vue';
|
||||||
|
import { deviceDetection, useGlobal } from '@pureadmin/utils';
|
||||||
|
import AccountManagement from './account-management.vue';
|
||||||
|
import { useDataThemeChange } from '@/layout/hooks/useDataThemeChange';
|
||||||
|
import LaySidebarTopCollapse from '@/layout/components/lay-sidebar/components/SidebarTopCollapse.vue';
|
||||||
|
import leftLine from '@iconify-icons/ri/arrow-left-s-line';
|
||||||
|
import ProfileIcon from '@iconify-icons/ri/user-3-line';
|
||||||
|
import PreferencesIcon from '@iconify-icons/ri/settings-3-line';
|
||||||
|
import SecurityLogIcon from '@iconify-icons/ri/window-line';
|
||||||
|
import AccountManagementIcon from '@iconify-icons/ri/profile-line';
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
import { userInfos } from '@/views/account-settings/utils/hooks';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const isOpen = ref(!deviceDetection());
|
||||||
|
const { $storage } = useGlobal<GlobalPropertiesApi>();
|
||||||
|
const witchPane = ref('profile');
|
||||||
|
|
||||||
|
const panes = [
|
||||||
|
{
|
||||||
|
key: 'profile',
|
||||||
|
label: '个人信息',
|
||||||
|
icon: ProfileIcon,
|
||||||
|
component: Profile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'preferences',
|
||||||
|
label: '偏好设置',
|
||||||
|
icon: PreferencesIcon,
|
||||||
|
component: Preferences,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'securityLog',
|
||||||
|
label: '安全日志',
|
||||||
|
icon: SecurityLogIcon,
|
||||||
|
component: SecurityLog,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'accountManagement',
|
||||||
|
label: '账户管理',
|
||||||
|
icon: AccountManagementIcon,
|
||||||
|
component: AccountManagement,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
useDataThemeChange().dataThemeChange($storage.layout?.overallStyle);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-container class="h-full">
|
||||||
|
<el-aside
|
||||||
|
v-if="isOpen"
|
||||||
|
:width="deviceDetection() ? '180px' : '240px'"
|
||||||
|
class="pure-account-settings overflow-hidden px-2 dark:!bg-[var(--el-bg-color)] border-r-[1px] border-[var(--pure-border-color)]"
|
||||||
|
>
|
||||||
|
<el-menu :default-active="witchPane" class="pure-account-settings-menu">
|
||||||
|
<el-menu-item class="hover:!transition-all hover:!duration-200 hover:!text-base !h-[50px]" @click="router.go(-1)">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<IconifyIconOffline :icon="leftLine" />
|
||||||
|
<span class="ml-2">{{ $t('back') }}</span>
|
||||||
|
</div>
|
||||||
|
</el-menu-item>
|
||||||
|
<div class="flex items-center ml-8 mt-4 mb-4">
|
||||||
|
<el-avatar :size="48" :src="userInfos.avatar" />
|
||||||
|
<div class="ml-4 flex flex-col max-w-[130px]">
|
||||||
|
<Text class="font-bold !self-baseline">
|
||||||
|
{{ userInfos.nickname }}
|
||||||
|
</Text>
|
||||||
|
<Text class="!self-baseline" type="info">
|
||||||
|
{{ userInfos.username }}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-menu-item
|
||||||
|
v-for="item in panes"
|
||||||
|
:key="item.key"
|
||||||
|
:index="item.key"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
witchPane = item.key;
|
||||||
|
if (deviceDetection()) {
|
||||||
|
isOpen = !isOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="flex items-center z-10">
|
||||||
|
<el-icon>
|
||||||
|
<IconifyIconOffline :icon="item.icon" />
|
||||||
|
</el-icon>
|
||||||
|
<span>{{ item.label }}</span>
|
||||||
|
</div>
|
||||||
|
</el-menu-item>
|
||||||
|
</el-menu>
|
||||||
|
</el-aside>
|
||||||
|
<el-main>
|
||||||
|
<LaySidebarTopCollapse v-if="deviceDetection()" :is-active="isOpen" class="px-0" @toggleClick="isOpen = !isOpen" />
|
||||||
|
<component :is="panes.find(item => item.key === witchPane).component" :class="[!deviceDetection() && 'ml-[120px]']" />
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.pure-account-settings {
|
||||||
|
background: $menuBg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pure-account-settings-menu {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
.el-menu-item {
|
||||||
|
height: 48px !important;
|
||||||
|
color: $menuText;
|
||||||
|
background-color: transparent !important;
|
||||||
|
transition: color 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $menuTitleHover !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
color: #fff !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0 8px;
|
||||||
|
margin: 4px 0;
|
||||||
|
clear: both;
|
||||||
|
content: '';
|
||||||
|
background: var(--el-color-primary);
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
body[layout] {
|
||||||
|
.el-menu--vertical .is-active {
|
||||||
|
color: #fff !important;
|
||||||
|
transition: color 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,118 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import { message } from '@/utils/message';
|
||||||
|
import type { FormInstance } from 'element-plus';
|
||||||
|
import ReCropperPreview from '@/components/CropperPreview';
|
||||||
|
import { createFormData, deviceDetection } from '@pureadmin/utils';
|
||||||
|
import uploadLine from '@iconify-icons/ri/upload-line';
|
||||||
|
import { useUserStore } from '@/store/system/user';
|
||||||
|
import { rules } from '@/views/account-settings/utils/columns';
|
||||||
|
import { onSearch, userInfos } from '@/views/account-settings/utils/hooks';
|
||||||
|
|
||||||
|
const imgSrc = ref('');
|
||||||
|
const cropperBlob = ref();
|
||||||
|
const cropRef = ref();
|
||||||
|
const uploadRef = ref();
|
||||||
|
const isShow = ref(false);
|
||||||
|
const userInfoFormRef = ref<FormInstance>();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
function queryEmail(queryString, callback) {
|
||||||
|
const emailList = [{ value: '@qq.com' }, { value: '@126.com' }, { value: '@163.com' }];
|
||||||
|
let results = [];
|
||||||
|
let queryList = [];
|
||||||
|
emailList.map(item => queryList.push({ value: queryString.split('@')[0] + item.value }));
|
||||||
|
results = queryString ? queryList.filter(item => item.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0) : queryList;
|
||||||
|
callback(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
const onChange = uploadFile => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = e => {
|
||||||
|
imgSrc.value = e.target.result as string;
|
||||||
|
isShow.value = true;
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(uploadFile.raw);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
cropRef.value.hidePopover();
|
||||||
|
uploadRef.value.clearFiles();
|
||||||
|
isShow.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCropper = ({ blob }) => (cropperBlob.value = blob);
|
||||||
|
|
||||||
|
const handleSubmitImage = () => {
|
||||||
|
const formData = createFormData({
|
||||||
|
files: new File([cropperBlob.value], 'avatar'),
|
||||||
|
});
|
||||||
|
// formUpload(formData)
|
||||||
|
// .then(({ success, data }) => {
|
||||||
|
// if (success) {
|
||||||
|
// message('更新头像成功', { type: 'success' });
|
||||||
|
// handleClose();
|
||||||
|
// } else {
|
||||||
|
// message('更新头像失败');
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .catch(error => {
|
||||||
|
// message(`提交异常 ${error}`, { type: 'error' });
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新信息
|
||||||
|
const onSubmit = async (formEl: FormInstance) => {
|
||||||
|
await formEl.validate((valid, fields) => {
|
||||||
|
if (valid) {
|
||||||
|
console.log(userInfos);
|
||||||
|
message('更新信息成功', { type: 'success' });
|
||||||
|
} else {
|
||||||
|
console.log('Error submit!', fields);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
onSearch();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="['min-w-[180px]', deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]']">
|
||||||
|
<h3 class="my-8">个人信息</h3>
|
||||||
|
<el-form ref="userInfoFormRef" :model="userInfos" :rules="rules" label-position="top">
|
||||||
|
<el-form-item label="头像">
|
||||||
|
<el-avatar :size="80" :src="userInfos.avatar" />
|
||||||
|
<el-upload ref="uploadRef" :auto-upload="false" :limit="1" :on-change="onChange" :show-file-list="false" accept="image/*" action="#">
|
||||||
|
<el-button class="ml-4" plain>
|
||||||
|
<IconifyIconOffline :icon="uploadLine" />
|
||||||
|
<span class="ml-2">更新头像</span>
|
||||||
|
</el-button>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="昵称" prop="nickname">
|
||||||
|
<el-input v-model="userInfos.nickname" placeholder="请输入昵称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="邮箱" prop="email">
|
||||||
|
<el-autocomplete v-model="userInfos.email" :fetch-suggestions="queryEmail" :trigger-on-focus="false" class="w-full" clearable placeholder="请输入邮箱" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="联系电话">
|
||||||
|
<el-input v-model="userInfos.phone" clearable placeholder="请输入联系电话" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="简介">
|
||||||
|
<el-input v-model="userInfos.description" :autosize="{ minRows: 6, maxRows: 8 }" maxlength="56" placeholder="请输入简介" show-word-limit type="textarea" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-button type="primary" @click="onSubmit(userInfoFormRef)"> 更新信息</el-button>
|
||||||
|
</el-form>
|
||||||
|
<el-dialog v-model="isShow" :before-close="handleClose" :closeOnClickModal="false" :fullscreen="deviceDetection()" destroy-on-close title="编辑头像" width="40%">
|
||||||
|
<ReCropperPreview ref="cropRef" :imgSrc="imgSrc" @cropper="onCropper" />
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button bg text @click="handleClose">取消</el-button>
|
||||||
|
<el-button bg text type="primary" @click="handleSubmitImage"> 确定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,69 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { message } from "@/utils/message";
|
||||||
|
import { deviceDetection } from "@pureadmin/utils";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "Preferences"
|
||||||
|
});
|
||||||
|
|
||||||
|
const list = ref([
|
||||||
|
{
|
||||||
|
title: "账户密码",
|
||||||
|
illustrate: "其他用户的消息将以站内信的形式通知",
|
||||||
|
checked: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "系统消息",
|
||||||
|
illustrate: "系统消息将以站内信的形式通知",
|
||||||
|
checked: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "待办任务",
|
||||||
|
illustrate: "待办任务将以站内信的形式通知",
|
||||||
|
checked: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
function onChange(val, item) {
|
||||||
|
console.log("onChange", val);
|
||||||
|
message(`${item.title}设置成功`, { type: "success" });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
:class="[
|
||||||
|
'min-w-[180px]',
|
||||||
|
deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]'
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<h3 class="my-8">偏好设置</h3>
|
||||||
|
<div v-for="(item, index) in list" :key="index">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="flex-1">
|
||||||
|
<p>{{ item.title }}</p>
|
||||||
|
<p class="wp-4">
|
||||||
|
<el-text class="mx-1" type="info">
|
||||||
|
{{ item.illustrate }}
|
||||||
|
</el-text>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<el-switch
|
||||||
|
v-model="item.checked"
|
||||||
|
inline-prompt
|
||||||
|
active-text="是"
|
||||||
|
inactive-text="否"
|
||||||
|
@change="val => onChange(val, item)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<el-divider />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-divider--horizontal {
|
||||||
|
border-top: 0.1px var(--el-border-color) var(--el-border-style);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,41 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
|
import { deviceDetection } from '@pureadmin/utils';
|
||||||
|
import { PaginationProps, PureTable } from '@pureadmin/table';
|
||||||
|
import { columns } from '@/views/account-settings/utils/columns';
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
|
||||||
|
const loading = ref(true);
|
||||||
|
const dataList = ref([]);
|
||||||
|
const pagination = reactive<PaginationProps>({
|
||||||
|
total: 0,
|
||||||
|
pageSize: 10,
|
||||||
|
currentPage: 1,
|
||||||
|
background: true,
|
||||||
|
layout: 'prev, pager, next',
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
//
|
||||||
|
// setTimeout(() => {
|
||||||
|
// loading.value = false;
|
||||||
|
// }, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
onSearch();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="['min-w-[180px]', deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]']">
|
||||||
|
<h3 class="my-8">{{ $t('security_log') }}</h3>
|
||||||
|
<pure-table :columns="columns" :data="dataList" :loading="loading" :pagination="pagination" row-key="id" table-layout="auto" />
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,41 @@
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { reactive } from 'vue';
|
||||||
|
import type { FormRules } from 'element-plus';
|
||||||
|
|
||||||
|
export const columns: TableColumnList = [
|
||||||
|
{
|
||||||
|
label: '详情',
|
||||||
|
prop: 'summary',
|
||||||
|
minWidth: 140,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'IP 地址',
|
||||||
|
prop: 'ip',
|
||||||
|
minWidth: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '地点',
|
||||||
|
prop: 'address',
|
||||||
|
minWidth: 140,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '操作系统',
|
||||||
|
prop: 'system',
|
||||||
|
minWidth: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '浏览器类型',
|
||||||
|
prop: 'browser',
|
||||||
|
minWidth: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '时间',
|
||||||
|
prop: 'operatingTime',
|
||||||
|
minWidth: 180,
|
||||||
|
formatter: ({ operatingTime }) => dayjs(operatingTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const rules = reactive<FormRules<any>>({
|
||||||
|
nickname: [{ required: true, message: '昵称必填', trigger: 'blur' }],
|
||||||
|
});
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { useUserStore } from '@/store/system/user';
|
||||||
|
import { reactive } from 'vue';
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
export const userInfos = reactive({
|
||||||
|
avatar: '',
|
||||||
|
username: '',
|
||||||
|
nickname: '',
|
||||||
|
email: '',
|
||||||
|
phone: '',
|
||||||
|
description: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const onSearch = async () => {
|
||||||
|
const data = await userStore.getUserinfo();
|
||||||
|
Object.assign(userInfos, data);
|
||||||
|
userInfos.description = data.personDescription;
|
||||||
|
};
|
|
@ -27,7 +27,6 @@ export function usePublicHooks() {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/** 当前网页是否为`dark`模式 */
|
/** 当前网页是否为`dark`模式 */
|
||||||
isDark,
|
isDark,
|
||||||
|
|
Loading…
Reference in New Issue