@jayfong/x-utils 1.0.0-202407012223
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_cjs/ai.js +80 -0
- package/_cjs/cli.js +51 -0
- package/_cjs/clipboard.js +65 -0
- package/_cjs/cmd.js +42 -0
- package/_cjs/crawler.js +341 -0
- package/_cjs/csv.js +97 -0
- package/_cjs/data_set.js +115 -0
- package/_cjs/env.js +63 -0
- package/_cjs/fs.js +35 -0
- package/_cjs/html.js +62 -0
- package/_cjs/http_server.js +56 -0
- package/_cjs/json.js +49 -0
- package/_cjs/ksb.js +217 -0
- package/_cjs/number.js +39 -0
- package/_cjs/ocr.js +74 -0
- package/_cjs/path.js +35 -0
- package/_cjs/pinyin.js +32 -0
- package/_cjs/puppeteer.js +271 -0
- package/_cjs/runner.js +88 -0
- package/_cjs/task.js +41 -0
- package/_cjs/text.js +136 -0
- package/_cjs/unicode/lib_unicode.js +58643 -0
- package/_cjs/unicode/unicode.js +441 -0
- package/_cjs/upload.js +100 -0
- package/_cjs/yaml.js +52 -0
- package/ai.d.ts +26 -0
- package/ai.js +60 -0
- package/cli.d.ts +14 -0
- package/cli.js +21 -0
- package/clipboard.d.ts +6 -0
- package/clipboard.js +35 -0
- package/cmd.d.ts +5 -0
- package/cmd.js +22 -0
- package/crawler.d.ts +162 -0
- package/crawler.js +332 -0
- package/csv.d.ts +14 -0
- package/csv.js +67 -0
- package/data_set.d.ts +22 -0
- package/data_set.js +85 -0
- package/env.d.ts +4 -0
- package/env.js +32 -0
- package/fs.d.ts +2 -0
- package/fs.js +5 -0
- package/html.d.ts +7 -0
- package/html.js +45 -0
- package/http_server.d.ts +10 -0
- package/http_server.js +26 -0
- package/json.d.ts +6 -0
- package/json.js +19 -0
- package/ksb.d.ts +32 -0
- package/ksb.js +197 -0
- package/number.d.ts +3 -0
- package/number.js +9 -0
- package/ocr.d.ts +10 -0
- package/ocr.js +54 -0
- package/ofd.d.ts +1 -0
- package/package.json +158 -0
- package/path.d.ts +2 -0
- package/path.js +5 -0
- package/pinyin.d.ts +3 -0
- package/pinyin.js +12 -0
- package/puppeteer.d.ts +38 -0
- package/puppeteer.js +241 -0
- package/runner.d.ts +13 -0
- package/runner.js +58 -0
- package/task.d.ts +6 -0
- package/task.js +21 -0
- package/text.d.ts +63 -0
- package/text.js +119 -0
- package/unicode/lib_unicode.d.ts +4 -0
- package/unicode/lib_unicode.js +58623 -0
- package/unicode/unicode.d.ts +347 -0
- package/unicode/unicode.js +426 -0
- package/upload.d.ts +22 -0
- package/upload.js +70 -0
- package/yaml.d.ts +6 -0
- package/yaml.js +22 -0
package/data_set.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { asyncExitHook } from "exit-hook";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { keyBy, keysStrict, pickStrict } from "vtils";
|
|
5
|
+
import { v } from "vtils/vae";
|
|
6
|
+
import { XCsv } from "./csv.js";
|
|
7
|
+
import { XJson } from "./json.js";
|
|
8
|
+
import { XYaml } from "./yaml.js";
|
|
9
|
+
class XDataSet {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.options = options;
|
|
12
|
+
this.storeType = options.storeFile.endsWith(".csv") ? "csv" : options.storeFile.endsWith(".yaml") || options.storeFile.endsWith(".yml") ? "yaml" : "json";
|
|
13
|
+
this.dataShapeSchema = options.dataSchema(v);
|
|
14
|
+
this.dataSchema = v.object(this.dataShapeSchema);
|
|
15
|
+
this.csvOptions = {
|
|
16
|
+
arrayDelimiter: options.csvArrayDelimiter,
|
|
17
|
+
arrayFieldNames: keysStrict(this.dataShapeSchema).filter(
|
|
18
|
+
(key) => this.dataShapeSchema[key].options.type === "array"
|
|
19
|
+
),
|
|
20
|
+
objectFieldNames: keysStrict(this.dataShapeSchema).filter(
|
|
21
|
+
(key) => this.dataShapeSchema[key].options.type === "object"
|
|
22
|
+
),
|
|
23
|
+
booleanFieldNames: keysStrict(this.dataShapeSchema).filter(
|
|
24
|
+
(key) => this.dataShapeSchema[key].options.type === "boolean"
|
|
25
|
+
),
|
|
26
|
+
dateFieldNames: keysStrict(this.dataShapeSchema).filter(
|
|
27
|
+
(key) => this.dataShapeSchema[key].options.type === "date"
|
|
28
|
+
)
|
|
29
|
+
};
|
|
30
|
+
if (!options.noAutoWrite) {
|
|
31
|
+
const timer = setInterval(() => {
|
|
32
|
+
this.write();
|
|
33
|
+
}, options.autoWriteInterval || 5e3);
|
|
34
|
+
asyncExitHook(
|
|
35
|
+
async () => {
|
|
36
|
+
clearInterval(timer);
|
|
37
|
+
await this.write();
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
wait: 1e4
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
storeType;
|
|
46
|
+
dataShapeSchema;
|
|
47
|
+
dataSchema;
|
|
48
|
+
csvOptions;
|
|
49
|
+
currentMap;
|
|
50
|
+
get current() {
|
|
51
|
+
const orderedDataFieldNames = keysStrict(this.dataShapeSchema);
|
|
52
|
+
const dataSet = keysStrict(this.currentMap).map((dataKeyValue) => {
|
|
53
|
+
const data = {
|
|
54
|
+
...this.currentMap[dataKeyValue],
|
|
55
|
+
[this.options.dataKey]: dataKeyValue
|
|
56
|
+
};
|
|
57
|
+
return this.dataSchema.cast(
|
|
58
|
+
pickStrict(data, orderedDataFieldNames)
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
return dataSet;
|
|
62
|
+
}
|
|
63
|
+
async read() {
|
|
64
|
+
let dataSet = [];
|
|
65
|
+
try {
|
|
66
|
+
dataSet = await (this.storeType === "csv" ? XCsv.read(this.options.storeFile, this.csvOptions) : this.storeType === "yaml" ? XYaml.read(this.options.storeFile) : XJson.read(this.options.storeFile));
|
|
67
|
+
} catch {
|
|
68
|
+
}
|
|
69
|
+
dataSet = dataSet.map((data) => this.dataSchema.cast(data));
|
|
70
|
+
this.currentMap = keyBy(
|
|
71
|
+
dataSet,
|
|
72
|
+
(data) => data[this.options.dataKey]
|
|
73
|
+
);
|
|
74
|
+
return dataSet;
|
|
75
|
+
}
|
|
76
|
+
async write(dataSet = this.current) {
|
|
77
|
+
console.log(`\u{1F4A5} \u5199\u5165 ${this.options.storeFile}`);
|
|
78
|
+
await fs.ensureDir(path.dirname(this.options.storeFile));
|
|
79
|
+
await (this.storeType === "csv" ? XCsv.write(this.options.storeFile, dataSet, this.csvOptions) : this.storeType === "yaml" ? XYaml.write(this.options.storeFile, dataSet) : XJson.write(this.options.storeFile, dataSet));
|
|
80
|
+
console.log(`\u2705 \u5199\u5165 ${this.options.storeFile}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export {
|
|
84
|
+
XDataSet
|
|
85
|
+
};
|
package/env.d.ts
ADDED
package/env.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import dotenv from "dotenv";
|
|
2
|
+
import { isPlainObject, memoize } from "vtils";
|
|
3
|
+
import { XFs } from "./fs.js";
|
|
4
|
+
import { XPath } from "./path.js";
|
|
5
|
+
import { XYaml } from "./yaml.js";
|
|
6
|
+
class XEnv {
|
|
7
|
+
static getEnvVarsFromFile = memoize(async () => {
|
|
8
|
+
const envYmlFile = XPath.join(import.meta.dirname, ".env.yml");
|
|
9
|
+
if (await XFs.pathExists(envYmlFile)) {
|
|
10
|
+
return XYaml.read(envYmlFile);
|
|
11
|
+
}
|
|
12
|
+
const envYamlFile = XPath.join(import.meta.dirname, ".env.yaml");
|
|
13
|
+
if (await XFs.pathExists(envYamlFile)) {
|
|
14
|
+
return XYaml.read(envYamlFile);
|
|
15
|
+
}
|
|
16
|
+
const dotenvFile = XPath.join(import.meta.dirname, ".env");
|
|
17
|
+
if (await XFs.pathExists(dotenvFile)) {
|
|
18
|
+
const dotenvContent = await XFs.readFile(dotenvFile, "utf-8");
|
|
19
|
+
return dotenv.parse(dotenvContent);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
static async getEnvVar(name) {
|
|
23
|
+
if (process.env[name] != null) {
|
|
24
|
+
return process.env[name];
|
|
25
|
+
}
|
|
26
|
+
const envVars = await XEnv.getEnvVarsFromFile();
|
|
27
|
+
return isPlainObject(envVars) ? envVars[name] ?? void 0 : void 0;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
XEnv
|
|
32
|
+
};
|
package/fs.d.ts
ADDED
package/fs.js
ADDED
package/html.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { ParagraphChild } from 'docx';
|
|
3
|
+
export { HTMLElement as XHtmlElement, NodeType as XHtmlNodeType, } from 'node-html-parser';
|
|
4
|
+
export declare class XHtml {
|
|
5
|
+
static parse(html: string): import("node-html-parser").HTMLElement;
|
|
6
|
+
static toDocxParagraphChildren(html: string, fetchImage: (url: string) => Promise<Buffer>): Promise<ParagraphChild[]>;
|
|
7
|
+
}
|
package/html.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ImageRun, TextRun } from "docx";
|
|
2
|
+
import { imageDimensionsFromData } from "image-dimensions";
|
|
3
|
+
import { parse } from "node-html-parser";
|
|
4
|
+
import { parser } from "posthtml-parser";
|
|
5
|
+
import { flattenDeep, ii } from "vtils";
|
|
6
|
+
import {
|
|
7
|
+
HTMLElement,
|
|
8
|
+
NodeType
|
|
9
|
+
} from "node-html-parser";
|
|
10
|
+
class XHtml {
|
|
11
|
+
static parse(html) {
|
|
12
|
+
return parse(html);
|
|
13
|
+
}
|
|
14
|
+
static async toDocxParagraphChildren(html, fetchImage) {
|
|
15
|
+
const nodes = parser(html, {
|
|
16
|
+
decodeEntities: true
|
|
17
|
+
}).map(function process(node) {
|
|
18
|
+
return typeof node === "object" && node.content && Array.isArray(node.content) ? flattenDeep(node.content).map(process).flat() : [node];
|
|
19
|
+
}).flat();
|
|
20
|
+
return await Promise.all(
|
|
21
|
+
nodes.map(async (node) => {
|
|
22
|
+
return typeof node === "string" || typeof node === "number" ? new TextRun({
|
|
23
|
+
text: String(node)
|
|
24
|
+
}) : node.tag === "img" && typeof node.attrs?.src === "string" ? await ii(async () => {
|
|
25
|
+
const imageBuffer = await fetchImage(node.attrs.src);
|
|
26
|
+
const size = imageDimensionsFromData(imageBuffer);
|
|
27
|
+
return new ImageRun({
|
|
28
|
+
data: imageBuffer,
|
|
29
|
+
transformation: {
|
|
30
|
+
width: size?.width || 0,
|
|
31
|
+
height: size?.height || 0
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}) : new TextRun({
|
|
35
|
+
text: ""
|
|
36
|
+
});
|
|
37
|
+
})
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
XHtml,
|
|
43
|
+
HTMLElement as XHtmlElement,
|
|
44
|
+
NodeType as XHtmlNodeType
|
|
45
|
+
};
|
package/http_server.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type XHttpServerOptions = {
|
|
2
|
+
port: number;
|
|
3
|
+
handlers: Record<string, (data: any) => any>;
|
|
4
|
+
};
|
|
5
|
+
export declare class XHttpServer {
|
|
6
|
+
private options;
|
|
7
|
+
constructor(options: XHttpServerOptions);
|
|
8
|
+
start(): Promise<void>;
|
|
9
|
+
static start(options: XHttpServerOptions): Promise<void>;
|
|
10
|
+
}
|
package/http_server.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import cors from "@fastify/cors";
|
|
2
|
+
import Fastify from "fastify";
|
|
3
|
+
class XHttpServer {
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.options = options;
|
|
6
|
+
}
|
|
7
|
+
async start() {
|
|
8
|
+
const fastify = Fastify({
|
|
9
|
+
logger: true
|
|
10
|
+
});
|
|
11
|
+
await fastify.register(cors);
|
|
12
|
+
Object.keys(this.options.handlers).forEach((name) => {
|
|
13
|
+
fastify.post(`/${name}`, (req) => this.options.handlers[name](req.body));
|
|
14
|
+
});
|
|
15
|
+
await fastify.listen({
|
|
16
|
+
host: "0.0.0.0",
|
|
17
|
+
port: this.options.port
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
static async start(options) {
|
|
21
|
+
await new XHttpServer(options).start();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
XHttpServer
|
|
26
|
+
};
|
package/json.d.ts
ADDED
package/json.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
class XJson {
|
|
3
|
+
static parse(value) {
|
|
4
|
+
return JSON.parse(value);
|
|
5
|
+
}
|
|
6
|
+
static stringify(value, compact = false) {
|
|
7
|
+
return JSON.stringify(value, null, compact ? void 0 : 2);
|
|
8
|
+
}
|
|
9
|
+
static async read(file) {
|
|
10
|
+
const value = await fs.promises.readFile(file, "utf8");
|
|
11
|
+
return XJson.parse(value);
|
|
12
|
+
}
|
|
13
|
+
static async write(file, value, compact = false) {
|
|
14
|
+
await fs.promises.writeFile(file, XJson.stringify(value, compact));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
XJson
|
|
19
|
+
};
|
package/ksb.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/// <reference types="lodash" />
|
|
2
|
+
export declare class XKsb {
|
|
3
|
+
static request<T>(url: string, data?: any): Promise<T>;
|
|
4
|
+
static desensitize(text: string): string;
|
|
5
|
+
static getPaperId(payload: {
|
|
6
|
+
paperName: string;
|
|
7
|
+
}): Promise<string | undefined>;
|
|
8
|
+
static getPaperIdMemo: ((payload: {
|
|
9
|
+
paperName: string;
|
|
10
|
+
}) => Promise<string | undefined>) & import("lodash").MemoizedFunction;
|
|
11
|
+
static deletePaper(payload: {
|
|
12
|
+
paperName: string;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
static addPaper(payload: {
|
|
15
|
+
paperName: string;
|
|
16
|
+
}): Promise<void>;
|
|
17
|
+
static ensurePaperExistsAndEmpty(payload: {
|
|
18
|
+
paperName: string;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
static addQuestion(payload: {
|
|
21
|
+
paperName: string;
|
|
22
|
+
question: {
|
|
23
|
+
type: '单选' | '判断' | '填空' | '问答';
|
|
24
|
+
question: string;
|
|
25
|
+
options: Array<{
|
|
26
|
+
key: string;
|
|
27
|
+
value: string;
|
|
28
|
+
}>;
|
|
29
|
+
answer: string | boolean | string[];
|
|
30
|
+
};
|
|
31
|
+
}): Promise<void>;
|
|
32
|
+
}
|
package/ksb.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { xr } from "@jayfong/x-request";
|
|
2
|
+
import { castArray, md5, memoize } from "vtils";
|
|
3
|
+
class XKsb {
|
|
4
|
+
static request(url, data) {
|
|
5
|
+
const token = "%22ZpWKMcjeUIsZMwZIMUdkhEfAq93e3dPsQyWxAtkRNbc=%22";
|
|
6
|
+
const key = "12b6bb84e093532fb72b4d65fec3f00b";
|
|
7
|
+
const clientId = "ca37dd67-f885-4678-91a7-6531bb153ef2";
|
|
8
|
+
const ts = (/* @__PURE__ */ new Date()).getTime();
|
|
9
|
+
const sign = md5(`${key}${clientId}${url}${ts}${key}`);
|
|
10
|
+
return xr.postJson({
|
|
11
|
+
url: `https://www.kaoshibao.com/api${url}`,
|
|
12
|
+
data,
|
|
13
|
+
autoReferer: true,
|
|
14
|
+
// proxyUrl: 'http://127.0.0.1:8888',
|
|
15
|
+
headers: {
|
|
16
|
+
Timestamp: ts,
|
|
17
|
+
Version: "2.2.2",
|
|
18
|
+
Platform: "web",
|
|
19
|
+
Authorization: token,
|
|
20
|
+
"Client-Identifier": clientId,
|
|
21
|
+
Sign: sign
|
|
22
|
+
}
|
|
23
|
+
}).then((res) => res.data);
|
|
24
|
+
}
|
|
25
|
+
static desensitize(text) {
|
|
26
|
+
return text.replace(/台湾|澳门|香港|西藏|新疆|习近平/g, (word) => {
|
|
27
|
+
return word.split("").join(String.fromCharCode(8290));
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
static async getPaperId(payload) {
|
|
31
|
+
const res = await XKsb.request("/user/paper/list", {
|
|
32
|
+
keyword: payload.paperName,
|
|
33
|
+
page: 1,
|
|
34
|
+
size: 10,
|
|
35
|
+
parentid: "",
|
|
36
|
+
column: "0",
|
|
37
|
+
direction: ""
|
|
38
|
+
});
|
|
39
|
+
return res.data.rows?.[0]?.paperid;
|
|
40
|
+
}
|
|
41
|
+
static getPaperIdMemo = memoize(
|
|
42
|
+
(payload) => XKsb.getPaperId(payload),
|
|
43
|
+
(payload) => payload.paperName
|
|
44
|
+
);
|
|
45
|
+
static async deletePaper(payload) {
|
|
46
|
+
const paperId = await XKsb.getPaperId(payload);
|
|
47
|
+
if (paperId) {
|
|
48
|
+
await XKsb.request("/user/paper/delete", {
|
|
49
|
+
id: paperId
|
|
50
|
+
});
|
|
51
|
+
XKsb.getPaperIdMemo.cache.delete(payload.paperName);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
static async addPaper(payload) {
|
|
55
|
+
await XKsb.request("/user/paper/add", {
|
|
56
|
+
name: payload.paperName,
|
|
57
|
+
type: "4"
|
|
58
|
+
});
|
|
59
|
+
XKsb.getPaperIdMemo.cache.delete(payload.paperName);
|
|
60
|
+
}
|
|
61
|
+
static async ensurePaperExistsAndEmpty(payload) {
|
|
62
|
+
await XKsb.deletePaper(payload);
|
|
63
|
+
await XKsb.addPaper(payload);
|
|
64
|
+
}
|
|
65
|
+
static async addQuestion(payload) {
|
|
66
|
+
payload.question.question = XKsb.desensitize(payload.question.question);
|
|
67
|
+
payload.question.options.forEach((opt) => {
|
|
68
|
+
opt.value = XKsb.desensitize(opt.value);
|
|
69
|
+
});
|
|
70
|
+
if (typeof payload.question.answer === "string") {
|
|
71
|
+
payload.question.answer = XKsb.desensitize(payload.question.answer);
|
|
72
|
+
} else if (Array.isArray(payload.question.answer)) {
|
|
73
|
+
payload.question.answer.forEach((v, i) => {
|
|
74
|
+
if (typeof v === "string") {
|
|
75
|
+
payload.question.answer[i] = XKsb.desensitize(v);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const paperId = await XKsb.getPaperIdMemo(payload);
|
|
80
|
+
await XKsb.request(
|
|
81
|
+
"/user/question/add",
|
|
82
|
+
// 单选
|
|
83
|
+
payload.question.type === "\u5355\u9009" ? {
|
|
84
|
+
id: "",
|
|
85
|
+
qtype: "1",
|
|
86
|
+
paperid: paperId,
|
|
87
|
+
options: JSON.stringify(
|
|
88
|
+
payload.question.options.map((opt) => ({
|
|
89
|
+
Key: opt.key,
|
|
90
|
+
Value: opt.value,
|
|
91
|
+
checked: false,
|
|
92
|
+
extend: ""
|
|
93
|
+
}))
|
|
94
|
+
),
|
|
95
|
+
judgeOptions: [
|
|
96
|
+
{ Key: "A", Value: "\u6B63\u786E" },
|
|
97
|
+
{ Key: "B", Value: "\u9519\u8BEF" }
|
|
98
|
+
],
|
|
99
|
+
question: payload.question.question,
|
|
100
|
+
answer: payload.question.answer,
|
|
101
|
+
extra: '{"ordered":"0","case_sensitive":"0"}',
|
|
102
|
+
paixuAnswer: "",
|
|
103
|
+
analysis: "",
|
|
104
|
+
parentid: 0,
|
|
105
|
+
chapter: "",
|
|
106
|
+
difficulty: "",
|
|
107
|
+
blanks: [{ Value: "" }],
|
|
108
|
+
optionData: [],
|
|
109
|
+
optionTipic: [],
|
|
110
|
+
optionDataTipic: {
|
|
111
|
+
options: [
|
|
112
|
+
{ Key: "A", Value: "", checked: false },
|
|
113
|
+
{ Key: "B", Value: "", checked: false },
|
|
114
|
+
{ Key: "C", Value: "", checked: false },
|
|
115
|
+
{ Key: "D", Value: "", checked: false }
|
|
116
|
+
],
|
|
117
|
+
answer: ""
|
|
118
|
+
},
|
|
119
|
+
fileList: []
|
|
120
|
+
} : payload.question.type === "\u5224\u65AD" ? {
|
|
121
|
+
id: "",
|
|
122
|
+
qtype: "3",
|
|
123
|
+
paperid: paperId,
|
|
124
|
+
options: '[{"Key":"A","Value":"","checked":false},{"Key":"B","Value":"","checked":false},{"Key":"C","Value":"","checked":false},{"Key":"D","Value":"","checked":false}]',
|
|
125
|
+
judgeOptions: [
|
|
126
|
+
{ Key: "A", Value: "\u6B63\u786E" },
|
|
127
|
+
{ Key: "B", Value: "\u9519\u8BEF" }
|
|
128
|
+
],
|
|
129
|
+
question: payload.question.question,
|
|
130
|
+
answer: payload.question.answer ? "A" : "B",
|
|
131
|
+
parentid: 0,
|
|
132
|
+
chapter: "",
|
|
133
|
+
difficulty: "",
|
|
134
|
+
extra: '{"ordered":"0","case_sensitive":"0"}',
|
|
135
|
+
analysis: "",
|
|
136
|
+
paixuAnswer: "",
|
|
137
|
+
blanks: [{ Value: "" }],
|
|
138
|
+
optionData: [],
|
|
139
|
+
optionTipic: [],
|
|
140
|
+
optionDataTipic: ""
|
|
141
|
+
} : payload.question.type === "\u586B\u7A7A" ? {
|
|
142
|
+
id: "",
|
|
143
|
+
qtype: "4",
|
|
144
|
+
paperid: paperId,
|
|
145
|
+
options: '[{"Key":"A","Value":"","checked":false},{"Key":"B","Value":"","checked":false},{"Key":"C","Value":"","checked":false},{"Key":"D","Value":"","checked":false}]',
|
|
146
|
+
judgeOptions: [
|
|
147
|
+
{ Key: "A", Value: "\u6B63\u786E" },
|
|
148
|
+
{ Key: "B", Value: "\u9519\u8BEF" }
|
|
149
|
+
],
|
|
150
|
+
question: payload.question.question,
|
|
151
|
+
answer: castArray(payload.question.answer).join("|"),
|
|
152
|
+
parentid: 0,
|
|
153
|
+
chapter: "",
|
|
154
|
+
difficulty: "",
|
|
155
|
+
extra: '{"ordered":"0","case_sensitive":"0"}',
|
|
156
|
+
analysis: "",
|
|
157
|
+
paixuAnswer: "",
|
|
158
|
+
blanks: castArray(payload.question.answer).map((v) => ({
|
|
159
|
+
Value: v
|
|
160
|
+
})),
|
|
161
|
+
optionData: [],
|
|
162
|
+
optionTipic: [],
|
|
163
|
+
optionDataTipic: ""
|
|
164
|
+
} : payload.question.type === "\u95EE\u7B54" ? {
|
|
165
|
+
id: "",
|
|
166
|
+
qtype: "11",
|
|
167
|
+
paperid: paperId,
|
|
168
|
+
options: '[{"Key":"A","Value":"","checked":false},{"Key":"B","Value":"","checked":false},{"Key":"C","Value":"","checked":false},{"Key":"D","Value":"","checked":false}]',
|
|
169
|
+
judgeOptions: [
|
|
170
|
+
{ Key: "A", Value: "\u6B63\u786E" },
|
|
171
|
+
{ Key: "B", Value: "\u9519\u8BEF" }
|
|
172
|
+
],
|
|
173
|
+
question: payload.question.question,
|
|
174
|
+
answer: payload.question.answer,
|
|
175
|
+
parentid: 0,
|
|
176
|
+
chapter: "",
|
|
177
|
+
difficulty: "",
|
|
178
|
+
extra: '{"ordered":"0","case_sensitive":"0"}',
|
|
179
|
+
analysis: "",
|
|
180
|
+
paixuAnswer: "",
|
|
181
|
+
blanks: [{ Value: "" }],
|
|
182
|
+
optionData: [],
|
|
183
|
+
optionTipic: [],
|
|
184
|
+
optionDataTipic: ""
|
|
185
|
+
} : {}
|
|
186
|
+
// 判断
|
|
187
|
+
// {"id":"","qtype":"3","paperid":"15844653","options":"[{\"Key\":\"A\",\"Value\":\"\",\"checked\":false},{\"Key\":\"B\",\"Value\":\"\",\"checked\":false},{\"Key\":\"C\",\"Value\":\"\",\"checked\":false},{\"Key\":\"D\",\"Value\":\"\",\"checked\":false}]","judgeOptions":[{"Key":"A","Value":"正确"},{"Key":"B","Value":"错误"}],"question":"<p>顶顶顶顶</p>","answer":"A","parentid":0,"chapter":"","difficulty":"","extra":"{\"ordered\":\"0\",\"case_sensitive\":\"0\"}","analysis":"","paixuAnswer":"","blanks":[{"Value":""}],"optionData":[],"optionTipic":[],"optionDataTipic":""}
|
|
188
|
+
// 填空
|
|
189
|
+
// {"id":"","qtype":"4","paperid":"15844653","options":"[{\"Key\":\"A\",\"Value\":\"\",\"checked\":false},{\"Key\":\"B\",\"Value\":\"\",\"checked\":false},{\"Key\":\"C\",\"Value\":\"\",\"checked\":false},{\"Key\":\"D\",\"Value\":\"\",\"checked\":false}]","judgeOptions":[{"Key":"A","Value":"正确"},{"Key":"B","Value":"错误"}],"question":"<p>99999999</p>","answer":"999|888","parentid":0,"chapter":"","difficulty":"","extra":"{\"ordered\":\"0\",\"case_sensitive\":\"0\"}","analysis":"","paixuAnswer":"","blanks":[{"Value":"999"},{"Value":"888"}],"optionData":[],"optionTipic":[],"optionDataTipic":""}
|
|
190
|
+
// 问答
|
|
191
|
+
// {"id":"","qtype":"11","paperid":"15844653","options":"[{\"Key\":\"A\",\"Value\":\"\",\"checked\":false},{\"Key\":\"B\",\"Value\":\"\",\"checked\":false},{\"Key\":\"C\",\"Value\":\"\",\"checked\":false},{\"Key\":\"D\",\"Value\":\"\",\"checked\":false}]","judgeOptions":[{"Key":"A","Value":"正确"},{"Key":"B","Value":"错误"}],"question":"<p>666666</p>","answer":"<p>67777777</p>","parentid":0,"chapter":"","difficulty":"","extra":"{\"ordered\":\"0\",\"case_sensitive\":\"0\"}","analysis":"","paixuAnswer":"","blanks":[{"Value":""}],"optionData":[],"optionTipic":[],"optionDataTipic":""}
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
export {
|
|
196
|
+
XKsb
|
|
197
|
+
};
|
package/number.d.ts
ADDED
package/number.js
ADDED
package/ocr.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
export declare class XOcr {
|
|
3
|
+
static recognize(url: string, { serverUrl, }?: {
|
|
4
|
+
serverUrl?: string;
|
|
5
|
+
}): Promise<string>;
|
|
6
|
+
static recognizeCaptcha(buffer: Buffer, { serverUrl, serverToken, }?: {
|
|
7
|
+
serverUrl?: string;
|
|
8
|
+
serverToken?: string;
|
|
9
|
+
}): Promise<string>;
|
|
10
|
+
}
|
package/ocr.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { xr } from "@jayfong/x-request";
|
|
2
|
+
import { XEnv } from "./env.js";
|
|
3
|
+
class XOcr {
|
|
4
|
+
static async recognize(url, {
|
|
5
|
+
serverUrl
|
|
6
|
+
} = {}) {
|
|
7
|
+
if (serverUrl == null) {
|
|
8
|
+
serverUrl = await XEnv.getEnvVar("X_OCR_RECOGNIZE_SERVER_URL");
|
|
9
|
+
}
|
|
10
|
+
const { data: buffer } = await xr.get({
|
|
11
|
+
url,
|
|
12
|
+
autoReferer: true
|
|
13
|
+
});
|
|
14
|
+
const base64 = buffer.toString("base64");
|
|
15
|
+
const { data: res } = await xr.postJson({
|
|
16
|
+
url: serverUrl,
|
|
17
|
+
data: {
|
|
18
|
+
base64,
|
|
19
|
+
options: {}
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
if (res.code !== 100) {
|
|
23
|
+
if (res.data.includes("No text found in image")) {
|
|
24
|
+
return "";
|
|
25
|
+
}
|
|
26
|
+
throw new Error(res.data);
|
|
27
|
+
}
|
|
28
|
+
return res.data.map((item) => item.text).join(" ");
|
|
29
|
+
}
|
|
30
|
+
static async recognizeCaptcha(buffer, {
|
|
31
|
+
serverUrl,
|
|
32
|
+
serverToken
|
|
33
|
+
} = {}) {
|
|
34
|
+
if (serverUrl == null) {
|
|
35
|
+
serverUrl = await XEnv.getEnvVar("X_OCR_RECOGNIZE_CAPTCHA_SERVER_URL");
|
|
36
|
+
}
|
|
37
|
+
if (serverToken == null) {
|
|
38
|
+
serverToken = await XEnv.getEnvVar(
|
|
39
|
+
"X_OCR_RECOGNIZE_CAPTCHA_SERVER_TOKEN"
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
const res = await xr.postJson({
|
|
43
|
+
url: serverUrl,
|
|
44
|
+
data: xr.formData({
|
|
45
|
+
token: serverToken,
|
|
46
|
+
file: xr.formFile(buffer, { name: "xx.png" })
|
|
47
|
+
})
|
|
48
|
+
});
|
|
49
|
+
return res.data.text;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
XOcr
|
|
54
|
+
};
|
package/ofd.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|