You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

288 lines
6.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// API接口封装
// 基础配置
const BASE_URL = 'http://localhost:8080/api'
// 课程接口定义
interface Course {
id?: number;
courseName: string;
classroom: string;
teacherName?: string;
dayOfWeek: number;
startTime: string;
endTime: string;
notes?: string;
userOpenid?: string;
weeks?: string; // 周次信息,如 "1-16周"
timeSlot?: number; // 对应第几节课 (1-11)
startWeek?: number; // 开始周次
endWeek?: number; // 结束周次
weekType?: number; // 单双周标识0=每周1=单周2=双周)
}
// API响应接口
interface ApiResponse<T = any> {
code: number;
message: string;
data: T;
}
// OCR结果接口
interface OcrResult {
success: boolean;
rawText?: string;
textLines?: string[];
courses?: Course[];
errorMessage?: string;
}
// 导入结果接口
interface ImportResult {
successCourses: Course[];
errorMessages: string[];
}
// 通用请求函数
const request = <T = any>(options: {
url: string;
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
data?: any;
header?: any;
}): Promise<ApiResponse<T>> => {
return new Promise((resolve, reject) => {
wx.request({
url: `${BASE_URL}${options.url}`,
method: options.method || 'GET',
data: options.data,
header: {
'content-type': 'application/json',
...options.header
},
success: (res: any) => {
if (res.statusCode === 200) {
resolve(res.data)
} else {
reject(new Error(`HTTP ${res.statusCode}: ${res.data?.message || '请求失败'}`))
}
},
fail: (error) => {
reject(new Error(`网络错误: ${error.errMsg || '请求失败'}`))
}
})
})
}
// 文件上传函数
const uploadFile = (options: {
url: string;
filePath: string;
name: string;
formData?: any;
}): Promise<ApiResponse> => {
return new Promise((resolve, reject) => {
wx.uploadFile({
url: `${BASE_URL}${options.url}`,
filePath: options.filePath,
name: options.name,
formData: options.formData,
success: (res) => {
try {
const data = JSON.parse(res.data)
if (res.statusCode === 200) {
resolve(data)
} else {
reject(new Error(`HTTP ${res.statusCode}: ${data?.message || '上传失败'}`))
}
} catch (error) {
reject(new Error('响应数据解析失败'))
}
},
fail: (error) => {
reject(new Error(`上传失败: ${error.errMsg || '网络错误'}`))
}
})
})
}
// 课程管理API
export const courseApi = {
// 获取课程列表
getCourses: (userOpenid: string, dayOfWeek?: number, currentWeek?: number): Promise<ApiResponse<Course[]>> => {
let url = `/courses?userOpenid=${encodeURIComponent(userOpenid)}`;
if (dayOfWeek) {
url += `&dayOfWeek=${dayOfWeek}`;
}
if (currentWeek) {
url += `&currentWeek=${currentWeek}`;
}
return request<Course[]>({
url: url,
method: 'GET'
})
},
// 获取单个课程
getCourse: (id: number): Promise<ApiResponse<Course>> => {
return request<Course>({
url: `/courses/${id}`,
method: 'GET'
})
},
// 创建课程
createCourse: (course: Course): Promise<ApiResponse<Course>> => {
return request<Course>({
url: '/courses',
method: 'POST',
data: course
})
},
// 更新课程
updateCourse: (id: number, course: Course): Promise<ApiResponse<Course>> => {
return request<Course>({
url: `/courses/${id}`,
method: 'PUT',
data: course
})
},
// 删除课程
deleteCourse: (id: number): Promise<ApiResponse<void>> => {
return request<void>({
url: `/courses/${id}`,
method: 'DELETE'
})
},
// 清空所有课程
clearAllCourses: (userOpenid: string): Promise<ApiResponse<void>> => {
return request<void>({
url: `/courses/clear?userOpenid=${encodeURIComponent(userOpenid)}`,
method: 'DELETE'
})
}
}
// OCR识别API
export const ocrApi = {
// 上传图片进行OCR识别
uploadImage: (filePath: string, userOpenid: string): Promise<ApiResponse<OcrResult>> => {
return uploadFile({
url: '/ocr/upload',
filePath,
name: 'file',
formData: { userOpenid }
})
},
// 导入OCR识别的课程
importCourses: (courses: Course[], userOpenid: string): Promise<ApiResponse<ImportResult>> => {
return request<ImportResult>({
url: '/ocr/import',
method: 'POST',
data: { courses, userOpenid }
})
}
}
// 系统API
export const systemApi = {
// 健康检查
healthCheck: (): Promise<ApiResponse<any>> => {
return request({
url: '/health',
method: 'GET'
})
}
}
// OCR测试API开发阶段使用
export const ocrTestApi = {
// 测试OCR配置
testConfig: (): Promise<ApiResponse<any>> => {
return request({
url: '/ocr-test/config',
method: 'GET'
})
},
// 简单OCR测试
simpleTest: (imageUrl?: string): Promise<ApiResponse<any>> => {
return request({
url: '/ocr-test/simple',
method: 'POST',
data: imageUrl ? { imageUrl } : {}
})
},
// 获取OCR帮助信息
getHelp: (): Promise<ApiResponse<any>> => {
return request({
url: '/ocr-test/help',
method: 'GET'
})
}
}
// 错误处理工具
export const handleApiError = (error: any, defaultMessage: string = '操作失败') => {
console.error('API错误:', error)
let message = defaultMessage
if (error.message) {
message = error.message
} else if (typeof error === 'string') {
message = error
}
wx.showToast({
title: message,
icon: 'none',
duration: 2000
})
}
// API状态检查
export const checkApiStatus = async (): Promise<boolean> => {
try {
await systemApi.healthCheck()
return true
} catch (error) {
console.error('API服务不可用:', error)
return false
}
}
// 获取用户OpenID开发阶段使用固定ID
export const getUserOpenid = (): string => {
// 直接使用固定的用户ID避免清除缓存后数据丢失
const FIXED_USER_ID = 'my_fixed_user_003'
// 设置到本地存储(保持一致性)
wx.setStorageSync('userOpenid', FIXED_USER_ID)
console.log('使用固定用户ID:', FIXED_USER_ID)
return FIXED_USER_ID
}
// 重置用户ID为固定测试ID用于开发调试
export const resetUserOpenid = (): string => {
const FIXED_TEST_USER_ID = 'dev_test_user_003'
wx.setStorageSync('userOpenid', FIXED_TEST_USER_ID)
console.log('已重置为固定测试用户ID:', FIXED_TEST_USER_ID)
return FIXED_TEST_USER_ID
}
// 导出所有API
export default {
course: courseApi,
ocr: ocrApi,
system: systemApi,
ocrTest: ocrTestApi,
handleError: handleApiError,
checkStatus: checkApiStatus,
getUserOpenid // 固定用户ID函数
}