mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-07 02:46:55 +08:00
cancel no payment
This commit is contained in:
@@ -1,25 +1,19 @@
|
||||
<template>
|
||||
<NSpin v-if="isLoading" show />
|
||||
<component
|
||||
v-else
|
||||
:is="SongListTemplateMap[componentType ?? '']?.compoent"
|
||||
:user-info="userInfo"
|
||||
:bili-info="biliInfo"
|
||||
:currentData="currentData"
|
||||
:live-request-settings="settings"
|
||||
:live-request-active="songsActive"
|
||||
@request-song="requestSong"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
<component v-else ref="dynamicConfigRef" :config="currentConfig"
|
||||
:is="SongListTemplateMap[componentType ?? '']?.compoent" :user-info="userInfo" :bili-info="biliInfo"
|
||||
:currentData="currentData" :live-request-settings="settings" :live-request-active="songsActive"
|
||||
@request-song="requestSong" v-bind="$attrs" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useAccount } from '@/api/account'
|
||||
import { DownloadConfig, downloadConfigDirect, useAccount } from '@/api/account'
|
||||
import { Setting_LiveRequest, SongRequestInfo, SongsInfo, UserInfo } from '@/api/api-models'
|
||||
import { QueryGetAPI, QueryPostAPIWithParams } from '@/api/query'
|
||||
import { SONG_API_URL, SONG_REQUEST_API_URL, SongListTemplateMap } from '@/data/constants'
|
||||
import { TemplateConfig } from '@/data/VTsuruTypes'
|
||||
import { SONG_API_URL, SONG_REQUEST_API_URL, SongListTemplateMap, VTSURU_API_URL } from '@/data/constants'
|
||||
import { NSpin, useMessage } from 'naive-ui'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { computed, onMounted, ref, watch, watchEffect } from 'vue'
|
||||
|
||||
const accountInfo = useAccount()
|
||||
|
||||
@@ -35,6 +29,21 @@ const componentType = computed(() => {
|
||||
return props.template ?? props.userInfo?.extra?.templateTypes['songlist']?.toLowerCase()
|
||||
})
|
||||
const currentData = ref<SongsInfo[]>()
|
||||
const dynamicConfigRef = ref()
|
||||
const selectedTemplateConfig = computed(() => {
|
||||
if (dynamicConfigRef.value?.Config) {
|
||||
return dynamicConfigRef.value?.Config as TemplateConfig<any>
|
||||
}
|
||||
return undefined
|
||||
})
|
||||
const currentConfig = ref()
|
||||
watch(
|
||||
() => dynamicConfigRef,
|
||||
() => {
|
||||
getConfig()
|
||||
},
|
||||
)
|
||||
|
||||
const isLoading = ref(true)
|
||||
const message = useMessage()
|
||||
|
||||
@@ -53,7 +62,7 @@ async function getSongRequestInfo() {
|
||||
if (data.code == 200) {
|
||||
return data.data
|
||||
}
|
||||
} catch (err) {}
|
||||
} catch (err) { }
|
||||
return {} as { songs: SongRequestInfo[]; setting: Setting_LiveRequest }
|
||||
}
|
||||
async function getSongs() {
|
||||
@@ -76,6 +85,23 @@ async function getSongs() {
|
||||
isLoading.value = false
|
||||
})
|
||||
}
|
||||
async function getConfig() {
|
||||
isLoading.value = true
|
||||
await DownloadConfig(selectedTemplateConfig.value!.name)
|
||||
.then((data) => {
|
||||
if (data.msg) {
|
||||
message.error('加载失败: ' + data.msg)
|
||||
} else {
|
||||
currentConfig.value = data.data
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
message.error('加载失败')
|
||||
})
|
||||
.finally(() => {
|
||||
isLoading.value = false
|
||||
})
|
||||
}
|
||||
async function requestSong(song: SongsInfo) {
|
||||
if (song.options || !settings.value.allowFromWeb) {
|
||||
navigator.clipboard.writeText(`${settings.value.orderPrefix} ${song.name}`)
|
||||
|
||||
@@ -47,7 +47,7 @@ function navigate(url: string) {
|
||||
|
||||
<script lang="ts">
|
||||
export type ConfigType = {
|
||||
cover: string
|
||||
test: string
|
||||
}
|
||||
export const DefaultConfig = {} as ConfigType
|
||||
export const Config: TemplateConfig<ConfigType> = {
|
||||
@@ -57,19 +57,12 @@ export const Config: TemplateConfig<ConfigType> = {
|
||||
name: '封面',
|
||||
type: 'image',
|
||||
imageLimit: 1,
|
||||
onUploaded: (url, config) => {
|
||||
config.cover = url instanceof String ? (url as string) : url[0]
|
||||
},
|
||||
key: 'cover',
|
||||
},
|
||||
{
|
||||
name: 'test',
|
||||
name: '测试',
|
||||
type: 'string',
|
||||
data: {
|
||||
get: (d) => d.cover,
|
||||
set: (d, v) => {
|
||||
d.cover = v
|
||||
},
|
||||
},
|
||||
key: 'test',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import { useAccount } from '@/api/account'
|
||||
import { ScheduleWeekInfo, UserInfo } from '@/api/api-models'
|
||||
import ScheduleList from '@/components/ScheduleList.vue'
|
||||
import { NDivider } from 'naive-ui'
|
||||
import { useAccount } from '@/api/account';
|
||||
import ScheduleList from '@/components/ScheduleList.vue';
|
||||
import { ScheduleConfigType } from '@/data/TemplateTypes';
|
||||
import { NDivider } from 'naive-ui';
|
||||
|
||||
const accountInfo = useAccount()
|
||||
|
||||
defineProps<{
|
||||
userInfo: UserInfo | undefined
|
||||
biliInfo: any | undefined
|
||||
currentData: ScheduleWeekInfo[] | undefined
|
||||
}>()
|
||||
defineProps<ScheduleConfigType>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NDivider style="margin-top: 10px" />
|
||||
<ScheduleList v-if="currentData" :schedules="currentData ?? []" :is-self="false" v-bind="$attrs" />
|
||||
<ScheduleList v-if="data" :schedules="data ?? []" :is-self="false" v-bind="$attrs" />
|
||||
<NDivider />
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ScheduleWeekInfo, UserInfo } from '@/api/api-models'
|
||||
import SaveCompoent from '@/components/SaveCompoent.vue'
|
||||
import { ScheduleConfigType } from '@/data/TemplateTypes'
|
||||
import { getWeek, getYear } from 'date-fns'
|
||||
import { NDivider, NSelect, NSpace } from 'naive-ui'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
@@ -8,17 +8,13 @@ import { computed, onMounted, ref } from 'vue'
|
||||
const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
|
||||
const table = ref()
|
||||
|
||||
const props = defineProps<{
|
||||
userInfo: UserInfo | undefined
|
||||
biliInfo: any | undefined
|
||||
currentData: ScheduleWeekInfo[] | undefined
|
||||
}>()
|
||||
const props = defineProps<ScheduleConfigType>()
|
||||
|
||||
const currentWeek = computed(() => {
|
||||
if (props.currentData?.length == 1) {
|
||||
return props.currentData[0]
|
||||
if (props.data?.length == 1) {
|
||||
return props.data[0]
|
||||
}
|
||||
return props.currentData?.find((item) => {
|
||||
return props.data?.find((item) => {
|
||||
if (selectedDate.value) {
|
||||
return item.year + '-' + item.week === selectedDate.value
|
||||
}
|
||||
@@ -26,7 +22,7 @@ const currentWeek = computed(() => {
|
||||
})
|
||||
})
|
||||
const options = computed(() => {
|
||||
return props.currentData?.map((item) => {
|
||||
return props.data?.map((item) => {
|
||||
return {
|
||||
label: item.year + '年' + item.week + '周',
|
||||
value: item.year + '-' + item.week,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { useAccount } from '@/api/account'
|
||||
import { Setting_LiveRequest, SongRequestInfo, SongsInfo, UserInfo } from '@/api/api-models'
|
||||
import { SongsInfo } from '@/api/api-models'
|
||||
import SongList from '@/components/SongList.vue'
|
||||
import { SongListConfigType } from '@/data/TemplateTypes'
|
||||
import LiveRequestOBS from '@/views/obs/LiveRequestOBS.vue'
|
||||
import { CloudAdd20Filled } from '@vicons/fluent'
|
||||
import { NButton, NCard, NCollapse, NCollapseItem, NDivider, NIcon, NTooltip, useMessage } from 'naive-ui'
|
||||
@@ -10,19 +11,13 @@ import { h, ref } from 'vue'
|
||||
const accountInfo = useAccount()
|
||||
|
||||
//所有模板都应该有这些
|
||||
const props = defineProps<{
|
||||
userInfo: UserInfo | undefined
|
||||
biliInfo: any | undefined
|
||||
songRequestSettings: Setting_LiveRequest
|
||||
songRequestActive: SongRequestInfo[]
|
||||
currentData?: SongsInfo[] | undefined
|
||||
}>()
|
||||
const props = defineProps<SongListConfigType>()
|
||||
const emits = defineEmits(['requestSong'])
|
||||
|
||||
const isLoading = ref('')
|
||||
const message = useMessage()
|
||||
|
||||
const buttoms = (song: SongsInfo) => [
|
||||
const buttons = (song: SongsInfo) => [
|
||||
accountInfo.value?.id != props.userInfo?.id
|
||||
? h(
|
||||
NTooltip,
|
||||
@@ -62,10 +57,10 @@ const buttoms = (song: SongsInfo) => [
|
||||
<template>
|
||||
<NDivider style="margin-top: 10px" />
|
||||
<SongList
|
||||
v-if="currentData"
|
||||
:songs="currentData ?? []"
|
||||
v-if="data"
|
||||
:songs="data ?? []"
|
||||
:is-self="accountInfo?.id == userInfo?.id"
|
||||
:extra-buttom="buttoms"
|
||||
:extraButton="buttons"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
<NCollapse v-if="userInfo?.canRequestSong">
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { GetGuardColor } from '@/Utils'
|
||||
import { useAccount } from '@/api/account'
|
||||
import { FunctionTypes, Setting_LiveRequest, SongRequestInfo, SongsInfo, UserInfo } from '@/api/api-models'
|
||||
import { FunctionTypes, SongsInfo } from '@/api/api-models'
|
||||
import SongPlayer from '@/components/SongPlayer.vue'
|
||||
import { SongListConfigType } from '@/data/TemplateTypes'
|
||||
import LiveRequestOBS from '@/views/obs/LiveRequestOBS.vue'
|
||||
import { CloudAdd20Filled, Play24Filled } from '@vicons/fluent'
|
||||
import { useWindowSize } from '@vueuse/core'
|
||||
@@ -28,13 +29,7 @@ import {
|
||||
} from 'naive-ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
userInfo: UserInfo | undefined
|
||||
biliInfo: any | undefined
|
||||
songRequestSettings: Setting_LiveRequest
|
||||
songRequestActive: SongRequestInfo[]
|
||||
currentData: SongsInfo[] | undefined
|
||||
}>()
|
||||
const props = defineProps<SongListConfigType>()
|
||||
const emits = defineEmits(['requestSong'])
|
||||
const windowSize = useWindowSize()
|
||||
const container = ref()
|
||||
@@ -51,10 +46,10 @@ const isLrcLoading = ref('')
|
||||
const isLoading = ref('')
|
||||
|
||||
const tags = computed(() => {
|
||||
if (props.currentData) {
|
||||
if (props.data) {
|
||||
return [
|
||||
...new Set(
|
||||
props.currentData
|
||||
props.data
|
||||
.map((item) => {
|
||||
return item.tags ?? []
|
||||
})
|
||||
@@ -65,10 +60,10 @@ const tags = computed(() => {
|
||||
return []
|
||||
})
|
||||
const authors = computed(() => {
|
||||
if (props.currentData) {
|
||||
if (props.data) {
|
||||
return [
|
||||
...new Set(
|
||||
props.currentData
|
||||
props.data
|
||||
.map((item) => {
|
||||
return item.author ?? []
|
||||
})
|
||||
@@ -79,8 +74,8 @@ const authors = computed(() => {
|
||||
return []
|
||||
})
|
||||
const songs = computed(() => {
|
||||
if (props.currentData) {
|
||||
return props.currentData
|
||||
if (props.data) {
|
||||
return props.data
|
||||
.filter((item) => {
|
||||
return (
|
||||
(!selectedTag.value || item.tags?.includes(selectedTag.value)) &&
|
||||
@@ -99,8 +94,8 @@ const onScroll = throttle((e: Event) => {
|
||||
}
|
||||
}, 100)
|
||||
function loadMore() {
|
||||
if (props.currentData) {
|
||||
index.value += props.currentData.length > 20 + index.value ? 20 : props.currentData.length - index.value
|
||||
if (props.data) {
|
||||
index.value += props.data.length > 20 + index.value ? 20 : props.data.length - index.value
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -151,7 +146,7 @@ function loadMore() {
|
||||
/>
|
||||
</NSpace>
|
||||
</NCard>
|
||||
<NEmpty v-if="!currentData || songs?.length == 0" description="暂无曲目" style="max-width: 0 auto" />
|
||||
<NEmpty v-if="!data || songs?.length == 0" description="暂无曲目" style="max-width: 0 auto" />
|
||||
<NScrollbar
|
||||
v-else
|
||||
ref="container"
|
||||
@@ -301,7 +296,7 @@ function loadMore() {
|
||||
</NGrid>
|
||||
<NDivider />
|
||||
<NSpace justify="center">
|
||||
<NButton v-if="currentData.length > index" @click="loadMore"> 加载更多 </NButton>
|
||||
<NButton v-if="data.length > index" @click="loadMore"> 加载更多 </NButton>
|
||||
</NSpace>
|
||||
</NScrollbar>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<script setup lang="ts">
|
||||
import { Setting_LiveRequest, SongRequestInfo, SongsInfo, UserInfo } from '@/api/api-models';
|
||||
import { SongListConfigType, SongListConfigTypeWithConfig } from '@/data/TemplateTypes';
|
||||
import { TemplateConfig } from '@/data/VTsuruTypes';
|
||||
import { FILE_BASE_URL } from '@/data/constants';
|
||||
|
||||
const props = defineProps<SongListConfigTypeWithConfig<ConfigType>>()
|
||||
defineExpose({ Config, DefaultConfig })
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export type ConfigType = {
|
||||
background: string[],
|
||||
notice: string,
|
||||
}
|
||||
export const DefaultConfig = {} as ConfigType
|
||||
export const Config: TemplateConfig<ConfigType> = {
|
||||
name: 'Template.SongList.Traditional',
|
||||
items: [
|
||||
{
|
||||
name: '背景',
|
||||
type: 'image',
|
||||
imageLimit: 1,
|
||||
key: 'background',
|
||||
onUploaded: (url, config) => {
|
||||
config.background = url
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '公告',
|
||||
type: 'string',
|
||||
key: 'notice',
|
||||
},
|
||||
],
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :style="{
|
||||
backgroundImage: `${props.config?.background ? 'url(' + FILE_BASE_URL + props.config?.background[0] + ')' : ''}`,
|
||||
height: '100%', 'max-width': '100%',
|
||||
minHeight: '400px',
|
||||
backgroundSize: 'cover',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
position: 'relative',
|
||||
}">
|
||||
<div style="{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
min-height: 400px;
|
||||
backdrop-filter: blur(10px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}">
|
||||
<div style="{
|
||||
border-radius: 20px;
|
||||
border: 3px solid var(--pinky-border-color-dark);
|
||||
height: 50px;
|
||||
width: 400px;
|
||||
}">
|
||||
<div v-for="song in props.data" :key="song.id">
|
||||
{{song.name}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user