帖子收藏 #100

This commit is contained in:
目棃
2024-03-19 21:51:57 +08:00
parent c5587211fd
commit 8996c1bce1
12 changed files with 602 additions and 19 deletions

View File

@@ -0,0 +1,103 @@
<template>
<div class="collect-box" data-html2canvas-ignore>
<div class="collect-btn" @click="switchCollect()" :title="isCollected ? '取消收藏' : '收藏'">
<v-icon :color="isCollected ? 'yellow' : 'white'">
{{ isCollected ? "mdi-star" : "mdi-star-outline" }}
</v-icon>
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from "vue";
import TGSqlite from "../../plugins/Sqlite";
import showConfirm from "../func/confirm";
import showSnackbar from "../func/snackbar";
const isCollected = ref(false);
const collect = ref<Array<string>>([]);
interface TSetCollectProps {
modelValue: number;
data: TGApp.Plugins.Mys.Post.FullData | undefined;
}
const props = defineProps<TSetCollectProps>();
onMounted(async () => await getCollect());
async function getCollect(): Promise<void> {
const res = await TGSqlite.checkPostCollect(props.modelValue.toString());
if (res !== false) {
isCollected.value = true;
try {
collect.value = JSON.parse(res);
console.warn(collect.value);
} catch (e) {
showSnackbar({
text: `收藏数据解析失败: ${res}`,
color: "error",
});
}
}
}
async function switchCollect(): Promise<void> {
if (isCollected.value === false) {
collect.value = ["default"];
if (props.data === undefined) {
showSnackbar({
text: "获取帖子数据失败",
color: "error",
});
return;
}
await TGSqlite.collectPost(props.data, collect.value);
isCollected.value = true;
showSnackbar({
text: "收藏成功",
color: "success",
});
return;
}
if (collect.value.length > 1) {
const check = await showConfirm({
title: "确定取消收藏?",
text: "该帖子有多个收藏分类,是否全部取消?",
});
if (!check) {
return;
}
}
await TGSqlite.cancelCollect(props.modelValue.toString());
isCollected.value = false;
showSnackbar({
text: "取消收藏成功",
color: "success",
});
}
</script>
<style lang="css" scoped>
.collect-box {
position: absolute;
top: 80px;
right: 20px;
border: 2px solid var(--common-shadow-8);
border-radius: 50%;
cursor: pointer;
}
.collect-box:hover {
opacity: 0.8;
}
.collect-btn {
display: flex;
width: 24px;
height: 24px;
align-items: center;
justify-content: center;
padding-right: 2px;
margin: 5px;
}
</style>

View File

@@ -205,6 +205,11 @@
<img src="/platforms/mhy/mys.webp" alt="酒馆" class="side-icon-menu" /> <img src="/platforms/mhy/mys.webp" alt="酒馆" class="side-icon-menu" />
</template> </template>
</v-list-item> </v-list-item>
<v-list-item class="side-item-menu" title="收藏" :link="true" href="/collection">
<template #prepend>
<img src="/source/UI/posts.png" alt="collect" class="side-icon-menu" />
</template>
</v-list-item>
<v-list-item <v-list-item
class="side-item-menu" class="side-item-menu"
title="登录" title="登录"

View File

