init first

This commit is contained in:
2025-11-24 03:52:19 +08:00
parent 125e519989
commit 21b56d0948
26 changed files with 7266 additions and 125 deletions

View File

@@ -0,0 +1,113 @@
import { generateId, getTodayDate } from '../module/utils.ts';
import { app } from '../app.ts';
import { getDb } from '../module/db.ts';
import { dailyQuestions, questionLibrary } from '../module/schema.ts';
import { eq } from 'drizzle-orm';
app.route({
path: 'daily',
key: 'random',
description: '随机获取一条未使用的问题'
}).define(async (ctx) => {
const force = ctx.query.force ?? false;
const db = getDb();
const day = getTodayDate();
if (force) {
const existingQuestion = await db
.select()
.from(dailyQuestions)
.where(eq(dailyQuestions.date, day))
.limit(1)
.get();
if (existingQuestion) {
// 删除dailyQuestions中的记录
await db
.delete(dailyQuestions)
.where(eq(dailyQuestions.id, existingQuestion.id));
console.log('已强制删除当天的问题记录', day);
}
}
try {
// 从questionLibrary中随机获取一条isUse为false的问题
const unusedQuestions = await db
.select()
.from(questionLibrary)
.where(eq(questionLibrary.isUse, false));
if (unusedQuestions.length === 0) {
ctx.throw(404, '没有未使用的问题');
return;
}
const randomIndex = Math.floor(Math.random() * unusedQuestions.length);
const selectedQuestion = unusedQuestions[randomIndex];
// 更新questionLibrary中的isUse和usedAt字段
await db
.update(questionLibrary)
.set({
isUse: true,
usedAt: day,
})
.where(eq(questionLibrary.id, selectedQuestion.id));
// 将选中的问题添加到dailyQuestions中
const insertedQuestions = await db
.insert(dailyQuestions)
.values({
id: generateId(),
qid: selectedQuestion.id,
title: selectedQuestion.title,
description: '',
tags: selectedQuestion.tags,
date: day,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}).returning();
ctx.body = { question: insertedQuestions[0], day: day };
} catch (error) {
console.error('随机获取问题失败:', error);
ctx.throw(500, '随机获取问题失败');
}
}).addTo(app);
app.route({
description: '获取今天的问题',
path: 'daily',
key: 'today'
}).define(async (ctx) => {
const db = getDb();
const day = getTodayDate();
try {
const todayQuestion = await db
.select()
.from(dailyQuestions)
.where(eq(dailyQuestions.date, day))
.limit(1)
.get();
if (!todayQuestion) {
const res = await ctx.call({
path: 'daily',
key: 'random',
});
if (res.code === 200) {
ctx.body = res.body;
return;
}
ctx.throw(500, '获取今天的问题失败');
}
ctx.body = {
question: todayQuestion,
day: day,
};
} catch (error) {
console.error('获取今天的问题失败:', error);
ctx.throw(500, '获取今天的问题失败');
}
}).addTo(app);

View File

@@ -0,0 +1,183 @@
import { generateId } from '../../module/utils.ts';
import { app } from '../../app.ts';
import { getDb } from '../../module/db.ts';
import { dailyQuestions } from '../../module/schema.ts';
import { eq } from 'drizzle-orm';
// 列出每日问题
app.route({
description: '列出每日问题',
path: 'daily',
key: 'list'
}).define(async (ctx) => {
const query = ctx.query;
const page = query.page ?? 1;
const pageSize = query.pageSize ?? 10;
const db = getDb();
try {
const offset = (page - 1) * pageSize;
const allResults = await db.select().from(dailyQuestions);
// Sort by createdAt in descending order (newest first)
const sortedResults = allResults.sort((a, b) =>
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
);
const list = sortedResults.slice(offset, offset + pageSize);
const totalResult = await db.select().from(dailyQuestions);
const total = totalResult.length;
ctx.body = {
list,
pagination: {
page,
pageSize,
total,
},
};
} catch (error) {
console.error('获取问题列表失败:', error);
ctx.throw(500, '获取问题列表失败');
}
}).addTo(app);
// 更新每日问题
app.route({
description: '更新每日问题',
path: 'daily',
key: 'update'
}).define(async (ctx) => {
const query = ctx.query;
const id = query.id;
const db = getDb();
const body = query;
try {
if (!id) {
// 新增数据
const newQuestion = await db
.insert(dailyQuestions)
.values({
id: generateId(),
title: body.title,
description: body.description,
tags: JSON.stringify(body.tags || []),
date: body.date || new Date().toISOString().split('T')[0],
qid: body.qid,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
})
.returning();
ctx.body = newQuestion[0];
} else {
// 更新数据
const updated = await db
.update(dailyQuestions)
.set({
title: body.title,
description: body.description,
tags: JSON.stringify(body.tags || []),
date: body.date,
qid: body.qid,
updatedAt: new Date().toISOString(),
})
.where(eq(dailyQuestions.id, id))
.returning();
if (updated.length === 0) {
ctx.throw(404, '数据未找到');
}
ctx.body = { success: true, data: updated[0] };
}
} catch (error) {
console.error('更新数据失败:', error);
ctx.throw(500, '更新数据失败');
}
}).addTo(app);
// 删除每日问题
app.route({
description: '删除每日问题',
path: 'daily',
key: 'delete'
}).define(async (ctx) => {
const query = ctx.query;
const id = query.id;
const db = getDb();
try {
if (!id) {
ctx.throw(400, '缺少ID参数');
}
const deleted = await db
.delete(dailyQuestions)
.where(eq(dailyQuestions.id, id))
.returning();
ctx.body = deleted;
} catch (error) {
console.error('删除数据失败:', error);
ctx.throw(500, '删除数据失败');
}
}).addTo(app);
// 获取每日问题详情
app.route({
description: '获取每日问题详情',
path: 'daily',
key: 'detail'
}).define(async (ctx) => {
const query = ctx.query;
const id = query.id;
const db = getDb();
try {
if (!id) {
ctx.throw(400, '缺少ID参数');
}
const result = await db
.select()
.from(dailyQuestions)
.where(eq(dailyQuestions.id, id));
if (result.length === 0) {
ctx.throw(404, '数据未找到');
}
ctx.body = result[0];
} catch (error) {
console.error('获取数据详情失败:', error);
ctx.throw(500, '获取数据详情失败');
}
}).addTo(app);
// 获取今日问题
app.route({
description: '获取今日问题',
path: 'daily',
key: 'today'
}).define(async (ctx) => {
const db = getDb();
try {
const allResults = await db.select().from(dailyQuestions);
// Sort by createdAt in descending order (newest first)
const sortedResults = allResults.sort((a, b) =>
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
);
const result = sortedResults.slice(0, 1);
if (result.length === 0) {
ctx.throw(404, '暂无今日问题');
}
ctx.body = result[0];
} catch (error) {
console.error('获取今日问题失败:', error);
ctx.throw(500, '获取今日问题失败');
}
}).addTo(app);

