From cc94b2a5f7cb11b14691785201a02ff40e7f767f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 12 Dec 2025 19:16:46 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E5=A2=9E=E5=8A=A0=E4=B8=BB?= =?UTF-8?q?=E5=8C=85=EF=BC=88tabbar=EF=BC=89=E3=80=81system=EF=BC=88?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=AE=A1=E7=90=86=EF=BC=89=E3=80=81infra?= =?UTF-8?q?=EF=BC=88=E5=9F=BA=E7=A1=80=E8=AE=BE=E6=96=BD=EF=BC=89=E3=80=81?= =?UTF-8?q?bpm=EF=BC=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E7=A8=8B=EF=BC=89?= =?UTF-8?q?=E7=9A=84=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/bpm/category/index.ts | 13 + src/api/bpm/definition/index.ts | 20 + src/api/bpm/processInstance/index.ts | 68 +++ src/api/bpm/task/index.ts | 50 ++ src/api/infra/apiAccessLog/index.ts | 36 ++ src/api/infra/apiErrorLog/index.ts | 45 ++ src/api/infra/file/index.ts | 82 +++ src/api/login.ts | 134 ++++- src/api/system/dept/index.ts | 45 ++ src/api/system/dict/data/index.ts | 20 + src/api/system/menu/index.ts | 51 ++ src/api/system/notify/index.ts | 39 ++ src/api/system/post/index.ts | 43 ++ src/api/system/role/index.ts | 46 ++ src/api/system/user/index.ts | 72 +++ src/api/system/user/profile/index.ts | 48 ++ src/api/types/login.ts | 16 +- .../processInstance/create/index.vue | 233 +++++++++ .../processInstance/detail/audit/index.vue | 128 +++++ .../processInstance/detail/index.vue | 267 ++++++++++ .../apiAccessLog/components/search-form.vue | 97 ++++ src/pages-infra/apiAccessLog/detail/index.vue | 132 +++++ src/pages-infra/apiAccessLog/index.vue | 173 +++++++ .../apiErrorLog/components/search-form.vue | 119 +++++ src/pages-infra/apiErrorLog/detail/index.vue | 165 ++++++ src/pages-infra/apiErrorLog/index.vue | 167 ++++++ src/pages-infra/webSocket/index.vue | 490 ++++++++++++++++++ .../dept/components/breadcrumb.vue | 84 +++ src/pages-system/dept/detail/index.vue | 152 ++++++ src/pages-system/dept/form/index.vue | 258 +++++++++ src/pages-system/dept/index.vue | 153 ++++++ .../menu/components/breadcrumb.vue | 98 ++++ src/pages-system/menu/detail/index.vue | 155 ++++++ .../menu/form/components/menu-picker.vue | 143 +++++ src/pages-system/menu/form/index.vue | 257 +++++++++ src/pages-system/menu/index.vue | 180 +++++++ .../post/components/search-form.vue | 116 +++++ src/pages-system/post/detail/index.vue | 123 +++++ src/pages-system/post/form/index.vue | 160 ++++++ src/pages-system/post/index.vue | 171 ++++++ .../role/components/search-form.vue | 116 +++++ src/pages-system/role/detail/index.vue | 124 +++++ src/pages-system/role/form/index.vue | 161 ++++++ src/pages-system/role/index.vue | 174 +++++++ .../user/components/search-form.vue | 96 ++++ .../user/detail/components/password-form.vue | 106 ++++ .../detail/components/role-assign-form.vue | 80 +++ src/pages-system/user/detail/index.vue | 207 ++++++++ .../user/form/components/dept-picker.vue | 129 +++++ .../user/form/components/post-picker.vue | 82 +++ src/pages-system/user/form/index.vue | 201 +++++++ src/pages-system/user/index.vue | 183 +++++++ src/pages/auth/code-login.vue | 135 +++++ src/pages/auth/components/code-input.vue | 90 ++++ src/pages/auth/components/header.vue | 12 + src/pages/auth/components/tenant-picker.vue | 134 +++++ src/pages/auth/forget-password.vue | 160 ++++++ src/pages/auth/login.vue | 185 +++++++ src/pages/auth/register.vue | 179 +++++++ src/pages/auth/styles/auth.scss | 63 +++ src/pages/bpm/components/copy-list.vue | 148 ++++++ src/pages/bpm/components/copy-search-form.vue | 164 ++++++ src/pages/bpm/components/done-list.vue | 147 ++++++ src/pages/bpm/components/done-search-form.vue | 246 +++++++++ src/pages/bpm/components/index.scss | 139 +++++ src/pages/bpm/components/my-list.vue | 172 ++++++ src/pages/bpm/components/my-search-form.vue | 246 +++++++++ src/pages/bpm/components/todo-list.vue | 167 ++++++ src/pages/bpm/components/todo-search-form.vue | 246 +++++++++ src/pages/bpm/index.vue | 85 +++ src/pages/contact/components/breadcrumb.vue | 84 +++ src/pages/contact/index.vue | 169 ++++++ src/pages/error/404.vue | 30 ++ src/pages/index/components/banner.vue | 33 ++ src/pages/index/components/menu-grid.vue | 87 ++++ src/pages/index/components/menu-section.vue | 79 +++ src/pages/index/components/user-header.vue | 76 +++ src/pages/index/index.ts | 173 +++++++ src/pages/index/index.vue | 62 +-- src/pages/index/settings/index.vue | 200 +++++++ src/pages/me/me.vue | 13 - src/pages/message/components/detail-popup.vue | 82 +++ src/pages/message/components/search-form.vue | 172 ++++++ src/pages/message/index.vue | 237 +++++++++ src/pages/user/contact/index.vue | 90 ++++ src/pages/user/faq/data.ts | 66 +++ src/pages/user/faq/index.vue | 98 ++++ src/pages/user/feedback/index.vue | 205 ++++++++ src/pages/user/index.vue | 176 +++++++ src/pages/user/profile/components/form.vue | 149 ++++++ src/pages/user/profile/index.vue | 138 +++++ .../security/components/password-form.vue | 122 +++++ src/pages/user/security/index.vue | 83 +++ src/pages/user/settings/agreement/index.vue | 122 +++++ src/pages/user/settings/index.vue | 148 ++++++ src/pages/user/settings/privacy/index.vue | 157 ++++++ uno.config.ts | 2 +- 97 files changed, 12198 insertions(+), 81 deletions(-) create mode 100644 src/api/bpm/category/index.ts create mode 100644 src/api/bpm/definition/index.ts create mode 100644 src/api/bpm/processInstance/index.ts create mode 100644 src/api/bpm/task/index.ts create mode 100644 src/api/infra/apiAccessLog/index.ts create mode 100644 src/api/infra/apiErrorLog/index.ts create mode 100644 src/api/infra/file/index.ts create mode 100644 src/api/system/dept/index.ts create mode 100644 src/api/system/dict/data/index.ts create mode 100644 src/api/system/menu/index.ts create mode 100644 src/api/system/notify/index.ts create mode 100644 src/api/system/post/index.ts create mode 100644 src/api/system/role/index.ts create mode 100644 src/api/system/user/index.ts create mode 100644 src/api/system/user/profile/index.ts create mode 100644 src/pages-bpm/processInstance/create/index.vue create mode 100644 src/pages-bpm/processInstance/detail/audit/index.vue create mode 100644 src/pages-bpm/processInstance/detail/index.vue create mode 100644 src/pages-infra/apiAccessLog/components/search-form.vue create mode 100644 src/pages-infra/apiAccessLog/detail/index.vue create mode 100644 src/pages-infra/apiAccessLog/index.vue create mode 100644 src/pages-infra/apiErrorLog/components/search-form.vue create mode 100644 src/pages-infra/apiErrorLog/detail/index.vue create mode 100644 src/pages-infra/apiErrorLog/index.vue create mode 100644 src/pages-infra/webSocket/index.vue create mode 100644 src/pages-system/dept/components/breadcrumb.vue create mode 100644 src/pages-system/dept/detail/index.vue create mode 100644 src/pages-system/dept/form/index.vue create mode 100644 src/pages-system/dept/index.vue create mode 100644 src/pages-system/menu/components/breadcrumb.vue create mode 100644 src/pages-system/menu/detail/index.vue create mode 100644 src/pages-system/menu/form/components/menu-picker.vue create mode 100644 src/pages-system/menu/form/index.vue create mode 100644 src/pages-system/menu/index.vue create mode 100644 src/pages-system/post/components/search-form.vue create mode 100644 src/pages-system/post/detail/index.vue create mode 100644 src/pages-system/post/form/index.vue create mode 100644 src/pages-system/post/index.vue create mode 100644 src/pages-system/role/components/search-form.vue create mode 100644 src/pages-system/role/detail/index.vue create mode 100644 src/pages-system/role/form/index.vue create mode 100644 src/pages-system/role/index.vue create mode 100644 src/pages-system/user/components/search-form.vue create mode 100644 src/pages-system/user/detail/components/password-form.vue create mode 100644 src/pages-system/user/detail/components/role-assign-form.vue create mode 100644 src/pages-system/user/detail/index.vue create mode 100644 src/pages-system/user/form/components/dept-picker.vue create mode 100644 src/pages-system/user/form/components/post-picker.vue create mode 100644 src/pages-system/user/form/index.vue create mode 100644 src/pages-system/user/index.vue create mode 100644 src/pages/auth/code-login.vue create mode 100644 src/pages/auth/components/code-input.vue create mode 100644 src/pages/auth/components/header.vue create mode 100644 src/pages/auth/components/tenant-picker.vue create mode 100644 src/pages/auth/forget-password.vue create mode 100644 src/pages/auth/login.vue create mode 100644 src/pages/auth/register.vue create mode 100644 src/pages/auth/styles/auth.scss create mode 100644 src/pages/bpm/components/copy-list.vue create mode 100644 src/pages/bpm/components/copy-search-form.vue create mode 100644 src/pages/bpm/components/done-list.vue create mode 100644 src/pages/bpm/components/done-search-form.vue create mode 100644 src/pages/bpm/components/index.scss create mode 100644 src/pages/bpm/components/my-list.vue create mode 100644 src/pages/bpm/components/my-search-form.vue create mode 100644 src/pages/bpm/components/todo-list.vue create mode 100644 src/pages/bpm/components/todo-search-form.vue create mode 100644 src/pages/bpm/index.vue create mode 100644 src/pages/contact/components/breadcrumb.vue create mode 100644 src/pages/contact/index.vue create mode 100644 src/pages/error/404.vue create mode 100644 src/pages/index/components/banner.vue create mode 100644 src/pages/index/components/menu-grid.vue create mode 100644 src/pages/index/components/menu-section.vue create mode 100644 src/pages/index/components/user-header.vue create mode 100644 src/pages/index/index.ts create mode 100644 src/pages/index/settings/index.vue delete mode 100644 src/pages/me/me.vue create mode 100644 src/pages/message/components/detail-popup.vue create mode 100644 src/pages/message/components/search-form.vue create mode 100644 src/pages/message/index.vue create mode 100644 src/pages/user/contact/index.vue create mode 100644 src/pages/user/faq/data.ts create mode 100644 src/pages/user/faq/index.vue create mode 100644 src/pages/user/feedback/index.vue create mode 100644 src/pages/user/index.vue create mode 100644 src/pages/user/profile/components/form.vue create mode 100644 src/pages/user/profile/index.vue create mode 100644 src/pages/user/security/components/password-form.vue create mode 100644 src/pages/user/security/index.vue create mode 100644 src/pages/user/settings/agreement/index.vue create mode 100644 src/pages/user/settings/index.vue create mode 100644 src/pages/user/settings/privacy/index.vue diff --git a/src/api/bpm/category/index.ts b/src/api/bpm/category/index.ts new file mode 100644 index 0000000..95211fd --- /dev/null +++ b/src/api/bpm/category/index.ts @@ -0,0 +1,13 @@ +import { http } from '@/http/http' + +/** 流程分类 */ +export interface Category { + id: number + name: string + code: string +} + +/** 获取流程分类简单列表 */ +export function getCategorySimpleList() { + return http.get('/bpm/category/simple-list') +} diff --git a/src/api/bpm/definition/index.ts b/src/api/bpm/definition/index.ts new file mode 100644 index 0000000..61352a5 --- /dev/null +++ b/src/api/bpm/definition/index.ts @@ -0,0 +1,20 @@ +import { http } from '@/http/http' + +/** 流程定义 */ +export interface ProcessDefinition { + id: string + key: string + name: string + description?: string + category: string + formType?: number + formId?: number + formCustomCreatePath?: string + formCustomViewPath?: string + suspensionState: number +} + +/** 获取流程定义列表 */ +export function getProcessDefinitionList(params?: { suspensionState?: number }) { + return http.get('/bpm/process-definition/list', params) +} diff --git a/src/api/bpm/processInstance/index.ts b/src/api/bpm/processInstance/index.ts new file mode 100644 index 0000000..ed23510 --- /dev/null +++ b/src/api/bpm/processInstance/index.ts @@ -0,0 +1,68 @@ +import type { PageParam, PageResult } from '@/http/types' +import { http } from '@/http/http' + +/** 流程实例用户信息 */ +export interface User { + id: number + nickname: string + avatar?: string + deptName?: string +} + +/** 流程实例 */ +export interface ProcessInstance { + id: string + name: string + status: number + category?: string + categoryName?: string + createTime?: number + startTime?: number + endTime?: number + startUser?: User + summary?: { + key: string + value: string + }[] +} + +/** 抄送流程实例 */ +export interface ProcessInstanceCopy { + id: string + processInstanceId: string + processInstanceName: string + startUser: User + createTime: number + summary?: { + key: string + value: string + }[] +} + +/** 查询我发起的流程分页列表 */ +export function getProcessInstanceMyPage(params: PageParam) { + return http.get>('/bpm/process-instance/my-page', params) +} + +/** 查询抄送我的流程分页列表 */ +export function getProcessInstanceCopyPage(params: PageParam) { + return http.get>('/bpm/process-instance/copy/page', params) +} + +/** 查询流程实例详情 */ +export function getProcessInstance(id: string) { + return http.get(`/bpm/process-instance/get?id=${id}`) +} + +/** 新增流程实例 */ +export function createProcessInstance(data: { + processDefinitionId: string + variables: Record +}) { + return http.post('/bpm/process-instance/create', data) +} + +/** 申请人取消流程实例 */ +export function cancelProcessInstanceByStartUser(id: string, reason: string) { + return http.delete('/bpm/process-instance/cancel-by-start-user', { id, reason }) +} diff --git a/src/api/bpm/task/index.ts b/src/api/bpm/task/index.ts new file mode 100644 index 0000000..d0d162f --- /dev/null +++ b/src/api/bpm/task/index.ts @@ -0,0 +1,50 @@ +import type { ProcessInstance } from '@/api/bpm/processInstance' +import type { PageParam, PageResult } from '@/http/types' +import { http } from '@/http/http' + +/** 任务处理人 */ +// TODO @芋艿:貌似暂时不需要这个?! +export interface TaskUser { + id: number + nickname: string + avatar?: string + deptName?: string +} + +/** 流程任务 */ +export interface Task { + id: string + name: string + status: number + createTime: number + endTime?: number + reason?: string + assigneeUser?: TaskUser + ownerUser?: TaskUser + processInstance: ProcessInstance +} + +/** 查询待办任务分页列表 */ +export function getTaskTodoPage(params: PageParam) { + return http.get>('/bpm/task/todo-page', params) +} + +/** 查询已办任务分页列表 */ +export function getTaskDonePage(params: PageParam) { + return http.get>('/bpm/task/done-page', params) +} + +/** 审批通过 */ +export function approveTask(data: { id: string, reason: string }) { + return http.put('/bpm/task/approve', data) +} + +/** 审批拒绝 */ +export function rejectTask(data: { id: string, reason: string }) { + return http.put('/bpm/task/reject', data) +} + +/** 根据流程实例 ID 查询任务列表 */ +export function getTaskListByProcessInstanceId(processInstanceId: string) { + return http.get(`/bpm/task/list-by-process-instance-id?processInstanceId=${processInstanceId}`) +} diff --git a/src/api/infra/apiAccessLog/index.ts b/src/api/infra/apiAccessLog/index.ts new file mode 100644 index 0000000..035c4bd --- /dev/null +++ b/src/api/infra/apiAccessLog/index.ts @@ -0,0 +1,36 @@ +import type { PageParam, PageResult } from '@/http/types' +import { http } from '@/http/http' + +/** API 访问日志信息 */ +export interface ApiAccessLog { + id: number + traceId: string + userId: number + userType: number + applicationName: string + requestMethod: string + requestParams: string + responseBody: string + requestUrl: string + userIp: string + userAgent: string + operateModule: string + operateName: string + operateType: number + beginTime: string + endTime: string + duration: number + resultCode: number + resultMsg: string + createTime: string +} + +/** 获取 API 访问日志分页列表 */ +export function getApiAccessLogPage(params: PageParam) { + return http.get>('/infra/api-access-log/page', params) +} + +/** 获取 API 访问日志详情 */ +export function getApiAccessLog(id: number) { + return http.get(`/infra/api-access-log/get?id=${id}`) +} diff --git a/src/api/infra/apiErrorLog/index.ts b/src/api/infra/apiErrorLog/index.ts new file mode 100644 index 0000000..a4e650c --- /dev/null +++ b/src/api/infra/apiErrorLog/index.ts @@ -0,0 +1,45 @@ +import type { PageParam, PageResult } from '@/http/types' +import { http } from '@/http/http' + +/** API 错误日志信息 */ +export interface ApiErrorLog { + id: number + traceId: string + userId: number + userType: number + applicationName: string + requestMethod: string + requestParams: string + requestUrl: string + userIp: string + userAgent: string + exceptionTime: string + exceptionName: string + exceptionMessage: string + exceptionRootCauseMessage: string + exceptionStackTrace: string + exceptionClassName: string + exceptionFileName: string + exceptionMethodName: string + exceptionLineNumber: number + processUserId: number + processStatus: number + processTime: string + resultCode: number + createTime: string +} + +/** 获取 API 错误日志分页列表 */ +export function getApiErrorLogPage(params: PageParam) { + return http.get>('/infra/api-error-log/page', params) +} + +/** 获取 API 错误日志详情 */ +export function getApiErrorLog(id: number) { + return http.get(`/infra/api-error-log/get?id=${id}`) +} + +/** 更新 API 错误日志的处理状态 */ +export function updateApiErrorLogStatus(id: number, processStatus: number) { + return http.put(`/infra/api-error-log/update-status?id=${id}&processStatus=${processStatus}`) +} diff --git a/src/api/infra/file/index.ts b/src/api/infra/file/index.ts new file mode 100644 index 0000000..ec3180a --- /dev/null +++ b/src/api/infra/file/index.ts @@ -0,0 +1,82 @@ +import { http } from '@/http/http' +import { useTokenStore } from '@/store/token' +import { useUserStore } from '@/store/user' + +/** 文件预签名信息 */ +export interface FilePresignedUrlRespVO { + configId: number // 配置编号 + uploadUrl: string // 文件上传 URL + url: string // 文件访问 URL + path: string // 文件路径 +} + +/** 创建文件请求 */ +export interface FileCreateReqVO { + configId: number + url: string + path: string + name: string + type?: string + size?: number +} + +/** + * 获取文件预签名地址 + * + * @param name 文件名 + * @param directory 目录(可选) + */ +export function getFilePresignedUrl(name: string, directory?: string) { + return http.get('/infra/file/presigned-url', { name, directory }) +} + +/** + * 创建文件记录 + * + * @param data 文件信息 + */ +export function createFile(data: FileCreateReqVO) { + return http.post('/infra/file/create', data) +} + +/** + * 上传文件到后端 + * + * @param filePath 本地文件路径 + * @param directory 目录(可选) + * @returns 文件访问 URL + */ +export function uploadFile(filePath: string, directory?: string): Promise { + const tokenStore = useTokenStore() + const userStore = useUserStore() + return new Promise((resolve, reject) => { + uni.uploadFile({ + url: `${import.meta.env.VITE_SERVER_BASEURL}/infra/file/upload`, + filePath, + name: 'file', + header: { + 'Accept': '*/*', + 'tenant-id': userStore.tenantId, + 'Authorization': `Bearer ${tokenStore.validToken}`, + }, + formData: directory ? { directory } : undefined, + success: (res) => { + if (res.statusCode === 200) { + const result = JSON.parse(res.data) + if (result.code === 0) { + resolve(result.data) + } else { + uni.showToast({ icon: 'none', title: result.msg || '上传失败' }) + reject(new Error(result.msg || '上传失败')) + } + } else { + reject(new Error('上传失败')) + } + }, + fail: (err) => { + console.error('上传失败:', err) + reject(err) + }, + }) + }) +} diff --git a/src/api/login.ts b/src/api/login.ts index 7691c9b..f4f086c 100644 --- a/src/api/login.ts +++ b/src/api/login.ts @@ -1,12 +1,68 @@ -import type { IAuthLoginRes, ICaptcha, IDoubleTokenRes, IUpdateInfo, IUpdatePassword, IUserInfoRes } from './types/login' -import { http } from '@/http/http' +import type { + AuthPermissionInfo, + IAuthLoginRes, + ICaptcha, + IDoubleTokenRes, + IUpdateInfo, + IUpdatePassword, + IUserInfoRes, +} from "./types/login"; +import { http } from "@/http/http"; /** * 登录表单 */ export interface ILoginForm { - username: string - password: string + type: "username" | "register" | "sms"; + username?: string; + password?: string; + nickname?: string; + captchaVerification?: string; + mobile?: string; + code?: string; +} + +/** 账号密码登录 Request VO */ +export interface AuthLoginReqVO { + password?: string; + username?: string; + captchaVerification?: string; + // 绑定社交登录时,需要传递如下参数 + socialType?: number; + socialCode?: string; + socialState?: string; +} + +/** 注册 Request VO */ +export interface AuthRegisterReqVO { + username: string; + password: string; + captchaVerification: string; +} + +/** 短信登录 Request VO */ +export interface AuthSmsLoginReqVO { + mobile: string; + code: string; +} + +/** 发送短信验证码 Request VO */ +export interface AuthSmsSendReqVO { + mobile: string; + scene: number; +} + +/** 租户信息 */ +export interface TenantVO { + id: number; + name: string; +} + +/** 重置密码 Request VO */ +export interface AuthResetPasswordReqVO { + mobile: string; + code: string; + password: string; } /** @@ -14,15 +70,42 @@ export interface ILoginForm { * @returns ICaptcha 验证码 */ export function getCode() { - return http.get('/user/getCode') + return http.get("/user/getCode"); } -/** - * 用户登录 - * @param loginForm 登录表单 - */ -export function login(loginForm: ILoginForm) { - return http.post('/auth/login', loginForm) +/** 使用账号密码登录 */ +export function login(data: AuthLoginReqVO) { + return http.post("/system/auth/login", data); +} + +/** 注册用户 */ +export function register(data: AuthRegisterReqVO) { + return http.post("/system/auth/register", data); +} + +/** 短信登录 */ +export function smsLogin(data: AuthSmsLoginReqVO) { + return http.post("/system/auth/sms-login", data); +} + +/** 发送短信验证码 */ +export function sendSmsCode(data: AuthSmsSendReqVO) { + return http.post("/system/auth/send-sms-code", data); +} + +/** 获取租户简单列表 */ +export function getTenantSimpleList() { + return http.get("/system/tenant/simple-list"); +} + +/** 根据租户域名获取租户信息 */ +export function getTenantByWebsite(website: string) { + return http.get(`/system/tenant/get-by-website?website=${website}`); +} + +/** 通过短信重置密码 */ +export function smsResetPassword(data: AuthResetPasswordReqVO) { + return http.post("/system/auth/reset-password", data); } /** @@ -30,35 +113,40 @@ export function login(loginForm: ILoginForm) { * @param refreshToken 刷新token */ export function refreshToken(refreshToken: string) { - return http.post('/auth/refreshToken', { refreshToken }) + return http.post(`/system/auth/refresh-token?refreshToken=${refreshToken}`); } /** * 获取用户信息 */ export function getUserInfo() { - return http.get('/user/info') + return http.get("/user/info"); } /** - * 退出登录 + * 获取权限信息 */ +export function getAuthPermissionInfo() { + return http.get("/system/auth/get-permission-info"); +} + +/** 退出登录 */ export function logout() { - return http.get('/auth/logout') + return http.post("/system/auth/logout"); } /** * 修改用户信息 */ export function updateInfo(data: IUpdateInfo) { - return http.post('/user/updateInfo', data) + return http.post("/user/updateInfo", data); } /** * 修改用户密码 */ export function updateUserPassword(data: IUpdatePassword) { - return http.post('/user/updatePassword', data) + return http.post("/user/updatePassword", data); } /** @@ -68,11 +156,11 @@ export function updateUserPassword(data: IUpdatePassword) { export function getWxCode() { return new Promise((resolve, reject) => { uni.login({ - provider: 'weixin', - success: res => resolve(res), - fail: err => reject(new Error(err)), - }) - }) + provider: "weixin", + success: (res) => resolve(res), + fail: (err) => reject(new Error(err)), + }); + }); } /** @@ -81,5 +169,5 @@ export function getWxCode() { * @returns Promise 包含登录结果 */ export function wxLogin(data: { code: string }) { - return http.post('/auth/wxLogin', data) + return http.post("/auth/wxLogin", data); } diff --git a/src/api/system/dept/index.ts b/src/api/system/dept/index.ts new file mode 100644 index 0000000..758e8e7 --- /dev/null +++ b/src/api/system/dept/index.ts @@ -0,0 +1,45 @@ +import { http } from '@/http/http' + +/** 部门信息 */ +export interface Dept { + id?: number + name: string + parentId: number + status: number + sort: number + leaderUserId?: number + phone?: string + email?: string + createTime?: string + children?: Dept[] +} + +/** 获取部门列表 */ +export function getDeptList(params?: { name?: string; status?: number }) { + return http.get('/system/dept/list', params) +} + +/** 获取部门精简列表 */ +export function getSimpleDeptList() { + return http.get('/system/dept/simple-list') +} + +/** 获取部门详情 */ +export function getDept(id: number) { + return http.get(`/system/dept/get?id=${id}`) +} + +/** 创建部门 */ +export function createDept(data: Dept) { + return http.post('/system/dept/create', data) +} + +/** 更新部门 */ +export function updateDept(data: Dept) { + return http.put('/system/dept/update', data) +} + +/** 删除部门 */ +export function deleteDept(id: number) { + return http.delete(`/system/dept/delete?id=${id}`) +} diff --git a/src/api/system/dict/data/index.ts b/src/api/system/dict/data/index.ts new file mode 100644 index 0000000..ceb56cb --- /dev/null +++ b/src/api/system/dict/data/index.ts @@ -0,0 +1,20 @@ +import { http } from '@/http/http' + +/** 字典数据 */ +export interface DictData { + id?: number + dictType: string + label: string + value: string + colorType?: string + cssClass?: string + sort?: number + status: number + remark?: string + createTime?: string +} + +/** 查询字典数据(精简)列表 */ +export function getSimpleDictDataList() { + return http.get('/system/dict-data/simple-list') +} diff --git a/src/api/system/menu/index.ts b/src/api/system/menu/index.ts new file mode 100644 index 0000000..c4cbd7d --- /dev/null +++ b/src/api/system/menu/index.ts @@ -0,0 +1,51 @@ +import { http } from '@/http/http' + +/** 菜单信息 */ +export interface Menu { + id?: number + name: string + permission: string + type: number + sort: number + parentId: number + path: string + icon: string + component: string + componentName?: string + status: number + visible: boolean + keepAlive: boolean + alwaysShow?: boolean + createTime?: string + children?: Menu[] +} + +/** 获取菜单列表 */ +export function getMenuList(params?: { name?: string, status?: number }) { + return http.get('/system/menu/list', params) +} + +/** 获取菜单精简列表 */ +export function getSimpleMenuList() { + return http.get('/system/menu/simple-list') +} + +/** 获取菜单详情 */ +export function getMenu(id: number) { + return http.get(`/system/menu/get?id=${id}`) +} + +/** 创建菜单 */ +export function createMenu(data: Menu) { + return http.post('/system/menu/create', data) +} + +/** 更新菜单 */ +export function updateMenu(data: Menu) { + return http.put('/system/menu/update', data) +} + +/** 删除菜单 */ +export function deleteMenu(id: number) { + return http.delete(`/system/menu/delete?id=${id}`) +} diff --git a/src/api/system/notify/index.ts b/src/api/system/notify/index.ts new file mode 100644 index 0000000..54ef334 --- /dev/null +++ b/src/api/system/notify/index.ts @@ -0,0 +1,39 @@ +import type { PageParam, PageResult } from '@/http/types' +import { http } from '@/http/http' + +/** 站内信消息 */ +export interface NotifyMessage { + id: number + userId: number + userType: number + templateId: number + templateCode: string + templateNickname: string + templateContent: string + templateType: number + templateParams: string + readStatus: boolean + readTime: string + createTime: string +} + +/** 获取我的站内信分页 */ +export function getMyNotifyMessagePage(params: PageParam) { + return http.get>('/system/notify-message/my-page', params) +} + +/** 批量标记站内信已读 */ +export function updateNotifyMessageRead(ids: number | number[]) { + const idsArray = Array.isArray(ids) ? ids : [ids] + return http.put('/system/notify-message/update-read', undefined, { ids: idsArray }) +} + +/** 标记所有站内信为已读 */ +export function updateAllNotifyMessageRead() { + return http.put('/system/notify-message/update-all-read') +} + +/** 获取当前用户的未读站内信数量 */ +export function getUnreadNotifyMessageCount() { + return http.get('/system/notify-message/get-unread-count') +} diff --git a/src/api/system/post/index.ts b/src/api/system/post/index.ts new file mode 100644 index 0000000..8d0687a --- /dev/null +++ b/src/api/system/post/index.ts @@ -0,0 +1,43 @@ +import type { PageParam, PageResult } from '@/http/types' +import { http } from '@/http/http' + +/** 岗位信息 */ +export interface Post { + id?: number + name: string + code: string + sort: number + status: number + remark?: string + createTime?: string +} + +/** 获取岗位分页列表 */ +export function getPostPage(params: PageParam) { + return http.get>('/system/post/page', params) +} + +/** 获取岗位精简列表 */ +export function getSimplePostList() { + return http.get('/system/post/simple-list') +} + +/** 获取岗位详情 */ +export function getPost(id: number) { + return http.get(`/system/post/get?id=${id}`) +} + +/** 创建岗位 */ +export function createPost(data: Post) { + return http.post('/system/post/create', data) +} + +/** 更新岗位 */ +export function updatePost(data: Post) { + return http.put('/system/post/update', data) +} + +/** 删除岗位 */ +export function deletePost(id: number) { + return http.delete(`/system/post/delete?id=${id}`) +} diff --git a/src/api/system/role/index.ts b/src/api/system/role/index.ts new file mode 100644 index 0000000..a5421cb --- /dev/null +++ b/src/api/system/role/index.ts @@ -0,0 +1,46 @@ +import { http } from '@/http/http' +import { PageParam, PageResult } from '@/http/types'; + +/** 角色信息 */ +export interface Role { + id: number + name: string + code: string + sort: number + status: number + type?: number + remark?: string + dataScope?: number + dataScopeDeptIds?: number[] + createTime: string +} + +/** 获取角色分页列表 */ +export function getRolePage(params: PageParam) { + return http.get>('/system/role/page', params) +} + +/** 获取角色详情 */ +export function getRole(id: number) { + return http.get(`/system/role/get?id=${id}`) +} + +/** 创建角色 */ +export function createRole(data: Role) { + return http.post('/system/role/create', data) +} + +/** 更新角色 */ +export function updateRole(data: Role) { + return http.put('/system/role/update', data) +} + +/** 删除角色 */ +export function deleteRole(id: number) { + return http.delete(`/system/role/delete?id=${id}`) +} + +/** 获取角色精简列表 */ +export function getSimpleRoleList() { + return http.get('/system/role/simple-list') +} diff --git a/src/api/system/user/index.ts b/src/api/system/user/index.ts new file mode 100644 index 0000000..a647eed --- /dev/null +++ b/src/api/system/user/index.ts @@ -0,0 +1,72 @@ +import type { PageParam, PageResult } from '@/http/types' +import { http } from '@/http/http' + +/** 用户信息 */ +export interface User { + id?: number + username: string + nickname: string + password?: string + deptId?: number + deptName?: string + postIds?: number[] + email?: string + mobile?: string + sex?: number + avatar?: string + status: number + remark?: string + loginIp?: string + loginDate?: string + createTime?: string +} + +/** 获取用户分页列表 */ +export function getUserPage(params: PageParam) { + return http.get>('/system/user/page', params) +} + +/** 获取用户详情 */ +export function getUser(id: number) { + return http.get(`/system/user/get?id=${id}`) +} + +/** 创建用户 */ +export function createUser(data: User) { + return http.post('/system/user/create', data) +} + +/** 更新用户 */ +export function updateUser(data: User) { + return http.put('/system/user/update', data) +} + +/** 删除用户 */ +export function deleteUser(id: number) { + return http.delete(`/system/user/delete?id=${id}`) +} + +/** 重置用户密码 */ +export function resetUserPassword(id: number, password: string) { + return http.put('/system/user/update-password', { id, password }) +} + +/** 修改用户状态 */ +export function updateUserStatus(id: number, status: number) { + return http.put('/system/user/update-status', { id, status }) +} + +/** 获取用户拥有的角色列表 */ +export function getUserRoleIds(userId: number) { + return http.get(`/system/permission/list-user-roles?userId=${userId}`) +} + +/** 分配用户角色 */ +export function assignUserRole(userId: number, roleIds: number[]) { + return http.post('/system/permission/assign-user-role', { userId, roleIds }) +} + +/** 获取用户精简列表 */ +export function getSimpleUserList() { + return http.get('/system/user/simple-list') +} diff --git a/src/api/system/user/profile/index.ts b/src/api/system/user/profile/index.ts new file mode 100644 index 0000000..054806f --- /dev/null +++ b/src/api/system/user/profile/index.ts @@ -0,0 +1,48 @@ +import { http } from '@/http/http' + +/** 用户个人中心信息 */ +export interface UserProfileVO { + id: number + username: string + nickname: string + email?: string + mobile?: string + sex?: number + avatar?: string + loginIp: string + loginDate: string + createTime: string + roles: { id: number, name: string }[] + dept: { id: number, name: string } + posts: { id: number, name: string }[] +} + +/** 更新个人信息请求 */ +export interface UpdateProfileReqVO { + nickname?: string + email?: string + mobile?: string + sex?: number + avatar?: string +} + +/** 更新密码请求 */ +export interface UpdatePasswordReqVO { + oldPassword: string + newPassword: string +} + +/** 获取登录用户个人信息 */ +export function getUserProfile() { + return http.get('/system/user/profile/get') +} + +/** 修改用户个人信息 */ +export function updateUserProfile(data: UpdateProfileReqVO) { + return http.put('/system/user/profile/update', data) +} + +/** 修改用户个人密码 */ +export function updateUserPassword(data: UpdatePasswordReqVO) { + return http.put('/system/user/profile/update-password', data) +} diff --git a/src/api/types/login.ts b/src/api/types/login.ts index d703fd8..ca87e8a 100644 --- a/src/api/types/login.ts +++ b/src/api/types/login.ts @@ -11,8 +11,9 @@ export interface ISingleTokenRes { export interface IDoubleTokenRes { accessToken: string refreshToken: string - accessExpiresIn: number // 访问令牌有效期(秒) - refreshExpiresIn: number // 刷新令牌有效期(秒) + // accessExpiresIn: number // 访问令牌有效期(秒) + // refreshExpiresIn: number // 刷新令牌有效期(秒) + expiresTime: number // 访问令牌过期时间,单位:毫秒 } /** @@ -31,7 +32,18 @@ export interface IUserInfoRes { [key: string]: any // 允许其他扩展字段 } +/** + * 权限信息 + */ +export interface AuthPermissionInfo { + user: IUserInfoRes; + roles: string[]; + permissions: string[]; + // menus: AppRouteRecordRaw[]; // add by 芋艿:暂时用不到 +} + // 认证存储数据结构 +// TODO @芋艿:可以考虑删除 export interface AuthStorage { mode: AuthMode tokens: ISingleTokenRes | IDoubleTokenRes diff --git a/src/pages-bpm/processInstance/create/index.vue b/src/pages-bpm/processInstance/create/index.vue new file mode 100644 index 0000000..3b2ce3f --- /dev/null +++ b/src/pages-bpm/processInstance/create/index.vue @@ -0,0 +1,233 @@ + + + diff --git a/src/pages-bpm/processInstance/detail/audit/index.vue b/src/pages-bpm/processInstance/detail/audit/index.vue new file mode 100644 index 0000000..76cd61a --- /dev/null +++ b/src/pages-bpm/processInstance/detail/audit/index.vue @@ -0,0 +1,128 @@ + + + diff --git a/src/pages-bpm/processInstance/detail/index.vue b/src/pages-bpm/processInstance/detail/index.vue new file mode 100644 index 0000000..110f8f1 --- /dev/null +++ b/src/pages-bpm/processInstance/detail/index.vue @@ -0,0 +1,267 @@ + + + diff --git a/src/pages-infra/apiAccessLog/components/search-form.vue b/src/pages-infra/apiAccessLog/components/search-form.vue new file mode 100644 index 0000000..996fbba --- /dev/null +++ b/src/pages-infra/apiAccessLog/components/search-form.vue @@ -0,0 +1,97 @@ + + + diff --git a/src/pages-infra/apiAccessLog/detail/index.vue b/src/pages-infra/apiAccessLog/detail/index.vue new file mode 100644 index 0000000..712e84a --- /dev/null +++ b/src/pages-infra/apiAccessLog/detail/index.vue @@ -0,0 +1,132 @@ + + + + + diff --git a/src/pages-infra/apiAccessLog/index.vue b/src/pages-infra/apiAccessLog/index.vue new file mode 100644 index 0000000..441d927 --- /dev/null +++ b/src/pages-infra/apiAccessLog/index.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/src/pages-infra/apiErrorLog/components/search-form.vue b/src/pages-infra/apiErrorLog/components/search-form.vue new file mode 100644 index 0000000..ab384bd --- /dev/null +++ b/src/pages-infra/apiErrorLog/components/search-form.vue @@ -0,0 +1,119 @@ + + + diff --git a/src/pages-infra/apiErrorLog/detail/index.vue b/src/pages-infra/apiErrorLog/detail/index.vue new file mode 100644 index 0000000..f38069e --- /dev/null +++ b/src/pages-infra/apiErrorLog/detail/index.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/src/pages-infra/apiErrorLog/index.vue b/src/pages-infra/apiErrorLog/index.vue new file mode 100644 index 0000000..e998528 --- /dev/null +++ b/src/pages-infra/apiErrorLog/index.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/src/pages-infra/webSocket/index.vue b/src/pages-infra/webSocket/index.vue new file mode 100644 index 0000000..feae779 --- /dev/null +++ b/src/pages-infra/webSocket/index.vue @@ -0,0 +1,490 @@ + + + + + diff --git a/src/pages-system/dept/components/breadcrumb.vue b/src/pages-system/dept/components/breadcrumb.vue new file mode 100644 index 0000000..18f674d --- /dev/null +++ b/src/pages-system/dept/components/breadcrumb.vue @@ -0,0 +1,84 @@ + + + diff --git a/src/pages-system/dept/detail/index.vue b/src/pages-system/dept/detail/index.vue new file mode 100644 index 0000000..f181201 --- /dev/null +++ b/src/pages-system/dept/detail/index.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/src/pages-system/dept/form/index.vue b/src/pages-system/dept/form/index.vue new file mode 100644 index 0000000..e0fde25 --- /dev/null +++ b/src/pages-system/dept/form/index.vue @@ -0,0 +1,258 @@ + + + + + diff --git a/src/pages-system/dept/index.vue b/src/pages-system/dept/index.vue new file mode 100644 index 0000000..f5ac47a --- /dev/null +++ b/src/pages-system/dept/index.vue @@ -0,0 +1,153 @@ + + + + + diff --git a/src/pages-system/menu/components/breadcrumb.vue b/src/pages-system/menu/components/breadcrumb.vue new file mode 100644 index 0000000..a650c28 --- /dev/null +++ b/src/pages-system/menu/components/breadcrumb.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/src/pages-system/menu/detail/index.vue b/src/pages-system/menu/detail/index.vue new file mode 100644 index 0000000..98b3c0b --- /dev/null +++ b/src/pages-system/menu/detail/index.vue @@ -0,0 +1,155 @@ + + + + + diff --git a/src/pages-system/menu/form/components/menu-picker.vue b/src/pages-system/menu/form/components/menu-picker.vue new file mode 100644 index 0000000..a8de1e4 --- /dev/null +++ b/src/pages-system/menu/form/components/menu-picker.vue @@ -0,0 +1,143 @@ + + + diff --git a/src/pages-system/menu/form/index.vue b/src/pages-system/menu/form/index.vue new file mode 100644 index 0000000..e6fd31d --- /dev/null +++ b/src/pages-system/menu/form/index.vue @@ -0,0 +1,257 @@ + + + + + diff --git a/src/pages-system/menu/index.vue b/src/pages-system/menu/index.vue new file mode 100644 index 0000000..8ff2212 --- /dev/null +++ b/src/pages-system/menu/index.vue @@ -0,0 +1,180 @@ + + + + + diff --git a/src/pages-system/post/components/search-form.vue b/src/pages-system/post/components/search-form.vue new file mode 100644 index 0000000..3c74450 --- /dev/null +++ b/src/pages-system/post/components/search-form.vue @@ -0,0 +1,116 @@ + + + diff --git a/src/pages-system/post/detail/index.vue b/src/pages-system/post/detail/index.vue new file mode 100644 index 0000000..dd772ff --- /dev/null +++ b/src/pages-system/post/detail/index.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/src/pages-system/post/form/index.vue b/src/pages-system/post/form/index.vue new file mode 100644 index 0000000..9a6ae85 --- /dev/null +++ b/src/pages-system/post/form/index.vue @@ -0,0 +1,160 @@ + + + + + diff --git a/src/pages-system/post/index.vue b/src/pages-system/post/index.vue new file mode 100644 index 0000000..9827ee8 --- /dev/null +++ b/src/pages-system/post/index.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/src/pages-system/role/components/search-form.vue b/src/pages-system/role/components/search-form.vue new file mode 100644 index 0000000..75d6ab8 --- /dev/null +++ b/src/pages-system/role/components/search-form.vue @@ -0,0 +1,116 @@ + + + diff --git a/src/pages-system/role/detail/index.vue b/src/pages-system/role/detail/index.vue new file mode 100644 index 0000000..312098d --- /dev/null +++ b/src/pages-system/role/detail/index.vue @@ -0,0 +1,124 @@ + + + + + diff --git a/src/pages-system/role/form/index.vue b/src/pages-system/role/form/index.vue new file mode 100644 index 0000000..3375233 --- /dev/null +++ b/src/pages-system/role/form/index.vue @@ -0,0 +1,161 @@ + + + + + diff --git a/src/pages-system/role/index.vue b/src/pages-system/role/index.vue new file mode 100644 index 0000000..2fc9f8b --- /dev/null +++ b/src/pages-system/role/index.vue @@ -0,0 +1,174 @@ + + + + + diff --git a/src/pages-system/user/components/search-form.vue b/src/pages-system/user/components/search-form.vue new file mode 100644 index 0000000..72dde22 --- /dev/null +++ b/src/pages-system/user/components/search-form.vue @@ -0,0 +1,96 @@ + + + diff --git a/src/pages-system/user/detail/components/password-form.vue b/src/pages-system/user/detail/components/password-form.vue new file mode 100644 index 0000000..be47b58 --- /dev/null +++ b/src/pages-system/user/detail/components/password-form.vue @@ -0,0 +1,106 @@ + + + diff --git a/src/pages-system/user/detail/components/role-assign-form.vue b/src/pages-system/user/detail/components/role-assign-form.vue new file mode 100644 index 0000000..ea87776 --- /dev/null +++ b/src/pages-system/user/detail/components/role-assign-form.vue @@ -0,0 +1,80 @@ + + + diff --git a/src/pages-system/user/detail/index.vue b/src/pages-system/user/detail/index.vue new file mode 100644 index 0000000..43c77dd --- /dev/null +++ b/src/pages-system/user/detail/index.vue @@ -0,0 +1,207 @@ + + + + + diff --git a/src/pages-system/user/form/components/dept-picker.vue b/src/pages-system/user/form/components/dept-picker.vue new file mode 100644 index 0000000..72a8cf1 --- /dev/null +++ b/src/pages-system/user/form/components/dept-picker.vue @@ -0,0 +1,129 @@ + + + + diff --git a/src/pages-system/user/form/components/post-picker.vue b/src/pages-system/user/form/components/post-picker.vue new file mode 100644 index 0000000..a914fc9 --- /dev/null +++ b/src/pages-system/user/form/components/post-picker.vue @@ -0,0 +1,82 @@ + + + + diff --git a/src/pages-system/user/form/index.vue b/src/pages-system/user/form/index.vue new file mode 100644 index 0000000..81404ce --- /dev/null +++ b/src/pages-system/user/form/index.vue @@ -0,0 +1,201 @@ + + + + + diff --git a/src/pages-system/user/index.vue b/src/pages-system/user/index.vue new file mode 100644 index 0000000..aaa4120 --- /dev/null +++ b/src/pages-system/user/index.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/src/pages/auth/code-login.vue b/src/pages/auth/code-login.vue new file mode 100644 index 0000000..455f9d9 --- /dev/null +++ b/src/pages/auth/code-login.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/src/pages/auth/components/code-input.vue b/src/pages/auth/components/code-input.vue new file mode 100644 index 0000000..125799b --- /dev/null +++ b/src/pages/auth/components/code-input.vue @@ -0,0 +1,90 @@ + + + diff --git a/src/pages/auth/components/header.vue b/src/pages/auth/components/header.vue new file mode 100644 index 0000000..eb4171a --- /dev/null +++ b/src/pages/auth/components/header.vue @@ -0,0 +1,12 @@ + + + diff --git a/src/pages/auth/components/tenant-picker.vue b/src/pages/auth/components/tenant-picker.vue new file mode 100644 index 0000000..5ef4baf --- /dev/null +++ b/src/pages/auth/components/tenant-picker.vue @@ -0,0 +1,134 @@ + + + + + diff --git a/src/pages/auth/forget-password.vue b/src/pages/auth/forget-password.vue new file mode 100644 index 0000000..bd61271 --- /dev/null +++ b/src/pages/auth/forget-password.vue @@ -0,0 +1,160 @@ + + + + + diff --git a/src/pages/auth/login.vue b/src/pages/auth/login.vue new file mode 100644 index 0000000..8318762 --- /dev/null +++ b/src/pages/auth/login.vue @@ -0,0 +1,185 @@ + + + + + diff --git a/src/pages/auth/register.vue b/src/pages/auth/register.vue new file mode 100644 index 0000000..a23764a --- /dev/null +++ b/src/pages/auth/register.vue @@ -0,0 +1,179 @@ + + + + + diff --git a/src/pages/auth/styles/auth.scss b/src/pages/auth/styles/auth.scss new file mode 100644 index 0000000..6518577 --- /dev/null +++ b/src/pages/auth/styles/auth.scss @@ -0,0 +1,63 @@ +/** 认证页面公共样式 */ + +// 页面容器 +.auth-container { + display: flex; + flex-direction: column; + min-height: 100vh; + background: linear-gradient(180deg, #e8f4ff 0%, #fff 50%); + box-sizing: border-box; +} + +// 表单容器 +.form-container { + flex: 1; + border-radius: 24rpx 24rpx 0 0; + background: #fff; + padding: 40rpx; +} + +// 输入项 +.input-item { + display: flex; + align-items: center; + padding: 20rpx 24rpx; + background: #f5f7fa; + border-radius: 12rpx; + margin-bottom: 24rpx; + + :deep(.wd-input) { + flex: 1; + margin-left: 16rpx; + background: transparent; + } + + :deep(.wd-picker) { + flex: 1; + margin-left: 16rpx; + } + + :deep(.wd-picker__field) { + background: transparent; + padding: 0; + } + + // 移除 picker 的边框,保持与 input 一致 + :deep(.wd-picker__cell) { + background: transparent !important; + padding: 0 !important; + } + + :deep(.wd-cell) { + background: transparent !important; + padding: 0 !important; + + &::after { + display: none !important; + } + } + + :deep(.wd-cell__wrapper) { + padding: 0 !important; + } +} diff --git a/src/pages/bpm/components/copy-list.vue b/src/pages/bpm/components/copy-list.vue new file mode 100644 index 0000000..ba1dbaa --- /dev/null +++ b/src/pages/bpm/components/copy-list.vue @@ -0,0 +1,148 @@ + + + diff --git a/src/pages/bpm/components/copy-search-form.vue b/src/pages/bpm/components/copy-search-form.vue new file mode 100644 index 0000000..1837271 --- /dev/null +++ b/src/pages/bpm/components/copy-search-form.vue @@ -0,0 +1,164 @@ + + + diff --git a/src/pages/bpm/components/done-list.vue b/src/pages/bpm/components/done-list.vue new file mode 100644 index 0000000..c77ca91 --- /dev/null +++ b/src/pages/bpm/components/done-list.vue @@ -0,0 +1,147 @@ + + + diff --git a/src/pages/bpm/components/done-search-form.vue b/src/pages/bpm/components/done-search-form.vue new file mode 100644 index 0000000..d1d63bd --- /dev/null +++ b/src/pages/bpm/components/done-search-form.vue @@ -0,0 +1,246 @@ + + + diff --git a/src/pages/bpm/components/index.scss b/src/pages/bpm/components/index.scss new file mode 100644 index 0000000..1d73eff --- /dev/null +++ b/src/pages/bpm/components/index.scss @@ -0,0 +1,139 @@ +/** + * BPM 列表组件共享样式 + */ + +// 列表容器 +.bpm-list { + padding: 24rpx; +} + +// 搜索框容器 +.bpm-search { + margin-bottom: 24rpx; +} + +// 列表卡片 +.bpm-card { + margin-bottom: 24rpx; + overflow: hidden; + border-radius: 12rpx; + background-color: #fff; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); +} + +// 卡片内容区 +.bpm-card-content { + padding: 24rpx; +} + +// 卡片标题行 +.bpm-card-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 16rpx; +} + +// 卡片标题 +.bpm-card-title { + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 32rpx; + font-weight: 600; + color: #333; +} + +// 卡片信息行 +.bpm-card-info { + display: flex; + align-items: center; + justify-content: space-between; + font-size: 28rpx; + color: #666; +} + +// 摘要区域 +.bpm-summary { + margin-bottom: 16rpx; + padding: 16rpx; + border-radius: 8rpx; + background-color: #f9f9f9; + font-size: 26rpx; +} + +.bpm-summary-item { + margin-bottom: 8rpx; + line-height: 1.5; + + &:last-child { + margin-bottom: 0; + } +} + +// 用户信息 +.bpm-user { + display: flex; + align-items: center; +} + +// 用户头像 +.bpm-avatar { + display: flex; + align-items: center; + justify-content: center; + width: 48rpx; + height: 48rpx; + margin-right: 12rpx; + border-radius: 50%; + background-color: #1890ff; + font-size: 24rpx; + color: #fff; +} + +// 用户昵称 +.bpm-nickname { + max-width: 200rpx; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +// 时间文本 +.bpm-time { + color: #999; +} + +// 时间文本 - 警告色 +.bpm-time--warning { + color: #ff9800; +} + +// 操作按钮区 +.bpm-actions { + display: flex; + border-top: 1rpx solid #f0f0f0; +} + +// 操作按钮 +.bpm-action-btn { + display: flex; + flex: 1; + align-items: center; + justify-content: center; + padding: 24rpx 0; + font-size: 28rpx; + font-weight: 500; + color: #1890ff; + + &:not(:last-child) { + border-right: 1rpx solid #f0f0f0; + } +} + +// 空状态 +.bpm-empty { + padding: 100rpx 0; + text-align: center; +} diff --git a/src/pages/bpm/components/my-list.vue b/src/pages/bpm/components/my-list.vue new file mode 100644 index 0000000..f2f44ed --- /dev/null +++ b/src/pages/bpm/components/my-list.vue @@ -0,0 +1,172 @@ + + + diff --git a/src/pages/bpm/components/my-search-form.vue b/src/pages/bpm/components/my-search-form.vue new file mode 100644 index 0000000..c5998c9 --- /dev/null +++ b/src/pages/bpm/components/my-search-form.vue @@ -0,0 +1,246 @@ + + + diff --git a/src/pages/bpm/components/todo-list.vue b/src/pages/bpm/components/todo-list.vue new file mode 100644 index 0000000..a552198 --- /dev/null +++ b/src/pages/bpm/components/todo-list.vue @@ -0,0 +1,167 @@ + + + diff --git a/src/pages/bpm/components/todo-search-form.vue b/src/pages/bpm/components/todo-search-form.vue new file mode 100644 index 0000000..dfa3ee6 --- /dev/null +++ b/src/pages/bpm/components/todo-search-form.vue @@ -0,0 +1,246 @@ + + + diff --git a/src/pages/bpm/index.vue b/src/pages/bpm/index.vue new file mode 100644 index 0000000..e94c4d9 --- /dev/null +++ b/src/pages/bpm/index.vue @@ -0,0 +1,85 @@ + + + diff --git a/src/pages/contact/components/breadcrumb.vue b/src/pages/contact/components/breadcrumb.vue new file mode 100644 index 0000000..8ca0e16 --- /dev/null +++ b/src/pages/contact/components/breadcrumb.vue @@ -0,0 +1,84 @@ + + + diff --git a/src/pages/contact/index.vue b/src/pages/contact/index.vue new file mode 100644 index 0000000..619f86d --- /dev/null +++ b/src/pages/contact/index.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/src/pages/error/404.vue b/src/pages/error/404.vue new file mode 100644 index 0000000..533e259 --- /dev/null +++ b/src/pages/error/404.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/src/pages/index/components/banner.vue b/src/pages/index/components/banner.vue new file mode 100644 index 0000000..9987844 --- /dev/null +++ b/src/pages/index/components/banner.vue @@ -0,0 +1,33 @@ + + + diff --git a/src/pages/index/components/menu-grid.vue b/src/pages/index/components/menu-grid.vue new file mode 100644 index 0000000..986c8ab --- /dev/null +++ b/src/pages/index/components/menu-grid.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/src/pages/index/components/menu-section.vue b/src/pages/index/components/menu-section.vue new file mode 100644 index 0000000..2ad5e48 --- /dev/null +++ b/src/pages/index/components/menu-section.vue @@ -0,0 +1,79 @@ + + + diff --git a/src/pages/index/components/user-header.vue b/src/pages/index/components/user-header.vue new file mode 100644 index 0000000..8c27954 --- /dev/null +++ b/src/pages/index/components/user-header.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/pages/index/index.ts b/src/pages/index/index.ts new file mode 100644 index 0000000..cfcf95e --- /dev/null +++ b/src/pages/index/index.ts @@ -0,0 +1,173 @@ +import { useAccess } from '@/hooks/useAccess' + +/** + * 工作台菜单数据 + * 定义菜单分组和菜单项的数据结构 + */ + +/** 菜单项类型 */ +export interface MenuItem { + key: string // 菜单唯一标识 + name: string // 菜单名称 + icon: string // 菜单图标(支持 wot-design-uni 图标名或图片路径) + url?: string // 跳转路径 + iconColor?: string // 图标颜色(可选) + enabled?: boolean // 是否启用(可选,默认 true) + permission?: string // 权限标识(可选) +} + +/** 菜单分组类型 */ +export interface MenuGroup { + key: string // 分组唯一标识 + name: string // 分组名称 + menus: MenuItem[] // 分组下的菜单列表 +} + +/** 菜单分组原始数据 */ +const menuGroupsData: MenuGroup[] = [ + { + key: 'system', + name: '系统管理', + menus: [ + { + key: 'user', + name: '用户管理', + icon: 'user', + url: '/pages-system/user/index', + iconColor: '#1890ff', + permission: 'system:user:list', + }, + { + key: 'role', + name: '角色管理', + icon: 'usergroup', + url: '/pages-system/role/index', + iconColor: '#52c41a', + permission: 'system:role:query', + }, + { + key: 'menu', + name: '菜单管理', + icon: 'menu-fold', + url: '/pages-system/menu/index', + iconColor: '#fa8c16', + permission: 'system:menu:query', + }, + { + key: 'dept', + name: '部门管理', + icon: 'attach', + url: '/pages-system/dept/index', + iconColor: '#13c2c2', + permission: 'system:dept:query', + }, + { + key: 'post', + name: '岗位管理', + icon: 'flag', + url: '/pages-system/post/index', + iconColor: '#eb2f96', + permission: 'system:post:query', + }, + ], + }, + { + key: 'infra', + name: '基础设施', + menus: [ + { + key: 'accessLog', + name: '访问日志', + icon: 'laptop', + url: '/pages-infra/apiAccessLog/index', + iconColor: '#2f54eb', + permission: 'infra:api-access-log:query', + }, + { + key: 'errorLog', + name: '错误日志', + icon: 'error-circle', + url: '/pages-infra/apiErrorLog/index', + iconColor: '#f5222d', + permission: 'infra:api-error-log:query', + }, + { + key: 'websocket', + name: 'WebSocket', + icon: 'chat', + url: '/pages-infra/webSocket/index', + iconColor: '#36cfc9', + }, + ], + }, + { + key: 'bpm', + name: '工作流程', + menus: [ + { + key: 'bpmMy', + name: '我的流程', + icon: 'list', + url: '/pages/bpm/index?tab=my', + iconColor: '#597ef7', + permission: 'bpm:process-instance:query', + }, + { + key: 'bpmTodo', + name: '待办任务', + icon: 'clock', + url: '/pages/bpm/index?tab=todo', + iconColor: '#ff7a45', + permission: 'bpm:task:query', + }, + { + key: 'bpmDone', + name: '已办任务', + icon: 'check-circle', + url: '/pages/bpm/index?tab=done', + iconColor: '#73d13d', + permission: 'bpm:task:query', + }, + { + key: 'bpmCopy', + name: '抄送我的', + icon: 'mail', + url: '/pages/bpm/index?tab=copy', + iconColor: '#5cdbd3', + permission: 'bpm:process-instance-cc:query', + }, + ], + }, +] + +/** + * 获取所有菜单分组数据(带权限过滤):过滤掉没有权限的菜单项,如果整个分组都没有权限则不展示该分组 + */ +export function getMenuGroups(): MenuGroup[] { + const { hasAccessByCodes } = useAccess() + return menuGroupsData + .map(group => ({ + ...group, + // 过滤掉没有权限的菜单项 + menus: group.menus.filter((menu) => { + // 没有配置权限的菜单项默认展示 + if (!menu.permission) { + return true + } + return hasAccessByCodes([menu.permission]) + }), + })) + // 过滤掉没有菜单项的分组 + .filter(group => group.menus.length > 0) +} + +/** 获取所有菜单项(扁平化) */ +export function getAllMenuItems(): MenuItem[] { + const groups = getMenuGroups() + return groups.flatMap(group => group.menus) +} + +/** 根据 key 获取菜单项 */ +export function getMenuItemByKey(key: string): MenuItem | undefined { + return getAllMenuItems().find(item => item.key === key) +} diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue index 27b81b8..9cb3498 100644 --- a/src/pages/index/index.vue +++ b/src/pages/index/index.vue @@ -1,53 +1,31 @@ + + - - diff --git a/src/pages/index/settings/index.vue b/src/pages/index/settings/index.vue new file mode 100644 index 0000000..3944a1a --- /dev/null +++ b/src/pages/index/settings/index.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/src/pages/me/me.vue b/src/pages/me/me.vue deleted file mode 100644 index 5df9e2e..0000000 --- a/src/pages/me/me.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - diff --git a/src/pages/message/components/detail-popup.vue b/src/pages/message/components/detail-popup.vue new file mode 100644 index 0000000..177e708 --- /dev/null +++ b/src/pages/message/components/detail-popup.vue @@ -0,0 +1,82 @@ + + + diff --git a/src/pages/message/components/search-form.vue b/src/pages/message/components/search-form.vue new file mode 100644 index 0000000..1c02465 --- /dev/null +++ b/src/pages/message/components/search-form.vue @@ -0,0 +1,172 @@ + + + diff --git a/src/pages/message/index.vue b/src/pages/message/index.vue new file mode 100644 index 0000000..ad422c4 --- /dev/null +++ b/src/pages/message/index.vue @@ -0,0 +1,237 @@ + + + + + diff --git a/src/pages/user/contact/index.vue b/src/pages/user/contact/index.vue new file mode 100644 index 0000000..85ffd2a --- /dev/null +++ b/src/pages/user/contact/index.vue @@ -0,0 +1,90 @@ + + + \ No newline at end of file diff --git a/src/pages/user/faq/data.ts b/src/pages/user/faq/data.ts new file mode 100644 index 0000000..70eef22 --- /dev/null +++ b/src/pages/user/faq/data.ts @@ -0,0 +1,66 @@ +/** + * FAQ 常见问题数据 + */ +export interface FaqItem { + /** 问题标题 */ + title: string + /** 问题答案 */ + content: string +} + +export interface FaqCategory { + /** 分类图标 */ + icon: string + /** 分类标题 */ + title: string + /** 问题列表 */ + childList: FaqItem[] +} + +/** FAQ 数据列表 */ +export const faqList: FaqCategory[] = [ + { + icon: 'github-filled', + title: '芋道问题', + childList: [ + { + title: '芋道开源吗?', + content: '开源,基于 MIT 协议,可免费商用。', + }, + { + title: '芋道可以商用吗?', + content: '可以,芋道采用 MIT 开源协议,允许商业使用。', + }, + { + title: '芋道官网地址多少?', + content: 'https://www.iocoder.cn', + }, + { + title: '芋道文档地址多少?', + content: 'https://doc.iocoder.cn', + }, + ], + }, + { + icon: 'warning', + title: '其他问题', + childList: [ + { + title: '如何退出登录?', + content: '请点击 [我的] - [退出登录] 即可退出登录。', + }, + { + title: '如何修改用户头像?', + content: '请点击 [我的] - [个人资料] - [选择头像] 即可更换用户头像。', + }, + { + title: '如何修改登录密码?', + content: '请点击 [我的] - [账号安全] - [修改密码] 即可修改登录密码。', + }, + { + title: '如何切换用户?', + content: '请先退出当前账号,然后使用其他账号重新登录即可。', + }, + ], + }, +] diff --git a/src/pages/user/faq/index.vue b/src/pages/user/faq/index.vue new file mode 100644 index 0000000..41782e0 --- /dev/null +++ b/src/pages/user/faq/index.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/src/pages/user/feedback/index.vue b/src/pages/user/feedback/index.vue new file mode 100644 index 0000000..2ada310 --- /dev/null +++ b/src/pages/user/feedback/index.vue @@ -0,0 +1,205 @@ + + + + + diff --git a/src/pages/user/index.vue b/src/pages/user/index.vue new file mode 100644 index 0000000..f656a1c --- /dev/null +++ b/src/pages/user/index.vue @@ -0,0 +1,176 @@ + + + + + diff --git a/src/pages/user/profile/components/form.vue b/src/pages/user/profile/components/form.vue new file mode 100644 index 0000000..1bcad3c --- /dev/null +++ b/src/pages/user/profile/components/form.vue @@ -0,0 +1,149 @@ + + + diff --git a/src/pages/user/profile/index.vue b/src/pages/user/profile/index.vue new file mode 100644 index 0000000..e654884 --- /dev/null +++ b/src/pages/user/profile/index.vue @@ -0,0 +1,138 @@ + + + + + diff --git a/src/pages/user/security/components/password-form.vue b/src/pages/user/security/components/password-form.vue new file mode 100644 index 0000000..f8d532f --- /dev/null +++ b/src/pages/user/security/components/password-form.vue @@ -0,0 +1,122 @@ + + + diff --git a/src/pages/user/security/index.vue b/src/pages/user/security/index.vue new file mode 100644 index 0000000..1562604 --- /dev/null +++ b/src/pages/user/security/index.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/pages/user/settings/agreement/index.vue b/src/pages/user/settings/agreement/index.vue new file mode 100644 index 0000000..6a05fe5 --- /dev/null +++ b/src/pages/user/settings/agreement/index.vue @@ -0,0 +1,122 @@ + + + \ No newline at end of file diff --git a/src/pages/user/settings/index.vue b/src/pages/user/settings/index.vue new file mode 100644 index 0000000..92f80bb --- /dev/null +++ b/src/pages/user/settings/index.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/src/pages/user/settings/privacy/index.vue b/src/pages/user/settings/privacy/index.vue new file mode 100644 index 0000000..a6cbd52 --- /dev/null +++ b/src/pages/user/settings/privacy/index.vue @@ -0,0 +1,157 @@ + + + \ No newline at end of file diff --git a/uno.config.ts b/uno.config.ts index 7a2f94c..4a4401f 100644 --- a/uno.config.ts +++ b/uno.config.ts @@ -71,7 +71,7 @@ export default defineConfig({ }, ], // 动态图标需要在这里配置,或者写在vue页面中注释掉 - safelist: ['i-carbon-code', 'i-carbon-home', 'i-carbon-user'], + safelist: ['i-carbon-code', 'i-carbon-home', 'i-carbon-user', 'i-carbon-document', 'i-carbon-chat', 'i-carbon-user-avatar'], rules: [ [ 'p-safe',