- 更新 deno.json 添加 postgres 依赖 - 重构 db/index.ts 使用 PostgreSQL 连接和适配器 - 更新所有路由文件支持异步数据库操作 - 将 SQLite 语法转换为 PostgreSQL 语法 - 添加数据库迁移文档和 schema 文件
192 lines
5.0 KiB
TypeScript
192 lines
5.0 KiB
TypeScript
import { Hono } from "hono";
|
||
import { db } from "../db/index.ts";
|
||
import type { JwtVariables } from "hono/jwt";
|
||
import { authMiddleware } from "../auth.ts";
|
||
|
||
const media = new Hono<{ Variables: JwtVariables }>();
|
||
|
||
// 查询满分(10分)作品,不需要JWT验证
|
||
media.get("/perfect", async (c) => {
|
||
try {
|
||
const perfectList = await db
|
||
.prepare("SELECT * FROM media WHERE rating = 10")
|
||
.all();
|
||
return c.json({
|
||
code: 0,
|
||
data: perfectList,
|
||
message: "Success",
|
||
});
|
||
} catch (error: any) {
|
||
return c.json({ code: 1, data: {}, message: error.message }, 500);
|
||
}
|
||
});
|
||
|
||
media.use("/*", authMiddleware);
|
||
|
||
// 获取所有媒体记录
|
||
media.get("/list", async (c) => {
|
||
try {
|
||
const mediaList = await db.prepare("SELECT * FROM media").all();
|
||
return c.json({
|
||
code: 0,
|
||
data: mediaList,
|
||
message: "Success",
|
||
});
|
||
} catch (error: any) {
|
||
return c.json({ code: 1, data: {}, message: error.message }, 500);
|
||
}
|
||
});
|
||
|
||
// 创建新的媒体记录
|
||
media.post("/create", async (c) => {
|
||
try {
|
||
const data = await c.req.json();
|
||
const { title, type, rating, notes, platform, date } = data;
|
||
|
||
const result = await db
|
||
.prepare(
|
||
`
|
||
INSERT INTO media (title, type, rating, notes, platform, date, created_at, updated_at)
|
||
VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW())
|
||
RETURNING id
|
||
`
|
||
)
|
||
.run(title, type, rating, notes, platform, date);
|
||
|
||
const newMedia = await db
|
||
.prepare("SELECT * FROM media WHERE id = ?")
|
||
.get(result.lastInsertRowid);
|
||
|
||
return c.json(
|
||
{
|
||
code: 0,
|
||
data: newMedia,
|
||
message: "Created successfully",
|
||
},
|
||
201
|
||
);
|
||
} catch (error: any) {
|
||
return c.json({ code: 2, data: {}, message: error.message }, 500);
|
||
}
|
||
});
|
||
|
||
// 更新媒体记录
|
||
media.put("/updateById/:id", async (c) => {
|
||
try {
|
||
const id = c.req.param("id");
|
||
const data = await c.req.json();
|
||
const { title, type, rating, notes, platform, date } = data;
|
||
|
||
await db
|
||
.prepare(
|
||
`
|
||
UPDATE media
|
||
SET title = ?, type = ?, rating = ?, notes = ?, platform = ?, date = ?, updated_at = NOW()
|
||
WHERE id = ?
|
||
`
|
||
)
|
||
.run(title, type, rating, notes, platform, date, id);
|
||
|
||
const updatedMedia = await db
|
||
.prepare("SELECT * FROM media WHERE id = ?")
|
||
.get(id);
|
||
|
||
if (!updatedMedia) {
|
||
return c.json({ code: 1, data: {}, message: "Media not found" }, 404);
|
||
}
|
||
|
||
return c.json({
|
||
code: 0,
|
||
data: updatedMedia,
|
||
message: "Updated successfully",
|
||
});
|
||
} catch (error: any) {
|
||
return c.json({ code: 2, data: {}, message: error.message }, 500);
|
||
}
|
||
});
|
||
|
||
// 删除媒体记录
|
||
media.delete("/deleteById/:id", async (c) => {
|
||
try {
|
||
const id = c.req.param("id");
|
||
await db.prepare("DELETE FROM media WHERE id = ?").run(id);
|
||
return c.json({ code: 0, data: {}, message: "Deleted successfully" });
|
||
} catch (error: any) {
|
||
return c.json({ code: 2, data: {}, message: error.message }, 500);
|
||
}
|
||
});
|
||
|
||
// 分页查询媒体记录
|
||
media.get("/page", async (c) => {
|
||
try {
|
||
const type = c.req.query("type");
|
||
const currentPage = parseInt(c.req.query("currentPage") || "1");
|
||
const pageSize = parseInt(c.req.query("pageSize") || "10");
|
||
const title = c.req.query("title") || "";
|
||
const startDate = c.req.query("startDate");
|
||
const endDate = c.req.query("endDate");
|
||
const sortBy = c.req.query("sortBy") || "date";
|
||
const sortType = c.req.query("sortType") || "desc";
|
||
|
||
if (!type) {
|
||
return c.json({ code: 1, data: {}, message: "Type is required" }, 400);
|
||
}
|
||
|
||
let query = "SELECT * FROM media WHERE type = ?";
|
||
const params = [type];
|
||
|
||
if (title) {
|
||
query += " AND title LIKE ?";
|
||
params.push(`%${title}%`);
|
||
}
|
||
if (startDate) {
|
||
query += " AND date >= ?";
|
||
params.push(startDate);
|
||
}
|
||
if (endDate) {
|
||
query += " AND date <= ?";
|
||
params.push(endDate);
|
||
}
|
||
|
||
// 添加排序
|
||
if (sortBy === "date") {
|
||
query += ` ORDER BY date ${sortType.toUpperCase()}`;
|
||
} else if (sortBy === "score") {
|
||
query += ` ORDER BY rating ${sortType.toUpperCase()}`;
|
||
}
|
||
|
||
// 添加分页
|
||
const offset = (currentPage - 1) * pageSize;
|
||
query += " LIMIT ? OFFSET ?";
|
||
params.push(pageSize.toString(), offset.toString());
|
||
|
||
// 获取总数
|
||
const countQuery = query
|
||
.replace("SELECT *", "SELECT COUNT(*) as total")
|
||
.replace(/ORDER BY.*$/, "") // 移除 ORDER BY 子句
|
||
.replace(/LIMIT.*$/, ""); // 移除 LIMIT 和 OFFSET 子句
|
||
const totalResult = await db
|
||
.prepare(countQuery)
|
||
.get(...params.slice(0, -2));
|
||
const total = totalResult?.total || 0;
|
||
|
||
// 获取分页数据
|
||
const mediaList = await db.prepare(query).all(...params);
|
||
|
||
return c.json({
|
||
code: 0,
|
||
data: {
|
||
list: mediaList,
|
||
total,
|
||
currentPage,
|
||
pageSize,
|
||
},
|
||
message: "Success",
|
||
});
|
||
} catch (error: any) {
|
||
return c.json({ code: 1, data: {}, message: error.message }, 500);
|
||
}
|
||
});
|
||
|
||
export default media;
|