AnCao/web/src/utils/request.ts
yanlongqi 3b7133d9de 添加论述题权限控制系统和AI评分功能
本次更新实现了基于用户类型的论述题访问权限控制,并为论述题添加了专门的AI评分功能。

后端更新:
- 添加论述题权限验证:根据用户类型(ordinary-person/management-person)控制不同论述题的访问权限
- 新增 GradeEssay 方法:为论述题提供专门的AI评分,不依赖标准答案,基于保密法规进行专业评分
- 优化AI评分提示词:增加法规依据要求,返回参考答案、评分依据等更详细的评分信息
- 添加用户类型管理:新增 UpdateUserType API,支持用户更新个人类型
- 路由调整:将练习题相关API移至需要认证的路由组

前端更新:
- 论述题答题界面优化:不显示标准答案,展示AI评分的参考答案和评分依据
- 用户类型选择:登录/注册时支持选择用户类型
- 权限控制适配:根据用户类型显示对应的论述题列表

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 16:47:37 +08:00

128 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
// 创建 axios 实例
const instance: AxiosInstance = axios.create({
baseURL: '/api', // 通过 Vite 代理转发到 Go 后端
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
})
// 请求拦截器
instance.interceptors.request.use(
(config) => {
// 可以在这里添加 token 等认证信息
const token = localStorage.getItem('token')
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => {
return Promise.reject(error)
}
)
// 响应拦截器
instance.interceptors.response.use(
(response: AxiosResponse) => {
return response.data
},
(error) => {
// 统一错误处理
if (error.response) {
switch (error.response.status) {
case 401:
// 未授权,清除本地存储并跳转到登录页
console.error('Token已过期或未授权请重新登录')
localStorage.removeItem('token')
localStorage.removeItem('user')
// 跳转到登录页
window.location.href = '/login'
break
case 403:
console.error('没有权限访问')
break
case 404:
console.error('请求的资源不存在')
break
case 500:
console.error('服务器错误')
break
default:
console.error('请求失败:', error.response.data)
}
} else {
console.error('网络错误:', error.message)
}
return Promise.reject(error)
}
)
// 封装请求方法
export const request = {
get: <T = any>(url: string, config?: AxiosRequestConfig): Promise<T> => {
return instance.get(url, config)
},
post: <T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> => {
return instance.post(url, data, config)
},
put: <T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> => {
return instance.put(url, data, config)
},
delete: <T = any>(url: string, config?: AxiosRequestConfig): Promise<T> => {
return instance.delete(url, config)
},
}
// 统一的 fetch 请求工具(用于需要原生 fetch 的场景,如流式请求)
interface FetchOptions extends RequestInit {
// 扩展选项(如果需要)
}
/**
* 统一封装的 fetch 请求方法
* 自动添加 Authorization header 和其他通用配置
*/
export const fetchWithAuth = async (
url: string,
options: FetchOptions = {}
): Promise<Response> => {
// 获取 token
const token = localStorage.getItem('token')
// 合并 headers
const headers: HeadersInit = {
'Content-Type': 'application/json',
...options.headers,
}
// 如果有 token添加到请求头
if (token) {
headers['Authorization'] = `Bearer ${token}`
}
// 构建完整的请求配置
const fetchOptions: RequestInit = {
...options,
headers,
}
// 发送请求
const response = await fetch(url, fetchOptions)
// 统一处理 401 未授权错误
if (response.status === 401) {
console.error('Token已过期或未授权请重新登录')
localStorage.removeItem('token')
localStorage.removeItem('user')
window.location.href = '/login'
throw new Error('未授权,请重新登录')
}
return response
}
export default instance