705 lines
18 KiB
TypeScript
705 lines
18 KiB
TypeScript
import request from '@/utils/request'
|
||
import aiService from '@/utils/aiRequest'
|
||
import type { ApiResult } from '@/api/auth'
|
||
import type { AiResult } from '@/utils/aiRequest'
|
||
|
||
// ==================== 简历列表相关 ====================
|
||
|
||
/** 时间戳结构(Instant) */
|
||
export interface InstantTime {
|
||
/** 秒级时间戳 */
|
||
seconds?: number
|
||
/** 纳秒部分 */
|
||
nanos?: number
|
||
}
|
||
|
||
/** 简历列表项 */
|
||
export interface ResumeListItem {
|
||
/** 简历 ID(字符串,避免大整数精度丢失) */
|
||
id?: string
|
||
/** 简历名称 */
|
||
resumeName?: string
|
||
/** 目标岗位 */
|
||
targetPosition?: string
|
||
/** 是否默认简历 0=否 1=是 */
|
||
isDefault?: number
|
||
/** 简历修改时间(毫秒时间戳) */
|
||
updateTime?: number
|
||
/** 简历创建时间(毫秒时间戳) */
|
||
createTime?: number
|
||
}
|
||
|
||
/**
|
||
* 获取简历列表
|
||
* GET /resume/list
|
||
*/
|
||
export function fetchResumeList() {
|
||
return request.get<any, ApiResult<ResumeListItem[]>>('/resume/list')
|
||
}
|
||
|
||
// ==================== 描述段落(通用) ====================
|
||
|
||
/** 描述段落 */
|
||
export interface DescriptionParagraph {
|
||
/** 段落标识,前端生成的短ID */
|
||
id?: string
|
||
/** 段落文本内容 */
|
||
text?: string
|
||
}
|
||
|
||
// ==================== 简历主表 ====================
|
||
|
||
/** 简历主表数据 */
|
||
export interface ResumeMainData {
|
||
/** 简历 ID(字符串,避免大整数精度丢失) */
|
||
id?: string
|
||
/** 简历名称 */
|
||
resumeName?: string
|
||
/** 目标岗位 */
|
||
targetPosition?: string
|
||
/** 是否默认简历 0=否 1=是 */
|
||
isDefault?: number
|
||
/** 头像URL */
|
||
avatarUrl?: string
|
||
/** 真实姓名 */
|
||
name?: string
|
||
/** 邮箱 */
|
||
email?: string
|
||
/** 手机号码 */
|
||
mobileNumber?: string
|
||
/** 所在城市 */
|
||
city?: string
|
||
/** 微信号 */
|
||
wechatNumber?: string
|
||
/** 作品集链接 */
|
||
portfolioUrl?: string
|
||
/** 技能标签列表 */
|
||
skills?: string[]
|
||
/** 证书标签列表 */
|
||
certificates?: string[]
|
||
/** 个人概述 */
|
||
summary?: string
|
||
}
|
||
|
||
/**
|
||
* 查询简历主表
|
||
* GET /resume?resumeId=xxx
|
||
*/
|
||
export function fetchResumeMain(resumeId: string) {
|
||
return request.get<any, ApiResult<ResumeMainData>>('/resume', {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
// ==================== 教育经历 ====================
|
||
|
||
/** 教育经历项 */
|
||
export interface ResumeEducation {
|
||
/** ID(字符串,避免大整数精度丢失) */
|
||
id?: string
|
||
/** 学校名称 */
|
||
school?: string
|
||
/** 专业 */
|
||
major?: string
|
||
/** 学历:大专/本科/硕士/博士 */
|
||
degree?: string
|
||
/** 学习形式:全日制/非全日制 */
|
||
studyType?: string
|
||
/** 开始时间,格式:2023.09 */
|
||
startDate?: string
|
||
/** 结束时间,格式:2024.06 */
|
||
endDate?: string
|
||
/** 描述段落 */
|
||
description?: DescriptionParagraph[]
|
||
}
|
||
|
||
/**
|
||
* 查询简历的教育经历列表
|
||
* GET /resume/education?resumeId=xxx
|
||
*/
|
||
export function fetchResumeEducation(resumeId: string) {
|
||
return request.get<any, ApiResult<ResumeEducation[]>>('/resume/education', {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
// ==================== 工作经历 ====================
|
||
|
||
/** 工作经历项 */
|
||
export interface ResumeWork {
|
||
/** ID(字符串,避免大整数精度丢失) */
|
||
id?: string
|
||
/** 公司名称 */
|
||
companyName?: string
|
||
/** 职位 */
|
||
position?: string
|
||
/** 开始时间 */
|
||
startDate?: string
|
||
/** 结束时间 */
|
||
endDate?: string
|
||
/** 描述段落 */
|
||
description?: DescriptionParagraph[]
|
||
}
|
||
|
||
/**
|
||
* 查询简历的工作经历列表
|
||
* GET /resume/work?resumeId=xxx
|
||
*/
|
||
export function fetchResumeWork(resumeId: string) {
|
||
return request.get<any, ApiResult<ResumeWork[]>>('/resume/work', {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
// ==================== 实习经历 ====================
|
||
|
||
/** 实习经历项 */
|
||
export interface ResumeInternship {
|
||
/** ID(字符串,避免大整数精度丢失) */
|
||
id?: string
|
||
/** 公司名称 */
|
||
companyName?: string
|
||
/** 职位 */
|
||
position?: string
|
||
/** 开始时间 */
|
||
startDate?: string
|
||
/** 结束时间 */
|
||
endDate?: string
|
||
/** 描述段落 */
|
||
description?: DescriptionParagraph[]
|
||
}
|
||
|
||
/**
|
||
* 查询简历的实习经历列表
|
||
* GET /resume/internship?resumeId=xxx
|
||
*/
|
||
export function fetchResumeInternship(resumeId: string) {
|
||
return request.get<any, ApiResult<ResumeInternship[]>>('/resume/internship', {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
// ==================== 项目经历 ====================
|
||
|
||
/** 项目经历项 */
|
||
export interface ResumeProject {
|
||
/** ID(字符串,避免大整数精度丢失) */
|
||
id?: string
|
||
/** 所属公司 */
|
||
companyName?: string
|
||
/** 项目名称 */
|
||
projectName?: string
|
||
/** 担任角色 */
|
||
role?: string
|
||
/** 开始时间 */
|
||
startDate?: string
|
||
/** 结束时间 */
|
||
endDate?: string
|
||
/** 描述段落 */
|
||
description?: DescriptionParagraph[]
|
||
}
|
||
|
||
/**
|
||
* 查询简历的项目经历列表
|
||
* GET /resume/project?resumeId=xxx
|
||
*/
|
||
export function fetchResumeProject(resumeId: string) {
|
||
return request.get<any, ApiResult<ResumeProject[]>>('/resume/project', {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
// ==================== 竞赛经历 ====================
|
||
|
||
/** 竞赛经历项 */
|
||
export interface ResumeCompetition {
|
||
/** ID(字符串,避免大整数精度丢失) */
|
||
id?: string
|
||
/** 竞赛名称 */
|
||
competitionName?: string
|
||
/** 获奖情况 */
|
||
award?: string
|
||
/** 获奖时间,格式:2023.07 */
|
||
awardDate?: string
|
||
/** 描述段落 */
|
||
description?: DescriptionParagraph[]
|
||
}
|
||
|
||
/**
|
||
* 查询简历的竞赛经历列表
|
||
* GET /resume/competition?resumeId=xxx
|
||
*/
|
||
export function fetchResumeCompetition(resumeId: string) {
|
||
return request.get<any, ApiResult<ResumeCompetition[]>>('/resume/competition', {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
// ==================== 简历保存相关 ====================
|
||
|
||
/** 保存简历主表参数 */
|
||
export interface SaveResumeMainParams {
|
||
/** 简历 ID */
|
||
resumeId: string
|
||
/** 简历名称 */
|
||
resumeName?: string
|
||
/** 目标岗位 */
|
||
targetPosition?: string
|
||
/** 真实姓名 */
|
||
name?: string
|
||
/** 邮箱 */
|
||
email?: string
|
||
/** 手机号码 */
|
||
mobileNumber?: string
|
||
/** 所在城市 */
|
||
city?: string
|
||
/** 微信号 */
|
||
wechatNumber?: string
|
||
/** 作品集链接 */
|
||
portfolioUrl?: string
|
||
/** 技能标签列表 */
|
||
skills?: string[]
|
||
/** 证书标签列表 */
|
||
certificates?: string[]
|
||
/** 个人概述 */
|
||
summary?: string
|
||
}
|
||
|
||
/**
|
||
* 保存/更新简历主表信息
|
||
* POST /resume
|
||
*/
|
||
export function saveResumeMain(data: SaveResumeMainParams) {
|
||
return request.post<any, ApiResult>('/resume', data)
|
||
}
|
||
|
||
/** 保存简历教育经历参数(单条) */
|
||
export interface SaveResumeEducationItem {
|
||
/** 记录ID(编辑时必传) */
|
||
id?: string | number
|
||
/** 学校名称 */
|
||
school?: string
|
||
/** 专业 */
|
||
major?: string
|
||
/** 学历 */
|
||
degree?: string
|
||
/** 学习形式 */
|
||
studyType?: string
|
||
/** 开始时间 */
|
||
startDate?: string
|
||
/** 结束时间 */
|
||
endDate?: string
|
||
/** 描述段落 */
|
||
description?: DescriptionParagraph[]
|
||
}
|
||
|
||
/**
|
||
* 保存简历教育经历(全量覆盖)— 旧接口,保留兼容
|
||
* POST /resume/education
|
||
*/
|
||
export function saveResumeEducation(resumeId: string, data: SaveResumeEducationItem[]) {
|
||
return request.post<any, ApiResult>('/resume/education', { resumeId, items: data })
|
||
}
|
||
|
||
/**
|
||
* 添加单条教育经历,返回新记录ID
|
||
* POST /resume/education/add
|
||
*/
|
||
export function addResumeEducation(resumeId: string, data: SaveResumeEducationItem) {
|
||
return request.post<any, ApiResult<string>>('/resume/education/add', data, {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 根据ID编辑单条教育经历
|
||
* POST /resume/education/update
|
||
*/
|
||
export function updateResumeEducation(data: SaveResumeEducationItem) {
|
||
return request.post<any, ApiResult>('/resume/education/update', data)
|
||
}
|
||
|
||
/**
|
||
* 根据ID删除单条教育经历
|
||
* POST /resume/education/delete
|
||
*/
|
||
export function deleteResumeEducation(id: string) {
|
||
return request.post<any, ApiResult>('/resume/education/delete', null, {
|
||
params: { id },
|
||
})
|
||
}
|
||
|
||
/** 保存简历工作经历参数(单条) */
|
||
export interface SaveResumeWorkItem {
|
||
/** 记录ID(编辑时必传) */
|
||
id?: string | number
|
||
/** 公司名称 */
|
||
companyName?: string
|
||
/** 职位 */
|
||
position?: string
|
||
/** 开始时间 */
|
||
startDate?: string
|
||
/** 结束时间 */
|
||
endDate?: string
|
||
/** 描述段落 */
|
||
description?: DescriptionParagraph[]
|
||
}
|
||
|
||
/**
|
||
* 保存简历工作经历(全量覆盖)— 旧接口,保留兼容
|
||
* POST /resume/work
|
||
*/
|
||
export function saveResumeWork(resumeId: string, data: SaveResumeWorkItem[]) {
|
||
return request.post<any, ApiResult>('/resume/work', { resumeId, items: data })
|
||
}
|
||
|
||
/**
|
||
* 添加单条工作经历,返回新记录ID
|
||
* POST /resume/work/add
|
||
*/
|
||
export function addResumeWork(resumeId: string, data: SaveResumeWorkItem) {
|
||
return request.post<any, ApiResult<string>>('/resume/work/add', data, {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 根据ID编辑单条工作经历
|
||
* POST /resume/work/update
|
||
*/
|
||
export function updateResumeWork(data: SaveResumeWorkItem) {
|
||
return request.post<any, ApiResult>('/resume/work/update', data)
|
||
}
|
||
|
||
/**
|
||
* 根据ID删除单条工作经历
|
||
* POST /resume/work/delete
|
||
*/
|
||
export function deleteResumeWork(id: string) {
|
||
return request.post<any, ApiResult>('/resume/work/delete', null, {
|
||
params: { id },
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 保存简历实习经历(全量覆盖)— 旧接口,保留兼容
|
||
* POST /resume/internship
|
||
*/
|
||
export function saveResumeInternship(resumeId: string, data: SaveResumeWorkItem[]) {
|
||
return request.post<any, ApiResult>('/resume/internship', { resumeId, items: data })
|
||
}
|
||
|
||
/**
|
||
* 添加单条实习经历,返回新记录ID
|
||
* POST /resume/internship/add
|
||
*/
|
||
export function addResumeInternship(resumeId: string, data: SaveResumeWorkItem) {
|
||
return request.post<any, ApiResult<string>>('/resume/internship/add', data, {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 根据ID编辑单条实习经历
|
||
* POST /resume/internship/update
|
||
*/
|
||
export function updateResumeInternship(data: SaveResumeWorkItem) {
|
||
return request.post<any, ApiResult>('/resume/internship/update', data)
|
||
}
|
||
|
||
/**
|
||
* 根据ID删除单条实习经历
|
||
* POST /resume/internship/delete
|
||
*/
|
||
export function deleteResumeInternship(id: string) {
|
||
return request.post<any, ApiResult>('/resume/internship/delete', null, {
|
||
params: { id },
|
||
})
|
||
}
|
||
|
||
/** 保存简历项目经历参数(单条) */
|
||
export interface SaveResumeProjectItem {
|
||
/** 记录ID(编辑时必传) */
|
||
id?: string | number
|
||
/** 项目名称 */
|
||
projectName?: string
|
||
/** 所属公司 */
|
||
companyName?: string
|
||
/** 担任角色 */
|
||
role?: string
|
||
/** 开始时间 */
|
||
startDate?: string
|
||
/** 结束时间 */
|
||
endDate?: string
|
||
/** 描述段落 */
|
||
description?: DescriptionParagraph[]
|
||
}
|
||
|
||
/**
|
||
* 保存简历项目经历(全量覆盖)— 旧接口,保留兼容
|
||
* POST /resume/project
|
||
*/
|
||
export function saveResumeProject(resumeId: string, data: SaveResumeProjectItem[]) {
|
||
return request.post<any, ApiResult>('/resume/project', { resumeId, items: data })
|
||
}
|
||
|
||
/**
|
||
* 添加单条项目经历,返回新记录ID
|
||
* POST /resume/project/add
|
||
*/
|
||
export function addResumeProject(resumeId: string, data: SaveResumeProjectItem) {
|
||
return request.post<any, ApiResult<string>>('/resume/project/add', data, {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 根据ID编辑单条项目经历
|
||
* POST /resume/project/update
|
||
*/
|
||
export function updateResumeProject(data: SaveResumeProjectItem) {
|
||
return request.post<any, ApiResult>('/resume/project/update', data)
|
||
}
|
||
|
||
/**
|
||
* 根据ID删除单条项目经历
|
||
* POST /resume/project/delete
|
||
*/
|
||
export function deleteResumeProject(id: string) {
|
||
return request.post<any, ApiResult>('/resume/project/delete', null, {
|
||
params: { id },
|
||
})
|
||
}
|
||
|
||
/** 保存简历竞赛经历参数(单条) */
|
||
export interface SaveResumeCompetitionItem {
|
||
/** 记录ID(编辑时必传) */
|
||
id?: string | number
|
||
/** 竞赛名称 */
|
||
competitionName?: string
|
||
/** 获奖情况 */
|
||
award?: string
|
||
/** 获奖时间 */
|
||
awardDate?: string
|
||
/** 描述段落 */
|
||
description?: DescriptionParagraph[]
|
||
}
|
||
|
||
/**
|
||
* 保存简历竞赛经历(全量覆盖)— 旧接口,保留兼容
|
||
* POST /resume/competition
|
||
*/
|
||
export function saveResumeCompetition(resumeId: string, data: SaveResumeCompetitionItem[]) {
|
||
return request.post<any, ApiResult>('/resume/competition', { resumeId, items: data })
|
||
}
|
||
|
||
/**
|
||
* 添加单条竞赛经历,返回新记录ID
|
||
* POST /resume/competition/add
|
||
*/
|
||
export function addResumeCompetition(resumeId: string, data: SaveResumeCompetitionItem) {
|
||
return request.post<any, ApiResult<string>>('/resume/competition/add', data, {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 根据ID编辑单条竞赛经历
|
||
* POST /resume/competition/update
|
||
*/
|
||
export function updateResumeCompetition(data: SaveResumeCompetitionItem) {
|
||
return request.post<any, ApiResult>('/resume/competition/update', data)
|
||
}
|
||
|
||
/**
|
||
* 根据ID删除单条竞赛经历
|
||
* POST /resume/competition/delete
|
||
*/
|
||
export function deleteResumeCompetition(id: string) {
|
||
return request.post<any, ApiResult>('/resume/competition/delete', null, {
|
||
params: { id },
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 删除简历
|
||
* POST /resume/delete
|
||
*/
|
||
export function deleteResume(resumeId: string) {
|
||
return request.post<any, ApiResult>('/resume/delete', null, {
|
||
params: { resumeId },
|
||
})
|
||
}
|
||
|
||
// ==================== 简历诊断相关 ====================
|
||
|
||
/** 诊断报告数据 */
|
||
export interface DiagnosisReport {
|
||
/** 报告 ID */
|
||
id?: string
|
||
/** 简历 ID */
|
||
resumeId?: string
|
||
/** 评级 A/B/C/D */
|
||
grade?: string
|
||
/** AI 整体评价 */
|
||
summary?: string
|
||
/** 紧急修复总数 */
|
||
urgentTotal?: number
|
||
/** 重点优化总数 */
|
||
importantTotal?: number
|
||
/** 表达提升总数 */
|
||
expressionTotal?: number
|
||
/** 创建时间 */
|
||
createTime?: string
|
||
}
|
||
|
||
/** 诊断问题子类型计数 */
|
||
export interface IssueSubCounts {
|
||
[key: string]: number
|
||
}
|
||
|
||
/** 诊断问题项 */
|
||
export interface DiagnosisIssue {
|
||
/** 问题 ID */
|
||
id?: string
|
||
/** 模块类型: summary/education/work/internship/project/competition */
|
||
moduleType?: string
|
||
/** 模块记录 ID,summary 时为 resume_id */
|
||
moduleRecordId?: string
|
||
/** 诊断发现 */
|
||
finding?: string
|
||
/** 为什么重要 */
|
||
importance?: string
|
||
/** 改进建议 */
|
||
suggestion?: string
|
||
/** 紧急修复子类型计数 */
|
||
urgentIssues?: IssueSubCounts
|
||
/** 重点优化子类型计数 */
|
||
importantIssues?: IssueSubCounts
|
||
/** 表达提升子类型计数 */
|
||
expressionIssues?: IssueSubCounts
|
||
/** AI 改写后的内容 */
|
||
optimizedContent?: any
|
||
/** 0=待处理 1=已处理 */
|
||
status?: number
|
||
/** 0=未评价 1=符合 2=不符合 */
|
||
userFeedback?: number
|
||
}
|
||
|
||
/** 诊断接口返回的 data 结构 */
|
||
export interface DiagnosisData {
|
||
/** 诊断报告 */
|
||
report: DiagnosisReport
|
||
/** 诊断问题列表 */
|
||
issues: DiagnosisIssue[]
|
||
}
|
||
|
||
/**
|
||
* 查询简历诊断报告(AI 接口)
|
||
* GET /resume/diagnose/{resume_id}
|
||
*/
|
||
export function fetchResumeDiagnosis(resumeId: string) {
|
||
return aiService.get<AiResult<DiagnosisData | null>>(`/resume/diagnose/${resumeId}`, {
|
||
transformResponse: [(data: string) => {
|
||
try {
|
||
// 大整数安全解析
|
||
const processed = data.replace(/:\s*(\d{16,})/g, ':"$1"')
|
||
return JSON.parse(processed)
|
||
} catch {
|
||
return data
|
||
}
|
||
}],
|
||
}).then(res => res.data)
|
||
}
|
||
|
||
/** 触发诊断返回的 data 结构 */
|
||
export interface TriggerDiagnosisData {
|
||
/** 诊断报告 ID */
|
||
reportId?: string
|
||
}
|
||
|
||
/**
|
||
* 触发简历诊断(AI 接口)
|
||
* POST /resume/diagnose
|
||
*/
|
||
export function triggerResumeDiagnosis(resumeId: string) {
|
||
return aiService.post<AiResult<TriggerDiagnosisData>>('/resume/diagnose', { resumeId }, {
|
||
transformResponse: [(data: string) => {
|
||
try {
|
||
const processed = data.replace(/:\s*(\d{16,})/g, ':"$1"')
|
||
return JSON.parse(processed)
|
||
} catch {
|
||
return data
|
||
}
|
||
}],
|
||
}).then(res => res.data)
|
||
}
|
||
|
||
// ==================== 问题润色(AI 优化用户改写内容) ====================
|
||
|
||
/** 润色接口返回的 data 结构 */
|
||
export interface PolishIssueData {
|
||
/** AI 润色后的文本段落数组 */
|
||
content: string[]
|
||
}
|
||
|
||
/**
|
||
* 对诊断问题进行 AI 润色(AI 接口)
|
||
* POST /resume/diagnose/issue/{issue_id}/polish
|
||
* @param issueId 问题 ID
|
||
* @param content 用户编辑后的文本段落数组
|
||
*/
|
||
export function polishDiagnosisIssue(issueId: string, content: string[]) {
|
||
return aiService.post<AiResult<PolishIssueData>>(`/resume/diagnose/issue/${issueId}/polish`, { content }, {
|
||
transformResponse: [(data: string) => {
|
||
try {
|
||
const processed = data.replace(/:\s*(\d{16,})/g, ':"$1"')
|
||
return JSON.parse(processed)
|
||
} catch {
|
||
return data
|
||
}
|
||
}],
|
||
}).then(res => res.data)
|
||
}
|
||
|
||
// ==================== 问题用户评价 ====================
|
||
|
||
/**
|
||
* 提交诊断问题的用户评价(AI 接口)
|
||
* PUT /resume/diagnose/issue/{issue_id}/feedback
|
||
* @param issueId 问题 ID
|
||
* @param userFeedback 1=符合(有用) 2=不符合(无用)
|
||
*/
|
||
export function feedbackDiagnosisIssue(issueId: string, userFeedback: number) {
|
||
return aiService.put<AiResult<null>>(`/resume/diagnose/issue/${issueId}/feedback`, { userFeedback }, {
|
||
transformResponse: [(data: string) => {
|
||
try {
|
||
const processed = data.replace(/:\s*(\d{16,})/g, ':"$1"')
|
||
return JSON.parse(processed)
|
||
} catch {
|
||
return data
|
||
}
|
||
}],
|
||
}).then(res => res.data)
|
||
}
|
||
|
||
// ==================== 标记问题已处理 ====================
|
||
|
||
/**
|
||
* 标记诊断问题为已处理(AI 接口)
|
||
* PUT /resume/diagnose/issue/{issue_id}/resolve
|
||
* @param issueId 问题 ID
|
||
*/
|
||
export function resolveDiagnosisIssue(issueId: string) {
|
||
return aiService.put<AiResult<null>>(`/resume/diagnose/issue/${issueId}/resolve`, null, {
|
||
transformResponse: [(data: string) => {
|
||
try {
|
||
const processed = data.replace(/:\s*(\d{16,})/g, ':"$1"')
|
||
return JSON.parse(processed)
|
||
} catch {
|
||
return data
|
||
}
|
||
}],
|
||
}).then(res => res.data)
|
||
}
|