Files
score-backend/routes/media.ts
ethan.chen 2b5b2f1d97 迁移数据库从 SQLite 到 PostgreSQL
- 更新 deno.json 添加 postgres 依赖
- 重构 db/index.ts 使用 PostgreSQL 连接和适配器
- 更新所有路由文件支持异步数据库操作
- 将 SQLite 语法转换为 PostgreSQL 语法
- 添加数据库迁移文档和 schema 文件
2026-01-08 14:26:27 +08:00

192 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;