Refactor config management to use Drizzle ORM
- Replaced Sequelize with Drizzle ORM in config-related routes and models. - Updated database queries to use Drizzle's syntax for selecting, inserting, updating, and deleting configurations. - Removed the ConfigModel class and replaced it with direct database interactions. - Introduced nanoid for generating unique IDs for new configurations. - Added new routes for managing marks, including CRUD operations and versioning. - Implemented transaction handling for critical operations in the MarkModel. - Enhanced error handling and validation in routes.
This commit is contained in:
308
src/routes/mark/list.ts
Normal file
308
src/routes/mark/list.ts
Normal file
@@ -0,0 +1,308 @@
|
||||
import { eq, desc, and, like, or, count, sql } from 'drizzle-orm';
|
||||
import { app, db, schema } from '../../app.ts';
|
||||
import { MarkServices } from './services/mark.ts';
|
||||
import dayjs from 'dayjs';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'mark',
|
||||
key: 'list',
|
||||
description: 'mark list.',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
ctx.body = await MarkServices.getList({
|
||||
uid: tokenUser.id,
|
||||
query: ctx.query,
|
||||
queryType: 'simple',
|
||||
});
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'mark',
|
||||
key: 'getVersion',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const { id } = ctx.query;
|
||||
if (id) {
|
||||
const marks = await db.select().from(schema.microMark).where(eq(schema.microMark.id, id)).limit(1);
|
||||
const markModel = marks[0];
|
||||
if (!markModel) {
|
||||
ctx.throw(404, 'mark not found');
|
||||
}
|
||||
if (markModel.uid !== tokenUser.id) {
|
||||
ctx.throw(403, 'no permission');
|
||||
}
|
||||
ctx.body = {
|
||||
version: Number(markModel.version),
|
||||
updatedAt: markModel.updatedAt,
|
||||
createdAt: markModel.createdAt,
|
||||
id: markModel.id,
|
||||
};
|
||||
} else {
|
||||
ctx.throw(400, 'id is required');
|
||||
// const [markModel, created] = await MarkModel.findOrCreate({
|
||||
// where: {
|
||||
// uid: tokenUser.id,
|
||||
// puid: tokenUser.uid,
|
||||
// title: dayjs().format('YYYY-MM-DD'),
|
||||
// },
|
||||
// defaults: {
|
||||
// title: dayjs().format('YYYY-MM-DD'),
|
||||
// uid: tokenUser.id,
|
||||
// markType: 'wallnote',
|
||||
// tags: ['daily'],
|
||||
// },
|
||||
// });
|
||||
// ctx.body = {
|
||||
// version: Number(markModel.version),
|
||||
// updatedAt: markModel.updatedAt,
|
||||
// createdAt: markModel.createdAt,
|
||||
// id: markModel.id,
|
||||
// created: created,
|
||||
// };
|
||||
}
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'mark',
|
||||
key: 'get',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const { id } = ctx.query;
|
||||
if (id) {
|
||||
const marks = await db.select().from(schema.microMark).where(eq(schema.microMark.id, id)).limit(1);
|
||||
const markModel = marks[0];
|
||||
if (!markModel) {
|
||||
ctx.throw(404, 'mark not found');
|
||||
}
|
||||
if (markModel.uid !== tokenUser.id) {
|
||||
ctx.throw(403, 'no permission');
|
||||
}
|
||||
ctx.body = markModel;
|
||||
} else {
|
||||
ctx.throw(400, 'id is required');
|
||||
// id 不存在,获取当天的title为 日期的一条数据
|
||||
// const [markModel, created] = await MarkModel.findOrCreate({
|
||||
// where: {
|
||||
// uid: tokenUser.id,
|
||||
// puid: tokenUser.uid,
|
||||
// title: dayjs().format('YYYY-MM-DD'),
|
||||
// },
|
||||
// defaults: {
|
||||
// title: dayjs().format('YYYY-MM-DD'),
|
||||
// uid: tokenUser.id,
|
||||
// markType: 'wallnote',
|
||||
// tags: ['daily'],
|
||||
// uname: tokenUser.username,
|
||||
// puid: tokenUser.uid,
|
||||
// version: 1,
|
||||
// },
|
||||
// });
|
||||
// ctx.body = markModel;
|
||||
}
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'mark',
|
||||
key: 'update',
|
||||
middleware: ['auth'],
|
||||
isDebug: true,
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const { id, createdAt, updatedAt, uid: _, puid: _2, uname: _3, data, ...rest } = ctx.query.data || {};
|
||||
let markModel: any;
|
||||
if (id) {
|
||||
const marks = await db.select().from(schema.microMark).where(eq(schema.microMark.id, id)).limit(1);
|
||||
markModel = marks[0];
|
||||
if (!markModel) {
|
||||
ctx.throw(404, 'mark not found');
|
||||
}
|
||||
if (markModel.uid !== tokenUser.id) {
|
||||
ctx.throw(403, 'no permission');
|
||||
}
|
||||
const version = Number(markModel.version) + 1;
|
||||
const updated = await db.update(schema.microMark)
|
||||
.set({
|
||||
...rest,
|
||||
data: {
|
||||
...(markModel.data as any || {}),
|
||||
...data,
|
||||
},
|
||||
version,
|
||||
updatedAt: new Date().toISOString(),
|
||||
})
|
||||
.where(eq(schema.microMark.id, id))
|
||||
.returning();
|
||||
markModel = updated[0];
|
||||
} else {
|
||||
const inserted = await db.insert(schema.microMark).values({
|
||||
id: nanoid(),
|
||||
data: data || {},
|
||||
...rest,
|
||||
uname: tokenUser.username,
|
||||
uid: tokenUser.id,
|
||||
puid: tokenUser.uid,
|
||||
}).returning();
|
||||
markModel = inserted[0];
|
||||
}
|
||||
ctx.body = markModel;
|
||||
})
|
||||
.addTo(app);
|
||||
app
|
||||
.route({
|
||||
path: 'mark',
|
||||
key: 'updateNode',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const operate = ctx.query.operate || 'update';
|
||||
const { id, node } = ctx.query.data || {};
|
||||
const marks = await db.select().from(schema.microMark).where(eq(schema.microMark.id, id)).limit(1);
|
||||
const markModel = marks[0];
|
||||
if (!markModel) {
|
||||
ctx.throw(404, 'mark not found');
|
||||
}
|
||||
if (markModel.uid !== tokenUser.id) {
|
||||
ctx.throw(403, 'no permission');
|
||||
}
|
||||
// Update JSON node logic with Drizzle
|
||||
const currentData = markModel.data as any || {};
|
||||
const nodes = currentData.nodes || [];
|
||||
const nodeIndex = nodes.findIndex((n: any) => n.id === node.id);
|
||||
|
||||
let updatedNodes;
|
||||
if (operate === 'delete') {
|
||||
updatedNodes = nodes.filter((n: any) => n.id !== node.id);
|
||||
} else if (nodeIndex >= 0) {
|
||||
updatedNodes = [...nodes];
|
||||
updatedNodes[nodeIndex] = { ...nodes[nodeIndex], ...node };
|
||||
} else {
|
||||
updatedNodes = [...nodes, node];
|
||||
}
|
||||
|
||||
const version = Number(markModel.version) + 1;
|
||||
const updated = await db.update(schema.microMark)
|
||||
.set({
|
||||
data: { ...currentData, nodes: updatedNodes },
|
||||
version,
|
||||
updatedAt: new Date().toISOString(),
|
||||
})
|
||||
.where(eq(schema.microMark.id, id))
|
||||
.returning();
|
||||
ctx.body = updated[0];
|
||||
})
|
||||
.addTo(app);
|
||||
app
|
||||
.route({
|
||||
path: 'mark',
|
||||
key: 'updateNodes',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const { id, nodeOperateList } = ctx.query.data || {};
|
||||
const marks = await db.select().from(schema.microMark).where(eq(schema.microMark.id, id)).limit(1);
|
||||
const markModel = marks[0];
|
||||
if (!markModel) {
|
||||
ctx.throw(404, 'mark not found');
|
||||
}
|
||||
if (markModel.uid !== tokenUser.id) {
|
||||
ctx.throw(403, 'no permission');
|
||||
}
|
||||
if (!nodeOperateList || !Array.isArray(nodeOperateList) || nodeOperateList.length === 0) {
|
||||
ctx.throw(400, 'nodeOperateList is required');
|
||||
}
|
||||
if (nodeOperateList.some((item: any) => !item.node)) {
|
||||
ctx.throw(400, 'nodeOperateList node is required');
|
||||
}
|
||||
|
||||
// Update multiple JSON nodes logic with Drizzle
|
||||
const currentData = markModel.data as any || {};
|
||||
let nodes = currentData.nodes || [];
|
||||
|
||||
for (const item of nodeOperateList) {
|
||||
const { node, operate = 'update' } = item;
|
||||
const nodeIndex = nodes.findIndex((n: any) => n.id === node.id);
|
||||
|
||||
if (operate === 'delete') {
|
||||
nodes = nodes.filter((n: any) => n.id !== node.id);
|
||||
} else if (nodeIndex >= 0) {
|
||||
nodes[nodeIndex] = { ...nodes[nodeIndex], ...node };
|
||||
} else {
|
||||
nodes.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
const version = Number(markModel.version) + 1;
|
||||
const updated = await db.update(schema.microMark)
|
||||
.set({
|
||||
data: { ...currentData, nodes },
|
||||
version,
|
||||
updatedAt: new Date().toISOString(),
|
||||
})
|
||||
.where(eq(schema.microMark.id, id))
|
||||
.returning();
|
||||
ctx.body = updated[0];
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'mark',
|
||||
key: 'delete',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const { id } = ctx.query;
|
||||
const marks = await db.select().from(schema.microMark).where(eq(schema.microMark.id, id)).limit(1);
|
||||
const markModel = marks[0];
|
||||
if (!markModel) {
|
||||
ctx.throw(404, 'mark not found');
|
||||
}
|
||||
if (markModel.uid !== tokenUser.id) {
|
||||
ctx.throw(403, 'no permission');
|
||||
}
|
||||
await db.delete(schema.microMark).where(eq(schema.microMark.id, id));
|
||||
ctx.body = markModel;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({ path: 'mark', key: 'getMenu', description: '获取菜单', middleware: ['auth'] })
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const [rows, totalResult] = await Promise.all([
|
||||
db.select({
|
||||
id: schema.microMark.id,
|
||||
title: schema.microMark.title,
|
||||
summary: schema.microMark.summary,
|
||||
tags: schema.microMark.tags,
|
||||
thumbnail: schema.microMark.thumbnail,
|
||||
link: schema.microMark.link,
|
||||
createdAt: schema.microMark.createdAt,
|
||||
updatedAt: schema.microMark.updatedAt,
|
||||
}).from(schema.microMark).where(eq(schema.microMark.uid, tokenUser.id)),
|
||||
db.select({ count: count() }).from(schema.microMark).where(eq(schema.microMark.uid, tokenUser.id))
|
||||
]);
|
||||
ctx.body = {
|
||||
list: rows,
|
||||
total: totalResult[0]?.count || 0,
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
Reference in New Issue
Block a user