feat(growth): 实现学生画像功能并下线推荐内容

- 替换学生画像页面占位符,新增简历式头部展示
- 集成雷达图展示能力维度评分
- 增加学分类别达成和成长轨迹时间线展示
- 管理端支持学生检索与切换查看画像
- 接口调用区分纯学生角色权限限制
- 删除推荐内容相关前端页面及菜单配置
- 更新文档说明学生画像功能与推荐内容下线情况
- 细节优化标题本地化判断逻辑及状态类型声明
This commit is contained in:
2026-11-07 10:28:08 +08:00
parent d8e7e2a2a8
commit 6236c7f723
9 changed files with 871 additions and 97 deletions
+82
View File
@@ -0,0 +1,82 @@
import request from '@/utils/request';
import type { ApiResult } from '@/api';
import { MODULES_API_URL } from '@/config/setting';
import type { GrowthHome } from '@/api/growth/home';
/** 画像维度 */
export interface PortraitDimension {
key: string;
name: string;
score: number;
desc?: string;
}
/** 成长轨迹节点 */
export interface PortraitTimelineItem {
type: string;
typeName: string;
title: string;
time: string;
extra?: string;
}
/** 学生画像 */
export interface StudentPortrait {
basic?: GrowthHome['basic'];
dimensions?: PortraitDimension[];
tags?: string[];
summary?: string;
credit?: GrowthHome['credit'];
volunteer?: Record<string, any>;
activity?: Record<string, any>;
practice?: Record<string, any>;
qmgc?: Record<string, any> | null;
timeline?: PortraitTimelineItem[];
updateTime?: string;
}
/** 画像可选学生 */
export interface PortraitStudentOption {
userId: number;
name?: string;
studentNo?: string;
collegeName?: string;
className?: string;
major?: string;
grade?: string;
}
/** 我的画像 */
export async function getMyPortrait() {
const res = await request.get<ApiResult<StudentPortrait>>(
MODULES_API_URL + '/gxmu/portrait/my'
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/** 指定学生的画像 */
export async function getStudentPortrait(userId: number) {
const res = await request.get<ApiResult<StudentPortrait>>(
MODULES_API_URL + '/gxmu/portrait',
{ params: { userId } }
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/** 检索可查看画像的学生 */
export async function searchPortraitStudents(keyword?: string) {
const res = await request.get<ApiResult<PortraitStudentOption[]>>(
MODULES_API_URL + '/gxmu/portrait/student/search',
{ params: { keyword } }
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}