mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-07 02:46:55 +08:00
add 'pinky' template
This commit is contained in:
@@ -1,18 +1,158 @@
|
||||
<script setup lang="ts">
|
||||
import { useAccount } from '@/api/account'
|
||||
import { NButton, NCard, NCheckbox, NCheckboxGroup, NDivider, NForm, NSelect, NSpace, NSwitch, NTabPane, NTabs, SelectOption, useMessage } from 'naive-ui'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useRequest } from 'vue-request'
|
||||
import { NButton, NCard, NCheckbox, NCheckboxGroup, NDivider, NForm, NModal, NSelect, NSpace, NSpin, NSwitch, NTabPane, NTabs, SelectOption, useMessage } from 'naive-ui'
|
||||
import { Ref, computed, h, onMounted, ref, defineAsyncComponent } from 'vue'
|
||||
import { FunctionTypes, ScheduleWeekInfo, SongFrom, SongLanguage, SongsInfo } from '@/api/api-models'
|
||||
import { QueryPostAPI } from '@/api/query'
|
||||
import { ACCOUNT_API_URL, FETCH_API } from '@/data/constants'
|
||||
import ScheduleView from '../view/ScheduleView.vue'
|
||||
import UserIndexView from '../view/UserIndexView.vue'
|
||||
import SongListView from '../view/SongListView.vue'
|
||||
import { ACCOUNT_API_URL, FETCH_API, IndexTemplateMap, ScheduleTemplateMap, SongListTemplateMap } from '@/data/constants'
|
||||
|
||||
interface TemplateDefineTypes {
|
||||
TemplateMap: { [name: string]: { name: string; compoent: any } }
|
||||
Options: SelectOption[]
|
||||
Data: any
|
||||
Selected: Ref<string>
|
||||
}
|
||||
|
||||
const accountInfo = useAccount()
|
||||
const message = useMessage()
|
||||
|
||||
const isSaving = ref(false)
|
||||
|
||||
const templates = {
|
||||
index: {
|
||||
TemplateMap: IndexTemplateMap,
|
||||
Options: Object.entries(IndexTemplateMap).map((v) => ({
|
||||
label: v[1].name,
|
||||
value: v[0],
|
||||
})),
|
||||
Data: null,
|
||||
Selected: ref(accountInfo.value?.settings.indexTemplate ?? ''),
|
||||
},
|
||||
schedule: {
|
||||
TemplateMap: ScheduleTemplateMap,
|
||||
Options: Object.entries(ScheduleTemplateMap).map((v) => ({
|
||||
label: v[1].name,
|
||||
value: v[0],
|
||||
})),
|
||||
Data: [
|
||||
{
|
||||
year: 2023,
|
||||
week: 30,
|
||||
days: [
|
||||
{
|
||||
title: '唱唱歌!',
|
||||
tag: '歌回',
|
||||
tagColor: '#61B589',
|
||||
time: '10:00 AM',
|
||||
},
|
||||
{
|
||||
title: '玩点游戏',
|
||||
tag: '游戏',
|
||||
tagColor: '#A36565',
|
||||
time: '20:00 PM',
|
||||
},
|
||||
{
|
||||
title: 'Title 3',
|
||||
tag: 'Tag 3',
|
||||
tagColor: '#7BCDEF',
|
||||
time: '11:00 PM',
|
||||
},
|
||||
{
|
||||
title: null,
|
||||
tag: null,
|
||||
tagColor: null,
|
||||
time: null,
|
||||
},
|
||||
{
|
||||
title: null,
|
||||
tag: null,
|
||||
tagColor: null,
|
||||
time: null,
|
||||
},
|
||||
{
|
||||
title: null,
|
||||
tag: null,
|
||||
tagColor: null,
|
||||
time: null,
|
||||
},
|
||||
{
|
||||
title: null,
|
||||
tag: null,
|
||||
tagColor: null,
|
||||
time: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
] as ScheduleWeekInfo[],
|
||||
Selected: ref(accountInfo.value?.settings.scheduleTemplate ?? ''),
|
||||
},
|
||||
songlist: {
|
||||
TemplateMap: SongListTemplateMap,
|
||||
Options: Object.entries(SongListTemplateMap).map((v) => ({
|
||||
label: v[1].name,
|
||||
value: v[0],
|
||||
})),
|
||||
Data: [
|
||||
{
|
||||
id: 1,
|
||||
key: 'song1',
|
||||
name: '歌曲1',
|
||||
author: ['作者1'],
|
||||
url: 'https://example.com/song1.mp3',
|
||||
from: SongFrom.Custom,
|
||||
language: [SongLanguage.Chinese],
|
||||
createTime: Date.now(),
|
||||
updateTime: Date.now(),
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
key: 'song2',
|
||||
name: '歌曲2',
|
||||
author: ['作者2'],
|
||||
url: 'https://example.com/song2.mp3',
|
||||
from: SongFrom.Custom,
|
||||
language: [SongLanguage.Chinese],
|
||||
createTime: Date.now(),
|
||||
updateTime: Date.now(),
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
key: 'song3',
|
||||
name: '歌曲3',
|
||||
author: ['作者3'],
|
||||
url: 'https://example.com/song3.mp3',
|
||||
from: SongFrom.Custom,
|
||||
language: [SongLanguage.Chinese],
|
||||
createTime: Date.now(),
|
||||
updateTime: Date.now(),
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
key: 'song4',
|
||||
name: '歌曲4',
|
||||
author: ['作者4'],
|
||||
url: 'https://example.com/song4.mp3',
|
||||
from: SongFrom.Custom,
|
||||
language: [SongLanguage.Chinese],
|
||||
createTime: Date.now(),
|
||||
updateTime: Date.now(),
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
key: 'song5',
|
||||
name: '歌曲5',
|
||||
author: ['作者5'],
|
||||
url: 'https://example.com/song5.mp3',
|
||||
from: SongFrom.Custom,
|
||||
language: [SongLanguage.Chinese],
|
||||
createTime: Date.now(),
|
||||
updateTime: Date.now(),
|
||||
},
|
||||
] as SongsInfo[],
|
||||
Selected: ref(accountInfo.value?.settings.songListTemplate ?? ''),
|
||||
},
|
||||
} as { [type: string]: TemplateDefineTypes }
|
||||
|
||||
const templateOptions = [
|
||||
{
|
||||
label: '主页',
|
||||
@@ -27,147 +167,14 @@ const templateOptions = [
|
||||
value: 'schedule',
|
||||
},
|
||||
] as SelectOption[]
|
||||
const fakeSongList = [
|
||||
{
|
||||
id: 1,
|
||||
key: 'song1',
|
||||
name: '歌曲1',
|
||||
author: ['作者1'],
|
||||
url: 'https://example.com/song1.mp3',
|
||||
from: SongFrom.Custom,
|
||||
language: [SongLanguage.Chinese],
|
||||
createTime: Date.now(),
|
||||
updateTime: Date.now(),
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
key: 'song2',
|
||||
name: '歌曲2',
|
||||
author: ['作者2'],
|
||||
url: 'https://example.com/song2.mp3',
|
||||
from: SongFrom.Custom,
|
||||
language: [SongLanguage.Chinese],
|
||||
createTime: Date.now(),
|
||||
updateTime: Date.now(),
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
key: 'song3',
|
||||
name: '歌曲3',
|
||||
author: ['作者3'],
|
||||
url: 'https://example.com/song3.mp3',
|
||||
from: SongFrom.Custom,
|
||||
language: [SongLanguage.Chinese],
|
||||
createTime: Date.now(),
|
||||
updateTime: Date.now(),
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
key: 'song4',
|
||||
name: '歌曲4',
|
||||
author: ['作者4'],
|
||||
url: 'https://example.com/song4.mp3',
|
||||
from: SongFrom.Custom,
|
||||
language: [SongLanguage.Chinese],
|
||||
createTime: Date.now(),
|
||||
updateTime: Date.now(),
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
key: 'song5',
|
||||
name: '歌曲5',
|
||||
author: ['作者5'],
|
||||
url: 'https://example.com/song5.mp3',
|
||||
from: SongFrom.Custom,
|
||||
language: [SongLanguage.Chinese],
|
||||
createTime: Date.now(),
|
||||
updateTime: Date.now(),
|
||||
},
|
||||
] as SongsInfo[]
|
||||
const fakeSchedule = [
|
||||
{
|
||||
year: 2023,
|
||||
week: 30,
|
||||
days: [
|
||||
{
|
||||
title: '唱唱歌!',
|
||||
tag: '歌回',
|
||||
tagColor: '#61B589',
|
||||
time: '10:00',
|
||||
},
|
||||
{
|
||||
title: '玩点游戏',
|
||||
tag: '游戏',
|
||||
tagColor: '#A36565',
|
||||
time: '20:00',
|
||||
},
|
||||
{
|
||||
title: 'Title 3',
|
||||
tag: 'Tag 3',
|
||||
tagColor: '#7BCDEF',
|
||||
time: '12:00 PM',
|
||||
},
|
||||
{
|
||||
title: null,
|
||||
tag: null,
|
||||
tagColor: null,
|
||||
time: null,
|
||||
},
|
||||
{
|
||||
title: null,
|
||||
tag: null,
|
||||
tagColor: null,
|
||||
time: null,
|
||||
},
|
||||
{
|
||||
title: null,
|
||||
tag: null,
|
||||
tagColor: null,
|
||||
time: null,
|
||||
},
|
||||
{
|
||||
title: null,
|
||||
tag: null,
|
||||
tagColor: null,
|
||||
time: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
] as ScheduleWeekInfo[]
|
||||
const selectedOption = ref(templateOptions[0].value)
|
||||
const selectedOption = ref('index')
|
||||
const selectedTab = ref('general')
|
||||
|
||||
const scheduleTemplateOptions = [
|
||||
{
|
||||
label: '默认',
|
||||
value: '',
|
||||
},
|
||||
{
|
||||
label: '粉粉',
|
||||
value: 'PinkySchedule',
|
||||
},
|
||||
] as SelectOption[]
|
||||
const selectedScheduleTemplate = ref(accountInfo.value?.settings.scheduleTemplate ?? scheduleTemplateOptions[0].value?.toString())
|
||||
const songListTemplateOptions = [
|
||||
{
|
||||
label: '默认',
|
||||
value: '',
|
||||
},
|
||||
] as SelectOption[]
|
||||
const selectedSongListTemplate = ref(accountInfo.value?.settings.songListTemplate ?? songListTemplateOptions[0].value)
|
||||
const selectedTemplateData = computed(() => templates[selectedOption.value])
|
||||
|
||||
const biliUserInfo = ref()
|
||||
const settingModalVisiable = ref(false)
|
||||
|
||||
function UpdateEnableFunction(func: FunctionTypes, enable: boolean) {
|
||||
if (accountInfo.value) {
|
||||
if (enable) {
|
||||
//从account.value?.settings.enableFunctions中移除指定的func
|
||||
accountInfo.value.settings.enableFunctions = accountInfo.value?.settings.enableFunctions.filter((f) => f != func)
|
||||
} else {
|
||||
accountInfo.value.settings.enableFunctions.push(func)
|
||||
}
|
||||
}
|
||||
}
|
||||
async function RequestBiliUserData() {
|
||||
await fetch(FETCH_API + `https://account.bilibili.com/api/member/getCardByMid?mid=10021741`)
|
||||
.then(async (respone) => {
|
||||
@@ -184,6 +191,7 @@ async function RequestBiliUserData() {
|
||||
}
|
||||
async function SaveComboGroupSetting(value: (string | number)[], meta: { actionType: 'check' | 'uncheck'; value: string | number }) {
|
||||
if (accountInfo.value) {
|
||||
isSaving.value = true
|
||||
//UpdateEnableFunction(meta.value as FunctionTypes, meta.actionType == 'check')
|
||||
await QueryPostAPI(ACCOUNT_API_URL + 'update-setting', accountInfo.value?.settings)
|
||||
.then((data) => {
|
||||
@@ -200,15 +208,19 @@ async function SaveComboGroupSetting(value: (string | number)[], meta: { actionT
|
||||
console.error(err)
|
||||
message.error('修改失败')
|
||||
})
|
||||
.finally(() => {
|
||||
isSaving.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
async function SaveComboSetting(value: boolean) {
|
||||
async function SaveComboSetting() {
|
||||
if (accountInfo.value) {
|
||||
isSaving.value = true
|
||||
//UpdateEnableFunction(meta.value as FunctionTypes, meta.actionType == 'check')
|
||||
await QueryPostAPI(ACCOUNT_API_URL + 'update-setting', accountInfo.value?.settings)
|
||||
.then((data) => {
|
||||
if (data.code == 200) {
|
||||
//message.success('保存成功')
|
||||
message.success('已保存')
|
||||
} else {
|
||||
message.error('修改失败')
|
||||
}
|
||||
@@ -217,19 +229,35 @@ async function SaveComboSetting(value: boolean) {
|
||||
console.error(err)
|
||||
message.error('修改失败')
|
||||
})
|
||||
.finally(() => {
|
||||
isSaving.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
const componentType = computed(() => {
|
||||
switch (selectedOption.value) {
|
||||
case 'index':
|
||||
return UserIndexView
|
||||
case 'songlist':
|
||||
return SongListView
|
||||
case 'schedule':
|
||||
return ScheduleView
|
||||
default:
|
||||
return UserIndexView
|
||||
async function SaveTemplateSetting() {
|
||||
if (accountInfo.value) {
|
||||
switch (selectedOption.value) {
|
||||
case 'index': {
|
||||
accountInfo.value.settings.indexTemplate = selectedTemplateData.value.Selected.value ?? ''
|
||||
break
|
||||
}
|
||||
case 'songlist': {
|
||||
accountInfo.value.settings.songListTemplate = selectedTemplateData.value.Selected.value ?? ''
|
||||
break
|
||||
}
|
||||
case 'schedule': {
|
||||
accountInfo.value.settings.scheduleTemplate = selectedTemplateData.value.Selected.value ?? ''
|
||||
break
|
||||
}
|
||||
}
|
||||
await SaveComboSetting()
|
||||
}
|
||||
}
|
||||
function onOpenTemplateSettings() {
|
||||
settingModalVisiable.value = true
|
||||
}
|
||||
const buttonGroup = computed(() => {
|
||||
return h(NSpace, () => [h(NButton, { type: 'primary', onClick: () => SaveTemplateSetting() }, () => '设为展示模板'), h(NButton, { type: 'info', onClick: onOpenTemplateSettings }, () => '模板设置')])
|
||||
})
|
||||
onMounted(() => {
|
||||
RequestBiliUserData()
|
||||
@@ -238,42 +266,46 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<NCard v-if="accountInfo" title="设置" :style="`${selectedTab === 'general' ? '' : 'min-height: 800px;'}`">
|
||||
<NTabs>
|
||||
<NTabPane tab="常规" name="general">
|
||||
<NDivider style="margin: 0"> 启用功能 </NDivider>
|
||||
<NCheckboxGroup v-model:value="accountInfo.settings.enableFunctions" @update:value="SaveComboGroupSetting">
|
||||
<NCheckbox :value="FunctionTypes.SongList"> 歌单 </NCheckbox>
|
||||
<NCheckbox :value="FunctionTypes.QuestionBox"> 提问箱(棉花糖 </NCheckbox>
|
||||
<NCheckbox :value="FunctionTypes.Schedule"> 日程 </NCheckbox>
|
||||
</NCheckboxGroup>
|
||||
<NDivider> 通知 </NDivider>
|
||||
<NSpace>
|
||||
<NCheckbox v-model:checked="accountInfo.settings.sendEmail.recieveQA" @update:checked="SaveComboSetting"> 收到新提问时发送邮件 </NCheckbox>
|
||||
<NCheckbox v-model:checked="accountInfo.settings.sendEmail.recieveQAReply" @update:checked="SaveComboSetting"> 提问收到回复时发送邮件 </NCheckbox>
|
||||
</NSpace>
|
||||
<NDivider> 提问箱 </NDivider>
|
||||
<NSpace>
|
||||
<NCheckbox v-model:checked="accountInfo.settings.questionBox.allowUnregistedUser" @update:checked="SaveComboSetting"> 允许未注册用户提问 </NCheckbox>
|
||||
</NSpace>
|
||||
</NTabPane>
|
||||
<NTabPane tab="模板" name="template">
|
||||
<NSpace vertical>
|
||||
<NSpace align="center"> 页面 <NSelect :options="templateOptions" v-model:value="selectedOption" style="width: 150px" /> </NSpace>
|
||||
<NDivider style="margin: 5px 0 5px 0" title-placement="left"> 模板 </NDivider>
|
||||
<template v-if="selectedOption == 'index'">
|
||||
<NSelect style="width: 150px" />
|
||||
<UserIndexView :user-info="accountInfo" :bili-info="biliUserInfo" />
|
||||
</template>
|
||||
<template v-else-if="selectedOption == 'songlist'">
|
||||
<NSelect :options="songListTemplateOptions" v-model:value="selectedSongListTemplate" style="width: 150px" />
|
||||
<SongListView :user-info="accountInfo" :bili-info="biliUserInfo" :fake-data="fakeSongList" :is-self="false" />
|
||||
</template>
|
||||
<template v-else-if="selectedOption == 'schedule'">
|
||||
<NSelect :options="scheduleTemplateOptions" v-model:value="selectedScheduleTemplate" style="width: 150px" />
|
||||
<ScheduleView :user-info="accountInfo" :bili-info="biliUserInfo" :fake-data="fakeSchedule" :is-self="false" :template="selectedScheduleTemplate" />
|
||||
</template>
|
||||
</NSpace>
|
||||
</NTabPane>
|
||||
</NTabs>
|
||||
<NSpin :show="isSaving">
|
||||
<NTabs>
|
||||
<NTabPane tab="常规" name="general">
|
||||
<NDivider style="margin: 0"> 启用功能 </NDivider>
|
||||
<NCheckboxGroup v-model:value="accountInfo.settings.enableFunctions" @update:value="SaveComboGroupSetting">
|
||||
<NCheckbox :value="FunctionTypes.SongList"> 歌单 </NCheckbox>
|
||||
<NCheckbox :value="FunctionTypes.QuestionBox"> 提问箱(棉花糖 </NCheckbox>
|
||||
<NCheckbox :value="FunctionTypes.Schedule"> 日程 </NCheckbox>
|
||||
</NCheckboxGroup>
|
||||
<NDivider> 通知 </NDivider>
|
||||
<NSpace>
|
||||
<NCheckbox v-model:checked="accountInfo.settings.sendEmail.recieveQA" @update:checked="SaveComboSetting"> 收到新提问时发送邮件 </NCheckbox>
|
||||
<NCheckbox v-model:checked="accountInfo.settings.sendEmail.recieveQAReply" @update:checked="SaveComboSetting"> 提问收到回复时发送邮件 </NCheckbox>
|
||||
</NSpace>
|
||||
<NDivider> 提问箱 </NDivider>
|
||||
<NSpace>
|
||||
<NCheckbox v-model:checked="accountInfo.settings.questionBox.allowUnregistedUser" @update:checked="SaveComboSetting"> 允许未注册用户提问 </NCheckbox>
|
||||
</NSpace>
|
||||
</NTabPane>
|
||||
<NTabPane tab="模板" name="template">
|
||||
<NSpace vertical>
|
||||
<NSpace align="center"> 页面 <NSelect :options="templateOptions" v-model:value="selectedOption" style="width: 150px" /> </NSpace>
|
||||
<NDivider style="margin: 5px 0 5px 0" title-placement="left"> 模板 </NDivider>
|
||||
<div>
|
||||
<NSpace>
|
||||
<NSelect style="width: 150px" :options="selectedTemplateData.Options" v-model:value="selectedTemplateData.Selected.value" />
|
||||
<component :is="buttonGroup" />
|
||||
</NSpace>
|
||||
<NDivider />
|
||||
<component
|
||||
:is="selectedTemplateData.TemplateMap[selectedTemplateData.Selected.value].compoent"
|
||||
:user-info="accountInfo"
|
||||
:bili-info="biliUserInfo"
|
||||
:current-data="selectedTemplateData.Data"
|
||||
/>
|
||||
</div>
|
||||
</NSpace>
|
||||
</NTabPane>
|
||||
</NTabs>
|
||||
</NSpin>
|
||||
</NCard>
|
||||
<NModal preset="card" v-model:show="settingModalVisiable" closable style="width: 600px; max-width: 90vw" title="模板设置"> 开发中... </NModal>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user