feat: build account dashboard and settings workspace

This commit is contained in:
2026-03-26 23:03:45 +08:00
parent be4bc8a3af
commit 8ee9a696b4
18 changed files with 2468 additions and 54 deletions

205
src/service/wk.ts Normal file
View File

@@ -0,0 +1,205 @@
import type { Accessor } from "solid-js";
import http from "~/service/http";
import type { CourseType } from "~/types/Course";
import type { userInfoType } from "~/types/Userinfo";
export type CourseKind = "run" | "finish" | "sign";
export type RecordType = "" | "/work" | "/exam" | "/discuss";
export type StudyStatus = 1 | 2 | 3;
type ApiResponse<T> = {
code: number;
message: string;
data: T;
};
export type LoginReq = {
username: string;
password: string;
token: string;
status: CourseKind;
host: string;
};
export type LoginData = {
courses: CourseType[];
session_id: string;
user: userInfoType;
};
export type LoginRes = ApiResponse<LoginData>;
export type RecordItem = {
id: string;
name: string;
type: string | null;
chapterId: string;
courseId: string;
videoFile: string;
videoDuration: string;
votingPath: string | null;
tabVideo: string;
tabFile: string;
tabVote: string;
tabWork: string;
tabExam: string;
sort: string;
videoMode: string;
localFile: string;
schoolId: string;
lock: string;
unlockTime: string;
bid: string;
duration: string;
progress: string;
state: string;
viewCount: string;
finalTime: string;
error: number;
errorMessage: string;
beginTime: string;
viewedDuration: string;
url: string;
};
export type PageInfo = {
keyName: string;
page: number;
pageCount: number;
recordsCount: number;
onlyCount: number;
pageSize: number;
};
export type RecordData = {
list: RecordItem[];
page_info: PageInfo;
};
export type RecordRes = ApiResponse<RecordData>;
export type StudyData = {
state: number;
studyId: number;
status: boolean;
msg: string;
};
export type StudyRes = ApiResponse<StudyData>;
export type LogoutRes = {
code: number;
message: string;
};
export type HostItem = {
host: string;
name: string;
};
export type HostRes = ApiResponse<{
list: HostItem[];
}>;
export type RecordReq = {
course_id: string;
page: number;
record_type?: RecordType;
};
export type StudyReq = {
node_id: string;
study_id: string;
study_time: string;
status: StudyStatus;
};
export type StudyRunnerItem = {
nodeId: string;
name: string;
currentTime: number;
totalTime: number;
progress: string;
completed: boolean;
};
export type StudyRunnerPayload = {
accountId: string;
courseId: number;
intervalSeconds: number;
items: StudyRunnerItem[];
isRunningStudy: Accessor<boolean>;
onLog?: (message: string) => void;
};
export const loginApi = async (payload: LoginReq) => {
const res = await http.post<LoginRes>("/api/login", payload);
if (res.data?.session_id) {
sessionStorage.setItem("session_id", res.data.session_id);
}
return res;
};
export const recordApi = async (payload: RecordReq) => {
return await http.post<RecordRes>("/api/v2/record", payload);
};
export const studyApi = async (payload: StudyReq) => {
return await http.post<StudyRes>("/api/v2/study", payload);
};
const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));
export const runStudyQueue = async (_payload: StudyRunnerPayload) => {
const stopFlag = _payload.isRunningStudy;
for (const item of _payload.items) {
let currentTime = 0;
let count = 0;
let study_id = 0;
while (currentTime <= item.totalTime) {
if (!stopFlag()) {
_payload.onLog?.("⛔ 已手动停止");
return;
}
const message = `[${item.name}]: ${currentTime}/${item.totalTime}`;
console.log(message);
_payload.onLog?.(message);
try {
const resp = await studyApi({
node_id: item.nodeId,
study_id: String(study_id),
study_time: String(currentTime),
status: count === 0 ? 1 : currentTime >= item.totalTime ? 3 : 2,
});
study_id = resp.data.studyId;
if (currentTime === item.totalTime) break;
currentTime = Math.min(currentTime + 5, item.totalTime);
count++;
} catch (error) {
const errorMessage = `请求失败: ${error instanceof Error ? error.message : String(error)}`;
console.log(errorMessage);
_payload.onLog?.(errorMessage);
}
await sleep(5000);
}
}
};
export const logoutApi = async () => {
const res = await http.post<LogoutRes>("/api/v2/logout");
sessionStorage.removeItem("session_id");
return res;
};
export const hostApi = async () => {
return await http.get<HostRes>("/api/v1/host");
};