|
|
// 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 += `¤tWeek=${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函数
|
|
|
}
|