mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
🧑💻 回复数据导出&样式测试
This commit is contained in:
125
src/components/postReply/tpr-debug.vue
Normal file
125
src/components/postReply/tpr-debug.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<TOverlay v-model="visible" hide :to-click="onCancel" blur-val="5px">
|
||||
<div class="tpr-debug-box">
|
||||
<div class="tpr-debug-title">
|
||||
<span>文件:</span>
|
||||
<span :title="filePath">{{ filePath }}</span>
|
||||
<v-btn @click="selectFile" color="primary">选择文件</v-btn>
|
||||
</div>
|
||||
<div class="tpr-debug-reply">
|
||||
<TprReply mode="main" :modelValue="replyData" v-if="replyData !== null" />
|
||||
</div>
|
||||
</div>
|
||||
</TOverlay>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { open } from "@tauri-apps/plugin-dialog";
|
||||
import { readTextFile } from "@tauri-apps/plugin-fs";
|
||||
import { computed, ref } from "vue";
|
||||
|
||||
import showSnackbar from "../func/snackbar.js";
|
||||
import TOverlay from "../main/t-overlay.vue";
|
||||
|
||||
import TprReply from "./tpr-reply.vue";
|
||||
|
||||
interface TprDebugProps {
|
||||
modelValue: boolean;
|
||||
}
|
||||
|
||||
interface TprDebugEmits {
|
||||
(event: "update:modelValue", value: boolean): void;
|
||||
}
|
||||
|
||||
const props = defineProps<TprDebugProps>();
|
||||
const emits = defineEmits<TprDebugEmits>();
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => {
|
||||
emits("update:modelValue", value);
|
||||
},
|
||||
});
|
||||
|
||||
const filePath = ref<string>("");
|
||||
const replyData = ref<TGApp.Plugins.Mys.Reply.ReplyFull | null>(null);
|
||||
|
||||
function onCancel(): void {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
async function selectFile(): Promise<void> {
|
||||
const file = await open({
|
||||
multiple: false,
|
||||
directory: false,
|
||||
filter: {
|
||||
name: "JSON",
|
||||
extensions: ["json"],
|
||||
},
|
||||
});
|
||||
if (file === null) {
|
||||
showSnackbar({
|
||||
text: "未选择文件",
|
||||
color: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
filePath.value = file.path;
|
||||
try {
|
||||
const data = await readTextFile(file.path);
|
||||
replyData.value = JSON.parse(data);
|
||||
} catch (error) {
|
||||
showSnackbar({
|
||||
text: `解析失败:${error}`,
|
||||
color: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tpr-debug-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 400px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
background: var(--box-bg-1);
|
||||
box-shadow: 0 0 5px var(--common-shadow-1);
|
||||
}
|
||||
|
||||
.tpr-debug-title {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid var(--box-bg-2);
|
||||
font-family: var(--font-title);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
:nth-child(2) {
|
||||
overflow: hidden;
|
||||
width: 300px;
|
||||
color: var(--common-text-title);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.tpr-debug-reply {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 50px;
|
||||
max-height: 300px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 5px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -21,7 +21,13 @@
|
||||
<div class="tpr-main-reply">
|
||||
<!-- 顶部负责显示回复条件&关闭按钮&刷新按钮 -->
|
||||
<div class="tpr-main-filter">
|
||||
<v-chip color="primary" label>回复列表</v-chip>
|
||||
<v-chip
|
||||
color="primary"
|
||||
label
|
||||
@click="handleDebug"
|
||||
:style="{ cursor: appStore.devMode ? 'pointer' : 'not-allowed' }"
|
||||
>回复列表
|
||||
</v-chip>
|
||||
<v-switch
|
||||
v-model="onlyLz"
|
||||
color="primary"
|
||||
@@ -54,13 +60,16 @@
|
||||
</div>
|
||||
</v-menu>
|
||||
</div>
|
||||
<TprDebug v-if="appStore.devMode" v-model="showDebug" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, watch } from "vue";
|
||||
|
||||
import Mys from "../../plugins/Mys/index.js";
|
||||
import { useAppStore } from "../../store/modules/app.js";
|
||||
import showSnackbar from "../func/snackbar.js";
|
||||
|
||||
import TprDebug from "./tpr-debug.vue";
|
||||
import TprReply from "./tpr-reply.vue";
|
||||
|
||||
interface TprMainProps {
|
||||
@@ -69,18 +78,23 @@ interface TprMainProps {
|
||||
}
|
||||
|
||||
const props = defineProps<TprMainProps>();
|
||||
const reply = ref<Array<TGApp.Plugins.Mys.Reply.ReplyFull>>([]);
|
||||
const lastId = ref<string | undefined>(undefined);
|
||||
const isLast = ref<boolean>(false);
|
||||
const loading = ref<boolean>(false);
|
||||
const showOverlay = ref<boolean>(false);
|
||||
const onlyLz = ref<boolean>(false);
|
||||
const orderType = ref<"hot" | "latest" | "oldest">("hot");
|
||||
const appStore = useAppStore();
|
||||
|
||||
const orderList = [
|
||||
{ label: "热门", value: "hot" },
|
||||
{ label: "最新", value: "latest" },
|
||||
{ label: "最早", value: "oldest" },
|
||||
];
|
||||
|
||||
const reply = ref<Array<TGApp.Plugins.Mys.Reply.ReplyFull>>([]);
|
||||
const lastId = ref<string | undefined>(undefined);
|
||||
const isLast = ref<boolean>(false);
|
||||
const loading = ref<boolean>(false);
|
||||
const showOverlay = ref<boolean>(false);
|
||||
const showDebug = ref<boolean>(false);
|
||||
const onlyLz = ref<boolean>(false);
|
||||
const orderType = ref<"hot" | "latest" | "oldest">("hot");
|
||||
|
||||
const isHot = computed<boolean>(() => orderType.value === "hot");
|
||||
const replyOrder = computed<1 | 2 | undefined>(() => {
|
||||
if (orderType.value === "hot") return undefined;
|
||||
@@ -137,6 +151,14 @@ async function loadReply(): Promise<void> {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function handleDebug(): void {
|
||||
if (!appStore.devMode || showDebug.value) {
|
||||
showDebug.value = false;
|
||||
return;
|
||||
}
|
||||
showDebug.value = true;
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tpr-main-box {
|
||||
|
||||
@@ -71,6 +71,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="tpr-extra" :title="`ID:${props.modelValue.reply.reply_id}`">
|
||||
<span class="tpr-debug" @click="exportData">
|
||||
<v-icon size="small">mdi-file-export</v-icon>
|
||||
</span>
|
||||
<span v-if="props.modelValue.r_user" class="tpr-reply-user">
|
||||
<span>回复</span>
|
||||
<span>{{ props.modelValue.r_user.nickname }}</span>
|
||||
@@ -80,9 +83,13 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { path } from "@tauri-apps/api";
|
||||
import { save } from "@tauri-apps/plugin-dialog";
|
||||
import { writeTextFile } from "@tauri-apps/plugin-fs";
|
||||
import { toRaw, ref } from "vue";
|
||||
|
||||
import Mys from "../../plugins/Mys/index.js";
|
||||
import showConfirm from "../func/confirm.js";
|
||||
import showSnackbar from "../func/snackbar.js";
|
||||
import TpParser from "../post/tp-parser.vue";
|
||||
|
||||
@@ -148,6 +155,39 @@ async function loadSub(): Promise<void> {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function exportData(): Promise<void> {
|
||||
const confirm = await showConfirm({
|
||||
title: "导出数据?",
|
||||
text: "将回复对应的JSON数据导出到文件",
|
||||
});
|
||||
if (!confirm) {
|
||||
showSnackbar({
|
||||
text: "已取消",
|
||||
color: "cancel",
|
||||
});
|
||||
return;
|
||||
}
|
||||
const data = JSON.stringify(toRaw(props.modelValue), null, 2);
|
||||
const fileName = `reply_${props.modelValue.reply.post_id}_${props.modelValue.reply.floor_id}_${props.modelValue.reply.reply_id}`;
|
||||
const savePath = await save({
|
||||
title: "导出回复数据",
|
||||
filters: [{ name: "JSON", extensions: ["json"] }],
|
||||
defaultPath: `${await path.downloadDir()}${path.sep()}${fileName}.json`,
|
||||
});
|
||||
if (savePath === null) {
|
||||
showSnackbar({
|
||||
text: "已取消",
|
||||
color: "cancel",
|
||||
});
|
||||
return;
|
||||
}
|
||||
await writeTextFile(savePath, data);
|
||||
showSnackbar({
|
||||
text: "导出成功",
|
||||
color: "success",
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tpr-reply-box {
|
||||
@@ -286,6 +326,13 @@ async function loadSub(): Promise<void> {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.tpr-debug {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tpr-reply-user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
<!-- 右侧内容-->
|
||||
<div class="right-wrap">
|
||||
<div v-if="curCardName !== '' && selectedSeries !== -1 && !loading">
|
||||
<!-- todo,这边用 v-if 包装,需要经过测试 -->
|
||||
<TopNamecard :data="curCard" @selected="openImg()" v-if="curCard" />
|
||||
</div>
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user