feat: 更新 UpdateNoteContainer 组件和 IndexView 视图,增强功能和用户体验

- 在 UpdateNoteContainer 组件中优化了内容渲染逻辑,简化了代码结构。
- 在 UpdateNote.ts 中新增版本 4 的更新记录,添加自动操作功能的详细说明。
- 在 IndexView 视图中引入新的图标,更新了功能列表,增强了用户界面。
- 改进了样式和布局,提升了整体视觉效果和用户交互体验。
This commit is contained in:
2025-04-22 23:11:32 +08:00
parent dd29a141de
commit f267592e37
4 changed files with 373 additions and 202 deletions

View File

@@ -3,19 +3,19 @@ import { updateNoteItemContentType, updateNotes } from '@/data/UpdateNote';
import { NDivider, NGrid } from 'naive-ui'; import { NDivider, NGrid } from 'naive-ui';
import { VNode } from 'vue'; import { VNode } from 'vue';
const currentVer = '1'
const savedVer = useStorage('UpdateNoteVer', 0)
function renderContent(content: updateNoteItemContentType): VNode | string | undefined { function renderContent(content: updateNoteItemContentType): VNode | string | undefined {
if (Array.isArray(content)) { if (Array.isArray(content)) {
return h('div', { style: { whiteSpace: 'pre-wrap' } }, content.map(item => renderContent(item))) return h('div', { style: { whiteSpace: 'pre-wrap' } }, content.map(item => renderContent(item)))
} }
if (typeof content === 'string') { const getContent = (c: unknown) => {
return content if (typeof c === 'string') {
return c
} }
if (typeof content === 'function') { if (typeof c === 'function') {
return content() return c()
} }
return undefined; }
return h('span', { style: { whiteSpace: 'pre-wrap' } }, getContent(content))
} }
</script> </script>
@@ -32,9 +32,7 @@ import { VNode } from 'vue';
<NDivider title-placement="left"> <NDivider title-placement="left">
{{ item.date }} {{ item.date }}
</NDivider> </NDivider>
<NGrid <NGrid x-gap="10">
x-gap="10"
>
<template <template
v-for="note in item.items" v-for="note in item.items"
:key="note.title" :key="note.title"

View File

