💄 美化生日组件

This commit is contained in:
目棃
2024-04-05 01:10:58 +08:00
parent 33edb3c33a
commit 914cddafc1
5 changed files with 113 additions and 68 deletions

View File

@@ -1,16 +1,21 @@
<!-- todo ui 优化结合 birth_calendar/birth_role 数据 -->
<template> <template>
<div class="tcb-container"> <div class="tcb-container">
<img v-if="!isBirthday" src="/source/UI/empty.webp" alt="empty" /> <div class="tcb-top-none" v-if="!isBirthday">
<img @click="toPost()" v-else src="/source/UI/act_birthday.png" alt="empty" class="active" /> <img src="/source/UI/empty.webp" alt="empty" />
<span v-if="isBirthday" class="tcb-label" @click="toBirth('today')"> <span>今天没有角色过生日哦~</span>
今天是{{ cur.map((i) => i.name).join("、") }}的生日哦~ </div>
</span> <div class="tcb-top-active" @click="toBirth(true)" v-else>
<span v-else>今天没有角色过生日哦~</span> <img @click="toPost()" src="/source/UI/act_birthday.png" alt="empty" class="active" />
<span v-if="next.length > 0" @click="toBirth('next')" class="tcb-label" <span>今天是{{ cur.map((i) => i.name).join("、") }}的生日哦~</span>
>即将到来{{ next[0].birthday[0] }}{{ next[0].birthday[1] }}</span </div>
> <div>即将到来{{ next[0].role_birthday }}</div>
<span v-if="next.length > 0">{{ next.map((i) => i.name).join("、") }}</span> <div v-for="i in next" :key="i.role_id" class="tcb-item" @click="toBirth(i)">
<img :src="i.head_icon" :alt="i.introduce" />
<div class="tcb-item-info">
<span>{{ i.name }} 所属{{ i.belong }}</span>
<span>{{ i.text }}</span>
</div>
</div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@@ -21,11 +26,11 @@ import TSAvatarBirth from "../../plugins/Sqlite/modules/avatarBirth";
const isBirthday = ref<boolean>(false); const isBirthday = ref<boolean>(false);
const router = useRouter(); const router = useRouter();
const cur = ref<TGApp.Sqlite.Character.AppData[]>([]); const cur = ref<TGApp.Archive.Birth.CalendarItem[]>([]);
const next = ref<TGApp.App.Character.WikiBriefInfo[]>([]); const next = ref<TGApp.Archive.Birth.RoleItem[]>([]);
onBeforeMount(async () => { onBeforeMount(async () => {
const check = await TSAvatarBirth.isAvatarBirth(); const check = TSAvatarBirth.isAvatarBirth();
if (check.length !== 0) { if (check.length !== 0) {
isBirthday.value = true; isBirthday.value = true;
cur.value = check; cur.value = check;
@@ -37,17 +42,15 @@ async function toPost() {
await router.push("/news/2"); await router.push("/news/2");
} }
function toBirth(type: "today" | "next") { function toBirth(type: TGApp.Archive.Birth.RoleItem | true) {
let dateStr; let dateStr;
if (type === "today") { if (type === true) {
const date = new Date(); const date = new Date();
const month = date.getMonth() + 1; const month = date.getMonth() + 1;
const day = date.getDate(); const day = date.getDate();
dateStr = `${month}/${day}`; dateStr = `${month}/${day}`;
} else { } else {
const month = next.value[0].birthday[0]; dateStr = type.role_birthday;
const day = next.value[0].birthday[1];
dateStr = `${month}/${day}`;
} }
router.push({ name: "留影叙佳期", params: { date: dateStr } }); router.push({ name: "留影叙佳期", params: { date: dateStr } });
} }
@@ -58,30 +61,61 @@ function toBirth(type: "today" | "next") {
width: 100%; width: 100%;
height: 100%; height: 100%;
flex-direction: column; flex-direction: column;
align-items: center; align-items: flex-start;
justify-content: center; justify-content: center;
padding: 10px;
border-radius: 5px;
box-shadow: 0 0 5px inset var(--common-shadow-2); box-shadow: 0 0 5px inset var(--common-shadow-2);
overflow-y: auto; overflow-y: auto;
} }
.tcb-container img { .tcb-top-none,
width: 100px; .tcb-top-active {
display: flex;
height: 100px; height: 100px;
align-items: center;
justify-content: center;
} }
.tcb-container img.active { .tcb-top-none img,
.tcb-top-active img {
width: 50px;
height: 50px;
}
.tcb-top-active img.active {
cursor: pointer; cursor: pointer;
} }
span { .tcb-item {
display: block; position: relative;
margin-top: 10px; display: flex;
text-align: center; width: 100%;
align-items: center;
justify-content: flex-start;
padding: 5px;
border-radius: 10px;
background: var(--box-bg-1);
} }
.tcb-label { .tcb-item img {
flex-wrap: wrap; height: 100px;
aspect-ratio: 1;
cursor: pointer; cursor: pointer;
}
.tcb-item-info {
display: flex;
flex-direction: column;
justify-content: center;
}
.tcb-item-info :first-child {
font-family: var(--font-title);
font-size: 20px;
}
.tcb-item-info :last-child {
word-break: break-all; word-break: break-all;
} }
</style> </style>

View File

@@ -24,7 +24,7 @@
>{{ text.text }} >{{ text.text }}
</v-btn> </v-btn>
</div> </div>
<v-pagination class="tc-page" v-model="page" total-visible="20" :length="length" /> <v-pagination class="tc-page" v-model="page" :total-visible="visible" :length="length" />
</div> </div>
<div class="tc-content"> <div class="tc-content">
<TCalendarBirth /> <TCalendarBirth />
@@ -58,6 +58,7 @@ const dateNow = ref<string>("");
// page // page
const page = ref<number>(1); const page = ref<number>(1);
const length = ref<number>(0); const length = ref<number>(0);
const visible = 16;
// calendar // calendar
const calendarNow = ref<TGApp.App.Calendar.Item[]>([]); const calendarNow = ref<TGApp.App.Calendar.Item[]>([]);
@@ -140,8 +141,8 @@ function getGrid(): TGApp.App.Calendar.Item[] {
} else { } else {
selectedCards = weaponCards.value; selectedCards = weaponCards.value;
} }
length.value = Math.ceil(selectedCards.length / 20); length.value = Math.ceil(selectedCards.length / visible);
return selectedCards.slice((page.value - 1) * 20, page.value * 20); return selectedCards.slice((page.value - 1) * visible, page.value * visible);
} }
function selectItem(item: TGApp.App.Calendar.Item): void { function selectItem(item: TGApp.App.Calendar.Item): void {
@@ -196,7 +197,7 @@ function getContents(day: number): void {
display: grid; display: grid;
height: 100%; height: 100%;
grid-gap: 10px; grid-gap: 10px;
grid-template-columns: repeat(10, 100px); grid-template-columns: repeat(8, 100px);
place-items: flex-start flex-start; place-items: flex-start flex-start;
} }
</style> </style>

View File

@@ -1,3 +1,4 @@
<!-- todo 角色名片 -->
<template> <template>
<div class="twc-box" v-if="data !== undefined"> <div class="twc-box" v-if="data !== undefined">
<div class="twc-brief"> <div class="twc-brief">
@@ -20,7 +21,11 @@
<span>命之座</span> <span>命之座</span>
<span>{{ data.brief.constellation }}</span> <span>{{ data.brief.constellation }}</span>
</div> </div>
<div class="twc-big-item"> <div
class="twc-big-item active"
title="点击查看生日画片"
@click="toBirth(data.brief.birth)"
>
<span>生日</span> <span>生日</span>
<span>{{ data.brief.birth }}</span> <span>{{ data.brief.birth }}</span>
</div> </div>
@@ -92,6 +97,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue"; import { computed, onMounted, ref, watch } from "vue";
import { useRouter } from "vue-router";
import TwcConstellations from "./twc-constellations.vue"; import TwcConstellations from "./twc-constellations.vue";
import TwcMaterials from "./twc-materials.vue"; import TwcMaterials from "./twc-materials.vue";
@@ -125,6 +131,7 @@ const box = computed(() => {
clickable: false, clickable: false,
}; };
}); });
const router = useRouter();
async function loadData(): Promise<void> { async function loadData(): Promise<void> {
const res = WikiCharacterData.find((item) => item.id === props.item.id); const res = WikiCharacterData.find((item) => item.id === props.item.id);
@@ -169,6 +176,11 @@ async function toWiki(): Promise<void> {
true, true,
); );
} }
async function toBirth(date: string): Promise<void> {
const birth = date.replace("月", "/").replace("日", "");
await router.push({ name: "留影叙佳期", params: { date: birth } });
}
</script> </script>
<style lang="css" scoped> <style lang="css" scoped>
.twc-box { .twc-box {
@@ -232,6 +244,10 @@ async function toWiki(): Promise<void> {
column-gap: 5px; column-gap: 5px;
} }
.twc-big-item.active {
cursor: pointer;
}
.twc-big-item :nth-child(1) { .twc-big-item :nth-child(1) {
font-weight: bold; font-weight: bold;
} }

View File

@@ -30,12 +30,12 @@
<div class="ab-di-text" :title="item.word_text">{{ item.word_text }}</div> <div class="ab-di-text" :title="item.word_text">{{ item.word_text }}</div>
</div> </div>
</div> </div>
<v-pagination v-model="page" :length="length" /> <v-pagination v-model="page" :length="length" :total-visible="visible" />
</div> </div>
<ToArcBrith v-model="showOverlay" :data="current" :choice="isAether" /> <ToArcBrith v-model="showOverlay" :data="current" :choice="isAether" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, ref, watch, watchEffect } from "vue"; import { onMounted, ref, watch } from "vue";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import ToArcBrith from "../../components/overlay/to-arcBrith.vue"; import ToArcBrith from "../../components/overlay/to-arcBrith.vue";
@@ -67,9 +67,6 @@ watch(curSelect, (val) => {
} }
length.value = Math.ceil(renderItems.value.length / 12); length.value = Math.ceil(renderItems.value.length / 12);
page.value = 1; page.value = 1;
});
watchEffect(() => {
selectedItem.value = renderItems.value.slice(0, 12); selectedItem.value = renderItems.value.slice(0, 12);
visible.value = length.value > 5 ? 5 : length.value; visible.value = length.value > 5 ? 5 : length.value;
}); });

