import db from "../index.js" class BookmarkModel { static async findAllByUser(userId) { return db("bookmarks").where("user_id", userId).orderBy("id", "desc") } static async findById(id) { return db("bookmarks").where("id", id).first() } static async create(data) { const userId = data.user_id const url = typeof data.url === "string" ? data.url.trim() : data.url if (userId != null && url) { const exists = await db("bookmarks").where({ user_id: userId, url }).first() if (exists) { throw new Error("该用户下已存在相同 URL 的书签") } } return db("bookmarks").insert({ ...data, url, updated_at: db.fn.now(), }).returning("*") } static async update(id, data) { // 若更新后 user_id 与 url 同时存在,则做排他性查重(排除自身) const current = await db("bookmarks").where("id", id).first() if (!current) return [] const nextUserId = data.user_id != null ? data.user_id : current.user_id const nextUrlRaw = data.url != null ? data.url : current.url const nextUrl = typeof nextUrlRaw === "string" ? nextUrlRaw.trim() : nextUrlRaw if (nextUserId != null && nextUrl) { const exists = await db("bookmarks") .where({ user_id: nextUserId, url: nextUrl }) .andWhereNot({ id }) .first() if (exists) { throw new Error("该用户下已存在相同 URL 的书签") } } return db("bookmarks").where("id", id).update({ ...data, url: data.url != null ? nextUrl : data.url, updated_at: db.fn.now(), }).returning("*") } static async delete(id) { return db("bookmarks").where("id", id).del() } static async findByUserAndUrl(userId, url) { return db("bookmarks").where({ user_id: userId, url }).first() } } export default BookmarkModel export { BookmarkModel }