mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-13 09:28:14 +08:00
📦 feat(calendar): 资源本地化
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<v-icon color="#EBD49E">
|
||||
mdi-calendar-clock
|
||||
</v-icon> 今日素材
|
||||
<span style="color: #faf7e8">{{ new Date().toLocaleDateString() }}</span>
|
||||
<span style="color: #faf7e8">{{ dateNow }}</span>
|
||||
<v-btn
|
||||
v-for="text of btnText"
|
||||
:key="text.week"
|
||||
@@ -14,34 +14,80 @@
|
||||
border: text.week === weekNow ? '2px solid #fec90b' : '0',
|
||||
background: text.week === btnNow ? '#fec90b' : '#4A5366',
|
||||
}"
|
||||
@click="getShowCards(text.week)"
|
||||
@click="getContents(text.week)"
|
||||
>
|
||||
{{ text.text }}
|
||||
</v-btn>
|
||||
</v-list-item-title>
|
||||
<div v-if="!loading" class="calendar-grid">
|
||||
<v-card title="天赋培养" class="calendar-single">
|
||||
<v-card-text class="calendar-icons">
|
||||
<v-img
|
||||
v-for="item in showCharacters"
|
||||
:key="item.id"
|
||||
:src="item.cover"
|
||||
class="calendar-icon"
|
||||
@click="showContent(item)"
|
||||
/>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
<v-card title="武器突破" class="calendar-single">
|
||||
<v-card-text class="calendar-icons">
|
||||
<v-img
|
||||
v-for="item in showWeapons"
|
||||
:key="item.id"
|
||||
:src="item.cover"
|
||||
class="calendar-icon"
|
||||
@click="showContent(item)"
|
||||
/>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
<div class="calendar-single">
|
||||
<div class="card-title">
|
||||
天赋培养
|
||||
</div>
|
||||
<div
|
||||
v-for="character of characterCards"
|
||||
:key="character.title"
|
||||
class="calendar-content"
|
||||
>
|
||||
<div class="content-title">
|
||||
{{ character.title }}
|
||||
</div>
|
||||
<div class="content-material">
|
||||
<v-img
|
||||
v-for="material of character.materials"
|
||||
:key="material.content_id"
|
||||
alt="material.content_id"
|
||||
:src="material.icon"
|
||||
class="calendar-icon"
|
||||
@click="showContent(material.content_id)"
|
||||
/>
|
||||
</div>
|
||||
<div class="content-detail">
|
||||
<v-img
|
||||
v-for="content of character.contents"
|
||||
:key="content.content_id"
|
||||
alt="content.content_id"
|
||||
:src="content.icon"
|
||||
class="calendar-icon"
|
||||
@click="showContent(content.content_id)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calendar-single">
|
||||
<div class="card-title">
|
||||
武器突破
|
||||
</div>
|
||||
<div
|
||||
v-for="weapon of weaponCards"
|
||||
:key="weapon.title"
|
||||
class="calendar-content"
|
||||
>
|
||||
<div class="content-title">
|
||||
{{ weapon.title }}
|
||||
</div>
|
||||
<div class="content-material">
|
||||
<v-img
|
||||
v-for="material of weapon.materials"
|
||||
:key="material.content_id"
|
||||
alt="material.content_id"
|
||||
:src="material.icon"
|
||||
class="calendar-icon"
|
||||
@click="showContent(material.content_id)"
|
||||
/>
|
||||
</div>
|
||||
<div class="content-detail">
|
||||
<v-img
|
||||
v-for="content of weapon.contents"
|
||||
:key="content.content_id"
|
||||
alt="content.content_id"
|
||||
:src="content.icon"
|
||||
class="calendar-icon"
|
||||
@click="showContent(content.content_id)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
@@ -49,20 +95,24 @@
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { ref, onMounted } from "vue";
|
||||
// plugins
|
||||
import MysOper from "../plugins/Mys";
|
||||
// data
|
||||
import { TGAppData } from "../data/index";
|
||||
// interface
|
||||
import { CalendarCard } from "../plugins/Mys/interface/calendar";
|
||||
import { type Map } from "../interface/Base";
|
||||
import { CalendarData, CalendarItem } from "../interface/Calendar";
|
||||
import { OBC_CONTENT_API } from "../plugins/Mys/interface/utils";
|
||||
|
||||
// loading
|
||||
const loading = ref(true as boolean);
|
||||
|
||||
// data
|
||||
const characterCards = ref([] as CalendarCard[]);
|
||||
const weaponCards = ref([] as CalendarCard[]);
|
||||
const weekNow = ref(new Date().getDay());
|
||||
const calendarData = ref(TGAppData.calendar as Map<CalendarData>);
|
||||
const weekNow = ref(0 as number);
|
||||
const btnNow = ref(0 as number);
|
||||
const dateNow = ref(new Date().toLocaleDateString());
|
||||
const calendarNow = ref({} as CalendarData);
|
||||
const characterCards = ref({} as Map<CalendarItem>);
|
||||
const weaponCards = ref({} as Map<CalendarItem>);
|
||||
|
||||
const btnText = [
|
||||
{
|
||||
@@ -94,47 +144,45 @@ const btnText = [
|
||||
text: "周六",
|
||||
},
|
||||
];
|
||||
|
||||
// show data
|
||||
const showCharacters = ref([] as CalendarCard[]);
|
||||
const showWeapons = ref([] as CalendarCard[]);
|
||||
|
||||
// expose
|
||||
defineExpose({
|
||||
name: "素材日历",
|
||||
loading,
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const calendarData = await MysOper.Calendar.get();
|
||||
if (!calendarData) {
|
||||
await console.error("获取材料日历失败");
|
||||
return;
|
||||
}
|
||||
const calendarCards = MysOper.Calendar.card(calendarData);
|
||||
const week = new Date().getDay();
|
||||
btnNow.value = week;
|
||||
characterCards.value = calendarCards.filter((card) => card.type === 2);
|
||||
weaponCards.value = calendarCards.filter((card) => card.type === 1);
|
||||
getShowCards(week);
|
||||
onMounted(() => {
|
||||
const dayNow = new Date().getDay();
|
||||
weekNow.value = dayNow;
|
||||
btnNow.value = dayNow;
|
||||
calendarNow.value = getCalendar(dayNow);
|
||||
characterCards.value = calendarNow.value.characters;
|
||||
weaponCards.value = calendarNow.value.weapons;
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
// 根据星期几获取显示内容
|
||||
function getShowCards (choice: number) {
|
||||
btnNow.value = choice;
|
||||
const week = choice === 0 ? 7 : choice;
|
||||
showCharacters.value = characterCards.value
|
||||
.filter((card) => card.drop_day.includes(week.toString()))
|
||||
.sort((a, b) => a.sort_day[week] - b.sort_day[week]);
|
||||
showWeapons.value = weaponCards.value
|
||||
.filter((card) => card.drop_day.includes(week.toString()))
|
||||
.sort((a, b) => a.sort_day[week] - b.sort_day[week]);
|
||||
// 获取当前日历
|
||||
function getCalendar (day: number) {
|
||||
let week;
|
||||
if (day < 4) week = day;
|
||||
else week = day - 3;
|
||||
return calendarData.value[week];
|
||||
}
|
||||
|
||||
function showContent (item: CalendarCard) {
|
||||
function showContent (contentId: number) {
|
||||
// todo:二级跳转,目前先直接跳到角色详情页
|
||||
window.open(OBC_CONTENT_API.replace("{content_id}", item.url));
|
||||
window.open(OBC_CONTENT_API.replace("{content_id}", contentId.toString()));
|
||||
}
|
||||
|
||||
function getContents (day: number) {
|
||||
const oldValue = btnNow.value % 4;
|
||||
btnNow.value = day;
|
||||
if (oldValue % 3 === day % 3 && oldValue !== 0 && day !== 0) {
|
||||
return;
|
||||
}
|
||||
calendarNow.value = getCalendar(day);
|
||||
characterCards.value = calendarNow.value.characters;
|
||||
weaponCards.value = calendarNow.value.weapons;
|
||||
console.log(characterCards.value);
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
@@ -145,6 +193,13 @@ function showContent (item: CalendarCard) {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.calendar-btn {
|
||||
margin-left: 10px;
|
||||
font-family: Genshin-Light, serif;
|
||||
color: #faf7e8;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.calendar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
@@ -158,27 +213,48 @@ function showContent (item: CalendarCard) {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.calendar-icons {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));
|
||||
grid-gap: 5px;
|
||||
.card-title {
|
||||
font-size: 1.5rem;
|
||||
font-family: Genshin, serif;
|
||||
color: #546D8B;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.calendar-content {
|
||||
background: #546D8B;
|
||||
color:#faf7e8;
|
||||
margin: 10px;
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.content-title {
|
||||
font-size: 1.2rem;
|
||||
font-family: Genshin, serif;
|
||||
color: #faf7e8;
|
||||
padding: 10px;
|
||||
display: v-bind("btnNow === 0 ? 'block' : 'inline-block'")
|
||||
}
|
||||
|
||||
.content-material {
|
||||
display: inline-block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.calendar-icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin: 5px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.calendar-icon :hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.calendar-btn {
|
||||
margin-left: 10px;
|
||||
font-family: Genshin-Light, serif;
|
||||
color: #faf7e8;
|
||||
border-radius: 10px;
|
||||
.content-detail {
|
||||
border-top: 1px solid #faf7e8;
|
||||
padding-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
2875
src/data/app/calendar.json
Normal file
2875
src/data/app/calendar.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
* @file data app index
|
||||
* @description data app index
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha
|
||||
* @since Alpha v0.1.2
|
||||
*/
|
||||
|
||||
// Data
|
||||
@@ -10,11 +10,13 @@ import achievements from "./achievements.json";
|
||||
import achievementSeries from "./achievementSeries.json";
|
||||
import GCG from "./GCG.json";
|
||||
import nameCards from "./nameCards.json";
|
||||
import calendar from "./calendar.json";
|
||||
// Interface
|
||||
import { type Achievement, type AchievementSeries } from "../../interface/Achievements";
|
||||
import { type Map } from "../../interface/Base";
|
||||
import { type BaseCard } from "../../interface/GCG";
|
||||
import { type NameCard } from "../../interface/NameCard";
|
||||
import { type CalendarData } from "../../interface/Calendar";
|
||||
|
||||
export const AppDataList = [
|
||||
{
|
||||
@@ -33,6 +35,10 @@ export const AppDataList = [
|
||||
name: "nameCards.json",
|
||||
data: nameCards as unknown as Map<NameCard[]>,
|
||||
},
|
||||
{
|
||||
name: "calendar.json",
|
||||
data: calendar as Map<CalendarData>,
|
||||
},
|
||||
];
|
||||
|
||||
export const AppData = {
|
||||
@@ -40,4 +46,5 @@ export const AppData = {
|
||||
achievementSeries: achievementSeries as Map<AchievementSeries>,
|
||||
GCG: GCG as BaseCard[],
|
||||
nameCards: nameCards as unknown as Map<NameCard[]>,
|
||||
calendar: calendar as Map<CalendarData>,
|
||||
};
|
||||
|
||||
@@ -5,53 +5,47 @@
|
||||
* @since Alpha v0.1.2
|
||||
*/
|
||||
|
||||
import { type GameCountry } from "./Base";
|
||||
import { type Map } from "./Base";
|
||||
|
||||
/**
|
||||
* @description 素材日历接口
|
||||
* @interface Calendar
|
||||
* @interface CalendarData
|
||||
* @since Alpha v0.1.2
|
||||
* @example Map<Calendar>
|
||||
* @property {number} weekDay - 一周的第几天
|
||||
* @property {CalendarCharacter} characters - 该天的角色相关数据
|
||||
* @property {CalendarWeapon} weapons - 该天的武器相关数据
|
||||
* @returns {Calendar}
|
||||
* @property {Map<CalendarItem>} characters - 该天的角色相关数据
|
||||
* @property {Map<CalendarItem>} weapons - 该天的武器相关数据
|
||||
* @returns {CalendarData}
|
||||
*/
|
||||
export interface Calendar {
|
||||
weekDay: number
|
||||
characters: Record<GameCountry, CalendarItem>
|
||||
weapons: Record<GameCountry, CalendarItem>
|
||||
export interface CalendarData {
|
||||
characters: Map<CalendarItem>
|
||||
weapons: Map<CalendarItem>
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 单日单秘境的素材日历接口
|
||||
* @interface CalendarItem
|
||||
* @since Alpha v0.1.2
|
||||
* @property {string} area - 地区
|
||||
* @property {string} source - 来源秘境
|
||||
* @todo 后续换成更为完善的类型
|
||||
* @property {string} title - 地区 秘境名称
|
||||
* @property {MiniMaterial[]} materials - 素材 url
|
||||
* @property {MiniMaterial[]} contents - 角色/武器 url
|
||||
* @returns {CalendarItem}
|
||||
*/
|
||||
export interface CalendarItem {
|
||||
area: string
|
||||
source: string
|
||||
materials: string[]
|
||||
contents: string[]
|
||||
title: string
|
||||
materials: MiniMaterial[]
|
||||
contents: MiniMaterial[]
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 材料类型
|
||||
* @interface MiniMaterial
|
||||
* @since Alpha v0.1.2
|
||||
* @property {number} star - 星级,或者说稀有度
|
||||
* @property {string} name - 材料名称
|
||||
* @property {string} url - 材料图片 url
|
||||
* @returns {MiniMaterial}
|
||||
* @property {number} content_id - 观测枢的 content_id
|
||||
* @property {string} name - 名称
|
||||
* @property {string} icon - 图标 url
|
||||
*/
|
||||
export interface MiniMaterial {
|
||||
star: number
|
||||
content_id: number
|
||||
name: string
|
||||
url: string
|
||||
icon: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user