View File

@@ -4,35 +4,38 @@
* @since Beta v0.4.5 * @since Beta v0.4.5
*/ */
import { AppCharacterData } from "../../../data"; import { ArcBirCalendar, ArcBirRole } from "../../../data";
import TGSqlite from "../index";
/** /**
* @description 判断今天是不是角色生日 * @description 判断今天是不是角色生日
* @since Beta v0.4.5 * @since Beta v0.4.5
* @param {[number,number]} date - 日期 * @return {TGApp.Archive.Birth.CalendarItem[]} 角色生日
* @return {Promise<TGApp.Sqlite.Character.AppData[]>} 角色生日
*/ */
async function isAvatarBirth(date?: [number, number]): Promise<TGApp.Sqlite.Character.AppData[]> { function isAvatarBirth(): TGApp.Archive.Birth.CalendarItem[] {
let dateNow: [number, number];
if (date) {
dateNow = date;
} else {
const date = new Date(); const date = new Date();
dateNow = [date.getMonth() + 1, date.getDate()]; const month = date.getMonth() + 1;
} const day = date.getDate();
const db = await TGSqlite.getDB(); const days = ArcBirCalendar[month];
const sql = "SELECT * FROM AppCharacters WHERE birthday = ?"; return days.filter((i) => i.role_birthday === `${month}/${day}`);
return await db.select(sql, [dateNow.join(",")]); }
/**
* @description 获取角色生日
* @since Beta v0.4.5
* @param {string} roleBirthday - 角色生日
* @return {[number,number]} 角色生日
*/
function getRoleBirth(roleBirthday: string): [number, number] {
return roleBirthday.split("/").map(Number) as [number, number];
} }
/** /**
* @description 获取下一个角色生日 * @description 获取下一个角色生日
* @since Beta v0.4.5 * @since Beta v0.4.5
* @param {[number,number]} date - 日期 * @param {[number,number]} date - 日期
* @return {TGApp.Sqlite.Character.AppData[]} 下一个角色生日 * @return {TGApp.Archive.Birth.RoleItem[]} 下一个角色生日
*/ */
function getNextAvatarBirth(date?: [number, number]): TGApp.App.Character.WikiBriefInfo[] { function getNextAvatarBirth(date?: [number, number]): TGApp.Archive.Birth.RoleItem[] {
const year = new Date().getFullYear(); const year = new Date().getFullYear();
let month, day; let month, day;
if (date) { if (date) {
@@ -44,24 +47,18 @@ function getNextAvatarBirth(date?: [number, number]): TGApp.App.Character.WikiBr
day = dateNow.getDate(); day = dateNow.getDate();
} }
const birthDateList: Date[] = []; const birthDateList: Date[] = [];
for (const item of AppCharacterData) { for (const item of ArcBirRole) {
if (item.birthday[0] === 0) { const roleBirth = getRoleBirth(item.role_birthday);
continue; if (roleBirth[0] < month || (roleBirth[0] === month && roleBirth[1] <= day)) {
} birthDateList.push(new Date(year + 1, roleBirth[0] - 1, roleBirth[1]));
if (item.birthday[0] < month || (item.birthday[0] === month && item.birthday[1] <= day)) {
birthDateList.push(new Date(year + 1, item.birthday[0] - 1, item.birthday[1]));
} else { } else {
birthDateList.push(new Date(year, item.birthday[0] - 1, item.birthday[1])); birthDateList.push(new Date(year, roleBirth[0] - 1, roleBirth[1]));
} }
} }
birthDateList.sort((a, b) => a.getTime() - b.getTime()); birthDateList.sort((a, b) => a.getTime() - b.getTime());
const nextDateGet = birthDateList[0]; const nextDateGet = birthDateList[0];
const nextDate = [nextDateGet.getMonth() + 1, nextDateGet.getDate()]; const nextDate = [nextDateGet.getMonth() + 1, nextDateGet.getDate()];
return ( return ArcBirRole.filter((i) => i.role_birthday === `${nextDate[0]}/${nextDate[1]}`);
AppCharacterData.filter(
(item) => item.birthday[0] === nextDate[0] && item.birthday[1] === nextDate[1],
) ?? []
);
} }
const TSAvatarBirth = { const TSAvatarBirth = {