View File

@@ -0,0 +1,4 @@
import './daily/index.ts'
import './library/index.ts'
import './daily-task.ts'
import './library-task.ts'

View File

@@ -0,0 +1,23 @@
import { generateId, getTodayDate } from '../module/utils.ts';
import { app } from '../app.ts';
import { getDb } from '../module/db.ts';
import { dailyQuestions, questionLibrary } from '../module/schema.ts';
import { eq } from 'drizzle-orm';
app.route({
path: 'library',
key: 'setAllUnused',
description: '将所有问题设置为未使用'
}).define(async (ctx) => {
const db = getDb();
try {
await db
.update(questionLibrary)
.set({ isUse: false });
ctx.body = { message: '所有问题已设置为未使用' };
} catch (error) {
console.error('设置所有问题为未使用失败:', error);
ctx.throw(500, '设置所有问题为未使用失败');
}
}).addTo(app);

View File

@@ -0,0 +1,157 @@
import { generateId } from '../../module/utils.ts';
import { app } from '../../app.ts';
import { getDb } from '../../module/db.ts';
import { questionLibrary } from '../../module/schema.ts';
import { eq } from 'drizzle-orm';
// 列出问题库
app.route({
description: '列出问题库',
path: 'library',
key: 'list'
}).define(async (ctx) => {
const query = ctx.query;
const page = query.page ?? 1;
const pageSize = query.pageSize ?? 10;
const db = getDb();
try {
const offset = (page - 1) * pageSize;
const allResults = await db.select().from(questionLibrary);
// Sort by createdAt in descending order (newest first)
const sortedResults = allResults.sort((a, b) =>
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
);
const list = sortedResults.slice(offset, offset + pageSize);
const totalResult = await db.select().from(questionLibrary);
const total = totalResult.length;
ctx.body = {
list,
pagination: {
page,
pageSize,
total,
},
};
} catch (error) {
console.error('获取问题库列表失败:', error);
ctx.throw(500, '获取问题库列表失败');
}
}).addTo(app);
// 更新问题库
app.route({
description: '更新问题库',
path: 'library',
key: 'update'
}).define(async (ctx) => {
const query = ctx.query;
const id = query.id;
const db = getDb();
const body = query;
try {
if (!id) {
// 新增数据
const newQuestion = await db
.insert(questionLibrary)
.values({
id: generateId(),
title: body.title,
description: body.description,
tags: JSON.stringify(body.tags || []),
repeat: body.repeat ?? false,
isUse: body.isUse ?? false,
usedAt: body.usedAt,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
})
.returning();
ctx.body = newQuestion[0];
} else {
// 更新数据
const updated = await db
.update(questionLibrary)
.set({
title: body.title,
description: body.description,
tags: JSON.stringify(body.tags || []),
repeat: body.repeat,
isUse: body.isUse,
usedAt: body.usedAt,
updatedAt: new Date().toISOString(),
})
.where(eq(questionLibrary.id, id))
.returning();
if (updated.length === 0) {
ctx.throw(404, '数据未找到');
}
ctx.body = { success: true, data: updated[0] };
}
} catch (error) {
console.error('更新问题库数据失败:', error);
ctx.throw(500, '更新问题库数据失败');
}
}).addTo(app);
// 删除问题库
app.route({
description: '删除问题库',
path: 'library',
key: 'delete'
}).define(async (ctx) => {
const query = ctx.query;
const id = query.id;
const db = getDb();
try {
if (!id) {
ctx.throw(400, '缺少ID参数');
}
const deleted = await db
.delete(questionLibrary)
.where(eq(questionLibrary.id, id))
.returning();
ctx.body = deleted;
} catch (error) {
console.error('删除问题库数据失败:', error);
ctx.throw(500, '删除问题库数据失败');
}
}).addTo(app);
// 获取问题库详情
app.route({
description: '获取问题库详情',
path: 'library',
key: 'detail'
}).define(async (ctx) => {
const query = ctx.query;
const id = query.id;
const db = getDb();
try {
if (!id) {
ctx.throw(400, '缺少ID参数');
}
const result = await db
.select()
.from(questionLibrary)
.where(eq(questionLibrary.id, id));
if (result.length === 0) {
ctx.throw(404, '数据未找到');
}
ctx.body = result[0];
} catch (error) {
console.error('获取问题库详情失败:', error);
ctx.throw(500, '获取问题库详情失败');
}
}).addTo(app);