mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-06 18:36:55 +08:00
add more custom item in index
This commit is contained in:
@@ -104,6 +104,7 @@ export interface UserSetting {
|
|||||||
queue: Setting_Queue
|
queue: Setting_Queue
|
||||||
point: Setting_Point
|
point: Setting_Point
|
||||||
questionDisplay: Setting_QuestionDisplay
|
questionDisplay: Setting_QuestionDisplay
|
||||||
|
index: Setting_Index
|
||||||
|
|
||||||
enableFunctions: FunctionTypes[]
|
enableFunctions: FunctionTypes[]
|
||||||
|
|
||||||
@@ -111,6 +112,13 @@ export interface UserSetting {
|
|||||||
songListTemplate: string | null
|
songListTemplate: string | null
|
||||||
scheduleTemplate: string | null
|
scheduleTemplate: string | null
|
||||||
}
|
}
|
||||||
|
export interface Setting_Index {
|
||||||
|
videos: string[]
|
||||||
|
notification: string
|
||||||
|
links: {
|
||||||
|
[key: string]: string
|
||||||
|
}
|
||||||
|
}
|
||||||
export interface Setting_LiveRequest {
|
export interface Setting_LiveRequest {
|
||||||
orderPrefix: string
|
orderPrefix: string
|
||||||
sortType?: QueueSortType
|
sortType?: QueueSortType
|
||||||
@@ -474,7 +482,7 @@ export enum SongRequestFrom {
|
|||||||
Danmaku,
|
Danmaku,
|
||||||
SC,
|
SC,
|
||||||
Web,
|
Web,
|
||||||
Gift
|
Gift,
|
||||||
}
|
}
|
||||||
export enum QueueFrom {
|
export enum QueueFrom {
|
||||||
Manual,
|
Manual,
|
||||||
@@ -716,3 +724,11 @@ export enum PointFrom {
|
|||||||
Manual,
|
Manual,
|
||||||
Use,
|
Use,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ResponseUserIndexModel{
|
||||||
|
notification: string
|
||||||
|
videos: VideoCollectVideo[]
|
||||||
|
links: {
|
||||||
|
[key: string]: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
34
src/components/SimpleVideoCard.vue
Normal file
34
src/components/SimpleVideoCard.vue
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { VideoCollectVideo } from '@/api/api-models'
|
||||||
|
import { NCard, NEllipsis, NImage, NText } from 'naive-ui'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
video: VideoCollectVideo
|
||||||
|
width?: number
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NCard size="small" hoverable :style="`max-width: ${width ?? 300}px;`">
|
||||||
|
<template #cover>
|
||||||
|
<NImage :src="video.cover" :img-props="{ referrerpolicy: 'no-referrer' }" />
|
||||||
|
</template>
|
||||||
|
<template #header>
|
||||||
|
<a :href="`https://bilibili.com/video/${video.id}`" target="_blank">
|
||||||
|
<NText>
|
||||||
|
<NEllipsis>{{ video.title }}</NEllipsis>
|
||||||
|
</NText>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
<NText depth="3" style="white-space: pre-line">
|
||||||
|
<NEllipsis>
|
||||||
|
{{ video.description }}
|
||||||
|
<template #tooltip>
|
||||||
|
<div style="white-space: pre-line; max-width: 300px">
|
||||||
|
{{ video.description }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</NEllipsis>
|
||||||
|
</NText>
|
||||||
|
</NCard>
|
||||||
|
</template>
|
||||||
@@ -48,6 +48,7 @@ export const VTSURU_API_URL = { toString: () => `${BASE_API_URL}vtsuru/` }
|
|||||||
export const POINT_API_URL = { toString: () => `${BASE_API_URL}point/` }
|
export const POINT_API_URL = { toString: () => `${BASE_API_URL}point/` }
|
||||||
export const BILI_AUTH_API_URL = { toString: () => `${BASE_API_URL}bili-auth/` }
|
export const BILI_AUTH_API_URL = { toString: () => `${BASE_API_URL}bili-auth/` }
|
||||||
export const FORUM_API_URL = { toString: () => `${BASE_API_URL}forum/` }
|
export const FORUM_API_URL = { toString: () => `${BASE_API_URL}forum/` }
|
||||||
|
export const USER_INDEX_API_URL = { toString: () => `${BASE_API_URL}user-index/` }
|
||||||
|
|
||||||
export const ScheduleTemplateMap = {
|
export const ScheduleTemplateMap = {
|
||||||
'': {
|
'': {
|
||||||
|
|||||||
@@ -6,10 +6,28 @@ import {
|
|||||||
downloadConfigDirect,
|
downloadConfigDirect,
|
||||||
useAccount,
|
useAccount,
|
||||||
} from '@/api/account'
|
} from '@/api/account'
|
||||||
import { FunctionTypes, ScheduleWeekInfo, SongFrom, SongLanguage, SongRequestOption, SongsInfo } from '@/api/api-models'
|
import {
|
||||||
|
FunctionTypes,
|
||||||
|
ResponseUserIndexModel,
|
||||||
|
ScheduleWeekInfo,
|
||||||
|
SongFrom,
|
||||||
|
SongLanguage,
|
||||||
|
SongRequestOption,
|
||||||
|
SongsInfo,
|
||||||
|
VideoCollectVideo,
|
||||||
|
} from '@/api/api-models'
|
||||||
|
import { QueryGetAPI, QueryPostAPI } from '@/api/query'
|
||||||
import DynamicForm from '@/components/DynamicForm.vue'
|
import DynamicForm from '@/components/DynamicForm.vue'
|
||||||
|
import SimpleVideoCard from '@/components/SimpleVideoCard.vue'
|
||||||
import { TemplateConfig } from '@/data/VTsuruTypes'
|
import { TemplateConfig } from '@/data/VTsuruTypes'
|
||||||
import { FETCH_API, IndexTemplateMap, ScheduleTemplateMap, SongListTemplateMap } from '@/data/constants'
|
import {
|
||||||
|
FETCH_API,
|
||||||
|
IndexTemplateMap,
|
||||||
|
ScheduleTemplateMap,
|
||||||
|
SongListTemplateMap,
|
||||||
|
USER_INDEX_API_URL,
|
||||||
|
} from '@/data/constants'
|
||||||
|
import { Delete24Regular } from '@vicons/fluent'
|
||||||
import {
|
import {
|
||||||
NAlert,
|
NAlert,
|
||||||
NButton,
|
NButton,
|
||||||
@@ -18,15 +36,21 @@ import {
|
|||||||
NCheckboxGroup,
|
NCheckboxGroup,
|
||||||
NDivider,
|
NDivider,
|
||||||
NEmpty,
|
NEmpty,
|
||||||
|
NFlex,
|
||||||
|
NIcon,
|
||||||
|
NInput,
|
||||||
NList,
|
NList,
|
||||||
NListItem,
|
NListItem,
|
||||||
NModal,
|
NModal,
|
||||||
|
NPopconfirm,
|
||||||
NSelect,
|
NSelect,
|
||||||
NSpace,
|
NSpace,
|
||||||
NSpin,
|
NSpin,
|
||||||
NTabPane,
|
NTabPane,
|
||||||
NTabs,
|
NTabs,
|
||||||
|
NTag,
|
||||||
NText,
|
NText,
|
||||||
|
NTooltip,
|
||||||
SelectOption,
|
SelectOption,
|
||||||
useMessage,
|
useMessage,
|
||||||
} from 'naive-ui'
|
} from 'naive-ui'
|
||||||
@@ -225,6 +249,15 @@ const selectedTemplateConfig = computed(() => {
|
|||||||
|
|
||||||
const biliUserInfo = ref()
|
const biliUserInfo = ref()
|
||||||
const settingModalVisiable = ref(false)
|
const settingModalVisiable = ref(false)
|
||||||
|
const showAddVideoModal = ref(false)
|
||||||
|
const showAddLinkModal = ref(false)
|
||||||
|
|
||||||
|
const indexDisplayInfo = ref<ResponseUserIndexModel>()
|
||||||
|
const addVideoUrl = ref('')
|
||||||
|
const isLoading = ref(false)
|
||||||
|
const addLinkName = ref('')
|
||||||
|
const addLinkUrl = ref('')
|
||||||
|
const linkKey = ref(0)
|
||||||
|
|
||||||
async function RequestBiliUserData() {
|
async function RequestBiliUserData() {
|
||||||
await fetch(FETCH_API + `https://account.bilibili.com/api/member/getCardByMid?mid=10021741`).then(async (respone) => {
|
await fetch(FETCH_API + `https://account.bilibili.com/api/member/getCardByMid?mid=10021741`).then(async (respone) => {
|
||||||
@@ -303,6 +336,96 @@ async function SaveTemplateSetting() {
|
|||||||
await SaveComboSetting()
|
await SaveComboSetting()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async function updateIndexSettings() {
|
||||||
|
await QueryPostAPI(USER_INDEX_API_URL + 'update-setting', accountInfo.value.settings.index)
|
||||||
|
.then((data) => {
|
||||||
|
if (data.code == 200) {
|
||||||
|
message.success('已保存')
|
||||||
|
} else {
|
||||||
|
message.error('保存失败: ' + data.message)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
message.error('保存失败: ' + err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function addVideo() {
|
||||||
|
if (!addVideoUrl.value) {
|
||||||
|
message.error('请输入视频链接')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isLoading.value = true
|
||||||
|
await QueryGetAPI<VideoCollectVideo>(USER_INDEX_API_URL + 'add-video', {
|
||||||
|
video: addVideoUrl.value,
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
if (data.code == 200) {
|
||||||
|
message.success('已添加')
|
||||||
|
indexDisplayInfo.value?.videos.push(data.data)
|
||||||
|
accountInfo.value?.settings.index.videos.push(data.data.id)
|
||||||
|
addVideoUrl.value = ''
|
||||||
|
} else {
|
||||||
|
message.error('保存失败: ' + data.message)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
message.error('保存失败: ' + err)
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
isLoading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function removeVideo(id: string) {
|
||||||
|
isLoading.value = true
|
||||||
|
await QueryGetAPI<VideoCollectVideo>(USER_INDEX_API_URL + 'del-video', {
|
||||||
|
video: id,
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
if (data.code == 200) {
|
||||||
|
message.success('已删除')
|
||||||
|
if (indexDisplayInfo.value) {
|
||||||
|
indexDisplayInfo.value.videos = indexDisplayInfo.value?.videos.filter((v) => v.id != id)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountInfo.value.settings.index.videos = accountInfo.value.settings.index.videos.filter((v) => v != id)
|
||||||
|
} else {
|
||||||
|
message.error('删除失败: ' + data.message)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
message.error('删除失败: ' + err)
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
isLoading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function addLink() {
|
||||||
|
if (!addLinkName.value || !addLinkUrl.value) {
|
||||||
|
message.error('请输入名称和链接')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
new URL(addLinkUrl.value)
|
||||||
|
} catch (e) {
|
||||||
|
message.error('请输入正确的链接')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (Object.keys(accountInfo.value.settings.index.links).includes(addLinkName.value)) {
|
||||||
|
message.error(addLinkName.value + '已存在')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
accountInfo.value.settings.index.links[addLinkName.value] = addLinkUrl.value
|
||||||
|
await updateIndexSettings()
|
||||||
|
addLinkName.value = ''
|
||||||
|
addLinkUrl.value = ''
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
async function removeLink(name: string) {
|
||||||
|
delete accountInfo.value.settings.index.links[name]
|
||||||
|
await updateIndexSettings()
|
||||||
|
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
async function onOpenTemplateSettings() {
|
async function onOpenTemplateSettings() {
|
||||||
settingModalVisiable.value = true
|
settingModalVisiable.value = true
|
||||||
nextTick(async () => {
|
nextTick(async () => {
|
||||||
@@ -354,6 +477,23 @@ function unblockUser(id: number) {
|
|||||||
message.error(err)
|
message.error(err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
async function getIndexInfo() {
|
||||||
|
try {
|
||||||
|
isLoading.value = true
|
||||||
|
const data = await QueryGetAPI<ResponseUserIndexModel>(USER_INDEX_API_URL + 'get', { id: accountInfo.value.id })
|
||||||
|
if (data.code == 200) {
|
||||||
|
return data.data
|
||||||
|
} else if (data.code != 404) {
|
||||||
|
message?.error('无法获取数据: ' + data.message)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
message?.error('无法获取数据: ' + err)
|
||||||
|
return undefined
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onActivated(() => {
|
onActivated(() => {
|
||||||
if (route.query.tab) {
|
if (route.query.tab) {
|
||||||
@@ -365,6 +505,10 @@ onActivated(() => {
|
|||||||
})
|
})
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await RequestBiliUserData()
|
await RequestBiliUserData()
|
||||||
|
indexDisplayInfo.value = await getIndexInfo()
|
||||||
|
if (route.query.tab) {
|
||||||
|
message.info('已切换到指定面板, 在页面下方')
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -403,6 +547,57 @@ onMounted(async () => {
|
|||||||
</NCheckbox>
|
</NCheckbox>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
</NTabPane>
|
</NTabPane>
|
||||||
|
<NTabPane tab="主页" name="index">
|
||||||
|
<NDivider> 通知 </NDivider>
|
||||||
|
<NInput v-model:value="accountInfo.settings.index.notification" type="textarea" />
|
||||||
|
<br /><br />
|
||||||
|
<NButton type="primary" @click="updateIndexSettings"> 保存 </NButton>
|
||||||
|
<NDivider> 展示视频 </NDivider>
|
||||||
|
<NButton type="primary" @click="showAddVideoModal = true"> 添加视频 </NButton>
|
||||||
|
<br /><br />
|
||||||
|
<NEmpty v-if="accountInfo.settings.index.videos.length == 0" />
|
||||||
|
<NFlex v-else>
|
||||||
|
<NCard v-for="item in indexDisplayInfo?.videos ?? []" :key="item.id" style="width: 300px">
|
||||||
|
<SimpleVideoCard :video="item" />
|
||||||
|
<template #footer>
|
||||||
|
<NButton type="warning" @click="removeVideo(item.id)"> 删除 </NButton>
|
||||||
|
</template>
|
||||||
|
</NCard>
|
||||||
|
</NFlex>
|
||||||
|
<NDivider> 其他链接 </NDivider>
|
||||||
|
<NButton type="primary" @click="showAddLinkModal = true"> 添加链接 </NButton>
|
||||||
|
<br /><br />
|
||||||
|
<NEmpty v-if="Object.entries(indexDisplayInfo?.links ?? {}).length == 0" />
|
||||||
|
<NFlex v-else :key="linkKey">
|
||||||
|
<NFlex v-for="item in Object.entries(indexDisplayInfo?.links ?? {})" :key="item[0]" align="center">
|
||||||
|
<NTooltip>
|
||||||
|
<template #trigger>
|
||||||
|
<NTag :bordered="false" size="small" type="info">
|
||||||
|
{{ item[0] }}
|
||||||
|
</NTag>
|
||||||
|
</template>
|
||||||
|
{{ item[1] }}
|
||||||
|
</NTooltip>
|
||||||
|
<NPopconfirm @positive-click="removeLink(item[0])">
|
||||||
|
<template #trigger>
|
||||||
|
<NButton type="error" text>
|
||||||
|
<template #icon>
|
||||||
|
<NIcon :component="Delete24Regular" />
|
||||||
|
</template>
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
确定要删除这个链接吗?
|
||||||
|
</NPopconfirm>
|
||||||
|
</NFlex>
|
||||||
|
</NFlex>
|
||||||
|
<NModal v-model:show="showAddLinkModal" :show-icon="false" preset="dialog" title="添加链接">
|
||||||
|
<NFlex vertical>
|
||||||
|
<NInput v-model:value="addLinkName" placeholder="链接名称" />
|
||||||
|
<NInput v-model:value="addLinkUrl" placeholder="链接地址" />
|
||||||
|
<NButton type="primary" @click="addLink"> 添加 </NButton>
|
||||||
|
</NFlex>
|
||||||
|
</NModal>
|
||||||
|
</NTabPane>
|
||||||
<NTabPane tab="黑名单" name="blacklist">
|
<NTabPane tab="黑名单" name="blacklist">
|
||||||
<NList v-if="accountInfo.biliBlackList && Object.keys(accountInfo.biliBlackList).length > 0">
|
<NList v-if="accountInfo.biliBlackList && Object.keys(accountInfo.biliBlackList).length > 0">
|
||||||
<NListItem v-for="item in Object.entries(accountInfo.biliBlackList)" :key="item[0]">
|
<NListItem v-for="item in Object.entries(accountInfo.biliBlackList)" :key="item[0]">
|
||||||
@@ -470,4 +665,15 @@ onMounted(async () => {
|
|||||||
:config="selectedTemplateConfig"
|
:config="selectedTemplateConfig"
|
||||||
/>
|
/>
|
||||||
</NModal>
|
</NModal>
|
||||||
|
<NModal
|
||||||
|
preset="card"
|
||||||
|
v-model:show="showAddVideoModal"
|
||||||
|
closable
|
||||||
|
style="width: 600px; max-width: 90vw"
|
||||||
|
title="添加视频"
|
||||||
|
>
|
||||||
|
<NInput v-model:value="addVideoUrl" placeholder="请输入视频链接" />
|
||||||
|
<NDivider />
|
||||||
|
<NButton type="primary" @click="addVideo" :loading="isLoading"> 添加视频 </NButton>
|
||||||
|
</NModal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { isDarkMode } from '@/Utils'
|
import { isDarkMode } from '@/Utils'
|
||||||
import { UserInfo } from '@/api/api-models'
|
import { useAccount } from '@/api/account'
|
||||||
|
import { ResponseUserIndexModel, UserInfo } from '@/api/api-models'
|
||||||
|
import { QueryGetAPI } from '@/api/query'
|
||||||
|
import SimpleVideoCard from '@/components/SimpleVideoCard.vue'
|
||||||
import { TemplateConfig } from '@/data/VTsuruTypes'
|
import { TemplateConfig } from '@/data/VTsuruTypes'
|
||||||
import { NAvatar, NButton, NDivider, NSpace, NText } from 'naive-ui'
|
import { USER_INDEX_API_URL } from '@/data/constants'
|
||||||
|
import { NAlert, NAvatar, NButton, NCard, NDivider, NFlex, NSpace, NText, useMessage } from 'naive-ui'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
defineExpose({ Config, DefaultConfig })
|
||||||
const width = window.innerWidth
|
const width = window.innerWidth
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -11,10 +17,32 @@ const props = defineProps<{
|
|||||||
biliInfo: any | undefined
|
biliInfo: any | undefined
|
||||||
currentData?: any
|
currentData?: any
|
||||||
}>()
|
}>()
|
||||||
|
const isLoading = ref(true)
|
||||||
|
const message = useMessage()
|
||||||
|
const accountInfo = useAccount()
|
||||||
|
|
||||||
|
const indexInfo = ref<ResponseUserIndexModel>((await getIndexInfo()) || ({} as ResponseUserIndexModel))
|
||||||
|
async function getIndexInfo() {
|
||||||
|
try {
|
||||||
|
isLoading.value = true
|
||||||
|
const data = await QueryGetAPI<ResponseUserIndexModel>(USER_INDEX_API_URL + 'get', { id: props.userInfo?.name })
|
||||||
|
if (data.code == 200) {
|
||||||
|
return data.data
|
||||||
|
} else if (data.code != 404) {
|
||||||
|
message?.error('无法获取数据: ' + data.message)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
message?.error('无法获取数据: ' + err)
|
||||||
|
return undefined
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function navigate(url: string) {
|
function navigate(url: string) {
|
||||||
window.open(url, '_blank')
|
window.open(url, '_blank')
|
||||||
}
|
}
|
||||||
defineExpose({ Config, DefaultConfig })
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -50,6 +78,19 @@ export const Config: TemplateConfig<ConfigType> = {
|
|||||||
<template>
|
<template>
|
||||||
<NDivider />
|
<NDivider />
|
||||||
<template v-if="userInfo?.biliId">
|
<template v-if="userInfo?.biliId">
|
||||||
|
<template v-if="userInfo?.id == accountInfo?.id">
|
||||||
|
<NButton type="primary" @click="$router.push({ name: 'manage-index', query: { tab: 'index' } })">
|
||||||
|
自定义个人主页
|
||||||
|
</NButton>
|
||||||
|
<NDivider />
|
||||||
|
</template>
|
||||||
|
<template v-if="indexInfo?.notification">
|
||||||
|
<NCard size="small" content-style="text-align: center">
|
||||||
|
{{ indexInfo?.notification }}
|
||||||
|
</NCard>
|
||||||
|
<br />
|
||||||
|
</template>
|
||||||
|
|
||||||
<NSpace justify="center" align="center" vertical>
|
<NSpace justify="center" align="center" vertical>
|
||||||
<NAvatar
|
<NAvatar
|
||||||
v-if="biliInfo"
|
v-if="biliInfo"
|
||||||
@@ -79,7 +120,31 @@ export const Config: TemplateConfig<ConfigType> = {
|
|||||||
<NButton type="primary" secondary @click="navigate('https://live.bilibili.com/' + userInfo?.biliRoomId)">
|
<NButton type="primary" secondary @click="navigate('https://live.bilibili.com/' + userInfo?.biliRoomId)">
|
||||||
直播间
|
直播间
|
||||||
</NButton>
|
</NButton>
|
||||||
|
<temlate v-if="Object.keys(indexInfo.links || {}).length > 0">
|
||||||
|
<NFlex align="center">
|
||||||
|
<NDivider vertical />
|
||||||
|
<NButton
|
||||||
|
type="info"
|
||||||
|
secondary
|
||||||
|
tag="a"
|
||||||
|
:href="link[1]"
|
||||||
|
target="_blank"
|
||||||
|
v-for="link in Object.entries(indexInfo.links || {})"
|
||||||
|
:key="link[0] + link[1]"
|
||||||
|
>
|
||||||
|
{{ link[0] }}
|
||||||
|
</NButton>
|
||||||
|
</NFlex>
|
||||||
|
</temlate>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
|
<template v-if="indexInfo.videos?.length || 0 > 0">
|
||||||
|
<NDivider>
|
||||||
|
<NText>相关视频</NText>
|
||||||
|
</NDivider>
|
||||||
|
<NFlex justify="center">
|
||||||
|
<SimpleVideoCard v-for="video in indexInfo.videos" :video="video" :key="video.id" />
|
||||||
|
</NFlex>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<NSpace justify="center" align="center">
|
<NSpace justify="center" align="center">
|
||||||
@@ -88,3 +153,4 @@ export const Config: TemplateConfig<ConfigType> = {
|
|||||||
</NSpace>
|
</NSpace>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
import { QueryGetAPI } from '@/api/query' import { USER_INDEX_API_URL } from '@/data/constants'
|
||||||
|
|||||||
Reference in New Issue
Block a user