重构帖子解析逻辑,增加新类型解析

*PostID:69886846,69915487
This commit is contained in:
BTMuli
2025-10-24 22:12:14 +08:00
parent 9020214d23
commit 33d9ba5c4d
9 changed files with 489 additions and 16 deletions

View File

@@ -7,6 +7,8 @@
/>
</template>
<script lang="ts" setup>
import TpUgcLevel from "@comp/viewPost/tp-ugc-level.vue";
import TpUgcTag from "@comp/viewPost/tp-ugc-tag.vue";
import type { Component } from "vue";
import TpBackupText from "./tp-backupText.vue";
@@ -72,6 +74,8 @@ function getParsedData(data: SctPostDataArr): SctPostDataArr {
if (check < parsedText.length && check !== 0) {
res.push(...child);
child = [];
} else if (check === 0 && child.length > 0) {
res.push(...child);
}
}
if (res.length === 0 && child.length > 0) res.push(...child);
@@ -95,8 +99,9 @@ function getTpName(tp: TGApp.BBS.SctPost.Base): Component {
if (tp.children) return TpTexts;
if (typeof tp.insert === "undefined") return TpUnknown;
if (typeof tp.insert === "string") return TpText;
// game_user_info属于backup_text的一种必须放在backup_text判断的前面
// 判断特殊backup_text
if ("game_user_info" in tp.insert) return TpUid;
if ("ugc_master_tag" in tp.insert) return TpUgcTag;
if ("backup_text" in tp.insert) {
if (tp.insert.backup_text === "[游戏卡片]" && "reception_card" in tp.insert) return TpGameCard;
if (tp.insert.backup_text === "[自定义表情]" && "custom_emoticon" in tp.insert) {
@@ -106,6 +111,7 @@ function getTpName(tp: TGApp.BBS.SctPost.Base): Component {
}
if ("divider" in tp.insert) return TpDivider;
if ("image" in tp.insert) return TpImage;
if ("level" in tp.insert) return TpUgcLevel;
if ("link_card" in tp.insert) return TpLinkCard;
if ("mention" in tp.insert) return TpMention;
if ("video" in tp.insert) return TpVideo;

View File

@@ -0,0 +1,139 @@
<!-- UGC关卡组件 TODO:UI调整-->
<template>
<div class="tul-card-box" @click="console.log(props.data)">
<TMiImg class="tul-cover" :src="props.data.insert.level.cover.url" alt="cover" />
<div class="tul-content">
<div class="tul-top">
<div class="tul-title">{{ props.data.insert.level.level_name }}</div>
<div class="tul-sub">
<div class="tul-info-item" title="游戏类型">
<v-icon size="16" color="yellow">mdi-gamepad-variant</v-icon>
<span>{{ props.data.insert.level.play_type }}</span>
</div>
<div class="tul-info-item" title="游玩人数">
<v-icon size="16" color="blue">mdi-account-multiple</v-icon>
<span>{{ props.data.insert.level.show_limit_play_num_str }}</span>
</div>
</div>
<div class="tul-attach" v-if="props.data.insert.level.level_attachment">
<span></span>
<span>{{ props.data.insert.level.level_attachment.content }}</span>
</div>
</div>
<div class="tul-bottom">
<div class="tul-info">
<div class="tul-info-item" title="热度">
<v-icon size="16" color="orange">mdi-fire</v-icon>
<span>{{ props.data.insert.level.hot_score }}</span>
</div>
<div class="tul-info-item" title="点赞率">
<v-icon size="16" color="pink">mdi-thumb-up</v-icon>
<span>{{ props.data.insert.level.good_rate }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import TMiImg from "@comp/app/t-mi-img.vue";
type TpUgcLevel = { insert: { level: TGApp.BBS.UGC.Level } };
type TpUgcLevelProps = { data: TpUgcLevel };
const props = defineProps<TpUgcLevelProps>();
</script>
<style lang="scss" scoped>
.tul-card-box {
display: flex;
width: 100%;
box-sizing: border-box;
padding: 8px;
border: 1px solid var(--common-shadow-1);
border-radius: 4px;
margin-bottom: 8px;
background: var(--box-bg-1);
column-gap: 8px;
}
.tul-cover {
max-width: 50%;
max-height: 180px;
border-radius: 4px;
cursor: pointer;
transition: all 0.5s;
&:hover {
scale: 0.9;
}
}
.tul-content {
display: flex;
width: 100%;
flex-direction: column;
align-items: center;
justify-content: space-between;
font-family: var(--font-title);
}
.tul-top {
display: flex;
width: 100%;
flex-direction: column;
align-items: flex-start;
justify-content: center;
}
.tul-title {
color: var(--tgc-od-red);
font-family: var(--font-title);
font-size: 20px;
}
.tul-sub {
display: flex;
width: 100%;
align-items: center;
justify-content: flex-start;
color: var(--tgc-od-white);
column-gap: 16px;
font-size: 16px;
}
.tul-attach {
margin-top: 8px;
color: var(--common-text-secondary);
font-size: 16px;
span {
color: var(--tgc-od-blue);
&:first-child {
font-family: Genshin, sans-serif;
font-size: 20px;
line-height: 14px;
vertical-align: top;
}
}
}
.tul-bottom {
display: flex;
width: 100%;
align-items: center;
justify-content: flex-end;
}
.tul-info {
display: flex;
gap: 16px;
}
.tul-info-item {
display: flex;
align-items: center;
font-size: 14px;
gap: 4px;
}
</style>

View File

@@ -0,0 +1,52 @@
<!-- ugc_master_tag backup_text -->
<template>
<span class="tut-box">
{{ tagName }}
</span>
</template>
<script lang="ts" setup>
import useAppStore from "@store/app.js";
import { str2Color } from "@utils/toolFunc.js";
import { storeToRefs } from "pinia";
import { computed } from "vue";
type TpUgcTag = {
insert: {
backup_text: string;
ugc_master_tag: {
id: number;
name: string;
is_available: boolean;
};
};
};
type TpUgcTagProps = { data: TpUgcTag };
const props = defineProps<TpUgcTagProps>();
const { theme } = storeToRefs(useAppStore());
const tagName = computed<string>(() => props.data.insert.ugc_master_tag.name);
const isDarkMode = computed<boolean>(() => theme.value === "dark");
const tagColor = computed<string>(() => tag2Color(tagName.value, isDarkMode.value));
const bgColor = computed<string>(() => `rgba(${tagColor.value.slice(4, -1)}, 0.18)`);
function tag2Color(str: string, isDarkMode: boolean = false): string {
const adjust = isDarkMode ? 80 : -40;
return str2Color(str, adjust);
}
</script>
<style lang="scss" scoped>
.tut-box {
display: inline-flex;
width: fit-content;
align-items: center;
justify-content: center;
padding: 0 6px;
border-radius: 12px;
margin-right: 4px;
background: v-bind(bgColor); /* stylelint-disable-line value-keyword-case */
color: v-bind(tagColor); /* stylelint-disable-line value-keyword-case */
font-family: var(--font-title);
font-size: 12px;
gap: 2px;
}
</style>