@@ -0,0 +1,255 @@
<template>
<ToLoading v-model="loading" :title="loadingTitle" :subtitle="loadingSub" />
<div class="pc-container">
<div class="pc-top">
<v-select
v-model="curSelect"
class="pc-select"
:items="Array.from(selects)"
variant="outlined"
label="合集"
/>
<v-btn rounded class="pc-btn" prepend-icon="mdi-refresh" @click="freshUser"
>获取用户收藏</v-btn
>
<!-- todo 编辑收藏 -->
<v-pagination class="pc-page" v-model="page" :length="length" />
</div>
<div class="pc-posts">
<div v-for="item in getPageItems()" :key="item.post.post_id">
<TPostCard :model-value="item" />
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { storeToRefs } from "pinia";
import { onMounted, ref, watch } from "vue";
import showSnackbar from "../../components/func/snackbar";
import TPostCard from "../../components/main/t-postcard.vue";
import ToLoading from "../../components/overlay/to-loading.vue";
import TGSqlite from "../../plugins/Sqlite";
import { insertPostCollectData } from "../../plugins/Sqlite/sql/insertData";
import { useUserStore } from "../../store/modules/user";
import TGLogger from "../../utils/TGLogger";
import TGRequest from "../../web/request/TGRequest";
const loading = ref(false);
const loadingTitle = ref("加载中...");
const loadingSub = ref("");
const userStore = storeToRefs(useUserStore());
const collections = ref<TGApp.Sqlite.UserCollection.SingleTable[]>([]);
const selected = ref<TGApp.Sqlite.UserCollection.SingleTable[]>([]);
const selects = ref<Set<string>>(new Set());
const curSelect = ref<string>("default");
const page = ref(1);
const length = ref(5);
onMounted(async () => {
loadingTitle.value = "检测 UserCollection 表...";
loading.value = true;
const check = await TGSqlite.checkTableExist("UserCollection");
if (!check) {
loadingTitle.value = "创建 UserCollection 表...";
await createCollectTable();
}
loadingTitle.value = "获取收藏帖子...";
await getCollect();
filterBySelect();
loading.value = false;
});
async function createCollectTable(): Promise<void> {
const db = await TGSqlite.getDB();
const sql = `
create table if not exists UserCollection
(
postId text not null, -- 帖子ID
title text not null, -- 帖子标题
content text, -- 帖子内容
collect text, -- 合集标题
uid text, -- 用户ID
updated text not null, -- 收藏时间
primary key (postId)
);
`;
await db.execute(sql);
showSnackbar({
text: "创建 UserCollection 表成功",
color: "success",
});
}
// 根据合集筛选
function filterBySelect(): void {
selected.value = collections.value.filter((item) => item.collect.includes(curSelect.value));
length.value = Math.ceil(selected.value.length / 12);
showSnackbar({
text: `筛选合集 ${curSelect.value} 成功,共 ${selected.value.length} 条数据`,
color: "success",
});
}
// 获取当前页的帖子
function getPageItems(): TGApp.Plugins.Mys.Post.FullData[] {
const posts = selected.value.slice((page.value - 1) * 12, page.value * 12);
const card: TGApp.Plugins.Mys.Post.FullData[] = [];
for (const post of posts) {
try {
card.push(JSON.parse(post.content));
} catch (e) {
TGLogger.Error("[PostCollect] getPageItems");
TGLogger.Error(<string>e);
}
}
return card;
}
watch(curSelect, () => {
filterBySelect();
});
async function getCollect(): Promise<void> {
const db = await TGSqlite.getDB();
const sql = "SELECT * FROM UserCollection";
collections.value = await db.select(sql);
for (const item of collections.value) {
try {
const parse: string[] = JSON.parse(item.collect);
for (const p of parse) {
selects.value.add(p);
}
} catch (e) {
await TGLogger.Error("[PostCollect] getCollect");
await TGLogger.Error(<string>e);
}
}
}
async function freshUser(): Promise<void> {
if (!userStore.cookie.value) {
showSnackbar({
text: "请先登录",
color: "error",
});
return;
}
const cookie = {
cookie_token: userStore.cookie.value.cookie_token,
account_id: userStore.cookie.value.account_id,
};
loadingTitle.value = "获取用户收藏...";
loading.value = true;
let res = await TGRequest.User.byCookie.getCollect(cookie);
let is_last = false;
while (!is_last) {
if ("retcode" in res) {
showSnackbar({
text: `[${res.retcode}] ${res.message}`,
color: "error",
});
return;
}
let posts = res.list;
loadingTitle.value = `合并收藏帖子 [offset]${res.next_offset}...`;
await mergePosts(posts);
if (res.is_last) {
is_last = true;
} else {
loadingTitle.value = "获取用户收藏...";
loadingSub.value = `[offset]${res.next_offset} [is_last]${res.is_last}`;
res = await TGRequest.User.byCookie.getCollect(cookie, res.next_offset);
}
}
loading.value = false;
showSnackbar({
text: "获取用户收藏成功",
color: "success",
});
window.location.reload();
}
// 合并收藏帖子
async function mergePosts(posts: TGApp.Plugins.Mys.Post.FullData[]): Promise<void> {
const db = await TGSqlite.getDB();
const collectTitle = `${userStore.briefInfo.value.nickname} 的收藏`;
for (const post of posts) {
loadingSub.value = `合并帖子 ${post.post.post_id} ${post.post.subject}`;
const postId = post.post.post_id;
const collect = await TGSqlite.checkPostCollect(postId.toString());
let collects = new Set<string>();
if (collect !== false) {
try {
const parse: string[] = JSON.parse(collect);
for (const item of parse) {
collects.add(item);
}
} catch (e) {
collects.add("default");
showSnackbar({
text: `收藏数据解析失败: ${collect}`,
color: "error",
});
await new Promise((resolve) => setTimeout(resolve, 1000));
}
collects.add(collectTitle);
}
const sql = insertPostCollectData(post, Array.from(collects), userStore.briefInfo.value.uid);
await db.execute(sql);
}
}
</script>
<style lang="css" scoped>
.pc-container {
position: relative;
display: flex;
height: 100%;
flex-direction: column;
align-items: center;
row-gap: 10px;
}
.pc-top {
position: relative;
display: flex;
width: 100%;
height: 60px;
align-items: center;
justify-content: flex-start;
column-gap: 10px;
}
.pc-select {
max-width: 400px;
max-height: 100%;
}
.pc-page {
margin-left: auto;
}
/* stylelint-disable-next-line selector-class-pattern */
.pc-page > .v-pagination__list {
justify-content: flex-end;
}
.pc-btn {
height: 40px;
background: var(--btn-bg-1);
color: var(--btn-text-1);
font-family: var(--font-title);
}
.dark .pc-btn {
border: 1px solid var(--common-shadow-2);
}
.pc-posts {
display: grid;
font-family: var(--font-title);
grid-gap: 10px;
grid-template-columns: repeat(4, minmax(320px, 1fr));
}
</style>

