Skip to content

Commit 7a3a948

Browse files
committed
refactor: directory refactor
BREAKING CHANGE: srcipts即将废弃,视图交互性代码完善1/3
1 parent 21faf94 commit 7a3a948

35 files changed

+241
-123
lines changed

common/utils/Readme.md

+2-4
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
| createQuestion | newPath | 以传入名称创建src/[newPath]/index.js 并填充模板 |
1616
| fulfillQuestion | questionPath,question | 在对应题目空模板中填充具体问题信息 |
1717
| removeDomTags | input | 从传入的html字符串中剥离html标签 |
18-
| readStore | key | 从缓存中读取对应的键值 |
19-
| writeStore | key,value | 从缓存中存入值(明文存储,文件为store.json) |
20-
| getJsCode | enName | 获取JS代码 |
18+
| getJsCode | slug | 获取JS代码 |
2119
| getTestCase | question | 根据获取到的question信息组装测试用例 |
22-
| getQuestionUrl | enName | 简单组装问题的URL |
20+
| getQuestionUrl | slug | 简单组装问题的URL |
2321
| getRandomId | | 获取随机当前src目录下不存在的问题id |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

common/utils/question-getter/getQuestionById.js

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export async function getQuestionById(id) {
66
if(!questionContent) {
77
return {
88
id: null,
9-
109
}
1110
}
1211
const slug = questionContent.titleSlug;

common/utils/question-getter/getQuestionRandom.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import {getQuestionSearchJson} from "../../../resources/headers/questionSearchJson.js";
22
import {getQuestionDetail} from "../question-handler/getQuestionDetail.js";
3+
import {getRandomId} from "#common/utils/question-handler/getRandomId.js";
34

4-
export async function getQuestionRandom(id) {
5+
export async function getQuestionRandom() {
6+
const id = await getRandomId()
57
const base = await fetch('https://leetcode.cn/graphql/', getQuestionSearchJson(id.toString())).then((res) => res.json());
68
const slug = base.data.problemsetQuestionList.questions.find((o) => o.frontendQuestionId === id.toString()).titleSlug;
79
const question = await getQuestionDetail(slug);
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import {writeStore} from "../store.js";
21
import {getQuestionTodayJson} from "../../../resources/headers/questionTodayJson.js";
32
import {getQuestionDetail} from "../question-handler/getQuestionDetail.js";
43

@@ -7,7 +6,6 @@ export async function getQuestionToday() {
76
const today = question.data.todayRecord[0].question;
87
const { date } = question.data.todayRecord[0];
98
const questionInfo = await getQuestionDetail(today.titleSlug, { date });
10-
writeStore('today-question-info', questionInfo);
119
return questionInfo;
1210
}
1311

Original file line numberDiff line numberDiff line change
@@ -1,54 +1,21 @@
11
import fs from "fs";
22
import path from "path";
3-
import readlinePromises from "node:readline/promises";
4-
import {getCountBySameName} from "../getCountBySameName.js";
5-
import { __dirname} from '#common/utils/getDirname.js'
6-
export const sourceFilePath = path.normalize(path.resolve(__dirname, '../template/template.js'));
7-
export function createQuestion(newPath) {
8-
const rl = readlinePromises.createInterface({
9-
input: process.stdin,
10-
output: process.stdout,
11-
});
12-
return new Promise((resolve, reject) => {
13-
let newDir = path.normalize(`${process.cwd()}/src/${newPath}`);
14-
let newFilePath = path.join(newDir, 'index.js');
15-
// 判断是否存在
16-
fs.exists(newFilePath, async (exists) => {
17-
if (exists) {
18-
const recover = await rl.question(`你想创建的题目[${newPath}]已经存在,是否覆盖? (Y/N)\n`);
19-
// 如果不覆盖 可以给出两个选择 一个是退出创建进程 一个是创建一个别名
20-
if (!['y', ''].includes(recover.toLocaleLowerCase())) {
21-
let reconfirm = await rl.question('是否添加额外内容对题目进行区分,以创建此题目的另外一个解?(Enter/[[$+任意字符]]/N)\n[注:`$`符为原题目完整标题,添加额外符号后按`Enter`键确认,如不填写直接确认,系统会自动添加`$[num]`标识,例如:1.模拟[1]]\n');
22-
if (reconfirm.toLocaleLowerCase() === 'n') {
23-
console.log(`题目[${newPath}]创建终止`);
24-
process.exit();
25-
}
26-
if (reconfirm === '' || reconfirm.includes('$')) {
27-
// 默认 添加序号
28-
reconfirm ||= `$[${getCountBySameName(path.normalize('./src'), newPath)}]`;
29-
const newFileName = reconfirm.replace('$', newPath);
30-
newDir = path.normalize(`./src/${newFileName}`);
31-
newFilePath = path.join(newDir, 'index.js');
32-
console.log(`[create]题目[${newPath}]创建副本[${newFileName}]`);
33-
} else {
34-
console.log(`提示:出于安全性和综合情况考虑,请务必按规定格式创建题目,违规题目暂时不予创建。
35-
当前尝试创建题目为:[${reconfirm}]`);
36-
process.exit();
37-
}
38-
}// 如果覆盖 直接进行下一步
39-
}
40-
rl.close();
41-
try {
42-
// 创建目录
43-
fs.mkdir(newDir, { recursive: true }, () => {
44-
// 复制文件
45-
fs.copyFile(sourceFilePath, newFilePath, 0, () => {
46-
resolve(newFilePath);
47-
});
3+
import {fulfillQuestion} from "#common/utils/question-handler/fulfillQuestion.js";
4+
export const sourceFilePath = path.normalize('resources/template/template.js');
5+
export const createQuestion = (question,questionDir) => {
6+
return new Promise(resolve=>{
7+
let filePath = path.normalize(path.join(questionDir, 'index.js'));
8+
if(fs.existsSync(filePath)){
9+
resolve(false);
10+
}else{
11+
// 创建目录
12+
fs.mkdir(questionDir, { recursive: true }, () => {
13+
// 复制文件
14+
fs.copyFile(sourceFilePath, filePath, 0, () => {
15+
fulfillQuestion(filePath,question)
16+
resolve(filePath);
4817
});
49-
} catch (error) {
50-
reject('[createQuestion]Error:', error.message);
51-
}
52-
});
53-
});
18+
});
19+
}
20+
})
5421
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//todo 创建问题副本
2+
export const createQuestionCopy = (question)=>{
3+
4+
}

common/utils/question-handler/fulfillQuestion.js

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import fs from 'fs';
2-
import { removeDomTags } from '../removeDomTags.js';
2+
import { removeDomTags } from '../functions/removeDomTags.js';
33
import { getTestCase } from './getTestCase.js';
44
import { getQuestionUrl } from './getQuestionUrl.js';
55
import createMarkdown from './createMarkdown.js';
6+
import path from "path";
67
/**
78
* @typedef {Object} Question
89
* @property {string} title
@@ -20,14 +21,16 @@ import createMarkdown from './createMarkdown.js';
2021
* @param {Question} question
2122
*
2223
*/
23-
export const generateTemplateContent = (data, question) => data.replace('@题目', `${question.id}.${question.title} ${question.date ? `[${question.date}]` : ''}`)
24+
export const generateTemplateContent = (data, question) =>
25+
data
26+
.replace('@题目', `${question.id}.${question.title} ${question.date ? `[${question.date}]` : ''}`)
2427
.replace('@描述', removeDomTags(question.detail)
25-
.replace('@url', question.url)
26-
.replace(/\n+/g, '\n')
27-
.replaceAll('\n', '\n * '))
28+
.replace('@url', question.url)
29+
.replace(/\n+/g, '\n')
30+
.replaceAll('\n', '\n * '))
2831
.replace('// @Function', question.jsCode)
2932
.replace('// @TestCase', getTestCase(question))
30-
.replace('@url', getQuestionUrl(question.enName));
33+
.replace('@url', getQuestionUrl(question.slug));
3134
/**
3235
* 填充模板文件
3336
* @param questionPath
@@ -42,7 +45,6 @@ export const fulfillQuestion = (questionPath, question) => {
4245
createMarkdown(question.detail, questionPath);
4346
fs.writeFile(questionPath, newData, (err) => {
4447
if (err) throw err;
45-
console.log(`[fulfillQuestion]题目[${question.id}][${question.title}]已完成填充.`);
4648
});
4749
});
4850
};

common/utils/question-handler/getJSCode.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
* 获取JS code 必须在获取基本信息之后调用 需要传入enName
44
* @returns {Promise<unknown>}
55
*/
6-
export function getJSCode(enName) {
6+
export function getJSCode(slug) {
77
return new Promise((resolve) => {
8-
fetch('https://leetcode.cn/graphql/', getCodeDetailJson(enName)).then(((res) => res.json())).then((res) => {
8+
fetch('https://leetcode.cn/graphql/', getCodeDetailJson(slug)).then(((res) => res.json())).then((res) => {
99
const id = res.data.question.questionFrontendId;
1010
const questionCodeDetail = res.data.question?.codeSnippets.filter((item) => item.lang === 'JavaScript');
1111
const jsCode = questionCodeDetail[0].code;
1212
resolve({ id, jsCode });
1313
});
1414
});
15-
}
15+
}

common/utils/question-handler/getQuestionDetail.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export async function getQuestionDetail(slug, extra) {
77
const detail = questionDetail.data.question;
88
const jsCode = await getJSCode(slug);
99
return {
10-
enName: slug,
10+
slug: slug,
1111
title: detail.translatedTitle,
1212
detail: detail.translatedContent,
1313
...jsCode,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* 获取题目的路径
3+
* @param question
4+
* @returns {string}
5+
*/
6+
export const getQuestionFileName = (question)=>{
7+
if(!question||!question?.id)return "";
8+
return `${question.id}.${question.slug}`;
9+
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export function getQuestionUrl(enName) {
2-
return `https://leetcode.cn/problems/${enName}/`;
1+
export function getQuestionUrl(slug) {
2+
return `https://leetcode.cn/problems/${slug}/`;
33
}

common/utils/question-handler/getTestCase.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {getDataStructure} from "./parseStructure.js";
2-
import {removeDomTags} from "../removeDomTags.js";
2+
import {removeDomTags} from "../functions/removeDomTags.js";
33

44
/**
55
* test case 需要从两个地方拿到内容

common/utils/question-handler/parseStructure.js

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
import {Node} from "../../structures/Node.js";
22
import {TreeNode} from "../../structures/TreeNode.js";
33
import {ListNode} from "#common/structures/ListNode.js";
4-
const parse = ListNode.parse;
5-
const toArray = ListNode.toArray;
64

75
const paramMap = {
86
// 入参map
97
cases: {
10-
ListNode: (_param) => parse(_param),
11-
'ListNode[]': (param) => param.map((res) => parse(res)),
8+
ListNode: (_param) => ListNode.parse(_param),
9+
'ListNode[]': (param) => param.map((res) => ListNode.parse(res)),
1210
TreeNode: (param) => TreeNode.parse(param),
1311
Node: (param) => Node.parse(param),
1412
default: (param) => param,
1513
},
1614
// 返回值map
1715
return: {
18-
ListNode: (param) => toArray(param),
19-
'ListNode[]': (param) => param.map((res) => toArray(res)),
16+
ListNode: (param) => ListNode.toArray(param),
17+
'ListNode[]': (param) => param.map((res) => ListNode.toArray(res)),
2018
TreeNode: (param) => TreeNode.toArray(param),
2119
Node: (param) => Node.toArray(param),
2220
default: (param) => param,

common/utils/showLogs.js common/utils/question-handler/showLogs.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import v8 from "v8";
2-
import {getFileSize} from "./sizeUtil.js";
3-
import {isSameData} from "./isSameData.js";
4-
import {setDataStructure} from "./question-handler/parseStructure.js";
2+
import {getFileSize} from "../functions/sizeUtil.js";
3+
import {isSameData} from "../functions/isSameData.js";
4+
import {setDataStructure} from "./parseStructure.js";
55

66
/**
77
* 执行并输出时间和内存

common/utils/store.js

-19
This file was deleted.
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import Realm from "realm";
2+
export class Question extends Realm.Object {
3+
static schema = {
4+
name: "Question",
5+
properties: {
6+
_id: {type: "objectId", default: () => new Realm.BSON.ObjectId()},
7+
id: "string",
8+
mode: "string",
9+
slug: "string",
10+
title: "string",
11+
detail: "string",
12+
jsCode: "string",
13+
url: "string?",
14+
date: "string?",
15+
timestamp: {type:"date",default:()=>new Date()}
16+
},
17+
primaryKey: "_id",
18+
};
19+
}

common/utils/store/store-realm.js

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import Realm from "realm";
2+
import {Question} from "#common/utils/store/schemas/question.js";
3+
import path from "path";
4+
const localPath = path.normalize("resources/stores/store.realm")
5+
/**
6+
* 开启
7+
* @returns {Promise<Realm>}
8+
*/
9+
const open = async ()=>{
10+
const realm =await Realm.open({
11+
schema: [Question],
12+
path:localPath
13+
});
14+
return realm;
15+
}
16+
/**
17+
* 执行一次
18+
* @param callback
19+
* @returns {Promise<void>}
20+
*/
21+
const exeOnce = async (callback)=>{
22+
const realm = await open();
23+
const res = callback(realm);
24+
realm.close()
25+
return res;
26+
}
27+
28+
/**
29+
* 读取对象
30+
* @param mode
31+
* @returns {unknown}
32+
*/
33+
export const getQuestionByMode = (mode)=>exeOnce((realm)=>{
34+
const all = realm.objects("Question");
35+
const question = all.filtered("mode=$0",mode)?.[0];
36+
return question.toJSON();
37+
})
38+
/**
39+
* 存对象
40+
* @param mode
41+
* @param question
42+
* @returns {*}
43+
*/
44+
export const setQuestion = (mode,question)=>exeOnce((realm)=>{
45+
let newQuestion;
46+
realm.write(() => {
47+
realm.delete(realm.objects("Question").filtered("mode=$0",mode));
48+
newQuestion = realm.create("Question", Object.assign(question,{mode}));
49+
});
50+
return newQuestion;
51+
});
52+
/**
53+
* 删除某一个模式
54+
* @param mode
55+
*/
56+
export const deleteQuestionByMode = (mode)=>exeOnce((realm)=>{
57+
realm.write(() => {
58+
const modes = realm.objects("Question").filtered("mode=$0",mode)
59+
realm.delete(modes);
60+
});
61+
});
62+
/**
63+
* 删除全部
64+
*/
65+
export const deleteAllQuestion = ()=>exeOnce((realm)=>{
66+
realm.write(() => {
67+
realm.delete(realm.objects("Question"));
68+
});
69+
});

common/view/check.view.js

Whitespace-only changes.

0 commit comments

Comments
 (0)