mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-16 09:58:13 +08:00
@@ -42,7 +42,6 @@
|
|||||||
<img :src="card.forum.icon" :alt="card.forum.name" />
|
<img :src="card.forum.icon" :alt="card.forum.name" />
|
||||||
<span>{{ card.forum.name }}</span>
|
<span>{{ card.forum.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- todo 需要测试 -->
|
|
||||||
<div v-if="props.selectMode" class="tpc-select">
|
<div v-if="props.selectMode" class="tpc-select">
|
||||||
<v-checkbox-btn v-model="selectedList" :value="props.modelValue.post.post_id" />
|
<v-checkbox-btn v-model="selectedList" :value="props.modelValue.post.post_id" />
|
||||||
</div>
|
</div>
|
||||||
@@ -60,12 +59,23 @@ interface TPostCardProps {
|
|||||||
selected?: string[];
|
selected?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TPostCardEmits {
|
||||||
|
(e: "update:selected", value: string[]): void;
|
||||||
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<TPostCardProps>(), {
|
const props = withDefaults(defineProps<TPostCardProps>(), {
|
||||||
selectMode: false,
|
selectMode: false,
|
||||||
});
|
});
|
||||||
|
const emits = defineEmits<TPostCardEmits>();
|
||||||
const isAct = ref<boolean>(false);
|
const isAct = ref<boolean>(false);
|
||||||
const card = ref<TGApp.Plugins.Mys.News.RenderCard>();
|
const card = ref<TGApp.Plugins.Mys.News.RenderCard>();
|
||||||
const selectedList = computed(() => props.selected);
|
const selectedList = computed({
|
||||||
|
get: () => props.selected,
|
||||||
|
set: (v) => {
|
||||||
|
if (v === undefined) return;
|
||||||
|
emits("update:selected", v);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
card.value = getPostCard(props.modelValue);
|
card.value = getPostCard(props.modelValue);
|
||||||
@@ -235,7 +245,7 @@ function getPostCard(item: TGApp.Plugins.Mys.Post.FullData): TGApp.Plugins.Mys.N
|
|||||||
|
|
||||||
.tpc-select {
|
.tpc-select {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
198
src/components/overlay/to-collectPost.vue
Normal file
198
src/components/overlay/to-collectPost.vue
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
<template>
|
||||||
|
<TOverlay v-model="visible" hide :to-click="onCancel" blur-val="20px">
|
||||||
|
<div class="tocp-container">
|
||||||
|
<div class="tocp-title">选择分类</div>
|
||||||
|
<div class="tocp-list">
|
||||||
|
<v-list-item v-for="item in collectList" :key="item.id">
|
||||||
|
<template #prepend>
|
||||||
|
<v-list-item-action start>
|
||||||
|
<v-checkbox-btn v-model="select" :value="item.title" />
|
||||||
|
</v-list-item-action>
|
||||||
|
</template>
|
||||||
|
<template #title>{{ item.title }}</template>
|
||||||
|
<template #subtitle>{{ item.desc }}</template>
|
||||||
|
</v-list-item>
|
||||||
|
</div>
|
||||||
|
<div class="tocp-bottom">
|
||||||
|
<v-btn class="tocp-btn" rounded @click="newCollect">新建分类</v-btn>
|
||||||
|
<v-btn class="tocp-btn" rounded @click="onCancel">取消</v-btn>
|
||||||
|
<v-btn :loading="submit" class="tocp-btn" rounded @click="onSubmit">确定</v-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TOverlay>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref, watch } from "vue";
|
||||||
|
|
||||||
|
import TSUserCollection from "../../plugins/Sqlite/modules/userCollect";
|
||||||
|
import showConfirm from "../func/confirm";
|
||||||
|
import showSnackbar from "../func/snackbar";
|
||||||
|
import TOverlay from "../main/t-overlay.vue";
|
||||||
|
|
||||||
|
interface ToPostCollectProps {
|
||||||
|
modelValue: boolean;
|
||||||
|
post: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ToPostCollectEmits {
|
||||||
|
(e: "update:modelValue", value: boolean): void;
|
||||||
|
|
||||||
|
(e: "submit"): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<ToPostCollectProps>();
|
||||||
|
const emits = defineEmits<ToPostCollectEmits>();
|
||||||
|
const select = ref<string>();
|
||||||
|
const collectList = ref<TGApp.Sqlite.UserCollection.UFCollection[]>([]);
|
||||||
|
const submit = ref(false);
|
||||||
|
|
||||||
|
const visible = computed({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (value) => {
|
||||||
|
emits("update:modelValue", value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function onCancel() {
|
||||||
|
visible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
async (val) => {
|
||||||
|
if (val) {
|
||||||
|
await freshData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
async function onSubmit(): Promise<void> {
|
||||||
|
if (!select.value) {
|
||||||
|
showSnackbar({
|
||||||
|
text: "请选择分类",
|
||||||
|
color: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
submit.value = true;
|
||||||
|
let force = false;
|
||||||
|
const forceCheck = await showConfirm({
|
||||||
|
title: "是否保留原分类",
|
||||||
|
text: "若否则仅保留新分类",
|
||||||
|
});
|
||||||
|
if (forceCheck === false) force = true;
|
||||||
|
const check = await TSUserCollection.updatePostsCollect(props.post, select.value, force);
|
||||||
|
if (!check) {
|
||||||
|
showSnackbar({
|
||||||
|
text: "处理失败",
|
||||||
|
color: "error",
|
||||||
|
});
|
||||||
|
submit.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showSnackbar({
|
||||||
|
text: `成功处理 ${props.post.length} 个帖子`,
|
||||||
|
color: "success",
|
||||||
|
});
|
||||||
|
submit.value = false;
|
||||||
|
visible.value = false;
|
||||||
|
emits("submit");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function newCollect(): Promise<void> {
|
||||||
|
let title, desc;
|
||||||
|
const titleC = await showConfirm({
|
||||||
|
mode: "input",
|
||||||
|
title: "新建分类",
|
||||||
|
text: "请输入分类名称",
|
||||||
|
});
|
||||||
|
if (titleC === undefined || titleC === false) return;
|
||||||
|
if (titleC === "未分类") {
|
||||||
|
showSnackbar({
|
||||||
|
text: "分类名不可为未分类",
|
||||||
|
color: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (collectList.value.find((i) => i.title === titleC)) {
|
||||||
|
showSnackbar({
|
||||||
|
text: "分类已存在",
|
||||||
|
color: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
title = titleC;
|
||||||
|
const descC = await showConfirm({
|
||||||
|
mode: "input",
|
||||||
|
title: "新建分类",
|
||||||
|
text: "请输入分类描述",
|
||||||
|
});
|
||||||
|
if (descC === false) return;
|
||||||
|
if (descC === undefined) desc = title;
|
||||||
|
else desc = descC;
|
||||||
|
const res = await TSUserCollection.createCollect(title, desc);
|
||||||
|
if (res) {
|
||||||
|
showSnackbar({
|
||||||
|
text: "新建成功",
|
||||||
|
color: "success",
|
||||||
|
});
|
||||||
|
await freshData();
|
||||||
|
} else {
|
||||||
|
showSnackbar({
|
||||||
|
text: "新建失败",
|
||||||
|
color: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function freshData(): Promise<void> {
|
||||||
|
collectList.value = await TSUserCollection.getCollectList();
|
||||||
|
select.value = undefined;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.tocp-container {
|
||||||
|
display: flex;
|
||||||
|
width: 400px;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: var(--app-page-bg);
|
||||||
|
row-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tocp-title {
|
||||||
|
font-family: var(--font-title);
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tocp-list {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 300px;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow-y: auto;
|
||||||
|
row-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tocp-bottom {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-left: auto;
|
||||||
|
column-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tocp-btn {
|
||||||
|
background: var(--btn-bg-1);
|
||||||
|
color: var(--btn-text-1);
|
||||||
|
font-family: var(--font-title);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tocp-btn {
|
||||||
|
border: 1px solid var(--common-shadow-2);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
当前所属分类:{{ postCollect.map((i) => i.collection).join(",") }}
|
当前所属分类:{{ postCollect.map((i) => i.collection).join(",") }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="topc-cur-collect">当前所属分类:未分类</div>
|
<div v-else class="topc-cur-collect">当前所属分类:未分类</div>
|
||||||
<div class="tpoc-collect-list">
|
<div class="topc-collect-list">
|
||||||
<v-list-item v-for="item in collectList" :key="item.id">
|
<v-list-item v-for="item in collectList" :key="item.id">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<v-list-item-action start>
|
<v-list-item-action start>
|
||||||
@@ -208,8 +208,8 @@ function onCancel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.topc-post-info {
|
.topc-post-info {
|
||||||
|
font-family: var(--font-title);
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.topc-cur-collect {
|
.topc-cur-collect {
|
||||||
@@ -218,7 +218,7 @@ function onCancel() {
|
|||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tpoc-collect-list {
|
.topc-collect-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<ToLoading v-model="loading" :title="loadingTitle" :subtitle="loadingSub" />
|
|
||||||
<div class="pc-container">
|
<div class="pc-container">
|
||||||
|
<ToLoading v-model="loading" :title="loadingTitle" :subtitle="loadingSub" />
|
||||||
<div class="pc-top">
|
<div class="pc-top">
|
||||||
<v-select
|
<v-select
|
||||||
v-model="curSelect"
|
v-model="curSelect"
|
||||||
@@ -30,31 +30,56 @@
|
|||||||
@click="freshOther"
|
@click="freshOther"
|
||||||
title="导入其他用户收藏"
|
title="导入其他用户收藏"
|
||||||
/>
|
/>
|
||||||
<v-btn size="small" class="pc-btn" icon="mdi-pencil" @click="toSelect()" title="编辑收藏" />
|
|
||||||
<v-btn
|
<v-btn
|
||||||
:disabled="selectedMode"
|
|
||||||
size="small"
|
size="small"
|
||||||
v-if="curSelect !== '未分类'"
|
|
||||||
class="pc-btn"
|
class="pc-btn"
|
||||||
icon="mdi-info"
|
:icon="selectedMode ? 'mdi-folder-move' : 'mdi-pencil'"
|
||||||
@click="toEdit()"
|
@click="toSelect()"
|
||||||
title="编辑分类"
|
title="编辑收藏"
|
||||||
/>
|
/>
|
||||||
<v-btn
|
<v-btn
|
||||||
:disabled="selectedMode"
|
:disabled="selectedMode"
|
||||||
size="small"
|
size="small"
|
||||||
v-if="curSelect !== '未分类'"
|
class="pc-btn"
|
||||||
|
icon="mdi-plus"
|
||||||
|
@click="addCollect"
|
||||||
|
title="新建分类"
|
||||||
|
/>
|
||||||
|
<v-btn
|
||||||
|
:disabled="selectedMode || curSelect === '未分类'"
|
||||||
|
size="small"
|
||||||
|
class="pc-btn"
|
||||||
|
icon="mdi-information"
|
||||||
|
@click="toEdit()"
|
||||||
|
title="编辑分类"
|
||||||
|
/>
|
||||||
|
<v-btn
|
||||||
|
size="small"
|
||||||
|
:disabled="curSelect === '未分类'"
|
||||||
class="pc-btn"
|
class="pc-btn"
|
||||||
icon="mdi-delete"
|
icon="mdi-delete"
|
||||||
@click="deleteCollect()"
|
@click="deleteOper(false)"
|
||||||
title="删除合集"
|
:title="selectedMode ? '删除帖子分类' : '清空合集'"
|
||||||
|
/>
|
||||||
|
<v-btn
|
||||||
|
size="small"
|
||||||
|
class="pc-btn"
|
||||||
|
icon="mdi-delete-forever"
|
||||||
|
@click="deleteOper(true)"
|
||||||
|
:title="selectedMode ? '删除帖子' : '删除合集'"
|
||||||
/>
|
/>
|
||||||
<v-pagination class="pc-page" v-model="page" :total-visible="view" :length="length" />
|
<v-pagination class="pc-page" v-model="page" :total-visible="view" :length="length" />
|
||||||
</div>
|
</div>
|
||||||
<div class="pc-posts">
|
<div class="pc-posts">
|
||||||
<div v-for="item in getPageItems()" :key="item.post.post_id">
|
<div v-for="item in getPageItems()" :key="item.post.post_id">
|
||||||
<TPostCard :model-value="item" :selected="selectedPost" :select-mode="selectedMode" />
|
<TPostCard
|
||||||
|
@update:selected="updateSelected"
|
||||||
|
:model-value="item"
|
||||||
|
:selected="selectedPost"
|
||||||
|
:select-mode="selectedMode"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<ToCollectPost @submit="load" :post="selectedPost" v-model="showOverlay" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -65,6 +90,7 @@ import { computed, onBeforeMount, onMounted, ref, watch } from "vue";
|
|||||||
import showConfirm from "../../components/func/confirm";
|
import showConfirm from "../../components/func/confirm";
|
||||||
import showSnackbar from "../../components/func/snackbar";
|
import showSnackbar from "../../components/func/snackbar";
|
||||||
import TPostCard from "../../components/main/t-postcard.vue";
|
import TPostCard from "../../components/main/t-postcard.vue";
|
||||||
|
import ToCollectPost from "../../components/overlay/to-collectPost.vue";
|
||||||
import ToLoading from "../../components/overlay/to-loading.vue";
|
import ToLoading from "../../components/overlay/to-loading.vue";
|
||||||
import TGSqlite from "../../plugins/Sqlite";
|
import TGSqlite from "../../plugins/Sqlite";
|
||||||
import TSUserCollection from "../../plugins/Sqlite/modules/userCollect";
|
import TSUserCollection from "../../plugins/Sqlite/modules/userCollect";
|
||||||
@@ -89,6 +115,7 @@ const view = computed(() => {
|
|||||||
|
|
||||||
const selectedMode = ref<boolean>(false);
|
const selectedMode = ref<boolean>(false);
|
||||||
const selectedPost = ref<Array<string>>([]);
|
const selectedPost = ref<Array<string>>([]);
|
||||||
|
const showOverlay = ref(false);
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
if (!(await TGSqlite.checkTableExist("UFPost"))) {
|
if (!(await TGSqlite.checkTableExist("UFPost"))) {
|
||||||
@@ -102,6 +129,10 @@ onBeforeMount(async () => {
|
|||||||
|
|
||||||
onMounted(async () => await load());
|
onMounted(async () => await load());
|
||||||
|
|
||||||
|
function updateSelected(v: string[]) {
|
||||||
|
selectedPost.value = v;
|
||||||
|
}
|
||||||
|
|
||||||
async function load(): Promise<void> {
|
async function load(): Promise<void> {
|
||||||
loadingTitle.value = "获取收藏帖子...";
|
loadingTitle.value = "获取收藏帖子...";
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@@ -116,16 +147,66 @@ async function load(): Promise<void> {
|
|||||||
selected.value = await TSUserCollection.getCollectPostList(collections.value[0].title);
|
selected.value = await TSUserCollection.getCollectPostList(collections.value[0].title);
|
||||||
curSelect.value = collections.value[0].title;
|
curSelect.value = collections.value[0].title;
|
||||||
}
|
}
|
||||||
|
selectedMode.value = false;
|
||||||
|
selectedPost.value = [];
|
||||||
page.value = 1;
|
page.value = 1;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toSelect() {
|
function toSelect() {
|
||||||
if (!selectedMode.value) {
|
if (!selectedMode.value) {
|
||||||
|
selectedPost.value = [];
|
||||||
selectedMode.value = true;
|
selectedMode.value = true;
|
||||||
} else {
|
} else {
|
||||||
// todo
|
selectedMode.value = false;
|
||||||
console.log(selectedPost.value);
|
if (selectedPost.value.length === 0) return;
|
||||||
|
showOverlay.value = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addCollect(): Promise<void> {
|
||||||
|
let title, desc;
|
||||||
|
const titleC = await showConfirm({
|
||||||
|
mode: "input",
|
||||||
|
title: "新建分类",
|
||||||
|
text: "请输入分类名称",
|
||||||
|
});
|
||||||
|
if (titleC === undefined || titleC === false) return;
|
||||||
|
if (titleC === "未分类") {
|
||||||
|
showSnackbar({
|
||||||
|
text: "分类名不可为未分类",
|
||||||
|
color: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (collections.value.find((i) => i.title === titleC)) {
|
||||||
|
showSnackbar({
|
||||||
|
text: "分类已存在",
|
||||||
|
color: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
title = titleC;
|
||||||
|
const descC = await showConfirm({
|
||||||
|
mode: "input",
|
||||||
|
title: "新建分类",
|
||||||
|
text: "请输入分类描述",
|
||||||
|
});
|
||||||
|
if (descC === false) return;
|
||||||
|
if (descC === undefined) desc = title;
|
||||||
|
else desc = descC;
|
||||||
|
const res = await TSUserCollection.createCollect(title, desc);
|
||||||
|
if (res) {
|
||||||
|
showSnackbar({
|
||||||
|
text: "新建成功",
|
||||||
|
color: "success",
|
||||||
|
});
|
||||||
|
await load();
|
||||||
|
} else {
|
||||||
|
showSnackbar({
|
||||||
|
text: "新建失败",
|
||||||
|
color: "error",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +225,13 @@ async function toEdit(): Promise<void> {
|
|||||||
text: "请输入分类标题",
|
text: "请输入分类标题",
|
||||||
input: collect.title,
|
input: collect.title,
|
||||||
});
|
});
|
||||||
|
if (cTc === false) {
|
||||||
|
showSnackbar({
|
||||||
|
text: "取消修改分类信息",
|
||||||
|
color: "cancel",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (typeof cTc !== "string") cTc = collect.title;
|
if (typeof cTc !== "string") cTc = collect.title;
|
||||||
if (cTc === "未分类") {
|
if (cTc === "未分类") {
|
||||||
showSnackbar({
|
showSnackbar({
|
||||||
@@ -194,11 +282,60 @@ async function toEdit(): Promise<void> {
|
|||||||
await load();
|
await load();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteCollect(): Promise<void> {
|
async function deleteOper(forever: boolean): Promise<void> {
|
||||||
|
if (selectedMode.value) {
|
||||||
|
await deletePost(forever);
|
||||||
|
} else {
|
||||||
|
await deleteCollect(forever);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deletePost(force: boolean = false): Promise<void> {
|
||||||
|
if (selectedPost.value.length === 0) {
|
||||||
|
showSnackbar({
|
||||||
|
text: "未选择帖子",
|
||||||
|
color: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const title = force ? "删除帖子" : "移除帖子分类";
|
||||||
const res = await showConfirm({
|
const res = await showConfirm({
|
||||||
title: "确定删除分类?",
|
title: `确定${title}?`,
|
||||||
text: selected.value.length > 0 ? `该分类下 ${selected.value.length} 条帖子将变为未分类` : "",
|
text: `共 ${selectedPost.value.length} 条帖子`,
|
||||||
});
|
});
|
||||||
|
if (!res) {
|
||||||
|
showSnackbar({
|
||||||
|
text: "取消操作",
|
||||||
|
color: "cancel",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loadingTitle.value = `正在${title}...`;
|
||||||
|
loading.value = true;
|
||||||
|
let success = 0;
|
||||||
|
for (const post of selectedPost.value) {
|
||||||
|
const check = await TSUserCollection.deletePostCollect(post, force);
|
||||||
|
if (!check) {
|
||||||
|
showSnackbar({
|
||||||
|
text: `帖子 ${post} 操作失败`,
|
||||||
|
color: "error",
|
||||||
|
});
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1500));
|
||||||
|
} else {
|
||||||
|
success++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
showSnackbar({
|
||||||
|
text: `成功${title} ${success} 条`,
|
||||||
|
color: "success",
|
||||||
|
});
|
||||||
|
await load();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteCollect(force: boolean): Promise<void> {
|
||||||
|
const title = force ? "删除分类" : "清空分类";
|
||||||
|
const res = await showConfirm({ title: `确定${title}?` });
|
||||||
if (!res) {
|
if (!res) {
|
||||||
showSnackbar({
|
showSnackbar({
|
||||||
text: "取消删除",
|
text: "取消删除",
|
||||||
@@ -206,16 +343,16 @@ async function deleteCollect(): Promise<void> {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const resD = await TSUserCollection.deleteCollect(curSelect.value);
|
const resD = await TSUserCollection.deleteCollect(curSelect.value, force);
|
||||||
if (resD) {
|
if (resD) {
|
||||||
showSnackbar({
|
showSnackbar({
|
||||||
text: "删除成功",
|
text: `成功 ${title}`,
|
||||||
color: "success",
|
color: "success",
|
||||||
});
|
});
|
||||||
await load();
|
await load();
|
||||||
} else {
|
} else {
|
||||||
showSnackbar({
|
showSnackbar({
|
||||||
text: "删除失败",
|
text: `${title} 失败`,
|
||||||
color: "error",
|
color: "error",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,17 +95,20 @@ async function createCollect(title: string, desc: string): Promise<boolean> {
|
|||||||
* @description 删除收藏合集
|
* @description 删除收藏合集
|
||||||
* @since Beta v0.4.5
|
* @since Beta v0.4.5
|
||||||
* @param {string} title 收藏合集标题
|
* @param {string} title 收藏合集标题
|
||||||
|
* @param {boolean} force 是否强制删除
|
||||||
* @return {Promise<boolean>} 返回是否删除成功
|
* @return {Promise<boolean>} 返回是否删除成功
|
||||||
*/
|
*/
|
||||||
async function deleteCollect(title: string): Promise<boolean> {
|
async function deleteCollect(title: string, force: boolean): Promise<boolean> {
|
||||||
const db = await TGSqlite.getDB();
|
const db = await TGSqlite.getDB();
|
||||||
const sql = "SELECT id FROM UFCollection WHERE title = ?";
|
const sql = "SELECT id FROM UFCollection WHERE title = ?";
|
||||||
const res: Array<{ id: number }> = await db.select(sql, [title]);
|
const res: Array<{ id: number }> = await db.select(sql, [title]);
|
||||||
if (res.length === 0) {
|
if (res.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const deleteSql = "DELETE FROM UFCollection WHERE title = ?";
|
if (force) {
|
||||||
await db.execute(deleteSql, [title]);
|
const deleteSql = "DELETE FROM UFCollection WHERE title = ?";
|
||||||
|
await db.execute(deleteSql, [title]);
|
||||||
|
}
|
||||||
const deleteRefSql = "DELETE FROM UFMap WHERE collectionId = ?";
|
const deleteRefSql = "DELETE FROM UFMap WHERE collectionId = ?";
|
||||||
await db.execute(deleteRefSql, [res[0].id]);
|
await db.execute(deleteRefSql, [res[0].id]);
|
||||||
return true;
|
return true;
|
||||||
@@ -210,25 +213,6 @@ async function addCollect(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 删除合集中的收藏
|
|
||||||
* @since Beta v0.4.5
|
|
||||||
* @param {string} postId 文章 id
|
|
||||||
* @param {string} collection 收藏合集标题
|
|
||||||
* @return {Promise<boolean>} 返回是否删除成功
|
|
||||||
*/
|
|
||||||
async function deleteCollectPost(postId: string, collection: string): Promise<boolean> {
|
|
||||||
const db = await TGSqlite.getDB();
|
|
||||||
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 更新帖子信息
|
* @description 更新帖子信息
|
||||||
* @since Beta v0.4.5
|
* @since Beta v0.4.5
|
||||||
@@ -275,12 +259,12 @@ async function deletePostCollect(postId: string, force: boolean = false): Promis
|
|||||||
if (selectRes.length === 0 && !force) {
|
if (selectRes.length === 0 && !force) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const deleteSql = "DELETE FROM UFMap WHERE postId = ?";
|
|
||||||
await db.execute(deleteSql, [postId]);
|
|
||||||
if (force) {
|
if (force) {
|
||||||
const deletePostSql = "DELETE FROM UFPost WHERE id = ?";
|
const deletePostSql = "DELETE FROM UFPost WHERE id = ?";
|
||||||
await db.execute(deletePostSql, [postId]);
|
await db.execute(deletePostSql, [postId]);
|
||||||
}
|
}
|
||||||
|
const deleteSql = "DELETE FROM UFMap WHERE postId = ?";
|
||||||
|
await db.execute(deleteSql, [postId]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,13 +312,13 @@ async function updatePostCollect(postId: string, collections: string[]): Promise
|
|||||||
* @since Beta v0.4.5
|
* @since Beta v0.4.5
|
||||||
* @param {string[]} postIds 文章 id
|
* @param {string[]} postIds 文章 id
|
||||||
* @param {string} collection 收藏合集标题
|
* @param {string} collection 收藏合集标题
|
||||||
* @param {string} oldCollection 旧的收藏合集标题
|
* @param {boolean} force 是否修改的同时移除其他收藏
|
||||||
* @return {Promise<boolean>} 返回是否修改成功
|
* @return {Promise<boolean>} 返回是否修改成功
|
||||||
*/
|
*/
|
||||||
async function updatePostsCollect(
|
async function updatePostsCollect(
|
||||||
postIds: string[],
|
postIds: string[],
|
||||||
collection: string,
|
collection: string,
|
||||||
oldCollection: string | undefined,
|
force: boolean = false,
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const db = await TGSqlite.getDB();
|
const db = await TGSqlite.getDB();
|
||||||
const collectionSql = "SELECT * FROM UFCollection WHERE title = ?";
|
const collectionSql = "SELECT * FROM UFCollection WHERE title = ?";
|
||||||
@@ -344,37 +328,22 @@ async function updatePostsCollect(
|
|||||||
if (collectionRes.length === 0) {
|
if (collectionRes.length === 0) {
|
||||||
return false;
|
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++) {
|
for (let i = 0; i < postIds.length; i++) {
|
||||||
const postSql = "SELECT id,title FROM UFPost WHERE id = ?";
|
const postSql = "SELECT id,title FROM UFPost WHERE id = ?";
|
||||||
const postRes: Array<{ id: number; title: string }> = await db.select(postSql, [postIds[i]]);
|
const postRes: Array<{ id: number; title: string }> = await db.select(postSql, [postIds[i]]);
|
||||||
if (postRes.length === 0) {
|
if (postRes.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (oldCollectionInfo !== undefined) {
|
if (force) {
|
||||||
const updateSql =
|
const deleteCheck = await deletePostCollect(postIds[i]);
|
||||||
"UPDATE UFMap SET collectionId = ?,post=?,collection=?,desc=?,updated=? WHERE postId = ? AND collectionId = ?";
|
if (!deleteCheck) return false;
|
||||||
await db.execute(updateSql, [
|
|
||||||
collectionRes[0].id,
|
|
||||||
postRes[0].title,
|
|
||||||
collection,
|
|
||||||
collectionRes[0].desc,
|
|
||||||
new Date().getTime(),
|
|
||||||
postIds[i],
|
|
||||||
oldCollectionInfo.id,
|
|
||||||
]);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
const mapSql = "SELECT * FROM UFMap WHERE postId = ? AND collectionId = ?";
|
||||||
|
const mapRes: TGApp.Sqlite.UserCollection.UFMap[] = await db.select(mapSql, [
|
||||||
|
postIds[i],
|
||||||
|
collectionRes[0].id,
|
||||||
|
]);
|
||||||
|
if (mapRes.length > 0) continue;
|
||||||
const insertSql =
|
const insertSql =
|
||||||
"INSERT INTO UFMap (postId, collectionId,post, collection, desc, updated) VALUES (?, ?, ?, ?, ?, ?)";
|
"INSERT INTO UFMap (postId, collectionId,post, collection, desc, updated) VALUES (?, ?, ?, ?, ?, ?)";
|
||||||
await db.execute(insertSql, [
|
await db.execute(insertSql, [
|
||||||
@@ -399,7 +368,6 @@ const TSUserCollection = {
|
|||||||
updateCollect,
|
updateCollect,
|
||||||
addCollect,
|
addCollect,
|
||||||
updatePostInfo,
|
updatePostInfo,
|
||||||
deleteCollectPost,
|
|
||||||
deletePostCollect,
|
deletePostCollect,
|
||||||
updatePostCollect,
|
updatePostCollect,
|
||||||
updatePostsCollect,
|
updatePostsCollect,
|
||||||
|
|||||||
Reference in New Issue
Block a user