@@ -4,6 +4,30 @@ import { VNode } from "vue";
import { FETCH_API } from "./constants"; import { FETCH_API } from "./constants";
export const updateNotes: updateNoteType[] = [ export const updateNotes: updateNoteType[] = [
{
ver: 4,
date: '2025.4.22',
items: [
{
type: 'new',
title: '添加自动操作功能',
content: [
[
'EventFetcher客户端新增多种自动操作类型支持包括弹幕自动回复、礼物感谢、上舰发送私信、关注感谢、入场欢迎、定时发送和SC感谢等, 可以执行js代码',
() => h(NImage, { src: 'https://pan.suki.club/d/vtsuru/imgur/QQ20250422-221703.png', width: 300 }),
],
[
'使用模板系统,支持随机回复、自定义表达式和条件判断等\r\n',
'数据持久化存储,各类操作配置和运行状态不会丢失\r\n\r\n',
'发送弹幕和私信需要客户端扫码登录, 客户端安装方式:',
() => h(NButton, {
text: true, tag: 'a', href: 'https://www.wolai.com/carN6qvUm3FErze9Xo53ii', target: '_blank', type: 'info'
}, () => '查看介绍'),
]
],
},
]
},
{ {
ver: 3, ver: 3,
date: '2025.4.15', date: '2025.4.15',

View File

@@ -8,11 +8,13 @@ import {
MoreHorizontal24Filled, MoreHorizontal24Filled,
TabletSpeaker24Filled, TabletSpeaker24Filled,
VehicleShip24Filled, VehicleShip24Filled,
VideoAdd20Filled VideoAdd20Filled,
Chat24Filled,
PersonFeedback24Filled
} from '@vicons/fluent' } from '@vicons/fluent'
import { AnalyticsSharp, Calendar, Chatbox, ListCircle, MusicalNote } from '@vicons/ionicons5' import { AnalyticsSharp, Calendar, Chatbox, ListCircle, MusicalNote } from '@vicons/ionicons5'
import { useWindowSize } from '@vueuse/core' import { useWindowSize } from '@vueuse/core'
import { NButton, NDivider, NEllipsis, NFlex, NGradientText, NGrid, NGridItem, NIcon, NNumberAnimation, NSpace, NText, NTooltip } from 'naive-ui' import { NButton, NDivider, NEllipsis, NFlex, NGradientText, NGrid, NGridItem, NIcon, NNumberAnimation, NSpace, NText, NTooltip, NAlert, NCard, NStatistic, NTag, NBadge } from 'naive-ui'
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import vtb from '@/svgs/ic_vtuber.svg' import vtb from '@/svgs/ic_vtuber.svg'
@@ -29,6 +31,11 @@ const functions = [
desc: '通过上舰, Superchat, 赠送礼物等操作可以获取积分, 并通过积分兑换虚拟或者实体礼物', desc: '通过上舰, Superchat, 赠送礼物等操作可以获取积分, 并通过积分兑换虚拟或者实体礼物',
icon: BookCoins20Filled, icon: BookCoins20Filled,
}, },
{
name: '弹幕机 (OBS',
desc: '在OBS上显示直播间弹幕、礼物和互动内容兼容blivechat样式 (开发中',
icon: Chat24Filled,
},
{ {
name: '日程表', name: '日程表',
desc: '提供多种样式的日程表', desc: '提供多种样式的日程表',
@@ -117,8 +124,10 @@ onMounted(async () => {
vertical vertical
justify="center" justify="center"
align="center" align="center"
style="padding-top: 30px" style="padding-top: 30px; padding-bottom: 30px;"
> >
<!-- 顶部标题部分 -->
<NCard style="background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border: none; width: 90vw; max-width: 1400px; ">
<NSpace <NSpace
justify="center" justify="center"
align="center" align="center"
@@ -210,50 +219,190 @@ onMounted(async () => {
</NSpace> </NSpace>
</NSpace> </NSpace>
</NSpace> </NSpace>
</NCard>
<NDivider style="width: 90vw"> <!-- 用户统计部分 -->
<NText :depth="3"> <NCard
本站用户 style="background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(10px);
</NText> border: none; width: 90vw; max-width: 1400px;"
<NDivider vertical /> size="small"
<NNumberAnimation >
<NFlex
justify="center"
align="center"
>
<NText style="font-size: 0.9rem; color: rgba(255,255,255,0.7);">
本站用户: <NNumberAnimation
:from="0" :from="0"
:to="indexData?.userCount" :to="indexData?.userCount"
show-separator show-separator
/> />
</NDivider> </NText>
<NGrid </NFlex>
cols="1 s:2 m:3 l:4 xl:5 2xl:5" </NCard>
x-gap="50"
y-gap="50" <!-- 功能列表部分 -->
style="max-width: 80vw" <NCard style="background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border: none; width: 90vw; max-width: 1400px; margin-bottom: 20px;">
responsive="screen" <NFlex vertical>
<NFlex
justify="center"
align="center"
style="margin-bottom: 20px;"
> >
<NGridItem <NText style="font-size: 1.2rem; font-weight: 500; background-image: linear-gradient(to right, #e5e5e5, #c2ebeb); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">
网站功能
</NText>
</NFlex>
<NFlex
:wrap="true"
justify="center"
style="gap: 15px;"
>
<NCard
v-for="item in functions" v-for="item in functions"
:key="item.name" :key="item.name"
style="width: 300px; max-width: 100%; background: rgba(255, 255, 255, 0.2); border: none; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);"
hoverable
> >
<NSpace <NFlex vertical>
align="end" <NFlex
:wrap="false" align="center"
style="margin-bottom: 10px;"
> >
<NIcon <NIcon
:component="item.icon" :component="item.icon"
:color="iconColor" size="24"
size="20" color="white"
/> />
<NEllipsis> <NText style="font-size: 1.1rem; font-weight: 500; margin-left: 10px; color: white;">
<NText class="index-feature header">
{{ item.name }} {{ item.name }}
</NText> </NText>
</NEllipsis> </NFlex>
</NSpace> <NText style="line-height: 1.6; color: rgba(255, 255, 255, 0.9);">
<NText class="index-feature content">
{{ item.desc }} {{ item.desc }}
</NText> </NText>
</NGridItem> </NFlex>
</NGrid> </NCard>
<NDivider style="width: 90vw"> </NFlex>
</NFlex>
</NCard>
<!-- 客户端专属功能部分 -->
<NCard style="background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border: none; width: 90vw; max-width: 1400px; margin-bottom: 20px;">
<NFlex vertical>
<NFlex
justify="center"
align="center"
style="margin-bottom: 20px;"
>
<NText style="font-size: 1.2rem; font-weight: 500; background-image: linear-gradient(to right, #e5e5e5, #c2ebeb); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">
客户端功能
</NText>
</NFlex>
<NFlex
:wrap="true"
justify="center"
style="gap: 20px;"
>
<NCard
style="width: 380px; max-width: 100%; background: rgba(255, 255, 255, 0.2); border: none; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);"
hoverable
>
<NFlex vertical>
<NFlex
align="center"
style="margin-bottom: 10px;"
>
<NIcon
:component="PersonFeedback24Filled"
size="24"
color="white"
/>
<NText style="font-size: 1.1rem; font-weight: 500; margin-left: 10px; color: white;">
自动操作
</NText>
</NFlex>
<NText style="line-height: 1.6; color: rgba(255, 255, 255, 0.9);">
支持弹幕自动回复礼物感谢上舰私信关注感谢入场欢迎定时发送和SC感谢等功能使用模板系统和JS执行环境可定制化程度挺高
</NText>
</NFlex>
</NCard>
<NCard
style="width: 380px; max-width: 100%; background: rgba(255, 255, 255, 0.2); border: none; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);"
hoverable
>
<NFlex vertical>
<NFlex
align="center"
style="margin-bottom: 10px;"
>
<NIcon
:component="Chat24Filled"
size="24"
color="white"
/>
<NText style="font-size: 1.1rem; font-weight: 500; margin-left: 10px; color: white;">
弹幕机 (客户端)
</NText>
</NFlex>
<NText style="line-height: 1.6; color: rgba(255, 255, 255, 0.9);">
在自己电脑上显示直播间弹幕礼物和互动内容
</NText>
</NFlex>
</NCard>
</NFlex>
<NFlex
justify="center"
style="margin-top: 20px;"
>
<NSpace>
<NButton
type="primary"
tag="a"
href="https://www.wolai.com/carN6qvUm3FErze9Xo53ii"
target="_blank"
>
<template #icon>
<NIcon :component="Info24Filled" />
</template>
客户端安装说明
</NButton>
<NButton
ghost
tag="a"
href="https://github.com/Megghy/vtsuru-fetvher-client"
target="_blank"
color="white"
>
客户端代码
</NButton>
<NButton
ghost
tag="a"
href="https://github.com/Megghy/vtsuru.live/tree/master/src/client"
target="_blank"
color="white"
>
逻辑代码
</NButton>
</NSpace>
</NFlex>
</NFlex>
</NCard>
<!-- 使用本站的主播部分 -->
<NCard style="background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border: none; width: 90vw; max-width: 1400px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);">
<NFlex vertical>
<NFlex
justify="center"
align="center"
style="margin-bottom: 20px;"
>
<NText style="font-size: 1.2rem; font-weight: 500; background-image: linear-gradient(to right, #e5e5e5, #c2ebeb); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">
正在使用本站的主播们 正在使用本站的主播们
<NTooltip> <NTooltip>
<template #trigger> <template #trigger>
@@ -261,16 +410,20 @@ onMounted(async () => {
</template> </template>
随机展示不分先后, 仅粉丝数大于500的主播 随机展示不分先后, 仅粉丝数大于500的主播
</NTooltip> </NTooltip>
</NDivider> </NText>
</NFlex>
<NFlex <NFlex
v-if="indexData" v-if="indexData"
vertical vertical
style="max-width: 80vw;" style="max-width: 90vw;"
> >
<NFlex <NFlex
align="center" align="center"
justify="center" justify="center"
:size="32" :size="32"
:wrap="true"
style="gap: 10px;"
> >
<NFlex <NFlex
v-for="streamer in indexData?.streamers" v-for="streamer in indexData?.streamers"
@@ -296,10 +449,13 @@ onMounted(async () => {
</NButton> </NButton>
</NFlex> </NFlex>
</NFlex> </NFlex>
<NText> <NText style="text-align: center; margin-top: 10px; color: white;">
还有更多... 还有更多...
</NText> </NText>
<NText depth="3"> <NText
depth="3"
style="text-align: center; margin-top: 5px;"
>
如果你不想要被展示在主页, 请前往 如果你不想要被展示在主页, 请前往
<NButton <NButton
text text
@@ -310,7 +466,8 @@ onMounted(async () => {
进行设置 进行设置
</NText> </NText>
</NFlex> </NFlex>
<NDivider style="width: 90vw" /> </NFlex>
</NCard>
</NSpace> </NSpace>
<NSpace <NSpace
style="position: absolute; bottom: 0; margin: 0 auto; width: 100vw" style="position: absolute; bottom: 0; margin: 0 auto; width: 100vw"
@@ -333,22 +490,11 @@ onMounted(async () => {
</template> </template>
<style lang="stylus" scoped> <style lang="stylus" scoped>
body
margin:0
.index-background .index-background
display: abslute; display: abslute;
height: 100vh;
background: #8360c3; /* fallback for old browsers */ background: #8360c3; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #2ebf91, #8360c3); /* Chrome 10-25, Safari 5.1-6 */ background: -webkit-linear-gradient(to right, #2ebf91, #8360c3); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #2ebf91, #8360c3); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ background: linear-gradient(to right, #2ebf91, #8360c3); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
overflow: auto overflow: auto
padding-bottom: 50px;
.index-background .header
font-size: 1.3rem;
font-weight: 700;
color: white;
.index-background .content
max-width: 300px;
font-size: 17px;
color: white;
</style> </style>

View File

@@ -278,10 +278,13 @@ async function ChangeBili() {
isLoading.value = false isLoading.value = false
}) })
} }
onMounted(() => {
checkUpdateNote();
})
onUnmounted(() => { onUnmounted(() => {
turnstile.value?.remove() turnstile.value?.remove()
// 当进入管理页时检查更新日志 // 当进入管理页时检查更新日志
checkUpdateNote();
}) })
</script> </script>