mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2026-04-21 21:49:55 +08:00
🎨 代码格式化
This commit is contained in:
@@ -29,7 +29,7 @@ const visible = computed({
|
||||
set: (value) => emits("update:modelValue", value),
|
||||
});
|
||||
|
||||
function onCancel () {
|
||||
function onCancel() {
|
||||
visible.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { computed } from "vue";
|
||||
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
|
||||
|
||||
interface TibCalendarAvatarProps {
|
||||
modelValue: TGApp.App.Calendar.Item
|
||||
modelValue: TGApp.App.Calendar.Item;
|
||||
}
|
||||
|
||||
const props = defineProps<TibCalendarAvatarProps>();
|
||||
|
||||
@@ -7,19 +7,17 @@ import { onMounted, ref } from "vue";
|
||||
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
|
||||
|
||||
interface TibUrAvatarProps {
|
||||
modelValue: TGApp.Sqlite.Record.Avatar
|
||||
modelValue: TGApp.Sqlite.Record.Avatar;
|
||||
}
|
||||
|
||||
const props = defineProps<TibUrAvatarProps>();
|
||||
const box = ref({} as TItemBoxData);
|
||||
const getName = () => {
|
||||
return (
|
||||
props.modelValue.id === 10000005
|
||||
? "旅行者-空"
|
||||
: props.modelValue.id === 10000007
|
||||
? "旅行者-荧"
|
||||
: props.modelValue.name
|
||||
);
|
||||
return props.modelValue.id === 10000005
|
||||
? "旅行者-空"
|
||||
: props.modelValue.id === 10000007
|
||||
? "旅行者-荧"
|
||||
: props.modelValue.name;
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -38,7 +36,7 @@ onMounted(async () => {
|
||||
};
|
||||
});
|
||||
|
||||
function showData () {
|
||||
function showData() {
|
||||
// todo @click 应该出来的是一个弹窗,而不是 console
|
||||
console.log(props.modelValue);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<TItemBox :model-value="box" style="cursor: pointer;" />
|
||||
<TItemBox :model-value="box" style="cursor: pointer" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
@@ -7,7 +7,7 @@ import { computed } from "vue";
|
||||
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
|
||||
|
||||
interface TibCalendarWeaponProps {
|
||||
modelValue: TGApp.App.Weapon.WikiBriefInfo
|
||||
modelValue: TGApp.App.Weapon.WikiBriefInfo;
|
||||
}
|
||||
|
||||
const props = defineProps<TibCalendarWeaponProps>();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<transition name="fade">
|
||||
<div v-show="canTop" class="back-top" @click="handleScrollTop">
|
||||
<img src="../../assets/icons/arrow-top.svg" alt="back-icon">
|
||||
<img src="../../assets/icons/arrow-top.svg" alt="back-icon" />
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
@@ -13,7 +13,7 @@ const scrollTop = ref(0); // 滚动条距离顶部的距离
|
||||
const canTop = ref(false); // 默认不显示
|
||||
|
||||
// 监听滚动事件
|
||||
function handleScroll () {
|
||||
function handleScroll() {
|
||||
scrollTop.value = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
// 超过500px显示回到顶部按钮
|
||||
canTop.value = scrollTop.value > 500;
|
||||
@@ -26,10 +26,10 @@ function handleScroll () {
|
||||
}
|
||||
|
||||
// 点击回到顶部
|
||||
function handleScrollTop () {
|
||||
function handleScrollTop() {
|
||||
let timer = 0;
|
||||
cancelAnimationFrame(timer);
|
||||
timer = requestAnimationFrame(function fn () {
|
||||
timer = requestAnimationFrame(function fn() {
|
||||
if (scrollTop.value > 0) {
|
||||
scrollTop.value -= 50;
|
||||
document.body.scrollTop = document.documentElement.scrollTop = scrollTop.value;
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
<div class="calendar-box">
|
||||
<div class="calendar-title">
|
||||
<div class="calendar-title-left">
|
||||
<v-icon size="small">
|
||||
mdi-calendar-clock
|
||||
</v-icon>
|
||||
<v-icon size="small"> mdi-calendar-clock </v-icon>
|
||||
<span>今日素材</span>
|
||||
<span>{{ dateNow }}</span>
|
||||
</div>
|
||||
@@ -119,7 +117,7 @@ defineExpose({
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
const dayNow = (new Date().getDay()) === 0 ? 7 : (new Date().getDay());
|
||||
const dayNow = new Date().getDay() === 0 ? 7 : new Date().getDay();
|
||||
weekNow.value = dayNow;
|
||||
btnNow.value = dayNow;
|
||||
calendarNow.value = getCalendar(dayNow);
|
||||
@@ -129,17 +127,17 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
// 获取当前日历
|
||||
function getCalendar (day: number) {
|
||||
function getCalendar(day: number) {
|
||||
return calendarData.value.filter((item) => item.dropDays.includes(day));
|
||||
}
|
||||
|
||||
function selectContent (item: TGApp.App.Calendar.Item, type: string) {
|
||||
function selectContent(item: TGApp.App.Calendar.Item, type: string) {
|
||||
selectedItem.value = item;
|
||||
selectedType.value = type;
|
||||
showItem.value = true;
|
||||
}
|
||||
|
||||
function getContents (day: number) {
|
||||
function getContents(day: number) {
|
||||
btnNow.value = day;
|
||||
calendarNow.value = getCalendar(day);
|
||||
characterCards.value = calendarNow.value.filter((item) => item.itemType === "character");
|
||||
@@ -159,7 +157,7 @@ function getContents (day: number) {
|
||||
height: 45px;
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
color:rgb(255 255 255 / 80%);
|
||||
color: rgb(255 255 255 / 80%);
|
||||
}
|
||||
|
||||
.calendar-title-left {
|
||||
@@ -182,8 +180,8 @@ function getContents (day: number) {
|
||||
}
|
||||
|
||||
.calendar-title-btn {
|
||||
margin-left: 10px;
|
||||
border-radius: 5px;
|
||||
margin-left: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.calendar-divider {
|
||||
@@ -194,12 +192,12 @@ function getContents (day: number) {
|
||||
}
|
||||
|
||||
.calendar-sub {
|
||||
margin: 5px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.cards-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
||||
grid-gap: 8px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
||||
grid-gap: 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<div class="tib2-left">
|
||||
<slot name="left">
|
||||
<div v-if="props.modelValue.bg !== undefined" class="tib2-bg">
|
||||
<img :src="props.modelValue.bg" alt="bg">
|
||||
<img :src="props.modelValue.bg" alt="bg" />
|
||||
</div>
|
||||
<div class="tib2-icon">
|
||||
<img :src="props.modelValue.icon" alt="icon">
|
||||
<img :src="props.modelValue.icon" alt="icon" />
|
||||
</div>
|
||||
<div v-if="props.modelValue.star !== undefined" class="tib2-star">
|
||||
<img :src="props.modelValue.star" alt="element">
|
||||
<img :src="props.modelValue.star" alt="element" />
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
@@ -19,18 +19,17 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
|
||||
export interface TItemBox2Data {
|
||||
width: string,
|
||||
height: string,
|
||||
bg?: string,
|
||||
icon: string,
|
||||
star?: string,
|
||||
name: string,
|
||||
width: string;
|
||||
height: string;
|
||||
bg?: string;
|
||||
icon: string;
|
||||
star?: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface TItemBox2Props {
|
||||
modelValue: TItemBox2Data,
|
||||
modelValue: TItemBox2Data;
|
||||
}
|
||||
|
||||
const props = defineProps<TItemBox2Props>();
|
||||
@@ -38,16 +37,16 @@ const props = defineProps<TItemBox2Props>();
|
||||
<style lang="css" scoped>
|
||||
.tib2-box {
|
||||
position: relative;
|
||||
height: v-bind(props["modelValue"]["height"]);
|
||||
width: v-bind(props["modelValue"]["width"]);
|
||||
height: v-bind(props[ "modelValue"][ "height"]);
|
||||
width: v-bind(props[ "modelValue"][ "width"]);
|
||||
display: flex;
|
||||
border-radius: 5px;
|
||||
background: rgb(20 20 20 / 30%);
|
||||
}
|
||||
|
||||
.tib2-left {
|
||||
width: v-bind(props["modelValue"]["height"]);
|
||||
height: v-bind(props["modelValue"]["height"]);
|
||||
width: v-bind(props[ "modelValue"][ "height"]);
|
||||
height: v-bind(props[ "modelValue"][ "height"]);
|
||||
border-top-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
overflow: hidden;
|
||||
@@ -57,8 +56,8 @@ const props = defineProps<TItemBox2Props>();
|
||||
.tib2-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: v-bind(props["modelValue"]["height"]);
|
||||
height: v-bind(props["modelValue"]["height"]);
|
||||
width: v-bind(props[ "modelValue"][ "height"]);
|
||||
height: v-bind(props[ "modelValue"][ "height"]);
|
||||
border-top-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
overflow: hidden;
|
||||
@@ -74,7 +73,7 @@ const props = defineProps<TItemBox2Props>();
|
||||
.tib2-star {
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
width: v-bind(props["modelValue"]["height"]);
|
||||
width: v-bind(props[ "modelValue"][ "height"]);
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@@ -87,7 +86,7 @@ const props = defineProps<TItemBox2Props>();
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(0.2 * v-bind(props["modelValue"]["height"]));
|
||||
font-size: calc(0.2 * v-bind(props[ "modelValue"][ "height"]));
|
||||
color: var(--common-color-white);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -2,31 +2,31 @@
|
||||
<div class="tib-box">
|
||||
<div class="tib-bg">
|
||||
<slot name="bg">
|
||||
<img :src="modelValue.bg" alt="bg">
|
||||
<img :src="modelValue.bg" alt="bg" />
|
||||
</slot>
|
||||
</div>
|
||||
<div class="tib-icon">
|
||||
<slot name="icon">
|
||||
<img :src="modelValue.icon" alt="icon">
|
||||
<img :src="modelValue.icon" alt="icon" />
|
||||
</slot>
|
||||
</div>
|
||||
<div class="tib-cover">
|
||||
<div class="tib-lt">
|
||||
<img :src="modelValue.lt" alt="lt">
|
||||
<img :src="modelValue.lt" alt="lt" />
|
||||
</div>
|
||||
<div v-show="modelValue.rt" class="tib-rt">
|
||||
{{ modelValue.rt }}
|
||||
</div>
|
||||
<div class="tib-inner">
|
||||
<slot name="inner-icon">
|
||||
<img v-show="modelValue.innerIcon" :src="modelValue.innerIcon" alt="inner-icon">
|
||||
<img v-show="modelValue.innerIcon" :src="modelValue.innerIcon" alt="inner-icon" />
|
||||
</slot>
|
||||
<slot name="inner-text">
|
||||
<span>{{ modelValue.innerText }}</span>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="modelValue.display==='outer'" class="tib-outer">
|
||||
<div v-if="modelValue.display === 'outer'" class="tib-outer">
|
||||
<slot name="outer-text">
|
||||
<span>{{ modelValue.outerText }}</span>
|
||||
</slot>
|
||||
@@ -37,24 +37,24 @@
|
||||
import { computed } from "vue";
|
||||
|
||||
export interface TItemBoxData {
|
||||
bg: string,
|
||||
icon: string,
|
||||
size: string,
|
||||
height: string,
|
||||
display: "inner" | "outer",
|
||||
lt: string,
|
||||
ltSize: string,
|
||||
rt?: string,
|
||||
rtSize?: string,
|
||||
innerHeight?: number,
|
||||
innerIcon?: string,
|
||||
innerText: string,
|
||||
outerHeight?: number,
|
||||
outerText?: string,
|
||||
bg: string;
|
||||
icon: string;
|
||||
size: string;
|
||||
height: string;
|
||||
display: "inner" | "outer";
|
||||
lt: string;
|
||||
ltSize: string;
|
||||
rt?: string;
|
||||
rtSize?: string;
|
||||
innerHeight?: number;
|
||||
innerIcon?: string;
|
||||
innerText: string;
|
||||
outerHeight?: number;
|
||||
outerText?: string;
|
||||
}
|
||||
|
||||
interface TItemBoxProps {
|
||||
modelValue: TItemBoxData,
|
||||
modelValue: TItemBoxData;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<TItemBoxProps>(), {
|
||||
@@ -78,16 +78,16 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
|
||||
<style lang="css" scoped>
|
||||
.tib-box {
|
||||
position: relative;
|
||||
width: v-bind(props["modelValue"]["size"]);
|
||||
height: v-bind(props["modelValue"]["height"]);
|
||||
width: v-bind(props[ "modelValue"][ "size"]);
|
||||
height: v-bind(props[ "modelValue"][ "height"]);
|
||||
}
|
||||
|
||||
.tib-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: v-bind(props["modelValue"]["size"]);
|
||||
height: v-bind(props["modelValue"]["size"]);
|
||||
width: v-bind(props[ "modelValue"][ "size"]);
|
||||
height: v-bind(props[ "modelValue"][ "size"]);
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -100,8 +100,8 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
|
||||
|
||||
.tib-icon {
|
||||
position: relative;
|
||||
width: v-bind(props["modelValue"]["size"]);
|
||||
height: v-bind(props["modelValue"]["size"]);
|
||||
width: v-bind(props[ "modelValue"][ "size"]);
|
||||
height: v-bind(props[ "modelValue"][ "size"]);
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
}
|
||||
@@ -116,8 +116,8 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: v-bind(props["modelValue"]["size"]);
|
||||
height: v-bind(props["modelValue"]["size"]);
|
||||
width: v-bind(props[ "modelValue"][ "size"]);
|
||||
height: v-bind(props[ "modelValue"][ "size"]);
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@@ -130,8 +130,8 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 5px;
|
||||
width: v-bind(props["modelValue"]["ltSize"]);
|
||||
height: v-bind(props["modelValue"]["ltSize"]);
|
||||
width: v-bind(props[ "modelValue"][ "ltSize"]);
|
||||
height: v-bind(props[ "modelValue"][ "ltSize"]);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@@ -147,8 +147,8 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: v-bind(props["modelValue"]["rtSize"]);
|
||||
height: v-bind(props["modelValue"]["rtSize"]);
|
||||
width: v-bind(props[ "modelValue"][ "rtSize"]);
|
||||
height: v-bind(props[ "modelValue"][ "rtSize"]);
|
||||
background: rgb(0 0 0 / 40%);
|
||||
border-top-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
|
||||
@@ -26,19 +26,21 @@ const props = withDefaults(defineProps<TolProps>(), {
|
||||
blurVal: "20px",
|
||||
});
|
||||
|
||||
watch(() => props.modelValue, () => {
|
||||
if (props.modelValue) {
|
||||
showTolo.value = true;
|
||||
showToli.value = true;
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
showToli.value = false;
|
||||
}, 100);
|
||||
setTimeout(() => {
|
||||
showTolo.value = false;
|
||||
}, 300);
|
||||
}
|
||||
},
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
() => {
|
||||
if (props.modelValue) {
|
||||
showTolo.value = true;
|
||||
showToli.value = true;
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
showToli.value = false;
|
||||
}, 100);
|
||||
setTimeout(() => {
|
||||
showTolo.value = false;
|
||||
}, 300);
|
||||
}
|
||||
},
|
||||
);
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
<template>
|
||||
<div class="pool-box">
|
||||
<div class="pool-title">
|
||||
<img src="../../assets/icons/icon-wish.svg" alt="wish">
|
||||
<img src="../../assets/icons/icon-wish.svg" alt="wish" />
|
||||
限时祈愿
|
||||
</div>
|
||||
<div v-if="!loading" class="pool-grid">
|
||||
<v-card
|
||||
v-for="pool in poolCards"
|
||||
:key="pool.post_id"
|
||||
class="pool-card"
|
||||
>
|
||||
<v-card v-for="pool in poolCards" :key="pool.post_id" class="pool-card">
|
||||
<v-list class="pool-list">
|
||||
<v-list-item :title="pool.title" :subtitle="pool.subtitle">
|
||||
<template #prepend>
|
||||
<img :src="pool.voice.icon" class="pool-sideIcon" alt="icon">
|
||||
<img :src="pool.voice.icon" class="pool-sideIcon" alt="icon" />
|
||||
</template>
|
||||
<template v-if="pool.voice.url" #append>
|
||||
<audio :src="pool.voice.url" controls />
|
||||
@@ -21,7 +17,7 @@
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<div class="pool-cover" @click="toPost(pool)">
|
||||
<img :src="pool.cover" alt="cover">
|
||||
<img :src="pool.cover" alt="cover" />
|
||||
</div>
|
||||
<div class="pool-character">
|
||||
<div class="pool-icon-grid">
|
||||
@@ -31,11 +27,16 @@
|
||||
class="pool-icon"
|
||||
@click="toOuter(character.url, pool.title)"
|
||||
>
|
||||
<img :src="character.icon" alt="character">
|
||||
<img :src="character.icon" alt="character" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="pool-clock">
|
||||
<v-progress-circular :model-value="poolTimePass[pool.post_id]" size="100" width="10" :color="poolColor[pool.post_id]">
|
||||
<v-progress-circular
|
||||
:model-value="poolTimePass[pool.post_id]"
|
||||
size="100"
|
||||
width="10"
|
||||
:color="poolColor[pool.post_id]"
|
||||
>
|
||||
{{ poolTimeGet[pool.post_id] }}
|
||||
</v-progress-circular>
|
||||
</div>
|
||||
@@ -92,7 +93,7 @@ defineExpose({
|
||||
loading,
|
||||
});
|
||||
|
||||
function poolLastInterval (postId: number) {
|
||||
function poolLastInterval(postId: number) {
|
||||
const pool = poolCards.value.find((pool) => pool.post_id === postId);
|
||||
if (!pool) return;
|
||||
if (poolTimeGet.value[postId] === "未开始") {
|
||||
@@ -105,7 +106,7 @@ function poolLastInterval (postId: number) {
|
||||
const isEnd = pool.time.end_stamp - Date.now();
|
||||
poolTimeGet.value[postId] = getLastPoolTime(isEnd);
|
||||
poolTimePass.value[postId] =
|
||||
((pool.time.end_stamp - Date.now()) / (pool.time.end_stamp - pool.time.start_stamp)) * 100;
|
||||
((pool.time.end_stamp - Date.now()) / (pool.time.end_stamp - pool.time.start_stamp)) * 100;
|
||||
if (isEnd >= 0) return;
|
||||
clearInterval(timer.value[postId]);
|
||||
timer.value[postId] = null;
|
||||
@@ -156,7 +157,7 @@ onMounted(async () => {
|
||||
});
|
||||
|
||||
// 检测是否有新的限时祈愿
|
||||
function checkCover (data: GachaData[]) {
|
||||
function checkCover(data: GachaData[]) {
|
||||
// 如果没有缓存
|
||||
if (!homeStore.poolCover || Object.keys(homeStore.poolCover).length === 0) {
|
||||
return false;
|
||||
@@ -180,7 +181,7 @@ function checkCover (data: GachaData[]) {
|
||||
});
|
||||
}
|
||||
|
||||
async function toOuter (url: string, title: string) {
|
||||
async function toOuter(url: string, title: string) {
|
||||
if (!url) {
|
||||
barText.value = "链接为空!";
|
||||
barColor.value = "error";
|
||||
@@ -190,14 +191,14 @@ async function toOuter (url: string, title: string) {
|
||||
createTGWindow(url, "祈愿", title, 1200, 800, true, true);
|
||||
}
|
||||
|
||||
function getLastPoolTime (time: number) {
|
||||
function getLastPoolTime(time: number) {
|
||||
const hour = Math.floor(time / 1000 / 60 / 60);
|
||||
const minute = Math.floor((time / 1000 / 60 / 60 - hour) * 60);
|
||||
const second = Math.floor(((time / 1000 / 60 / 60 - hour) * 60 - minute) * 60);
|
||||
return `${hour}:${minute.toFixed(0).padStart(2, "0")}:${second.toFixed(0).padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
function toPost (pool: GachaCard) {
|
||||
function toPost(pool: GachaCard) {
|
||||
const path = router.resolve({
|
||||
name: "帖子详情",
|
||||
params: {
|
||||
@@ -225,7 +226,7 @@ onUnmounted(() => {
|
||||
|
||||
.pool-title {
|
||||
color: var(--common-text);
|
||||
font-family: var(--font-title);
|
||||
font-family: var(--font-title);
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
}
|
||||
@@ -235,7 +236,7 @@ onUnmounted(() => {
|
||||
height: 25px;
|
||||
transform: translate(0, 2px);
|
||||
margin-right: 10px;
|
||||
border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
background: var(--common-bg-2);
|
||||
}
|
||||
|
||||
@@ -247,19 +248,19 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.pool-card {
|
||||
background: #45b787; /* 蛙绿 */
|
||||
color: #eef7f2; /* 丹白 */
|
||||
border-radius: 5px;
|
||||
background: #45b787; /* 蛙绿 */
|
||||
color: #eef7f2; /* 丹白 */
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.dark .pool-card {
|
||||
background: #1f2623; /* 苷蓝绿 */
|
||||
background: #1f2623; /* 苷蓝绿 */
|
||||
}
|
||||
|
||||
.pool-list {
|
||||
font-family: var(--font-title);
|
||||
background: inherit;
|
||||
color: inherit;
|
||||
font-family: var(--font-title);
|
||||
background: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.pool-sideIcon {
|
||||
@@ -267,7 +268,7 @@ onUnmounted(() => {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: var(--common-bg-2);
|
||||
background: var(--common-bg-2);
|
||||
}
|
||||
|
||||
.pool-cover {
|
||||
@@ -282,7 +283,7 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.pool-cover img {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
transition: all 0.5s;
|
||||
border-radius: 10px;
|
||||
}
|
||||
@@ -301,22 +302,22 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.pool-icon-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4,70px);
|
||||
grid-column-gap: 10px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 70px);
|
||||
grid-column-gap: 10px;
|
||||
}
|
||||
|
||||
.pool-icon {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border-radius: 5px;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.pool-icon img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pool-clock {
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
<template>
|
||||
<div class="position-box">
|
||||
<div class="position-title">
|
||||
<img src="../../assets/icons/board.svg" alt="act">
|
||||
<img src="../../assets/icons/board.svg" alt="act" />
|
||||
<span>近期活动</span>
|
||||
</div>
|
||||
<div v-if="!loading" class="position-grid">
|
||||
<v-card
|
||||
v-for="card in positionCards"
|
||||
:key="card.post_id"
|
||||
class="position-card"
|
||||
>
|
||||
<v-card v-for="card in positionCards" :key="card.post_id" class="position-card">
|
||||
<v-list class="position-list">
|
||||
<v-list-item :title="card.title" :subtitle="card.abstract">
|
||||
<template #prepend>
|
||||
@@ -18,9 +14,7 @@
|
||||
</v-avatar>
|
||||
</template>
|
||||
<template #append>
|
||||
<v-btn variant="outlined" @click="toPost(card)">
|
||||
查看
|
||||
</v-btn>
|
||||
<v-btn variant="outlined" @click="toPost(card)"> 查看 </v-btn>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
@@ -38,7 +32,9 @@
|
||||
positionTimeGet[card.post_id]
|
||||
}}</span>
|
||||
<!-- 粉红 -->
|
||||
<span v-if="positionTimeGet[card.post_id] === '已结束'" style="color: #f2b9b2">已结束</span>
|
||||
<span v-if="positionTimeGet[card.post_id] === '已结束'" style="color: #f2b9b2"
|
||||
>已结束</span
|
||||
>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
@@ -74,7 +70,7 @@ defineExpose({
|
||||
loading,
|
||||
});
|
||||
|
||||
function positionLastInterval (postId: number) {
|
||||
function positionLastInterval(postId: number) {
|
||||
const timeGet = positionTimeGet.value[postId];
|
||||
if (timeGet === "未知" || timeGet === "已结束") {
|
||||
clearInterval(positionTimer.value[postId]);
|
||||
@@ -110,17 +106,17 @@ onMounted(async () => {
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
function getLastPositionTime (time: number) {
|
||||
function getLastPositionTime(time: number) {
|
||||
const day = Math.floor(time / (24 * 3600 * 1000));
|
||||
const hour = Math.floor((time % (24 * 3600 * 1000)) / (3600 * 1000));
|
||||
const minute = Math.floor((time % (3600 * 1000)) / (60 * 1000));
|
||||
const second = Math.floor((time % (60 * 1000)) / 1000);
|
||||
return `${day}天 ${hour.toFixed(0).padStart(2, "0")}:${minute.toFixed(0).padStart(2, "0")}:${second
|
||||
return `${day}天 ${hour.toFixed(0).padStart(2, "0")}:${minute
|
||||
.toFixed(0)
|
||||
.padStart(2, "0")}`;
|
||||
.padStart(2, "0")}:${second.toFixed(0).padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
async function toPost (card: PositionCard) {
|
||||
async function toPost(card: PositionCard) {
|
||||
// 获取路由路径
|
||||
const path = router.resolve({
|
||||
name: "帖子详情",
|
||||
@@ -173,7 +169,7 @@ onUnmounted(() => {
|
||||
.position-card {
|
||||
background: #45b787; /* 蛙绿 */
|
||||
color: #eef7f2; /* 月白 */
|
||||
border-radius: 5px
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.dark .position-card {
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<template>
|
||||
<div class="share-box">
|
||||
<div class="share-btn" @click="shareContent()">
|
||||
<v-icon style="color:var(--theme-switch-icon)">
|
||||
mdi-share-variant
|
||||
</v-icon>
|
||||
<v-icon style="color: var(--theme-switch-icon)"> mdi-share-variant </v-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -18,7 +16,7 @@ interface TShareBtnProps {
|
||||
|
||||
const props = defineProps<TShareBtnProps>();
|
||||
|
||||
async function shareContent () {
|
||||
async function shareContent() {
|
||||
await generateShareImg(props.title, props.modelValue);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -17,38 +17,38 @@
|
||||
<!-- 菜单项 -->
|
||||
<v-list-item value="home" title="首页" :link="true" href="/">
|
||||
<template #prepend>
|
||||
<img src="/source/UI/paimon.webp" alt="homeIcon" class="side-icon">
|
||||
<img src="/source/UI/paimon.webp" alt="homeIcon" class="side-icon" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="公告" value="announcements" :link="true" href="/announcements">
|
||||
<template #prepend>
|
||||
<img src="../../assets/icons/board.svg" alt="annoIcon" class="side-icon">
|
||||
<img src="../../assets/icons/board.svg" alt="annoIcon" class="side-icon" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="咨讯" value="news" :link="true" href="/news/2">
|
||||
<template #prepend>
|
||||
<img src="/platforms/mhy/mys.webp" alt="mihoyo" class="side-icon">
|
||||
<img src="/platforms/mhy/mys.webp" alt="mihoyo" class="side-icon" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="成就" value="achievements" :link="true" href="/achievements">
|
||||
<template #prepend>
|
||||
<img src="../../assets/icons/achievements.svg" alt="achievementsIcon" class="side-icon">
|
||||
<img src="../../assets/icons/achievements.svg" alt="achievementsIcon" class="side-icon" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-divider />
|
||||
<v-list-item title="原神战绩" value="record" :link="true" href="/user/record">
|
||||
<template #prepend>
|
||||
<img src="/source/UI/userRecord.webp" alt="record" class="side-icon">
|
||||
<img src="/source/UI/userRecord.webp" alt="record" class="side-icon" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="我的角色" value="character" :link="true" href="/user/characters">
|
||||
<template #prepend>
|
||||
<img src="/source/UI/userAvatar.webp" alt="characters" class="side-icon">
|
||||
<img src="/source/UI/userAvatar.webp" alt="characters" class="side-icon" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="深渊记录" value="abyss" :link="true" href="/user/abyss">
|
||||
<template #prepend>
|
||||
<img src="/source/UI/userAbyss.webp" alt="abyss" class="side-icon">
|
||||
<img src="/source/UI/userAbyss.webp" alt="abyss" class="side-icon" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
<!-- todo -->
|
||||
@@ -68,35 +68,35 @@
|
||||
<template #activator="{ props }">
|
||||
<v-list-item title="图鉴" v-bind="props">
|
||||
<template #prepend>
|
||||
<img src="/source/UI/guideMini.webp" alt="wikiIcon" class="side-icon-mini">
|
||||
<img src="/source/UI/guideMini.webp" alt="wikiIcon" class="side-icon-mini" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
</template>
|
||||
<v-list-item title="深渊数据库" value="wiki-abyss" :link="true" href="/wiki/abyss">
|
||||
<template #prepend>
|
||||
<img src="/icon/star/Abyss.webp" alt="abyssIcon" class="side-icon">
|
||||
<img src="/icon/star/Abyss.webp" alt="abyssIcon" class="side-icon" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="GCG" value="wiki-GCG" :link="true" href="/wiki/GCG">
|
||||
<template #prepend>
|
||||
<img src="../../assets/icons/GCG.svg" alt="gcgIcon" class="side-icon">
|
||||
<img src="../../assets/icons/GCG.svg" alt="gcgIcon" class="side-icon" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="角色图鉴" value="wiki-character" :link="true" href="/wiki/character">
|
||||
<template #prepend>
|
||||
<img src="/source/UI/avatarMini.webp" alt="characterIcon" class="side-icon-mini">
|
||||
<img src="/source/UI/avatarMini.webp" alt="characterIcon" class="side-icon-mini" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="武器图鉴" value="wiki-weapon" :link="true" href="/wiki/weapon">
|
||||
<template #prepend>
|
||||
<img src="/source/UI/weaponMini.webp" alt="weaponIcon" class="side-icon-mini">
|
||||
<img src="/source/UI/weaponMini.webp" alt="weaponIcon" class="side-icon-mini" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list-group>
|
||||
<div class="bottom-menu">
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<img :src="userInfo.avatar" alt="userIcon" class="side-icon">
|
||||
<img :src="userInfo.avatar" alt="userIcon" class="side-icon" />
|
||||
</template>
|
||||
<template #default>
|
||||
<v-list-item-title>
|
||||
@@ -113,7 +113,7 @@
|
||||
</v-list-item>
|
||||
<v-list-item title="设置" value="config" :link="true" href="/config">
|
||||
<template #prepend>
|
||||
<img src="../../assets/icons/setting.svg" alt="setting" class="side-icon">
|
||||
<img src="../../assets/icons/setting.svg" alt="setting" class="side-icon" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
</div>
|
||||
@@ -143,10 +143,10 @@ const userInfo = computed(() => {
|
||||
const rail = ref(appStore.sidebar.collapse);
|
||||
// theme
|
||||
const themeGet = computed({
|
||||
get () {
|
||||
get() {
|
||||
return appStore.theme;
|
||||
},
|
||||
set (value: string) {
|
||||
set(value: string) {
|
||||
appStore.theme = value;
|
||||
},
|
||||
});
|
||||
@@ -155,15 +155,15 @@ const themeTitle = computed(() => {
|
||||
});
|
||||
|
||||
const open = computed({
|
||||
get () {
|
||||
get() {
|
||||
return appStore.getSubmenu();
|
||||
},
|
||||
set (value: string[]) {
|
||||
set(value: string[]) {
|
||||
appStore.sidebar.submenu.wiki = value.includes("wiki");
|
||||
},
|
||||
});
|
||||
|
||||
function collapse () {
|
||||
function collapse() {
|
||||
rail.value = !rail.value;
|
||||
appStore.sidebar.collapse = rail.value;
|
||||
}
|
||||
@@ -172,14 +172,14 @@ onMounted(async () => {
|
||||
await listenOnTheme();
|
||||
});
|
||||
|
||||
async function listenOnTheme () {
|
||||
async function listenOnTheme() {
|
||||
await event.listen("readTheme", (e) => {
|
||||
const theme = e.payload as string;
|
||||
themeGet.value = theme === "default" ? "default" : "dark";
|
||||
});
|
||||
}
|
||||
|
||||
async function switchTheme () {
|
||||
async function switchTheme() {
|
||||
await event.emit("readTheme", themeGet.value === "default" ? "dark" : "default");
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="tsl-box">
|
||||
<img src="/src/assets/icons/arrow-right.svg" alt="right">
|
||||
<img src="/src/assets/icons/arrow-right.svg" alt="right" />
|
||||
<slot>
|
||||
{{ title }}
|
||||
</slot>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="switch-box">
|
||||
<div class="switch-btn" @click="switchTheme()">
|
||||
<v-icon style="color:var(--theme-switch-icon)">
|
||||
{{ themeGet === 'default' ? 'mdi-weather-night' : 'mdi-weather-sunny' }}
|
||||
<v-icon style="color: var(--theme-switch-icon)">
|
||||
{{ themeGet === "default" ? "mdi-weather-night" : "mdi-weather-sunny" }}
|
||||
</v-icon>
|
||||
</div>
|
||||
</div>
|
||||
@@ -19,10 +19,10 @@ import { useAppStore } from "../../store/modules/app";
|
||||
const appStore = useAppStore();
|
||||
// theme
|
||||
const themeGet = computed({
|
||||
get () {
|
||||
get() {
|
||||
return appStore.theme;
|
||||
},
|
||||
set (value: string) {
|
||||
set(value: string) {
|
||||
appStore.theme = value;
|
||||
},
|
||||
});
|
||||
@@ -31,12 +31,12 @@ onMounted(async () => {
|
||||
await listenOnTheme();
|
||||
});
|
||||
|
||||
async function switchTheme () {
|
||||
async function switchTheme() {
|
||||
appStore.changeTheme();
|
||||
await event.emit("readTheme", themeGet.value);
|
||||
}
|
||||
|
||||
async function listenOnTheme () {
|
||||
async function listenOnTheme() {
|
||||
await event.listen("readTheme", (e) => {
|
||||
const theme = e.payload as string;
|
||||
themeGet.value = theme === "default" ? "default" : "dark";
|
||||
|
||||
@@ -4,27 +4,33 @@
|
||||
<div class="box-div">
|
||||
<div class="toc-top">
|
||||
<div class="toc-icon">
|
||||
<TibCalendarAvatar v-if="itemType=== 'character'" v-model="itemVal" size="100px" style="cursor: default" />
|
||||
<TibCalendarWeapon v-if="itemType=== 'weapon'" v-model="itemVal" size="100px" style="cursor: default" />
|
||||
<TibCalendarAvatar
|
||||
v-if="itemType === 'character'"
|
||||
v-model="itemVal"
|
||||
size="100px"
|
||||
style="cursor: default"
|
||||
/>
|
||||
<TibCalendarWeapon
|
||||
v-if="itemType === 'weapon'"
|
||||
v-model="itemVal"
|
||||
size="100px"
|
||||
style="cursor: default"
|
||||
/>
|
||||
</div>
|
||||
<div class="toc-material-grid">
|
||||
<TibCalendarMaterial v-for="item in itemVal.materials" :item="item" />
|
||||
</div>
|
||||
</div>
|
||||
<img src="/source/UI/item-line.webp" alt="line" class="toc-line">
|
||||
<img src="/source/UI/item-line.webp" alt="line" class="toc-line" />
|
||||
<div class="toc-bottom">
|
||||
<div class="toc-src-box">
|
||||
<div class="toc-src-text">
|
||||
来源:
|
||||
</div>
|
||||
<img :src="`/icon/nation/${itemVal.source.area}.webp`" alt="icon">
|
||||
<div class="toc-src-text">
|
||||
{{ itemVal.source.area }} - {{ itemVal.source.name }}
|
||||
</div>
|
||||
<div class="toc-src-text">来源:</div>
|
||||
<img :src="`/icon/nation/${itemVal.source.area}.webp`" alt="icon" />
|
||||
<div class="toc-src-text">{{ itemVal.source.area }} - {{ itemVal.source.name }}</div>
|
||||
</div>
|
||||
<v-btn variant="outlined" @click="toDetail(itemVal)">
|
||||
<template #append>
|
||||
<img src="../../assets/icons/arrow-right.svg" alt="right" class="toc-btn-img">
|
||||
<img src="../../assets/icons/arrow-right.svg" alt="right" class="toc-btn-img" />
|
||||
</template>
|
||||
详情
|
||||
</v-btn>
|
||||
@@ -83,7 +89,7 @@ const onCancel = () => {
|
||||
emits("cancel");
|
||||
};
|
||||
|
||||
function toDetail (item: TGApp.App.Calendar.Item) {
|
||||
function toDetail(item: TGApp.App.Calendar.Item) {
|
||||
if (item.contentId === 0) {
|
||||
snackbar.value = true;
|
||||
return;
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
<TOverlay v-model="visible" hide :to-click="onCancel" blur-val="20px">
|
||||
<div class="toc-box">
|
||||
<div class="toc-top">
|
||||
<div class="toc-title">
|
||||
请选择要跳转的频道
|
||||
</div>
|
||||
<div class="toc-title">请选择要跳转的频道</div>
|
||||
<div class="toc-list">
|
||||
<div v-for="item in channelList" class="toc-list-item" @click="toChannel(item.link)">
|
||||
<img :src="item.icon" alt="icon">
|
||||
<img :src="item.icon" alt="icon" />
|
||||
<span>{{ item.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -86,13 +84,14 @@ const channelList: ToChannelItem[] = [
|
||||
title: "大别野",
|
||||
icon: "/platforms/mhy/dby.webp",
|
||||
link: "/news/5",
|
||||
}];
|
||||
},
|
||||
];
|
||||
|
||||
function onCancel () {
|
||||
function onCancel() {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
function toChannel (link: string) {
|
||||
function toChannel(link: string) {
|
||||
visible.value = false;
|
||||
router.push(link);
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -5,21 +5,26 @@
|
||||
<div class="confirm-title">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div v-show="subtitle!=='' && !isInput" class="confirm-subtitle">
|
||||
<div v-show="subtitle !== '' && !isInput" class="confirm-subtitle">
|
||||
{{ subtitle }}
|
||||
</div>
|
||||
<div v-show="isInput" class="confirm-input">
|
||||
<v-text-field v-model="inputVal" :label="subtitle||''" hide-details="auto" @keyup.enter="onConfirm" />
|
||||
<v-text-field
|
||||
v-model="inputVal"
|
||||
:label="subtitle || ''"
|
||||
hide-details="auto"
|
||||
@keyup.enter="onConfirm"
|
||||
/>
|
||||
</div>
|
||||
<div class="confirm-btn-box">
|
||||
<button class="confirm-btn" @click="onCancel">
|
||||
<img class="btn-icon" src="../../assets/icons/circle-cancel.svg" alt="cancel">
|
||||
<img class="btn-icon" src="../../assets/icons/circle-cancel.svg" alt="cancel" />
|
||||
<span class="btn-text">
|
||||
{{ cancel }}
|
||||
</span>
|
||||
</button>
|
||||
<button class="confirm-btn" @click="onConfirm">
|
||||
<img class="btn-icon" src="../../assets/icons/circle-check.svg" alt="confirm">
|
||||
<img class="btn-icon" src="../../assets/icons/circle-check.svg" alt="confirm" />
|
||||
<span class="btn-text">
|
||||
{{ confirm }}
|
||||
</span>
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
</div>
|
||||
<div class="tol-img">
|
||||
<slot name="img">
|
||||
<img v-if="!empty" src="/source/UI/loading.webp" alt="loading">
|
||||
<img v-else src="/source/UI/empty.webp" alt="empty">
|
||||
<img v-if="!empty" src="/source/UI/loading.webp" alt="loading" />
|
||||
<img v-else src="/source/UI/empty.webp" alt="empty" />
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,9 +43,12 @@ const props = withDefaults(defineProps<LoadingProps>(), {
|
||||
empty: false,
|
||||
});
|
||||
|
||||
watch(() => props.modelValue, (v) => {
|
||||
show.value = v;
|
||||
});
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(v) => {
|
||||
show.value = v;
|
||||
},
|
||||
);
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tol-div {
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
<div class="tud-db-icons-grid">
|
||||
<TibAbyssDetail
|
||||
v-for="avatar in props.modelValue.characters"
|
||||
:key="avatar.id" :model-value="avatar"
|
||||
:key="avatar.id"
|
||||
:model-value="avatar"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</slot>
|
||||
</div>
|
||||
<div class="tud-t-val">
|
||||
<img src="/icon/star/Abyss.webp" alt="Abyss">
|
||||
<img src="/icon/star/Abyss.webp" alt="Abyss" />
|
||||
<slot name="val">
|
||||
<span>{{ props.val }}</span>
|
||||
</slot>
|
||||
@@ -53,7 +53,7 @@ const getFontSize: ComputedRef<string> = computed(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: var(--font-text);
|
||||
font-size: v-bind(getFontSize);
|
||||
font-size: v-bind(getFontSize);
|
||||
color: var(--common-color-white);
|
||||
text-shadow: 0 0 10px var(--common-color-yellow);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
<template>
|
||||
<div class="tuad-box">
|
||||
<TuaDetailTitle :val="props.modelValue.winStar" :name="`第${props.modelValue.id}层`" mode="floor" />
|
||||
<TuaDetailTitle
|
||||
:val="props.modelValue.winStar"
|
||||
:name="`第${props.modelValue.id}层`"
|
||||
mode="floor"
|
||||
/>
|
||||
<div class="tuad-index-box">
|
||||
<TuaDetailLevel v-for="level in props.modelValue.levels" :key="level.id" :model-value="level" />
|
||||
<TuaDetailLevel
|
||||
v-for="level in props.modelValue.levels"
|
||||
:key="level.id"
|
||||
:model-value="level"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
|
||||
import TuaDetailTitle from "./tua-detail-title.vue";
|
||||
import TuaDetailLevel from "./tua-detail-level.vue";
|
||||
|
||||
interface TuaDetailProps {
|
||||
modelValue: TGApp.Sqlite.Abyss.Floor
|
||||
modelValue: TGApp.Sqlite.Abyss.Floor;
|
||||
}
|
||||
|
||||
const props = defineProps<TuaDetailProps>();
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
<slot name="val-icons">
|
||||
<TibAbyssOverview
|
||||
v-for="avatar in JSON.parse(props.valIcons) as TGApp.Sqlite.Abyss.Character[]"
|
||||
:key="avatar.id" :model-value="avatar"
|
||||
:key="avatar.id"
|
||||
:model-value="avatar"
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
@@ -25,10 +26,10 @@
|
||||
import TibAbyssOverview from "../itembox/tib-abyss-overview.vue";
|
||||
|
||||
interface TAOProps {
|
||||
title: string,
|
||||
valText?: string | number,
|
||||
valIcons?: string,
|
||||
iconNum: number,
|
||||
title: string;
|
||||
valText?: string | number;
|
||||
valIcons?: string;
|
||||
iconNum: number;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<TAOProps>(), {
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
<template>
|
||||
<div class="tuc-dc-box">
|
||||
<div v-if="!modelValue.active" class="tuc-dc-lock">
|
||||
<v-icon color="white">
|
||||
mdi-lock
|
||||
</v-icon>
|
||||
<v-icon color="white"> mdi-lock </v-icon>
|
||||
</div>
|
||||
<div class="tuc-dc-icon">
|
||||
<img :src="modelValue.icon" alt="constellation">
|
||||
<img :src="modelValue.icon" alt="constellation" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
interface TucDetailConstellationProps {
|
||||
modelValue: TGApp.Sqlite.Character.RoleConstellation
|
||||
modelValue: TGApp.Sqlite.Character.RoleConstellation;
|
||||
}
|
||||
|
||||
defineProps<TucDetailConstellationProps>();
|
||||
|
||||
@@ -34,7 +34,7 @@ interface TucDetailDescConstellationProps {
|
||||
const props = defineProps<TucDetailDescConstellationProps>();
|
||||
|
||||
// 解析描述
|
||||
function parseDesc (desc: string): string {
|
||||
function parseDesc(desc: string): string {
|
||||
const reg = /<color=(.*?)>(.*?)<\/color>/g;
|
||||
let match = reg.exec(desc);
|
||||
while (match) {
|
||||
|
||||
@@ -12,14 +12,12 @@
|
||||
<span>{{ props.modelValue.level }}</span>
|
||||
</div>
|
||||
<div class="tuc-ddrc-bottom">
|
||||
<img :src="`/icon/star/${props.modelValue.star}.webp`" alt="star">
|
||||
<img :src="`/icon/star/${props.modelValue.star}.webp`" alt="star" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #desc>
|
||||
<div class="tuc-ddrd-title">
|
||||
{{ props.modelValue.set.name }}:
|
||||
</div>
|
||||
<div class="tuc-ddrd-title">{{ props.modelValue.set.name }}:</div>
|
||||
<div v-for="desc in props.modelValue.set.effect" class="tuc-ddrc-desc">
|
||||
<span>{{ desc.active }}件套:</span>
|
||||
<span>{{ desc.description }}</span>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<span>阶</span>
|
||||
</div>
|
||||
<div class="tuc-ddwc-bottom">
|
||||
<img :src="`/icon/star/${props.modelValue.star}.webp`" alt="star">
|
||||
<img :src="`/icon/star/${props.modelValue.star}.webp`" alt="star" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
<template>
|
||||
<div class="tuc-dib-box">
|
||||
<div v-if="modelValue.bg" class="tuc-dib-bg">
|
||||
<img :src="modelValue.bg" alt="bg">
|
||||
<img :src="modelValue.bg" alt="bg" />
|
||||
</div>
|
||||
<div v-if="modelValue.icon" class="tuc-dib-icon">
|
||||
<img :src="modelValue.icon" alt="icon">
|
||||
<img :src="modelValue.icon" alt="icon" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
|
||||
interface TucDetailItemBoxProps {
|
||||
modelValue: {
|
||||
icon?: string,
|
||||
bg?: string,
|
||||
icon?: string;
|
||||
bg?: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
<TOverlay v-model="visible" hide :to-click="onCancel" blur-val="20px">
|
||||
<div class="tuc-do-box">
|
||||
<div class="tuc-do-bg">
|
||||
<img :src="data.bg" alt="role">
|
||||
</div>
|
||||
<div class="tuc-do-quote">
|
||||
* 所有数据以游戏内为准,此处仅供参考
|
||||
<img :src="data.bg" alt="role" />
|
||||
</div>
|
||||
<div class="tuc-do-quote">* 所有数据以游戏内为准,此处仅供参考</div>
|
||||
<!-- 衣装 -->
|
||||
<div v-if="data.costume.length>0" class="tuc-do-costume">
|
||||
<div v-if="data.costume.length > 0" class="tuc-do-costume">
|
||||
<v-switch v-model="showCostumeSwitch" color="#faf7e8" @click="switchBg">
|
||||
<template #label>
|
||||
<v-icon>mdi-tshirt-crew-outline</v-icon>
|
||||
@@ -26,7 +24,7 @@
|
||||
:style="{
|
||||
border: selected.pos === 0 ? '2px solid var(--common-color-yellow)' : '',
|
||||
}"
|
||||
@click="showDetail(data.weapon,'武器',0)"
|
||||
@click="showDetail(data.weapon, '武器', 0)"
|
||||
>
|
||||
<TucDetailItemBox v-model="weaponBox" />
|
||||
</div>
|
||||
@@ -37,7 +35,7 @@
|
||||
cursor: item ? 'pointer' : 'default',
|
||||
border: selected.pos === index + 1 ? '2px solid var(--common-color-yellow)' : '',
|
||||
}"
|
||||
@click="showDetail(item,'圣遗物',index + 1)"
|
||||
@click="showDetail(item, '圣遗物', index + 1)"
|
||||
>
|
||||
<TucDetailRelic :model-value="item" :pos="index.toString()" />
|
||||
</div>
|
||||
@@ -50,9 +48,9 @@
|
||||
class="tuc-dor-item"
|
||||
:model-value="item"
|
||||
:style="{
|
||||
border: selected.pos === item.pos+5 ? '2px solid var(--common-color-yellow)' : '',
|
||||
border: selected.pos === item.pos + 5 ? '2px solid var(--common-color-yellow)' : '',
|
||||
}"
|
||||
@click="showDetail(item, '命座', item.pos+5)"
|
||||
@click="showDetail(item, '命座', item.pos + 5)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -123,18 +121,21 @@ const data = ref({
|
||||
bg: "" as string,
|
||||
});
|
||||
const selected = ref({
|
||||
data: {} as TGApp.Sqlite.Character.RoleConstellation
|
||||
| TGApp.Sqlite.Character.RoleWeapon
|
||||
| TGApp.Sqlite.Character.RoleReliquary,
|
||||
data: {} as
|
||||
| TGApp.Sqlite.Character.RoleConstellation
|
||||
| TGApp.Sqlite.Character.RoleWeapon
|
||||
| TGApp.Sqlite.Character.RoleReliquary,
|
||||
type: "武器" || "命之座" || "圣遗物",
|
||||
pos: 0, // 用于标记选中的是哪个位置
|
||||
});
|
||||
|
||||
// 加载数据
|
||||
function loadData () {
|
||||
function loadData() {
|
||||
if (!props.modelValue) return;
|
||||
data.value.weapon = JSON.parse(props.dataVal.weapon) as TGApp.Sqlite.Character.RoleWeapon;
|
||||
data.value.constellation = JSON.parse(props.dataVal.constellation) as TGApp.Sqlite.Character.RoleConstellation[];
|
||||
data.value.constellation = JSON.parse(
|
||||
props.dataVal.constellation,
|
||||
) as TGApp.Sqlite.Character.RoleConstellation[];
|
||||
if (props.dataVal.reliquary !== "") {
|
||||
const relics = JSON.parse(props.dataVal.reliquary) as TGApp.Sqlite.Character.RoleReliquary[];
|
||||
relics.map((item) => {
|
||||
@@ -173,12 +174,12 @@ const onCancel = () => {
|
||||
emits("cancel");
|
||||
};
|
||||
|
||||
function showDetail (
|
||||
function showDetail(
|
||||
item:
|
||||
TGApp.Sqlite.Character.RoleConstellation |
|
||||
TGApp.Sqlite.Character.RoleWeapon |
|
||||
TGApp.Sqlite.Character.RoleReliquary |
|
||||
false,
|
||||
| TGApp.Sqlite.Character.RoleConstellation
|
||||
| TGApp.Sqlite.Character.RoleWeapon
|
||||
| TGApp.Sqlite.Character.RoleReliquary
|
||||
| false,
|
||||
type: string,
|
||||
pos: number = 0,
|
||||
) {
|
||||
@@ -190,7 +191,7 @@ function showDetail (
|
||||
};
|
||||
}
|
||||
|
||||
function switchBg () {
|
||||
function switchBg() {
|
||||
if (data.value.bg === props.dataVal.img) {
|
||||
data.value.bg = data.value.costume[0].icon;
|
||||
} else {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div class="tuc-dr-box">
|
||||
<div class="tuc-dr-bg">
|
||||
<img :src="`/icon/relic/${props.pos}.webp`" alt="relic">
|
||||
<img :src="`/icon/relic/${props.pos}.webp`" alt="relic" />
|
||||
</div>
|
||||
<div v-if="props.modelValue" class="tuc-dr-bg">
|
||||
<img :src="`/icon/bg/${props.modelValue.star}-Star.webp`" alt="bg">
|
||||
<img :src="`/icon/bg/${props.modelValue.star}-Star.webp`" alt="bg" />
|
||||
</div>
|
||||
<div v-if="props.modelValue" class="tuc-dr-icon">
|
||||
<img :src="props.modelValue.icon" alt="relic">
|
||||
<img :src="props.modelValue.icon" alt="relic" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -6,21 +6,19 @@
|
||||
</div>
|
||||
<div class="tuc-rb-bottom">
|
||||
<!-- bg 好感名片 -->
|
||||
<div v-if="nameCard!==false" class="tuc-rbb-bg">
|
||||
<img :src="nameCard" alt="nameCard">
|
||||
<div v-if="nameCard !== false" class="tuc-rbb-bg">
|
||||
<img :src="nameCard" alt="nameCard" />
|
||||
</div>
|
||||
<!-- 表面 lock -->
|
||||
<div v-if="props.modelValue.fetter!==10" class="tuc-rbb-lock">
|
||||
<v-icon size="20" color="var(--page-bg)">
|
||||
mdi-lock
|
||||
</v-icon>
|
||||
<div v-if="props.modelValue.fetter !== 10" class="tuc-rbb-lock">
|
||||
<v-icon size="20" color="var(--page-bg)"> mdi-lock </v-icon>
|
||||
</div>
|
||||
<!-- 左上角好感等级 -->
|
||||
<div class="tuc-rbb-fetter">
|
||||
<img src="/icon/material/105.webp" alt="fetter">
|
||||
<img src="/icon/material/105.webp" alt="fetter" />
|
||||
<span>{{ props.modelValue.fetter }}</span>
|
||||
<!-- 衣装 icon -->
|
||||
<span v-if="props.modelValue.costume!=='[]'">
|
||||
<span v-if="props.modelValue.costume !== '[]'">
|
||||
<v-icon>mdi-tshirt-crew-outline</v-icon>
|
||||
</span>
|
||||
</div>
|
||||
@@ -83,14 +81,12 @@ onMounted(async () => {
|
||||
nameCard.value = `/source/nameCard/profile/${role.nameCard}.webp`;
|
||||
});
|
||||
|
||||
function getAvatarName () {
|
||||
return (
|
||||
props.modelValue.cid === 10000005
|
||||
? "旅行者-空"
|
||||
: props.modelValue.cid === 10000007
|
||||
? "旅行者-荧"
|
||||
: props.modelValue.name
|
||||
);
|
||||
function getAvatarName() {
|
||||
return props.modelValue.cid === 10000005
|
||||
? "旅行者-空"
|
||||
: props.modelValue.cid === 10000007
|
||||
? "旅行者-荧"
|
||||
: props.modelValue.name;
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div v-if="props.modelValue===undefined">
|
||||
暂无数据
|
||||
</div>
|
||||
<div v-if="props.modelValue === undefined">暂无数据</div>
|
||||
<div v-else class="tur-ag-box">
|
||||
<TibUrAvatar v-for="avatar in data" :key="avatar.id" :model-value="avatar" />
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div v-if="props.modelValue===undefined">
|
||||
暂无数据
|
||||
</div>
|
||||
<div v-if="props.modelValue === undefined">暂无数据</div>
|
||||
<div v-else class="tur-hg-box">
|
||||
<TurHomeSub v-for="home in homes" :data="home" />
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</div>
|
||||
<div class="tur-hs-title">
|
||||
<!-- canvas -->
|
||||
<img :src="getUrl.icon" alt="comfort">
|
||||
<img :src="getUrl.icon" alt="comfort" />
|
||||
{{ data.comfortName }}
|
||||
</div>
|
||||
<div class="tur-hs-text-grid">
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div v-if="props.modelValue===undefined">
|
||||
暂无数据
|
||||
</div>
|
||||
<div v-if="props.modelValue === undefined">暂无数据</div>
|
||||
<div v-else class="tur-og-box">
|
||||
<TurOverviewSub title="活跃天数" :text="data.activeDays" />
|
||||
<TurOverviewSub title="成就达成数" :text="data.achievementNumber" />
|
||||
@@ -26,13 +24,11 @@ import { computed } from "vue";
|
||||
import TurOverviewSub from "./tur-overview-sub.vue";
|
||||
|
||||
interface TurOverviewGridProps {
|
||||
modelValue?: string
|
||||
modelValue?: string;
|
||||
}
|
||||
|
||||
const props = defineProps<TurOverviewGridProps>();
|
||||
const data = computed(() =>
|
||||
JSON.parse(<string>props.modelValue) as TGApp.Sqlite.Record.Stats,
|
||||
);
|
||||
const data = computed(() => JSON.parse(<string>props.modelValue) as TGApp.Sqlite.Record.Stats);
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tur-og-box {
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
interface TAOProps {
|
||||
title: string,
|
||||
text: string | number,
|
||||
title: string;
|
||||
text: string | number;
|
||||
}
|
||||
|
||||
defineProps<TAOProps>();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div v-if="props.modelValue===undefined">
|
||||
暂无数据
|
||||
</div>
|
||||
<div v-if="props.modelValue === undefined">暂无数据</div>
|
||||
<div v-else class="tur-wg-box">
|
||||
<TurWorldSub v-for="area in getData()" :data="area" :theme="theme" />
|
||||
</div>
|
||||
@@ -25,7 +23,7 @@ const theme = computed(() => {
|
||||
}
|
||||
});
|
||||
|
||||
function getData () {
|
||||
function getData() {
|
||||
return JSON.parse(<string>props.modelValue) as TGApp.Sqlite.Record.WorldExplore[];
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
backgroundImage: `url('${getUrl.bg}')`,
|
||||
backgroundPositionX: 'right',
|
||||
backgroundSize: 'cover',
|
||||
backgroundRepeat: 'no-repeat'
|
||||
backgroundRepeat: 'no-repeat',
|
||||
}"
|
||||
>
|
||||
<div class="tur-ws-icon">
|
||||
<img :src="getUrl.icon" alt="icon">
|
||||
<img :src="getUrl.icon" alt="icon" />
|
||||
</div>
|
||||
<div class="tur-ws-content">
|
||||
<div class="tur-ws-title">
|
||||
@@ -20,13 +20,13 @@
|
||||
<span>{{ data.exploration / 10 }}</span>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<div v-if="data.type==='Reputation'" class="tur-ws-sub">
|
||||
<div v-if="data.type === 'Reputation'" class="tur-ws-sub">
|
||||
<span>声望等级:</span>
|
||||
<span>{{ data.level }}</span>
|
||||
<span>级</span>
|
||||
</div>
|
||||
<div v-if="data.offerings.length>0" class="tur-ws-sub">
|
||||
<img :src="getUrl.offer" alt="offer">
|
||||
<div v-if="data.offerings.length > 0" class="tur-ws-sub">
|
||||
<img :src="getUrl.offer" alt="offer" />
|
||||
<span>{{ data.offerings[0].name }}等级:</span>
|
||||
<span>{{ data.offerings[0].level }}</span>
|
||||
<span>级</span>
|
||||
@@ -35,7 +35,6 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
|
||||
// vue
|
||||
import { onMounted, ref } from "vue";
|
||||
// tauri
|
||||
@@ -44,8 +43,8 @@ import { event } from "@tauri-apps/api";
|
||||
import { saveImgLocal } from "../../utils/TGShare";
|
||||
|
||||
interface TurWorldSubProps {
|
||||
theme: "default" | "dark",
|
||||
data: TGApp.Sqlite.Record.WorldExplore
|
||||
theme: "default" | "dark";
|
||||
data: TGApp.Sqlite.Record.WorldExplore;
|
||||
}
|
||||
|
||||
const props = defineProps<TurWorldSubProps>();
|
||||
@@ -66,11 +65,11 @@ onMounted(async () => {
|
||||
getUrl.value.offer = await saveImgLocal(props.data.offerings[0].icon);
|
||||
}
|
||||
props.theme === "dark"
|
||||
? getUrl.value.icon = getUrl.value.iconLight
|
||||
: getUrl.value.icon = getUrl.value.iconDark;
|
||||
? (getUrl.value.icon = getUrl.value.iconLight)
|
||||
: (getUrl.value.icon = getUrl.value.iconDark);
|
||||
});
|
||||
|
||||
async function listenOnTheme () {
|
||||
async function listenOnTheme() {
|
||||
await event.listen("readTheme", (e) => {
|
||||
const theme = e.payload as string;
|
||||
if (theme === "dark") {
|
||||
|
||||
Reference in New Issue
Block a user