刘光辉
12 小时以前 0dfe84494048ce27ba8449831782128412d3eb13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import type { FillDataResponse, FillFieldData, FillFieldType } from '../domain/types';
 
const FIELD_TYPES = new Set<FillFieldType>(['text', 'multiline', 'select', 'checkbox', 'date']);
 
export class FillDataError extends Error {
  constructor(message: string, public readonly status?: number) {
    super(message);
    this.name = 'FillDataError';
  }
}
 
function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}
 
export function parseFillData(raw: unknown): FillDataResponse {
  if (!isRecord(raw) || !isRecord(raw.fields)) throw new Error('填写数据格式无效');
  const fields: Record<string, FillFieldData> = {};
  for (const [tag, value] of Object.entries(raw.fields)) {
    if (!tag || !isRecord(value) || !FIELD_TYPES.has(value.type as FillFieldType)) throw new Error('填写数据格式无效');
    const type = value.type as FillFieldType;
    if (type === 'checkbox') {
      if (value.value !== null && typeof value.value !== 'boolean') throw new Error('填写数据格式无效');
      fields[tag] = { type, value: value.value ?? false };
    } else {
      if (value.value !== null && typeof value.value !== 'string') throw new Error('填写数据格式无效');
      fields[tag] = { type, value: value.value as null | string };
    }
  }
  return { fields };
}
 
function messageFor(status: number): string {
  if (status === 401) return '填写凭证已过期,请重新打开文档';
  if (status === 403) return '无权读取填写数据';
  if (status === 404) return '填写数据不存在';
  return '填写数据加载失败';
}
 
export async function fetchFillData(context: { apiBaseUrl: string; ticket: string }): Promise<FillDataResponse> {
  let response: Response;
  try {
    response = await fetch(`${context.apiBaseUrl}/api/eln/onlyoffice/template-fill/data`, {
      headers: { Authorization: `Ticket ${context.ticket}` },
    });
  } catch {
    throw new FillDataError('填写数据加载失败');
  }
  if (!response.ok) throw new FillDataError(messageFor(response.status), response.status);
  try {
    return parseFillData(await response.json());
  } catch (error) {
    if (error instanceof FillDataError) throw error;
    throw new FillDataError('填写数据格式无效');
  }
}