82 lines
3.1 KiB
TypeScript
82 lines
3.1 KiB
TypeScript
import { WORKS_SQUARE_CONFIG } from '../api/works-config';
|
|
import { proxyAwareFetch } from '../utils/proxy-fetch';
|
|
import {
|
|
getValidWorksSquareAccessToken,
|
|
getWorksSquareAccountBinding,
|
|
isCurrentWorksSquareAccountBinding,
|
|
type WorksSquareAccountBinding,
|
|
} from '../services/works-square-session';
|
|
import type { TeacherAvailability, TeacherDefinition } from '../../shared/coding-teacher';
|
|
|
|
export class TeacherError extends Error {
|
|
constructor(
|
|
public status: number,
|
|
public code: string,
|
|
message: string
|
|
) {
|
|
super(message);
|
|
}
|
|
}
|
|
export interface TeacherAccount {
|
|
id: string;
|
|
binding: WorksSquareAccountBinding;
|
|
}
|
|
export function assertTeacherAccount(account: TeacherAccount) {
|
|
if (!isCurrentWorksSquareAccountBinding(account.binding))
|
|
throw new TeacherError(401, 'teacher_account_changed', '登录账号已变化,请重新打开老师。');
|
|
}
|
|
export async function teacherCloudRequest<T>(
|
|
account: TeacherAccount,
|
|
pathname: string
|
|
): Promise<T> {
|
|
assertTeacherAccount(account);
|
|
const token = await getValidWorksSquareAccessToken();
|
|
assertTeacherAccount(account);
|
|
if (!token) throw new TeacherError(401, 'teacher_auth_required', '请先登录。');
|
|
const response = await proxyAwareFetch(
|
|
WORKS_SQUARE_CONFIG.apiBaseUrl.replace(/\/+$/, '') + pathname,
|
|
{
|
|
headers: { Authorization: 'Bearer ' + token },
|
|
signal: AbortSignal.timeout(30000),
|
|
}
|
|
);
|
|
assertTeacherAccount(account);
|
|
if (!response.ok) {
|
|
const code =
|
|
response.status === 403
|
|
? 'teacher_access_denied'
|
|
: response.status === 409
|
|
? 'teacher_draft_changed'
|
|
: 'teacher_config_unavailable';
|
|
const message =
|
|
response.status === 403
|
|
? '当前账号没有使用权限。'
|
|
: response.status === 409
|
|
? '草稿已变化,请在运营页面重新打开试聊。'
|
|
: '老师配置暂不可用,请稍后重试。';
|
|
throw new TeacherError(response.status, code, message);
|
|
}
|
|
return (await response.json()) as T;
|
|
}
|
|
export async function currentTeacherAccount(): Promise<TeacherAccount> {
|
|
const binding = getWorksSquareAccountBinding();
|
|
if (!binding) throw new TeacherError(401, 'teacher_auth_required', '请先登录。');
|
|
const provisional = { id: '', binding };
|
|
const profile = await teacherCloudRequest<{ id: string }>(provisional, '/api/auth/me');
|
|
if (!/^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i.test(profile.id))
|
|
throw new TeacherError(502, 'teacher_account_unavailable', '无法确认当前账号。');
|
|
return { id: profile.id, binding };
|
|
}
|
|
export const teacherAvailability = (account: TeacherAccount) =>
|
|
teacherCloudRequest<TeacherAvailability>(account, '/api/coding-teacher/config');
|
|
export const teacherVersion = (account: TeacherAccount, version: number) =>
|
|
teacherCloudRequest<{ version: number; payload: TeacherDefinition }>(
|
|
account,
|
|
'/api/coding-teacher/versions/' + version
|
|
);
|
|
export const teacherPreview = (account: TeacherAccount, revision: number) =>
|
|
teacherCloudRequest<{ draft_revision: number; payload: TeacherDefinition }>(
|
|
account,
|
|
'/api/admin/coding-teacher/preview?draft_revision=' + revision
|
|
);
|