From 68882f94cf92f18fb4514ea4d3157fa687db6d69 Mon Sep 17 00:00:00 2001 From: ddrwode <34234@3来 34> Date: Fri, 6 Mar 2026 16:35:38 +0800 Subject: [PATCH] ha'ha --- .env.development | 3 +- src/api/BoosAccountManagement/index.ts | 9 + src/api/ScreeningManagement/index.ts | 71 -- src/api/TaskManagement/index.ts | 41 +- src/api/ai/index.ts | 191 ----- src/api/auth-api.ts | 86 --- src/composables/auth/useTokenRefresh.ts | 91 --- src/composables/index.ts | 2 +- src/composables/useAiAction.ts | 56 +- src/enums/api/code-enum.ts | 18 +- src/router/index.ts | 19 - src/settings.ts | 2 +- src/store/modules/user-store.ts | 27 - src/styles/index.scss | 3 +- src/styles/ops-ui.scss | 79 ++ src/types/global.d.ts | 6 +- src/utils/request.ts | 42 +- .../components/RecruitTaskForm.vue | 346 ++++++++- src/views/BoosAccountManagement/index.vue | 616 +++++++++------- src/views/ContactInformation/index.vue | 350 ++++----- .../components/DailyDataBreakdown.vue | 97 +-- .../components/DataTrendChart.vue | 28 +- src/views/DataStatistics/index.vue | 381 ++++++---- .../components/FilterSettingsForm.vue | 137 ---- src/views/ScreeningManagement/index.vue | 240 ------ src/views/dashboard/index.vue | 691 ++++++++++++++---- 26 files changed, 1829 insertions(+), 1803 deletions(-) delete mode 100644 src/api/ScreeningManagement/index.ts delete mode 100644 src/api/ai/index.ts delete mode 100644 src/api/auth-api.ts delete mode 100644 src/composables/auth/useTokenRefresh.ts create mode 100644 src/styles/ops-ui.scss delete mode 100644 src/views/ScreeningManagement/components/FilterSettingsForm.vue delete mode 100644 src/views/ScreeningManagement/index.vue diff --git a/.env.development b/.env.development index b03c6a3..e1bfcd0 100644 --- a/.env.development +++ b/.env.development @@ -9,8 +9,7 @@ VITE_APP_BASE_API=/dev-api VITE_APP_ENV = 'development' # 接口地址 -# VITE_APP_API_URL=http://192.168.0.61:8007 # 本地 -VITE_APP_API_URL=http://26.151.107.60:8007 # 本地 +VITE_APP_API_URL=http://8.137.99.82:9000 # WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws VITE_APP_WS_ENDPOINT= diff --git a/src/api/BoosAccountManagement/index.ts b/src/api/BoosAccountManagement/index.ts index 02fd6a7..63d4b30 100644 --- a/src/api/BoosAccountManagement/index.ts +++ b/src/api/BoosAccountManagement/index.ts @@ -85,3 +85,12 @@ export const ApiRecruitFilterOptions = (accountId: string) => { method: 'get' }) } + +// 触发筛选条件同步(派发任务给 Worker 抓取) +export const ApiRecruitFilterSync = (accountId: string) => { + return request({ + url: `/api/filters/sync`, + method: 'post', + data: { account_id: accountId } + }) +} diff --git a/src/api/ScreeningManagement/index.ts b/src/api/ScreeningManagement/index.ts deleted file mode 100644 index 3cd3f86..0000000 --- a/src/api/ScreeningManagement/index.ts +++ /dev/null @@ -1,71 +0,0 @@ -import request from '@/utils/request' - -/* - * 筛选管理 - * */ - -// 获取筛选配置列表 -export const ApiFilters = () => { - return request({ - url: `/api/filters`, - method: 'get' - }) -} - -// 获取单个复聊配置 -export const ApiFiltersId = (id: string) => { - return request({ - url: `/api/filters/${id}`, - method: 'get' - }) -} - -// 创建筛选配置 -export const ApiFiltersAdd = (data: any) => { - const formData = new FormData() - formData.append('name', data.name) - formData.append('position_keywords', data.position_keywords) - formData.append('city', data.city) - formData.append('salary_min', data.salary_min) - formData.append('salary_max', data.salary_max) - formData.append('experience', data.experience) - formData.append('education', data.education) - formData.append('is_active', data.is_active) - return request({ - url: `/api/filters`, - method: 'post', - data: formData, - headers: { - 'Content-Type': 'multipart/form-data' - } - }) -} - -// 更新筛选配置 -export const ApiFiltersEditor = (data: any) => { - const formData = new FormData() - if (data.name) formData.append('name', data.name) - if (data.position_keywords) formData.append('position_keywords', data.position_keywords) - if (data.city) formData.append('city', data.city) - if (data.salary_min) formData.append('salary_min', data.salary_min) - if (data.salary_max) formData.append('salary_max', data.salary_max) - if (data.experience) formData.append('experience', data.experience) - if (data.education) formData.append('education', data.education) - formData.append('is_active', data.is_active) - return request({ - url: `/api/filters/${data.id}`, - method: 'put', - data: formData, - headers: { - 'Content-Type': 'multipart/form-data' - } - }) -} - -// 删除筛选配置 -export const ApiFiltersDelete = (id: string) => { - return request({ - url: `/api/filters/${id}`, - method: 'delete' - }) -} diff --git a/src/api/TaskManagement/index.ts b/src/api/TaskManagement/index.ts index 470af09..b611856 100644 --- a/src/api/TaskManagement/index.ts +++ b/src/api/TaskManagement/index.ts @@ -4,7 +4,7 @@ import request from '@/utils/request' * 任务管理 * */ -// 查询任务列表 +// 查询指定账号的任务列表 export const ApiTasks = (boss_id: string, page: number, page_size: number) => { return request({ url: `/api/tasks/${boss_id}?page=${page}&page_size=${page_size}`, @@ -15,7 +15,7 @@ export const ApiTasks = (boss_id: string, page: number, page_size: number) => { // 查询指定任务的状态和结果 export const ApiTasksTaskId = (task_id: string) => { return request({ - url: `/api/tasks/${task_id}`, + url: `/api/tasks/detail/${task_id}`, method: 'get' }) } @@ -24,8 +24,6 @@ export const ApiTasksTaskId = (task_id: string) => { export const ApiTasksAdd = (data: any) => { const formData = new FormData() formData.append('task_type', data.task_type) - // formData.append('worker_id', data.worker_id) - // formData.append('account_name', data.account_name) formData.append('id', data.boss_id) const rawParams = data?.params if (typeof rawParams === 'string') { @@ -43,31 +41,10 @@ export const ApiTasksAdd = (data: any) => { }) } -// // 编辑申请用印 -// export const BusinessEditApplication = (data: any) => { -// const formData = new FormData() -// formData.append('id', data.id) -// formData.append('Printingpurpose', data.Printingpurpose) -// formData.append('case_id', data.case_id) -// formData.append('Reason', data.Reason) -// formData.append('seal_number', data.seal_number) -// formData.append('seal_type', data.seal_type) -// if (isFile(data.file)) formData.append('file', data.file) -// formData.append('approvers', data.approvers) -// return request({ -// url: `/business/editApplication`, -// method: 'post', -// data: formData, -// headers: { -// 'Content-Type': 'multipart/form-data' -// } -// }) -// } -// -// // 删除指定账号 -// export const ApiAccountsDelete = (id: string) => { -// return request({ -// url: `/api/accounts/${id}`, -// method: 'delete' -// }) -// } +// 取消指定任务 +export const ApiTasksCancel = (task_id: string) => { + return request({ + url: `/api/tasks/${task_id}/cancel`, + method: 'post' + }) +} diff --git a/src/api/ai/index.ts b/src/api/ai/index.ts deleted file mode 100644 index 5705c5f..0000000 --- a/src/api/ai/index.ts +++ /dev/null @@ -1,191 +0,0 @@ -import request from '@/utils/request' - -/** - * AI 命令请求参数 - */ -export interface AiCommandRequest { - /** 用户输入的自然语言命令 */ - command: string - /** 当前页面路由(用于上下文) */ - currentRoute?: string - /** 当前激活的组件名称 */ - currentComponent?: string - /** 额外上下文信息 */ - context?: Record -} - -/** - * 函数调用参数 - */ -export interface FunctionCall { - /** 函数名称 */ - name: string - /** 函数描述 */ - description?: string - /** 参数对象 */ - arguments: Record -} - -/** - * AI 命令解析响应 - */ -export interface AiCommandResponse { - /** 解析日志ID(用于关联执行记录) */ - parseLogId?: string - /** 是否成功解析 */ - success: boolean - /** 解析后的函数调用列表 */ - functionCalls: FunctionCall[] - /** AI 的理解和说明 */ - explanation?: string - /** 置信度 (0-1) */ - confidence?: number - /** 错误信息 */ - error?: string - /** 原始 LLM 响应(用于调试) */ - rawResponse?: string -} - -/** - * AI 命令执行请求 - */ -export interface AiExecuteRequest { - /** 关联的解析日志ID */ - parseLogId?: string - /** 原始命令(用于审计) */ - originalCommand?: string - /** 要执行的函数调用 */ - functionCall: FunctionCall - /** 确认模式:auto=自动执行, manual=需要用户确认 */ - confirmMode?: 'auto' | 'manual' - /** 用户确认标志 */ - userConfirmed?: boolean - /** 幂等性令牌(防止重复执行) */ - idempotencyKey?: string - /** 当前页面路由 */ - currentRoute?: string -} - -/** - * AI 命令执行响应 - */ -export interface AiExecuteResponse { - /** 是否执行成功 */ - success: boolean - /** 执行结果数据 */ - data?: any - /** 执行结果说明 */ - message?: string - /** 影响的记录数 */ - affectedRows?: number - /** 错误信息 */ - error?: string - /** 记录ID(用于追踪) */ - recordId?: string - /** 需要用户确认 */ - requiresConfirmation?: boolean - /** 确认提示信息 */ - confirmationPrompt?: string -} - -export interface AiCommandRecordPageQuery extends PageQuery { - keywords?: string - executeStatus?: string - parseSuccess?: boolean - userId?: number - isDangerous?: boolean - provider?: string - model?: string - functionName?: string - createTime?: [string, string] -} - -export interface AiCommandRecordVO { - id: string - userId: number - username: string - originalCommand: string - provider?: string - model?: string - parseSuccess?: boolean - functionCalls?: string - explanation?: string - confidence?: number - parseErrorMessage?: string - inputTokens?: number - outputTokens?: number - totalTokens?: number - parseTime?: number - functionName?: string - functionArguments?: string - executeStatus?: string - executeResult?: string - executeErrorMessage?: string - affectedRows?: number - isDangerous?: boolean - requiresConfirmation?: boolean - userConfirmed?: boolean - executionTime?: number - ipAddress?: string - userAgent?: string - currentRoute?: string - createTime?: string - updateTime?: string - remark?: string -} - -/** - * AI 命令 API - */ -class AiCommandApi { - /** - * 解析自然语言命令 - * - * @param data 命令请求参数 - * @returns 解析结果 - */ - static parseCommand(data: AiCommandRequest): Promise { - return request({ - url: '/api/v1/ai/command/parse', - method: 'post', - data - }) - } - - /** - * 执行已解析的命令 - * - * @param data 执行请求参数 - * @returns 执行结果数据(成功时返回,失败时抛出异常) - */ - static executeCommand(data: AiExecuteRequest): Promise { - return request({ - url: '/api/v1/ai/command/execute', - method: 'post', - data - }) - } - - /** - * 获取命令记录分页列表 - */ - static getCommandRecordPage(queryParams: AiCommandRecordPageQuery) { - return request>({ - url: '/api/v1/ai/command/records', - method: 'get', - params: queryParams - }) - } - - /** - * 撤销命令执行(如果支持) - */ - static rollbackCommand(recordId: string) { - return request({ - url: `/api/v1/ai/command/rollback/${recordId}`, - method: 'post' - }) - } -} - -export default AiCommandApi diff --git a/src/api/auth-api.ts b/src/api/auth-api.ts deleted file mode 100644 index a0074ac..0000000 --- a/src/api/auth-api.ts +++ /dev/null @@ -1,86 +0,0 @@ -import request from '@/utils/request' - -const AUTH_BASE_URL = '/api/v1/auth' - -const AuthAPI = { - /** 登录接口*/ - login(data: LoginFormData) { - const formData = new FormData() - formData.append('username', 'admin') - formData.append('password', data.password) - formData.append('captchaKey', data.captchaKey) - formData.append('captchaCode', data.captchaCode) - return request({ - url: `${AUTH_BASE_URL}/login`, - method: 'post', - data: formData, - headers: { - 'Content-Type': 'multipart/form-data' - } - }) - }, - - /** 刷新 token 接口*/ - refreshToken(refreshToken: string) { - return request({ - url: `${AUTH_BASE_URL}/refresh-token`, - method: 'post', - params: { refreshToken }, - headers: { - Authorization: 'no-auth' - } - }) - }, - - /** 退出登录接口 */ - logout() { - return request({ - url: `${AUTH_BASE_URL}/logout`, - method: 'delete' - }) - }, - - /** 获取验证码接口*/ - getCaptcha() { - return request({ - url: `${AUTH_BASE_URL}/captcha`, - method: 'get' - }) - } -} - -export default AuthAPI - -/** 登录表单数据 */ -export interface LoginFormData { - /** 用户名 */ - username: string - /** 密码 */ - password: string - /** 验证码缓存key */ - captchaKey: string - /** 验证码 */ - captchaCode: string - /** 记住我 */ - rememberMe: boolean -} - -/** 登录响应 */ -export interface LoginResult { - /** 访问令牌 */ - accessToken: string - /** 刷新令牌 */ - refreshToken: string - /** 令牌类型 */ - tokenType: string - /** 过期时间(秒) */ - expiresIn: number -} - -/** 验证码信息 */ -export interface CaptchaInfo { - /** 验证码缓存key */ - captchaKey: string - /** 验证码图片Base64字符串 */ - captchaBase64: string -} diff --git a/src/composables/auth/useTokenRefresh.ts b/src/composables/auth/useTokenRefresh.ts deleted file mode 100644 index 2d37880..0000000 --- a/src/composables/auth/useTokenRefresh.ts +++ /dev/null @@ -1,91 +0,0 @@ -import type { InternalAxiosRequestConfig } from 'axios' -import { useUserStoreHook } from '@/store/modules/user-store' -import { AuthStorage, redirectToLogin } from '@/utils/auth' - -/** - * 重试请求的回调函数类型 - */ -type RetryCallback = () => void - -/** - * Token刷新组合式函数 - */ -export function useTokenRefresh() { - // Token 刷新相关状态 - let isRefreshingToken = false - const pendingRequests: RetryCallback[] = [] - - /** - * 刷新 Token 并重试请求 - */ - async function refreshTokenAndRetry( - config: InternalAxiosRequestConfig, - httpRequest: any - ): Promise { - return new Promise((resolve, reject) => { - // 封装需要重试的请求 - const retryRequest = () => { - const newToken = AuthStorage.getAccessToken() - if (newToken && config.headers) { - config.headers.Authorization = `Bearer ${newToken}` - } - httpRequest(config).then(resolve).catch(reject) - } - - // 将请求加入等待队列 - pendingRequests.push(retryRequest) - - // 如果没有正在刷新,则开始刷新流程 - if (!isRefreshingToken) { - isRefreshingToken = true - - useUserStoreHook() - .refreshToken() - .then(() => { - // 刷新成功,重试所有等待的请求 - pendingRequests.forEach((callback) => { - try { - callback() - } catch (error) { - console.error('Retry request error:', error) - } - }) - // 清空队列 - pendingRequests.length = 0 - }) - .catch(async (error) => { - console.error('Token refresh failed:', error) - // 刷新失败,先 reject 所有等待的请求,再清空队列 - const failedRequests = [...pendingRequests] - pendingRequests.length = 0 - - // 拒绝所有等待的请求 - failedRequests.forEach(() => { - reject(new Error('Token refresh failed')) - }) - - // 跳转登录页 - await redirectToLogin('登录状态已失效,请重新登录') - }) - .finally(() => { - isRefreshingToken = false - }) - } - }) - } - - /** - * 获取刷新状态(用于外部判断) - */ - function getRefreshStatus() { - return { - isRefreshing: isRefreshingToken, - pendingCount: pendingRequests.length - } - } - - return { - refreshTokenAndRetry, - getRefreshStatus - } -} diff --git a/src/composables/index.ts b/src/composables/index.ts index 185e184..01a98d8 100644 --- a/src/composables/index.ts +++ b/src/composables/index.ts @@ -2,7 +2,7 @@ export { useStomp } from './websocket/useStomp' export { useDictSync } from './websocket/useDictSync' export type { DictMessage } from './websocket/useDictSync' export { useOnlineCount } from './websocket/useOnlineCount' -export { useTokenRefresh } from './auth/useTokenRefresh' + export { useLayout } from './layout/useLayout' export { useLayoutMenu } from './layout/useLayoutMenu' diff --git a/src/composables/useAiAction.ts b/src/composables/useAiAction.ts index ca9b1f3..7771c91 100644 --- a/src/composables/useAiAction.ts +++ b/src/composables/useAiAction.ts @@ -1,7 +1,6 @@ import { useRoute } from 'vue-router' import { ElMessage, ElMessageBox } from 'element-plus' import { onMounted, onBeforeUnmount, nextTick } from 'vue' -import AiCommandApi from '@/api/ai' /** * AI 操作处理器(简化版) @@ -11,17 +10,17 @@ import AiCommandApi from '@/api/ai' export type AiActionHandler = | ((args: T) => Promise | void) | { - /** 执行函数 */ - execute: (args: T) => Promise | void - /** 是否需要确认(默认 true) */ - needConfirm?: boolean - /** 确认消息(支持函数或字符串) */ - confirmMessage?: string | ((args: T) => string) - /** 成功消息(支持函数或字符串) */ - successMessage?: string | ((args: T) => string) - /** 是否调用后端 API(默认 false,如果为 true 则自动调用 executeCommand) */ - callBackendApi?: boolean - } + /** 执行函数 */ + execute: (args: T) => Promise | void + /** 是否需要确认(默认 true) */ + needConfirm?: boolean + /** 确认消息(支持函数或字符串) */ + confirmMessage?: string | ((args: T) => string) + /** 成功消息(支持函数或字符串) */ + successMessage?: string | ((args: T) => string) + /** 是否调用后端 API(默认 false,如果为 true 则自动调用 executeCommand) */ + callBackendApi?: boolean + } /** * AI 操作配置 @@ -104,17 +103,8 @@ export function useAiAction(options: UseAiActionOptions = {}) { // 2. 执行阶段 if (config.callBackendApi) { - // 自动调用后端 API - await AiCommandApi.executeCommand({ - originalCommand: action.originalCommand || '', - confirmMode: 'manual', - userConfirmed: true, - currentRoute, - functionCall: { - name: fnCall.name, - arguments: fnCall.arguments - } - }) + // AI 后端 API 暂未实现 + ElMessage.warning('AI 后端接口暂未实现') } else { // 执行自定义函数 await config.execute(fnCall.arguments) @@ -179,24 +169,8 @@ export function useAiAction(options: UseAiActionOptions = {}) { } } - try { - await AiCommandApi.executeCommand({ - originalCommand, - confirmMode, - userConfirmed: true, - currentRoute, - functionCall: { - name: functionName, - arguments: args - } - }) - - ElMessage.success('操作执行成功') - } catch (error: any) { - if (error !== 'cancel') { - throw error - } - } + // AI 后端 API 暂未实现 + ElMessage.warning('AI 后端接口暂未实现') } /** diff --git a/src/enums/api/code-enum.ts b/src/enums/api/code-enum.ts index f5328fb..03d3cdb 100644 --- a/src/enums/api/code-enum.ts +++ b/src/enums/api/code-enum.ts @@ -3,21 +3,11 @@ */ export const enum ApiCodeEnum { /** - * 成功 + * 成功(后端 api_success 返回 code=0) */ - SUCCESS = '00000', + SUCCESS = 0, /** - * 错误 + * 未认证 / Token 无效(后端返回 HTTP 401) */ - ERROR = 'B0001', - - /** - * 访问令牌无效或过期 - */ - ACCESS_TOKEN_INVALID = 'A0230', - - /** - * 刷新令牌无效或过期 - */ - REFRESH_TOKEN_INVALID = 'A0231' + UNAUTHORIZED = 401, } diff --git a/src/router/index.ts b/src/router/index.ts index 0da380e..4c5c207 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -362,25 +362,6 @@ export const constantRoutes: RouteRecordRaw[] = [ } } ] - }, - { - path: '/screening', - name: 'Screening', - component: Layout, - meta: { - title: '筛选管理', - icon: 'setting' - }, - children: [ - { - path: 'screeningManagement', - name: 'ScreeningManagement', - component: () => import('@/views/ScreeningManagement/index.vue'), - meta: { - title: '筛选管理' - } - } - ] } // 注册平台登记 // { diff --git a/src/settings.ts b/src/settings.ts index deac95b..39dfecb 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -48,7 +48,7 @@ export const authConfig = { * * 适用场景:后端没有刷新接口或不需要自动刷新的项目可设为false */ - enableTokenRefresh: true + enableTokenRefresh: false } as const // 主题色预设 - 现代配色方案(基于示例模板风格) diff --git a/src/store/modules/user-store.ts b/src/store/modules/user-store.ts index 4719332..ec12f67 100644 --- a/src/store/modules/user-store.ts +++ b/src/store/modules/user-store.ts @@ -1,6 +1,5 @@ import { store } from '@/store' -import AuthAPI from '@/api/auth-api' import type { UserInfo } from '@/api/system/user-api' import { AuthStorage } from '@/utils/auth' @@ -107,31 +106,6 @@ export const useUserStore = defineStore('user', () => { setPermissionCharactersArr([]) } - /** - * 刷新 token - */ - function refreshToken() { - const refreshToken = AuthStorage.getRefreshToken() - - if (!refreshToken) { - return Promise.reject(new Error('没有有效的刷新令牌')) - } - - return new Promise((resolve, reject) => { - AuthAPI.refreshToken(refreshToken) - .then((data) => { - const { accessToken, refreshToken: newRefreshToken } = data - // 更新令牌,保持当前记住我状态 - AuthStorage.setTokens(accessToken, newRefreshToken, AuthStorage.getRememberMe()) - resolve() - }) - .catch((error) => { - console.log(' refreshToken 刷新失败', error) - reject(error) - }) - }) - } - const checkPermission = (permission: string): boolean => { if (userInfo.value?.permission_data.includes('*:*:*')) { return true @@ -149,7 +123,6 @@ export const useUserStore = defineStore('user', () => { logout, resetAllState, resetUserState, - refreshToken, permissionCharactersArr, setPermissionCharactersArr, checkPermission diff --git a/src/styles/index.scss b/src/styles/index.scss index c1536c9..240b039 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -1,6 +1,7 @@ @use "./reset"; @use "./element-plus"; @use "./template-style"; // 示例模板风格 +@use "./ops-ui"; // Vxe Table @use "./vxe-table"; @import url("./vxe-table.css"); @@ -190,4 +191,4 @@ html.sidebar-color-blue { } } } -} \ No newline at end of file +} diff --git a/src/styles/ops-ui.scss b/src/styles/ops-ui.scss new file mode 100644 index 0000000..198d452 --- /dev/null +++ b/src/styles/ops-ui.scss @@ -0,0 +1,79 @@ +:root { + --ops-radius-lg: 14px; + --ops-radius-md: 10px; + --ops-border-color: #e8edf5; + --ops-soft-bg: #f7f9fc; + --ops-hover-bg: #f5f9ff; + --ops-title-color: #1f2d3d; + --ops-text-regular: #303133; + --ops-text-secondary: #909399; +} + +.ops-page { + .ops-card { + border: 1px solid var(--ops-border-color); + border-radius: var(--ops-radius-lg); + } + + .ops-section-title { + color: var(--ops-title-color); + font-weight: 700; + letter-spacing: 0.25px; + } + + .ops-table { + .el-table__header th { + background: var(--ops-soft-bg); + color: #475569; + } + + .el-table__row:hover > td { + background: var(--ops-hover-bg) !important; + } + } + + .ops-status-tag { + min-width: 64px; + justify-content: center; + border-radius: 999px; + font-weight: 600; + letter-spacing: 0.2px; + } + + .ops-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + flex-wrap: wrap; + } + + .ops-actions { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; + } + + .ops-btn { + --el-button-border-radius: 10px; + min-height: 32px; + padding: 0 14px; + font-weight: 600; + letter-spacing: 0.2px; + } + + .ops-btn.el-button--small { + min-height: 28px; + padding: 0 10px; + } +} + +@media (max-width: 768px) { + .ops-page { + .ops-btn { + min-height: 30px; + padding: 0 12px; + } + } +} diff --git a/src/types/global.d.ts b/src/types/global.d.ts index 5a0d0f6..fb772e8 100644 --- a/src/types/global.d.ts +++ b/src/types/global.d.ts @@ -3,7 +3,7 @@ declare global { * 响应数据 */ interface ApiResponse { - code: string + code: number data: T msg: string } @@ -99,7 +99,7 @@ declare global { */ interface ExcelResult { /** 状态码 */ - code: string + code: number /** 无效数据条数 */ invalidCount: number /** 有效数据条数 */ @@ -108,4 +108,4 @@ declare global { messageList: Array } } -export {} +export { } diff --git a/src/utils/request.ts b/src/utils/request.ts index d648b22..298d20b 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -2,11 +2,6 @@ import axios, { type InternalAxiosRequestConfig, type AxiosResponse } from 'axio import qs from 'qs' import { ApiCodeEnum } from '@/enums/api/code-enum' import { AuthStorage, redirectToLogin } from '@/utils/auth' -import { useTokenRefresh } from '@/composables/auth/useTokenRefresh' -import { authConfig } from '@/settings' - -// 初始化token刷新组合式函数 -const { refreshTokenAndRetry } = useTokenRefresh() /** * 创建 HTTP 请求实例 @@ -50,8 +45,8 @@ httpRequest.interceptors.response.use( } const { code, msg } = response.data - // 请求成功 - if (code === ApiCodeEnum.SUCCESS || code == '0' || code == '200') { + // 请求成功:后端成功响应 code === 0 + if (code === ApiCodeEnum.SUCCESS) { return response.data as any } @@ -62,7 +57,7 @@ httpRequest.interceptors.response.use( async (error) => { console.error('Response interceptor error:', error) - const { config, response } = error + const { response } = error // 网络错误或服务器无响应 if (!response) { @@ -70,29 +65,16 @@ httpRequest.interceptors.response.use( return Promise.reject(error) } - const { code, message } = response.data as any - - switch (code) { - case ApiCodeEnum.ACCESS_TOKEN_INVALID: - // Access Token 过期 - if (authConfig.enableTokenRefresh) { - // 启用了token刷新,尝试刷新 - return refreshTokenAndRetry(config, httpRequest) - } else { - // 未启用token刷新,直接跳转登录页 - await redirectToLogin('登录已过期,请重新登录') - return Promise.reject(new Error(message || 'Access Token Invalid')) - } - - case ApiCodeEnum.REFRESH_TOKEN_INVALID: - // Refresh Token 过期,跳转登录页 - await redirectToLogin('登录已过期,请重新登录') - return Promise.reject(new Error(message || 'Refresh Token Invalid')) - - default: - ElMessage.error(message || '请求失败') - return Promise.reject(new Error(message || 'Request Error')) + // HTTP 401:Token 无效或过期,直接跳转登录页 + if (response.status === 401) { + await redirectToLogin('登录已过期,请重新登录') + return Promise.reject(new Error('Token Invalid')) } + + // 其他错误 + const msg = response.data?.msg || response.data?.message || '请求失败' + ElMessage.error(msg) + return Promise.reject(new Error(msg)) } ) diff --git a/src/views/BoosAccountManagement/components/RecruitTaskForm.vue b/src/views/BoosAccountManagement/components/RecruitTaskForm.vue index d34d378..dcd5bd0 100644 --- a/src/views/BoosAccountManagement/components/RecruitTaskForm.vue +++ b/src/views/BoosAccountManagement/components/RecruitTaskForm.vue @@ -1,7 +1,15 @@ + + diff --git a/src/views/ContactInformation/index.vue b/src/views/ContactInformation/index.vue index 1ec2315..7adeea3 100644 --- a/src/views/ContactInformation/index.vue +++ b/src/views/ContactInformation/index.vue @@ -1,12 +1,16 @@