diff --git a/src/api/prison/ai-dash-entry/index.ts b/src/api/prison/ai-dash-entry/index.ts new file mode 100644 index 00000000..570af494 --- /dev/null +++ b/src/api/prison/ai-dash-entry/index.ts @@ -0,0 +1,71 @@ +import request from '@/config/axios' + +/** 风险分布数据项 */ +export interface RiskDistributionVO { + name: string + value: number + color: string +} + +/** 风险趋势数据项 */ +export interface RiskTrendVO { + month: string + highRisk: number + warning: number + normal: number +} + +/** AI心航360°统计数据 */ +export interface AiDashEntryStatisticsVO { + // 统计卡片 + totalCount: number + monthlyNewCount: number + monthlyChange: number + highRiskCount: number + highRiskMonthlyNew: number + highRiskMonthlyChange: number + warningCount: number + warningMonthlyNew: number + warningMonthlyChange: number + normalCount: number + normalMonthlyNew: number + normalMonthlyChange: number + // 图表数据 + riskDistribution: RiskDistributionVO[] + riskTrendData: RiskTrendVO[] +} + +/** 重点关注对象 */ +export interface FocusPersonVO { + id: number + name: string + gender: string + age: number + riskLevelType: string + riskLevel: string + supervisionArea: string + psychologicalRiskLevel: string + isNew: boolean +} + +/** 重点关注对象分页请求 */ +export interface FocusPersonPageReqVO { + pageNo: number + pageSize: number + riskLevelType?: string + name?: string + areaId?: number +} + +/** AI心航360° API */ +export const AiDashEntryApi = { + /** 获取AI心航360°统计数据 */ + getStatistics: async (): Promise => { + return await request.get({ url: '/prison/dashboard/ai-dash-entry/statistics' }) + }, + + /** 获取重点关注对象分页列表 */ + getFocusPersonPage: async (params: FocusPersonPageReqVO) => { + return await request.get({ url: '/prison/dashboard/ai-dash-entry/focus-person-page', params }) + } +} diff --git a/src/api/prison/consumption/index.ts b/src/api/prison/consumption/index.ts index e0a124bf..73651199 100644 --- a/src/api/prison/consumption/index.ts +++ b/src/api/prison/consumption/index.ts @@ -90,5 +90,17 @@ export const ConsumptionApi = { // 导出消费订单 Excel exportConsumption: async (params: ConsumptionPageParams) => { return await request.download({ url: `/prison/consumption/export-excel`, params }) + }, + + // 获取导入模板 + getImportTemplate: async () => { + return await request.download({ url: `/prison/consumption/get-import-template` }) + }, + + // 导入消费记录 + importConsumption: async (file: File) => { + const formData = new FormData() + formData.append('file', file) + return await request.upload({ url: `/prison/consumption/import`, data: formData }) } } diff --git a/src/api/prison/risk/index.ts b/src/api/prison/risk/index.ts index c8c03223..f29e46c1 100644 --- a/src/api/prison/risk/index.ts +++ b/src/api/prison/risk/index.ts @@ -119,5 +119,10 @@ export const RiskApi = { // 导出风险评估 Excel exportRisk: async (params) => { return await request.download({ url: `/prison/risk/export-excel`, params }) + }, + + // 获取导入模板 + getImportTemplate: async () => { + return await request.download({ url: `/prison/risk/get-import-template` }) } } diff --git a/src/api/prison/riskassessment/index.ts b/src/api/prison/riskassessment/index.ts index 1abfa0b1..a1bf2c47 100644 --- a/src/api/prison/riskassessment/index.ts +++ b/src/api/prison/riskassessment/index.ts @@ -72,5 +72,10 @@ export const RiskAssessmentApi = { // 导出危险评估 Excel exportRiskAssessment: async (params: RiskAssessmentPageParams) => { return await request.download({ url: `/prison/risk-assessment/export-excel`, params }) + }, + + // 获取导入模板 + getImportTemplate: async () => { + return await request.download({ url: `/prison/risk-assessment/get-import-template` }) } } \ No newline at end of file diff --git a/src/api/prison/score/index.ts b/src/api/prison/score/index.ts index 9dbd5b9e..63469541 100644 --- a/src/api/prison/score/index.ts +++ b/src/api/prison/score/index.ts @@ -74,5 +74,10 @@ export const ScoreApi = { // 导出计分考核 Excel exportScore: async (params: ScorePageParams) => { return await request.download({ url: `/prison/score/export-excel`, params }) + }, + + // 获取导入模板 + getImportTemplate: async () => { + return await request.download({ url: `/prison/score/get-import-template` }) } } \ No newline at end of file diff --git a/src/api/prison/situation/index.ts b/src/api/prison/situation/index.ts index 189e4533..95445208 100644 --- a/src/api/prison/situation/index.ts +++ b/src/api/prison/situation/index.ts @@ -114,6 +114,11 @@ export const SituationApi = { return await request.download({ url: `/prison/situation/export-excel`, params }) }, + // 获取导入模板 + getImportTemplate: async () => { + return await request.download({ url: `/prison/situation/get-import-template` }) + }, + // 导出 AreaApi 供页面使用 AreaApi } diff --git a/src/api/prison/warning/index.ts b/src/api/prison/warning/index.ts index 5e138017..35963bf0 100644 --- a/src/api/prison/warning/index.ts +++ b/src/api/prison/warning/index.ts @@ -169,6 +169,11 @@ export const WarningApi = { return await request.download({ url: `/prison/warning/export-excel`, params }) }, + // 获取导入模板 + getImportTemplate: async () => { + return await request.download({ url: `/prison/warning/get-import-template` }) + }, + // 导出 AreaApi 供页面使用 AreaApi } diff --git a/src/assets/imgs/avatar.png b/src/assets/imgs/avatar.png new file mode 100644 index 00000000..3dcdf1c0 Binary files /dev/null and b/src/assets/imgs/avatar.png differ diff --git a/src/components/ImportDialog/index.vue b/src/components/ImportDialog/index.vue new file mode 100644 index 00000000..2e112a08 --- /dev/null +++ b/src/components/ImportDialog/index.vue @@ -0,0 +1,163 @@ + + + diff --git a/src/config/axios/service.ts b/src/config/axios/service.ts index 27015102..75f6df0f 100644 --- a/src/config/axios/service.ts +++ b/src/config/axios/service.ts @@ -82,14 +82,18 @@ service.interceptors.request.use( const isFormUrlEncoded = contentType === 'application/x-www-form-urlencoded' || contentType.includes('application/x-www-form-urlencoded') + const isMultipartFormData = + contentType === 'multipart/form-data' || + contentType.includes('multipart/form-data') if (isFormUrlEncoded) { // 使用表单序列化 if (config.data && typeof config.data !== 'string') { config.data = qs.stringify(config.data, { allowDots: true, indices: false }) } - } else { + } else if (!isMultipartFormData) { // 默认使用 JSON 序列化,确保数组被正确序列化为 JSON 数组 // 这包括 'application/json' 以及其他情况 + // 注意:multipart/form-data 类型不进行转换,需要保持 FormData 对象原样 if (config.data && typeof config.data === 'object') { config.data = JSON.stringify(config.data) config.headers['Content-Type'] = 'application/json' diff --git a/src/locales/en.ts b/src/locales/en.ts index ace21ae6..700ec47d 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -113,8 +113,8 @@ export default { small: 'Small' }, login: { - welcome: 'Welcome to the system', - message: 'Backstage management system', + welcome: 'Welcome to AI Xinhang 360°', + message: 'Focusing on psychological needs of different individuals, building a full-process, intelligent one-stop psychological evaluation service platform, making psychological assessment more professional, efficient, and caring.', tenantname: 'TenantName', username: 'Username', password: 'Password', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index e3e7a118..e617cb95 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -114,8 +114,8 @@ export default { small: '小' }, login: { - welcome: '欢迎使用本系统', - message: '开箱即用的中后台管理系统', + welcome: '欢迎使用AI心航360°', + message: '聚焦不同人员心理需求,构建全流程、智能化的一站式心理测评服务平台,让心理评估更专业、更高效、更贴心。', tenantname: '租户名称', username: '用户名', password: '密码', @@ -470,4 +470,4 @@ export default { } }, 'OAuth 2.0': 'OAuth 2.0' // 避免菜单名是 OAuth 2.0 时,一直 warn 报错 -} \ No newline at end of file +} diff --git a/src/permission.ts b/src/permission.ts index a01a4f69..b087307f 100644 --- a/src/permission.ts +++ b/src/permission.ts @@ -55,18 +55,13 @@ const whiteList = [ '/register', '/oauthLogin/gitee', '/dashboard', // Dashboard 页面 - '/dashentry' // DashEntry 页面 + '/ai-dash-entry' // DashEntry 页面 ] // 路由加载前 router.beforeEach(async (to, from, next) => { start() loadStart() - // 如果是主页路径或 dashboard 路径,直接放行(跳过权限验证) - if (to.path === '/dashboard' || to.path === '/dashentry') { - next() - return - } if (getAccessToken()) { if (to.path === '/login') { next({ path: '/' }) @@ -100,6 +95,10 @@ router.beforeEach(async (to, from, next) => { } } else { if (whiteList.indexOf(to.path) !== -1) { + const permissionStore = usePermissionStoreWithOut() + if (permissionStore.getRouters.length === 0) { + await permissionStore.generateRoutes() + } next() } else { next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index e8c02437..f3eebca5 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -59,7 +59,7 @@ const remainingRouter: AppRouteRecordRaw[] = [ children: [ { path: 'index', - component: () => import('@/views/Home/Index.vue'), + component: () => import('@/views/DashEntry/DashEntry.vue'), name: 'Index', meta: { title: t('router.home'), @@ -186,16 +186,6 @@ const remainingRouter: AppRouteRecordRaw[] = [ } }, - { - path: '/dashentry', - component: () => import('@/views/DashEntry/DashEntry.vue'), - name: 'DashEntry', - meta: { - hidden: true, - title: 'DashEntry', - noTagsView: true - } - }, { path: '/login', component: () => import('@/views/Login/Login.vue'), diff --git a/src/views/DashEntry/DashEntry.vue b/src/views/DashEntry/DashEntry.vue index 2a6d71b5..0f3af436 100644 --- a/src/views/DashEntry/DashEntry.vue +++ b/src/views/DashEntry/DashEntry.vue @@ -42,7 +42,7 @@
重点关注对象列表
- +