mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-07 02:46:55 +08:00
add livelottery obs compoent
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
"vue-router": "4",
|
"vue-router": "4",
|
||||||
"vue-turnstile": "^1.0.0",
|
"vue-turnstile": "^1.0.0",
|
||||||
"vue3-aplayer": "^1.7.3",
|
"vue3-aplayer": "^1.7.3",
|
||||||
|
"vue3-marquee": "^4.1.0",
|
||||||
"vuex": "^4.0.0"
|
"vuex": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
30
src/App.vue
30
src/App.vue
@@ -2,18 +2,21 @@
|
|||||||
<NMessageProvider>
|
<NMessageProvider>
|
||||||
<NNotificationProvider>
|
<NNotificationProvider>
|
||||||
<NConfigProvider :theme-overrides="themeOverrides" :theme="theme" style="height: 100vh" :locale="zhCN" :date-locale="dateZhCN">
|
<NConfigProvider :theme-overrides="themeOverrides" :theme="theme" style="height: 100vh" :locale="zhCN" :date-locale="dateZhCN">
|
||||||
<NElement style="height: 100vh">
|
<Suspense>
|
||||||
<Suspense>
|
<div style="height: 100vh">
|
||||||
<ViewerLayout v-if="layout == 'viewer'" />
|
<NElement style="height: 100%;" v-if="layout != 'obs'">
|
||||||
<ManageLayout v-else-if="layout == 'manage'" />
|
<ViewerLayout v-if="layout == 'viewer'" />
|
||||||
<template v-else>
|
<ManageLayout v-else-if="layout == 'manage'" />
|
||||||
<RouterView />
|
<template v-else-if="layout == ''">
|
||||||
</template>
|
<RouterView />
|
||||||
<template #fallback>
|
</template>
|
||||||
<NSpin size="large" show/>
|
</NElement>
|
||||||
</template>
|
<RouterView v-else/>
|
||||||
</Suspense>
|
</div>
|
||||||
</NElement>
|
<template #fallback>
|
||||||
|
<NSpin size="large" show />
|
||||||
|
</template>
|
||||||
|
</Suspense>
|
||||||
</NConfigProvider>
|
</NConfigProvider>
|
||||||
</NNotificationProvider>
|
</NNotificationProvider>
|
||||||
</NMessageProvider>
|
</NMessageProvider>
|
||||||
@@ -38,6 +41,9 @@ const layout = computed(() => {
|
|||||||
} else if (route.path.startsWith('/manage')) {
|
} else if (route.path.startsWith('/manage')) {
|
||||||
document.title = route.meta.title + ' · 管理 · VTsuru'
|
document.title = route.meta.title + ' · 管理 · VTsuru'
|
||||||
return 'manage'
|
return 'manage'
|
||||||
|
} else if (route.path.startsWith('/obs')) {
|
||||||
|
document.title = route.meta.title + ' · OBS · VTsuru'
|
||||||
|
return 'obs'
|
||||||
} else {
|
} else {
|
||||||
document.title = route.meta.title + ' · VTsuru'
|
document.title = route.meta.title + ' · VTsuru'
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ export interface AccountInfo extends UserInfo {
|
|||||||
settings: UserSetting
|
settings: UserSetting
|
||||||
token: string
|
token: string
|
||||||
|
|
||||||
|
biliAuthCode?: string
|
||||||
biliAuthCodeStatus: BiliAuthCodeStatusType
|
biliAuthCodeStatus: BiliAuthCodeStatusType
|
||||||
|
|
||||||
eventFetcherOnline: boolean
|
eventFetcherOnline: boolean
|
||||||
@@ -236,3 +237,22 @@ export interface OpenLiveInfo {
|
|||||||
websocket_info: WebsocketInfo
|
websocket_info: WebsocketInfo
|
||||||
anchor_info: AnchorInfo
|
anchor_info: AnchorInfo
|
||||||
}
|
}
|
||||||
|
export interface OpenLiveLotteryUserInfo {
|
||||||
|
name: string
|
||||||
|
uId: number
|
||||||
|
level?: number
|
||||||
|
avatar: string
|
||||||
|
fans_medal_level: number
|
||||||
|
fans_medal_name: string //粉丝勋章名
|
||||||
|
fans_medal_wearing_status: boolean //该房间粉丝勋章佩戴情况
|
||||||
|
guard_level: number
|
||||||
|
}
|
||||||
|
export enum OpenLiveLotteryType{
|
||||||
|
Waiting,
|
||||||
|
Result
|
||||||
|
}
|
||||||
|
export interface UpdateLiveLotteryUsersModel {
|
||||||
|
users: OpenLiveLotteryUserInfo[]
|
||||||
|
resultUsers: OpenLiveLotteryUserInfo[]
|
||||||
|
type: OpenLiveLotteryType
|
||||||
|
}
|
||||||
@@ -205,6 +205,20 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/obs',
|
||||||
|
name: 'obs',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'live-lottery',
|
||||||
|
name: 'obs-live-lottery',
|
||||||
|
component: () => import('@/views/obs/LiveLotteryOBS.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '直播抽奖',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/:pathMatch(.*)*',
|
path: '/:pathMatch(.*)*',
|
||||||
name: 'notfound',
|
name: 'notfound',
|
||||||
|
|||||||
7
src/views/manage/MusicRequestManage.vue
Normal file
7
src/views/manage/MusicRequestManage.vue
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
1
|
||||||
|
</template>
|
||||||
168
src/views/obs/LiveLotteryOBS.vue
Normal file
168
src/views/obs/LiveLotteryOBS.vue
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { OpenLiveLotteryType, OpenLiveLotteryUserInfo, UpdateLiveLotteryUsersModel } from '@/api/api-models'
|
||||||
|
import { QueryGetAPI } from '@/api/query'
|
||||||
|
import { LOTTERY_API_URL } from '@/data/constants'
|
||||||
|
import { useElementSize } from '@vueuse/core'
|
||||||
|
import { NCard, NDivider, NEmpty, NSpace, NText, useMessage } from 'naive-ui'
|
||||||
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { Vue3Marquee } from 'vue3-marquee'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
code?: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const message = useMessage()
|
||||||
|
const route = useRoute()
|
||||||
|
const currentCode = computed(() => {
|
||||||
|
return props.code ?? route.query.code
|
||||||
|
})
|
||||||
|
const listContainerRef = ref()
|
||||||
|
const { height, width } = useElementSize(listContainerRef)
|
||||||
|
|
||||||
|
const result = ref(await getUsers())
|
||||||
|
const users = computed(() => {
|
||||||
|
return result.value?.users
|
||||||
|
})
|
||||||
|
const isMoreThanContainer = computed(() => {
|
||||||
|
return (users.value?.length ?? 0) * 50 > height.value
|
||||||
|
})
|
||||||
|
|
||||||
|
async function getUsers() {
|
||||||
|
try {
|
||||||
|
const data = await QueryGetAPI<UpdateLiveLotteryUsersModel>(LOTTERY_API_URL + 'live/get-users', {
|
||||||
|
code: currentCode.value,
|
||||||
|
})
|
||||||
|
if (data.code == 200) {
|
||||||
|
console.log('[OPEN-LIVE] 已获历史抽奖用户')
|
||||||
|
return data.data
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
users: [],
|
||||||
|
resultUsers: [],
|
||||||
|
type: OpenLiveLotteryType.Waiting,
|
||||||
|
} as UpdateLiveLotteryUsersModel
|
||||||
|
}
|
||||||
|
|
||||||
|
let timer: any
|
||||||
|
onMounted(() => {
|
||||||
|
timer = setInterval(async () => {
|
||||||
|
const r = await getUsers()
|
||||||
|
if (r) {
|
||||||
|
result.value = r
|
||||||
|
}
|
||||||
|
}, 2000)
|
||||||
|
})
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(timer)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="lottery-background" v-bind="$attrs">
|
||||||
|
<p class="lottery-header">抽奖</p>
|
||||||
|
<NDivider v-if="result.type == OpenLiveLotteryType.Waiting" class="lottery-divider">
|
||||||
|
<p class="lottery-header-count">已有 {{ users?.length ?? 0 }} 人</p>
|
||||||
|
</NDivider>
|
||||||
|
<div class="lottery-content" ref="listContainerRef">
|
||||||
|
<template v-if="users.length > 0">
|
||||||
|
<Vue3Marquee v-if="result.type == OpenLiveLotteryType.Waiting" vertical :pause="!isMoreThanContainer" :duration="20" :style="`height: ${height}px;`">
|
||||||
|
<span class="lottery-list-item" :id="index.toString()" v-for="(user, index) in users" :key="user.uId" style="height: 50px">
|
||||||
|
<img class="lottery-avatar" :src="user.avatar + '@30h'" referrerpolicy="no-referrer" />
|
||||||
|
<div>
|
||||||
|
<p class="lottery-name">{{ user.name }}</p>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</Vue3Marquee>
|
||||||
|
</template>
|
||||||
|
<div v-else style="position: relative; top: 20%">
|
||||||
|
<NEmpty description="暂无人参与" />
|
||||||
|
</div>
|
||||||
|
<template v-if="result.type == OpenLiveLotteryType.Result">
|
||||||
|
<p style="text-align: center; font-size: 20px; margin: 0; font-weight: bold; color: #eeabab">结果</p>
|
||||||
|
<Vue3Marquee v-if="100 * result.resultUsers.length > width" justify="center" style="height: 100px">
|
||||||
|
<div
|
||||||
|
v-for="user in result.resultUsers"
|
||||||
|
:key="user.uId"
|
||||||
|
title="抽奖结果"
|
||||||
|
style="height: 100px; width: 100px; display: flex; flex-direction: column; align-items: center; border-radius: 5px; border: #fff 1px solid; padding: 10px; margin: 10px"
|
||||||
|
>
|
||||||
|
<NSpace vertical>
|
||||||
|
<img height="50" width="50" style="border-radius: 50%" :src="user.avatar + '@50h_50w'" referrerpolicy="no-referrer" />
|
||||||
|
<NText style="font-size: large">
|
||||||
|
{{ user.name }}
|
||||||
|
</NText>
|
||||||
|
</NSpace>
|
||||||
|
</div>
|
||||||
|
</Vue3Marquee>
|
||||||
|
<NSpace justify="center">
|
||||||
|
<div
|
||||||
|
v-for="user in result.resultUsers"
|
||||||
|
:key="user.uId"
|
||||||
|
title="抽奖结果"
|
||||||
|
style="height: 100px; width: 100px; display: flex; flex-direction: column; align-items: center; border-radius: 5px; border: #fff 1px solid; padding: 10px; margin: 10px"
|
||||||
|
>
|
||||||
|
<img height="50" width="50" style="border-radius: 50%" :src="user.avatar + '@50h_50w'" referrerpolicy="no-referrer" />
|
||||||
|
<NText style="font-size: large; margin-top: 10px">
|
||||||
|
{{ user.name }}
|
||||||
|
</NText>
|
||||||
|
</div>
|
||||||
|
</NSpace>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.lottery-background {
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: column !important;
|
||||||
|
height: 100% !important;
|
||||||
|
width: 100% !important;
|
||||||
|
min-height: 100px !important;
|
||||||
|
min-width: 100px !important;
|
||||||
|
background-color: #0f0f0f48 !important;
|
||||||
|
border-radius: 10px !important;
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
.lottery-header {
|
||||||
|
margin: 0 !important;
|
||||||
|
color: #fff !important;
|
||||||
|
text-align: center !important;
|
||||||
|
font-size: 24px !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
text-shadow: 0 0 10px #ca7b7b6e, 0 0 20px #ffffff8e, 0 0 30px #61606086, 0 0 40px rgba(64, 156, 179, 0.555) !important;
|
||||||
|
}
|
||||||
|
.lottery-header-count {
|
||||||
|
color: #ffffffbd !important;
|
||||||
|
text-align: center !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
}
|
||||||
|
.lottery-divider {
|
||||||
|
margin: -10px 10px -10px 10px !important;
|
||||||
|
width: 90% !important;
|
||||||
|
}
|
||||||
|
.n-divider__line {
|
||||||
|
background-color: #ffffffd5 !important;
|
||||||
|
}
|
||||||
|
.lottery-content {
|
||||||
|
background-color: #0f0f0f4f !important;
|
||||||
|
margin: 10px !important;
|
||||||
|
padding: 10px !important;
|
||||||
|
height: 100% !important;
|
||||||
|
border-radius: 10px !important;
|
||||||
|
}
|
||||||
|
.lottery-list-item {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
gap: 10px !important;
|
||||||
|
transition: color 0.3s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||||
|
}
|
||||||
|
.lottery-avatar {
|
||||||
|
height: 30px !important;
|
||||||
|
border-radius: 50% !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, h, onMounted, ref } from 'vue'
|
import { computed, h, onMounted, onUnmounted, ref } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { QueryPostAPI } from '@/api/query'
|
import { QueryGetAPI, QueryPostAPI } from '@/api/query'
|
||||||
import { OPEN_LIVE_API_URL } from '@/data/constants'
|
import { LOTTERY_API_URL, OPEN_LIVE_API_URL } from '@/data/constants'
|
||||||
import { LotteryUserInfo, OpenLiveInfo } from '@/api/api-models'
|
import { LotteryUserInfo, OpenLiveInfo, OpenLiveLotteryType, OpenLiveLotteryUserInfo } from '@/api/api-models'
|
||||||
import {
|
import {
|
||||||
NAlert,
|
NAlert,
|
||||||
NAvatar,
|
NAvatar,
|
||||||
NButton,
|
NButton,
|
||||||
NCard,
|
NCard,
|
||||||
NCheckbox,
|
NCheckbox,
|
||||||
|
NCollapse,
|
||||||
|
NCollapseItem,
|
||||||
NCollapseTransition,
|
NCollapseTransition,
|
||||||
NDivider,
|
NDivider,
|
||||||
NEmpty,
|
NEmpty,
|
||||||
@@ -21,6 +23,7 @@ import {
|
|||||||
NInputGroupLabel,
|
NInputGroupLabel,
|
||||||
NInputNumber,
|
NInputNumber,
|
||||||
NLayoutContent,
|
NLayoutContent,
|
||||||
|
NLi,
|
||||||
NList,
|
NList,
|
||||||
NListItem,
|
NListItem,
|
||||||
NModal,
|
NModal,
|
||||||
@@ -33,6 +36,7 @@ import {
|
|||||||
NTag,
|
NTag,
|
||||||
NTime,
|
NTime,
|
||||||
NTooltip,
|
NTooltip,
|
||||||
|
NUl,
|
||||||
useMessage,
|
useMessage,
|
||||||
useNotification,
|
useNotification,
|
||||||
} from 'naive-ui'
|
} from 'naive-ui'
|
||||||
@@ -41,6 +45,7 @@ import ChatClientDirectOpenLive from '@/data/chat/ChatClientDirectOpenLive.js'
|
|||||||
import { useLocalStorage, useStorage } from '@vueuse/core'
|
import { useLocalStorage, useStorage } from '@vueuse/core'
|
||||||
import { format } from 'date-fns'
|
import { format } from 'date-fns'
|
||||||
import { Delete24Filled, Info24Filled } from '@vicons/fluent'
|
import { Delete24Filled, Info24Filled } from '@vicons/fluent'
|
||||||
|
import LiveLotteryOBS from '../obs/LiveLotteryOBS.vue'
|
||||||
|
|
||||||
interface AuthInfo {
|
interface AuthInfo {
|
||||||
Timestamp: string
|
Timestamp: string
|
||||||
@@ -49,18 +54,6 @@ interface AuthInfo {
|
|||||||
Caller: string
|
Caller: string
|
||||||
CodeSign: string
|
CodeSign: string
|
||||||
}
|
}
|
||||||
interface OpenLiveLotteryBaseUserInfo {
|
|
||||||
name: string
|
|
||||||
uId: number
|
|
||||||
level?: number
|
|
||||||
avatar: string
|
|
||||||
}
|
|
||||||
interface OpenLiveLotteryUserInfo extends OpenLiveLotteryBaseUserInfo {
|
|
||||||
fans_medal_level: number
|
|
||||||
fans_medal_name: string //粉丝勋章名
|
|
||||||
fans_medal_wearing_status: boolean //该房间粉丝勋章佩戴情况
|
|
||||||
guard_level: number
|
|
||||||
}
|
|
||||||
interface LotteryOption {
|
interface LotteryOption {
|
||||||
resultCount: number
|
resultCount: number
|
||||||
lotteryType: 'single' | 'half'
|
lotteryType: 'single' | 'half'
|
||||||
@@ -75,7 +68,7 @@ interface LotteryOption {
|
|||||||
giftName?: string
|
giftName?: string
|
||||||
}
|
}
|
||||||
interface LotteryHistory {
|
interface LotteryHistory {
|
||||||
users: OpenLiveLotteryBaseUserInfo[]
|
users: OpenLiveLotteryUserInfo[]
|
||||||
time: number
|
time: number
|
||||||
}
|
}
|
||||||
const CMD_CALLBACK_MAP = {
|
const CMD_CALLBACK_MAP = {
|
||||||
@@ -102,6 +95,9 @@ const notification = useNotification()
|
|||||||
|
|
||||||
const authInfo = ref<AuthInfo>()
|
const authInfo = ref<AuthInfo>()
|
||||||
const authResult = ref<OpenLiveInfo | null>(null)
|
const authResult = ref<OpenLiveInfo | null>(null)
|
||||||
|
const code = computed(() => {
|
||||||
|
return authInfo.value?.Code ?? accountInfo.value?.biliAuthCode
|
||||||
|
})
|
||||||
|
|
||||||
const originUsers = ref<OpenLiveLotteryUserInfo[]>([])
|
const originUsers = ref<OpenLiveLotteryUserInfo[]>([])
|
||||||
const currentUsers = ref<OpenLiveLotteryUserInfo[]>([])
|
const currentUsers = ref<OpenLiveLotteryUserInfo[]>([])
|
||||||
@@ -111,6 +107,7 @@ const isLottering = ref(false)
|
|||||||
const isLotteried = ref(false)
|
const isLotteried = ref(false)
|
||||||
const isConnected = ref(false)
|
const isConnected = ref(false)
|
||||||
const showModal = ref(false)
|
const showModal = ref(false)
|
||||||
|
const showOBSModal = ref(false)
|
||||||
|
|
||||||
let chatClient: any
|
let chatClient: any
|
||||||
|
|
||||||
@@ -129,6 +126,30 @@ async function get() {
|
|||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
async function getUsers() {
|
||||||
|
try {
|
||||||
|
const data = await QueryGetAPI<OpenLiveLotteryUserInfo[]>(LOTTERY_API_URL + 'live/get-users', {
|
||||||
|
code: code.value,
|
||||||
|
})
|
||||||
|
if (data.code == 200) {
|
||||||
|
console.log('[OPEN-LIVE] 已获历史抽奖用户')
|
||||||
|
return data.data
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
function updateUsers() {
|
||||||
|
QueryPostAPI(LOTTERY_API_URL + 'live/update-users', {
|
||||||
|
code: code.value,
|
||||||
|
users: originUsers.value,
|
||||||
|
resultUsers: resultUsers.value,
|
||||||
|
type: isLotteried.value ? OpenLiveLotteryType.Result : OpenLiveLotteryType.Waiting,
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error('[OPEN-LIVE] 更新历史抽奖用户失败: ' + err)
|
||||||
|
})
|
||||||
|
}
|
||||||
async function start() {
|
async function start() {
|
||||||
if (!chatClient) {
|
if (!chatClient) {
|
||||||
const auth = await get()
|
const auth = await get()
|
||||||
@@ -160,6 +181,7 @@ function addUser(user: OpenLiveLotteryUserInfo, danmu: any) {
|
|||||||
originUsers.value.push(user)
|
originUsers.value.push(user)
|
||||||
currentUsers.value.push(user)
|
currentUsers.value.push(user)
|
||||||
console.log(`[OPEN-LIVE-Lottery] ${user.name} 添加到队列中`)
|
console.log(`[OPEN-LIVE-Lottery] ${user.name} 添加到队列中`)
|
||||||
|
updateUsers()
|
||||||
} else {
|
} else {
|
||||||
console.log(`[OPEN-LIVE-Lottery] ${user.name} 因不符合条件而被忽略`)
|
console.log(`[OPEN-LIVE-Lottery] ${user.name} 因不符合条件而被忽略`)
|
||||||
}
|
}
|
||||||
@@ -264,6 +286,7 @@ function onFinishLottery() {
|
|||||||
message.success('已保存至历史')
|
message.success('已保存至历史')
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
updateUsers()
|
||||||
lotteryHistory.value.push({
|
lotteryHistory.value.push({
|
||||||
users: currentUsers.value ?? [],
|
users: currentUsers.value ?? [],
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
@@ -272,6 +295,7 @@ function onFinishLottery() {
|
|||||||
function reset() {
|
function reset() {
|
||||||
currentUsers.value = JSON.parse(JSON.stringify(originUsers.value))
|
currentUsers.value = JSON.parse(JSON.stringify(originUsers.value))
|
||||||
isLotteried.value = false
|
isLotteried.value = false
|
||||||
|
updateUsers()
|
||||||
}
|
}
|
||||||
function clear() {
|
function clear() {
|
||||||
originUsers.value = []
|
originUsers.value = []
|
||||||
@@ -279,10 +303,14 @@ function clear() {
|
|||||||
resultUsers.value = []
|
resultUsers.value = []
|
||||||
currentUsers.value = []
|
currentUsers.value = []
|
||||||
message.success('已清空队列')
|
message.success('已清空队列')
|
||||||
|
|
||||||
|
updateUsers()
|
||||||
}
|
}
|
||||||
function removeUser(user: OpenLiveLotteryUserInfo) {
|
function removeUser(user: OpenLiveLotteryUserInfo) {
|
||||||
currentUsers.value = currentUsers.value.filter((u) => u.uId != user.uId)
|
currentUsers.value = currentUsers.value.filter((u) => u.uId != user.uId)
|
||||||
originUsers.value = originUsers.value.filter((u) => u.uId != user.uId)
|
originUsers.value = originUsers.value.filter((u) => u.uId != user.uId)
|
||||||
|
|
||||||
|
updateUsers()
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDanmaku(command: any) {
|
function onDanmaku(command: any) {
|
||||||
@@ -324,16 +352,51 @@ function continueLottery() {
|
|||||||
message.info('开始监听')
|
message.info('开始监听')
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
let timer: any
|
||||||
|
onMounted(async () => {
|
||||||
authInfo.value = route.query as unknown as AuthInfo
|
authInfo.value = route.query as unknown as AuthInfo
|
||||||
|
if (authInfo.value?.Code) {
|
||||||
|
const users = (await getUsers()) ?? []
|
||||||
|
originUsers.value = users
|
||||||
|
currentUsers.value = JSON.parse(JSON.stringify(users))
|
||||||
|
console.log('[OPEN-LIVE-Lottery] 从历史记录中加载 ' + users.length + ' 位用户')
|
||||||
|
if (users.length > 0) {
|
||||||
|
message.info('从历史记录中加载 ' + users.length + ' 位用户')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timer = setInterval(updateUsers, 1000 * 10)
|
||||||
|
|
||||||
|
const data: OpenLiveLotteryUserInfo[] = []
|
||||||
|
|
||||||
|
for (let i = 0; i < 13; i++) {
|
||||||
|
const userInfo: OpenLiveLotteryUserInfo = {
|
||||||
|
name: `User ${i + 1}`,
|
||||||
|
uId: i + 1,
|
||||||
|
level: i + 10,
|
||||||
|
avatar: `http://i0.hdslb.com/bfs/face/284f87fba8ff1b9c9564925747c7dc456df65cca.jpg`,
|
||||||
|
fans_medal_level: i + 1,
|
||||||
|
fans_medal_name: `Fans Medal ${i + 1}`,
|
||||||
|
fans_medal_wearing_status: true,
|
||||||
|
guard_level: i + 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
data.push(userInfo)
|
||||||
|
}
|
||||||
|
originUsers.value = data
|
||||||
|
currentUsers.value = JSON.parse(JSON.stringify(data))
|
||||||
|
})
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (timer) {
|
||||||
|
clearInterval(timer)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NLayoutContent style="height: 100vh">
|
<NLayoutContent style="height: 100vh; padding: 20px">
|
||||||
<NResult v-if="!authInfo?.Code && !accountInfo" status="403" title="403" description="该页面只能从饭贩访问或者注册用户使用" />
|
<NResult v-if="!authInfo?.Code && !accountInfo" status="403" title="403" description="该页面只能从饭贩访问或者注册用户使用" />
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<NCard style="margin: 20px">
|
<NCard>
|
||||||
<template #header>
|
<template #header>
|
||||||
直播抽奖
|
直播抽奖
|
||||||
<NDivider vertical />
|
<NDivider vertical />
|
||||||
@@ -349,6 +412,7 @@ onMounted(() => {
|
|||||||
连接直播间
|
连接直播间
|
||||||
</NButton>
|
</NButton>
|
||||||
<NButton type="info" @click="showModal = true" size="small"> 抽奖历史</NButton>
|
<NButton type="info" @click="showModal = true" size="small"> 抽奖历史</NButton>
|
||||||
|
<NButton type="success" @click="showOBSModal = true" size="small"> OBS组件</NButton>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
</NCard>
|
</NCard>
|
||||||
<NCard size="small" embedded title="抽奖选项">
|
<NCard size="small" embedded title="抽奖选项">
|
||||||
@@ -503,5 +567,27 @@ onMounted(() => {
|
|||||||
</NScrollbar>
|
</NScrollbar>
|
||||||
<NEmpty v-else description="暂无记录" />
|
<NEmpty v-else description="暂无记录" />
|
||||||
</NModal>
|
</NModal>
|
||||||
|
<NModal v-model:show="showOBSModal" preset="card" title="OBS 组件" style="max-width: 90%; width: 800px; max-height: 90vh" closable content-style="overflow: auto">
|
||||||
|
<NAlert title="这是什么? " type="info"> 将等待队列以及结果显示在OBS中 </NAlert>
|
||||||
|
<NDivider> 浏览 </NDivider>
|
||||||
|
<div style="height: 400px; width: 250px; position: relative; margin: 0 auto">
|
||||||
|
<LiveLotteryOBS :code="code" />
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<NInput :value="'https://localhost:5173/obs/live-lottery?code=' + code" />
|
||||||
|
<NDivider />
|
||||||
|
<NCollapse>
|
||||||
|
<NCollapseItem title="使用说明">
|
||||||
|
<NUl>
|
||||||
|
<NLi>在 OBS 来源中添加源, 选择 浏览器</NLi>
|
||||||
|
<NLi>在 URL 栏填入上方链接</NLi>
|
||||||
|
<NLi>根据自己的需要调整宽度和高度</NLi>
|
||||||
|
<NLi>完事</NLi>
|
||||||
|
</NUl>
|
||||||
|
</NCollapseItem>
|
||||||
|
</NCollapse>
|
||||||
|
|
||||||
|
<NDivider />
|
||||||
|
</NModal>
|
||||||
</NLayoutContent>
|
</NLayoutContent>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
11
src/views/view/songListTemplate/SimpleSongListTemplate.vue
Normal file
11
src/views/view/songListTemplate/SimpleSongListTemplate.vue
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
import { NGridItem,NGrid } from 'naive-ui';
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<NGrid>
|
||||||
|
<NGridItem>
|
||||||
|
|
||||||
|
</NGridItem>
|
||||||
|
</NGrid>
|
||||||
|
</template>
|
||||||
@@ -3362,6 +3362,11 @@ vue3-aplayer@^1.7.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
vue-loader "^16.1.2"
|
vue-loader "^16.1.2"
|
||||||
|
|
||||||
|
vue3-marquee@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue3-marquee/-/vue3-marquee-4.1.0.tgz#145baa65dd40059358e4079d51ab596c2ccf1299"
|
||||||
|
integrity sha512-AkvpNC6+7CwvIBgiAr8qMs1XvhGhfSS2ahlMEp80YXAmDOP8nDdn/smQ6eWtusf+hLX21yTaSOoKGcill4bCRg==
|
||||||
|
|
||||||
vue@^3.2.13, vue@^3.2.45:
|
vue@^3.2.13, vue@^3.2.45:
|
||||||
version "3.3.7"
|
version "3.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.3.7.tgz#972a218682443a3819d121261b2bff914417f4f0"
|
resolved "https://registry.yarnpkg.com/vue/-/vue-3.3.7.tgz#972a218682443a3819d121261b2bff914417f4f0"
|
||||||
|
|||||||
Reference in New Issue
Block a user