Compare commits
3 Commits
Author | SHA1 | Date |
---|---|---|
|
e019c83643 | 1 year ago |
|
26ec154e34 | 1 year ago |
|
3cdcc93095 | 1 year ago |
193 changed files with 1734 additions and 10492 deletions
@ -1,36 +0,0 @@
|
||||
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 }) |
||||
} |
@ -0,0 +1,29 @@
|
||||
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', |
||||
}) |
||||
} |
@ -0,0 +1,32 @@
|
||||
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 |
||||
} |
@ -1,11 +0,0 @@
|
||||
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,48 +1,36 @@
|
||||
import type { Department, LazyGetDeptListParams } from './types' |
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface DeptVO { |
||||
id?: number |
||||
name: string |
||||
parentId: number |
||||
status: number |
||||
sort: number |
||||
leaderUserId: number |
||||
phone: string |
||||
email: string |
||||
createTime: Date |
||||
export function lazyGetDeptList(params?: LazyGetDeptListParams) { |
||||
return defHttp.get<Department[]>({ |
||||
url: '/system/dept/lazy-list', |
||||
params, |
||||
}) |
||||
} |
||||
|
||||
export interface DeptPageReqVO { |
||||
name?: string |
||||
status?: number |
||||
export function createDept(data: Partial<Department>) { |
||||
return defHttp.post({ |
||||
url: '/system/dept/save', |
||||
data, |
||||
}) |
||||
} |
||||
|
||||
// 查询部门(精简)列表
|
||||
export function listSimpleDept() { |
||||
return defHttp.get({ url: '/system/dept/list-all-simple' }) |
||||
export function updateDept(data: Partial<Department>) { |
||||
return defHttp.post({ |
||||
url: '/system/dept/update', |
||||
data, |
||||
}) |
||||
} |
||||
|
||||
// 查询部门列表
|
||||
export function getDeptPage(params: DeptPageReqVO) { |
||||
return defHttp.get({ url: '/system/dept/list', params }) |
||||
export function deleteDept(id: string) { |
||||
return defHttp.post({ |
||||
url: `/system/dept/delete?id=${id}`, |
||||
}) |
||||
} |
||||
|
||||
// 查询部门详情
|
||||
export function getDept(id: number) { |
||||
return defHttp.get({ url: `/system/dept/get?id=${id}` }) |
||||
} |
||||
|
||||
// 新增部门
|
||||
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}` }) |
||||
export function getDeptTree(params?: { tenantId: string }) { |
||||
return defHttp.get<{ id: string, title: string }[]>({ |
||||
url: '/system/dept/tree', |
||||
params, |
||||
}) |
||||
} |
||||
|
@ -0,0 +1,17 @@
|
||||
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 |
||||
} |
@ -1,36 +0,0 @@
|
||||
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 }) |
||||
} |
@ -1,36 +0,0 @@
|
||||
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 }) |
||||
} |
@ -1,46 +0,0 @@
|
||||
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 |
||||
} |
@ -1,49 +0,0 @@
|
||||
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') |
||||
} |
@ -1,30 +0,0 @@
|
||||
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') |
||||
} |
@ -1,31 +0,0 @@
|
||||
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' }) |
||||
} |
@ -1,11 +0,0 @@
|
||||
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 }) |
||||
} |
@ -1,54 +0,0 @@
|
||||
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,52 +1,41 @@
|
||||
import type { GetMenuListParams, MenuItem } from './types' |
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface MenuVO { |
||||
id: number |
||||
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 getMenuListWithoutButtons() { |
||||
return defHttp.get<MenuItem[]>({ |
||||
url: '/system/menu/tree', |
||||
}) |
||||
} |
||||
|
||||
export interface MenuPageReqVO { |
||||
name?: string |
||||
status?: number |
||||
export function getMenuList(params: GetMenuListParams) { |
||||
return defHttp.get<PageResult<MenuItem>>({ |
||||
url: '/system/menu/list', |
||||
params, |
||||
}) |
||||
} |
||||
|
||||
// 查询菜单(精简)列表
|
||||
export function listSimpleMenus() { |
||||
return defHttp.get({ url: '/system/menu/list-all-simple' }) |
||||
export function getMenu(id: string) { |
||||
return defHttp.get({ |
||||
url: `/system/menu/get?id=${id}`, |
||||
}) |
||||
} |
||||
|
||||
// 查询菜单列表
|
||||
export function getMenuList(params: MenuPageReqVO) { |
||||
return defHttp.get({ url: '/system/menu/list', params }) |
||||
export function createMenu(data: Omit<MenuItem, 'id' | 'children'>) { |
||||
return defHttp.post({ |
||||
url: '/system/menu/save', |
||||
data, |
||||
}) |
||||
} |
||||
|
||||
// 获取菜单详情
|
||||
export function getMenu(id: number) { |
||||
return defHttp.get({ url: `/system/menu/get?id=${id}` }) |
||||
export function updateMenu(data: Omit<MenuItem, 'children'>) { |
||||
return defHttp.post({ |
||||
url: '/system/menu/update', |
||||
data, |
||||
}) |
||||
} |
||||
|
||||
// 新增菜单
|
||||
export function createMenu(data: MenuVO) { |
||||
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}` }) |
||||
export function deleteMenu(id: string) { |
||||
return defHttp.post({ |
||||
url: `/system/menu/delete?id=${id}`, |
||||
}) |
||||
} |
||||
|
@ -0,0 +1,26 @@
|
||||
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 |
||||
} |
@ -1,42 +0,0 @@
|
||||
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}` }) |
||||
} |
@ -1,32 +0,0 @@
|
||||
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' }) |
||||
} |
@ -1,63 +0,0 @@
|
||||
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 }) |
||||
} |
@ -1,51 +0,0 @@
|
||||
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}` }) |
||||
} |
@ -1,28 +0,0 @@
|
||||
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}` }) |
||||
} |
@ -1,41 +0,0 @@
|
||||
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') |
||||
} |
@ -1,42 +0,0 @@
|
||||
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 }) |
||||
} |
@ -1,58 +0,0 @@
|
||||
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,70 +1,56 @@
|
||||
import type { GetRoleListParams, MenuTreeNode, Role } from './types' |
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface RoleVO { |
||||
id: number |
||||
name: string |
||||
code: string |
||||
sort: number |
||||
status: number |
||||
type: number |
||||
createTime: Date |
||||
export function lazyGetRoleList(params: GetRoleListParams) { |
||||
return defHttp.get<Role[]>({ |
||||
url: '/system/role/lazy-list', |
||||
params, |
||||
}) |
||||
} |
||||
|
||||
export interface RolePageReqVO extends PageParam { |
||||
name?: string |
||||
code?: string |
||||
status?: number |
||||
createTime?: Date[] |
||||
export function createRole(data: Partial<Role>) { |
||||
return defHttp.post({ |
||||
url: '/system/role/save', |
||||
data, |
||||
}) |
||||
} |
||||
|
||||
export interface UpdateStatusReqVO { |
||||
id: number |
||||
status: number |
||||
export function updateRole(data: Partial<Role>) { |
||||
return defHttp.post({ |
||||
url: '/system/role/update', |
||||
data, |
||||
}) |
||||
} |
||||
|
||||
export interface RoleExportReqVO { |
||||
name?: string |
||||
code?: string |
||||
status?: number |
||||
createTime?: Date[] |
||||
export function deleteRole(id: string) { |
||||
return defHttp.post({ |
||||
url: `/system/role/delete?id=${id}`, |
||||
}) |
||||
} |
||||
|
||||
// 查询角色列表
|
||||
export function getRolePage(params: RolePageReqVO) { |
||||
return defHttp.get({ url: '/system/role/page', params }) |
||||
export function getRoleTree(params?: { tenantId: string }) { |
||||
return defHttp.get<{ id: string, title: string }[]>({ |
||||
url: '/system/role/tree', |
||||
params, |
||||
}) |
||||
} |
||||
|
||||
// 查询角色(精简)列表
|
||||
export function listSimpleRoles() { |
||||
return defHttp.get({ url: '/system/role/list-all-simple' }) |
||||
export function getMenuTree() { |
||||
return defHttp.get<MenuTreeNode[]>({ |
||||
url: '/system/menu/grant-tree', |
||||
}) |
||||
} |
||||
|
||||
// 查询角色详情
|
||||
export function getRole(id: number) { |
||||
return defHttp.get({ url: `/system/role/get?id=${id}` }) |
||||
export function getMenuIdsByRole(roleId: string) { |
||||
return defHttp.get<string[]>({ |
||||
url: '/system/permission/list-role-menus', |
||||
params: { roleId }, |
||||
}) |
||||
} |
||||
|
||||
// 新增角色
|
||||
export function createRole(data: RoleVO) { |
||||
return defHttp.post({ url: '/system/role/create', 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') |
||||
export function assignMenuToRole(data: { roleId: string, menuIds: string[] }) { |
||||
return defHttp.post({ |
||||
url: '/system/permission/assign-role-menu', |
||||
data, |
||||
}) |
||||
} |
||||
|
@ -0,0 +1,29 @@
|
||||
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[] |
||||
} |
@ -1,64 +0,0 @@
|
||||
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}` }) |
||||
} |
@ -1,50 +0,0 @@
|
||||
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}` }) |
||||
} |
@ -1,55 +0,0 @@
|
||||
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') |
||||
} |
@ -1,94 +0,0 @@
|
||||
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,62 +1,35 @@
|
||||
import type { GetTenantListParams, Tenant } from './types' |
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface TenantVO { |
||||
id: number |
||||
name: string |
||||
contactName: string |
||||
contactMobile: string |
||||
status: number |
||||
domain: string |
||||
packageId: number |
||||
username: string |
||||
password: string |
||||
expireTime: Date |
||||
accountCount: number |
||||
createTime: Date |
||||
export function getTenantList(params: GetTenantListParams) { |
||||
return defHttp.get<PageResult<Tenant>>({ |
||||
url: '/system/tenant/page', |
||||
params, |
||||
}) |
||||
} |
||||
|
||||
export interface TenantPageReqVO extends PageParam { |
||||
name?: string |
||||
contactName?: string |
||||
contactMobile?: string |
||||
status?: number |
||||
createTime?: Date[] |
||||
export function updateTenant(data: Tenant) { |
||||
return defHttp.post({ |
||||
url: '/system/tenant/update', |
||||
data, |
||||
}) |
||||
} |
||||
|
||||
export interface TenantExportReqVO { |
||||
name?: string |
||||
contactName?: string |
||||
contactMobile?: string |
||||
status?: number |
||||
createTime?: Date[] |
||||
export function createTenant(data: Tenant) { |
||||
return defHttp.post({ |
||||
url: '/system/tenant/save', |
||||
data, |
||||
}) |
||||
} |
||||
|
||||
// 查询租户列表
|
||||
export function getTenantPage(params: TenantPageReqVO) { |
||||
return defHttp.get({ url: '/system/tenant/page', params }) |
||||
export function deleteTenant(id: string) { |
||||
return defHttp.post({ |
||||
url: `/system/tenant/remove?id=${id}`, |
||||
}) |
||||
} |
||||
|
||||
// 查询租户详情
|
||||
export function getTenant(id: number) { |
||||
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') |
||||
export function getAllTenants() { |
||||
return defHttp.get({ |
||||
url: '/system/tenant/select', |
||||
}) |
||||
} |
||||
|
@ -0,0 +1,16 @@
|
||||
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 |
||||
} |
@ -1,49 +0,0 @@
|
||||
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,91 +1,29 @@
|
||||
import type { GetUserListParams, SystemUser } from './types' |
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface UserVO { |
||||
id: number |
||||
username: string |
||||
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 getUserList(params: GetUserListParams) { |
||||
return defHttp.get<PageResult<SystemUser>>({ |
||||
url: '/system/user/page', |
||||
params, |
||||
}) |
||||
} |
||||
|
||||
export interface UserPageReqVO extends PageParam { |
||||
deptId?: number |
||||
username?: string |
||||
mobile?: string |
||||
status?: number |
||||
createTime?: Date[] |
||||
export function createUser(data: Partial<SystemUser>) { |
||||
return defHttp.post({ |
||||
url: '/system/user/save', |
||||
data, |
||||
}) |
||||
} |
||||
|
||||
export interface UserExportReqVO { |
||||
code?: string |
||||
name?: string |
||||
status?: number |
||||
createTime?: Date[] |
||||
export function updateUser(data: Partial<SystemUser>) { |
||||
return defHttp.post({ |
||||
url: '/system/user/update', |
||||
data, |
||||
}) |
||||
} |
||||
|
||||
// 查询用户管理列表
|
||||
export function getUserPage(params: UserPageReqVO) { |
||||
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' }) |
||||
export function deleteUser(id: string) { |
||||
return defHttp.post({ |
||||
url: `/system/user/delete?id=${id}`, |
||||
}) |
||||
} |
||||
|
@ -0,0 +1,23 @@
|
||||
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 |
||||
} |
@ -1,4 +0,0 @@
|
||||
import dictTag from './src/DictTag.vue' |
||||
import { withInstall } from '@/utils' |
||||
|
||||
export const DictTag = withInstall(dictTag) |
@ -1,72 +0,0 @@
|
||||
<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> |
@ -1,67 +0,0 @@
|
||||
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) |
||||
} |
@ -1,24 +0,0 @@
|
||||
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 |
||||
}, |
||||
}, |
||||
}) |
@ -1,97 +0,0 @@
|
||||
/** |
||||
* 数据字典工具类 |
||||
*/ |
||||
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', |
||||
} |
@ -1,155 +0,0 @@
|
||||
<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> |
@ -1,37 +0,0 @@
|
||||
<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> |
@ -1,199 +0,0 @@
|
||||
<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> |
@ -1,200 +0,0 @@
|
||||
<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