Compare commits
No commits in common. 'dev' and 'main' have entirely different histories.
193 changed files with 10492 additions and 1734 deletions
@ -0,0 +1,36 @@ |
|||||||
|
import type { GetUserInfoModel, LoginParams, LoginResultModel, SmsLoginParams } from './model/userModel' |
||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
import type { ErrorMessageMode } from '@/types/axios' |
||||||
|
|
||||||
|
enum Api { |
||||||
|
Login = '/system/auth/login', |
||||||
|
Logout = '/system/auth/logout', |
||||||
|
SmsLogin = '/system/auth/sms-login', |
||||||
|
GetUserInfo = '/system/auth/get-permission-info', |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: user login api |
||||||
|
*/ |
||||||
|
export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal') { |
||||||
|
return defHttp.post<LoginResultModel>({ url: Api.Login, params }, { errorMessageMode: mode }) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: user smslogin api |
||||||
|
*/ |
||||||
|
export function smsLogin(params: SmsLoginParams, mode: ErrorMessageMode = 'modal') { |
||||||
|
return defHttp.post<LoginResultModel>({ url: Api.SmsLogin, params }, { errorMessageMode: mode }) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: getUserInfo |
||||||
|
*/ |
||||||
|
export function getUserInfo() { |
||||||
|
return defHttp.get<GetUserInfoModel>({ url: Api.GetUserInfo }, { errorMessageMode: 'none' }) |
||||||
|
} |
||||||
|
|
||||||
|
export function doLogout() { |
||||||
|
return defHttp.post({ url: Api.Logout }) |
||||||
|
} |
@ -1,29 +0,0 @@ |
|||||||
import type { LoginParams, LoginResult, UserInfo } from './types' |
|
||||||
import { defHttp } from '@/utils/http/axios' |
|
||||||
import type { ErrorMessageMode } from '@/types/axios' |
|
||||||
|
|
||||||
export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal') { |
|
||||||
return defHttp.post<LoginResult>({ |
|
||||||
url: '/auth/login', |
|
||||||
params, |
|
||||||
headers: { |
|
||||||
'tenant-id': '000000', |
|
||||||
}, |
|
||||||
}, { |
|
||||||
errorMessageMode: mode, |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
export function getUserInfo() { |
|
||||||
return defHttp.get<UserInfo>({ |
|
||||||
url: '/system/permission/get-permission-info', |
|
||||||
}, { |
|
||||||
errorMessageMode: 'none', |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
export function doLogout() { |
|
||||||
return defHttp.post({ |
|
||||||
url: '/auth/logout', |
|
||||||
}) |
|
||||||
} |
|
@ -1,32 +0,0 @@ |
|||||||
import type { MenuItem } from '@/api/system/menu/types' |
|
||||||
|
|
||||||
export interface LoginParams { |
|
||||||
username: string |
|
||||||
password: string |
|
||||||
} |
|
||||||
|
|
||||||
export interface LoginResult { |
|
||||||
userId: string |
|
||||||
accessToken: string |
|
||||||
refreshToken: string |
|
||||||
expiresTime: number |
|
||||||
} |
|
||||||
|
|
||||||
export interface UserInfo { |
|
||||||
user: User |
|
||||||
menus: MenuItem[] |
|
||||||
buttons: string[] |
|
||||||
} |
|
||||||
|
|
||||||
export interface User { |
|
||||||
id: string |
|
||||||
tenantId: string |
|
||||||
account: string |
|
||||||
realName: string |
|
||||||
avatar?: string |
|
||||||
email?: string |
|
||||||
mobile?: string |
|
||||||
remark?: string |
|
||||||
deptId: string |
|
||||||
roleId: string |
|
||||||
} |
|
@ -0,0 +1,11 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
// 获得地区树
|
||||||
|
export function getAreaTree() { |
||||||
|
return defHttp.get({ url: '/system/area/tree' }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得 IP 对应的地区名
|
||||||
|
export function getAreaByIp(ip: string) { |
||||||
|
return defHttp.get({ url: `/system/area/get-by-ip?ip=${ip}` }) |
||||||
|
} |
@ -1,36 +1,48 @@ |
|||||||
import type { Department, LazyGetDeptListParams } from './types' |
|
||||||
import { defHttp } from '@/utils/http/axios' |
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
export function lazyGetDeptList(params?: LazyGetDeptListParams) { |
export interface DeptVO { |
||||||
return defHttp.get<Department[]>({ |
id?: number |
||||||
url: '/system/dept/lazy-list', |
name: string |
||||||
params, |
parentId: number |
||||||
}) |
status: number |
||||||
|
sort: number |
||||||
|
leaderUserId: number |
||||||
|
phone: string |
||||||
|
email: string |
||||||
|
createTime: Date |
||||||
} |
} |
||||||
|
|
||||||
export function createDept(data: Partial<Department>) { |
export interface DeptPageReqVO { |
||||||
return defHttp.post({ |
name?: string |
||||||
url: '/system/dept/save', |
status?: number |
||||||
data, |
|
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function updateDept(data: Partial<Department>) { |
// 查询部门(精简)列表
|
||||||
return defHttp.post({ |
export function listSimpleDept() { |
||||||
url: '/system/dept/update', |
return defHttp.get({ url: '/system/dept/list-all-simple' }) |
||||||
data, |
|
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function deleteDept(id: string) { |
// 查询部门列表
|
||||||
return defHttp.post({ |
export function getDeptPage(params: DeptPageReqVO) { |
||||||
url: `/system/dept/delete?id=${id}`, |
return defHttp.get({ url: '/system/dept/list', params }) |
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function getDeptTree(params?: { tenantId: string }) { |
// 查询部门详情
|
||||||
return defHttp.get<{ id: string, title: string }[]>({ |
export function getDept(id: number) { |
||||||
url: '/system/dept/tree', |
return defHttp.get({ url: `/system/dept/get?id=${id}` }) |
||||||
params, |
} |
||||||
}) |
|
||||||
|
// 新增部门
|
||||||
|
export function createDept(data: DeptVO) { |
||||||
|
return defHttp.post({ url: '/system/dept/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改部门
|
||||||
|
export function updateDept(params: DeptVO) { |
||||||
|
return defHttp.put({ url: '/system/dept/update', data: params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除部门
|
||||||
|
export function deleteDept(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/dept/delete?id=${id}` }) |
||||||
} |
} |
||||||
|
@ -1,17 +0,0 @@ |
|||||||
export interface Department { |
|
||||||
id: string |
|
||||||
tenantId: string |
|
||||||
parentId: string |
|
||||||
deptName: string |
|
||||||
parentName: string |
|
||||||
deptTypeName: string |
|
||||||
children: Department[] |
|
||||||
hasChildren: boolean |
|
||||||
} |
|
||||||
|
|
||||||
export interface LazyGetDeptListParams { |
|
||||||
id?: string |
|
||||||
tenantId?: string |
|
||||||
parentId?: string |
|
||||||
deptName?: string |
|
||||||
} |
|
@ -0,0 +1,36 @@ |
|||||||
|
import type { DictDataExportReqVO, DictDataPageReqVO, DictDataVO } from './types' |
||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
// 查询字典数据(精简)列表
|
||||||
|
export function listSimpleDictData() { |
||||||
|
return defHttp.get({ url: '/system/dict-data/list-all-simple' }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询字典数据列表
|
||||||
|
export function getDictDataPage(params: DictDataPageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/dict-data/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询字典数据详情
|
||||||
|
export function getDictData(id: number) { |
||||||
|
return defHttp.get({ url: `/system/dict-data/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 新增字典数据
|
||||||
|
export function createDictData(data: DictDataVO) { |
||||||
|
return defHttp.post({ url: '/system/dict-data/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改字典数据
|
||||||
|
export function updateDictData(data: DictDataVO) { |
||||||
|
return defHttp.put({ url: '/system/dict-data/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除字典数据
|
||||||
|
export function deleteDictData(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/dict-data/delete?id=${id}` }) |
||||||
|
} |
||||||
|
// 导出字典类型数据
|
||||||
|
export function exportDictData(params: DictDataExportReqVO) { |
||||||
|
return defHttp.get({ url: '/system/dict-data/export', params }) |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
import type { DictTypeExportReqVO, DictTypePageReqVO, DictTypeVO } from './types' |
||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
// 查询字典(精简)列表
|
||||||
|
export function listSimpleDictType() { |
||||||
|
return defHttp.get({ url: '/system/dict-type/list-all-simple' }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询字典列表
|
||||||
|
export function getDictTypePage(params: DictTypePageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/dict-type/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询字典详情
|
||||||
|
export function getDictType(id: number) { |
||||||
|
return defHttp.get({ url: `/system/dict-type/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 新增字典
|
||||||
|
export function createDictType(data: DictTypeVO) { |
||||||
|
return defHttp.post({ url: '/system/dict-type/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改字典
|
||||||
|
export function updateDictType(data: DictTypeVO) { |
||||||
|
return defHttp.put({ url: '/system/dict-type/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除字典
|
||||||
|
export function deleteDictType(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/dict-type/delete?id=${id}` }) |
||||||
|
} |
||||||
|
// 导出字典类型
|
||||||
|
export function exportDictType(params: DictTypeExportReqVO) { |
||||||
|
return defHttp.get({ url: '/system/dict-type/export', params }) |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
export interface DictTypeVO { |
||||||
|
id: number |
||||||
|
name: string |
||||||
|
type: string |
||||||
|
status: number |
||||||
|
remark: string |
||||||
|
createTime: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface DictTypePageReqVO { |
||||||
|
name: string |
||||||
|
type: string |
||||||
|
status: number |
||||||
|
createTime: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
export interface DictTypeExportReqVO { |
||||||
|
name: string |
||||||
|
type: string |
||||||
|
status: number |
||||||
|
createTime: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
export interface DictDataVO { |
||||||
|
id: number |
||||||
|
sort: number |
||||||
|
label: string |
||||||
|
value: string |
||||||
|
dictType: string |
||||||
|
status: number |
||||||
|
colorType: string |
||||||
|
cssClass: string |
||||||
|
remark: string |
||||||
|
createTime: Date |
||||||
|
} |
||||||
|
export interface DictDataPageReqVO { |
||||||
|
label: string |
||||||
|
dictType: string |
||||||
|
status: number |
||||||
|
} |
||||||
|
|
||||||
|
export interface DictDataExportReqVO { |
||||||
|
label: string |
||||||
|
dictType: string |
||||||
|
status: number |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface ErrorCodeVO { |
||||||
|
id: number |
||||||
|
type: number |
||||||
|
applicationName: string |
||||||
|
code: number |
||||||
|
message: string |
||||||
|
memo: string |
||||||
|
createTime: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface ErrorCodePageReqVO extends PageParam { |
||||||
|
type?: number |
||||||
|
applicationName?: string |
||||||
|
code?: number |
||||||
|
message?: string |
||||||
|
createTime?: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
// 查询错误码列表
|
||||||
|
export function getErrorCodePage(params: ErrorCodePageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/error-code/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询错误码详情
|
||||||
|
export function getErrorCode(id: number) { |
||||||
|
return defHttp.get({ url: `/system/error-code/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 新增错误码
|
||||||
|
export function createErrorCode(data: ErrorCodeVO) { |
||||||
|
return defHttp.post({ url: '/system/error-code/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改错误码
|
||||||
|
export function updateErrorCode(data: ErrorCodeVO) { |
||||||
|
return defHttp.put({ url: '/system/error-code/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除错误码
|
||||||
|
export function deleteErrorCode(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/error-code/delete?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 导出错误码
|
||||||
|
export function excelErrorCode(params: ErrorCodePageReqVO) { |
||||||
|
return defHttp.download({ url: '/system/error-code/export-excel', params }, '错误码.xls') |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface LoginLogVO { |
||||||
|
id: number |
||||||
|
logType: number |
||||||
|
traceId: number |
||||||
|
userId: number |
||||||
|
userType: number |
||||||
|
username: string |
||||||
|
status: number |
||||||
|
userIp: string |
||||||
|
userAgent: string |
||||||
|
createTime: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface LoginLogReqVO extends PageParam { |
||||||
|
userIp?: string |
||||||
|
username?: string |
||||||
|
status?: boolean |
||||||
|
createTime?: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
// 查询登录日志列表
|
||||||
|
export function getLoginLogPage(params: LoginLogReqVO) { |
||||||
|
return defHttp.get({ url: '/system/login-log/page', params }) |
||||||
|
} |
||||||
|
// 导出登录日志
|
||||||
|
export function exportLoginLog(params: LoginLogReqVO) { |
||||||
|
return defHttp.download({ url: '/system/login-log/export', params }, '登录日志.xls') |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
// 创建邮箱账号
|
||||||
|
export function createMailAccount(data) { |
||||||
|
return defHttp.post({ url: '/system/mail-account/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 更新邮箱账号
|
||||||
|
export function updateMailAccount(data) { |
||||||
|
return defHttp.put({ url: '/system/mail-account/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除邮箱账号
|
||||||
|
export function deleteMailAccount(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/mail-account/delete?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得邮箱账号
|
||||||
|
export function getMailAccount(id: number) { |
||||||
|
return defHttp.get({ url: `/system/mail-account/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得邮箱账号分页
|
||||||
|
export function getMailAccountPage(params) { |
||||||
|
return defHttp.get({ url: '/system/mail-account/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获取邮箱账号的精简信息列表
|
||||||
|
export function getSimpleMailAccountList() { |
||||||
|
return defHttp.get({ url: '/system/mail-account/list-all-simple' }) |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
// 获得邮件日志
|
||||||
|
export function getMailLog(id: number) { |
||||||
|
return defHttp.get({ url: `/system/mail-log/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得邮件日志分页
|
||||||
|
export function getMailAccountPage(params) { |
||||||
|
return defHttp.get({ url: '/system/mail-log/page', params }) |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
// 创建邮件模版
|
||||||
|
export function createMailTemplate(data) { |
||||||
|
return defHttp.post({ url: '/system/mail-template/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 更新邮件模版
|
||||||
|
export function updateMailTemplate(data) { |
||||||
|
return defHttp.put({ url: '/system/mail-template/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除邮件模版
|
||||||
|
export function deleteMailTemplate(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/mail-template/delete?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得邮件模版
|
||||||
|
export function getMailTemplate(id: number) { |
||||||
|
return defHttp.get({ url: `/system/mail-template/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得邮件模版分页
|
||||||
|
export function getMailTemplatePage(params) { |
||||||
|
return defHttp.get({ url: '/system/mail-template/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 邮件模板
|
||||||
|
export interface MailTemplate { |
||||||
|
name: string // 标题
|
||||||
|
code: string // 编码
|
||||||
|
accountId: number |
||||||
|
nickname: string // 发送人
|
||||||
|
title: string // 标题
|
||||||
|
content: string // 内容
|
||||||
|
status: number //
|
||||||
|
remark?: any // 备注
|
||||||
|
id: number |
||||||
|
params: string[] // 模板里的参数
|
||||||
|
createTime: number |
||||||
|
} |
||||||
|
|
||||||
|
export interface SendMailParams { |
||||||
|
mail: string |
||||||
|
templateCode: string |
||||||
|
templateParams: { |
||||||
|
[key: string]: any |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 发送测试邮件
|
||||||
|
export function sendMail(data: SendMailParams) { |
||||||
|
return defHttp.post({ url: '/system/mail-template/send-mail', data }) |
||||||
|
} |
@ -1,41 +1,52 @@ |
|||||||
import type { GetMenuListParams, MenuItem } from './types' |
|
||||||
import { defHttp } from '@/utils/http/axios' |
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
export function getMenuListWithoutButtons() { |
export interface MenuVO { |
||||||
return defHttp.get<MenuItem[]>({ |
id: number |
||||||
url: '/system/menu/tree', |
name: string |
||||||
}) |
permission: string |
||||||
|
type: number |
||||||
|
sort: number |
||||||
|
parentId: number |
||||||
|
path: string |
||||||
|
icon: string |
||||||
|
component: string |
||||||
|
status: number |
||||||
|
visible: boolean |
||||||
|
keepAlive: boolean |
||||||
|
createTime: Date |
||||||
} |
} |
||||||
|
|
||||||
export function getMenuList(params: GetMenuListParams) { |
export interface MenuPageReqVO { |
||||||
return defHttp.get<PageResult<MenuItem>>({ |
name?: string |
||||||
url: '/system/menu/list', |
status?: number |
||||||
params, |
|
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function getMenu(id: string) { |
// 查询菜单(精简)列表
|
||||||
return defHttp.get({ |
export function listSimpleMenus() { |
||||||
url: `/system/menu/get?id=${id}`, |
return defHttp.get({ url: '/system/menu/list-all-simple' }) |
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function createMenu(data: Omit<MenuItem, 'id' | 'children'>) { |
// 查询菜单列表
|
||||||
return defHttp.post({ |
export function getMenuList(params: MenuPageReqVO) { |
||||||
url: '/system/menu/save', |
return defHttp.get({ url: '/system/menu/list', params }) |
||||||
data, |
|
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function updateMenu(data: Omit<MenuItem, 'children'>) { |
// 获取菜单详情
|
||||||
return defHttp.post({ |
export function getMenu(id: number) { |
||||||
url: '/system/menu/update', |
return defHttp.get({ url: `/system/menu/get?id=${id}` }) |
||||||
data, |
|
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function deleteMenu(id: string) { |
// 新增菜单
|
||||||
return defHttp.post({ |
export function createMenu(data: MenuVO) { |
||||||
url: `/system/menu/delete?id=${id}`, |
return defHttp.post({ url: '/system/menu/create', data }) |
||||||
}) |
} |
||||||
|
|
||||||
|
// 修改菜单
|
||||||
|
export function updateMenu(data: MenuVO) { |
||||||
|
return defHttp.put({ url: '/system/menu/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除菜单
|
||||||
|
export function deleteMenu(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/menu/delete?id=${id}` }) |
||||||
} |
} |
||||||
|
@ -1,26 +0,0 @@ |
|||||||
export interface GetMenuListParams { |
|
||||||
name?: string |
|
||||||
code?: string |
|
||||||
} |
|
||||||
|
|
||||||
export enum SystemMenuTypeEnum { |
|
||||||
DIR = 0, // 目录
|
|
||||||
MENU = 1, // 菜单
|
|
||||||
BUTTON = 2, // 按钮
|
|
||||||
} |
|
||||||
|
|
||||||
export interface MenuItem { |
|
||||||
id: string |
|
||||||
parentId: string |
|
||||||
name: string |
|
||||||
component: string |
|
||||||
componentName?: string |
|
||||||
path: string |
|
||||||
icon: string |
|
||||||
sort: number |
|
||||||
children: MenuItem[] |
|
||||||
code: string |
|
||||||
type: SystemMenuTypeEnum |
|
||||||
visible: BooleanFlag |
|
||||||
keepAlive: BooleanFlag |
|
||||||
} |
|
@ -0,0 +1,42 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface NoticeVO { |
||||||
|
id: number |
||||||
|
title: string |
||||||
|
type: number |
||||||
|
content: string |
||||||
|
status: number |
||||||
|
remark: string |
||||||
|
creator: string |
||||||
|
createTime: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface NoticePageReqVO extends PageParam { |
||||||
|
title?: string |
||||||
|
status?: number |
||||||
|
} |
||||||
|
|
||||||
|
// 查询公告列表
|
||||||
|
export function getNoticePage(params: NoticePageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/notice/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询公告详情
|
||||||
|
export function getNotice(id: number) { |
||||||
|
return defHttp.get({ url: `/system/notice/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 新增公告
|
||||||
|
export function createNotice(data: NoticeVO) { |
||||||
|
return defHttp.post({ url: '/system/notice/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改公告
|
||||||
|
export function updateNotice(data: NoticeVO) { |
||||||
|
return defHttp.put({ url: '/system/notice/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除公告
|
||||||
|
export function deleteNotice(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/notice/delete?id=${id}` }) |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
import qs from 'qs' |
||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
// 获得站内信分页
|
||||||
|
export function getNotifyMessagePage(params) { |
||||||
|
return defHttp.get({ url: '/system/notify-message/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得我的站内信分页
|
||||||
|
export function getMyNotifyMessagePage(params) { |
||||||
|
return defHttp.get({ url: '/system/notify-message/my-page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 批量标记已读
|
||||||
|
export function updateNotifyMessageRead(ids: number[]) { |
||||||
|
return defHttp.put({ url: `/system/notify-message/update-read?${qs.stringify({ ids }, { indices: false })}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 标记所有站内信为已读
|
||||||
|
export function updateAllNotifyMessageRead() { |
||||||
|
return defHttp.put({ url: '/system/notify-message/update-all-read' }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获取当前用户的最新站内信列表
|
||||||
|
export function getUnreadNotifyMessageList() { |
||||||
|
return defHttp.get({ url: '/system/notify-message/get-unread-list' }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得当前用户的未读站内信数量
|
||||||
|
export function getUnreadNotifyMessageCount() { |
||||||
|
return defHttp.get<number>({ url: '/system/notify-message/get-unread-count' }) |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
// 创建站内信模板
|
||||||
|
export function createNotifyTemplate(data) { |
||||||
|
return defHttp.post({ url: '/system/notify-template/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 更新站内信模板
|
||||||
|
export function updateNotifyTemplate(data) { |
||||||
|
return defHttp.put({ url: '/system/notify-template/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除站内信模板
|
||||||
|
export function deleteNotifyTemplate(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/notify-template/delete?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得站内信模板
|
||||||
|
export function getNotifyTemplate(id: number) { |
||||||
|
return defHttp.get({ url: `/system/notify-template/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得站内信模板分页
|
||||||
|
export function getNotifyTemplatePage(params) { |
||||||
|
return defHttp.get({ url: '/system/notify-template/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获取岗位精简信息列表
|
||||||
|
export function listSimplePosts() { |
||||||
|
return defHttp.get({ url: '/system/post/list-all-simple' }) |
||||||
|
} |
||||||
|
|
||||||
|
// 导出站内信模板 Excel
|
||||||
|
export function exportNotifyTemplateExcel(params) { |
||||||
|
return defHttp.download({ url: '/system/notify-template/export-excel', params }, '导出站内信模板.xls') |
||||||
|
} |
||||||
|
|
||||||
|
export interface SendNotifyParam { |
||||||
|
userId: number |
||||||
|
templateCode: string |
||||||
|
templateParams: { |
||||||
|
[key: string]: string |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export interface NotifyTemplate { |
||||||
|
name: string |
||||||
|
code: string |
||||||
|
type: number |
||||||
|
nickname: string |
||||||
|
content: string |
||||||
|
status: number |
||||||
|
remark?: any |
||||||
|
id: number |
||||||
|
params: string[] |
||||||
|
createTime: number |
||||||
|
key: string |
||||||
|
} |
||||||
|
|
||||||
|
// 发送
|
||||||
|
export function sendNotify(data: SendNotifyParam) { |
||||||
|
return defHttp.post({ url: '/system/notify-template/send-notify', data }) |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface OAuth2ClientVO { |
||||||
|
id: number |
||||||
|
clientId: string |
||||||
|
secret: string |
||||||
|
name: string |
||||||
|
logo: string |
||||||
|
description: string |
||||||
|
status: number |
||||||
|
accessTokenValiditySeconds: number |
||||||
|
refreshTokenValiditySeconds: number |
||||||
|
redirectUris: string[] |
||||||
|
autoApprove: boolean |
||||||
|
authorizedGrantTypes: string[] |
||||||
|
scopes: string[] |
||||||
|
authorities: string[] |
||||||
|
resourceIds: string[] |
||||||
|
additionalInformation: string |
||||||
|
isAdditionalInformationJson: boolean |
||||||
|
createTime: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface OAuth2ClientPageReqVO extends PageParam { |
||||||
|
name?: string |
||||||
|
status?: number |
||||||
|
} |
||||||
|
// 查询 OAuth2列表
|
||||||
|
export function getOAuth2ClientPage(params: OAuth2ClientPageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/oauth2-client/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询 OAuth2详情
|
||||||
|
export function getOAuth2Client(id: number) { |
||||||
|
return defHttp.get({ url: `/system/oauth2-client/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 新增 OAuth2
|
||||||
|
export function createOAuth2Client(data: OAuth2ClientVO) { |
||||||
|
return defHttp.post({ url: '/system/oauth2-client/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改 OAuth2
|
||||||
|
export function updateOAuth2Client(data: OAuth2ClientVO) { |
||||||
|
return defHttp.put({ url: '/system/oauth2-client/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除 OAuth2
|
||||||
|
export function deleteOAuth2Client(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/oauth2-client/delete?id=${id}` }) |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface OAuth2TokenVO { |
||||||
|
id: number |
||||||
|
accessToken: string |
||||||
|
refreshToken: string |
||||||
|
userId: number |
||||||
|
userType: number |
||||||
|
clientId: string |
||||||
|
createTime: Date |
||||||
|
expiresTime: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface OAuth2TokenPageReqVO extends PageParam { |
||||||
|
userId?: number |
||||||
|
userType?: number |
||||||
|
clientId?: string |
||||||
|
} |
||||||
|
|
||||||
|
// 查询 token列表
|
||||||
|
export function getAccessTokenPage(params: OAuth2TokenPageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/oauth2-token/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除 token
|
||||||
|
export function deleteAccessToken(accessToken: number) { |
||||||
|
return defHttp.delete({ url: `/system/oauth2-token/delete?accessToken=${accessToken}` }) |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface OperateLogVO { |
||||||
|
id: number |
||||||
|
userNickname: string |
||||||
|
traceId: string |
||||||
|
userId: number |
||||||
|
module: string |
||||||
|
name: string |
||||||
|
type: number |
||||||
|
content: string |
||||||
|
exts: Map<string, object> |
||||||
|
defHttpMethod: string |
||||||
|
defHttpUrl: string |
||||||
|
userIp: string |
||||||
|
userAgent: string |
||||||
|
javaMethod: string |
||||||
|
javaMethodArgs: string |
||||||
|
startTime: Date |
||||||
|
duration: number |
||||||
|
resultCode: number |
||||||
|
resultMsg: string |
||||||
|
resultData: string |
||||||
|
} |
||||||
|
|
||||||
|
export interface OperateLogPageReqVO extends PageParam { |
||||||
|
module?: string |
||||||
|
userNickname?: string |
||||||
|
type?: number |
||||||
|
success?: boolean |
||||||
|
startTime?: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
// 查询操作日志列表
|
||||||
|
export function getOperateLogPage(params: OperateLogPageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/operate-log/page', params }) |
||||||
|
} |
||||||
|
// 导出操作日志
|
||||||
|
export function exportOperateLog(params: OperateLogPageReqVO) { |
||||||
|
return defHttp.download({ url: '/system/operate-log/export', params }, '操作日志.xls') |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface PermissionAssignUserRoleReqVO { |
||||||
|
userId: number |
||||||
|
roleIds: number[] |
||||||
|
} |
||||||
|
|
||||||
|
export interface PermissionAssignRoleMenuReqVO { |
||||||
|
roleId: number |
||||||
|
menuIds: number[] |
||||||
|
} |
||||||
|
|
||||||
|
export interface PermissionAssignRoleDataScopeReqVO { |
||||||
|
roleId: number |
||||||
|
dataScope: number |
||||||
|
dataScopeDeptIds: number[] |
||||||
|
} |
||||||
|
|
||||||
|
// 查询角色拥有的菜单权限
|
||||||
|
export function listRoleMenus(roleId: number) { |
||||||
|
return defHttp.get({ url: `/system/permission/list-role-menus?roleId=${roleId}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 赋予角色菜单权限
|
||||||
|
export function assignRoleMenu(data: PermissionAssignRoleMenuReqVO) { |
||||||
|
return defHttp.post({ url: '/system/permission/assign-role-menu', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 赋予角色数据权限
|
||||||
|
export function assignRoleDataScope(data: PermissionAssignRoleDataScopeReqVO) { |
||||||
|
return defHttp.post({ url: '/system/permission/assign-role-data-scope', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询用户拥有的角色数组
|
||||||
|
export function listUserRoles(userId: number) { |
||||||
|
return defHttp.get({ url: `/system/permission/list-user-roles?userId=${userId}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 赋予用户角色
|
||||||
|
export function assignUserRole(data: PermissionAssignUserRoleReqVO) { |
||||||
|
return defHttp.post({ url: '/system/permission/assign-user-role', data }) |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface PostVO { |
||||||
|
id?: number |
||||||
|
name: string |
||||||
|
code: string |
||||||
|
sort: number |
||||||
|
status: number |
||||||
|
remark: string |
||||||
|
createTime?: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface PostPageReqVO extends PageParam { |
||||||
|
code?: string |
||||||
|
name?: string |
||||||
|
status?: number |
||||||
|
} |
||||||
|
|
||||||
|
export interface PostExportReqVO { |
||||||
|
code?: string |
||||||
|
name?: string |
||||||
|
status?: number |
||||||
|
} |
||||||
|
|
||||||
|
// 查询岗位列表
|
||||||
|
export function getPostPage(params: PostPageReqVO) { |
||||||
|
return defHttp.get<PageResult<PostVO>>({ url: '/system/post/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获取岗位精简信息列表
|
||||||
|
export function listSimplePosts() { |
||||||
|
return defHttp.get({ url: '/system/post/list-all-simple' }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询岗位详情
|
||||||
|
export function getPost(id: number) { |
||||||
|
return defHttp.get({ url: `/system/post/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 新增岗位
|
||||||
|
export function createPost(data) { |
||||||
|
return defHttp.post({ url: '/system/post/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改岗位
|
||||||
|
export function updatePost(data) { |
||||||
|
return defHttp.put({ url: '/system/post/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除岗位
|
||||||
|
export function deletePost(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/post/delete?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 导出岗位
|
||||||
|
export function exportPost(params: PostExportReqVO) { |
||||||
|
return defHttp.download({ url: '/system/post/export', params }, '导出岗位.xls') |
||||||
|
} |
@ -1,56 +1,70 @@ |
|||||||
import type { GetRoleListParams, MenuTreeNode, Role } from './types' |
|
||||||
import { defHttp } from '@/utils/http/axios' |
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
export function lazyGetRoleList(params: GetRoleListParams) { |
export interface RoleVO { |
||||||
return defHttp.get<Role[]>({ |
id: number |
||||||
url: '/system/role/lazy-list', |
name: string |
||||||
params, |
code: string |
||||||
}) |
sort: number |
||||||
|
status: number |
||||||
|
type: number |
||||||
|
createTime: Date |
||||||
} |
} |
||||||
|
|
||||||
export function createRole(data: Partial<Role>) { |
export interface RolePageReqVO extends PageParam { |
||||||
return defHttp.post({ |
name?: string |
||||||
url: '/system/role/save', |
code?: string |
||||||
data, |
status?: number |
||||||
}) |
createTime?: Date[] |
||||||
} |
} |
||||||
|
|
||||||
export function updateRole(data: Partial<Role>) { |
export interface UpdateStatusReqVO { |
||||||
return defHttp.post({ |
id: number |
||||||
url: '/system/role/update', |
status: number |
||||||
data, |
|
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function deleteRole(id: string) { |
export interface RoleExportReqVO { |
||||||
return defHttp.post({ |
name?: string |
||||||
url: `/system/role/delete?id=${id}`, |
code?: string |
||||||
}) |
status?: number |
||||||
|
createTime?: Date[] |
||||||
} |
} |
||||||
|
|
||||||
export function getRoleTree(params?: { tenantId: string }) { |
// 查询角色列表
|
||||||
return defHttp.get<{ id: string, title: string }[]>({ |
export function getRolePage(params: RolePageReqVO) { |
||||||
url: '/system/role/tree', |
return defHttp.get({ url: '/system/role/page', params }) |
||||||
params, |
|
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function getMenuTree() { |
// 查询角色(精简)列表
|
||||||
return defHttp.get<MenuTreeNode[]>({ |
export function listSimpleRoles() { |
||||||
url: '/system/menu/grant-tree', |
return defHttp.get({ url: '/system/role/list-all-simple' }) |
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function getMenuIdsByRole(roleId: string) { |
// 查询角色详情
|
||||||
return defHttp.get<string[]>({ |
export function getRole(id: number) { |
||||||
url: '/system/permission/list-role-menus', |
return defHttp.get({ url: `/system/role/get?id=${id}` }) |
||||||
params: { roleId }, |
|
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function assignMenuToRole(data: { roleId: string, menuIds: string[] }) { |
// 新增角色
|
||||||
return defHttp.post({ |
export function createRole(data: RoleVO) { |
||||||
url: '/system/permission/assign-role-menu', |
return defHttp.post({ url: '/system/role/create', data }) |
||||||
data, |
} |
||||||
}) |
|
||||||
|
// 修改角色
|
||||||
|
export function updateRole(data: RoleVO) { |
||||||
|
return defHttp.put({ url: '/system/role/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改角色状态
|
||||||
|
export function updateRoleStatus(data: UpdateStatusReqVO) { |
||||||
|
return defHttp.put({ url: '/system/role/update-status', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除角色
|
||||||
|
export function deleteRole(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/role/delete?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 导出角色
|
||||||
|
export function exportRole(params: RoleExportReqVO) { |
||||||
|
return defHttp.download({ url: '/system/post/export', params }, '导出角色.xls') |
||||||
} |
} |
||||||
|
@ -1,29 +0,0 @@ |
|||||||
export interface GetRoleListParams extends PageParam { |
|
||||||
tenantId?: string |
|
||||||
parentId?: string |
|
||||||
roleName?: string |
|
||||||
roleAlias?: string |
|
||||||
} |
|
||||||
|
|
||||||
export interface Role { |
|
||||||
id: string |
|
||||||
tenantId: string |
|
||||||
tenantName: string |
|
||||||
parentId: string |
|
||||||
roleName: string |
|
||||||
roleAlias: string |
|
||||||
createTime?: string |
|
||||||
createUser?: string |
|
||||||
createDept?: string |
|
||||||
updateTime?: string |
|
||||||
updateUser?: string |
|
||||||
hasChildren?: boolean |
|
||||||
children?: Role[] |
|
||||||
} |
|
||||||
|
|
||||||
export interface MenuTreeNode { |
|
||||||
id: string |
|
||||||
parentId: string |
|
||||||
title: string |
|
||||||
children?: MenuTreeNode[] |
|
||||||
} |
|
@ -0,0 +1,64 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface SensitiveWordVO { |
||||||
|
id: number |
||||||
|
name: string |
||||||
|
status: number |
||||||
|
description: string |
||||||
|
tags: string[] |
||||||
|
createTime: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface SensitiveWordPageReqVO extends PageParam { |
||||||
|
name?: string |
||||||
|
tag?: string |
||||||
|
status?: number |
||||||
|
createTime?: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
export interface SensitiveWordExportReqVO { |
||||||
|
name?: string |
||||||
|
tag?: string |
||||||
|
status?: number |
||||||
|
createTime?: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
// 查询敏感词列表
|
||||||
|
export function getSensitiveWordPage(params: SensitiveWordPageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/sensitive-word/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询敏感词详情
|
||||||
|
export function getSensitiveWord(id: number) { |
||||||
|
return defHttp.get({ url: `/system/sensitive-word/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 新增敏感词
|
||||||
|
export function createSensitiveWord(data: SensitiveWordVO) { |
||||||
|
return defHttp.post({ url: '/system/sensitive-word/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改敏感词
|
||||||
|
export function updateSensitiveWord(data: SensitiveWordVO) { |
||||||
|
return defHttp.put({ url: '/system/sensitive-word/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除敏感词
|
||||||
|
export function deleteSensitiveWord(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/sensitive-word/delete?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 导出敏感词
|
||||||
|
export function exportSensitiveWord(params: SensitiveWordExportReqVO) { |
||||||
|
return defHttp.download({ url: '/system/sensitive-word/export-excel', params }, '导出敏感词.xls') |
||||||
|
} |
||||||
|
|
||||||
|
// 获取所有敏感词的标签数组
|
||||||
|
export function getSensitiveWordTags() { |
||||||
|
return defHttp.get({ url: '/system/sensitive-word/get-tags' }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得文本所包含的不合法的敏感词数组
|
||||||
|
export function validateText(id: number) { |
||||||
|
return defHttp.get({ url: `/system/sensitive-word/validate-text?${id}` }) |
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface SmsChannelVO { |
||||||
|
id: number |
||||||
|
code: string |
||||||
|
status: number |
||||||
|
signature: string |
||||||
|
remark: string |
||||||
|
apiKey: string |
||||||
|
apiSecret: string |
||||||
|
callbackUrl: string |
||||||
|
createTime: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface SmsChannelPageReqVO extends PageParam { |
||||||
|
signature?: string |
||||||
|
code?: string |
||||||
|
status?: number |
||||||
|
createTime?: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
// 查询短信渠道列表
|
||||||
|
export function getSmsChannelPage(params: SmsChannelPageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/sms-channel/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得短信渠道精简列表
|
||||||
|
export function getSimpleSmsChannels() { |
||||||
|
return defHttp.get({ url: '/system/sms-channel/list-all-simple' }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询短信渠道详情
|
||||||
|
export function getSmsChannel(id: number) { |
||||||
|
return defHttp.get({ url: `/system/sms-channel/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 新增短信渠道
|
||||||
|
export function createSmsChannel(data: SmsChannelVO) { |
||||||
|
return defHttp.post({ url: '/system/sms-channel/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改短信渠道
|
||||||
|
export function updateSmsChannel(data: SmsChannelVO) { |
||||||
|
return defHttp.put({ url: '/system/sms-channel/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除短信渠道
|
||||||
|
export function deleteSmsChannel(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/sms-channel/delete?id=${id}` }) |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface SmsLogVO { |
||||||
|
id: number |
||||||
|
channelId: number |
||||||
|
channelCode: string |
||||||
|
templateId: number |
||||||
|
templateCode: string |
||||||
|
templateType: number |
||||||
|
templateContent: string |
||||||
|
templateParams: Map<string, object> |
||||||
|
mobile: string |
||||||
|
userId: number |
||||||
|
userType: number |
||||||
|
sendStatus: number |
||||||
|
sendTime: Date |
||||||
|
apiSendCode: string |
||||||
|
apiSendMsg: string |
||||||
|
apidefHttpId: string |
||||||
|
apiSerialNo: string |
||||||
|
receiveStatus: number |
||||||
|
receiveTime: Date |
||||||
|
apiReceiveCode: string |
||||||
|
apiReceiveMsg: string |
||||||
|
createTime: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface SmsLogPageReqVO extends PageParam { |
||||||
|
channelId?: number |
||||||
|
templateId?: number |
||||||
|
mobile?: string |
||||||
|
sendStatus?: number |
||||||
|
sendTime?: Date[] |
||||||
|
receiveStatus?: number |
||||||
|
receiveTime?: Date[] |
||||||
|
} |
||||||
|
export interface SmsLogExportReqVO { |
||||||
|
channelId?: number |
||||||
|
templateId?: number |
||||||
|
mobile?: string |
||||||
|
sendStatus?: number |
||||||
|
sendTime?: Date[] |
||||||
|
receiveStatus?: number |
||||||
|
receiveTime?: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
// 查询短信日志列表
|
||||||
|
export function getSmsLogPage(params: SmsLogPageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/sms-log/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 导出短信日志
|
||||||
|
export function exportSmsLog(params: SmsLogExportReqVO) { |
||||||
|
return defHttp.download({ url: '/system/sms-log/export', params }, '短信日志.xls') |
||||||
|
} |
@ -0,0 +1,94 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface SmsTemplateVO { |
||||||
|
id: number |
||||||
|
type: number |
||||||
|
status: number |
||||||
|
code: string |
||||||
|
name: string |
||||||
|
content: string |
||||||
|
remark: string |
||||||
|
apiTemplateId: string |
||||||
|
channelId: number |
||||||
|
channelCode: string |
||||||
|
params: string[] |
||||||
|
createTime: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface SendSmsReqVO { |
||||||
|
mobile: string |
||||||
|
templateCode: string |
||||||
|
templateParams: { |
||||||
|
[key: string]: any |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export interface SmsTemplatePageReqVO { |
||||||
|
type?: number |
||||||
|
status?: number |
||||||
|
code?: string |
||||||
|
content?: string |
||||||
|
apiTemplateId?: string |
||||||
|
channelId?: number |
||||||
|
createTime?: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
export interface SmsTemplateExportReqVO { |
||||||
|
type?: number |
||||||
|
status?: number |
||||||
|
code?: string |
||||||
|
content?: string |
||||||
|
apiTemplateId?: string |
||||||
|
channelId?: number |
||||||
|
createTime?: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
// 查询短信模板列表
|
||||||
|
export function getSmsTemplatePage(params: SmsTemplatePageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/sms-template/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 查询短信模板详情
|
||||||
|
export function getSmsTemplate(id: number) { |
||||||
|
return defHttp.get({ url: `/system/sms-template/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 新增短信模板
|
||||||
|
export function createSmsTemplate(data: SmsTemplateVO) { |
||||||
|
return defHttp.post({ url: '/system/sms-template/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改短信模板
|
||||||
|
export function updateSmsTemplate(data: SmsTemplateVO) { |
||||||
|
return defHttp.put({ url: '/system/sms-template/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除短信模板
|
||||||
|
export function deleteSmsTemplate(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/sms-template/delete?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 邮件模板
|
||||||
|
export interface SmsTemplate { |
||||||
|
name: string // 标题
|
||||||
|
code: string // 编码
|
||||||
|
accountId: number |
||||||
|
nickname: string // 发送人
|
||||||
|
title: string // 标题
|
||||||
|
content: string // 内容
|
||||||
|
status: number //
|
||||||
|
remark?: any // 备注
|
||||||
|
id: number |
||||||
|
params: string[] // 模板里的参数
|
||||||
|
createTime: number |
||||||
|
} |
||||||
|
|
||||||
|
// 发送短信
|
||||||
|
export function sendSms(data: SendSmsReqVO) { |
||||||
|
return defHttp.post({ url: '/system/sms-template/send-sms', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 导出短信模板
|
||||||
|
export function exportSmsTemplate(params: SmsTemplateExportReqVO) { |
||||||
|
return defHttp.download({ url: '/system/sms-template/export-excel', params }, '短信模板.xls') |
||||||
|
} |
@ -1,35 +1,62 @@ |
|||||||
import type { GetTenantListParams, Tenant } from './types' |
|
||||||
import { defHttp } from '@/utils/http/axios' |
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
export function getTenantList(params: GetTenantListParams) { |
export interface TenantVO { |
||||||
return defHttp.get<PageResult<Tenant>>({ |
id: number |
||||||
url: '/system/tenant/page', |
name: string |
||||||
params, |
contactName: string |
||||||
}) |
contactMobile: string |
||||||
|
status: number |
||||||
|
domain: string |
||||||
|
packageId: number |
||||||
|
username: string |
||||||
|
password: string |
||||||
|
expireTime: Date |
||||||
|
accountCount: number |
||||||
|
createTime: Date |
||||||
} |
} |
||||||
|
|
||||||
export function updateTenant(data: Tenant) { |
export interface TenantPageReqVO extends PageParam { |
||||||
return defHttp.post({ |
name?: string |
||||||
url: '/system/tenant/update', |
contactName?: string |
||||||
data, |
contactMobile?: string |
||||||
}) |
status?: number |
||||||
|
createTime?: Date[] |
||||||
} |
} |
||||||
|
|
||||||
export function createTenant(data: Tenant) { |
export interface TenantExportReqVO { |
||||||
return defHttp.post({ |
name?: string |
||||||
url: '/system/tenant/save', |
contactName?: string |
||||||
data, |
contactMobile?: string |
||||||
}) |
status?: number |
||||||
|
createTime?: Date[] |
||||||
} |
} |
||||||
|
|
||||||
export function deleteTenant(id: string) { |
// 查询租户列表
|
||||||
return defHttp.post({ |
export function getTenantPage(params: TenantPageReqVO) { |
||||||
url: `/system/tenant/remove?id=${id}`, |
return defHttp.get({ url: '/system/tenant/page', params }) |
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
export function getAllTenants() { |
// 查询租户详情
|
||||||
return defHttp.get({ |
export function getTenant(id: number) { |
||||||
url: '/system/tenant/select', |
return defHttp.get({ url: `/system/tenant/get?id=${id}` }) |
||||||
}) |
} |
||||||
|
|
||||||
|
// 新增租户
|
||||||
|
export function createTenant(data: TenantVO) { |
||||||
|
return defHttp.post({ url: '/system/tenant/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改租户
|
||||||
|
export function updateTenant(data: TenantVO) { |
||||||
|
return defHttp.put({ url: '/system/tenant/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除租户
|
||||||
|
export function deleteTenant(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/tenant/delete?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 导出租户
|
||||||
|
export function exportTenant(params: TenantExportReqVO) { |
||||||
|
return defHttp.download({ url: '/system/tenant/export-excel', params }, '租户.xls') |
||||||
} |
} |
||||||
|
@ -1,16 +0,0 @@ |
|||||||
export interface Tenant { |
|
||||||
id: string |
|
||||||
tenantId?: string |
|
||||||
tenantName: string |
|
||||||
adminAccount: string |
|
||||||
contactName: string |
|
||||||
contactMobile: string |
|
||||||
expireTime?: string |
|
||||||
} |
|
||||||
|
|
||||||
export interface GetTenantListParams extends PageParam { |
|
||||||
tenantId?: string |
|
||||||
tenantName?: string |
|
||||||
contactName?: string |
|
||||||
contactMobile?: string |
|
||||||
} |
|
@ -0,0 +1,49 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
export interface TenantPackageVO { |
||||||
|
id: number |
||||||
|
name: string |
||||||
|
status: number |
||||||
|
remark: string |
||||||
|
creator: string |
||||||
|
updater: string |
||||||
|
updateTime: string |
||||||
|
menuIds: number[] |
||||||
|
createTime: Date |
||||||
|
} |
||||||
|
|
||||||
|
export interface TenantPackagePageReqVO extends PageParam { |
||||||
|
name?: string |
||||||
|
status?: number |
||||||
|
remark?: string |
||||||
|
createTime?: Date[] |
||||||
|
} |
||||||
|
|
||||||
|
// 查询租户套餐列表
|
||||||
|
export function getTenantPackagePage(params: TenantPackagePageReqVO) { |
||||||
|
return defHttp.get({ url: '/system/tenant-package/page', params }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获得租户
|
||||||
|
export function getTenantPackage(id: number) { |
||||||
|
return defHttp.get({ url: `/system/tenant-package/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 新增租户套餐
|
||||||
|
export function createTenantPackage(data: TenantPackageVO) { |
||||||
|
return defHttp.post({ url: '/system/tenant-package/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改租户套餐
|
||||||
|
export function updateTenantPackage(data: TenantPackageVO) { |
||||||
|
return defHttp.put({ url: '/system/tenant-package/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除租户套餐
|
||||||
|
export function deleteTenantPackage(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/tenant-package/delete?id=${id}` }) |
||||||
|
} |
||||||
|
// 获取租户套餐精简信息列表
|
||||||
|
export function getTenantPackageList() { |
||||||
|
return defHttp.get({ url: '/system/tenant-package/get-simple-list' }) |
||||||
|
} |
@ -1,29 +1,91 @@ |
|||||||
import type { GetUserListParams, SystemUser } from './types' |
|
||||||
import { defHttp } from '@/utils/http/axios' |
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
export function getUserList(params: GetUserListParams) { |
export interface UserVO { |
||||||
return defHttp.get<PageResult<SystemUser>>({ |
id: number |
||||||
url: '/system/user/page', |
username: string |
||||||
params, |
nickname: string |
||||||
}) |
deptId: number |
||||||
|
postIds: string[] |
||||||
|
email: string |
||||||
|
mobile: string |
||||||
|
sex: number |
||||||
|
avatar: string |
||||||
|
loginIp: string |
||||||
|
status: number |
||||||
|
remark: string |
||||||
|
loginDate: Date |
||||||
|
createTime: Date |
||||||
} |
} |
||||||
|
|
||||||
export function createUser(data: Partial<SystemUser>) { |
export interface UserPageReqVO extends PageParam { |
||||||
return defHttp.post({ |
deptId?: number |
||||||
url: '/system/user/save', |
username?: string |
||||||
data, |
mobile?: string |
||||||
}) |
status?: number |
||||||
|
createTime?: Date[] |
||||||
} |
} |
||||||
|
|
||||||
export function updateUser(data: Partial<SystemUser>) { |
export interface UserExportReqVO { |
||||||
return defHttp.post({ |
code?: string |
||||||
url: '/system/user/update', |
name?: string |
||||||
data, |
status?: number |
||||||
}) |
createTime?: Date[] |
||||||
} |
} |
||||||
|
|
||||||
export function deleteUser(id: string) { |
// 查询用户管理列表
|
||||||
return defHttp.post({ |
export function getUserPage(params: UserPageReqVO) { |
||||||
url: `/system/user/delete?id=${id}`, |
return defHttp.get({ url: '/system/user/page', params }) |
||||||
}) |
} |
||||||
|
|
||||||
|
// 查询用户详情
|
||||||
|
export function getUser(id: number) { |
||||||
|
return defHttp.get({ url: `/system/user/get?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 新增用户
|
||||||
|
export function createUser(data: UserVO) { |
||||||
|
return defHttp.post({ url: '/system/user/create', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 修改用户
|
||||||
|
export function updateUser(data: UserVO) { |
||||||
|
return defHttp.put({ url: '/system/user/update', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 删除用户
|
||||||
|
export function deleteUser(id: number) { |
||||||
|
return defHttp.delete({ url: `/system/user/delete?id=${id}` }) |
||||||
|
} |
||||||
|
|
||||||
|
// 导出用户
|
||||||
|
export function exportUser(params: UserExportReqVO) { |
||||||
|
return defHttp.download({ url: '/system/user/export', params }, '用户.xls') |
||||||
|
} |
||||||
|
|
||||||
|
// 下载用户导入模板
|
||||||
|
export function importUserTemplate() { |
||||||
|
return defHttp.download({ url: '/system/user/get-import-template' }, '用户导入模板.xls') |
||||||
|
} |
||||||
|
|
||||||
|
// 用户密码重置
|
||||||
|
export function resetUserPwd(id: number, password: string) { |
||||||
|
const data = { |
||||||
|
id, |
||||||
|
password, |
||||||
|
} |
||||||
|
return defHttp.put({ url: '/system/user/update-password', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 用户状态修改
|
||||||
|
export function updateUserStatus(id: number, status: number) { |
||||||
|
const data = { |
||||||
|
id, |
||||||
|
status, |
||||||
|
} |
||||||
|
return defHttp.put({ url: '/system/user/update-status', data }) |
||||||
|
} |
||||||
|
|
||||||
|
// 获取用户精简信息列表
|
||||||
|
export function getListSimpleUsers() { |
||||||
|
return defHttp.get({ url: '/system/user/list-all-simple' }) |
||||||
} |
} |
||||||
|
@ -1,23 +0,0 @@ |
|||||||
export interface GetUserListParams extends PageParam { |
|
||||||
tenantId?: string |
|
||||||
deptId?: string |
|
||||||
account?: string |
|
||||||
mobile?: string |
|
||||||
} |
|
||||||
|
|
||||||
export interface SystemUser { |
|
||||||
id: string |
|
||||||
account: string |
|
||||||
avatar: string |
|
||||||
deptId: string |
|
||||||
deptName: string |
|
||||||
email: string |
|
||||||
mobile: string |
|
||||||
realName: string |
|
||||||
remark: string |
|
||||||
roleId: string |
|
||||||
roleName: string |
|
||||||
sex: 1 | 2 | 3 |
|
||||||
tenantId: string |
|
||||||
tenantName: string |
|
||||||
} |
|
@ -0,0 +1,4 @@ |
|||||||
|
import dictTag from './src/DictTag.vue' |
||||||
|
import { withInstall } from '@/utils' |
||||||
|
|
||||||
|
export const DictTag = withInstall(dictTag) |
@ -0,0 +1,72 @@ |
|||||||
|
<script lang="tsx"> |
||||||
|
import type { PropType } from 'vue' |
||||||
|
import { defineComponent, ref } from 'vue' |
||||||
|
import { Tag } from 'ant-design-vue' |
||||||
|
import { isHexColor } from '@/utils/color' |
||||||
|
import type { DictDataType } from '@/utils/dict' |
||||||
|
import { getDictOpts } from '@/utils/dict' |
||||||
|
import { propTypes } from '@/utils/propTypes' |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'DictTag', |
||||||
|
props: { |
||||||
|
type: { |
||||||
|
type: String as PropType<string>, |
||||||
|
required: true, |
||||||
|
}, |
||||||
|
value: propTypes.oneOfType([propTypes.string, propTypes.number, propTypes.bool]), |
||||||
|
icon: { type: String }, |
||||||
|
}, |
||||||
|
setup(props) { |
||||||
|
const dictData = ref<DictDataType>() |
||||||
|
const getDictObj = (dictType: string, value: string) => { |
||||||
|
let dictOptions: DictDataType[] = [] |
||||||
|
dictOptions = getDictOpts(dictType) |
||||||
|
if (dictOptions && dictOptions.length === 0) |
||||||
|
return |
||||||
|
|
||||||
|
dictOptions.forEach((dict: DictDataType) => { |
||||||
|
if (dict.value === value) { |
||||||
|
if (`${dict.colorType}` === 'primary') |
||||||
|
dict.colorType = 'processing' |
||||||
|
else if (`${dict.colorType}` === 'danger') |
||||||
|
dict.colorType = 'error' |
||||||
|
else if (`${dict.colorType}` === 'info') |
||||||
|
dict.colorType = 'default' |
||||||
|
|
||||||
|
dictData.value = dict |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
const rederDictTag = () => { |
||||||
|
if (!props.type) |
||||||
|
return null |
||||||
|
|
||||||
|
// 解决自定义字典标签值为零时标签不渲染的问题 |
||||||
|
if (props.value === undefined || props.value === null) |
||||||
|
return null |
||||||
|
|
||||||
|
getDictObj(props.type, props.value.toString()) |
||||||
|
|
||||||
|
if (dictData.value === undefined) |
||||||
|
return null |
||||||
|
|
||||||
|
// 添加标签的文字颜色为白色,解决自定义背景颜色时标签文字看不清的问题 && isHexColor(dictData.value?.cssClass) |
||||||
|
return ( |
||||||
|
<Tag |
||||||
|
color={ |
||||||
|
dictData.value?.colorType |
||||||
|
? dictData.value?.colorType |
||||||
|
: dictData.value?.cssClass && isHexColor(dictData.value?.cssClass) |
||||||
|
? dictData.value?.cssClass |
||||||
|
: '' |
||||||
|
} |
||||||
|
> |
||||||
|
{dictData.value?.label || ''} |
||||||
|
</Tag> |
||||||
|
) |
||||||
|
} |
||||||
|
return () => rederDictTag() |
||||||
|
}, |
||||||
|
}) |
||||||
|
</script> |
@ -0,0 +1,67 @@ |
|||||||
|
import { defineStore } from 'pinia' |
||||||
|
import type { DictState } from '@/types/store' |
||||||
|
|
||||||
|
import { store } from '@/store' |
||||||
|
|
||||||
|
import { DICT_KEY } from '@/enums/cacheEnum' |
||||||
|
import { createLocalStorage } from '@/utils/cache' |
||||||
|
import { listSimpleDictData } from '@/api/system/dict/data' |
||||||
|
import type { DictDataVO } from '@/api/system/dict/types' |
||||||
|
|
||||||
|
const ls = createLocalStorage() |
||||||
|
|
||||||
|
export const useDictStore = defineStore({ |
||||||
|
id: 'app-dict', |
||||||
|
state: (): DictState => ({ |
||||||
|
dictMap: new Map<string, any>(), |
||||||
|
isSetDict: false, |
||||||
|
}), |
||||||
|
getters: { |
||||||
|
getDictMap(state): Recordable { |
||||||
|
const dictMap = ls.get(DICT_KEY) |
||||||
|
if (dictMap) |
||||||
|
state.dictMap = dictMap |
||||||
|
|
||||||
|
return state.dictMap |
||||||
|
}, |
||||||
|
getIsSetDict(state): boolean { |
||||||
|
return state.isSetDict |
||||||
|
}, |
||||||
|
}, |
||||||
|
actions: { |
||||||
|
async setDictMap() { |
||||||
|
const dictMap = ls.get(DICT_KEY) |
||||||
|
if (dictMap) { |
||||||
|
this.dictMap = dictMap |
||||||
|
this.isSetDict = true |
||||||
|
} |
||||||
|
else { |
||||||
|
const res = await listSimpleDictData() |
||||||
|
// 设置数据
|
||||||
|
const dictDataMap = new Map<string, any>() |
||||||
|
res.forEach((dictData: DictDataVO) => { |
||||||
|
// 获得 dictType 层级
|
||||||
|
const enumValueObj = dictDataMap[dictData.dictType] |
||||||
|
if (!enumValueObj) |
||||||
|
dictDataMap[dictData.dictType] = [] |
||||||
|
|
||||||
|
// 处理 dictValue 层级
|
||||||
|
dictDataMap[dictData.dictType].push({ |
||||||
|
value: dictData.value, |
||||||
|
label: dictData.label, |
||||||
|
colorType: dictData.colorType, |
||||||
|
cssClass: dictData.cssClass, |
||||||
|
}) |
||||||
|
}) |
||||||
|
this.dictMap = dictDataMap |
||||||
|
this.isSetDict = true |
||||||
|
ls.set(DICT_KEY, dictDataMap, 60) // 60 秒 过期
|
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
}) |
||||||
|
|
||||||
|
// Need to be used outside the setup
|
||||||
|
export function useDictStoreWithOut() { |
||||||
|
return useDictStore(store) |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
import { defineStore } from 'pinia' |
||||||
|
import { getUnreadNotifyMessageCount } from '@/api/system/notify/message' |
||||||
|
|
||||||
|
interface MessageState { |
||||||
|
unreadCount: number // 未读消息数量
|
||||||
|
} |
||||||
|
|
||||||
|
export const useUserMessageStore = defineStore('userMessage', { |
||||||
|
state: (): MessageState => ({ |
||||||
|
unreadCount: 0, |
||||||
|
}), |
||||||
|
getters: { |
||||||
|
getUnreadCount(state) { |
||||||
|
return state.unreadCount |
||||||
|
}, |
||||||
|
}, |
||||||
|
actions: { |
||||||
|
// 更新未读消息的数量
|
||||||
|
async updateUnreadCount() { |
||||||
|
const count = await getUnreadNotifyMessageCount() |
||||||
|
this.unreadCount = count |
||||||
|
}, |
||||||
|
}, |
||||||
|
}) |
@ -0,0 +1,97 @@ |
|||||||
|
/** |
||||||
|
* 数据字典工具类 |
||||||
|
*/ |
||||||
|
import { useDictStoreWithOut } from '@/store/modules/dict' |
||||||
|
import type { StringLiteralsToType } from '@/types/utils' |
||||||
|
|
||||||
|
const dictStore = useDictStoreWithOut() |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取 dictType 对应的数据字典数组 |
||||||
|
* |
||||||
|
* @param dictType 数据类型 |
||||||
|
* @returns {*|Array} 数据字典数组 |
||||||
|
*/ |
||||||
|
export interface DictDataType<T extends string | number | boolean = string> { |
||||||
|
dictType: string |
||||||
|
label: string |
||||||
|
value: T |
||||||
|
key?: any |
||||||
|
colorType: string |
||||||
|
cssClass: string |
||||||
|
} |
||||||
|
|
||||||
|
export function getDictDatas(dictType: string) { |
||||||
|
return dictStore.getDictMap[dictType] || [] |
||||||
|
} |
||||||
|
|
||||||
|
export function getDictOpts(dictType: string) { |
||||||
|
/** |
||||||
|
* 这里原来是转换类型 转换类型后反而显示不出来正确的Tag |
||||||
|
* 实际类型转换交给下面的getDictOptions来处理 |
||||||
|
* |
||||||
|
* bugfix: |
||||||
|
* dictOption.push({ |
||||||
|
...dict, |
||||||
|
value: parseInt(dict.value + '') |
||||||
|
}) |
||||||
|
原来的这种写法是造成页面卡死的原因 |
||||||
|
*/ |
||||||
|
return getDictDatas(dictType) |
||||||
|
} |
||||||
|
|
||||||
|
export function getDictOptions<T extends 'string' | 'number' | 'boolean' = 'string'>(dictType: string, valueType?: T) { |
||||||
|
const dictOption: DictDataType<StringLiteralsToType<T>>[] = [] |
||||||
|
const dictOptions: DictDataType[] = getDictDatas(dictType) |
||||||
|
if (dictOptions && dictOptions.length > 0) { |
||||||
|
dictOptions.forEach((dict: DictDataType) => { |
||||||
|
dictOption.push({ |
||||||
|
...dict, |
||||||
|
key: dict.value, |
||||||
|
value: |
||||||
|
valueType === 'string' |
||||||
|
? `${dict.value}` |
||||||
|
: valueType === 'boolean' |
||||||
|
? `${dict.value}` === 'true' |
||||||
|
: Number.parseInt(`${dict.value}`), |
||||||
|
} as DictDataType<StringLiteralsToType<T>>) |
||||||
|
}) |
||||||
|
} |
||||||
|
return dictOption |
||||||
|
} |
||||||
|
|
||||||
|
export function getDictObj(dictType: string, value: any) { |
||||||
|
const dictOptions: DictDataType[] = getDictDatas(dictType) |
||||||
|
if (dictOptions) { |
||||||
|
dictOptions.forEach((dict: DictDataType) => { |
||||||
|
if (dict.value === value.toString()) |
||||||
|
return dict |
||||||
|
}) |
||||||
|
} |
||||||
|
else { |
||||||
|
return null |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export enum DICT_TYPE { |
||||||
|
USER_TYPE = 'user_type', |
||||||
|
COMMON_STATUS = 'common_status', |
||||||
|
SYSTEM_TENANT_PACKAGE_ID = 'system_tenant_package_id', |
||||||
|
SYSTEM_USER_SEX = 'system_user_sex', |
||||||
|
SYSTEM_MENU_TYPE = 'system_menu_type', |
||||||
|
SYSTEM_ROLE_TYPE = 'system_role_type', |
||||||
|
SYSTEM_DATA_SCOPE = 'system_data_scope', |
||||||
|
SYSTEM_NOTICE_TYPE = 'system_notice_type', |
||||||
|
SYSTEM_OPERATE_TYPE = 'system_operate_type', |
||||||
|
SYSTEM_LOGIN_TYPE = 'system_login_type', |
||||||
|
SYSTEM_LOGIN_RESULT = 'system_login_result', |
||||||
|
SYSTEM_SMS_CHANNEL_CODE = 'system_sms_channel_code', |
||||||
|
SYSTEM_SMS_TEMPLATE_TYPE = 'system_sms_template_type', |
||||||
|
SYSTEM_SMS_SEND_STATUS = 'system_sms_send_status', |
||||||
|
SYSTEM_SMS_RECEIVE_STATUS = 'system_sms_receive_status', |
||||||
|
SYSTEM_ERROR_CODE_TYPE = 'system_error_code_type', |
||||||
|
SYSTEM_OAUTH2_GRANT_TYPE = 'system_oauth2_grant_type', |
||||||
|
SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status', |
||||||
|
SYSTEM_NOTIFY_TEMPLATE_TYPE = 'system_notify_template_type', |
||||||
|
INFRA_BOOLEAN_STRING = 'infra_boolean_string', |
||||||
|
} |
@ -0,0 +1,155 @@ |
|||||||
|
<script lang="ts" setup> |
||||||
|
import { computed, reactive, ref, unref } from 'vue' |
||||||
|
import { Form, Input } from 'ant-design-vue' |
||||||
|
import LoginFormTitle from './LoginFormTitle.vue' |
||||||
|
import { LoginStateEnum, useFormRules, useFormValid, useLoginState } from './useLogin' |
||||||
|
import { CountdownInput } from '@/components/CountDown' |
||||||
|
import { useI18n } from '@/hooks/web/useI18n' |
||||||
|
import { useMessage } from '@/hooks/web/useMessage' |
||||||
|
import { useUserStore } from '@/store/modules/user' |
||||||
|
import { usePermissionStore } from '@/store/modules/permission' |
||||||
|
import { useGlobSetting } from '@/hooks/setting' |
||||||
|
import { useDesign } from '@/hooks/web/useDesign' |
||||||
|
import * as authUtil from '@/utils/auth' |
||||||
|
|
||||||
|
import { Verify } from '@/components/Verifition' |
||||||
|
import { getTenantIdByName, sendSmsCode } from '@/api/base/login' |
||||||
|
|
||||||
|
const FormItem = Form.Item |
||||||
|
|
||||||
|
const { t } = useI18n() |
||||||
|
const { prefixCls } = useDesign('login') |
||||||
|
const { createMessage, notification, createErrorModal } = useMessage() |
||||||
|
const { handleBackLogin, getLoginState } = useLoginState() |
||||||
|
const { tenantEnable, captchaEnable } = useGlobSetting() |
||||||
|
const { getFormRules } = useFormRules() |
||||||
|
const userStore = useUserStore() |
||||||
|
const permissionStore = usePermissionStore() |
||||||
|
|
||||||
|
const formRef = ref() |
||||||
|
const loading = ref(false) |
||||||
|
|
||||||
|
const mobileCodeTimer = ref(0) |
||||||
|
const scene = ref(21) |
||||||
|
|
||||||
|
const verify = ref() |
||||||
|
const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 |
||||||
|
|
||||||
|
const formData = reactive({ |
||||||
|
tenantName: '芋道源码', |
||||||
|
mobile: '', |
||||||
|
mobileCode: '', |
||||||
|
captchaVerification: '', |
||||||
|
}) |
||||||
|
|
||||||
|
const { validForm } = useFormValid(formRef) |
||||||
|
|
||||||
|
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.MOBILE) |
||||||
|
|
||||||
|
// 获取验证码 |
||||||
|
async function getCode() { |
||||||
|
// 情况一,未开启:则直接登录 |
||||||
|
if (captchaEnable === 'false') { |
||||||
|
await handleLogin() |
||||||
|
} |
||||||
|
else { |
||||||
|
// 情况二,已开启:则展示验证码;只有完成验证码的情况,才进行登录 |
||||||
|
// 弹出验证码 |
||||||
|
verify.value.show() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 获取租户ID |
||||||
|
async function getTenantId() { |
||||||
|
if (tenantEnable === 'true') { |
||||||
|
const res = await getTenantIdByName(formData.tenantName) |
||||||
|
authUtil.setTenantId(res) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
async function handleLogin() { |
||||||
|
const data = await validForm() |
||||||
|
if (!data) |
||||||
|
return |
||||||
|
try { |
||||||
|
loading.value = true |
||||||
|
const userInfo = await userStore.smsLogin({ |
||||||
|
mobile: data.mobile, |
||||||
|
code: data.mobileCode, |
||||||
|
mode: 'none', // 不要默认的错误提示 |
||||||
|
}) |
||||||
|
if (userInfo) { |
||||||
|
await permissionStore.changePermissionCode(userInfo.permissions) |
||||||
|
notification.success({ |
||||||
|
message: t('sys.login.loginSuccessTitle'), |
||||||
|
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.user.nickname}`, |
||||||
|
duration: 3, |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
catch (error) { |
||||||
|
createErrorModal({ |
||||||
|
title: t('sys.api.errorTip'), |
||||||
|
content: (error as unknown as Error).message || t('sys.api.networkExceptionMsg'), |
||||||
|
getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body, |
||||||
|
}) |
||||||
|
} |
||||||
|
finally { |
||||||
|
loading.value = false |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
async function getSmsCode() { |
||||||
|
await getTenantId() |
||||||
|
if (mobileCodeTimer.value > 0) |
||||||
|
return |
||||||
|
const data = await validForm() |
||||||
|
if (!data) |
||||||
|
return |
||||||
|
const res = await sendSmsCode(formData.mobile, scene.value) |
||||||
|
if (res) { |
||||||
|
createMessage.success(t('common.successText')) |
||||||
|
mobileCodeTimer.value = 60 |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<div v-if="getShow"> |
||||||
|
<LoginFormTitle class="enter-x" /> |
||||||
|
<Form ref="formRef" class="enter-x p-4" :model="formData" :rules="getFormRules"> |
||||||
|
<FormItem name="tenantName" class="enter-x"> |
||||||
|
<Input |
||||||
|
v-if="tenantEnable === 'true'" |
||||||
|
v-model:value="formData.tenantName" |
||||||
|
size="large" |
||||||
|
:placeholder="t('sys.login.tenantName')" |
||||||
|
class="fix-auto-fill" |
||||||
|
/> |
||||||
|
</FormItem> |
||||||
|
<FormItem name="mobile" class="enter-x"> |
||||||
|
<Input v-model:value="formData.mobile" size="large" :placeholder="t('sys.login.mobile')" class="fix-auto-fill" /> |
||||||
|
</FormItem> |
||||||
|
<FormItem name="mobileCode" class="enter-x"> |
||||||
|
<CountdownInput |
||||||
|
v-model:value="formData.mobileCode" |
||||||
|
size="large" |
||||||
|
class="fix-auto-fill" |
||||||
|
:count="mobileCodeTimer" |
||||||
|
:send-code-api="getSmsCode" |
||||||
|
:placeholder="t('sys.login.smsCode')" |
||||||
|
/> |
||||||
|
</FormItem> |
||||||
|
|
||||||
|
<FormItem class="enter-x"> |
||||||
|
<a-button type="primary" size="large" block :loading="loading" @click="getCode"> |
||||||
|
{{ t('sys.login.loginButton') }} |
||||||
|
</a-button> |
||||||
|
<a-button size="large" block class="mt-4" @click="handleBackLogin"> |
||||||
|
{{ t('sys.login.backSignIn') }} |
||||||
|
</a-button> |
||||||
|
</FormItem> |
||||||
|
</Form> |
||||||
|
<Verify ref="verify" mode="pop" :captcha-type="captchaType" :img-size="{ width: '400px', height: '200px' }" @success="handleLogin" /> |
||||||
|
</div> |
||||||
|
</template> |
@ -0,0 +1,37 @@ |
|||||||
|
<script lang="ts" setup> |
||||||
|
import { computed, unref } from 'vue' |
||||||
|
import { Divider, Popover, QRCode } from 'ant-design-vue' |
||||||
|
import LoginFormTitle from './LoginFormTitle.vue' |
||||||
|
import { LoginStateEnum, useLoginState } from './useLogin' |
||||||
|
import { useI18n } from '@/hooks/web/useI18n' |
||||||
|
|
||||||
|
import loginImg from '@/assets/images/logo.png' |
||||||
|
|
||||||
|
// Login QR code |
||||||
|
const qrCodeUrl = '' |
||||||
|
|
||||||
|
const { t } = useI18n() |
||||||
|
const { handleBackLogin, getLoginState } = useLoginState() |
||||||
|
|
||||||
|
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.QR_CODE) |
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<div v-if="getShow"> |
||||||
|
<LoginFormTitle class="enter-x" /> |
||||||
|
<div class="enter-x min-h-64 min-w-64"> |
||||||
|
<Popover :overlay-inner-style="{ padding: 0 }"> |
||||||
|
<template #content> |
||||||
|
<QRCode :value="qrCodeUrl" class="enter-x flex justify-center xl:justify-start" :width="280" :bordered="false" /> |
||||||
|
</template> |
||||||
|
<img width="100" height="100" :src="loginImg"> |
||||||
|
</Popover> |
||||||
|
<Divider class="enter-x"> |
||||||
|
{{ t('sys.login.scanSign') }} |
||||||
|
</Divider> |
||||||
|
<a-button size="large" block class="enter-x mt-4" @click="handleBackLogin"> |
||||||
|
{{ t('sys.login.backSignIn') }} |
||||||
|
</a-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
@ -0,0 +1,199 @@ |
|||||||
|
<script lang="ts" setup> |
||||||
|
import { onMounted, reactive, ref } from 'vue' |
||||||
|
import { useRoute } from 'vue-router' |
||||||
|
import { Checkbox, Col, Form, Row } from 'ant-design-vue' |
||||||
|
|
||||||
|
import { useFormValid, useLoginState } from './useLogin' |
||||||
|
import { useI18n } from '@/hooks/web/useI18n' |
||||||
|
import { useMessage } from '@/hooks/web/useMessage' |
||||||
|
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign' |
||||||
|
import { authorize, getAuthorize } from '@/api/base/login' |
||||||
|
|
||||||
|
const FormItem = Form.Item |
||||||
|
|
||||||
|
const { t } = useI18n() |
||||||
|
const { query } = useRoute() |
||||||
|
const { notification, createErrorModal } = useMessage() |
||||||
|
const { prefixCls } = useDesign('login') |
||||||
|
|
||||||
|
const { handleBackLogin } = useLoginState() |
||||||
|
|
||||||
|
const formRef = ref() |
||||||
|
const loading = ref(false) |
||||||
|
|
||||||
|
const loginForm = reactive({ |
||||||
|
scopes: [] as any[], // 已选中的 scope 数组 |
||||||
|
}) |
||||||
|
|
||||||
|
// URL 上的 client_id、scope 等参数 |
||||||
|
const params = reactive({ |
||||||
|
responseType: undefined as any, |
||||||
|
clientId: undefined as any, |
||||||
|
redirectUri: undefined as any, |
||||||
|
state: undefined as any, |
||||||
|
scopes: [] as any[], // 优先从 query 参数获取;如果未传递,从后端获取 |
||||||
|
}) |
||||||
|
|
||||||
|
// 客户端信息 |
||||||
|
let client = reactive({ |
||||||
|
name: '', |
||||||
|
logo: '', |
||||||
|
}) |
||||||
|
|
||||||
|
const { validForm } = useFormValid(formRef) |
||||||
|
|
||||||
|
async function init() { |
||||||
|
// 解析参数 |
||||||
|
// 例如说【自动授权不通过】:client_id=default&redirect_uri=https%3A%2F%2Fwww.iocoder.cn&response_type=code&scope=user.read%20user.write |
||||||
|
// 例如说【自动授权通过】:client_id=default&redirect_uri=https%3A%2F%2Fwww.iocoder.cn&response_type=code&scope=user.read |
||||||
|
params.responseType = query.response_type as any |
||||||
|
params.clientId = query.client_id as any |
||||||
|
params.redirectUri = query.redirect_uri as any |
||||||
|
params.state = query.state as any |
||||||
|
if (query.scope) |
||||||
|
params.scopes = (query.scope as any).split(' ') |
||||||
|
|
||||||
|
// 如果有 scope 参数,先执行一次自动授权,看看是否之前都授权过了。 |
||||||
|
if (params.scopes.length > 0) { |
||||||
|
const res = await doAuthorize(true, params.scopes, []) |
||||||
|
const href = res |
||||||
|
if (!href) { |
||||||
|
console.log('自动授权未通过!') |
||||||
|
return |
||||||
|
} |
||||||
|
location.href = href |
||||||
|
} |
||||||
|
|
||||||
|
// 获取授权页的基本信息 |
||||||
|
const res = await getAuthorize(params.clientId) |
||||||
|
client = res.client |
||||||
|
// 解析 scope |
||||||
|
let scopes |
||||||
|
// 1.1 如果 params.scope 非空,则过滤下返回的 scopes |
||||||
|
if (params.scopes.length > 0) { |
||||||
|
scopes = [] |
||||||
|
for (const scope of res.scopes) { |
||||||
|
if (params.scopes.includes(scope.key)) |
||||||
|
scopes.push(scope) |
||||||
|
} |
||||||
|
// 1.2 如果 params.scope 为空,则使用返回的 scopes 设置它 |
||||||
|
} |
||||||
|
else { |
||||||
|
scopes = res.scopes |
||||||
|
for (const scope of scopes) |
||||||
|
params.scopes.push(scope.key) |
||||||
|
} |
||||||
|
// 生成已选中的 checkedScopes |
||||||
|
for (const scope of scopes) { |
||||||
|
if (scope.value) |
||||||
|
loginForm.scopes.push(scope.key) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
async function handleAuthorize(approved) { |
||||||
|
const data = await validForm() |
||||||
|
if (!data) |
||||||
|
return |
||||||
|
try { |
||||||
|
loading.value = true |
||||||
|
// 计算 checkedScopes + uncheckedScopes |
||||||
|
let checkedScopes |
||||||
|
let uncheckedScopes |
||||||
|
if (approved) { |
||||||
|
// 同意授权,按照用户的选择 |
||||||
|
checkedScopes = loginForm.scopes |
||||||
|
uncheckedScopes = params.scopes.filter(item => !checkedScopes.includes(item)) |
||||||
|
} |
||||||
|
else { |
||||||
|
// 拒绝,则都是取消 |
||||||
|
checkedScopes = [] |
||||||
|
uncheckedScopes = params.scopes |
||||||
|
} |
||||||
|
// 提交授权的请求 |
||||||
|
const res = await doAuthorize(false, checkedScopes, uncheckedScopes) |
||||||
|
if (res) { |
||||||
|
const href = res |
||||||
|
if (!href) |
||||||
|
return |
||||||
|
|
||||||
|
location.href = href |
||||||
|
notification.success({ |
||||||
|
message: t('sys.login.loginSuccessTitle'), |
||||||
|
description: `${t('sys.login.loginSuccessDesc')}`, |
||||||
|
duration: 3, |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
catch (error) { |
||||||
|
createErrorModal({ |
||||||
|
title: t('sys.api.errorTip'), |
||||||
|
content: (error as unknown as Error).message || t('sys.api.networkExceptionMsg'), |
||||||
|
getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body, |
||||||
|
}) |
||||||
|
} |
||||||
|
finally { |
||||||
|
loading.value = false |
||||||
|
} |
||||||
|
} |
||||||
|
async function doAuthorize(autoApprove, checkedScopes, uncheckedScopes) { |
||||||
|
return await authorize( |
||||||
|
params.responseType, |
||||||
|
params.clientId, |
||||||
|
params.redirectUri, |
||||||
|
params.state, |
||||||
|
autoApprove, |
||||||
|
checkedScopes, |
||||||
|
uncheckedScopes, |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
function formatScope(scope) { |
||||||
|
// 格式化 scope 授权范围,方便用户理解。 |
||||||
|
// 这里仅仅是一个 demo,可以考虑录入到字典数据中,例如说字典类型 "system_oauth2_scope",它的每个 scope 都是一条字典数据。 |
||||||
|
switch (scope) { |
||||||
|
case 'user.read': |
||||||
|
return t('sys.login.ssoInfoDesc') |
||||||
|
case 'user.write': |
||||||
|
return t('sys.login.ssoEditDesc') |
||||||
|
default: |
||||||
|
return scope |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
onMounted(() => { |
||||||
|
init() |
||||||
|
}) |
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<h2 class="enter-x mb-3 text-center text-2xl font-bold xl:text-left xl:text-3xl"> |
||||||
|
{{ client.name + t('sys.login.ssoSignInFormTitle') }} |
||||||
|
</h2> |
||||||
|
<Form ref="formRef" class="enter-x p-4" :model="loginForm" @keypress.enter="handleAuthorize(true)"> |
||||||
|
此第三方应用请求获取以下权限: |
||||||
|
<Row class="enter-x"> |
||||||
|
<Col :span="12"> |
||||||
|
<template v-for="scope in params.scopes" :key="scope"> |
||||||
|
<FormItem> |
||||||
|
<!-- No logic, you need to deal with it yourself --> |
||||||
|
<Checkbox :checked="scope" size="small"> |
||||||
|
<a-button type="link" size="small"> |
||||||
|
{{ formatScope(scope) }} |
||||||
|
</a-button> |
||||||
|
</Checkbox> |
||||||
|
</FormItem> |
||||||
|
</template> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
|
||||||
|
<FormItem class="enter-x"> |
||||||
|
<a-button type="primary" size="large" block :loading="loading" @click="handleAuthorize(true)"> |
||||||
|
{{ t('sys.login.loginButton') }} |
||||||
|
</a-button> |
||||||
|
<a-button size="large" class="enter-x mt-4" block @click="handleBackLogin"> |
||||||
|
{{ t('common.cancelText') }} |
||||||
|
</a-button> |
||||||
|
</FormItem> |
||||||
|
</Form> |
||||||
|
</template> |
@ -0,0 +1,200 @@ |
|||||||
|
<script lang="ts" setup> |
||||||
|
import { computed } from 'vue' |
||||||
|
import SSOForm from './SSOForm.vue' |
||||||
|
import { AppDarkModeToggle, AppLocalePicker, AppLogo } from '@/components/Application' |
||||||
|
import { useGlobSetting } from '@/hooks/setting' |
||||||
|
import { useI18n } from '@/hooks/web/useI18n' |
||||||
|
import { useDesign } from '@/hooks/web/useDesign' |
||||||
|
import { useLocaleStore } from '@/store/modules/locale' |
||||||
|
|
||||||
|
defineProps({ |
||||||
|
sessionTimeout: { |
||||||
|
type: Boolean, |
||||||
|
}, |
||||||
|
}) |
||||||
|
|
||||||
|
const globSetting = useGlobSetting() |
||||||
|
const { prefixCls } = useDesign('login') |
||||||
|
const { t } = useI18n() |
||||||
|
const localeStore = useLocaleStore() |
||||||
|
const showLocale = localeStore.getShowPicker |
||||||
|
const title = computed(() => globSetting?.title ?? '') |
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<div :class="prefixCls" class="relative h-full w-full px-4"> |
||||||
|
<div class="absolute right-4 top-4 flex items-center"> |
||||||
|
<AppDarkModeToggle v-if="!sessionTimeout" class="enter-x mr-2" /> |
||||||
|
<AppLocalePicker v-if="!sessionTimeout && showLocale" class="enter-x text-white xl:text-gray-600" :show-text="false" /> |
||||||
|
</div> |
||||||
|
|
||||||
|
<span class="-enter-x xl:hidden"> |
||||||
|
<AppLogo :always-show-title="true" /> |
||||||
|
</span> |
||||||
|
|
||||||
|
<div class="relative mx-auto h-full py-2 container sm:px-10"> |
||||||
|
<div class="h-full flex"> |
||||||
|
<div class="mr-4 hidden min-h-full pl-4 xl:w-6/12 xl:flex xl:flex-col"> |
||||||
|
<AppLogo class="-enter-x" /> |
||||||
|
<div class="my-auto"> |
||||||
|
<img :alt="title" src="@/assets/svg/login-box-bg.svg" class="-enter-x w-1/2 -mt-16"> |
||||||
|
<div class="-enter-x mt-10 text-white font-medium"> |
||||||
|
<span class="mt-4 inline-block text-3xl"> {{ t('sys.login.signInTitle') }}</span> |
||||||
|
</div> |
||||||
|
<div class="-enter-x mt-5 text-white font-normal dark:text-gray-500"> |
||||||
|
{{ t('sys.login.signInDesc') }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="h-full w-full flex py-5 xl:my-0 xl:h-auto xl:w-6/12 xl:py-0"> |
||||||
|
<!-- eslint-disable max-len --> |
||||||
|
<div |
||||||
|
:class="`${prefixCls}-form`" |
||||||
|
class="enter-x relative mx-auto my-auto w-full rounded-md px-5 py-8 shadow-md xl:ml-16 lg:w-2/4 sm:w-3/4 xl:w-auto xl:bg-transparent xl:p-4 sm:px-8 xl:shadow-none" |
||||||
|
> |
||||||
|
<SSOForm /> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<style lang="less"> |
||||||
|
@prefix-cls: ~'@{namespace}-login'; |
||||||
|
@logo-prefix-cls: ~'@{namespace}-app-logo'; |
||||||
|
@countdown-prefix-cls: ~'@{namespace}-countdown-input'; |
||||||
|
@dark-bg: #293146; |
||||||
|
|
||||||
|
html[data-theme='dark'] { |
||||||
|
.@{prefix-cls} { |
||||||
|
background-color: @dark-bg; |
||||||
|
|
||||||
|
&::before { |
||||||
|
background-image: url('@/assets/svg/login-bg-dark.svg'); |
||||||
|
} |
||||||
|
|
||||||
|
.ant-input, |
||||||
|
.ant-input-password { |
||||||
|
background-color: #232a3b; |
||||||
|
} |
||||||
|
|
||||||
|
.ant-btn:not(.ant-btn-link, .ant-btn-primary) { |
||||||
|
border: 1px solid #4a5569; |
||||||
|
} |
||||||
|
|
||||||
|
&-form { |
||||||
|
background: transparent !important; |
||||||
|
} |
||||||
|
|
||||||
|
.app-iconify { |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
input.fix-auto-fill, |
||||||
|
.fix-auto-fill input { |
||||||
|
-webkit-text-fill-color: #c9d1d9 !important; |
||||||
|
box-shadow: inherit !important; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.@{prefix-cls} { |
||||||
|
min-height: 100%; |
||||||
|
overflow: hidden; |
||||||
|
|
||||||
|
@media (max-width: @screen-xl) { |
||||||
|
background-color: #293146; |
||||||
|
|
||||||
|
.@{prefix-cls}-form { |
||||||
|
background-color: #fff; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&::before { |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
margin-left: -48%; |
||||||
|
content: ''; |
||||||
|
background-image: url('@/assets/svg/login-bg.svg'); |
||||||
|
background-repeat: no-repeat; |
||||||
|
background-position: 100%; |
||||||
|
background-size: auto 100%; |
||||||
|
|
||||||
|
@media (max-width: @screen-xl) { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.@{logo-prefix-cls} { |
||||||
|
position: absolute; |
||||||
|
top: 12px; |
||||||
|
height: 30px; |
||||||
|
|
||||||
|
&__title { |
||||||
|
font-size: 16px; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
img { |
||||||
|
width: 32px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.container { |
||||||
|
.@{logo-prefix-cls} { |
||||||
|
display: flex; |
||||||
|
width: 60%; |
||||||
|
height: 80px; |
||||||
|
|
||||||
|
&__title { |
||||||
|
font-size: 24px; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
img { |
||||||
|
width: 48px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&-sign-in-way { |
||||||
|
.anticon { |
||||||
|
font-size: 22px; |
||||||
|
color: #888; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
input:not([type='checkbox']) { |
||||||
|
min-width: 360px; |
||||||
|
|
||||||
|
@media (max-width: @screen-xl) { |
||||||
|
min-width: 320px; |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: @screen-lg) { |
||||||
|
min-width: 260px; |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: @screen-md) { |
||||||
|
min-width: 240px; |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: @screen-sm) { |
||||||
|
min-width: 160px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.@{countdown-prefix-cls} input { |
||||||
|
min-width: unset; |
||||||
|
} |
||||||
|
|
||||||
|
.ant-divider-inner-text { |
||||||
|
font-size: 12px; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
Some files were not shown because too many files have changed in this diff Show More
Reference in new issue