import {HttpUtils, removeHTML, randNumber} from "../utils/utils";
import {SystemConfig} from "@App/config";
import {Application} from "../application";
export interface Topic {
topic: string
type: TopicType
id?: string
}
export interface Option {
option: any
content: any
}
export interface Answer {
index: number
topic: string
type: TopicType
status: TopicStatus
answers?: Option[]
correct: Option[]
id?: string
Equal(content1: string, content2: string): boolean
}
export class PushAnswer implements Answer {
public index: number;
public topic: string;
public type: TopicType;
public status: TopicStatus;
public answers: Option[];
public correct: Option[];
public Equal(content1: string, content2: string): boolean {
return content1 == content2;
}
}
export interface Options {
Random(): TopicStatus;
Fill(s: Answer): TopicStatus;
Correct(): Answer
}
export interface Question extends Options {
GetType(): TopicType;
GetTopic(): string;
SetStatus(status: TopicStatus): void;
}
//-1-一个错误 1-单选 2-多选 3-判断 4-填空
export type TopicType = -1 | 1 | 2 | 3 | 4;
export type FillType = 1;
// 1随机答案 2不支持的随机答案类型 3无答案 4无符合答案
export type TopicStatus = "ok" | "random" | "no_support_random" | "no_answer" | "no_match";
let topicStatusMap = new Map();
topicStatusMap.set("ok", "搜索成功").set("random", "随机答案").set("no_support_random", "不支持的随机答案类型").set("no_answer", "题库中没有搜索到答案").set("no_match", "题库中没有符合的答案");
let questionStatusMap = new Map();
questionStatusMap.set("success", "搜索成功").set("network", "题库网络错误").set("incomplete", "题库不全").set("processing", "搜索中...");
export function TopicStatusString(status: TopicStatus): string {
return topicStatusMap.get(status) || "未知错误";
}
export function QuestionStatusString(status: QuestionStatus): string {
return questionStatusMap.get(status) || "未知错误";
}
export function SwitchTopicType(title: string): TopicType {
switch (title) {
case "单选题": {
return 1;
}
case "多选题": {
return 2;
}
case "判断题": {
return 3;
}
case "填空题": {
return 4;
}
default: {
return null;
}
}
}
export type QuestionStatus = "success" | "network" | "incomplete" | "processing";
export type QuestionCallback = (status: QuestionStatus) => void
export type QuestionBankCallback = (args: { status: QuestionStatus, answer: Answer[] }) => void
export interface QuestionBank {
Answer(topic: Topic[], resolve: QuestionBankCallback): void;
Push(answer: Answer[]): Promise;
SetInfo(info: QuestionInfo): void;
}
export interface QuestionInfo {
refer: string
id: string
}
// 小工具题库
export class ToolsQuestionBank implements QuestionBank {
protected platform: string
protected info: QuestionInfo;
constructor(platform: string, info?: QuestionInfo) {
this.platform = platform;
this.info = info;
}
public SetInfo(info: QuestionInfo): void {
this.info = info;
}
public GetInfo(): string {
return encodeURIComponent(JSON.stringify(this.info));
}
public Answer(topic: Topic[], resolve: QuestionBankCallback): void {
Application.App.log.Debug("答案查询", topic);
let num = 5;
let answer = new Array();
let retStatus: QuestionStatus = "success";
let next = (index: number) => {
let body = "info=" + this.GetInfo() + "&";
let t = index;
for (; t < index + num && t < topic.length; t++) {
let val = topic[t];
body += "topic[" + (t - index) + "]=" + encodeURIComponent((val.topic)) + "&type[" + (t - index) + "]=" + val.type + "&";
}
HttpUtils.HttpPost(SystemConfig.url + "v2/answer?platform=" + this.platform, body, {
json: true,
success: (result: any) => {
let status: QuestionStatus = "success";
let tmpResult = new Array();
for (let i = 0; i < result.length; i++) {
if (result[i].result == undefined || result[i].result.length <= 0) {
tmpResult.push({
index: index + result[i].index,
topic: result[i].topic,
type: -1,
status: "no_answer",
answers: null,
correct: null,
Equal: this.Equal,
});
status = "incomplete";
continue;
}
let val = result[i].result[0];
tmpResult.push({
index: index + result[i].index,
topic: val.topic,
type: val.type,
correct: val.correct,
status: "ok",
Equal: this.Equal,
});
}
answer = answer.concat(tmpResult);
if (status != "success") {
retStatus = status;
}
resolve({status: "processing", answer: tmpResult});
if (t < topic.length) {
next(t);
} else {
return resolve({status: retStatus, answer: answer});
}
},
error: () => {
return resolve({status: "network", answer: answer});
}
});
}
next(0);
}
public Push(answer: Answer[]): Promise {
return new Promise((resolve) => {
Application.App.log.Debug("采集提交", answer);
HttpUtils.HttpPost(SystemConfig.url + "answer?platform=" + this.platform, "info=" + this.GetInfo() + "&data=" + encodeURIComponent(JSON.stringify(answer)), {
json: true,
success: (result: any) => {
Application.App.log.Info("答案自动记录成功,成功获得" + result.add_token_num + "个打码数,剩余数量:" + result.token_num);
resolve("success");
},
error: () => {
resolve("network");
}
});
});
}
public Equal(content1: string, content2: string): boolean {
return removeHTML(content1) == removeHTML(content2);
}
}
export interface QuestionBankFacade {
ClearQuestion(): void
AddQuestion(q: Question): void
Answer(callback: (status: QuestionStatus) => void): void
Push(callback: (status: QuestionStatus) => void): void
}
export class ToolsQuestionBankFacade implements QuestionBankFacade {
protected bank: QuestionBank;
protected question: Array;
constructor(platform: string, info?: any) {
this.bank = new ToolsQuestionBank(platform, info);
this.question = new Array();
}
public ClearQuestion() {
this.question = new Array();
}
public AddQuestion(q: Question) {
this.question.push(q);
}
public Answer(callback: (status: QuestionStatus) => void) {
let topic = new Array();
this.question.forEach((val) => {
let type = val.GetType();
if (type == -1) {
return;
}
topic.push({
topic: (val.GetTopic()),
type: type,
});
});
let status: QuestionStatus = "success";
this.bank.Answer(topic, (ret: { status: QuestionStatus, answer: Answer[] }) => {
if (ret.status != "processing") {
Application.App.log.Debug("题库返回", ret);
if (ret.status != "success" || status == "success") {
return callback(ret.status);
}
return callback(status);
}
for (let i = 0; i < ret.answer.length; i++) {
let answer = ret.answer[i];
let question = this.question[answer.index];
let tmpStatus = answer.status;
if (answer.status == "no_answer") {
status = this.randAnswer(status, tmpStatus, question);
continue;
}
if (answer.type != question.GetType()) {
tmpStatus = "no_match";
} else {
tmpStatus = question.Fill(answer);
}
if (tmpStatus == "no_match") {
status = this.randAnswer(status, tmpStatus, question);
continue;
}
question.SetStatus(tmpStatus);
}
});
}
protected randAnswer(status: QuestionStatus, tmpStatus: TopicStatus, question: Question): QuestionStatus {
if (Application.App.config.rand_answer) {
tmpStatus = question.Random();
} else {
status = "incomplete";
}
if (tmpStatus == "no_support_random") {
status = "incomplete";
}
question.SetStatus(tmpStatus);
return status;
}
public Push(callback: (status: QuestionStatus) => void): void {
let answer = new Array();
this.question.forEach((val) => {
let correct = val.Correct();
if (correct == null || correct.correct == null || correct.type == -1) {
return;
}
correct.topic = correct.topic;
correct.answers = correct.answers;
correct.correct = correct.correct;
answer.push(correct);
});
this.bank.Push(answer).then((ret: QuestionStatus) => {
Application.App.log.Debug("题库返回", ret);
return callback(ret);
});
}
protected dealOption(options: Option[]): Option[] {
for (let i = 0; i < options.length; i++) {
if (typeof options[i].content == "string") {
options[i].content = (options[i].content);
}
}
return options;
}
}