add 'pinky' template

This commit is contained in:
2023-10-27 14:31:25 +08:00
parent a733ca8ae7
commit 558c9a047e
20 changed files with 559 additions and 258 deletions

View File

@@ -33,6 +33,7 @@ import { NButton, NCard, NDivider, NLayoutContent, NSpace, NText, NTimeline, NTi
</NSpace>
<NDivider title-placement="left"> 更新日志 </NDivider>
<NTimeline>
<NTimelineItem type="info" title="功能更新" content="日程表添加 '粉粉' 模板" time="2023-10-27" />
<NTimelineItem type="info" title="功能更新" content="提问箱新增公开选项" time="2023-10-26" />
<NTimelineItem type="success" title="功能添加" content="提问箱分享卡片" time="2023-10-25" />
<NTimelineItem type="success" title="功能添加" content="舰长及SC记录" time="2023-10-24" line-type="dashed" />

View File

@@ -1,6 +1,26 @@
<!-- eslint-disable vue/component-name-in-template-casing -->
<script setup lang="ts">
import { NAvatar, NIcon, NLayout, NLayoutHeader, NLayoutSider, NMenu, NSpace, NText, NButton, NResult, NPageHeader, NSwitch, NModal, NEllipsis, MenuOption, NSpin, NLayoutContent, NBackTop } from 'naive-ui'
import {
NAvatar,
NIcon,
NLayout,
NLayoutHeader,
NLayoutSider,
NMenu,
NSpace,
NText,
NButton,
NResult,
NPageHeader,
NSwitch,
NModal,
NEllipsis,
MenuOption,
NSpin,
NLayoutContent,
NBackTop,
NScrollbar,
} from 'naive-ui'
import { computed, h, onMounted, ref } from 'vue'
import { BookOutline as BookIcon, Chatbox, Home, Moon, MusicalNote, PersonOutline as PersonIcon, Sunny, WineOutline as WineIcon } from '@vicons/ionicons5'
import { GetInfo, useUser, useUserWithUId } from '@/api/user'
@@ -49,10 +69,8 @@ async function RequestBiliUserData() {
}
onMounted(async () => {
const result = await GetInfo(id.value?.toString())
if (result.code == 200) {
userInfo.value = result.data
} else {
userInfo.value = await useUser(id.value?.toString())
if (!userInfo.value) {
notfount.value = true
}
@@ -181,15 +199,19 @@ onMounted(async () => {
class="viewer-page-content"
:style="`box-shadow:${isDarkMode() ? 'rgb(28 28 28 / 9%) 5px 5px 6px inset, rgba(139, 139, 139, 0.09) -5px -5px 6px inset' : 'inset 5px 5px 6px #8b8b8b17, inset -5px -5px 6px #8b8b8b17;'}`"
>
<RouterView v-if="userInfo" v-slot="{ Component }">
<KeepAlive>
<component :is="Component" :bili-info="biliUserInfo" :user-info="userInfo" />
</KeepAlive>
<RouterView v-if="userInfo" v-slot="{ Component, route }">
<Transition name="fade" mode="out-in">
<KeepAlive>
<div :key="route.name">
<component :is="Component" :bili-info="biliUserInfo" :user-info="userInfo" />
</div>
</KeepAlive>
</Transition>
</RouterView>
<template v-else>
<NSpin show />
</template>
<NBackTop/>
<NBackTop />
</div>
</NLayout>
</NLayout>
@@ -206,5 +228,6 @@ onMounted(async () => {
padding: 15px;
margin-right: 10px;
box-sizing: border-box;
overflow-y: auto;
}
</style>

View File

@@ -79,26 +79,27 @@ const exportType = ref<'json' | 'xml' | 'csv'>('csv')
async function onDateChange() {
isLoading.value = true
await QueryGetAPI<EventModel[]>(BASE_API + 'event/get', {
start: selectedDate.value[0],
end: selectedDate.value[1],
})
.then((data) => {
if (data.code == 200) {
events.value = new List(data.data).OrderByDescending((d) => d.time).ToArray()
message.success('已获取数据')
//selectedType.value = type
} else {
message.error('获取数据失败: ' + data.message)
}
})
.catch((err) => {
console.error(err)
message.error('获取数据失败')
})
.finally(() => {
isLoading.value = false
const data = await get()
events.value = data
isLoading.value = false
}
async function get() {
try {
const data = await QueryGetAPI<EventModel[]>(BASE_API + 'event/get', {
start: selectedDate.value[0],
end: selectedDate.value[1],
})
if (data.code == 200) {
message.success('已获取数据')
return new List(data.data).OrderByDescending((d) => d.time).ToArray()
} else {
message.error('获取数据失败: ' + data.message)
return []
}
} catch (err) {
message.error('获取数据失败')
return []
}
}
function GetSCColor(price: number): string {
if (price === 0) return `#2a60b2`
@@ -219,7 +220,13 @@ onMounted(() => {
<NAvatar round lazy borderd :size="64" :src="AVATAR_URL + item.uId" :img-props="{ referrerpolicy: 'no-referrer' }" style="box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2)" />
<NSpace>
<NTag size="tiny" v-if="selectedType == EventType.Guard" :bordered="false"> {{ item.msg }} </NTag>
<NTag size="tiny" round :color="{ color: selectedType == EventType.Guard ? GetGuardColor(item.price) : GetSCColor(item.price), textColor: 'white', borderColor: isDarkMode() ? 'white' : '#00000000' }"> {{ item.price }} </NTag>
<NTag
size="tiny"
round
:color="{ color: selectedType == EventType.Guard ? GetGuardColor(item.price) : GetSCColor(item.price), textColor: 'white', borderColor: isDarkMode() ? 'white' : '#00000000' }"
>
{{ item.price }}
</NTag>
</NSpace>
<NText>
{{ item.name }}

View File

@@ -360,10 +360,9 @@ onMounted(() => {
<NCard :bordered="false" size="small">
<template #header>
<NSpace align="center">
<NTag size="small" type="warning" :bordered="false">
{{ item.target.name }}
</NTag>
<NText depth="3">
回复
</NText>
</NSpace>
</template>
{{ item.answer.message }}

View File

@@ -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>

View File

@@ -1,17 +1,15 @@
<template>
<NSpin v-if="isLoading" show />
<component v-else v-bind="$attrs" :is="componentType" :user-info="userInfo" :currentData="currentData" />
<component v-else :is="ScheduleTemplateMap[componentType ?? ''].compoent" :bili-info="biliInfo" :user-info="userInfo" :currentData="currentData" v-bind="$attrs" />
</template>
<script lang="ts" setup>
import { ScheduleWeekInfo } from '@/api/api-models'
import DefaultScheduleTemplate from '@/views/view/scheduleTemplate/DefaultScheduleTemplate.vue'
import { computed, onMounted, ref, watch } from 'vue'
import { UserInfo } from '@/api/api-models'
import { QueryGetAPI } from '@/api/query'
import { SCHEDULE_API_URL } from '@/data/constants'
import { SCHEDULE_API_URL, ScheduleTemplateMap } from '@/data/constants'
import { NSpin, useMessage } from 'naive-ui'
import PinkySchedule from './scheduleTemplate/PinkySchedule.vue'
import { computed, onMounted, ref } from 'vue'
const props = defineProps<{
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -22,19 +20,7 @@ const props = defineProps<{
}>()
const componentType = computed(() => {
const type = props.template ?? props.userInfo?.extra?.templateTypes['schedule']?.toLowerCase()
if (props.userInfo) {
switch (type?.toLocaleLowerCase()) {
case 'test':
return DefaultScheduleTemplate
case 'pinkyschedule':
return PinkySchedule
default:
return DefaultScheduleTemplate
}
} else {
return DefaultScheduleTemplate
}
return props.template ?? props.userInfo?.extra?.templateTypes['schedule']?.toLowerCase()
})
const currentData = ref<ScheduleWeekInfo[]>()
const isLoading = ref(true)

View File

@@ -1,6 +1,6 @@
<template>
<NSpin v-if="isLoading" show />
<component v-else :is="componentType" :user-info="userInfo" :currentData="currentData" />
<component v-else :is="componentType" :user-info="userInfo" :bili-info="biliInfo" :currentData="currentData" />
</template>
<script lang="ts" setup>

View File

@@ -8,6 +8,7 @@ const width = window.innerWidth
const props = defineProps<{
userInfo: UserInfo | undefined
biliInfo: any | undefined
currentData: any
}>()
function navigate(url: string) {
window.open(url, '_blank')
@@ -24,6 +25,9 @@ function navigate(url: string) {
:size="width > 750 ? 175 : 100"
round
bordered
:img-props="{
referrerpolicy: 'no-referrer'
}"
:style="{ boxShadow: isDarkMode() ? 'rgb(195 192 192 / 35%) 0px 5px 20px' : '0 5px 15px rgba(0, 0, 0, 0.2)' }"
/>
<NSpace align="baseline" justify="center">

View File

@@ -8,6 +8,7 @@ const accountInfo = useAccount()
defineProps<{
userInfo: UserInfo | undefined
biliInfo: any | undefined
currentData: ScheduleWeekInfo[] | undefined
}>()
</script>

View File

@@ -1,23 +1,167 @@
<script setup lang="ts">
import { ScheduleWeekInfo, UserInfo } from '@/api/api-models';
import { ScheduleWeekInfo, UserInfo } from '@/api/api-models'
import { getYear, getWeek, startOfWeek } from 'date-fns'
import { NDivider, NSelect, NSpace } from 'naive-ui'
import { computed, onMounted, ref } from 'vue'
import SaveCompoent from '@/components/SaveCompoent.vue'
defineProps<{
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 currentWeek = computed(() => {
if (props.currentData?.length == 1) {
return props.currentData[0]
}
return props.currentData?.find((item) => {
if (selectedDate.value) {
return item.year + '-' + item.week === selectedDate.value
}
return isTodayInWeek(item.year, item.week)
})
})
const options = computed(() => {
return props.currentData?.map((item) => {
return {
label: item.year + '年' + item.week + '周',
value: item.year + '-' + item.week,
}
})
})
const selectedDate = ref<string>()
function isTodayInWeek(year: number, week: number): boolean {
const today = new Date()
const todayYear = getYear(today)
const todayWeek = getWeek(today, { weekStartsOn: 1 })
return todayYear === year && todayWeek === week
}
onMounted(() => {
if (currentWeek.value) {
selectedDate.value = currentWeek.value.year + '-' + currentWeek.value.week
}
})
</script>
<template>
<div class="schedule-template pinky">
<div v-for="item in currentData" :key="item.week">
test
<NSpace>
<NSelect :options="options" v-model:value="selectedDate" style="max-width: 200px" placeholder="选择其他周表" />
<SaveCompoent :compoent="table" :file-name="`周表_${selectedDate}_${userInfo?.name}`" />
</NSpace>
<NDivider />
<div ref="table" class="schedule-template pinky container">
<div class="schedule-template pinky day-container">
<div class="schedule-template pinky day-item" :id="index.toString()" v-for="(item, index) in currentWeek?.days" :key="index">
<div class="schedule-template pinky header">
<span class="schedule-template pinky week">
{{ days[index] }}
</span>
<span class="schedule-template pinky time">
{{ item.time }}
</span>
<span class="schedule-template pinky tag">
{{ item.tag }}
</span>
</div>
<div class="schedule-template pinky day-content-container">
<span v-if="item.tag" class="schedule-template pinky day-content" id="work">
{{ item.title }}
</span>
<span v-else class="schedule-template pinky day-content" id="rest"> 休息 </span>
</div>
</div>
</div>
<div class="schedule-template pinky title-container">
<div class="schedule-template pinky title">S C H E D U L E</div>
</div>
</div>
</template>
<style scoped>
.schedule-template pinky {
background-color: #ebf0fa;
.schedule-template.pinky.container {
--pinky-font-color-dark: #dba2a2c9;
--pinky-border-color-dark: #eeb9b9;
width: 540px;
height: 700px;
border-radius: 20px;
background-color: #faebeb;
background-image: linear-gradient(90deg, #ffffff 10%, rgba(0, 0, 0, 0) 10%), linear-gradient(#ffffff 10%, rgba(0, 0, 0, 0) 10%);
background-size: 20px 20px;
border: 3px solid #e0cbcb;
}
.schedule-template.pinky.day-container {
display: flex;
width: 500px;
margin-top: 10px;
flex-wrap: wrap;
flex-direction: column;
margin-left: 20px;
}
.schedule-template.pinky.day-content-container {
height: 50px;
border-radius: 15px;
border: 3px solid var(--pinky-border-color-dark);
border-top: none;
border-left: none;
background-color: #f5dadac9;
}
.schedule-template.pinky.header {
position: relative;
height: 30px;
font-size: 16px;
font-weight: bold;
color: #dba2a2c9;
top: 2px;
}
.schedule-template.pinky.week {
position: relative;
left: 5px;
}
.schedule-template.pinky.time {
position: relative;
left: 15px;
}
.schedule-template.pinky.tag {
position: absolute;
text-align: right;
right: 5px;
}
.schedule-template.pinky.day-content {
position: relative;
top: 10px;
left: 10px;
font-size: 18px;
font-weight: 550;
color: #af8080c9;
}
.schedule-template.pinky.day-content#rest {
color: #cfb7b7c9;
font-style: italic;
}
.schedule-template.pinky.title-container {
position: relative;
background: #fdf8f8c9;
width: 400px;
height: 70px;
left: 70px;
top: 20px;
border-radius: 20px;
border: 3px solid var(--pinky-border-color-dark);
border-top: none;
border-left: none;
}
.schedule-template.pinky.title {
position: relative;
top: -5px;
font-size: 50px;
text-align: center;
color: var(--pinky-font-color-dark);
}
</style>

View File

@@ -8,6 +8,7 @@ const accountInfo = useAccount()
defineProps<{
userInfo: UserInfo | undefined
biliInfo: any | undefined
currentData: SongsInfo[] | undefined
}>()
</script>