mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
🌈 style(eslint): 第三次格式化
camecase 回头在部分文件 ignore 掉,不然不兼容之前的版本及外部接口 (cherry picked from commit 740b4698e916ce0f7911f5eac934183a94288e61)
This commit is contained in:
54
src/App.vue
54
src/App.vue
@@ -1,27 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="isMain">
|
<div v-if="isMain">
|
||||||
<v-layout>
|
<v-layout>
|
||||||
<!-- 侧边栏菜单 -->
|
<!-- 侧边栏菜单 -->
|
||||||
<TSidebar />
|
<TSidebar />
|
||||||
<!-- 主体内容 -->
|
<!-- 主体内容 -->
|
||||||
<v-main class="app-main">
|
<v-main class="app-main">
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
<router-view />
|
<router-view />
|
||||||
</v-container>
|
</v-container>
|
||||||
</v-main>
|
</v-main>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<v-layout>
|
<v-layout>
|
||||||
<!-- 主体内容 -->
|
<!-- 主体内容 -->
|
||||||
<v-main class="app-main">
|
<v-main class="app-main">
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
<router-view />
|
<router-view />
|
||||||
</v-container>
|
</v-container>
|
||||||
</v-main>
|
</v-main>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</div>
|
</div>
|
||||||
<TBackTop />
|
<TBackTop />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -43,7 +43,7 @@ const isMain = ref(true as boolean);
|
|||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 获取当前窗口
|
// 获取当前窗口
|
||||||
const win = await window.getCurrent();
|
const win = window.getCurrent();
|
||||||
isMain.value = win.label === "tauri-genshin";
|
isMain.value = win.label === "tauri-genshin";
|
||||||
if (isMain.value) {
|
if (isMain.value) {
|
||||||
const title = "Tauri.Genshin v" + (await app.getVersion()) + " Alpha";
|
const title = "Tauri.Genshin v" + (await app.getVersion()) + " Alpha";
|
||||||
@@ -93,8 +93,8 @@ async function writeIndex () {
|
|||||||
</script>
|
</script>
|
||||||
<style lang="css">
|
<style lang="css">
|
||||||
.app-main {
|
.app-main {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: #ece5d8;
|
background: #ece5d8;
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,74 +4,74 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.anno-body {
|
.anno-body {
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
width: 800px;
|
width: 800px;
|
||||||
font-family: "Genshin-Light", serif;
|
font-family: "Genshin-Light", serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-title {
|
.anno-title {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
color: #5b738f;
|
color: #5b738f;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-subtitle {
|
.anno-subtitle {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: #a1aeb6;
|
color: #a1aeb6;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-img {
|
.anno-img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
width: 800px;
|
width: 800px;
|
||||||
height: auto;
|
height: auto;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-content {
|
.anno-content {
|
||||||
line-height: 2;
|
line-height: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-link-icon {
|
.anno-link-icon {
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
color: #00c3ff;
|
color: #00c3ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-content :deep(a) {
|
.anno-content :deep(a) {
|
||||||
color: #00c3ff;
|
color: #00c3ff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-content :deep(p) {
|
.anno-content :deep(p) {
|
||||||
line-height: 2;
|
line-height: 2;
|
||||||
color: #4b5366;
|
color: #4b5366;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-content :deep(details) {
|
.anno-content :deep(details) {
|
||||||
border: #35acce 2px solid;
|
border: #35acce 2px solid;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-content :deep(details) div {
|
.anno-content :deep(details) div {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-content :deep(details) ::marker {
|
.anno-content :deep(details) ::marker {
|
||||||
color: #35acce;
|
color: #35acce;
|
||||||
content: "✧";
|
content: "✧";
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-content :deep(ol) {
|
.anno-content :deep(ol) {
|
||||||
list-style: "✧";
|
list-style: "✧";
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-content :deep(td) {
|
.anno-content :deep(td) {
|
||||||
line-height: 2;
|
line-height: 2;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,122 +4,122 @@
|
|||||||
*/
|
*/
|
||||||
/* todo scoped 不生效 */
|
/* todo scoped 不生效 */
|
||||||
.mys-post-body {
|
.mys-post-body {
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
width: 800px;
|
width: 800px;
|
||||||
font-family: "Genshin-Light", serif;
|
font-family: "Genshin-Light", serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-div) {
|
:deep(.mys-post-div) {
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-span) {
|
:deep(.mys-post-span) {
|
||||||
line-height: 2;
|
line-height: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-link) {
|
:deep(.mys-post-link) {
|
||||||
color: #00c3ff;
|
color: #00c3ff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-details) {
|
:deep(.mys-post-details) {
|
||||||
border: #35acce 2px solid;
|
border: #35acce 2px solid;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-details) ::marker {
|
:deep(.mys-post-details) ::marker {
|
||||||
color: #35acce;
|
color: #35acce;
|
||||||
content: "✧";
|
content: "✧";
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-divider) {
|
:deep(.mys-post-divider) {
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-divider) img {
|
:deep(.mys-post-divider) img {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-img) {
|
:deep(.mys-post-img) {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
width: 800px;
|
width: 800px;
|
||||||
height: auto;
|
height: auto;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-vod) {
|
:deep(.mys-post-vod) {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
height: 450px;
|
height: 450px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-iframe) {
|
:deep(.mys-post-iframe) {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
height: 450px;
|
height: 450px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-link-card) {
|
:deep(.mys-post-link-card) {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
background: #faf7e8;
|
background: #faf7e8;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-unknown) {
|
:deep(.mys-post-unknown) {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
background: #5b738f;
|
background: #5b738f;
|
||||||
color: #faf7e8;
|
color: #faf7e8;
|
||||||
font-family: Consolas, monospace;
|
font-family: Consolas, monospace;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin: 10px auto;
|
margin: 10px auto;
|
||||||
border: 2px solid #485466;
|
border: 2px solid #485466;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-link-card-cover) {
|
:deep(.mys-post-link-card-cover) {
|
||||||
width: auto;
|
width: auto;
|
||||||
height: 180px;
|
height: 180px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-link-card-cover) img {
|
:deep(.mys-post-link-card-cover) img {
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
width: auto;
|
width: auto;
|
||||||
height: 180px;
|
height: 180px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-link-card-content) {
|
:deep(.mys-post-link-card-content) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
height: 180px;
|
height: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-link-card-title) {
|
:deep(.mys-post-link-card-title) {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
color: #546d8b;
|
color: #546d8b;
|
||||||
height: 150px;
|
height: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-link-card-price) {
|
:deep(.mys-post-link-card-price) {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ff6d6d;
|
color: #ff6d6d;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-link-card-btn) {
|
:deep(.mys-post-link-card-btn) {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
float: right;
|
float: right;
|
||||||
color: #00c3ff;
|
color: #00c3ff;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* 设置全局字体 */
|
/* 设置全局字体 */
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Genshin";
|
font-family: "Genshin";
|
||||||
src: url("./汉仪文黑-85W.ttf") format("truetype");
|
src: url("./汉仪文黑-85W.ttf") format("truetype");
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Genshin-Light";
|
font-family: "Genshin-Light";
|
||||||
src: url("./汉仪文黑-55W.ttf") format("truetype");
|
src: url("./汉仪文黑-55W.ttf") format("truetype");
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Consolas";
|
font-family: "Consolas";
|
||||||
src: url("./consolas.ttf") format("truetype");
|
src: url("./consolas.ttf") format("truetype");
|
||||||
}
|
}
|
||||||
/* 全局字体样式 */
|
/* 全局字体样式 */
|
||||||
.global-font {
|
.global-font {
|
||||||
font-family: "Genshin", sans-serif;
|
font-family: "Genshin", sans-serif;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,31 +5,31 @@
|
|||||||
* @since Alpha v0.1.1
|
* @since Alpha v0.1.1
|
||||||
*/
|
*/
|
||||||
.dev-json {
|
.dev-json {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
font-family: Consolas, serif;
|
font-family: Consolas, serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* card action 内的按钮 */
|
/* card action 内的按钮 */
|
||||||
.card-btn {
|
.card-btn {
|
||||||
background: #4a5366;
|
background: #4a5366;
|
||||||
color: #ece5d8;
|
color: #ece5d8;
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-btn img {
|
.card-btn img {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-dev-btn {
|
.card-dev-btn {
|
||||||
background: #546d8b;
|
background: #546d8b;
|
||||||
color: #faf7e8;
|
color: #faf7e8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-dev-btn img {
|
.card-dev-btn img {
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div v-show="canTop" class="back-top" @click="handleScrollTop">
|
<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>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
@@ -50,37 +50,37 @@ onMounted(() => {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.back-top {
|
.back-top {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 0.4rem;
|
right: 0.4rem;
|
||||||
bottom: 1rem;
|
bottom: 1rem;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
transition: all 0.3s ease-in-out;
|
transition: all 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.back-top :hover {
|
.back-top :hover {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transform: scale(0.9);
|
transform: scale(0.9);
|
||||||
transition: all 0.3s ease-in-out;
|
transition: all 0.3s ease-in-out;
|
||||||
box-shadow: 0 0 10px 5px #546d8b;
|
box-shadow: 0 0 10px 5px #546d8b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.back-top img {
|
.back-top img {
|
||||||
transition: all 0.3s ease-in-out;
|
transition: all 0.3s ease-in-out;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 动画 */
|
/* 动画 */
|
||||||
.fade-enter-active,
|
.fade-enter-active,
|
||||||
.fade-leave-active {
|
.fade-leave-active {
|
||||||
transition: opacity 0.5s;
|
transition: opacity 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-enter,
|
.fade-enter,
|
||||||
.fade-leave-to {
|
.fade-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,38 +1,50 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-list class="calendar-card">
|
<v-list class="calendar-card">
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<v-list-item-title style="color: #fec90b; margin-left: 10px; margin-bottom: 10px; font-family: Genshin, serif">
|
<v-list-item-title style="color: #fec90b; margin-left: 10px; margin-bottom: 10px; font-family: Genshin, serif">
|
||||||
<v-icon color="#EBD49E">
|
<v-icon color="#EBD49E">
|
||||||
mdi-calendar-clock
|
mdi-calendar-clock
|
||||||
</v-icon> 今日素材
|
</v-icon> 今日素材
|
||||||
<span style="color: #faf7e8">{{ new Date().toLocaleDateString() }}</span>
|
<span style="color: #faf7e8">{{ new Date().toLocaleDateString() }}</span>
|
||||||
<v-btn
|
<v-btn
|
||||||
v-for="text of btnText"
|
v-for="text of btnText"
|
||||||
:key="text.week"
|
:key="text.week"
|
||||||
class="calendar-btn"
|
class="calendar-btn"
|
||||||
:style="{
|
:style="{
|
||||||
border: text.week === weekNow ? '2px solid #fec90b' : '0',
|
border: text.week === weekNow ? '2px solid #fec90b' : '0',
|
||||||
background: text.week === btnNow ? '#fec90b' : '#4A5366',
|
background: text.week === btnNow ? '#fec90b' : '#4A5366',
|
||||||
}"
|
}"
|
||||||
@click="getShowCards(text.week)"
|
@click="getShowCards(text.week)"
|
||||||
>
|
>
|
||||||
{{ text.text }}
|
{{ text.text }}
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
<div v-if="!loading" class="calendar-grid">
|
<div v-if="!loading" class="calendar-grid">
|
||||||
<v-card title="天赋培养" class="calendar-single">
|
<v-card title="天赋培养" class="calendar-single">
|
||||||
<v-card-text class="calendar-icons">
|
<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-img
|
||||||
</v-card-text>
|
v-for="item in showCharacters"
|
||||||
</v-card>
|
:key="item.id"
|
||||||
<v-card title="武器突破" class="calendar-single">
|
:src="item.cover"
|
||||||
<v-card-text class="calendar-icons">
|
class="calendar-icon"
|
||||||
<v-img v-for="item in showWeapons" :key="item.id" :src="item.cover" class="calendar-icon" @click="showContent(item)" />
|
@click="showContent(item)"
|
||||||
</v-card-text>
|
/>
|
||||||
</v-card>
|
</v-card-text>
|
||||||
</div>
|
</v-card>
|
||||||
</v-list-item>
|
<v-card title="武器突破" class="calendar-single">
|
||||||
</v-list>
|
<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>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
@@ -127,46 +139,46 @@ function showContent (item: CalendarCard) {
|
|||||||
</script>
|
</script>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.calendar-card {
|
.calendar-card {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
font-family: Genshin-Light, serif;
|
font-family: Genshin-Light, serif;
|
||||||
background: #546d8b;
|
background: #546d8b;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-grid {
|
.calendar-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
grid-gap: 10px;
|
grid-gap: 10px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-single {
|
.calendar-single {
|
||||||
background: #faf7e8;
|
background: #faf7e8;
|
||||||
color: #546d8b;
|
color: #546d8b;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-icons {
|
.calendar-icons {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));
|
||||||
grid-gap: 5px;
|
grid-gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-icon {
|
.calendar-icon {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-icon :hover {
|
.calendar-icon :hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-btn {
|
.calendar-btn {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
font-family: Genshin-Light, serif;
|
font-family: Genshin-Light, serif;
|
||||||
color: #faf7e8;
|
color: #faf7e8;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-overlay v-model="visible">
|
<v-overlay v-model="visible">
|
||||||
<div class="confirm-div">
|
<div class="confirm-div">
|
||||||
<div class="confirm-box">
|
<div class="confirm-box">
|
||||||
<div class="confirm-title">
|
<div class="confirm-title">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</div>
|
</div>
|
||||||
<div class="confirm-btn-box">
|
<div class="confirm-btn-box">
|
||||||
<button class="confirm-btn" @click="onCancel">
|
<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">
|
<span class="btn-text">
|
||||||
{{ cancel }}
|
{{ cancel }}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="confirm-btn" @click="onConfirm">
|
<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">
|
<span class="btn-text">
|
||||||
{{ confirm }}
|
{{ confirm }}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</v-overlay>
|
||||||
</v-overlay>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -68,64 +68,64 @@ const onConfirm = () => {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.confirm-div {
|
.confirm-div {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 40vw;
|
width: 40vw;
|
||||||
height: 20vh;
|
height: 20vh;
|
||||||
top: 40vh;
|
top: 40vh;
|
||||||
left: 30vw;
|
left: 30vw;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirm-box {
|
.confirm-box {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirm-title {
|
.confirm-title {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
height: 20%;
|
height: 20%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
color: #393b40;
|
color: #393b40;
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirm-btn-box {
|
.confirm-btn-box {
|
||||||
height: 60%;
|
height: 60%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirm-btn {
|
.confirm-btn {
|
||||||
width: 30%;
|
width: 30%;
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
min-height: 30px;
|
min-height: 30px;
|
||||||
background: #4a5366;
|
background: #4a5366;
|
||||||
color: #faf7e8;
|
color: #faf7e8;
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-icon {
|
.btn-icon {
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
width: 25px;
|
width: 25px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-text {
|
.btn-text {
|
||||||
width: calc(100% - 70px);
|
width: calc(100% - 70px);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-family: Genshin-Light, serif;
|
font-family: Genshin-Light, serif;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="loading-div">
|
<div class="loading-div">
|
||||||
<div class="loading-content">
|
<div class="loading-content">
|
||||||
<div class="loading-title">
|
<div class="loading-title">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
<v-progress-circular v-show="!empty" indeterminate color="#f4d8a8" />
|
<v-progress-circular v-show="!empty" indeterminate color="#f4d8a8" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="subtitle !== ''" class="loading-subtitle">
|
<div v-if="subtitle !== ''" class="loading-subtitle">
|
||||||
{{ subtitle }}
|
{{ subtitle }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!empty" class="loading-img">
|
<div v-if="!empty" class="loading-img">
|
||||||
<img src="/source/UI/loading.webp" alt="loading">
|
<img src="/source/UI/loading.webp" alt="loading">
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="loading-img">
|
<div v-else class="loading-img">
|
||||||
<img src="/source/UI/empty.webp" alt="empty">
|
<img src="/source/UI/empty.webp" alt="empty">
|
||||||
</div>
|
</div>
|
||||||
<div v-if="content !== ''" class="loading-text">
|
<div v-if="content !== ''" class="loading-text">
|
||||||
{{ content }}
|
{{ content }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
interface LoadingProps {
|
interface LoadingProps {
|
||||||
@@ -29,59 +29,56 @@ interface LoadingProps {
|
|||||||
position?: string;
|
position?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
withDefaults(
|
withDefaults(defineProps<LoadingProps>(), {
|
||||||
defineProps<LoadingProps>(),
|
title: "加载中",
|
||||||
{
|
subtitle: "",
|
||||||
title: "加载中",
|
content: "",
|
||||||
subtitle: "",
|
empty: false,
|
||||||
content: "",
|
position: "absolute",
|
||||||
empty: false,
|
});
|
||||||
position: "absolute",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.loading-div {
|
.loading-div {
|
||||||
position: v-bind(position);
|
position: v-bind(position);
|
||||||
display: flex;
|
display: flex;
|
||||||
top: 25%;
|
top: 25%;
|
||||||
left: 25%;
|
left: 25%;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
height: 50%;
|
height: 50%;
|
||||||
background: rgb(57 59 64 / 50%);
|
background: rgb(57 59 64 / 50%);
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-content {
|
.loading-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
border: #f4d8a8 1px solid;
|
border: #f4d8a8 1px solid;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-title {
|
.loading-title {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #f4d8a8;
|
color: #f4d8a8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-subtitle {
|
.loading-subtitle {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-family: Genshin-Light, serif;
|
font-family: Genshin-Light, serif;
|
||||||
color: #f4d8a8;
|
color: #f4d8a8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-img {
|
.loading-img {
|
||||||
width: 256px;
|
width: 256px;
|
||||||
height: 256px;
|
height: 256px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,45 +1,49 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-list class="pool-card">
|
<v-list class="pool-card">
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<v-list-item-title style="color: #fec90b; margin-left: 10px; font-family: Genshin, serif">
|
<v-list-item-title style="color: #fec90b; margin-left: 10px; font-family: Genshin, serif">
|
||||||
<img src="../assets/icons/icon-wish.svg" alt="wish" class="pool-wish-icon">
|
<img src="../assets/icons/icon-wish.svg" alt="wish" class="pool-wish-icon">
|
||||||
限时祈愿
|
限时祈愿
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
<div v-if="!loading" class="pool-grid">
|
<div v-if="!loading" class="pool-grid">
|
||||||
<v-card v-for="pool in poolCards" :key="pool.post_id" style="background: #faf7e8; color: #546d8b; border-radius: 10px">
|
<v-card
|
||||||
<v-list style="background: #faf7e8; color: #546d8b">
|
v-for="pool in poolCards"
|
||||||
<v-list-item :title="pool.title" :subtitle="pool.subtitle">
|
:key="pool.post_id"
|
||||||
<template #prepend>
|
style="background: #faf7e8; color: #546d8b; border-radius: 10px"
|
||||||
<v-img :src="pool.voice.icon" style="transform: translate(0, -10px); width: 60px; height: 60px" />
|
>
|
||||||
</template>
|
<v-list style="background: #faf7e8; color: #546d8b">
|
||||||
<template #append>
|
<v-list-item :title="pool.title" :subtitle="pool.subtitle">
|
||||||
<audio :src="pool.voice.url" controls />
|
<template #prepend>
|
||||||
</template>
|
<v-img :src="pool.voice.icon" style="transform: translate(0, -10px); width: 60px; height: 60px" />
|
||||||
</v-list-item>
|
</template>
|
||||||
</v-list>
|
<template #append>
|
||||||
<div class="pool-cover" @click="toPost(pool)">
|
<audio :src="pool.voice.url" controls />
|
||||||
<img :src="pool.cover" alt="cover">
|
</template>
|
||||||
</div>
|
</v-list-item>
|
||||||
<div class="pool-character">
|
</v-list>
|
||||||
<div v-for="character in pool.characters" :key="character.url" @click="toOuter(character.url, pool.title)">
|
<div class="pool-cover" @click="toPost(pool)">
|
||||||
<img :src="character.icon" class="pool-icon" alt="character">
|
<img :src="pool.cover" alt="cover">
|
||||||
</div>
|
</div>
|
||||||
<div class="pool-clock">
|
<div class="pool-character">
|
||||||
<v-progress-circular :model-value="poolTimePass[pool.post_id]" size="100" width="10" color="#90caf9">
|
<div v-for="character in pool.characters" :key="character.url" @click="toOuter(character.url, pool.title)">
|
||||||
{{ poolTimeGet[pool.post_id] }}
|
<img :src="character.icon" class="pool-icon" alt="character">
|
||||||
</v-progress-circular>
|
</div>
|
||||||
|
<div class="pool-clock">
|
||||||
|
<v-progress-circular :model-value="poolTimePass[pool.post_id]" size="100" width="10" color="#90caf9">
|
||||||
|
{{ poolTimeGet[pool.post_id] }}
|
||||||
|
</v-progress-circular>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<v-card-text>
|
||||||
<v-card-text>
|
<span style="width: 60%">
|
||||||
<span style="width: 60%">
|
<v-icon>mdi-calendar-clock</v-icon>
|
||||||
<v-icon>mdi-calendar-clock</v-icon>
|
{{ pool.time.start }}~{{ pool.time.end }}
|
||||||
{{ pool.time.start }}~{{ pool.time.end }}
|
</span>
|
||||||
</span>
|
</v-card-text>
|
||||||
</v-card-text>
|
</v-card>
|
||||||
</v-card>
|
</div>
|
||||||
</div>
|
</v-list-item>
|
||||||
</v-list-item>
|
</v-list>
|
||||||
</v-list>
|
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
@@ -101,7 +105,7 @@ onMounted(async () => {
|
|||||||
poolCards.value.map((pool) => {
|
poolCards.value.map((pool) => {
|
||||||
poolTimeGet.value[pool.post_id] = getLastPoolTime(pool.time.end_stamp - Date.now());
|
poolTimeGet.value[pool.post_id] = getLastPoolTime(pool.time.end_stamp - Date.now());
|
||||||
poolTimePass.value[pool.post_id] =
|
poolTimePass.value[pool.post_id] =
|
||||||
((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;
|
||||||
return pool;
|
return pool;
|
||||||
});
|
});
|
||||||
}, 1000);
|
}, 1000);
|
||||||
@@ -120,14 +124,14 @@ function checkCover (data: GachaData[]) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return data.every((item) => {
|
return data.every((item) => {
|
||||||
const post_id = item.activity_url.split("/").pop();
|
const postId = item.activity_url.split("/").pop();
|
||||||
if (!post_id || isNaN(Number(post_id))) {
|
if (!postId || isNaN(Number(postId))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!Object.keys(cover).includes(post_id)) {
|
if (!Object.keys(cover).includes(postId)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
const coverUrl = Object.keys(cover).find((key) => key === post_id);
|
const coverUrl = Object.keys(cover).find((key) => key === postId);
|
||||||
return coverUrl !== "/source/UI/empty.webp";
|
return coverUrl !== "/source/UI/empty.webp";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -148,6 +152,7 @@ function toPost (pool: GachaCard) {
|
|||||||
const path = router.resolve({
|
const path = router.resolve({
|
||||||
name: "帖子详情",
|
name: "帖子详情",
|
||||||
params: {
|
params: {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
post_id: pool.post_id.toString(),
|
post_id: pool.post_id.toString(),
|
||||||
},
|
},
|
||||||
}).href;
|
}).href;
|
||||||
@@ -157,75 +162,75 @@ function toPost (pool: GachaCard) {
|
|||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.pool-wish-icon {
|
.pool-wish-icon {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pool-card {
|
.pool-card {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: #546d8b;
|
background: #546d8b;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pool-grid {
|
.pool-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(600px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(600px, 1fr));
|
||||||
grid-gap: 20px;
|
grid-gap: 20px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pool-cover {
|
.pool-cover {
|
||||||
margin: 0 20px 10px;
|
margin: 0 20px 10px;
|
||||||
width: calc(100% - 40px);
|
width: calc(100% - 40px);
|
||||||
height: auto;
|
height: auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pool-cover img {
|
.pool-cover img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
transition: all 0.5s;
|
transition: all 0.5s;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pool-cover :hover {
|
.pool-cover :hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
transition: all 0.5s;
|
transition: all 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pool-character {
|
.pool-character {
|
||||||
margin: 0 20px;
|
margin: 0 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pool-character img {
|
.pool-character img {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pool-icon {
|
.pool-icon {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
margin: 0 10px;
|
margin: 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pool-character :hover .pool-icon {
|
.pool-character :hover .pool-icon {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pool-clock {
|
.pool-clock {
|
||||||
width: auto;
|
width: auto;
|
||||||
margin-left: 40px;
|
margin-left: 40px;
|
||||||
float: right;
|
float: right;
|
||||||
font-size: small;
|
font-size: small;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,47 +1,51 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-list class="position-card">
|
<v-list class="position-card">
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<v-list-item-title style="color: #fec90b; margin-left: 10px; font-family: Genshin, serif">
|
<v-list-item-title style="color: #fec90b; margin-left: 10px; font-family: Genshin, serif">
|
||||||
<img src="../assets/icons/board.svg" alt="act" class="position-act-icon">
|
<img src="../assets/icons/board.svg" alt="act" class="position-act-icon">
|
||||||
近期活动
|
近期活动
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
<div v-if="!loading" class="position-grid">
|
<div v-if="!loading" class="position-grid">
|
||||||
<v-card v-for="card in positionCards" :key="card.post_id" style="background: #faf7e8; color: #546d8b; border-radius: 10px">
|
<v-card
|
||||||
<v-list style="background: #faf7e8; color: #546d8b">
|
v-for="card in positionCards"
|
||||||
<v-list-item :title="card.title" :subtitle="card.abstract">
|
:key="card.post_id"
|
||||||
<template #prepend>
|
style="background: #faf7e8; color: #546d8b; border-radius: 10px"
|
||||||
<v-avatar rounded="0" style="cursor: pointer" @click="toPost(card)">
|
>
|
||||||
<v-img :src="card.icon" style="border-radius: 10px" />
|
<v-list style="background: #faf7e8; color: #546d8b">
|
||||||
</v-avatar>
|
<v-list-item :title="card.title" :subtitle="card.abstract">
|
||||||
</template>
|
<template #prepend>
|
||||||
</v-list-item>
|
<v-avatar rounded="0" style="cursor: pointer" @click="toPost(card)">
|
||||||
</v-list>
|
<v-img :src="card.icon" style="border-radius: 10px" />
|
||||||
<v-divider class="border-opacity-75" />
|
</v-avatar>
|
||||||
<v-card-text>
|
</template>
|
||||||
<span style="width: 60%">
|
</v-list-item>
|
||||||
<v-icon>mdi-calendar-clock</v-icon>
|
</v-list>
|
||||||
{{ card.time.start }}~{{ card.time.end }}
|
<v-divider class="border-opacity-75" />
|
||||||
</span>
|
<v-card-text>
|
||||||
</v-card-text>
|
<span style="width: 60%">
|
||||||
<v-card-actions>
|
<v-icon>mdi-calendar-clock</v-icon>
|
||||||
<span style="width: 80%; margin-left: 10px">
|
{{ card.time.start }}~{{ card.time.end }}
|
||||||
<v-icon>mdi-clock-outline</v-icon>
|
</span>
|
||||||
剩余时间:
|
</v-card-text>
|
||||||
<span v-if="positionTimeGet[card.post_id] !== '已结束'" style="color: #90caf9">{{
|
<v-card-actions>
|
||||||
positionTimeGet[card.post_id]
|
<span style="width: 80%; margin-left: 10px">
|
||||||
}}</span>
|
<v-icon>mdi-clock-outline</v-icon>
|
||||||
<span v-if="positionTimeGet[card.post_id] === '已结束'" style="color: #ff6d6d">已结束</span>
|
剩余时间:
|
||||||
</span>
|
<span v-if="positionTimeGet[card.post_id] !== '已结束'" style="color: #90caf9">{{
|
||||||
<v-btn class="card-btn" @click="toPost(card)">
|
positionTimeGet[card.post_id]
|
||||||
<template #prepend>
|
}}</span>
|
||||||
<img src="../assets/icons/circle-check.svg" alt="check">查看
|
<span v-if="positionTimeGet[card.post_id] === '已结束'" style="color: #ff6d6d">已结束</span>
|
||||||
</template>
|
</span>
|
||||||
</v-btn>
|
<v-btn class="card-btn" @click="toPost(card)">
|
||||||
</v-card-actions>
|
<template #prepend>
|
||||||
</v-card>
|
<img src="../assets/icons/circle-check.svg" alt="check">查看
|
||||||
</div>
|
</template>
|
||||||
</v-list-item>
|
</v-btn>
|
||||||
</v-list>
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
@@ -105,12 +109,12 @@ function getLastPositionTime (time: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function toPost (card: PositionCard) {
|
async function toPost (card: PositionCard) {
|
||||||
const post_id = card.post_id;
|
|
||||||
// 获取路由路径
|
// 获取路由路径
|
||||||
const path = router.resolve({
|
const path = router.resolve({
|
||||||
name: "帖子详情",
|
name: "帖子详情",
|
||||||
params: {
|
params: {
|
||||||
post_id,
|
// eslint-disable-next-line camelcase
|
||||||
|
post_id: card.post_id,
|
||||||
},
|
},
|
||||||
}).href;
|
}).href;
|
||||||
// 打开新窗口
|
// 打开新窗口
|
||||||
@@ -120,22 +124,22 @@ async function toPost (card: PositionCard) {
|
|||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.position-act-icon {
|
.position-act-icon {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-card {
|
.position-card {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
background: #546d8b;
|
background: #546d8b;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-grid {
|
.position-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, minmax(400px, 1fr));
|
grid-template-columns: repeat(3, minmax(400px, 1fr));
|
||||||
grid-gap: 20px;
|
grid-gap: 20px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,110 +1,110 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-navigation-drawer permanent :rail="rail" style="background: #485466; color: #faf7e8">
|
<v-navigation-drawer permanent :rail="rail" style="background: #485466; color: #faf7e8">
|
||||||
<v-list v-model:opened="open" class="side-list" density="compact" nav>
|
<v-list v-model:opened="open" class="side-list" density="compact" nav>
|
||||||
<!-- 负责收缩侧边栏 -->
|
<!-- 负责收缩侧边栏 -->
|
||||||
<v-list-item @click="collapse">
|
<v-list-item @click="collapse">
|
||||||
<template v-if="rail" #prepend>
|
<template v-if="rail" #prepend>
|
||||||
<v-list-item-action>
|
<v-list-item-action>
|
||||||
<v-icon color="rgb(205, 182, 145)">
|
|
||||||
mdi-chevron-right
|
|
||||||
</v-icon>
|
|
||||||
</v-list-item-action>
|
|
||||||
</template>
|
|
||||||
<template v-else #append>
|
|
||||||
<v-list-item-action>
|
|
||||||
<v-icon color="rgb(205, 182, 145)">
|
|
||||||
mdi-chevron-left
|
|
||||||
</v-icon>
|
|
||||||
</v-list-item-action>
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
<!-- 菜单项 -->
|
|
||||||
<v-list-item value="home" title="首页" link href="/">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="/source/UI/paimon.webp" alt="homeIcon" class="side-icon">
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item title="公告" value="announcements" link href="/announcements">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="../assets/icons/board.svg" alt="annoIcon" class="side-icon">
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
<v-divider />
|
|
||||||
<v-list-group value="mihoyo" fluid>
|
|
||||||
<template #activator="{ props }">
|
|
||||||
<v-list-item title="米游社" v-bind="props">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="/platforms/mhy/mys.webp" alt="mihoyo" class="side-icon">
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
</template>
|
|
||||||
<v-list-item title="原神" value="mhy-ys" link href="/news/2">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="/platforms/mhy/ys.webp" alt="ys" class="side-icon">
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item title="崩坏3" value="mhy-bh3" link href="/news/1">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="/platforms/mhy/bh3.webp" alt="bh3" class="side-icon">
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item title="崩坏2" value="mhy-bh2" link href="/news/3">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="/platforms/mhy/bh2.webp" alt="bh2" class="side-icon">
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item title="未定事件簿" value="mhy-wd" link href="/news/4">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="/platforms/mhy/wd.webp" alt="wd" class="side-icon">
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item title="星穹铁道" value="mhy-sr" link href="/news/6">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="/platforms/mhy/sr.webp" alt="sr" class="side-icon">
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item title="绝区零" value="mhy-zzz" link href="/news/8">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="/platforms/mhy/zzz.webp" alt="zzz" class="side-icon">
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item title="大别野" value="mhy-dby" link href="/news/5">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="/platforms/mhy/dby.webp" alt="dby" class="side-icon">
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list-group>
|
|
||||||
<v-divider />
|
|
||||||
<v-list-item title="成就" value="achievements" link href="/achievements">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="../assets/icons/achievements.svg" alt="achievementsIcon" class="side-icon">
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
<v-divider />
|
|
||||||
<v-list-group value="database" fluid>
|
|
||||||
<template #activator="{ props }">
|
|
||||||
<v-list-item title="数据库" v-bind="props">
|
|
||||||
<template #prepend>
|
|
||||||
<v-icon color="rgb(205, 182, 145)">
|
<v-icon color="rgb(205, 182, 145)">
|
||||||
mdi-database
|
mdi-chevron-right
|
||||||
</v-icon>
|
</v-icon>
|
||||||
</template>
|
</v-list-item-action>
|
||||||
</v-list-item>
|
</template>
|
||||||
</template>
|
<template v-else #append>
|
||||||
<v-list-item title="GCG" value="db-GCG" link href="/GCG">
|
<v-list-item-action>
|
||||||
<template #prepend>
|
<v-icon color="rgb(205, 182, 145)">
|
||||||
<img src="../assets/icons/GCG.svg" alt="gcgIcon" class="side-icon">
|
mdi-chevron-left
|
||||||
|
</v-icon>
|
||||||
|
</v-list-item-action>
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</v-list-group>
|
<!-- 菜单项 -->
|
||||||
<v-divider />
|
<v-list-item value="home" title="首页" link href="/">
|
||||||
<v-list-item title="设置" value="config" link href="/config">
|
<template #prepend>
|
||||||
<template #prepend>
|
<img src="/source/UI/paimon.webp" alt="homeIcon" class="side-icon">
|
||||||
<img src="../assets/icons/setting.svg" alt="setting" class="side-icon">
|
</template>
|
||||||
</template>
|
</v-list-item>
|
||||||
</v-list-item>
|
<v-list-item title="公告" value="announcements" link href="/announcements">
|
||||||
</v-list>
|
<template #prepend>
|
||||||
</v-navigation-drawer>
|
<img src="../assets/icons/board.svg" alt="annoIcon" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
<v-divider />
|
||||||
|
<v-list-group value="mihoyo" fluid>
|
||||||
|
<template #activator="{ props }">
|
||||||
|
<v-list-item title="米游社" v-bind="props">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="/platforms/mhy/mys.webp" alt="mihoyo" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</template>
|
||||||
|
<v-list-item title="原神" value="mhy-ys" link href="/news/2">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="/platforms/mhy/ys.webp" alt="ys" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item title="崩坏3" value="mhy-bh3" link href="/news/1">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="/platforms/mhy/bh3.webp" alt="bh3" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item title="崩坏2" value="mhy-bh2" link href="/news/3">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="/platforms/mhy/bh2.webp" alt="bh2" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item title="未定事件簿" value="mhy-wd" link href="/news/4">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="/platforms/mhy/wd.webp" alt="wd" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item title="星穹铁道" value="mhy-sr" link href="/news/6">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="/platforms/mhy/sr.webp" alt="sr" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item title="绝区零" value="mhy-zzz" link href="/news/8">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="/platforms/mhy/zzz.webp" alt="zzz" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item title="大别野" value="mhy-dby" link href="/news/5">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="/platforms/mhy/dby.webp" alt="dby" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list-group>
|
||||||
|
<v-divider />
|
||||||
|
<v-list-item title="成就" value="achievements" link href="/achievements">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="../assets/icons/achievements.svg" alt="achievementsIcon" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
<v-divider />
|
||||||
|
<v-list-group value="database" fluid>
|
||||||
|
<template #activator="{ props }">
|
||||||
|
<v-list-item title="数据库" v-bind="props">
|
||||||
|
<template #prepend>
|
||||||
|
<v-icon color="rgb(205, 182, 145)">
|
||||||
|
mdi-database
|
||||||
|
</v-icon>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</template>
|
||||||
|
<v-list-item title="GCG" value="db-GCG" link href="/GCG">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="../assets/icons/GCG.svg" alt="gcgIcon" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list-group>
|
||||||
|
<v-divider />
|
||||||
|
<v-list-item title="设置" value="config" link href="/config">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="../assets/icons/setting.svg" alt="setting" class="side-icon">
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-navigation-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -134,13 +134,13 @@ function collapse () {
|
|||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.side-list {
|
.side-list {
|
||||||
font-family: Genshin-Light, serif;
|
font-family: Genshin-Light, serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-icon {
|
.side-icon {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
margin-right: 32px;
|
margin-right: 32px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,102 +1,102 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 顶部操作栏 -->
|
<!-- 顶部操作栏 -->
|
||||||
<v-app-bar style="background: rgb(0 0 0 / 50%); color: #f4d8a8; font-family: Genshin, serif">
|
<v-app-bar style="background: rgb(0 0 0 / 50%); color: #f4d8a8; font-family: Genshin, serif">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<span style="font-size: 30px">{{ title }}</span>
|
<span style="font-size: 30px">{{ title }}</span>
|
||||||
</template>
|
</template>
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-model="search"
|
v-model="search"
|
||||||
append-icon="mdi-magnify"
|
append-icon="mdi-magnify"
|
||||||
label="搜索"
|
label="搜索"
|
||||||
hide-details
|
hide-details
|
||||||
@click:append="searchCard"
|
@click:append="searchCard"
|
||||||
@keyup.enter="searchCard"
|
@keyup.enter="searchCard"
|
||||||
/>
|
/>
|
||||||
<template #append>
|
<template #append>
|
||||||
<v-btn prepend-icon="mdi-import" class="ms-2 top-btn" @click="importJson">
|
<v-btn prepend-icon="mdi-import" class="ms-2 top-btn" @click="importJson">
|
||||||
导入
|
导入
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn prepend-icon="mdi-export" class="ms-2 top-btn" @click="exportJson">
|
<v-btn prepend-icon="mdi-export" class="ms-2 top-btn" @click="exportJson">
|
||||||
导出
|
导出
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</template>
|
||||||
</v-app-bar>
|
</v-app-bar>
|
||||||
<div v-show="loading">
|
<div v-show="loading">
|
||||||
<TLoading :title="loadingTitle" />
|
<TLoading :title="loadingTitle" />
|
||||||
</div>
|
|
||||||
<div v-show="!loading" class="wrap">
|
|
||||||
<!-- 左侧菜单 -->
|
|
||||||
<div class="left-wrap">
|
|
||||||
<v-list v-for="(series, index) in seriesList" :key="series.id" class="card-left" @click="selectSeries(index)">
|
|
||||||
<div class="version-icon-series">
|
|
||||||
v{{ series.version }}
|
|
||||||
</div>
|
|
||||||
<v-list-item>
|
|
||||||
<template #prepend>
|
|
||||||
<v-img width="40px" style="margin-right: 10px" :src="series.icon" />
|
|
||||||
</template>
|
|
||||||
<v-list-item-title>
|
|
||||||
{{ series.name }}
|
|
||||||
</v-list-item-title>
|
|
||||||
<v-list-item-subtitle> {{ series.completed_count }} / {{ series.total_count }} </v-list-item-subtitle>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- 右侧内容-->
|
<div v-show="!loading" class="wrap">
|
||||||
<div class="right-wrap">
|
<!-- 左侧菜单 -->
|
||||||
<v-list
|
<div class="left-wrap">
|
||||||
v-show="selectedIndex !== -1 && selectedSeries !== 0 && selectedSeries !== 17"
|
<v-list v-for="(series, index) in seriesList" :key="series.id" class="card-left" @click="selectSeries(index)">
|
||||||
:style="{
|
<div class="version-icon-series">
|
||||||
backgroundImage: 'url(' + getCardInfo.bg || null + ')',
|
v{{ series.version }}
|
||||||
backgroundPosition: 'right',
|
</div>
|
||||||
backgroundSize: 'auto 100%',
|
<v-list-item>
|
||||||
backgroundRepeat: 'no-repeat',
|
<template #prepend>
|
||||||
margin: '10px',
|
<v-img width="40px" style="margin-right: 10px" :src="series.icon" />
|
||||||
borderRadius: '10px 50px 50px 10px',
|
</template>
|
||||||
color: '#485466',
|
<v-list-item-title>
|
||||||
fontFamily: 'Genshin,serif',
|
{{ series.name }}
|
||||||
cursor: 'pointer',
|
</v-list-item-title>
|
||||||
}"
|
<v-list-item-subtitle> {{ series.completed_count }} / {{ series.total_count }} </v-list-item-subtitle>
|
||||||
@click="openImg()"
|
</v-list-item>
|
||||||
>
|
</v-list>
|
||||||
<v-list-item :title="getCardInfo.name" :subtitle="getCardInfo.description">
|
</div>
|
||||||
<template #prepend>
|
<!-- 右侧内容-->
|
||||||
<v-img width="80px" style="margin-right: 10px" :src="getCardInfo.icon" />
|
<div class="right-wrap">
|
||||||
</template>
|
<v-list
|
||||||
</v-list-item>
|
v-show="selectedIndex !== -1 && selectedSeries !== 0 && selectedSeries !== 17"
|
||||||
</v-list>
|
:style="{
|
||||||
<v-list v-for="achievement in selectedAchievement" :key="achievement.id" class="card-right">
|
backgroundImage: 'url(' + getCardInfo.bg || null + ')',
|
||||||
<v-list-item>
|
backgroundPosition: 'right',
|
||||||
<template #prepend>
|
backgroundSize: 'auto 100%',
|
||||||
<v-icon :color="achievement.completed ? '#fec90b' : '#485466'">
|
backgroundRepeat: 'no-repeat',
|
||||||
<!-- todo 图标替换 -->
|
margin: '10px',
|
||||||
{{ achievement.completed ? "mdi-check-circle" : "mdi-circle" }}
|
borderRadius: '10px 50px 50px 10px',
|
||||||
</v-icon>
|
color: '#485466',
|
||||||
</template>
|
fontFamily: 'Genshin,serif',
|
||||||
<v-list-item-title>
|
cursor: 'pointer',
|
||||||
{{ achievement.name }}
|
}"
|
||||||
{{ achievement.progress !== 0 ? "| " + achievement.progress : null }}
|
@click="openImg()"
|
||||||
<span class="version-icon-single">v{{ achievement.version }}</span>
|
>
|
||||||
</v-list-item-title>
|
<v-list-item :title="getCardInfo.name" :subtitle="getCardInfo.description">
|
||||||
<v-list-item-subtitle>{{ achievement.description }}</v-list-item-subtitle>
|
<template #prepend>
|
||||||
<template #append>
|
<v-img width="80px" style="margin-right: 10px" :src="getCardInfo.icon" />
|
||||||
<span v-show="achievement.completed" class="right-time">{{ achievement.completed_time }}</span>
|
</template>
|
||||||
<v-card class="reward-card" @click="showMaterial('/source/material/原石.webp')">
|
</v-list-item>
|
||||||
<v-img src="/source/material/原石.webp" sizes="32" />
|
</v-list>
|
||||||
<div class="reward-num">
|
<v-list v-for="achievement in selectedAchievement" :key="achievement.id" class="card-right">
|
||||||
<span>{{ achievement.reward }}</span>
|
<v-list-item>
|
||||||
</div>
|
<template #prepend>
|
||||||
</v-card>
|
<v-icon :color="achievement.completed ? '#fec90b' : '#485466'">
|
||||||
</template>
|
<!-- todo 图标替换 -->
|
||||||
</v-list-item>
|
{{ achievement.completed ? "mdi-check-circle" : "mdi-circle" }}
|
||||||
</v-list>
|
</v-icon>
|
||||||
|
</template>
|
||||||
|
<v-list-item-title>
|
||||||
|
{{ achievement.name }}
|
||||||
|
{{ achievement.progress !== 0 ? "| " + achievement.progress : null }}
|
||||||
|
<span class="version-icon-single">v{{ achievement.version }}</span>
|
||||||
|
</v-list-item-title>
|
||||||
|
<v-list-item-subtitle>{{ achievement.description }}</v-list-item-subtitle>
|
||||||
|
<template #append>
|
||||||
|
<span v-show="achievement.completed" class="right-time">{{ achievement.completed_time }}</span>
|
||||||
|
<v-card class="reward-card" @click="showMaterial('/source/material/原石.webp')">
|
||||||
|
<v-img src="/source/material/原石.webp" sizes="32" />
|
||||||
|
<div class="reward-num">
|
||||||
|
<span>{{ achievement.reward }}</span>
|
||||||
|
</div>
|
||||||
|
</v-card>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</div>
|
||||||
|
<!-- 弹窗提示 -->
|
||||||
|
<v-snackbar v-model="snackbar" timeout="1500" color="#F5810A" top>
|
||||||
|
{{ snackbarText }}
|
||||||
|
</v-snackbar>
|
||||||
</div>
|
</div>
|
||||||
<!-- 弹窗提示 -->
|
|
||||||
<v-snackbar v-model="snackbar" timeout="1500" color="#F5810A" top>
|
|
||||||
{{ snackbarText }}
|
|
||||||
</v-snackbar>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -271,7 +271,7 @@ async function importJson () {
|
|||||||
const localTime = localData.completed_time;
|
const localTime = localData.completed_time;
|
||||||
// 如果本地数据不存在,或者本地数据的 timeStamp 小于远程数据的 timeStamp,更新数据
|
// 如果本地数据不存在,或者本地数据的 timeStamp 小于远程数据的 timeStamp,更新数据
|
||||||
if (data.timestamp !== 0) {
|
if (data.timestamp !== 0) {
|
||||||
const fin_time = new Date(data.timestamp * 1000).toLocaleString("zh", {
|
const finishTime = new Date(data.timestamp * 1000).toLocaleString("zh", {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "2-digit",
|
month: "2-digit",
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
@@ -279,8 +279,9 @@ async function importJson () {
|
|||||||
minute: "2-digit",
|
minute: "2-digit",
|
||||||
second: "2-digit",
|
second: "2-digit",
|
||||||
});
|
});
|
||||||
if (fin_time !== localTime || localData.progress !== data.current) {
|
if (finishTime !== localTime || localData.progress !== data.current) {
|
||||||
localData.completed_time = fin_time;
|
// eslint-disable-next-line camelcase
|
||||||
|
localData.completed_time = finishTime;
|
||||||
localData.progress = data.current;
|
localData.progress = data.current;
|
||||||
localData.completed = true;
|
localData.completed = true;
|
||||||
// 更新数据
|
// 更新数据
|
||||||
@@ -288,6 +289,7 @@ async function importJson () {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (localData.progress !== data.current) {
|
if (localData.progress !== data.current) {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
localData.completed_time = "";
|
localData.completed_time = "";
|
||||||
localData.progress = data.current;
|
localData.progress = data.current;
|
||||||
localData.completed = false;
|
localData.completed = false;
|
||||||
@@ -303,6 +305,7 @@ async function importJson () {
|
|||||||
seriesDB.map(async (data) => {
|
seriesDB.map(async (data) => {
|
||||||
const seriesId = data.id;
|
const seriesId = data.id;
|
||||||
const achievementsDB = await ReadTGDataByIndex("Achievements", "series", seriesId);
|
const achievementsDB = await ReadTGDataByIndex("Achievements", "series", seriesId);
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
data.completed_count = achievementsDB.filter((data) => {
|
data.completed_count = achievementsDB.filter((data) => {
|
||||||
return data.completed === true;
|
return data.completed === true;
|
||||||
}).length;
|
}).length;
|
||||||
@@ -311,13 +314,13 @@ async function importJson () {
|
|||||||
);
|
);
|
||||||
loadingTitle.value = "正在刷新数据";
|
loadingTitle.value = "正在刷新数据";
|
||||||
seriesDB = await ReadAllTGData("AchievementSeries");
|
seriesDB = await ReadAllTGData("AchievementSeries");
|
||||||
const fin_achievements = seriesDB.reduce((a, b) => {
|
const finishAchievments = seriesDB.reduce((a, b) => {
|
||||||
return a + b.completed_count;
|
return a + b.completed_count;
|
||||||
}, 0);
|
}, 0);
|
||||||
const total_achievements = seriesDB.reduce((a, b) => {
|
const totalAchievements = seriesDB.reduce((a, b) => {
|
||||||
return a + b.total_count;
|
return a + b.total_count;
|
||||||
}, 0);
|
}, 0);
|
||||||
achievementsStore.flushData(total_achievements, fin_achievements);
|
achievementsStore.flushData(totalAchievements, finishAchievments);
|
||||||
// 刷新数据
|
// 刷新数据
|
||||||
await loadData();
|
await loadData();
|
||||||
}
|
}
|
||||||
@@ -361,7 +364,7 @@ async function exportJson () {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
UIAF_DATA.info = await UiafOper.getUiafInfo();
|
UIAF_DATA.info = await UiafOper.getUiafInfo();
|
||||||
const is_save = await dialog.save({
|
const isSave = await dialog.save({
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
name: "achievements",
|
name: "achievements",
|
||||||
@@ -369,8 +372,8 @@ async function exportJson () {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
if (is_save) {
|
if (isSave) {
|
||||||
await fs.writeTextFile(is_save, JSON.stringify(UIAF_DATA));
|
await fs.writeTextFile(isSave, JSON.stringify(UIAF_DATA));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -378,102 +381,102 @@ async function exportJson () {
|
|||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
/* 顶部按钮 */
|
/* 顶部按钮 */
|
||||||
.top-btn {
|
.top-btn {
|
||||||
background: #393b40;
|
background: #393b40;
|
||||||
color: #faf7e8 !important;
|
color: #faf7e8 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 内容区域 */
|
/* 内容区域 */
|
||||||
.wrap {
|
.wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
font-family: Genshin-Light, serif;
|
font-family: Genshin-Light, serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 左侧系列 */
|
/* 左侧系列 */
|
||||||
.left-wrap {
|
.left-wrap {
|
||||||
float: left;
|
float: left;
|
||||||
width: 25%;
|
width: 25%;
|
||||||
max-height: calc(100vh - 100px);
|
max-height: calc(100vh - 100px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 右侧成就 */
|
/* 右侧成就 */
|
||||||
.right-wrap {
|
.right-wrap {
|
||||||
float: right;
|
float: right;
|
||||||
width: 75%;
|
width: 75%;
|
||||||
max-height: calc(100vh - 100px);
|
max-height: calc(100vh - 100px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 版本信息 */
|
/* 版本信息 */
|
||||||
.version-icon-series {
|
.version-icon-series {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
background: #546d8b;
|
background: #546d8b;
|
||||||
border-radius: 10px 0 0;
|
border-radius: 10px 0 0;
|
||||||
border-top: #fff 2px solid;
|
border-top: #fff 2px solid;
|
||||||
border-left: #fff 2px solid;
|
border-left: #fff 2px solid;
|
||||||
color: #fec90b;
|
color: #fec90b;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.version-icon-single {
|
.version-icon-single {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #ff6d6d !important;
|
color: #ff6d6d !important;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-left {
|
.card-left {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
background: #485466;
|
background: #485466;
|
||||||
color: #fec90b;
|
color: #fec90b;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 成就卡片 */
|
/* 成就卡片 */
|
||||||
.card-right {
|
.card-right {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
background: #546d8b;
|
background: #546d8b;
|
||||||
color: #faf7e8;
|
color: #faf7e8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 成就完成时间 */
|
/* 成就完成时间 */
|
||||||
.right-time {
|
.right-time {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
font-size: small;
|
font-size: small;
|
||||||
color: #faf7e8;
|
color: #faf7e8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 成就奖励 */
|
/* 成就奖励 */
|
||||||
.reward-card {
|
.reward-card {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: url("/source/material/bg/5-Star.webp");
|
background: url("/source/material/bg/5-Star.webp");
|
||||||
}
|
}
|
||||||
|
|
||||||
.reward-num {
|
.reward-num {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
background: rgb(0 0 0 / 50%);
|
background: rgb(0 0 0 / 50%);
|
||||||
color: #faf7e8;
|
color: #faf7e8;
|
||||||
display: flex;
|
display: flex;
|
||||||
font-size: 8px;
|
font-size: 8px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,90 +1,90 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="loading">
|
<div v-if="loading">
|
||||||
<TLoading :title="loadingTitle" />
|
<TLoading :title="loadingTitle" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<v-tabs v-model="tab" align-tabs="start" class="global-font mb-2">
|
<v-tabs v-model="tab" align-tabs="start" class="global-font mb-2">
|
||||||
<v-tab value="activity" title="活动公告" />
|
<v-tab value="activity" title="活动公告" />
|
||||||
<v-tab value="game" title="游戏公告" />
|
<v-tab value="game" title="游戏公告" />
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
<v-btn class="switch-btn" @click="switchNews">
|
<v-btn class="switch-btn" @click="switchNews">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<v-icon>mdi-bullhorn</v-icon>
|
<v-icon>mdi-bullhorn</v-icon>
|
||||||
</template>
|
</template>
|
||||||
切换米游社咨讯
|
切换米游社咨讯
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-tabs>
|
</v-tabs>
|
||||||
<v-window v-model="tab">
|
<v-window v-model="tab">
|
||||||
<v-window-item value="activity">
|
<v-window-item value="activity">
|
||||||
<div class="anno-grid">
|
<div class="anno-grid">
|
||||||
<v-card v-for="item in annoCards.activity" :key="item.id" class="anno-card" width="340">
|
<v-card v-for="item in annoCards.activity" :key="item.id" class="anno-card" width="340">
|
||||||
<div class="anno-cover" @click="toPost(item)">
|
<div class="anno-cover" @click="toPost(item)">
|
||||||
<img :src="item.banner" alt="cover">
|
<img :src="item.banner" alt="cover">
|
||||||
</div>
|
</div>
|
||||||
<v-card-title>
|
<v-card-title>
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-card-subtitle>{{ item.subtitle }}</v-card-subtitle>
|
<v-card-subtitle>{{ item.subtitle }}</v-card-subtitle>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-btn class="anno-btn" @click="toPost(item)">
|
<v-btn class="anno-btn" @click="toPost(item)">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<img :src="item.tag_icon || '../assets/icons/arrow-right.svg'" alt="right">
|
<img :src="item.tag_icon || '../assets/icons/arrow-right.svg'" alt="right">
|
||||||
</template>
|
</template>
|
||||||
查看
|
查看
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-card-subtitle v-show="!appStore.devMode">
|
<v-card-subtitle v-show="!appStore.devMode">
|
||||||
<v-icon>mdi-calendar</v-icon>
|
<v-icon>mdi-calendar</v-icon>
|
||||||
{{ item.start_time.split(" ")[0] }} -
|
{{ item.start_time.split(" ")[0] }} -
|
||||||
{{ item.end_time.split(" ")[0] }}
|
{{ item.end_time.split(" ")[0] }}
|
||||||
</v-card-subtitle>
|
</v-card-subtitle>
|
||||||
<v-card-subtitle v-show="appStore.devMode">
|
<v-card-subtitle v-show="appStore.devMode">
|
||||||
id: {{ item.id }}
|
id: {{ item.id }}
|
||||||
</v-card-subtitle>
|
</v-card-subtitle>
|
||||||
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="toJson(item)">
|
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="toJson(item)">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<img src="../assets/icons/arrow-right.svg" alt="right">
|
<img src="../assets/icons/arrow-right.svg" alt="right">
|
||||||
</template>
|
</template>
|
||||||
查看数据
|
查看数据
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
<v-window-item value="game">
|
<v-window-item value="game">
|
||||||
<div class="anno-grid">
|
<div class="anno-grid">
|
||||||
<v-card v-for="item in annoCards.game" :key="item.id" class="anno-card" width="340">
|
<v-card v-for="item in annoCards.game" :key="item.id" class="anno-card" width="340">
|
||||||
<div class="anno-cover" @click="toPost(item)">
|
<div class="anno-cover" @click="toPost(item)">
|
||||||
<img :src="item.banner" alt="cover">
|
<img :src="item.banner" alt="cover">
|
||||||
</div>
|
</div>
|
||||||
<v-card-title>{{ item.title }}</v-card-title>
|
<v-card-title>{{ item.title }}</v-card-title>
|
||||||
<v-card-subtitle>{{ item.subtitle }}</v-card-subtitle>
|
<v-card-subtitle>{{ item.subtitle }}</v-card-subtitle>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-btn class="anno-btn" @click="toPost(item)">
|
<v-btn class="anno-btn" @click="toPost(item)">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<img :src="item.tag_icon || '../assets/icons/arrow-right.svg'" alt="right">
|
<img :src="item.tag_icon || '../assets/icons/arrow-right.svg'" alt="right">
|
||||||
</template>
|
</template>
|
||||||
查看
|
查看
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-card-subtitle v-show="!appStore.devMode">
|
<v-card-subtitle v-show="!appStore.devMode">
|
||||||
<v-icon>mdi-calendar</v-icon>
|
<v-icon>mdi-calendar</v-icon>
|
||||||
{{ item.start_time.split(" ")[0] }} -
|
{{ item.start_time.split(" ")[0] }} -
|
||||||
{{ item.end_time.split(" ")[0] }}
|
{{ item.end_time.split(" ")[0] }}
|
||||||
</v-card-subtitle>
|
</v-card-subtitle>
|
||||||
<v-card-subtitle v-show="appStore.devMode">
|
<v-card-subtitle v-show="appStore.devMode">
|
||||||
id: {{ item.id }}
|
id: {{ item.id }}
|
||||||
</v-card-subtitle>
|
</v-card-subtitle>
|
||||||
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="toJson(item)">
|
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="toJson(item)">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<img src="../assets/icons/arrow-right.svg" alt="right">
|
<img src="../assets/icons/arrow-right.svg" alt="right">
|
||||||
</template>
|
</template>
|
||||||
查看数据
|
查看数据
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
</v-window>
|
</v-window>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -140,6 +140,7 @@ async function toPost (item: AnnoListCard) {
|
|||||||
const path = router.resolve({
|
const path = router.resolve({
|
||||||
name: "游戏内公告",
|
name: "游戏内公告",
|
||||||
params: {
|
params: {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
anno_id: item.id,
|
anno_id: item.id,
|
||||||
},
|
},
|
||||||
}).href;
|
}).href;
|
||||||
@@ -150,6 +151,7 @@ async function toJson (item: AnnoListCard) {
|
|||||||
const path = router.resolve({
|
const path = router.resolve({
|
||||||
name: "游戏内公告(JSON)",
|
name: "游戏内公告(JSON)",
|
||||||
params: {
|
params: {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
anno_id: item.id,
|
anno_id: item.id,
|
||||||
},
|
},
|
||||||
}).href;
|
}).href;
|
||||||
@@ -159,55 +161,55 @@ async function toJson (item: AnnoListCard) {
|
|||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.anno-grid {
|
.anno-grid {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
||||||
grid-gap: 20px;
|
grid-gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-card {
|
.anno-card {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #faf7e8;
|
background: #faf7e8;
|
||||||
color: #546d8b;
|
color: #546d8b;
|
||||||
border-bottom: #4b5366 1px solid;
|
border-bottom: #4b5366 1px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-cover {
|
.anno-cover {
|
||||||
height: 130px;
|
height: 130px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-cover :hover {
|
.anno-cover :hover {
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
transition: all 0.3s linear;
|
transition: all 0.3s linear;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-cover img {
|
.anno-cover img {
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 130px;
|
height: 130px;
|
||||||
transition: all 0.3s linear;
|
transition: all 0.3s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-btn {
|
.anno-btn {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
background: #546d8b;
|
background: #546d8b;
|
||||||
color: #faf7e8;
|
color: #faf7e8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.anno-btn img {
|
.anno-btn img {
|
||||||
height: 30px;
|
height: 30px;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* switch */
|
/* switch */
|
||||||
.switch-btn {
|
.switch-btn {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
background: #ffca0a;
|
background: #ffca0a;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
color: #546d8b;
|
color: #546d8b;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,127 +1,127 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="loading">
|
<div v-if="loading">
|
||||||
<TLoading />
|
<TLoading />
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<v-list class="config-list">
|
<v-list class="config-list">
|
||||||
<v-list-subheader inset class="config-header">
|
<v-list-subheader inset class="config-header">
|
||||||
应用信息
|
应用信息
|
||||||
</v-list-subheader>
|
</v-list-subheader>
|
||||||
<v-divider inset class="border-opacity-75" />
|
<v-divider inset class="border-opacity-75" />
|
||||||
<v-list-item title="Tauri 版本" @click="toOuter('https://next--tauri.netlify.app/')">
|
<v-list-item title="Tauri 版本" @click="toOuter('https://next--tauri.netlify.app/')">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<img class="config-icon" src="/platforms/tauri.webp" alt="Tauri">
|
<img class="config-icon" src="/platforms/tauri.webp" alt="Tauri">
|
||||||
</template>
|
</template>
|
||||||
<template #append>
|
<template #append>
|
||||||
<v-list-item-subtitle>{{ versionTauri }}</v-list-item-subtitle>
|
<v-list-item-subtitle>{{ versionTauri }}</v-list-item-subtitle>
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<img class="config-icon" src="/icon.webp" alt="App">
|
<img class="config-icon" src="/icon.webp" alt="App">
|
||||||
</template>
|
</template>
|
||||||
<v-list-item-title>
|
<v-list-item-title>
|
||||||
应用版本
|
应用版本
|
||||||
<v-btn
|
<v-btn
|
||||||
class="card-btn"
|
class="card-btn"
|
||||||
size="small"
|
size="small"
|
||||||
@click="toOuter('https://github.com/BTMuli/Tauri.Genshin/releases/latest')"
|
@click="toOuter('https://github.com/BTMuli/Tauri.Genshin/releases/latest')"
|
||||||
>
|
>
|
||||||
Alpha
|
Alpha
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
<template #append>
|
<template #append>
|
||||||
<v-list-item-subtitle>{{ versionApp }}</v-list-item-subtitle>
|
<v-list-item-subtitle>{{ versionApp }}</v-list-item-subtitle>
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item title="成就版本">
|
<v-list-item title="成就版本">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<img class="config-icon" src="../assets/icons/achievements.svg" alt="Achievements">
|
<img class="config-icon" src="../assets/icons/achievements.svg" alt="Achievements">
|
||||||
</template>
|
</template>
|
||||||
<template #append>
|
<template #append>
|
||||||
<v-list-item-subtitle>{{ achievementsStore.last_version }}</v-list-item-subtitle>
|
<v-list-item-subtitle>{{ achievementsStore.last_version }}</v-list-item-subtitle>
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-subheader inset class="config-header">
|
<v-list-subheader inset class="config-header">
|
||||||
系统信息
|
系统信息
|
||||||
</v-list-subheader>
|
</v-list-subheader>
|
||||||
<v-divider inset class="border-opacity-75" />
|
<v-divider inset class="border-opacity-75" />
|
||||||
<v-list-item title="系统平台">
|
<v-list-item title="系统平台">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<v-icon>mdi-desktop-classic</v-icon>
|
<v-icon>mdi-desktop-classic</v-icon>
|
||||||
</template>
|
</template>
|
||||||
<template #append>
|
<template #append>
|
||||||
<v-list-item-subtitle>{{ osPlatform }}</v-list-item-subtitle>
|
<v-list-item-subtitle>{{ osPlatform }}</v-list-item-subtitle>
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item title="系统版本">
|
<v-list-item title="系统版本">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<v-icon>mdi-desktop-classic</v-icon>
|
<v-icon>mdi-desktop-classic</v-icon>
|
||||||
</template>
|
</template>
|
||||||
<template #append>
|
<template #append>
|
||||||
<v-list-item-subtitle>{{ osVersion }}</v-list-item-subtitle>
|
<v-list-item-subtitle>{{ osVersion }}</v-list-item-subtitle>
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-subheader inset class="config-header">
|
<v-list-subheader inset class="config-header">
|
||||||
设置
|
设置
|
||||||
</v-list-subheader>
|
</v-list-subheader>
|
||||||
<v-divider inset class="border-opacity-75" />
|
<v-divider inset class="border-opacity-75" />
|
||||||
<v-list-item prepend-icon="mdi-folder" title="打开用户数据目录" @click="openMergeData" />
|
<v-list-item prepend-icon="mdi-folder" title="打开用户数据目录" @click="openMergeData" />
|
||||||
<v-list-item prepend-icon="mdi-delete" title="清除用户缓存" @click="tryConfirm('delUser')" />
|
<v-list-item prepend-icon="mdi-delete" title="清除用户缓存" @click="tryConfirm('delUser')" />
|
||||||
<v-list-item prepend-icon="mdi-delete" title="清除临时数据" @click="tryConfirm('delTemp')" />
|
<v-list-item prepend-icon="mdi-delete" title="清除临时数据" @click="tryConfirm('delTemp')" />
|
||||||
<v-list-item prepend-icon="mdi-cog" title="恢复默认设置" @click="tryConfirm('delApp')" />
|
<v-list-item prepend-icon="mdi-cog" title="恢复默认设置" @click="tryConfirm('delApp')" />
|
||||||
<v-list-subheader inset class="config-header">
|
<v-list-subheader inset class="config-header">
|
||||||
调试
|
调试
|
||||||
</v-list-subheader>
|
</v-list-subheader>
|
||||||
<v-divider inset class="border-opacity-75" />
|
<v-divider inset class="border-opacity-75" />
|
||||||
<v-list-item title="开发者模式" subtitle="开启后将显示调试信息">
|
<v-list-item title="开发者模式" subtitle="开启后将显示调试信息">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<v-icon>mdi-bug</v-icon>
|
<v-icon>mdi-bug</v-icon>
|
||||||
</template>
|
</template>
|
||||||
<template #append>
|
<template #append>
|
||||||
<v-switch
|
<v-switch
|
||||||
v-model="appStore.devMode"
|
v-model="appStore.devMode"
|
||||||
:label="appStore.devMode ? '开启' : '关闭'"
|
:label="appStore.devMode ? '开启' : '关闭'"
|
||||||
inset
|
inset
|
||||||
color="#FAC51E"
|
color="#FAC51E"
|
||||||
@click="submitDevMode"
|
@click="submitDevMode"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<v-icon>mdi-view-dashboard</v-icon>
|
<v-icon>mdi-view-dashboard</v-icon>
|
||||||
</template>
|
</template>
|
||||||
<v-select v-model="showHome" :items="homeStore.getShowItem()" label="首页显示组件" multiple chips />
|
<v-select v-model="showHome" :items="homeStore.getShowItem()" label="首页显示组件" multiple chips />
|
||||||
<template #append>
|
<template #append>
|
||||||
<v-btn class="card-btn" @click="submitHome">
|
<v-btn class="card-btn" @click="submitHome">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<img src="../assets/icons/circle-check.svg" alt="check">
|
<img src="../assets/icons/circle-check.svg" alt="check">
|
||||||
提交
|
提交
|
||||||
</template>
|
</template>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-subheader inset class="config-header">
|
<v-list-subheader inset class="config-header">
|
||||||
路径
|
路径
|
||||||
</v-list-subheader>
|
</v-list-subheader>
|
||||||
<v-divider inset class="border-opacity-75" />
|
<v-divider inset class="border-opacity-75" />
|
||||||
<v-list-item prepend-icon="mdi-folder">
|
<v-list-item prepend-icon="mdi-folder">
|
||||||
<v-list-item-title>本地应用数据路径</v-list-item-title>
|
<v-list-item-title>本地应用数据路径</v-list-item-title>
|
||||||
<v-list-item-subtitle>{{ appStore.dataPath.app }}</v-list-item-subtitle>
|
<v-list-item-subtitle>{{ appStore.dataPath.app }}</v-list-item-subtitle>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item prepend-icon="mdi-folder">
|
<v-list-item prepend-icon="mdi-folder">
|
||||||
<v-list-item-title>本地用户数据路径</v-list-item-title>
|
<v-list-item-title>本地用户数据路径</v-list-item-title>
|
||||||
<v-list-item-subtitle>{{ appStore.dataPath.user }}</v-list-item-subtitle>
|
<v-list-item-subtitle>{{ appStore.dataPath.user }}</v-list-item-subtitle>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
<!-- 弹窗提示条 -->
|
<!-- 弹窗提示条 -->
|
||||||
<v-snackbar v-model="snackbar" timeout="1500" :color="snackbarColor">
|
<v-snackbar v-model="snackbar" timeout="1500" :color="snackbarColor">
|
||||||
{{ snackbarText }}
|
{{ snackbarText }}
|
||||||
</v-snackbar>
|
</v-snackbar>
|
||||||
<!-- 确认弹窗 -->
|
<!-- 确认弹窗 -->
|
||||||
<TConfirm v-model="confirmShow" :title="confirmText" @confirm="doConfirm(confirmOper)" />
|
<TConfirm v-model="confirmShow" :title="confirmText" @confirm="doConfirm(confirmOper)" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -301,27 +301,27 @@ async function submitHome () {
|
|||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.config-list {
|
.config-list {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
font-family: Genshin-Light, serif;
|
font-family: Genshin-Light, serif;
|
||||||
background: #faf7e8;
|
background: #faf7e8;
|
||||||
color: #546d8b;
|
color: #546d8b;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-header {
|
.config-header {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
background: #faf7e8;
|
background: #faf7e8;
|
||||||
color: #fec90b;
|
color: #fec90b;
|
||||||
font-size: large;
|
font-size: large;
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-icon {
|
.config-icon {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
background: #5b738f;
|
background: #5b738f;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,93 +1,93 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="loading">
|
<div v-if="loading">
|
||||||
<TLoading title="正在加载卡牌列表" />
|
<TLoading title="正在加载卡牌列表" />
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<v-tabs v-model="tab" align-tabs="start" class="global-font">
|
|
||||||
<div v-show="!doSearch">
|
|
||||||
<v-tab value="character" title="角色牌" />
|
|
||||||
<v-tab value="action" title="行动牌" />
|
|
||||||
<v-tab value="monster" title="魔物牌" />
|
|
||||||
</div>
|
|
||||||
<v-spacer />
|
|
||||||
<v-text-field
|
|
||||||
v-model="search"
|
|
||||||
append-icon="mdi-magnify"
|
|
||||||
label="搜索"
|
|
||||||
single-line
|
|
||||||
hide-details
|
|
||||||
@click:append="searchCard"
|
|
||||||
@keyup.enter="searchCard"
|
|
||||||
/>
|
|
||||||
</v-tabs>
|
|
||||||
<div v-if="!doSearch">
|
|
||||||
<v-window v-model="tab">
|
|
||||||
<v-window-item value="character">
|
|
||||||
<div class="cards-grid">
|
|
||||||
<v-card v-for="item in CardsInfoC" :key="item.id" class="card-cls" @click="toOuter(item.name, item.id)">
|
|
||||||
<div class="card-border">
|
|
||||||
<img src="/source/GCG/base/bg-normal.webp" alt="border">
|
|
||||||
</div>
|
|
||||||
<div class="card-cover">
|
|
||||||
<img :src="item.icon.normal" alt="cover">
|
|
||||||
</div>
|
|
||||||
<div class="card-content">
|
|
||||||
<span>{{ item.name }}</span>
|
|
||||||
</div>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</v-window-item>
|
|
||||||
<v-window-item value="action">
|
|
||||||
<div class="cards-grid">
|
|
||||||
<v-card v-for="item in CardsInfoA" :key="item.id" class="card-cls" @click="toOuter(item.name, item.id)">
|
|
||||||
<div class="card-border">
|
|
||||||
<img src="/source/GCG/base/bg-normal.webp" alt="border">
|
|
||||||
</div>
|
|
||||||
<div class="card-cover">
|
|
||||||
<img :src="item.icon.normal" alt="cover">
|
|
||||||
</div>
|
|
||||||
<div class="card-content">
|
|
||||||
<span>{{ item.name }}</span>
|
|
||||||
</div>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</v-window-item>
|
|
||||||
<v-window-item value="monster">
|
|
||||||
<div class="cards-grid">
|
|
||||||
<v-card v-for="item in CardsInfoM" :key="item.id" class="card-cls" @click="toOuter(item.name, item.id)">
|
|
||||||
<div class="card-border">
|
|
||||||
<img src="/source/GCG/base/bg-normal.webp" alt="border">
|
|
||||||
</div>
|
|
||||||
<div class="card-cover">
|
|
||||||
<img :src="item.icon.normal" alt="cover">
|
|
||||||
</div>
|
|
||||||
<div class="card-content">
|
|
||||||
<span>{{ item.name }}</span>
|
|
||||||
</div>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</v-window-item>
|
|
||||||
</v-window>
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="cards-grid">
|
<v-tabs v-model="tab" align-tabs="start" class="global-font">
|
||||||
<div v-for="item in CardsInfoS" :key="item.id" class="card-cls" @click="toOuter(item.name, item.id)">
|
<div v-show="!doSearch">
|
||||||
<div class="card-border">
|
<v-tab value="character" title="角色牌" />
|
||||||
<img src="/source/GCG/base/bg-normal.webp" alt="border">
|
<v-tab value="action" title="行动牌" />
|
||||||
</div>
|
<v-tab value="monster" title="魔物牌" />
|
||||||
<div class="card-cover">
|
</div>
|
||||||
<img :src="item.icon.normal" alt="cover">
|
<v-spacer />
|
||||||
</div>
|
<v-text-field
|
||||||
<div class="card-content">
|
v-model="search"
|
||||||
<span>{{ item.name }}</span>
|
append-icon="mdi-magnify"
|
||||||
|
label="搜索"
|
||||||
|
single-line
|
||||||
|
hide-details
|
||||||
|
@click:append="searchCard"
|
||||||
|
@keyup.enter="searchCard"
|
||||||
|
/>
|
||||||
|
</v-tabs>
|
||||||
|
<div v-if="!doSearch">
|
||||||
|
<v-window v-model="tab">
|
||||||
|
<v-window-item value="character">
|
||||||
|
<div class="cards-grid">
|
||||||
|
<v-card v-for="item in CardsInfoC" :key="item.id" class="card-cls" @click="toOuter(item.name, item.id)">
|
||||||
|
<div class="card-border">
|
||||||
|
<img src="/source/GCG/base/bg-normal.webp" alt="border">
|
||||||
|
</div>
|
||||||
|
<div class="card-cover">
|
||||||
|
<img :src="item.icon.normal" alt="cover">
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
</div>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
</v-window-item>
|
||||||
|
<v-window-item value="action">
|
||||||
|
<div class="cards-grid">
|
||||||
|
<v-card v-for="item in CardsInfoA" :key="item.id" class="card-cls" @click="toOuter(item.name, item.id)">
|
||||||
|
<div class="card-border">
|
||||||
|
<img src="/source/GCG/base/bg-normal.webp" alt="border">
|
||||||
|
</div>
|
||||||
|
<div class="card-cover">
|
||||||
|
<img :src="item.icon.normal" alt="cover">
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
</div>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
</v-window-item>
|
||||||
|
<v-window-item value="monster">
|
||||||
|
<div class="cards-grid">
|
||||||
|
<v-card v-for="item in CardsInfoM" :key="item.id" class="card-cls" @click="toOuter(item.name, item.id)">
|
||||||
|
<div class="card-border">
|
||||||
|
<img src="/source/GCG/base/bg-normal.webp" alt="border">
|
||||||
|
</div>
|
||||||
|
<div class="card-cover">
|
||||||
|
<img :src="item.icon.normal" alt="cover">
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
</div>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
</v-window-item>
|
||||||
|
</v-window>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div class="cards-grid">
|
||||||
|
<div v-for="item in CardsInfoS" :key="item.id" class="card-cls" @click="toOuter(item.name, item.id)">
|
||||||
|
<div class="card-border">
|
||||||
|
<img src="/source/GCG/base/bg-normal.webp" alt="border">
|
||||||
|
</div>
|
||||||
|
<div class="card-cover">
|
||||||
|
<img :src="item.icon.normal" alt="cover">
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<v-snackbar v-model="snackbar" timeout="1500" color="error">
|
||||||
|
未找到相关卡牌
|
||||||
|
</v-snackbar>
|
||||||
</div>
|
</div>
|
||||||
<v-snackbar v-model="snackbar" timeout="1500" color="error">
|
|
||||||
未找到相关卡牌
|
|
||||||
</v-snackbar>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
@@ -125,9 +125,9 @@ async function loadData () {
|
|||||||
CardsInfoM.value = CardsInfo.filter((item) => item.type === "魔物牌") as MonsterCard[];
|
CardsInfoM.value = CardsInfo.filter((item) => item.type === "魔物牌") as MonsterCard[];
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
function toOuter (card_name: string, card_id: number) {
|
function toOuter (cardName: string, cardId: number) {
|
||||||
const url = OBC_CONTENT_API.replace("{content_id}", card_id.toString());
|
const url = OBC_CONTENT_API.replace("{content_id}", cardId.toString());
|
||||||
createTGWindow(url, "GCG", card_name, 1200, 800, true);
|
createTGWindow(url, "GCG", cardName, 1200, 800, true);
|
||||||
}
|
}
|
||||||
async function searchCard () {
|
async function searchCard () {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@@ -147,73 +147,73 @@ async function searchCard () {
|
|||||||
</script>
|
</script>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.cards-grid {
|
.cards-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
||||||
grid-gap: 10px;
|
grid-gap: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 0 0 10px 10px;
|
border-radius: 0 0 10px 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-cls {
|
.card-cls {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 140px;
|
width: 140px;
|
||||||
height: 240px;
|
height: 240px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-cover {
|
.card-cover {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-cls:hover .card-cover {
|
.card-cls:hover .card-cover {
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-border {
|
.card-border {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-border img {
|
.card-border img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-cover img {
|
.card-cover img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-content {
|
.card-content {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
background: rgb(0 0 0 / 50%);
|
background: rgb(0 0 0 / 50%);
|
||||||
color: white;
|
color: white;
|
||||||
display: flex;
|
display: flex;
|
||||||
font-size: small;
|
font-size: small;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
border-radius: 0 0 10px 10px;
|
border-radius: 0 0 10px 10px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<TLoading v-if="loading" :title="loadingTitle" :subtitle="loadingSubtitle" />
|
<TLoading v-if="loading" :title="loadingTitle" :subtitle="loadingSubtitle" />
|
||||||
<component :is="item" v-for="item in components" v-show="!loading" :key="item" :ref="setItemRef" />
|
<component :is="item" v-for="item in components" v-show="!loading" :key="item" :ref="setItemRef" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const ANNO_LIST_API = `${Hk4eAnnoApi}/getAnnList?`;
|
|||||||
const ANNO_CONTENT_API = `${Hk4eAnnoApi}/getAnnContent?`;
|
const ANNO_CONTENT_API = `${Hk4eAnnoApi}/getAnnContent?`;
|
||||||
// 公告 Query
|
// 公告 Query
|
||||||
const ANNO_QUERY =
|
const ANNO_QUERY =
|
||||||
"game=hk4e&game_biz=hk4e_cn&lang=zh-cn&bundle_id=hk4e_cn&platform=pc®ion=cn_gf01&level=60&uid=500299765";
|
"game=hk4e&game_biz=hk4e_cn&lang=zh-cn&bundle_id=hk4e_cn&platform=pc®ion=cn_gf01&level=60&uid=500299765";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 获取游戏内公告列表
|
* @description 获取游戏内公告列表
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* @returns {string} API
|
* @returns {string} API
|
||||||
*/
|
*/
|
||||||
export const OBC_CONTENT_API =
|
export const OBC_CONTENT_API =
|
||||||
"https://bbs.mihoyo.com/ys/obc/content/{content_id}/detail?bbs_presentation_style=no_header";
|
"https://bbs.mihoyo.com/ys/obc/content/{content_id}/detail?bbs_presentation_style=no_header";
|
||||||
|
|
||||||
// 杂项接口
|
// 杂项接口
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { type NewsData, type NewsResponse } from "../interface/news";
|
|||||||
|
|
||||||
// 咨讯 API
|
// 咨讯 API
|
||||||
const NEWS_LIST_API =
|
const NEWS_LIST_API =
|
||||||
"https://bbs-api.mihoyo.com/post/wapi/getNewsList?gids={gid}&page_size={page_size}&type={news_type}&last_id={last_id}";
|
"https://bbs-api.mihoyo.com/post/wapi/getNewsList?gids={gid}&page_size={page_size}&type={news_type}&last_id={last_id}";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 咨讯类型
|
* @description 咨讯类型
|
||||||
@@ -53,11 +53,7 @@ export async function getNoticeList (gid: string = "2", pageSize: number = 20, l
|
|||||||
* @param {number} lastId 上一次请求的最后一条数据的 id
|
* @param {number} lastId 上一次请求的最后一条数据的 id
|
||||||
* @return {Promise<NewsData>}
|
* @return {Promise<NewsData>}
|
||||||
*/
|
*/
|
||||||
export async function getActivityList (
|
export async function getActivityList (gid: string = "2", pageSize: number = 20, lastId: number = 0): Promise<NewsData> {
|
||||||
gid: string = "2",
|
|
||||||
pageSize: number = 20,
|
|
||||||
lastId: number = 0,
|
|
||||||
): Promise<NewsData> {
|
|
||||||
const url = NEWS_LIST_API.replace("{page_size}", pageSize.toString())
|
const url = NEWS_LIST_API.replace("{page_size}", pageSize.toString())
|
||||||
.replace("{gid}", gid)
|
.replace("{gid}", gid)
|
||||||
.replace("{news_type}", NewsType.ACTIVITY)
|
.replace("{news_type}", NewsType.ACTIVITY)
|
||||||
|
|||||||
@@ -231,13 +231,13 @@ function DividerParser (data: PostStructuredContent): HTMLDivElement {
|
|||||||
const img = document.createElement("img");
|
const img = document.createElement("img");
|
||||||
if (data.insert.divider === "line_1") {
|
if (data.insert.divider === "line_1") {
|
||||||
img.src =
|
img.src =
|
||||||
"https://mihoyo-community-web.oss-cn-shanghai.aliyuncs.com/upload/2021/01/05/40eb5281cb24042bf34a9f1bcc61eaf5.png";
|
"https://mihoyo-community-web.oss-cn-shanghai.aliyuncs.com/upload/2021/01/05/40eb5281cb24042bf34a9f1bcc61eaf5.png";
|
||||||
} else if (data.insert.divider === "line_2") {
|
} else if (data.insert.divider === "line_2") {
|
||||||
img.src =
|
img.src =
|
||||||
"https://mihoyo-community-web.oss-cn-shanghai.aliyuncs.com/upload/2021/01/05/477d4c535e965bec1791203aecdfa8e6.png";
|
"https://mihoyo-community-web.oss-cn-shanghai.aliyuncs.com/upload/2021/01/05/477d4c535e965bec1791203aecdfa8e6.png";
|
||||||
} else if (data.insert.divider === "line_3") {
|
} else if (data.insert.divider === "line_3") {
|
||||||
img.src =
|
img.src =
|
||||||
"https://mihoyo-community-web.oss-cn-shanghai.aliyuncs.com/upload/2021/01/05/e7047588e912d60ff87a975e037c7606.png";
|
"https://mihoyo-community-web.oss-cn-shanghai.aliyuncs.com/upload/2021/01/05/e7047588e912d60ff87a975e037c7606.png";
|
||||||
} else if (data.insert.divider === "line_4") {
|
} else if (data.insert.divider === "line_4") {
|
||||||
img.src = "https://mihoyo-community-web.oss-cn-shanghai.aliyuncs.com/upload/2022/07/13/line_4.png";
|
img.src = "https://mihoyo-community-web.oss-cn-shanghai.aliyuncs.com/upload/2022/07/13/line_4.png";
|
||||||
} else {
|
} else {
|
||||||
@@ -265,13 +265,13 @@ function ImageParser (data: PostStructuredContent): HTMLDivElement {
|
|||||||
throw new Error("data.insert.image is not defined");
|
throw new Error("data.insert.image is not defined");
|
||||||
}
|
}
|
||||||
// if (!data.attributes) {
|
// if (!data.attributes) {
|
||||||
// throw new Error("data.attributes is not defined");
|
// throw new Error("data.attributes is not defined");
|
||||||
// }
|
// }
|
||||||
// if (!data.attributes.width) {
|
// if (!data.attributes.width) {
|
||||||
// throw new Error("data.attributes.width is not defined");
|
// throw new Error("data.attributes.width is not defined");
|
||||||
// }
|
// }
|
||||||
// if (!data.attributes.height) {
|
// if (!data.attributes.height) {
|
||||||
// throw new Error("data.attributes.height is not defined");
|
// throw new Error("data.attributes.height is not defined");
|
||||||
// }
|
// }
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
// 创建图片
|
// 创建图片
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="loading">
|
<div v-if="loading">
|
||||||
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
||||||
</div>
|
|
||||||
<div v-else class="dev-json">
|
|
||||||
<div class="anno-title">
|
|
||||||
活动列表 JSON
|
|
||||||
</div>
|
</div>
|
||||||
<JsonViewer :value="jsonList" copyable boxed />
|
<div v-else class="dev-json">
|
||||||
<div class="anno-title">
|
<div class="anno-title">
|
||||||
活动内容 JSON
|
活动列表 JSON
|
||||||
|
</div>
|
||||||
|
<JsonViewer :value="jsonList" copyable boxed />
|
||||||
|
<div class="anno-title">
|
||||||
|
活动内容 JSON
|
||||||
|
</div>
|
||||||
|
<JsonViewer :value="jsonContent" copyable boxed />
|
||||||
</div>
|
</div>
|
||||||
<JsonViewer :value="jsonContent" copyable boxed />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
@@ -32,14 +32,14 @@ const loadingTitle = ref("正在加载");
|
|||||||
const loadingEmpty = ref(false as boolean);
|
const loadingEmpty = ref(false as boolean);
|
||||||
|
|
||||||
// 数据
|
// 数据
|
||||||
const anno_id = Number(useRoute().params.anno_id);
|
const annoId = Number(useRoute().params.anno_id);
|
||||||
let jsonList = reactive({});
|
let jsonList = reactive({});
|
||||||
let jsonContent = reactive({});
|
let jsonContent = reactive({});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await appWindow.show();
|
await appWindow.show();
|
||||||
// 检查数据
|
// 检查数据
|
||||||
if (!anno_id) {
|
if (!annoId) {
|
||||||
loadingEmpty.value = true;
|
loadingEmpty.value = true;
|
||||||
loadingTitle.value = "未找到数据";
|
loadingTitle.value = "未找到数据";
|
||||||
return;
|
return;
|
||||||
@@ -49,10 +49,10 @@ onMounted(async () => {
|
|||||||
const listData = await GenshinOper.Announcement.getList();
|
const listData = await GenshinOper.Announcement.getList();
|
||||||
listData.list.map((item: Announcement) => {
|
listData.list.map((item: Announcement) => {
|
||||||
return item.list.map((single: AnnoListItem) => {
|
return item.list.map((single: AnnoListItem) => {
|
||||||
return single.ann_id === anno_id ? (jsonList = single) : null;
|
return single.ann_id === annoId ? (jsonList = single) : null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
jsonContent = await GenshinOper.Announcement.getContent(anno_id);
|
jsonContent = await GenshinOper.Announcement.getContent(annoId);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}, 200);
|
}, 200);
|
||||||
@@ -60,10 +60,10 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.anno-title {
|
.anno-title {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: #546d8b;
|
color: #546d8b;
|
||||||
font-family: Genshin-Light, serif;
|
font-family: Genshin-Light, serif;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<!-- eslint-disable vue/no-v-html -->
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
<template>
|
<template>
|
||||||
<div v-if="loading" class="loading">
|
<div v-if="loading" class="loading">
|
||||||
<TLoading :title="loadingTitle" :empty="loadingEmpty" />
|
<TLoading :title="loadingTitle" :empty="loadingEmpty" />
|
||||||
</div>
|
|
||||||
<div v-else class="anno-body">
|
|
||||||
<div class="anno-title">
|
|
||||||
{{ annoData.title }}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="anno-subtitle">
|
<div v-else class="anno-body">
|
||||||
{{ annoData.subtitle }}
|
<div class="anno-title">
|
||||||
|
{{ annoData.title }}
|
||||||
|
</div>
|
||||||
|
<div class="anno-subtitle">
|
||||||
|
{{ annoData.subtitle }}
|
||||||
|
</div>
|
||||||
|
<img :src="annoData.banner" alt="cover" class="anno-img">
|
||||||
|
<div class="anno-content" v-html="annoHtml" />
|
||||||
</div>
|
</div>
|
||||||
<img :src="annoData.banner" alt="cover" class="anno-img">
|
|
||||||
<div class="anno-content" v-html="annoHtml" />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
@@ -32,14 +32,14 @@ const loadingTitle = ref("正在加载");
|
|||||||
const loadingEmpty = ref(false as boolean);
|
const loadingEmpty = ref(false as boolean);
|
||||||
|
|
||||||
// 数据
|
// 数据
|
||||||
const anno_id = Number(useRoute().params.anno_id);
|
const annoId = Number(useRoute().params.anno_id);
|
||||||
const annoData = ref({} as AnnoContentItem);
|
const annoData = ref({} as AnnoContentItem);
|
||||||
const annoHtml = ref("");
|
const annoHtml = ref("");
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await appWindow.show();
|
await appWindow.show();
|
||||||
// 检查数据
|
// 检查数据
|
||||||
if (!anno_id) {
|
if (!annoId) {
|
||||||
loadingEmpty.value = true;
|
loadingEmpty.value = true;
|
||||||
loadingTitle.value = "未找到数据";
|
loadingTitle.value = "未找到数据";
|
||||||
return;
|
return;
|
||||||
@@ -47,7 +47,7 @@ onMounted(async () => {
|
|||||||
// 获取数据
|
// 获取数据
|
||||||
loadingTitle.value = "正在获取数据...";
|
loadingTitle.value = "正在获取数据...";
|
||||||
try {
|
try {
|
||||||
annoData.value = await GenshinOper.Announcement.getContent(anno_id);
|
annoData.value = await GenshinOper.Announcement.getContent(annoId);
|
||||||
loadingTitle.value = "正在渲染数据...";
|
loadingTitle.value = "正在渲染数据...";
|
||||||
annoHtml.value = GenshinOper.Announcement.parser(annoData.value.content);
|
annoHtml.value = GenshinOper.Announcement.parser(annoData.value.content);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,69 +1,69 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="loading">
|
<div v-if="loading">
|
||||||
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<div class="lottery-div">
|
|
||||||
<div class="lottery-title">
|
|
||||||
抽奖详情 {{ timeStatus }}
|
|
||||||
</div>
|
|
||||||
<v-list class="lottery-list">
|
|
||||||
<v-list-item>
|
|
||||||
<template #prepend>
|
|
||||||
<v-avatar>
|
|
||||||
<v-img :src="lotteryCard.creator.avatar_url" />
|
|
||||||
</v-avatar>
|
|
||||||
</template>
|
|
||||||
{{ lotteryCard.creator.nickname }}
|
|
||||||
<v-list-item-subtitle>{{ lotteryCard.creator.introduce }}</v-list-item-subtitle>
|
|
||||||
<template #append>
|
|
||||||
发起人
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item>
|
|
||||||
<v-list-item-title>{{ lotteryCard.participantWay }}</v-list-item-title>
|
|
||||||
<v-list-item-subtitle>{{ lotteryCard.id }}</v-list-item-subtitle>
|
|
||||||
<template #append>
|
|
||||||
抽奖 ID
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
<v-btn class="lottery-back" @click="backPost">
|
|
||||||
返回
|
|
||||||
</v-btn>
|
|
||||||
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="showJson = true">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="../assets/icons/arrow-right.svg" alt="right">
|
|
||||||
</template>
|
|
||||||
JSON
|
|
||||||
</v-btn>
|
|
||||||
</div>
|
</div>
|
||||||
<div v-show="showJson" class="dev-json">
|
<div v-else>
|
||||||
<JsonViewer :value="jsonData" copyable boxed />
|
<div class="lottery-div">
|
||||||
</div>
|
<div class="lottery-title">
|
||||||
<div class="lottery-div">
|
抽奖详情 {{ timeStatus }}
|
||||||
<div class="lottery-title">
|
</div>
|
||||||
奖品详情
|
|
||||||
</div>
|
|
||||||
<div v-for="reward in lotteryCard.rewards" :key="reward.rewardName">
|
|
||||||
<v-list class="lottery-list">
|
<v-list class="lottery-list">
|
||||||
<v-list-item :title="reward.rewardName" :subtitle="'中奖人数' + reward.winnerNumber" />
|
<v-list-item>
|
||||||
|
<template #prepend>
|
||||||
|
<v-avatar>
|
||||||
|
<v-img :src="lotteryCard.creator.avatar_url" />
|
||||||
|
</v-avatar>
|
||||||
|
</template>
|
||||||
|
{{ lotteryCard.creator.nickname }}
|
||||||
|
<v-list-item-subtitle>{{ lotteryCard.creator.introduce }}</v-list-item-subtitle>
|
||||||
|
<template #append>
|
||||||
|
发起人
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item>
|
||||||
|
<v-list-item-title>{{ lotteryCard.participantWay }}</v-list-item-title>
|
||||||
|
<v-list-item-subtitle>{{ lotteryCard.id }}</v-list-item-subtitle>
|
||||||
|
<template #append>
|
||||||
|
抽奖 ID
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
<div class="lottery-grid">
|
<v-btn class="lottery-back" @click="backPost">
|
||||||
<v-list v-for="user in reward.users" :key="user.uid" class="lottery-sub-list">
|
返回
|
||||||
<v-list-item>
|
</v-btn>
|
||||||
<template #prepend>
|
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="showJson = true">
|
||||||
<v-avatar>
|
<template #prepend>
|
||||||
<v-img :src="user.avatar_url" />
|
<img src="../assets/icons/arrow-right.svg" alt="right">
|
||||||
</v-avatar>
|
</template>
|
||||||
</template>
|
JSON
|
||||||
{{ user.nickname }}
|
</v-btn>
|
||||||
</v-list-item>
|
</div>
|
||||||
|
<div v-show="showJson" class="dev-json">
|
||||||
|
<JsonViewer :value="jsonData" copyable boxed />
|
||||||
|
</div>
|
||||||
|
<div class="lottery-div">
|
||||||
|
<div class="lottery-title">
|
||||||
|
奖品详情
|
||||||
|
</div>
|
||||||
|
<div v-for="reward in lotteryCard.rewards" :key="reward.rewardName">
|
||||||
|
<v-list class="lottery-list">
|
||||||
|
<v-list-item :title="reward.rewardName" :subtitle="'中奖人数' + reward.winnerNumber" />
|
||||||
</v-list>
|
</v-list>
|
||||||
|
<div class="lottery-grid">
|
||||||
|
<v-list v-for="user in reward.users" :key="user.uid" class="lottery-sub-list">
|
||||||
|
<v-list-item>
|
||||||
|
<template #prepend>
|
||||||
|
<v-avatar>
|
||||||
|
<v-img :src="user.avatar_url" />
|
||||||
|
</v-avatar>
|
||||||
|
</template>
|
||||||
|
{{ user.nickname }}
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
@@ -89,7 +89,7 @@ const loadingEmpty = ref(false as boolean);
|
|||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
|
|
||||||
// 数据
|
// 数据
|
||||||
const lottery_id = useRoute().params.lottery_id as string;
|
const lotteryId = useRoute().params.lottery_id as string;
|
||||||
const lotteryCard = ref({} as LotteryCard);
|
const lotteryCard = ref({} as LotteryCard);
|
||||||
const showJson = ref(false as boolean);
|
const showJson = ref(false as boolean);
|
||||||
let jsonData = reactive({} as LotteryData);
|
let jsonData = reactive({} as LotteryData);
|
||||||
@@ -102,14 +102,14 @@ function backPost () {
|
|||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await appWindow.show();
|
await appWindow.show();
|
||||||
// 检查数据
|
// 检查数据
|
||||||
if (!lottery_id) {
|
if (!lotteryId) {
|
||||||
loadingEmpty.value = true;
|
loadingEmpty.value = true;
|
||||||
loadingTitle.value = "未找到数据";
|
loadingTitle.value = "未找到数据";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 获取数据
|
// 获取数据
|
||||||
loadingTitle.value = "正在获取数据...";
|
loadingTitle.value = "正在获取数据...";
|
||||||
jsonData = await MysOper.Lottery.get(lottery_id);
|
jsonData = await MysOper.Lottery.get(lotteryId);
|
||||||
if (!jsonData) {
|
if (!jsonData) {
|
||||||
loadingEmpty.value = true;
|
loadingEmpty.value = true;
|
||||||
loadingTitle.value = "未找到数据";
|
loadingTitle.value = "未找到数据";
|
||||||
@@ -143,48 +143,48 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
<style lang="css">
|
<style lang="css">
|
||||||
.lottery-div {
|
.lottery-div {
|
||||||
background: #faf7e8;
|
background: #faf7e8;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lottery-title {
|
.lottery-title {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: #546d8b;
|
color: #546d8b;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lottery-list {
|
.lottery-list {
|
||||||
background: #546d8b;
|
background: #546d8b;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
color: #faf7e8;
|
color: #faf7e8;
|
||||||
font-family: Genshin-Light, serif;
|
font-family: Genshin-Light, serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lottery-sub-list {
|
.lottery-sub-list {
|
||||||
background: #faf7e8;
|
background: #faf7e8;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
color: #546d8b;
|
color: #546d8b;
|
||||||
font-family: Genshin-Light, serif;
|
font-family: Genshin-Light, serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lottery-back {
|
.lottery-back {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
color: #faf7e8 !important;
|
color: #faf7e8 !important;
|
||||||
background: #546d8b !important;
|
background: #546d8b !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lottery-grid {
|
.lottery-grid {
|
||||||
background: #546d8b;
|
background: #546d8b;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
grid-gap: 10px;
|
grid-gap: 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,143 +1,143 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="loading">
|
<div v-if="loading">
|
||||||
<TLoading :title="loadingTitle" />
|
<TLoading :title="loadingTitle" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<v-tabs v-model="tab" align-tabs="start" class="news-tabs">
|
<v-tabs v-model="tab" align-tabs="start" class="news-tabs">
|
||||||
<v-tab value="notice" title="公告" />
|
<v-tab value="notice" title="公告" />
|
||||||
<v-tab value="activity" title="活动" />
|
<v-tab value="activity" title="活动" />
|
||||||
<v-tab v-if="showNews" value="news" title="新闻" />
|
<v-tab v-if="showNews" value="news" title="新闻" />
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
<v-btn v-if="showSwitch" class="switch-btn" @click="switchAnno">
|
<v-btn v-if="showSwitch" class="switch-btn" @click="switchAnno">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<v-icon>mdi-bullhorn</v-icon>
|
<v-icon>mdi-bullhorn</v-icon>
|
||||||
</template>
|
</template>
|
||||||
切换游戏内公告
|
切换游戏内公告
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-show="appStore.devMode"
|
v-show="appStore.devMode"
|
||||||
v-model="search"
|
v-model="search"
|
||||||
append-icon="mdi-magnify"
|
append-icon="mdi-magnify"
|
||||||
label="搜索"
|
label="搜索"
|
||||||
single-line
|
single-line
|
||||||
hide-details
|
hide-details
|
||||||
@click:append="searchPost"
|
@click:append="searchPost"
|
||||||
@keyup.enter="searchPost"
|
@keyup.enter="searchPost"
|
||||||
/>
|
/>
|
||||||
</v-tabs>
|
</v-tabs>
|
||||||
<v-window v-model="tab">
|
<v-window v-model="tab">
|
||||||
<v-window-item value="notice">
|
<v-window-item value="notice">
|
||||||
<div class="news-grid">
|
<div class="news-grid">
|
||||||
<v-card v-for="item in postData.notice" :key="item.post_id" class="news-card" width="340">
|
<v-card v-for="item in postData.notice" :key="item.post_id" class="news-card" width="340">
|
||||||
<div class="news-cover" @click="toPost(item)">
|
<div class="news-cover" @click="toPost(item)">
|
||||||
<img :src="item.cover" alt="cover">
|
<img :src="item.cover" alt="cover">
|
||||||
</div>
|
|
||||||
<v-card-title>{{ item.title }}</v-card-title>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-btn class="card-btn" @click="toPost(item)">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="../assets/icons/circle-check.svg" alt="check">查看
|
|
||||||
</template>
|
|
||||||
</v-btn>
|
|
||||||
<v-card-subtitle>id:{{ item.post_id }}</v-card-subtitle>
|
|
||||||
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="toJson(item)">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="../assets/icons/arrow-right.svg" alt="right">
|
|
||||||
</template>
|
|
||||||
JSON
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
<div class="load-news">
|
|
||||||
<v-btn :loading="loadingSub" @click="loadMore('notice')">
|
|
||||||
<template #append>
|
|
||||||
<img src="../assets/icons/arrow-left.svg" alt="right">
|
|
||||||
</template>
|
|
||||||
已加载:{{ rawData.notice.last_id }},加载更多
|
|
||||||
</v-btn>
|
|
||||||
</div>
|
|
||||||
</v-window-item>
|
|
||||||
<v-window-item value="activity">
|
|
||||||
<div class="news-grid">
|
|
||||||
<v-card v-for="item in postData.activity" :key="item.post_id" class="news-card" width="340">
|
|
||||||
<div class="news-cover" @click="toPost(item)">
|
|
||||||
<img :src="item.cover" alt="cover">
|
|
||||||
</div>
|
|
||||||
<v-card-title>{{ item.title }}</v-card-title>
|
|
||||||
<v-card-subtitle>{{ item.subtitle }}</v-card-subtitle>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-btn class="card-btn" @click="toPost(item)">
|
|
||||||
<template #prepend>
|
|
||||||
<img src="../assets/icons/circle-check.svg" alt="check">查看
|
|
||||||
</template>
|
|
||||||
</v-btn>
|
|
||||||
<v-card-subtitle>id:{{ item.post_id }}</v-card-subtitle>
|
|
||||||
<div v-show="!appStore.devMode">
|
|
||||||
<v-btn
|
|
||||||
:style="{
|
|
||||||
background: item.status?.colorCss,
|
|
||||||
color: '#faf7e8 !important',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
{{ item.status?.status }}
|
|
||||||
</v-btn>
|
|
||||||
</div>
|
</div>
|
||||||
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="toJson(item)">
|
<v-card-title>{{ item.title }}</v-card-title>
|
||||||
<template #prepend>
|
<v-card-actions>
|
||||||
<img src="../assets/icons/arrow-right.svg" alt="right">
|
<v-btn class="card-btn" @click="toPost(item)">
|
||||||
</template>
|
<template #prepend>
|
||||||
JSON
|
<img src="../assets/icons/circle-check.svg" alt="check">查看
|
||||||
</v-btn>
|
</template>
|
||||||
</v-card-actions>
|
</v-btn>
|
||||||
</v-card>
|
<v-card-subtitle>id:{{ item.post_id }}</v-card-subtitle>
|
||||||
</div>
|
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="toJson(item)">
|
||||||
<div class="load-news">
|
<template #prepend>
|
||||||
<v-btn :loading="loadingSub" @click="loadMore('activity')">
|
<img src="../assets/icons/arrow-right.svg" alt="right">
|
||||||
<template #append>
|
</template>
|
||||||
<img src="../assets/icons/arrow-left.svg" alt="right">
|
JSON
|
||||||
</template>
|
</v-btn>
|
||||||
已加载:{{ rawData.activity.last_id }},加载更多
|
</v-card-actions>
|
||||||
</v-btn>
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
</v-window-item>
|
<div class="load-news">
|
||||||
<v-window-item v-if="showNews" value="news">
|
<v-btn :loading="loadingSub" @click="loadMore('notice')">
|
||||||
<div class="news-grid">
|
<template #append>
|
||||||
<v-card v-for="item in postData.news" :key="item.post_id" class="news-card" width="340">
|
<img src="../assets/icons/arrow-left.svg" alt="right">
|
||||||
<div class="news-cover" @click="toPost(item)">
|
</template>
|
||||||
<img :src="item.cover" alt="cover">
|
已加载:{{ rawData.notice.lastId }},加载更多
|
||||||
</div>
|
</v-btn>
|
||||||
<v-card-title>{{ item.title }}</v-card-title>
|
</div>
|
||||||
<v-card-actions>
|
</v-window-item>
|
||||||
<v-btn class="card-btn" @click="toPost(item)">
|
<v-window-item value="activity">
|
||||||
<template #prepend>
|
<div class="news-grid">
|
||||||
<img src="../assets/icons/circle-check.svg" alt="check">查看
|
<v-card v-for="item in postData.activity" :key="item.post_id" class="news-card" width="340">
|
||||||
</template>
|
<div class="news-cover" @click="toPost(item)">
|
||||||
</v-btn>
|
<img :src="item.cover" alt="cover">
|
||||||
<v-card-subtitle>id:{{ item.post_id }}</v-card-subtitle>
|
</div>
|
||||||
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="toJson(item)">
|
<v-card-title>{{ item.title }}</v-card-title>
|
||||||
<template #prepend>
|
<v-card-subtitle>{{ item.subtitle }}</v-card-subtitle>
|
||||||
<img src="../assets/icons/arrow-right.svg" alt="right">
|
<v-card-actions>
|
||||||
</template>
|
<v-btn class="card-btn" @click="toPost(item)">
|
||||||
JSON
|
<template #prepend>
|
||||||
</v-btn>
|
<img src="../assets/icons/circle-check.svg" alt="check">查看
|
||||||
</v-card-actions>
|
</template>
|
||||||
</v-card>
|
</v-btn>
|
||||||
</div>
|
<v-card-subtitle>id:{{ item.post_id }}</v-card-subtitle>
|
||||||
<div class="load-news">
|
<div v-show="!appStore.devMode">
|
||||||
<v-btn :loading="loadingSub" @click="loadMore('news')">
|
<v-btn
|
||||||
<template #append>
|
:style="{
|
||||||
<img src="../assets/icons/arrow-left.svg" alt="right">
|
background: item.status?.colorCss,
|
||||||
</template>
|
color: '#faf7e8 !important',
|
||||||
已加载:{{ rawData.news.last_id }},加载更多
|
}"
|
||||||
</v-btn>
|
>
|
||||||
</div>
|
{{ item.status?.status }}
|
||||||
</v-window-item>
|
</v-btn>
|
||||||
</v-window>
|
</div>
|
||||||
<v-snackbar v-model="snackbar" timeout="1500" :color="snackbarColor">
|
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="toJson(item)">
|
||||||
{{ snackbarText }}
|
<template #prepend>
|
||||||
</v-snackbar>
|
<img src="../assets/icons/arrow-right.svg" alt="right">
|
||||||
</div>
|
</template>
|
||||||
|
JSON
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
<div class="load-news">
|
||||||
|
<v-btn :loading="loadingSub" @click="loadMore('activity')">
|
||||||
|
<template #append>
|
||||||
|
<img src="../assets/icons/arrow-left.svg" alt="right">
|
||||||
|
</template>
|
||||||
|
已加载:{{ rawData.activity.lastId }},加载更多
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</v-window-item>
|
||||||
|
<v-window-item v-if="showNews" value="news">
|
||||||
|
<div class="news-grid">
|
||||||
|
<v-card v-for="item in postData.news" :key="item.post_id" class="news-card" width="340">
|
||||||
|
<div class="news-cover" @click="toPost(item)">
|
||||||
|
<img :src="item.cover" alt="cover">
|
||||||
|
</div>
|
||||||
|
<v-card-title>{{ item.title }}</v-card-title>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-btn class="card-btn" @click="toPost(item)">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="../assets/icons/circle-check.svg" alt="check">查看
|
||||||
|
</template>
|
||||||
|
</v-btn>
|
||||||
|
<v-card-subtitle>id:{{ item.post_id }}</v-card-subtitle>
|
||||||
|
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="toJson(item)">
|
||||||
|
<template #prepend>
|
||||||
|
<img src="../assets/icons/arrow-right.svg" alt="right">
|
||||||
|
</template>
|
||||||
|
JSON
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
<div class="load-news">
|
||||||
|
<v-btn :loading="loadingSub" @click="loadMore('news')">
|
||||||
|
<template #append>
|
||||||
|
<img src="../assets/icons/arrow-left.svg" alt="right">
|
||||||
|
</template>
|
||||||
|
已加载:{{ rawData.news.lastId }},加载更多
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</v-window-item>
|
||||||
|
</v-window>
|
||||||
|
<v-snackbar v-model="snackbar" timeout="1500" :color="snackbarColor">
|
||||||
|
{{ snackbarText }}
|
||||||
|
</v-snackbar>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -152,7 +152,7 @@ import MysOper from "../plugins/Mys";
|
|||||||
// utils
|
// utils
|
||||||
import { createTGWindow } from "../utils/TGWindow";
|
import { createTGWindow } from "../utils/TGWindow";
|
||||||
// interface
|
// interface
|
||||||
import { NewsCard } from "../plugins/Mys/interface/news";
|
import { NewsCard, NewsData } from "../plugins/Mys/interface/news";
|
||||||
|
|
||||||
// 路由
|
// 路由
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -184,33 +184,33 @@ const postData = ref({
|
|||||||
});
|
});
|
||||||
const rawData = ref({
|
const rawData = ref({
|
||||||
notice: {
|
notice: {
|
||||||
is_last: false,
|
isLast: false,
|
||||||
last_id: 0,
|
lastId: 0,
|
||||||
},
|
},
|
||||||
activity: {
|
activity: {
|
||||||
is_last: false,
|
isLast: false,
|
||||||
last_id: 0,
|
lastId: 0,
|
||||||
},
|
},
|
||||||
news: {
|
news: {
|
||||||
is_last: false,
|
isLast: false,
|
||||||
last_id: 0,
|
lastId: 0,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
loadingTitle.value = "正在获取公告数据...";
|
loadingTitle.value = "正在获取公告数据...";
|
||||||
const noticeData = await MysOper.News.get.notice(gid);
|
const noticeData = await MysOper.News.get.notice(gid);
|
||||||
rawData.value.notice.is_last = noticeData.is_last;
|
rawData.value.notice.isLast = noticeData.is_last;
|
||||||
rawData.value.notice.last_id = noticeData.list.length;
|
rawData.value.notice.lastId = noticeData.list.length;
|
||||||
loadingTitle.value = "正在获取活动数据...";
|
loadingTitle.value = "正在获取活动数据...";
|
||||||
const activityData = await MysOper.News.get.activity(gid);
|
const activityData = await MysOper.News.get.activity(gid);
|
||||||
rawData.value.activity.is_last = activityData.is_last;
|
rawData.value.activity.isLast = activityData.is_last;
|
||||||
rawData.value.activity.last_id = activityData.list.length;
|
rawData.value.activity.lastId = activityData.list.length;
|
||||||
if (showNews.value) {
|
if (showNews.value) {
|
||||||
loadingTitle.value = "正在获取新闻数据...";
|
loadingTitle.value = "正在获取新闻数据...";
|
||||||
const newsData = await MysOper.News.get.news(gid);
|
const newsData = await MysOper.News.get.news(gid);
|
||||||
rawData.value.news.is_last = newsData.is_last;
|
rawData.value.news.isLast = newsData.is_last;
|
||||||
rawData.value.news.last_id = newsData.list.length;
|
rawData.value.news.lastId = newsData.list.length;
|
||||||
postData.value = {
|
postData.value = {
|
||||||
notice: MysOper.News.card.notice(noticeData),
|
notice: MysOper.News.card.notice(noticeData),
|
||||||
activity: MysOper.News.card.activity(activityData),
|
activity: MysOper.News.card.activity(activityData),
|
||||||
@@ -234,50 +234,52 @@ async function switchAnno () {
|
|||||||
// 加载更多
|
// 加载更多
|
||||||
async function loadMore (data: string) {
|
async function loadMore (data: string) {
|
||||||
loadingSub.value = true;
|
loadingSub.value = true;
|
||||||
|
let getData: NewsData;
|
||||||
|
let getCard: NewsCard[];
|
||||||
switch (data) {
|
switch (data) {
|
||||||
case "notice":
|
case "notice":
|
||||||
if (rawData.value.notice.is_last) {
|
if (rawData.value.notice.isLast) {
|
||||||
snackbarText.value = "已经是最后一页了";
|
snackbarText.value = "已经是最后一页了";
|
||||||
snackbarColor.value = "#35acce";
|
snackbarColor.value = "#35acce";
|
||||||
snackbar.value = true;
|
snackbar.value = true;
|
||||||
loadingSub.value = false;
|
loadingSub.value = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const getNotice = await MysOper.News.get.notice(gid, 20, rawData.value.notice.last_id);
|
getData = await MysOper.News.get.notice(gid, 20, rawData.value.notice.lastId);
|
||||||
rawData.value.notice.last_id = rawData.value.notice.last_id + getNotice.list.length;
|
rawData.value.notice.lastId = rawData.value.notice.lastId + getData.list.length;
|
||||||
rawData.value.notice.is_last = getNotice.is_last;
|
rawData.value.notice.isLast = getData.is_last;
|
||||||
const noticeCard = MysOper.News.card.notice(getNotice);
|
getCard = MysOper.News.card.notice(getData);
|
||||||
postData.value.notice = postData.value.notice.concat(noticeCard);
|
postData.value.notice = postData.value.notice.concat(getCard);
|
||||||
loadingSub.value = false;
|
loadingSub.value = false;
|
||||||
break;
|
break;
|
||||||
case "activity":
|
case "activity":
|
||||||
if (rawData.value.activity.is_last) {
|
if (rawData.value.activity.isLast) {
|
||||||
snackbarText.value = "已经是最后一页了";
|
snackbarText.value = "已经是最后一页了";
|
||||||
snackbarColor.value = "#35acce";
|
snackbarColor.value = "#35acce";
|
||||||
snackbar.value = true;
|
snackbar.value = true;
|
||||||
loadingSub.value = false;
|
loadingSub.value = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const getActivity = await MysOper.News.get.activity(gid, 20, rawData.value.activity.last_id);
|
getData = await MysOper.News.get.activity(gid, 20, rawData.value.activity.lastId);
|
||||||
rawData.value.activity.last_id = rawData.value.activity.last_id + getActivity.list.length;
|
rawData.value.activity.lastId = rawData.value.activity.lastId + getData.list.length;
|
||||||
rawData.value.activity.is_last = getActivity.is_last;
|
rawData.value.activity.isLast = getData.is_last;
|
||||||
const activityCard = MysOper.News.card.activity(getActivity);
|
getCard = MysOper.News.card.activity(getData);
|
||||||
postData.value.activity = postData.value.activity.concat(activityCard);
|
postData.value.activity = postData.value.activity.concat(getCard);
|
||||||
loadingSub.value = false;
|
loadingSub.value = false;
|
||||||
break;
|
break;
|
||||||
case "news":
|
case "news":
|
||||||
if (rawData.value.news.is_last) {
|
if (rawData.value.news.isLast) {
|
||||||
snackbarText.value = "已经是最后一页了";
|
snackbarText.value = "已经是最后一页了";
|
||||||
snackbarColor.value = "#35acce";
|
snackbarColor.value = "#35acce";
|
||||||
snackbar.value = true;
|
snackbar.value = true;
|
||||||
loadingSub.value = false;
|
loadingSub.value = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const getNews = await MysOper.News.get.news(gid, 20, rawData.value.news.last_id);
|
getData = await MysOper.News.get.news(gid, 20, rawData.value.news.lastId);
|
||||||
rawData.value.news.last_id = rawData.value.news.last_id + getNews.list.length;
|
rawData.value.news.lastId = rawData.value.news.lastId + getData.list.length;
|
||||||
rawData.value.news.is_last = getNews.is_last;
|
rawData.value.news.isLast = getData.is_last;
|
||||||
const newsCard = MysOper.News.card.news(getNews);
|
getCard = MysOper.News.card.news(getData);
|
||||||
postData.value.news = postData.value.news.concat(newsCard);
|
postData.value.news = postData.value.news.concat(getCard);
|
||||||
loadingSub.value = false;
|
loadingSub.value = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -290,6 +292,7 @@ async function toPost (item: NewsCard | string) {
|
|||||||
const path = router.resolve({
|
const path = router.resolve({
|
||||||
name: "帖子详情",
|
name: "帖子详情",
|
||||||
params: {
|
params: {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
post_id: item,
|
post_id: item,
|
||||||
},
|
},
|
||||||
}).href;
|
}).href;
|
||||||
@@ -298,6 +301,7 @@ async function toPost (item: NewsCard | string) {
|
|||||||
const path = router.resolve({
|
const path = router.resolve({
|
||||||
name: "帖子详情",
|
name: "帖子详情",
|
||||||
params: {
|
params: {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
post_id: item.post_id.toString(),
|
post_id: item.post_id.toString(),
|
||||||
},
|
},
|
||||||
}).href;
|
}).href;
|
||||||
@@ -309,6 +313,7 @@ async function toJson (item: NewsCard | string) {
|
|||||||
const path = router.resolve({
|
const path = router.resolve({
|
||||||
name: "帖子详情(JSON)",
|
name: "帖子详情(JSON)",
|
||||||
params: {
|
params: {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
post_id: item,
|
post_id: item,
|
||||||
},
|
},
|
||||||
}).href;
|
}).href;
|
||||||
@@ -317,6 +322,7 @@ async function toJson (item: NewsCard | string) {
|
|||||||
const path = router.resolve({
|
const path = router.resolve({
|
||||||
name: "帖子详情(JSON)",
|
name: "帖子详情(JSON)",
|
||||||
params: {
|
params: {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
post_id: item.post_id.toString(),
|
post_id: item.post_id.toString(),
|
||||||
},
|
},
|
||||||
}).href;
|
}).href;
|
||||||
@@ -344,70 +350,70 @@ async function searchPost () {
|
|||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.news-tabs {
|
.news-tabs {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-grid {
|
.news-grid {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
||||||
grid-gap: 20px;
|
grid-gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-card {
|
.news-card {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #faf7e8;
|
background: #faf7e8;
|
||||||
color: #546d8b;
|
color: #546d8b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-cover {
|
.news-cover {
|
||||||
height: 150px;
|
height: 150px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-cover :hover {
|
.news-cover :hover {
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
transition: all 0.3s linear;
|
transition: all 0.3s linear;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-cover img {
|
.news-cover img {
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 150px;
|
height: 150px;
|
||||||
transition: all 0.3s linear;
|
transition: all 0.3s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* switch */
|
/* switch */
|
||||||
.switch-btn {
|
.switch-btn {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
background: #ffca0a;
|
background: #ffca0a;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
color: #546d8b;
|
color: #546d8b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* load more */
|
/* load more */
|
||||||
.load-news {
|
.load-news {
|
||||||
font-family: Genshin, serif;
|
font-family: Genshin, serif;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
transition: all 0.3s linear;
|
transition: all 0.3s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
.load-news button {
|
.load-news button {
|
||||||
background: #546d8b !important;
|
background: #546d8b !important;
|
||||||
color: #faf7e8 !important;
|
color: #faf7e8 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.load-news button img {
|
.load-news button img {
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="loading">
|
<div v-if="loading">
|
||||||
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="dev-json">
|
<div v-else class="dev-json">
|
||||||
<JsonViewer :value="jsonData" copyable boxed />
|
<JsonViewer :value="jsonData" copyable boxed />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
@@ -23,20 +23,20 @@ const loadingTitle = ref("正在加载");
|
|||||||
const loadingEmpty = ref(false as boolean);
|
const loadingEmpty = ref(false as boolean);
|
||||||
|
|
||||||
// 数据
|
// 数据
|
||||||
const post_id = Number(useRoute().params.post_id);
|
const postId = Number(useRoute().params.post_id);
|
||||||
let jsonData = reactive({});
|
let jsonData = reactive({});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await appWindow.show();
|
await appWindow.show();
|
||||||
// 检查数据
|
// 检查数据
|
||||||
if (!post_id) {
|
if (!postId) {
|
||||||
loadingEmpty.value = true;
|
loadingEmpty.value = true;
|
||||||
loadingTitle.value = "未找到数据";
|
loadingTitle.value = "未找到数据";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 获取数据
|
// 获取数据
|
||||||
loadingTitle.value = "正在获取数据...";
|
loadingTitle.value = "正在获取数据...";
|
||||||
jsonData = await MysOper.Post.get(post_id);
|
jsonData = await MysOper.Post.get(postId);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<!-- eslint-disable vue/no-v-html -->
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
<template>
|
<template>
|
||||||
<div v-if="loading">
|
<div v-if="loading">
|
||||||
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="mys-post-body" v-html="postHtml" />
|
<div v-else class="mys-post-body" v-html="postHtml" />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
@@ -21,13 +21,13 @@ const loadingTitle = ref("正在加载");
|
|||||||
const loadingEmpty = ref(false as boolean);
|
const loadingEmpty = ref(false as boolean);
|
||||||
|
|
||||||
// 数据
|
// 数据
|
||||||
const post_id = Number(useRoute().params.post_id);
|
const postId = Number(useRoute().params.post_id);
|
||||||
const postHtml = ref("");
|
const postHtml = ref("");
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await appWindow.show();
|
await appWindow.show();
|
||||||
// 检查数据
|
// 检查数据
|
||||||
if (!post_id) {
|
if (!postId) {
|
||||||
loadingEmpty.value = true;
|
loadingEmpty.value = true;
|
||||||
loadingTitle.value = "未找到数据";
|
loadingTitle.value = "未找到数据";
|
||||||
await appWindow.setTitle("未找到数据");
|
await appWindow.setTitle("未找到数据");
|
||||||
@@ -36,7 +36,7 @@ onMounted(async () => {
|
|||||||
// 获取数据
|
// 获取数据
|
||||||
loadingTitle.value = "正在获取数据...";
|
loadingTitle.value = "正在获取数据...";
|
||||||
try {
|
try {
|
||||||
const postData = await MysOper.Post.get(post_id);
|
const postData = await MysOper.Post.get(postId);
|
||||||
loadingTitle.value = "正在渲染数据...";
|
loadingTitle.value = "正在渲染数据...";
|
||||||
postHtml.value = MysOper.Post.parser(postData);
|
postHtml.value = MysOper.Post.parser(postData);
|
||||||
await appWindow.setTitle(postData.post.subject);
|
await appWindow.setTitle(postData.post.subject);
|
||||||
|
|||||||
Reference in New Issue
Block a user