View File

@@ -1,19 +1,19 @@
/** /**
* @file plugins/Sqlite/index.ts * @file plugins/Sqlite/index.ts
* @description Sqlite 数据库操作类 * @description Sqlite 数据库操作类
* @since Beta v0.4.4 * @since Beta v0.4.5
*/ */
import { app } from "@tauri-apps/api"; import { app } from "@tauri-apps/api";
import Database from "tauri-plugin-sql-api"; import Database from "tauri-plugin-sql-api";
import initDataSql from "./sql/initData"; import initDataSql from "./sql/initData";
import initTableSql from "./sql/initTable";
import { import {
importAbyssData, importAbyssData,
insertAbyssData, insertAbyssData,
insertAppData, insertAppData,
insertGameAccountData, insertGameAccountData,
insertPostCollectData,
insertRecordData, insertRecordData,
insertRoleData, insertRoleData,
} from "./sql/insertData"; } from "./sql/insertData";
@@ -66,12 +66,12 @@ class Sqlite {
/** /**
* @description 初始化数据库 * @description 初始化数据库
* @since Beta v0.3.3 * @since Beta v0.4.5
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
public async initDB(): Promise<void> { public async initDB(): Promise<void> {
const db = await this.getDB(); const db = await this.getDB();
const sql = [...initTableSql(), ...(await initDataSql())]; const sql = await initDataSql();
for (const item of sql) { for (const item of sql) {
await db.execute(item); await db.execute(item);
} }
@@ -181,7 +181,6 @@ class Sqlite {
let isVerified = false; let isVerified = false;
const sqlT = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;"; const sqlT = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;";
const res: Array<{ name: string }> = await db.select(sqlT); const res: Array<{ name: string }> = await db.select(sqlT);
// 只检测已有的表是否具备,不检测总表数目
if (this.tables.every((item) => res.map((i) => i.name).includes(item))) { if (this.tables.every((item) => res.map((i) => i.name).includes(item))) {
isVerified = true; isVerified = true;
} }
@@ -491,6 +490,70 @@ class Sqlite {
if (res.length === 0) return undefined; if (res.length === 0) return undefined;
return res[0].id; return res[0].id;
} }
/**
* @description 检测特定表是否存在
* @since Beta v0.4.5
* @param {string} table 表名
* @returns {Promise<boolean>}
*/
async checkTableExist(table: string): Promise<boolean> {
const db = await this.getDB();
const sql = `SELECT name
FROM sqlite_master
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<false|string>} 当该帖子被归到多个分类时,返回分类数量
*/
async checkPostCollect(postId: string): Promise<false | string> {
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<string>} collect 分类
* @param {string} uid 用户 uid
* @returns {Promise<void>}
*/
async collectPost(
post: TGApp.Plugins.Mys.Post.FullData,
collect: string[],
uid?: string,
): Promise<void> {
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<void>}
*/
async cancelCollect(postId: string): Promise<void> {
const db = await this.getDB();
const sql = `DELETE
FROM UserCollection
WHERE postId = '${postId}';`;
await db.execute(sql);
}
} }
const TGSqlite = new Sqlite(); const TGSqlite = new Sqlite();

View File

@@ -1,11 +1,12 @@
/** /**
* @file plugins Sqlite sql initData.ts * @file plugins/Sqlite/sql/initData.ts
* @description Sqlite 初始化数据 sql 语句 * @description Sqlite 初始化数据 sql 语句
* @since Alpha v0.2.0 * @since Beta v0.4.5
*/ */
import { app } from "@tauri-apps/api"; import { app } from "@tauri-apps/api";
import initTableSql from "./initTable";
import { import {
insertAchievementData, insertAchievementData,
insertAchievementSeriesData, insertAchievementSeriesData,
@@ -31,19 +32,21 @@ async function initAppData(): Promise<string[]> {
const buildTime: string = getBuildTime(); const buildTime: string = getBuildTime();
// 初始化应用版本 // 初始化应用版本
sqlRes.push(` sqlRes.push(`
INSERT INTO AppData (key, value, updated) INSERT INTO AppData (key, value, updated)
VALUES ('appVersion', '${appVersion}', datetime('now', 'localtime')) VALUES ('appVersion', '${appVersion}', datetime('now', 'localtime'))
ON CONFLICT(key) DO UPDATE SET value = '${appVersion}', updated = datetime('now', 'localtime');`); ON CONFLICT(key) DO UPDATE SET value = '${appVersion}',
updated = datetime('now', 'localtime');`);
// 初始化应用数据更新时间 // 初始化应用数据更新时间
sqlRes.push(` sqlRes.push(`
INSERT INTO AppData (key, value, updated) INSERT INTO AppData (key, value, updated)
VALUES ('dataUpdated', '${buildTime}', datetime('now', 'localtime')) VALUES ('dataUpdated', '${buildTime}', datetime('now', 'localtime'))
ON CONFLICT(key) DO UPDATE SET value = '${buildTime}', updated = datetime('now', 'localtime');`); ON CONFLICT(key) DO UPDATE SET value = '${buildTime}',
updated = datetime('now', 'localtime');`);
// 初始化 cookie // 初始化 cookie
sqlRes.push(` sqlRes.push(`
INSERT INTO AppData (key, value, updated) INSERT INTO AppData (key, value, updated)
VALUES ('cookie', '{}', datetime('now', 'localtime')) VALUES ('cookie', '{}', datetime('now', 'localtime'))
ON CONFLICT(key) DO NOTHING;`); ON CONFLICT(key) DO NOTHING;`);
return sqlRes; return sqlRes;
} }
@@ -85,11 +88,12 @@ function initCharacterData(): string[] {
/** /**
* @description 初始化数据 * @description 初始化数据
* @since Alpha v0.2.0 * @since Beta v0.4.5
* @returns {Promise<string[]>} sql * @returns {Promise<string[]>} sql
*/ */
async function initDataSql(): Promise<string[]> { async function initDataSql(): Promise<string[]> {
const sqlRes: string[] = []; const sqlRes: string[] = [];
sqlRes.push(...initTableSql());
sqlRes.push(...(await initAppData())); sqlRes.push(...(await initAppData()));
sqlRes.push(...initAchievementSeriesData()); sqlRes.push(...initAchievementSeriesData());
sqlRes.push(...initAchievementData()); sqlRes.push(...initAchievementData());

View File

@@ -269,3 +269,28 @@ export function insertRoleData(uid: string, data: TGApp.Game.Character.ListItem[
}); });
return sql.join(""); return sql.join("");
} }
/**
* @description 插入帖子收藏数据
* @since Beta v0.4.5
* @param {TGApp.Plugins.Mys.Post.FullData} data 帖子数据
* @param {Array<string>} collect 合集
* @param {string} uid 用户 UID
* @returns {string} sql
*/
export function insertPostCollectData(
data: TGApp.Plugins.Mys.Post.FullData,
collect: string[],
uid?: string,
): string {
return `
INSERT INTO UserCollection (postId, title, content, collect, uid, updated)
VALUES (${data.post.post_id}, '${data.post.subject}', '${JSON.stringify(data)}',
'${JSON.stringify(collect)}', '${uid}', datetime('now', 'localtime'))
ON CONFLICT DO UPDATE
SET title = '${data.post.subject}',
content = '${JSON.stringify(data)}',
collect = '${JSON.stringify(collect)}',
updated = datetime('now', 'localtime');
`;
}

View File

@@ -1,7 +1,7 @@
/** /**
* @file router/modules/main.ts * @file router/modules/main.ts
* @description 主路由模块 * @description 主路由模块
* @since Beta v0.4.4 * @since Beta v0.4.5
*/ */
const mainRoutes = [ const mainRoutes = [
@@ -30,6 +30,11 @@ const mainRoutes = [
name: "成就", name: "成就",
component: async () => await import("../../pages/common/Achievements.vue"), component: async () => await import("../../pages/common/Achievements.vue"),
}, },
{
path: "/collection",
name: "收藏",
component: async () => await import("../../pages/common/PostCollect.vue"),
},
{ {
path: "/test", path: "/test",
name: "测试页", name: "测试页",

40
src/types/BBS/Collection.d.ts vendored Normal file
View File

@@ -0,0 +1,40 @@
/**
* @file types/BBS/Collection.d.ts
* @description BBS 收藏相关类型定义文件
* @since Beta v0.4.5
*/
/**
* @description BBS 收藏命名空间
* @since Beta v0.4.5
* @namespace TGApp.BBS.Collection
* @memberof TGApp.BBS
*/
declare namespace TGApp.BBS.Collection {
/**
* @description 用户收藏帖子数据返回
* @since Beta v0.4.5
* @interface PostResponse
* @extends TGApp.BBS.Response.BaseWithData
* @property {PostRespData} data - 响应数据
* @return PostResponse
*/
interface PostResponse extends TGApp.BBS.Response.BaseWithData {
data: PostRespData;
}
/**
* @description 用户收藏帖子响应数据
* @since Beta v0.4.5
* @interface PostRespData
* @property {boolean} is_last - 是否最后一页
* @property {string} next_offset - 下一页偏移量
* @property {Array<TGApp.Plugins.Mys.Post.FullData>} list - 帖子列表
* @return PostRespData
*/
interface PostRespData {
is_last: boolean;
next_offset: string;
list: TGApp.Plugins.Mys.Post.FullData[];
}
}

41
src/types/Sqlite/Collection.d.ts vendored Normal file
View File

@@ -0,0 +1,41 @@
/**
* @file types/Sqlite/Collection.d.ts
* @description Sqlite UserCollection 类型定义文件
* @since Beta v0.4.5
*/
/**
* @description 用户收藏命名空间
* @since Beta v0.4.5
* @namespace TGApp.Sqlite.UserCollection
* @memberof TGApp.Sqlite
*/
declare namespace TGApp.Sqlite.UserCollection {
/**
* @description 数据库-用户收藏表
* @since Beta v0.4.5
* @interface SingleTable
* @property {string} postId - 帖子 ID
* @property {string} title - 标题
* @property {string} content - 内容
* @property {string} collect - 合集
* @property {string} uid - 用户 UID
* @property {string} updated - 更新时间
* @return SingleTable
*/
interface SingleTable {
postId: string;
title: string;
content: string;
collect: string;
uid: string;
updated: string;
}
/**
* @description 渲染卡片
* @since Beta v0.4.5
* @interface RenderCard
*/
type RenderCard = TGApp.Plugins.Mys.Forum.RenderCard;
}

View File

@@ -1,5 +1,6 @@
<template> <template>
<TSwitchTheme /> <TSwitchTheme />
<TSetCollect v-if="collectExist" :model-value="postId" :data="postData" />
<TShareBtn <TShareBtn
v-show="!loadingEmpty" v-show="!loadingEmpty"
v-model="postRef" v-model="postRef"
@@ -85,6 +86,7 @@ import { appWindow } from "@tauri-apps/api/window";
import { nextTick, onMounted, onUnmounted, ref, watch } from "vue"; import { nextTick, onMounted, onUnmounted, ref, watch } from "vue";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import TSetCollect from "../components/app/t-setCollect.vue";
import TSwitchTheme from "../components/app/t-switchTheme.vue"; import TSwitchTheme from "../components/app/t-switchTheme.vue";
import TShareBtn from "../components/main/t-shareBtn.vue"; import TShareBtn from "../components/main/t-shareBtn.vue";
import ToLoading from "../components/overlay/to-loading.vue"; import ToLoading from "../components/overlay/to-loading.vue";
@@ -92,6 +94,7 @@ import TpAvatar from "../components/post/tp-avatar.vue";
import TpParser from "../components/post/tp-parser.vue"; import TpParser from "../components/post/tp-parser.vue";
import TpoCollection from "../components/post/tpo-collection.vue"; import TpoCollection from "../components/post/tpo-collection.vue";
import Mys from "../plugins/Mys"; import Mys from "../plugins/Mys";
import TGSqlite from "../plugins/Sqlite";
import { useAppStore } from "../store/modules/app"; import { useAppStore } from "../store/modules/app";
import TGClient from "../utils/TGClient"; import TGClient from "../utils/TGClient";
import TGLogger from "../utils/TGLogger"; import TGLogger from "../utils/TGLogger";
@@ -119,6 +122,7 @@ const shareTime = ref<number>(Math.floor(Date.now() / 1000));
const shareTimeTimer = ref<any>(); const shareTimeTimer = ref<any>();
// 合集 // 合集
const showCollection = ref<boolean>(false); const showCollection = ref<boolean>(false);
const collectExist = ref<boolean>(false);
onMounted(async () => { onMounted(async () => {
await appWindow.show(); await appWindow.show();
@@ -160,6 +164,7 @@ onMounted(async () => {
await TGLogger.Info(`[t-post][${postId}][onMounted] 打开 JSON 窗口`); await TGLogger.Info(`[t-post][${postId}][onMounted] 打开 JSON 窗口`);
createPostJson(postId); createPostJson(postId);
} }
collectExist.value = await TGSqlite.checkTableExist("UserCollection");
await nextTick(() => { await nextTick(() => {
shareTimeTimer.value = setInterval(() => { shareTimeTimer.value = setInterval(() => {
shareTime.value = Math.floor(Date.now() / 1000); shareTime.value = Math.floor(Date.now() / 1000);

View File

@@ -1,7 +1,7 @@
/** /**
* @file web/request/TGRequest.ts * @file web/request/TGRequest.ts
* @description 应用用到的请求函数 * @description 应用用到的请求函数
* @since Beta v0.4.3 * @since Beta v0.4.5
*/ */
import { genAuthkey, genAuthkey2 } from "./genAuthkey"; import { genAuthkey, genAuthkey2 } from "./genAuthkey";
@@ -20,6 +20,7 @@ import { getStokenByGameToken, getTokenBySToken } from "./getStoken";
import getSyncAvatarDetail from "./getSyncAvatarDetail"; import getSyncAvatarDetail from "./getSyncAvatarDetail";
import getSyncAvatarListAll from "./getSyncAvatarListAll"; import getSyncAvatarListAll from "./getSyncAvatarListAll";
import { getTokensByLoginTicket } from "./getTokens"; import { getTokensByLoginTicket } from "./getTokens";
import { getUserCollect } from "./getUserCollect";
import { getUserInfoByCookie } from "./getUserInfo"; import { getUserInfoByCookie } from "./getUserInfo";
import { verifyLToken } from "./verifyLToken"; import { verifyLToken } from "./verifyLToken";
@@ -43,6 +44,7 @@ const TGRequest = {
getAbyss, getAbyss,
getAccounts: getGameAccountsByCookie, getAccounts: getGameAccountsByCookie,
getUserInfo: getUserInfoByCookie, getUserInfo: getUserInfoByCookie,
getCollect: getUserCollect,
}, },
byLToken: { byLToken: {
verify: verifyLToken, verify: verifyLToken,

View File

@@ -0,0 +1,35 @@
/**
* @file web/request/getUserCollect.ts
* @description 获取用户收藏请求模块
* @since Beta v0.4.5
*/
import { http } from "@tauri-apps/api";
import TGUtils from "../utils/TGUtils";
/**
* @description 获取用户收藏帖子
* @since Beta v0.4.5
* @param {Record<string, string>} cookie - 用户 cookie
* @param {string} offset - 偏移量
* @returns {Promise<TGApp.BBS.Collection.PostRespData|TGApp.BBS.Response.Base>} 用户收藏帖子
*/
export async function getUserCollect(
cookie: Record<string, string>,
offset: string = "",
): Promise<TGApp.BBS.Collection.PostRespData | TGApp.BBS.Response.Base> {
const url = "https://bbs-api.miyoushe.com/post/wapi/userFavouritePost";
const params = { size: "20", offset };
const header = TGUtils.User.getHeader(cookie, "GET", params, "common");
return await http
.fetch<TGApp.BBS.Collection.PostResponse | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
})
.then((res) => {
if (res.data.retcode !== 0) return <TGApp.BBS.Response.Base>res.data;
return res.data.data;
});
}