diff --git a/src/components/app/t-setCollect.vue b/src/components/app/t-setCollect.vue index ea84774f..7babcf3c 100644 --- a/src/components/app/t-setCollect.vue +++ b/src/components/app/t-setCollect.vue @@ -1,4 +1,5 @@ diff --git a/src/plugins/Sqlite/index.ts b/src/plugins/Sqlite/index.ts index 581bc7dc..143de4f9 100644 --- a/src/plugins/Sqlite/index.ts +++ b/src/plugins/Sqlite/index.ts @@ -13,7 +13,6 @@ import { insertAbyssData, insertAppData, insertGameAccountData, - insertPostCollectData, insertRecordData, insertRoleData, } from "./sql/insertData"; @@ -501,59 +500,11 @@ class Sqlite { const db = await this.getDB(); const sql = `SELECT name FROM sqlite_master - WHERE type='table' - AND name='${table}';`; + WHERE type = 'table' + AND name = '${table}';`; const res: Array<{ name: string }> = await db.select(sql); return res.length > 0; } - - /** - * @description 检测帖子是否已收藏 - * @since Beta v0.4.5 - * @param {string} postId 帖子 id - * @returns {Promise} 当该帖子被归到多个分类时,返回分类数量 - */ - async checkPostCollect(postId: string): Promise { - const db = await this.getDB(); - const sql = `SELECT collect - FROM UserCollection - WHERE postId = '${postId}';`; - const res: Array<{ collect: string }> = await db.select(sql); - if (res.length === 0) return false; - return res[0].collect; - } - - /** - * @description 收藏单个帖子 - * @since Beta v0.4.5 - * @param {TGApp.Plugins.Mys.Post.FullData} post 帖子 - * @param {Array} collect 分类 - * @param {string} uid 用户 uid - * @returns {Promise} - */ - async collectPost( - post: TGApp.Plugins.Mys.Post.FullData, - collect: string[], - uid?: string, - ): Promise { - const db = await this.getDB(); - const sql = insertPostCollectData(post, collect, uid); - await db.execute(sql); - } - - /** - * @description 取消收藏 - * @since Beta v0.4.5 - * @param {string} postId 帖子 id - * @returns {Promise} - */ - async cancelCollect(postId: string): Promise { - const db = await this.getDB(); - const sql = `DELETE - FROM UserCollection - WHERE postId = '${postId}';`; - await db.execute(sql); - } } const TGSqlite = new Sqlite(); diff --git a/src/plugins/Sqlite/modules/userCollect.ts b/src/plugins/Sqlite/modules/userCollect.ts new file mode 100644 index 00000000..79f2e47a --- /dev/null +++ b/src/plugins/Sqlite/modules/userCollect.ts @@ -0,0 +1,381 @@ +/** + * @file plugins/Sqlite/modules/userCollect.ts + * @description 用户收藏模块 + * @since Beta v0.4.5 + */ + +import type DataBase from "tauri-plugin-sql-api"; + +/** + * @description 获取单个帖子的收藏信息 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @param {string} postId 文章 id + * @return {Promise} 返回收藏信息 + */ +async function getCollectPost( + db: DataBase, + postId: string, +): Promise { + const sql = "SELECT * FROM UFMap WHERE postId = ?"; + const res: TGApp.Sqlite.UserCollection.UFMap[] = await db.select(sql, [postId]); + if (res.length > 0) { + return res; + } + const unclassifiedSql = "SELECT * FROM UFPost WHERE id = ?"; + const unclassifiedRes: TGApp.Sqlite.UserCollection.UFPost[] = await db.select(unclassifiedSql, [ + postId, + ]); + return unclassifiedRes.length > 0; +} + +/** + * @description 获取收藏合集列表 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @return {Promise} 返回收藏合集列表 + */ +async function getCollectList(db: DataBase): Promise { + const sql = "SELECT * FROM UFCollection"; + return await db.select(sql); +} + +/** + * @description 获取收藏合集中的帖子列表 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @param {string} collection 收藏合集标题 + * @return {Promise} 返回收藏合集中的帖子列表 + */ +async function getCollectPostList( + db: DataBase, + collection: string, +): Promise { + const sql = "SELECT * FROM UFMap WHERE collection = ?"; + const res: TGApp.Sqlite.UserCollection.UFMap[] = await db.select(sql, [collection]); + const postList: TGApp.Sqlite.UserCollection.UFPost[] = []; + for (let i = 0; i < res.length; i++) { + const postSql = "SELECT * FROM UFPost WHERE id = ?"; + const postRes: TGApp.Sqlite.UserCollection.UFPost[] = await db.select(postSql, [res[i].postId]); + postList.push(postRes[0]); + } + return postList; +} + +/** + * @description 获取未分类的收藏帖子列表 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @return {Promise} 返回未分类的收藏帖子列表 + */ +async function getUnCollectPostList(db: DataBase): Promise { + const sql = "SELECT * FROM UFPost WHERE id NOT IN (SELECT postId FROM UFMap)"; + return await db.select(sql); +} + +/** + * @description 新建收藏合集 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @param {string} title 收藏合集标题 + * @param {string} desc 收藏合集描述 + * @return {Promise} 返回收藏合集 id + */ +async function createCollect(db: DataBase, title: string, desc: string): Promise { + if (title === "未分类" || title === "") return false; + const sql = "SELECT id FROM UFCollection WHERE title = ?"; + const res: Array<{ id: number }> = await db.select(sql, [title]); + if (res.length > 0) { + return false; + } + const insertSql = "INSERT INTO UFCollection (title, desc,updated) VALUES (?, ?,?)"; + await db.execute(insertSql, [title, desc, new Date().getTime()]); + return true; +} + +/** + * @description 删除收藏合集 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @param {string} title 收藏合集标题 + * @return {Promise} 返回是否删除成功 + */ +async function deleteCollect(db: DataBase, title: string): Promise { + const sql = "SELECT id FROM UFCollection WHERE title = ?"; + const res: Array<{ id: number }> = await db.select(sql, [title]); + if (res.length === 0) { + return false; + } + const deleteSql = "DELETE FROM UFCollection WHERE title = ?"; + await db.execute(deleteSql, [title]); + const deleteRefSql = "DELETE FROM UFMap WHERE collectionId = ?"; + await db.execute(deleteRefSql, [res[0].id]); + return true; +} + +/** + * @description 更新收藏合集信息,标题/描述 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @param {string} title 收藏合集标题 + * @param {string} newTitle 新标题 + * @param {string} newDesc 新描述 + * @return {Promise} 返回是否更新成功 + */ +async function updateCollect( + db: DataBase, + title: string, + newTitle: string, + newDesc: string, +): Promise { + const sql = "SELECT id FROM UFCollection WHERE title = ?"; + const res: Array<{ id: number }> = await db.select(sql, [title]); + if (res.length === 0) { + return false; + } + const updateSql = "UPDATE UFCollection SET title = ?, desc = ?, updated = ? WHERE id = ?"; + await db.execute(updateSql, [newTitle, newDesc, new Date().getTime(), res[0].id]); + const updateRefSql = "UPDATE UFMap SET collection = ?,desc=?,updated=? WHERE collectionId = ?"; + await db.execute(updateRefSql, [newTitle, newDesc, new Date().getTime(), res[0].id]); + return true; +} + +/** + * @description 添加收藏 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @param {string} postId 文章 id + * @param {TGApp.Plugins.Mys.Post.FullData} post 文章信息 + * @param {string} collection 收藏合集标题,可能为 undefined + * @param {boolean} recursive 是否递归添加 + * @return {Promise} 返回是否添加成功 + */ +async function addCollect( + db: DataBase, + postId: string, + post: TGApp.Plugins.Mys.Post.FullData, + collection: string | undefined = undefined, + recursive: boolean = false, +): Promise { + const sql = "SELECT id FROM UFPost WHERE id = ?"; + const res: Array<{ id: number }> = await db.select(sql, [postId]); + if (res.length > 0) { + return false; + } + const insertSql = "INSERT INTO UFPost (id, title, content, updated) VALUES (?, ?, ?, ?)"; + await db.execute(insertSql, [ + postId, + post.post.subject, + JSON.stringify(post), + new Date().getTime(), + ]); + if (collection !== undefined) { + const collectionSql = "SELECT * FROM UFCollection WHERE title = ?"; + let collectionRes: TGApp.Sqlite.UserCollection.UFCollection[] = await db.select(collectionSql, [ + collection, + ]); + if (collectionRes.length === 0 || collectionRes.length > 1) { + if (!recursive) { + return false; + } + const createCollectionRes = await createCollect(db, collection, collection); + if (!createCollectionRes) { + return false; + } + collectionRes = await db.select(collectionSql, [collection]); + } + const insertMapSql = + "INSERT INTO UFMap (postId, collectionId,post, collection, desc, updated) VALUES (?, ?, ?, ?, ?, ?)"; + await db.execute(insertMapSql, [ + postId, + collectionRes[0].id, + post.post.subject, + collection, + collectionRes[0].desc, + new Date().getTime(), + ]); + } + return true; +} + +/** + * @description 删除合集中的收藏 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @param {string} postId 文章 id + * @param {string} collection 收藏合集标题 + * @return {Promise} 返回是否删除成功 + */ +async function deleteCollectPost( + db: DataBase, + postId: string, + collection: string, +): Promise { + const sql = "SELECT id FROM UFCollection WHERE title = ?"; + const res: Array<{ id: number }> = await db.select(sql, [collection]); + if (res.length === 0) { + return false; + } + const deleteSql = "DELETE FROM UFMap WHERE postId = ? AND collectionId = ?"; + await db.execute(deleteSql, [postId, res[0].id]); + return true; +} + +/** + * @description 删除某个帖子的收藏,可选是否强制删除 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @param {string} postId 文章 id + * @param {boolean} force 是否强制删除 + * @return {Promise} 返回是否删除成功 + */ +async function deletePostCollect( + db: DataBase, + postId: string, + force: boolean = false, +): Promise { + const sql = "SELECT id FROM UFPost WHERE id = ?"; + const res: Array<{ id: number }> = await db.select(sql, [postId]); + if (res.length === 0) { + return false; + } + const selectSql = "SELECT * FROM UFMap WHERE postId = ?"; + const selectRes: TGApp.Sqlite.UserCollection.UFMap[] = await db.select(selectSql, [postId]); + if (selectRes.length === 0 && !force) { + return false; + } + const deleteSql = "DELETE FROM UFMap WHERE postId = ?"; + await db.execute(deleteSql, [postId]); + if (force) { + const deletePostSql = "DELETE FROM UFPost WHERE id = ?"; + await db.execute(deletePostSql, [postId]); + } + return true; +} + +/** + * @description 修改单个帖子的收藏合集 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @param {string} postId 文章 id + * @param {string[]} collections 收藏合集标题 + * @return {Promise} 返回是否修改成功 + */ +async function updateCollectPost( + db: DataBase, + postId: string, + collections: string[], +): Promise { + const sql = "SELECT id,title FROM UFPost WHERE id = ?"; + const res: Array<{ id: number; title: string }> = await db.select(sql, [postId]); + if (res.length === 0) { + return false; + } + const deleteSql = "DELETE FROM UFMap WHERE postId = ?"; + await db.execute(deleteSql, [postId]); + for (let i = 0; i < collections.length; i++) { + const collectionSql = "SELECT * FROM UFCollection WHERE title = ?"; + const collectionRes: TGApp.Sqlite.UserCollection.UFCollection[] = await db.select( + collectionSql, + [collections[i]], + ); + if (collectionRes.length === 0) { + return false; + } + const insertSql = + "INSERT INTO UFMap (postId, collectionId,post, collection, desc, updated) VALUES (?, ?, ?, ?, ?, ?)"; + await db.execute(insertSql, [ + postId, + collectionRes[0].id, + res[0].title, + collections[i], + collectionRes[0].desc, + new Date().getTime(), + ]); + } + return true; +} + +/** + * @description 批量修改帖子的收藏合集 + * @since Beta v0.4.5 + * @param {DataBase} db 数据库 + * @param {string[]} postIds 文章 id + * @param {string} collection 收藏合集标题 + * @param {string} oldCollection 旧的收藏合集标题 + * @return {Promise} 返回是否修改成功 + */ +async function updateCollectPosts( + db: DataBase, + postIds: string[], + collection: string, + oldCollection: string | undefined, +): Promise { + const collectionSql = "SELECT * FROM UFCollection WHERE title = ?"; + const collectionRes: TGApp.Sqlite.UserCollection.UFCollection[] = await db.select(collectionSql, [ + collection, + ]); + if (collectionRes.length === 0) { + return false; + } + let oldCollectionInfo: TGApp.Sqlite.UserCollection.UFCollection | undefined; + if (oldCollection !== undefined) { + const oldCollectionRes: TGApp.Sqlite.UserCollection.UFCollection[] = await db.select( + collectionSql, + [oldCollection], + ); + if (oldCollectionRes.length === 0) { + return false; + } + oldCollectionInfo = oldCollectionRes[0]; + } + for (let i = 0; i < postIds.length; i++) { + const postSql = "SELECT id,title FROM UFPost WHERE id = ?"; + const postRes: Array<{ id: number; title: string }> = await db.select(postSql, [postIds[i]]); + if (postRes.length === 0) { + return false; + } + if (oldCollectionInfo !== undefined) { + const updateSql = + "UPDATE UFMap SET collectionId = ?,post=?,collection=?,desc=?,updated=? WHERE postId = ? AND collectionId = ?"; + await db.execute(updateSql, [ + collectionRes[0].id, + postRes[0].title, + collection, + collectionRes[0].desc, + new Date().getTime(), + postIds[i], + oldCollectionInfo.id, + ]); + continue; + } + const insertSql = + "INSERT INTO UFMap (postId, collectionId,post, collection, desc, updated) VALUES (?, ?, ?, ?, ?, ?)"; + await db.execute(insertSql, [ + postIds[i], + collectionRes[0].id, + postRes[0].title, + collection, + collectionRes[0].desc, + new Date().getTime(), + ]); + } + return true; +} + +const TSUserCollection = { + getCollectPost, + getCollectList, + getCollectPostList, + getUnCollectPostList, + createCollect, + deleteCollect, + updateCollect, + addCollect, + deleteCollectPost, + deletePostCollect, + updateCollectPost, + updateCollectPosts, +}; + +export default TSUserCollection; diff --git a/src/plugins/Sqlite/sql/createTable.sql b/src/plugins/Sqlite/sql/createTable.sql index a0d5b634..fcf6221e 100644 --- a/src/plugins/Sqlite/sql/createTable.sql +++ b/src/plugins/Sqlite/sql/createTable.sql @@ -1,7 +1,6 @@ -- @file plugins Sqlite sql createTable.sql -- @brief sqlite数据库创建表语句 --- @author BTMuli --- @since Alpha v0.2.3 +-- @since Beta v0.4.5 -- @brief 创建成就数据表 create table if not exists Achievements @@ -151,3 +150,35 @@ create table if not exists GachaRecords count text, updated text ); + +-- @brief 创建用户帖子收藏 +create table if not exists UFPost +( + id text not null, -- 帖子ID + title text not null, -- 帖子标题 + content text, -- 帖子内容 + updated text not null, -- 收藏时间 + primary key (id) +); + +-- @brief 创建用户帖子合集 +create table if not exists UFCollection +( + + id integer primary key autoincrement,-- 自增合集ID + title text not null, -- 合集标题 + desc text, -- 合集描述 + updated text not null -- 创建时间 +); + +-- @brief 创建用户帖子收藏-合集对照表 +create table if not exists UFMap +( + postId text not null, -- 帖子ID + collectionId integer not null, -- 合集ID + post text not null, -- 帖子标题 + collection text not null, -- 合集标题 + desc text, -- 合集描述 + updated text not null, -- 收藏时间 + primary key (postId, collectionId) +); diff --git a/src/types/Sqlite/Collection.d.ts b/src/types/Sqlite/Collection.d.ts index 2f3bc949..a59a9f8c 100644 --- a/src/types/Sqlite/Collection.d.ts +++ b/src/types/Sqlite/Collection.d.ts @@ -12,30 +12,58 @@ */ declare namespace TGApp.Sqlite.UserCollection { /** - * @description 数据库-用户收藏表 + * @description 数据库-用户收藏帖子表 * @since Beta v0.4.5 - * @interface SingleTable - * @property {string} postId - 帖子 ID + * @interface UFPost + * @property {string} id - 帖子 ID * @property {string} title - 标题 + * @description 反序列化后是 TGApp.Plugins.Mys.Post.FullData * @property {string} content - 内容 - * @property {string} collect - 合集 - * @property {string} uid - 用户 UID * @property {string} updated - 更新时间 - * @return SingleTable + * @return UFPost */ - interface SingleTable { - postId: string; + interface UFPost { + id: string; title: string; content: string; - collect: string; - uid: string; updated: string; } /** - * @description 渲染卡片 + * @description 数据库-用户收藏合集表 + * @since Beta v0.4.5 + * @interface UFCollection + * @property {string} id - 合集 ID + * @property {string} title - 标题 + * @property {string} desc - 描述 + * @property {string} updated - 更新时间 + * @return UFCollection + */ + interface UFCollection { + id: string; + title: string; + desc: string; + updated: string; + } + + /** + * @description 数据库-用户收藏帖子合集关联表 * @since Beta v0.4.5 - * @interface RenderCard + * @interface UFMap + * @property {string} postId - 帖子 ID + * @property {string} collectionId - 合集 ID + * @property {string} post - 帖子标题 + * @property {string} collection - 合集标题 + * @property {string} desc - 合集描述 + * @property {string} updated - 更新时间 + * @return UFMap */ - type RenderCard = TGApp.Plugins.Mys.Forum.RenderCard; + interface UFMap { + postId: string; + collectionId: string; + post: string; + collection: string; + desc: string; + updated: string; + } } diff --git a/src/views/t-lottery.vue b/src/views/t-lottery.vue index 088f57d2..5deaa365 100644 --- a/src/views/t-lottery.vue +++ b/src/views/t-lottery.vue @@ -1,3 +1,4 @@ +