mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2026-03-23 05:09:45 +08:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
436ed453e7 | ||
|
|
d6115cffcb | ||
|
|
01962fffb8 | ||
|
|
ad2d5ca657 | ||
|
|
c6af9870ab | ||
|
|
9c0fc4b315 | ||
|
|
ddec6bdc6f | ||
|
|
6f0813b27a | ||
|
|
eb96409a5d | ||
|
|
c91e2f80e9 | ||
|
|
3599ef0b74 | ||
|
|
4bf48636f9 | ||
|
|
20060287ab | ||
|
|
7fd7dfc642 | ||
|
|
b8a1f996f0 | ||
|
|
4769731d52 | ||
|
|
d962d52bd2 | ||
|
|
a1b85b3526 | ||
|
|
5ee9be1079 | ||
|
|
f48b7ef6ed | ||
|
|
5a14b90b67 | ||
|
|
9978becb3b | ||
|
|
2677bc44db | ||
|
|
cf74f7f6b4 | ||
|
|
c68716960b | ||
|
|
6c25e56010 | ||
|
|
f1db614dee | ||
|
|
a398a5fac3 | ||
|
|
e648ed6b59 | ||
|
|
749f68f982 | ||
|
|
9e95fb29b0 | ||
|
|
0408b222dc | ||
|
|
3edfff7388 | ||
|
|
2fc183bc9b | ||
|
|
00a2d7f009 | ||
|
|
7648fa4fc0 | ||
|
|
71f5c30ff9 | ||
|
|
a428c86a7e | ||
|
|
52926916b4 | ||
|
|
6c11a67a58 |
22
CHANGELOG.md
22
CHANGELOG.md
@@ -2,15 +2,33 @@
|
||||
Author: 目棃
|
||||
Date: 2023-03-30
|
||||
Description: CHANGELOG
|
||||
Update: 2023-05-25
|
||||
Update: 2023-05-28
|
||||
---
|
||||
|
||||
> 本文档 [`Front-matter`](https://github.com/BTMuli/Mucli#FrontMatter) 由 [MuCli](https://github.com/BTMuli/Mucli) 自动生成于`2023-03-30 15:39:49`
|
||||
>
|
||||
> 更新于 `2023-05-25 17:24:07`
|
||||
> 更新于 `2023-05-28 16:11:30`
|
||||
|
||||
# CHANGELOG
|
||||
|
||||
## [0.1.6](https://github.com/BTMuli/Tauri.Genshin/releases/v0.1.6) (2023-05-28)
|
||||
|
||||
### Feat
|
||||
|
||||
- 用户:添加部分数据获取请求
|
||||
|
||||
### Fix
|
||||
|
||||
- 页面:修复间距显示异常 [`a428c86a`](https://github.com/BTMuli/Tauri.Genshin/commit/a428c86a)
|
||||
- 成就:数据库更新后成就版本自动更新 [`71f5c30f`](https://github.com/BTMuli/Tauri.Genshin/commit/71f5c30f)
|
||||
- 首页:修复首页卡素材日历的问题 [`5a14b90b`](https://github.com/BTMuli/Tauri.Genshin/commit/5a14b90b)
|
||||
|
||||
### Change
|
||||
|
||||
- 组件:部分组件实现方式更改
|
||||
|
||||
FullCommits: [`v0.1.5 ~ v0.1.6`](https://github.com/BTMuli/Tauri.Genshin/compare/v0.1.5...v0.1.6)
|
||||
|
||||
## [0.1.5](https://github.com/BTMuli/Tauri.Genshin/releases/v0.1.5) (2023-05-25)
|
||||
|
||||
### Feat
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.5",
|
||||
"notes": "See the assets to download this version and install.",
|
||||
"pub_date": "2023-05-02T10:45:45.017Z",
|
||||
"pub_date": "2023-05-25T09:50:54.739Z",
|
||||
"platforms": {
|
||||
"windows-x86_64": {
|
||||
"signature": "dW50cnVzdGVkIGNvbW1lbnQ6IHNpZ25hdHVyZSBmcm9tIHRhdXJpIHNlY3JldCBrZXkKUlVSWkdzekNNZjh1aG54TWY5cWpnNW02d3dxSFNRSFg2aDlTOGdmSlRaM0VoQWUrR2JERE1MdGdDYUJXYUYybDlLa0RycW5SZjdjRndKVVNLdDhoQzltNVp3ZWhIVzhwRkFNPQp0cnVzdGVkIGNvbW1lbnQ6IHRpbWVzdGFtcDoxNjgzMDI0MzM4CWZpbGU6dGF1cmktZ2Vuc2hpbl8wLjEuNF94NjRfemgtQ04ubXNpLnppcApuOFNqamJqN0FwVXI2OHlTODhHVEl3Q1FTQzU2R1JVNi96b1Z4ZU5nRlk3aEY2WnMzaHZNTGJVdmpXc2wraTNWZUlkK2VZdlBxd1JYaWt3MUdGVWhBQT09Cg==",
|
||||
"url": "https://github.com/BTMuli/Tauri.Genshin/releases/download/v0.1.4/tauri-genshin_0.1.4_x64_zh-CN.msi.zip"
|
||||
"signature": "dW50cnVzdGVkIGNvbW1lbnQ6IHNpZ25hdHVyZSBmcm9tIHRhdXJpIHNlY3JldCBrZXkKUlVSWkdzekNNZjh1aHB0Y0g4b2Jyd2pMVkhKSDdGa0Q2UjM1OWRObFJFMlVEMXZkay9QNXRCOTQ5VS8wUkxPeHFCNVplRVdnTEt0QnM1U3lIZXVxK21VN3VBMlQ4TDRpMHdvPQp0cnVzdGVkIGNvbW1lbnQ6IHRpbWVzdGFtcDoxNjg1MDA4MjM5CWZpbGU6dGF1cmktZ2Vuc2hpbl8wLjEuNV94NjRfemgtQ04ubXNpLnppcAozSWFYSHJIT2JzYjdDLzhjV3FKMW9odzNTN05wZVVYalphM3ZFYS90R1E1WHl5aFMyNCt3MFFxR3hZM0tBZUE5Qjk2TG91WXorRXFzQ1VXR2pwZllDZz09Cg==",
|
||||
"url": "https://github.com/BTMuli/Tauri.Genshin/releases/download/v0.1.5/tauri-genshin_0.1.5_x64_zh-CN.msi.zip"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "tauri-genshin",
|
||||
"version": "0.1.5",
|
||||
"version": "0.1.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "tauri-genshin",
|
||||
"version": "0.1.5",
|
||||
"version": "0.1.6",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@mdi/font": "7.2.96",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "tauri-genshin",
|
||||
"description": "A Tauri App Demo",
|
||||
"private": true,
|
||||
"version": "0.1.5",
|
||||
"version": "0.1.6",
|
||||
"author": "BTMuli <bt-muli@outlook.com>",
|
||||
"packageManager": "npm@9.6.6",
|
||||
"scripts": {
|
||||
|
||||
2
src-tauri/Cargo.lock
generated
2
src-tauri/Cargo.lock
generated
@@ -3117,7 +3117,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-genshin"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-genshin"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
description = "A Tauri App"
|
||||
authors = ["BTMuli<bt-muli@outlook.com>"]
|
||||
license = "MIT"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"package": {
|
||||
"productName": "tauri-genshin",
|
||||
"version": "0.1.5"
|
||||
"version": "0.1.6"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
@@ -67,7 +67,7 @@
|
||||
"width": 1600,
|
||||
"height": 900,
|
||||
"center": true,
|
||||
"transparent": false
|
||||
"transparent": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
10
src/App.vue
10
src/App.vue
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<!-- glass-app{background: rgba(255, 255, 255, 0.1) !important;} -->
|
||||
<v-app class="glass-app">
|
||||
<TSidebar v-if="isMain" />
|
||||
<v-main>
|
||||
<v-container fluid class="app-container">
|
||||
@@ -77,9 +78,8 @@ async function createDataDir () {
|
||||
</script>
|
||||
<style lang="css">
|
||||
.app-container {
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background: var(--page-bg);
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background: var(--page-bg);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -56,62 +56,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<v-snackbar v-model="snackbar" :timeout="1500" :color="snackbarColor">
|
||||
{{ snackbarText }}
|
||||
</v-snackbar>
|
||||
<v-overlay v-model="showItem">
|
||||
<div class="calendar-item-box">
|
||||
<div class="calendar-item-top">
|
||||
<div class="calendar-item-icon">
|
||||
<TMiniAvatar v-if="selectedType=== 'character'" :model-value="selectedItem" size="100px" />
|
||||
<TMiniWeapon v-if="selectedType=== 'weapon'" :model-value="selectedItem" size="100px" />
|
||||
</div>
|
||||
<div class="calendar-item-content">
|
||||
<div v-for="item in selectedItem.materials" class="calendar-item-sub">
|
||||
<TCalendarMaterial :item="item" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calendar-item-line">
|
||||
<img src="/source/UI/item-line.webp" alt="line">
|
||||
</div>
|
||||
<div class="calendar-item-bottom">
|
||||
<div class="calendar-item-source">
|
||||
<div class="calendar-source-text">
|
||||
来源:
|
||||
</div>
|
||||
<img :src="`/icon/nation/${selectedItem.source.area}.webp`" alt="icon">
|
||||
<div class="calendar-source-text">
|
||||
{{ selectedItem.source.area }} - {{ selectedItem.source.name }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-btn">
|
||||
<v-btn @click="showDetail(selectedItem)">
|
||||
<template #append>
|
||||
<img src="../../assets/icons/arrow-right.svg" alt="right">
|
||||
</template>
|
||||
详情
|
||||
</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calendar-item-close" @click="showItem = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</div>
|
||||
</v-overlay>
|
||||
<ToCalendar v-model="showItem" :data-type="selectedType" :data-val="selectedItem" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import ToCalendar from "../overlay/to-calendar.vue";
|
||||
import TMiniAvatar from "../mini/t-mini-avatar.vue";
|
||||
import TMiniWeapon from "../mini/t-mini-weapon.vue";
|
||||
import TCalendarMaterial from "../mini/t-calendar-material.vue";
|
||||
// data
|
||||
import { AppCalendarData } from "../../data";
|
||||
// interface
|
||||
import { OBC_CONTENT_API } from "../../plugins/Mys/interface/utils";
|
||||
import { createTGWindow } from "../../utils/TGWindow";
|
||||
|
||||
// loading
|
||||
const loading = ref(true as boolean);
|
||||
@@ -132,11 +87,6 @@ const showItem = ref(false as boolean);
|
||||
const selectedItem = ref({} as TGApp.App.Calendar.Item);
|
||||
const selectedType = ref("character");
|
||||
|
||||
// snackbar
|
||||
const snackbar = ref(false as boolean);
|
||||
const snackbarText = ref("" as string);
|
||||
const snackbarColor = ref("success" as string);
|
||||
|
||||
const btnText = [
|
||||
{
|
||||
week: 7,
|
||||
@@ -194,17 +144,6 @@ function selectContent (item: TGApp.App.Calendar.Item, type: string) {
|
||||
showItem.value = true;
|
||||
}
|
||||
|
||||
function showDetail (item: TGApp.App.Calendar.Item) {
|
||||
if (item.contentId === 0) {
|
||||
snackbarText.value = "暂无详情";
|
||||
snackbarColor.value = "error";
|
||||
snackbar.value = true;
|
||||
return;
|
||||
}
|
||||
const url = OBC_CONTENT_API.replace("{content_id}", item.contentId.toString());
|
||||
createTGWindow(url, "素材详情", item.name, 1200, 800, true);
|
||||
}
|
||||
|
||||
function getContents (day: number) {
|
||||
btnNow.value = day;
|
||||
calendarNow.value = getCalendar(day);
|
||||
@@ -216,8 +155,8 @@ function getContents (day: number) {
|
||||
.calendar-box {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
|
||||
background: rgb(255 255 255 / 10%);
|
||||
box-shadow: 0 0 10px rgb(0 0 0 / 40%);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
@@ -225,14 +164,14 @@ function getContents (day: number) {
|
||||
height: 45px;
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
color:rgba(255, 255, 255, 0.8);
|
||||
color:rgb(255 255 255 / 80%);
|
||||
}
|
||||
|
||||
.calendar-title-left {
|
||||
width: 20%;
|
||||
height: 45px;
|
||||
font-family: Genshin, serif;
|
||||
text-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
|
||||
text-shadow: 0 0 10px rgb(0 0 0 / 80%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -256,7 +195,7 @@ function getContents (day: number) {
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
border-radius: 2px;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
background: rgb(0 0 0 / 40%);
|
||||
}
|
||||
|
||||
.calendar-sub {
|
||||
@@ -264,7 +203,7 @@ function getContents (day: number) {
|
||||
}
|
||||
|
||||
.calendar-sub-title {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
background: rgb(0 0 0 / 20%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
@@ -272,8 +211,8 @@ function getContents (day: number) {
|
||||
margin: 5px 0;
|
||||
border-radius: 5px;
|
||||
font-family: Genshin-Light, serif;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
text-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
|
||||
color: rgb(255 255 255 / 80%);
|
||||
text-shadow: 0 0 10px rgb(0 0 0 / 80%);
|
||||
}
|
||||
|
||||
.calendar-sub-title img {
|
||||
@@ -287,129 +226,4 @@ function getContents (day: number) {
|
||||
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
||||
grid-gap: 8px;
|
||||
}
|
||||
|
||||
/* overlay 盒子 */
|
||||
.calendar-item-box {
|
||||
position: absolute;
|
||||
width: 440px;
|
||||
height: 200px;
|
||||
color: #faf7e8;
|
||||
top: calc(50vh - 100px);
|
||||
left: calc(50vw - 220px);
|
||||
background: var(--content-bg-2);
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.calendar-item-top {
|
||||
height: 100px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.calendar-item-icon {
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.calendar-item-content {
|
||||
margin-left: 10px;
|
||||
font-family: Genshin, serif;
|
||||
color: var(--content-bg-1);
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
column-gap: 10px;
|
||||
row-gap: 10px;
|
||||
}
|
||||
|
||||
.calendar-item-sub {
|
||||
width: 150px;
|
||||
height: 45px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.calendar-item-sub img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
object-fit: cover;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.calendar-item-line {
|
||||
width: 420px;
|
||||
}
|
||||
|
||||
.calendar-item-line img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.calendar-item-bottom {
|
||||
background: rgb(0 0 0 / 30%);
|
||||
padding: 3px 10px;
|
||||
width: 420px;
|
||||
height: 56px;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.calendar-item-bottom img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.calendar-item-source {
|
||||
width: 300px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.calendar-source-text {
|
||||
height: 50px;
|
||||
font-size: 20px;
|
||||
font-family: Genshin-Light, serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.detail-btn {
|
||||
font-family: Genshin, serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
transition: all 0.3s linear;
|
||||
}
|
||||
|
||||
.detail-btn button {
|
||||
background: var(--btn-bg-1);
|
||||
color: #faf7e8;
|
||||
}
|
||||
|
||||
.detail-btn button img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.calendar-item-close {
|
||||
position: absolute;
|
||||
top: calc(50vh + 120px);
|
||||
left: calc(50vw - 15px);
|
||||
border-radius: 50%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: var(--content-bg-2);
|
||||
color: #546D8B;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
98
src/components/main/t-overlay.vue
Normal file
98
src/components/main/t-overlay.vue
Normal file
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<transition enter-from-class="tolo-enter-from" name="tolo">
|
||||
<div v-if="showTolo" class="tolo-box" @click.self.prevent="toClick">
|
||||
<transition enter-from-class="toli-enter-from" name="toli">
|
||||
<slot v-if="showToli" />
|
||||
</transition>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { ref, watch } from "vue";
|
||||
|
||||
interface TolProps {
|
||||
modelValue: boolean;
|
||||
toClick?: () => void;
|
||||
blurVal: string;
|
||||
hide?: true;
|
||||
}
|
||||
|
||||
const showTolo = ref(!props.hide);
|
||||
const showToli = ref(!props.hide);
|
||||
|
||||
const props = withDefaults(defineProps<TolProps>(), {
|
||||
modelValue: false,
|
||||
blurVal: "20px",
|
||||
});
|
||||
|
||||
watch(() => props.modelValue, () => {
|
||||
if (props.modelValue) {
|
||||
showTolo.value = true;
|
||||
showToli.value = true;
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
showToli.value = false;
|
||||
}, 100);
|
||||
setTimeout(() => {
|
||||
showTolo.value = false;
|
||||
}, 300);
|
||||
}
|
||||
},
|
||||
);
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tolo-enter-active,
|
||||
.tolo-leave-active,
|
||||
.toli-enter-active {
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.toli-leave-active {
|
||||
transition: all 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.tolo-enter-from,
|
||||
.toli-enter-from {
|
||||
opacity: 0;
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
.tolo-enter-to,
|
||||
.toli-enter-to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.tolo-leave-from {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.tolo-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.toli-leave-from {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.toli-leave-to {
|
||||
opacity: 0;
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
.tolo-box {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: rgb(0 0 0 / 50%);
|
||||
backdrop-filter: blur(v-bind(blurVal));
|
||||
z-index: 100;
|
||||
}
|
||||
</style>
|
||||
@@ -213,14 +213,14 @@ onUnmounted(() => {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
font-family: Genshin, serif;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
|
||||
background: rgb(255 255 255 / 10%);
|
||||
box-shadow: 0 0 10px rgb(0 0 0 / 40%);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.pool-title {
|
||||
color:rgba(255, 255, 255, 0.8);
|
||||
text-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
|
||||
color:rgb(255 255 255 / 80%);
|
||||
text-shadow: 0 0 10px rgb(0 0 0 / 80%);
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
}
|
||||
@@ -231,7 +231,7 @@ onUnmounted(() => {
|
||||
transform: translate(0, 2px);
|
||||
margin-right: 10px;
|
||||
border-radius: 50%;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
background: rgb(0 0 0 / 30%);
|
||||
}
|
||||
|
||||
.pool-grid {
|
||||
|
||||
@@ -142,14 +142,14 @@ onUnmounted(() => {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
font-family: Genshin, serif;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
|
||||
background: rgb(255 255 255 / 10%);
|
||||
box-shadow: 0 0 10px rgb(0 0 0 / 40%);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.position-title {
|
||||
color:rgba(255, 255, 255, 0.8);
|
||||
text-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
|
||||
color:rgb(255 255 255 / 80%);
|
||||
text-shadow: 0 0 10px rgb(0 0 0 / 80%);
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
172
src/components/mini/t-user-avatar.vue
Normal file
172
src/components/mini/t-user-avatar.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<div class="tua-box" @click="showData">
|
||||
<div class="tua-top">
|
||||
<div class="top-item">
|
||||
<div class="top-icon">
|
||||
<div class="ti-bg">
|
||||
<img :src="`/icon/bg/${props.modelValue.rarity===105?5:props.modelValue.rarity}-Star.webp`" alt="rarity">
|
||||
</div>
|
||||
<div class="ti-content">
|
||||
<img :src="props.modelValue.icon" alt="avatar">
|
||||
</div>
|
||||
<div class="ti-level">
|
||||
{{ props.modelValue.actived_constellation_num }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="top-text">
|
||||
Lv.{{ props.modelValue.level }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="top-item">
|
||||
<div class="top-icon">
|
||||
<div class="ti-bg">
|
||||
<img :src="`/icon/bg/${props.modelValue.weapon.rarity}-Star.webp`" alt="rarity">
|
||||
</div>
|
||||
<div class="ti-content">
|
||||
<img :src="props.modelValue.weapon.icon" alt="avatar">
|
||||
</div>
|
||||
<div class="ti-level">
|
||||
{{ props.modelValue.weapon.affix_level }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="top-text">
|
||||
Lv.{{ props.modelValue.level }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="tua-bottom">-->
|
||||
<!-- <div class="bottom-item">A</div>-->
|
||||
<!-- <div class="bottom-item">E</div>-->
|
||||
<!-- <div class="bottom-item">Q</div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
interface TUAProps {
|
||||
modelValue: TGApp.Game.Character.ListItem
|
||||
}
|
||||
|
||||
const props = defineProps<TUAProps>();
|
||||
|
||||
function showData () {
|
||||
console.log(JSON.stringify(props.modelValue, null, 2));
|
||||
}
|
||||
|
||||
function getNameCard () {
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="css">
|
||||
.tua-box {
|
||||
padding: 5px;
|
||||
width: 190px;
|
||||
height: 100%;
|
||||
background: rgb(255 255 255 / 10%);
|
||||
box-shadow: 0 0 10px rgb(0 0 0 / 40%);
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tua-top {
|
||||
width: 180px;
|
||||
height: 110px;
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-item {
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
background: rgb(0 0 0 / 20%);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.top-icon {
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.ti-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.ti-bg img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.ti-content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.ti-content img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.ti-level {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
padding: 5px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: rgb(0 0 0 / 50%);
|
||||
color: #faf7e8;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-top-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
font-family: Genshin,sans-serif;
|
||||
}
|
||||
|
||||
.top-text {
|
||||
width: 80px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #faf7e8;
|
||||
font-family: Genshin-Light,sans-serif;
|
||||
}
|
||||
|
||||
.top-love img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tua-bottom {
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.bottom-item {
|
||||
width: 32%;
|
||||
height: 100%;
|
||||
background: rgb(0 0 0 / 20%);
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,84 +0,0 @@
|
||||
<template>
|
||||
<div class="loading-div">
|
||||
<div class="loading-content">
|
||||
<div class="loading-title">
|
||||
{{ title }}
|
||||
<v-progress-circular v-show="!empty" indeterminate color="#f4d8a8" />
|
||||
</div>
|
||||
<div v-if="subtitle !== ''" class="loading-subtitle">
|
||||
{{ subtitle }}
|
||||
</div>
|
||||
<div v-if="!empty" class="loading-img">
|
||||
<img src="/source/UI/loading.webp" alt="loading">
|
||||
</div>
|
||||
<div v-else class="loading-img">
|
||||
<img src="/source/UI/empty.webp" alt="empty">
|
||||
</div>
|
||||
<div v-if="content !== ''" class="loading-text">
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
interface LoadingProps {
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
content?: string;
|
||||
empty?: boolean;
|
||||
position?: string;
|
||||
}
|
||||
|
||||
withDefaults(defineProps<LoadingProps>(), {
|
||||
title: "加载中",
|
||||
subtitle: "",
|
||||
content: "",
|
||||
empty: false,
|
||||
position: "absolute",
|
||||
});
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.loading-div {
|
||||
position: v-bind(position);
|
||||
display: flex;
|
||||
top: 25%;
|
||||
left: 25%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
background: rgb(57 59 64 / 50%);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
width: 100%;
|
||||
margin: 20px;
|
||||
display: flex;
|
||||
border: #f4d8a8 1px solid;
|
||||
border-radius: 20px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.loading-title {
|
||||
font-size: 2rem;
|
||||
font-family: Genshin, serif;
|
||||
font-weight: 600;
|
||||
color: #f4d8a8;
|
||||
}
|
||||
|
||||
.loading-subtitle {
|
||||
font-size: 1rem;
|
||||
font-family: Genshin-Light, serif;
|
||||
color: #f4d8a8;
|
||||
}
|
||||
|
||||
.loading-img {
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
191
src/components/overlay/to-calendar.vue
Normal file
191
src/components/overlay/to-calendar.vue
Normal file
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<TOverlay v-model="visible" hide :to-click="onCancel">
|
||||
<div class="toc-box">
|
||||
<div class="box-div">
|
||||
<div class="toc-top">
|
||||
<div class="toc-icon">
|
||||
<TMiniAvatar v-if="itemType=== 'character'" v-model="itemVal" size="100px" />
|
||||
<TMiniWeapon v-if="itemType=== 'weapon'" v-model="itemVal" size="100px" />
|
||||
</div>
|
||||
<div class="toc-material-grid">
|
||||
<TCalendarMaterial v-for="item in itemVal.materials" :item="item" />
|
||||
</div>
|
||||
</div>
|
||||
<img src="/source/UI/item-line.webp" alt="line" class="toc-line">
|
||||
<div class="toc-bottom">
|
||||
<div class="toc-src-box">
|
||||
<div class="toc-src-text">
|
||||
来源:
|
||||
</div>
|
||||
<img :src="`/icon/nation/${itemVal.source.area}.webp`" alt="icon">
|
||||
<div class="toc-src-text">
|
||||
{{ itemVal.source.area }} - {{ itemVal.source.name }}
|
||||
</div>
|
||||
</div>
|
||||
<v-btn variant="outlined" @click="toDetail(itemVal)">
|
||||
<template #append>
|
||||
<img src="../../assets/icons/arrow-right.svg" alt="right" class="toc-btn-img">
|
||||
</template>
|
||||
详情
|
||||
</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
<div class="close-div">
|
||||
<div class="close-btn" @click="onCancel">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TOverlay>
|
||||
<v-snackbar v-model="snackbar" :timeout="1500" color="error">
|
||||
该 {{ itemType === "weapon" ? "武器" : "角色" }} 暂无详情
|
||||
</v-snackbar>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
// vue
|
||||
import { computed, ref } from "vue";
|
||||
import TOverlay from "../main/t-overlay.vue";
|
||||
import TCalendarMaterial from "../mini/t-calendar-material.vue";
|
||||
import TMiniAvatar from "../mini/t-mini-avatar.vue";
|
||||
import TMiniWeapon from "../mini/t-mini-weapon.vue";
|
||||
// utils
|
||||
import { OBC_CONTENT_API } from "../../plugins/Mys/interface/utils";
|
||||
import { createTGWindow } from "../../utils/TGWindow";
|
||||
|
||||
interface TOCalendarProps {
|
||||
modelValue: boolean;
|
||||
dataType: string;
|
||||
dataVal: TGApp.App.Calendar.Item;
|
||||
}
|
||||
|
||||
interface TOCalendarEmits {
|
||||
(e: "update:modelValue", value: TGApp.App.Calendar.Item): void;
|
||||
(e: "cancel"): void;
|
||||
}
|
||||
|
||||
const emits = defineEmits<TOCalendarEmits>();
|
||||
const props = withDefaults(defineProps<TOCalendarProps>(), {
|
||||
modelValue: false,
|
||||
dataType: "",
|
||||
dataVal: {} as TGApp.App.Calendar.Item,
|
||||
});
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emits("update:modelValue", value),
|
||||
});
|
||||
const itemType = computed(() => props.dataType);
|
||||
const itemVal = computed(() => props.dataVal);
|
||||
const snackbar = ref(false);
|
||||
|
||||
const onCancel = () => {
|
||||
visible.value = false;
|
||||
emits("cancel");
|
||||
};
|
||||
|
||||
function toDetail (item: TGApp.App.Calendar.Item) {
|
||||
if (item.contentId === 0) {
|
||||
snackbar.value = true;
|
||||
return;
|
||||
}
|
||||
const url = OBC_CONTENT_API.replace("{content_id}", item.contentId.toString());
|
||||
createTGWindow(url, "素材详情", item.name, 1200, 800, true);
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
/* overlay 盒子 */
|
||||
.toc-box {
|
||||
width: 440px;
|
||||
height: 260px;
|
||||
}
|
||||
|
||||
.box-div {
|
||||
height: 200px;
|
||||
background: rgb(255 255 255 / 30%);
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
color: #faf7e8;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toc-top {
|
||||
height: 100px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.toc-icon {
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.toc-material-grid {
|
||||
margin-left: 10px;
|
||||
font-family: Genshin, serif;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-gap: 10px;
|
||||
}
|
||||
|
||||
.toc-line {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.toc-bottom {
|
||||
background: rgb(0 0 0 / 30%);
|
||||
padding: 3px 10px;
|
||||
width: 420px;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toc-bottom img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.toc-src-box {
|
||||
width: 300px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toc-src-text {
|
||||
height: 50px;
|
||||
font-size: 20px;
|
||||
font-family: Genshin-Light, serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toc-btn-img {
|
||||
width: 18px !important;
|
||||
height: 18px !important;
|
||||
}
|
||||
|
||||
.close-div {
|
||||
height: 60px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
border-radius: 50%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: rgb(255 255 255 / 30%);
|
||||
color: #faf7e8;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-overlay v-model="visible">
|
||||
<TOverlay v-model="visible" :to-click="onCancel" :blur-val="'3px'" hide>
|
||||
<div class="confirm-div">
|
||||
<div class="confirm-box">
|
||||
<div class="confirm-title">
|
||||
@@ -27,14 +27,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</v-overlay>
|
||||
</TOverlay>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { computed } from "vue";
|
||||
import { computed, inject } from "vue";
|
||||
import TOverlay from "../main/t-overlay.vue";
|
||||
|
||||
interface TConfirmProps {
|
||||
const test = inject("hide");
|
||||
|
||||
interface TOConfirmProps {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
isInput?: boolean;
|
||||
@@ -45,16 +48,16 @@ interface TConfirmProps {
|
||||
modelInput: string;
|
||||
}
|
||||
|
||||
interface TConfirmEmits {
|
||||
(e: "update:show", v: boolean): void;
|
||||
interface TOConfirmEmits {
|
||||
(e: "update:modelValue", v: boolean): void;
|
||||
(e: "update:modelInput", v: string): void;
|
||||
(e: "confirm"): void;
|
||||
(e: "cancel"): void;
|
||||
}
|
||||
|
||||
const emits = defineEmits<TConfirmEmits>();
|
||||
const props = withDefaults(defineProps<TConfirmProps>(), {
|
||||
const emits = defineEmits<TOConfirmEmits>();
|
||||
const props = withDefaults(defineProps<TOConfirmProps>(), {
|
||||
modelValue: false,
|
||||
title: "确认",
|
||||
subtitle: "",
|
||||
isInput: false,
|
||||
106
src/components/overlay/to-loading.vue
Normal file
106
src/components/overlay/to-loading.vue
Normal file
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<TOverlay v-model="show" :blur-val="'5px'">
|
||||
<div class="tol-div">
|
||||
<div class="tol-box">
|
||||
<div class="tol-title">
|
||||
<slot name="title">
|
||||
{{ title }}
|
||||
</slot>
|
||||
<v-progress-circular v-show="!empty" indeterminate color="#f4d8a8" />
|
||||
</div>
|
||||
<div v-if="subtitle" class="tol-subtitle">
|
||||
<slot name="subtitle">
|
||||
{{ subtitle }}
|
||||
</slot>
|
||||
</div>
|
||||
<div class="tol-img">
|
||||
<slot name="img">
|
||||
<img v-if="!empty" src="/source/UI/loading.webp" alt="loading">
|
||||
<img v-else src="/source/UI/empty.webp" alt="empty">
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TOverlay>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { ref, watch } from "vue";
|
||||
import TOverlay from "../main/t-overlay.vue";
|
||||
|
||||
interface LoadingProps {
|
||||
modelValue: boolean;
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
empty?: boolean;
|
||||
}
|
||||
|
||||
const show = ref(true);
|
||||
|
||||
const props = withDefaults(defineProps<LoadingProps>(), {
|
||||
modelValue: true,
|
||||
title: "加载中",
|
||||
empty: false,
|
||||
});
|
||||
|
||||
watch(() => props.modelValue, (v) => {
|
||||
show.value = v;
|
||||
});
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tol-div {
|
||||
display: flex;
|
||||
min-width: 800px;
|
||||
min-height: 300px;
|
||||
padding: 15px;
|
||||
background: rgb(255 255 255 / 5%);
|
||||
box-shadow: 0 0 10px rgb(0 0 0 / 50%);
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.tol-box {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
box-sizing: content-box;
|
||||
border: #f4d8a8 1px solid;
|
||||
color: #f4d8a8;
|
||||
border-radius: 5px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tol-title {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 2rem;
|
||||
font-family: Genshin, serif;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tol-subtitle {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 1rem;
|
||||
height: 25px;
|
||||
font-family: Genshin-Light, serif;
|
||||
}
|
||||
|
||||
.tol-img {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tol-img:deep(img) {
|
||||
max-height: 200px;
|
||||
max-width: 100%;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -22,10 +22,8 @@
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-app-bar>
|
||||
<div v-show="loading">
|
||||
<TLoading :title="loadingTitle" />
|
||||
</div>
|
||||
<div v-show="!loading" class="wrap">
|
||||
<TOLoading v-model="loading" :title="loadingTitle" />
|
||||
<div class="wrap">
|
||||
<!-- 左侧菜单 -->
|
||||
<div class="left-wrap">
|
||||
<v-list v-for="series in seriesList" :key="series.id" class="card-left" @click="selectSeries(series.id)">
|
||||
@@ -110,7 +108,7 @@
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { onMounted, ref, onBeforeMount, computed } from "vue";
|
||||
import TLoading from "../components/overlay/t-loading.vue";
|
||||
import TOLoading from "../components/overlay/to-loading.vue";
|
||||
// tauri
|
||||
import { dialog, fs } from "@tauri-apps/api";
|
||||
// Store
|
||||
@@ -321,27 +319,23 @@ async function exportJson () {
|
||||
/* 内容区域 */
|
||||
.wrap {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: auto;
|
||||
max-height: 90vh;
|
||||
font-family: Genshin-Light, serif;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* 左侧系列 */
|
||||
.left-wrap {
|
||||
float: left;
|
||||
width: 25%;
|
||||
max-height: calc(100vh - 100px);
|
||||
overflow: auto;
|
||||
width: 400px;
|
||||
height: calc(100vh - 100px);
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 右侧成就 */
|
||||
.right-wrap {
|
||||
position: relative;
|
||||
float: right;
|
||||
width: 75%;
|
||||
max-height: calc(100vh - 100px);
|
||||
overflow: auto;
|
||||
width: calc(100% - 410px);
|
||||
height: calc(100vh - 100px);
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.list-empty {
|
||||
|
||||
@@ -1,101 +1,97 @@
|
||||
<template>
|
||||
<div v-if="loading">
|
||||
<TLoading :title="loadingTitle" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<v-tabs v-model="tab" align-tabs="start" class="anno-tab">
|
||||
<v-tab value="activity">
|
||||
活动公告
|
||||
</v-tab>
|
||||
<v-tab value="game">
|
||||
游戏公告
|
||||
</v-tab>
|
||||
<v-spacer />
|
||||
<v-btn class="switch-btn" @click="switchNews">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-bullhorn</v-icon>
|
||||
</template>
|
||||
切换米游社咨讯
|
||||
</v-btn>
|
||||
</v-tabs>
|
||||
<v-window v-model="tab">
|
||||
<v-window-item value="activity">
|
||||
<div class="anno-grid">
|
||||
<v-card v-for="item in annoCards.activity" :key="item.id" class="anno-card" width="340">
|
||||
<div class="anno-cover" @click="toPost(item)">
|
||||
<img :src="item.banner" 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="anno-btn" @click="toPost(item)">
|
||||
<template #prepend>
|
||||
<img :src="item.tagIcon || '../assets/icons/arrow-right.svg'" alt="right">
|
||||
</template>
|
||||
查看
|
||||
</v-btn>
|
||||
<v-card-subtitle v-show="!appStore.devMode">
|
||||
<v-icon>mdi-calendar</v-icon>
|
||||
{{ item.startTime.split(" ")[0] }} -
|
||||
{{ item.endTime.split(" ")[0] }}
|
||||
</v-card-subtitle>
|
||||
<v-card-subtitle v-show="appStore.devMode">
|
||||
id: {{ item.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>
|
||||
查看数据
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-window-item>
|
||||
<v-window-item value="game">
|
||||
<div class="anno-grid">
|
||||
<v-card v-for="item in annoCards.game" :key="item.id" class="anno-card" width="340">
|
||||
<div class="anno-cover" @click="toPost(item)">
|
||||
<img :src="item.banner" 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="anno-btn" @click="toPost(item)">
|
||||
<template #prepend>
|
||||
<img :src="item.tagIcon || '../assets/icons/arrow-right.svg'" alt="right">
|
||||
</template>
|
||||
查看
|
||||
</v-btn>
|
||||
<v-card-subtitle v-show="!appStore.devMode">
|
||||
<v-icon>mdi-calendar</v-icon>
|
||||
{{ item.startTime.split(" ")[0] }} -
|
||||
{{ item.endTime.split(" ")[0] }}
|
||||
</v-card-subtitle>
|
||||
<v-card-subtitle v-show="appStore.devMode">
|
||||
id: {{ item.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>
|
||||
查看数据
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
</div>
|
||||
<TLoading v-model="loading" :title="loadingTitle" />
|
||||
<v-tabs v-model="tab" align-tabs="start" class="anno-tab">
|
||||
<v-tab value="activity">
|
||||
活动公告
|
||||
</v-tab>
|
||||
<v-tab value="game">
|
||||
游戏公告
|
||||
</v-tab>
|
||||
<v-spacer />
|
||||
<v-btn class="switch-btn" @click="switchNews">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-bullhorn</v-icon>
|
||||
</template>
|
||||
切换米游社咨讯
|
||||
</v-btn>
|
||||
</v-tabs>
|
||||
<v-window v-model="tab">
|
||||
<v-window-item value="activity">
|
||||
<div class="anno-grid">
|
||||
<v-card v-for="item in annoCards.activity" :key="item.id" class="anno-card" width="340">
|
||||
<div class="anno-cover" @click="toPost(item)">
|
||||
<img :src="item.banner" 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="anno-btn" @click="toPost(item)">
|
||||
<template #prepend>
|
||||
<img :src="item.tagIcon || '../assets/icons/arrow-right.svg'" alt="right">
|
||||
</template>
|
||||
查看
|
||||
</v-btn>
|
||||
<v-card-subtitle v-show="!appStore.devMode">
|
||||
<v-icon>mdi-calendar</v-icon>
|
||||
{{ item.startTime.split(" ")[0] }} -
|
||||
{{ item.endTime.split(" ")[0] }}
|
||||
</v-card-subtitle>
|
||||
<v-card-subtitle v-show="appStore.devMode">
|
||||
id: {{ item.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>
|
||||
查看数据
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-window-item>
|
||||
<v-window-item value="game">
|
||||
<div class="anno-grid">
|
||||
<v-card v-for="item in annoCards.game" :key="item.id" class="anno-card" width="340">
|
||||
<div class="anno-cover" @click="toPost(item)">
|
||||
<img :src="item.banner" 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="anno-btn" @click="toPost(item)">
|
||||
<template #prepend>
|
||||
<img :src="item.tagIcon || '../assets/icons/arrow-right.svg'" alt="right">
|
||||
</template>
|
||||
查看
|
||||
</v-btn>
|
||||
<v-card-subtitle v-show="!appStore.devMode">
|
||||
<v-icon>mdi-calendar</v-icon>
|
||||
{{ item.startTime.split(" ")[0] }} -
|
||||
{{ item.endTime.split(" ")[0] }}
|
||||
</v-card-subtitle>
|
||||
<v-card-subtitle v-show="appStore.devMode">
|
||||
id: {{ item.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>
|
||||
查看数据
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { onMounted, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import TLoading from "../components/overlay/t-loading.vue";
|
||||
import TLoading from "../components/overlay/to-loading.vue";
|
||||
// store
|
||||
import { useAppStore } from "../store/modules/app";
|
||||
// utils
|
||||
|
||||
@@ -1,183 +1,179 @@
|
||||
<template>
|
||||
<div v-if="loading">
|
||||
<TLoading :title="loadingTitle" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<v-list class="config-list">
|
||||
<v-list-subheader inset class="config-header">
|
||||
应用信息
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item title="Tauri 版本" @click="toOuter('https://next--tauri.netlify.app/')">
|
||||
<template #prepend>
|
||||
<img class="config-icon" src="/platforms/tauri.webp" alt="Tauri">
|
||||
</template>
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ versionTauri }}</v-list-item-subtitle>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<img class="config-icon" src="/icon.webp" alt="App">
|
||||
</template>
|
||||
<v-list-item-title>
|
||||
应用版本
|
||||
<v-btn
|
||||
class="card-btn" size="small"
|
||||
@click="toOuter('https://github.com/BTMuli/Tauri.Genshin/releases/latest')"
|
||||
>
|
||||
Alpha
|
||||
</v-btn>
|
||||
</v-list-item-title>
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ versionApp }}.{{ buildTime }}</v-list-item-subtitle>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="成就版本">
|
||||
<template #prepend>
|
||||
<img class="config-icon" src="../assets/icons/achievements.svg" alt="Achievements">
|
||||
</template>
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ achievementsStore.lastVersion }}</v-list-item-subtitle>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="登录信息">
|
||||
<v-list-item-subtitle v-show="userInfo.nickname!=='未登录'">
|
||||
{{ userInfo.nickname }} uid:{{ userInfo.uid }}
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-subtitle v-show="userInfo.nickname==='未登录'">
|
||||
未登录,请输入 Cookie 登录!
|
||||
</v-list-item-subtitle>
|
||||
<template #prepend>
|
||||
<img class="config-icon" :src="userInfo.avatar" alt="Login">
|
||||
</template>
|
||||
<template #append>
|
||||
<v-btn class="card-btn" @click="tryConfirm('refreshUser')">
|
||||
<template #prepend>
|
||||
<img src="../assets/icons/circle-check.svg" alt="check">
|
||||
刷新数据
|
||||
</template>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-subheader inset class="config-header">
|
||||
系统信息
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item title="系统平台">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-desktop-classic</v-icon>
|
||||
</template>
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ osPlatform }}</v-list-item-subtitle>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="系统版本">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-desktop-classic</v-icon>
|
||||
</template>
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ osVersion }}</v-list-item-subtitle>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="数据库更新时间" prepend-icon="mdi-database">
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ dbInfo.find(item => item.key === "dataUpdated")?.value }}</v-list-item-subtitle>
|
||||
</template>
|
||||
<v-list-item-subtitle>更新于 {{ dbInfo.find(item => item.key === "dataUpdated")?.updated }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-item title="数据库版本" prepend-icon="mdi-database">
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ dbInfo.find(item => item.key === "appVersion")?.value }}</v-list-item-subtitle>
|
||||
</template>
|
||||
<v-list-item-subtitle>更新于 {{ dbInfo.find(item => item.key === "appVersion")?.updated }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-subheader inset class="config-header">
|
||||
设置
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<v-icon>mdi-view-dashboard</v-icon>
|
||||
</template>
|
||||
<v-select v-model="showHome" :items="homeStore.getShowItems()" label="首页显示组件" multiple chips />
|
||||
<template #append>
|
||||
<v-btn class="card-btn" @click="submitHome">
|
||||
<template #prepend>
|
||||
<img src="../assets/icons/circle-check.svg" alt="check">
|
||||
确定
|
||||
</template>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item prepend-icon="mdi-content-save" title="数据备份" @click="tryConfirm('backup')" />
|
||||
<v-list-item prepend-icon="mdi-content-save" title="数据恢复" @click="tryConfirm('restore')" />
|
||||
<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-cog" title="恢复默认设置" @click="tryConfirm('delApp')" />
|
||||
<v-list-subheader inset class="config-header">
|
||||
调试
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item v-if="appStore.devEnv" title="调试模式" subtitle="开启后将显示调试信息">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-bug</v-icon>
|
||||
</template>
|
||||
<template #append>
|
||||
<v-switch
|
||||
v-model="appStore.devMode" :label="appStore.devMode ? '开启' : '关闭'" inset color="#FAC51E"
|
||||
@click="submitDevMode"
|
||||
/>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<v-icon>mdi-cookie</v-icon>
|
||||
</template>
|
||||
<template #title>
|
||||
<span style="cursor: pointer" @click="tryConfirm('inputCookie')">手动输入 Cookie</span>
|
||||
</template>
|
||||
<template #append>
|
||||
<v-icon style="cursor: pointer" @click="toOuter('https://github.com/BTMuli/Tauri.Genshin/issues/18')">
|
||||
mdi-help-circle-outline
|
||||
</v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="重置数据库" prepend-icon="mdi-delete" @click="tryConfirm('resetDB')" />
|
||||
<v-list-item title="检测 SQLite 数据库完整性" prepend-icon="mdi-database-check" @click="tryConfirm('checkDB')" />
|
||||
<v-list-subheader inset class="config-header">
|
||||
路径
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item prepend-icon="mdi-database">
|
||||
<v-list-item-title>本地数据库路径</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ appStore.dataPath.dbDataPath }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-item prepend-icon="mdi-folder">
|
||||
<v-list-item-title>本地临时数据路径</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ appStore.dataPath.tempDataDir }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-item prepend-icon="mdi-folder">
|
||||
<v-list-item-title>本地用户数据路径</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ appStore.dataPath.userDataDir }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<!-- 弹窗提示条 -->
|
||||
<v-snackbar v-model="snackbar" timeout="1500" :color="snackbarColor">
|
||||
{{ snackbarText }}
|
||||
</v-snackbar>
|
||||
<!-- 确认弹窗 -->
|
||||
<TConfirm v-model:model-value="confirmShow" v-model:model-input="confirmInput" :title="confirmText" :subtitle="confirmSub" :is-input="isConfirmInput" @confirm="doConfirm(confirmOper)" />
|
||||
</div>
|
||||
<TOLoading v-model="loading" :title="loadingTitle" />
|
||||
<v-list class="config-list">
|
||||
<v-list-subheader inset class="config-header">
|
||||
应用信息
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item title="Tauri 版本" @click="toOuter('https://next--tauri.netlify.app/')">
|
||||
<template #prepend>
|
||||
<img class="config-icon" src="/platforms/tauri.webp" alt="Tauri">
|
||||
</template>
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ versionTauri }}</v-list-item-subtitle>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<img class="config-icon" src="/icon.webp" alt="App">
|
||||
</template>
|
||||
<v-list-item-title>
|
||||
应用版本
|
||||
<v-btn
|
||||
class="card-btn" size="small"
|
||||
@click="toOuter('https://github.com/BTMuli/Tauri.Genshin/releases/latest')"
|
||||
>
|
||||
Alpha
|
||||
</v-btn>
|
||||
</v-list-item-title>
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ versionApp }}.{{ buildTime }}</v-list-item-subtitle>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="成就版本">
|
||||
<template #prepend>
|
||||
<img class="config-icon" src="../assets/icons/achievements.svg" alt="Achievements">
|
||||
</template>
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ achievementsStore.lastVersion }}</v-list-item-subtitle>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="登录信息">
|
||||
<v-list-item-subtitle v-show="userInfo.nickname!=='未登录'">
|
||||
{{ userInfo.nickname }} uid:{{ userInfo.uid }}
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-subtitle v-show="userInfo.nickname==='未登录'">
|
||||
未登录,请输入 Cookie 登录!
|
||||
</v-list-item-subtitle>
|
||||
<template #prepend>
|
||||
<img class="config-icon" :src="userInfo.avatar" alt="Login">
|
||||
</template>
|
||||
<template #append>
|
||||
<v-btn class="card-btn" @click="tryConfirm('refreshUser')">
|
||||
<template #prepend>
|
||||
<img src="../assets/icons/circle-check.svg" alt="check">
|
||||
刷新数据
|
||||
</template>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-subheader inset class="config-header">
|
||||
系统信息
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item title="系统平台">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-desktop-classic</v-icon>
|
||||
</template>
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ osPlatform }}</v-list-item-subtitle>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="系统版本">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-desktop-classic</v-icon>
|
||||
</template>
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ osVersion }}</v-list-item-subtitle>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="数据库更新时间" prepend-icon="mdi-database">
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ dbInfo.find(item => item.key === "dataUpdated")?.value }}</v-list-item-subtitle>
|
||||
</template>
|
||||
<v-list-item-subtitle>更新于 {{ dbInfo.find(item => item.key === "dataUpdated")?.updated }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-item title="数据库版本" prepend-icon="mdi-database">
|
||||
<template #append>
|
||||
<v-list-item-subtitle>{{ dbInfo.find(item => item.key === "appVersion")?.value }}</v-list-item-subtitle>
|
||||
</template>
|
||||
<v-list-item-subtitle>更新于 {{ dbInfo.find(item => item.key === "appVersion")?.updated }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-subheader inset class="config-header">
|
||||
设置
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<v-icon>mdi-view-dashboard</v-icon>
|
||||
</template>
|
||||
<v-select v-model="showHome" :items="homeStore.getShowItems()" label="首页显示组件" multiple chips />
|
||||
<template #append>
|
||||
<v-btn class="card-btn" @click="submitHome">
|
||||
<template #prepend>
|
||||
<img src="../assets/icons/circle-check.svg" alt="check">
|
||||
确定
|
||||
</template>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item prepend-icon="mdi-content-save" title="数据备份" @click="tryConfirm('backup')" />
|
||||
<v-list-item prepend-icon="mdi-content-save" title="数据恢复" @click="tryConfirm('restore')" />
|
||||
<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-cog" title="恢复默认设置" @click="tryConfirm('delApp')" />
|
||||
<v-list-subheader inset class="config-header">
|
||||
调试
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item v-if="appStore.devEnv" title="调试模式" subtitle="开启后将显示调试信息">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-bug</v-icon>
|
||||
</template>
|
||||
<template #append>
|
||||
<v-switch
|
||||
v-model="appStore.devMode" :label="appStore.devMode ? '开启' : '关闭'" inset color="#FAC51E"
|
||||
@click="submitDevMode"
|
||||
/>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<v-icon>mdi-cookie</v-icon>
|
||||
</template>
|
||||
<template #title>
|
||||
<span style="cursor: pointer" @click="tryConfirm('inputCookie')">手动输入 Cookie</span>
|
||||
</template>
|
||||
<template #append>
|
||||
<v-icon style="cursor: pointer" @click="toOuter('https://github.com/BTMuli/Tauri.Genshin/issues/18')">
|
||||
mdi-help-circle-outline
|
||||
</v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="重置数据库" prepend-icon="mdi-delete" @click="tryConfirm('resetDB')" />
|
||||
<v-list-item title="检测 SQLite 数据库完整性" prepend-icon="mdi-database-check" @click="tryConfirm('checkDB')" />
|
||||
<v-list-subheader inset class="config-header">
|
||||
路径
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item prepend-icon="mdi-database">
|
||||
<v-list-item-title>本地数据库路径</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ appStore.dataPath.dbDataPath }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-item prepend-icon="mdi-folder">
|
||||
<v-list-item-title>本地临时数据路径</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ appStore.dataPath.tempDataDir }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-item prepend-icon="mdi-folder">
|
||||
<v-list-item-title>本地用户数据路径</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ appStore.dataPath.userDataDir }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<!-- 弹窗提示条 -->
|
||||
<v-snackbar v-model="snackbar" timeout="1500" :color="snackbarColor">
|
||||
{{ snackbarText }}
|
||||
</v-snackbar>
|
||||
<!-- 确认弹窗 -->
|
||||
<TOConfirm v-model:model-value="confirmShow" v-model:model-input="confirmInput" :title="confirmText" :subtitle="confirmSub" :is-input="isConfirmInput" @confirm="doConfirm(confirmOper)" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import TLoading from "../components/overlay/t-loading.vue";
|
||||
import TConfirm from "../components/overlay/t-confirm.vue";
|
||||
import TOLoading from "../components/overlay/to-loading.vue";
|
||||
import TOConfirm from "../components/overlay/to-confirm.vue";
|
||||
// tauri
|
||||
import { fs, app, os } from "@tauri-apps/api";
|
||||
import { app, fs, os } from "@tauri-apps/api";
|
||||
// store
|
||||
import { useAppStore } from "../store/modules/app";
|
||||
import { useHomeStore } from "../store/modules/home";
|
||||
@@ -319,6 +315,7 @@ function tryConfirm (oper: string) {
|
||||
|
||||
// transfer confirm oper
|
||||
async function doConfirm (oper: string) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
switch (oper) {
|
||||
case "backup":
|
||||
await backupData();
|
||||
@@ -557,6 +554,7 @@ async function checkDB () {
|
||||
loadingTitle.value = "正在检查数据库表单完整性...";
|
||||
loading.value = true;
|
||||
const res = await TGSqlite.check();
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
if (!res) {
|
||||
confirmOper.value = "resetDB";
|
||||
confirmText.value = "数据库表单不完整,是否重置数据库?";
|
||||
@@ -603,9 +601,11 @@ async function resetDB () {
|
||||
|
||||
// 更新 SQLite 数据库
|
||||
async function updateDB () {
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
loadingTitle.value = "正在更新数据库...";
|
||||
loading.value = true;
|
||||
await TGSqlite.update();
|
||||
achievementsStore.lastVersion = await TGSqlite.getLatestAchievementVersion();
|
||||
loading.value = false;
|
||||
snackbarText.value = "数据库已是最新!";
|
||||
snackbarColor.value = "success";
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<TLoading v-if="loading" :title="loadingTitle" :subtitle="loadingSubtitle" />
|
||||
<component :is="item" v-for="item in components" v-show="!loading" :key="item" :ref="setItemRef" />
|
||||
<TOLoading v-model="loading" :title="loadingTitle" :subtitle="loadingSubtitle" />
|
||||
<component :is="item" v-for="item in components" :key="item" :ref="setItemRef" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { ref, markRaw, onMounted, onUnmounted, onUpdated } from "vue";
|
||||
import TLoading from "../components/overlay/t-loading.vue";
|
||||
import { markRaw, onMounted, onUnmounted, onUpdated, ref } from "vue";
|
||||
import TOLoading from "../components/overlay/to-loading.vue";
|
||||
import TPool from "../components/main/t-pool.vue";
|
||||
import TPosition from "../components/main/t-position.vue";
|
||||
import TCalendar from "../components/main/t-calendar.vue";
|
||||
@@ -45,6 +45,14 @@ function readLoading (): void {
|
||||
|
||||
onMounted(async () => {
|
||||
loadingTitle.value = "正在加载首页";
|
||||
loading.value = true;
|
||||
// 获取当前环境
|
||||
const timeGet = getBuildTime();
|
||||
appStore.devEnv = timeGet.startsWith("dev");
|
||||
if (!appStore.devEnv && appStore.devMode) {
|
||||
appStore.devMode = false;
|
||||
}
|
||||
appStore.buildTime = getBuildTime();
|
||||
const showItems = homeStore.getShowValue();
|
||||
await Promise.allSettled(
|
||||
showItems.map((item) => {
|
||||
@@ -61,13 +69,6 @@ onMounted(async () => {
|
||||
}),
|
||||
);
|
||||
timer.value = setInterval(readLoading, 100);
|
||||
// 获取当前环境
|
||||
const timeGet = getBuildTime();
|
||||
appStore.devEnv = timeGet.startsWith("dev");
|
||||
if (!appStore.devEnv && appStore.devMode) {
|
||||
appStore.devMode = false;
|
||||
}
|
||||
appStore.buildTime = getBuildTime();
|
||||
});
|
||||
|
||||
function setItemRef (item: any) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
import { onMounted, ref } from "vue";
|
||||
// store
|
||||
import { useUserStore } from "../../store/modules/user";
|
||||
// request
|
||||
// utils
|
||||
import TGRequest from "../../web/request/TGRequest";
|
||||
import TGSqlite from "../../utils/TGSqlite";
|
||||
|
||||
|
||||
@@ -1,49 +1,100 @@
|
||||
<template>
|
||||
<h1>角色数据获取、展示、详情</h1>
|
||||
<v-btn @click="getRoleList">
|
||||
获取角色列表
|
||||
</v-btn>
|
||||
{{ roleList }}
|
||||
<ToLoading v-model="loading" :title="loadingTitle" />
|
||||
<div class="uc-top">
|
||||
<div class="uc-top-title">
|
||||
我的角色
|
||||
</div>
|
||||
<v-btn variant="outlined" @click="refresh">
|
||||
更新数据
|
||||
</v-btn>
|
||||
</div>
|
||||
<div class="uc-grid">
|
||||
<TUserAvatar v-for="avatar in roleList" :model-value="avatar" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { onMounted, ref } from "vue";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import ToLoading from "../../components/overlay/to-loading.vue";
|
||||
import TUserAvatar from "../../components/mini/t-user-avatar.vue";
|
||||
// tauri
|
||||
import { fs } from "@tauri-apps/api";
|
||||
// store
|
||||
import { useAppStore } from "../../store/modules/app";
|
||||
import { useUserStore } from "../../store/modules/user";
|
||||
// request
|
||||
import TGRequest from "../../web/request/TGRequest";
|
||||
// utils
|
||||
import TGSqlite from "../../utils/TGSqlite";
|
||||
|
||||
// store
|
||||
const appStore = useAppStore();
|
||||
const userStore = useUserStore();
|
||||
const roleList = ref([]);
|
||||
|
||||
// loading
|
||||
const loading = ref(false);
|
||||
const loadingTitle = ref("");
|
||||
|
||||
// data
|
||||
const characterCookie = ref({
|
||||
cookie_token: "",
|
||||
account_id: "",
|
||||
ltoken: "",
|
||||
ltuid: "",
|
||||
});
|
||||
const roleList = ref([] as TGApp.Game.Character.ListItem[]);
|
||||
const characterCookie = ref({} as TGApp.BBS.Constant.CookieGroup4);
|
||||
const user = ref({} as TGApp.Sqlite.Account.Game);
|
||||
const filePath = computed(() => `${appStore.dataPath.userDataDir}/roleList.json`);
|
||||
|
||||
onMounted(async () => {
|
||||
loadingTitle.value = "正在获取角色数据";
|
||||
loading.value = true;
|
||||
const curUser = await TGSqlite.getCurAccount();
|
||||
if (curUser) {
|
||||
user.value = curUser;
|
||||
}
|
||||
characterCookie.value = {
|
||||
cookie_token: userStore.getCookieItem("cookie_token"),
|
||||
account_id: userStore.getCookieItem("account_id"),
|
||||
ltoken: userStore.getCookieItem("ltoken"),
|
||||
ltuid: userStore.getCookieItem("ltuid"),
|
||||
};
|
||||
characterCookie.value = userStore.getCookieGroup4();
|
||||
const fileGet = await fs.readTextFile(filePath.value);
|
||||
if (fileGet) {
|
||||
roleList.value = JSON.parse(fileGet);
|
||||
}
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
async function getRoleList () {
|
||||
async function refresh () {
|
||||
loadingTitle.value = "正在获取角色数据";
|
||||
loading.value = true;
|
||||
const res = await TGRequest.User.byLToken.getRoleList(characterCookie.value, user.value);
|
||||
console.log(res);
|
||||
if (Array.isArray(res)) {
|
||||
loadingTitle.value = "正在保存角色数据";
|
||||
await fs.writeTextFile({
|
||||
path: filePath.value,
|
||||
contents: JSON.stringify(res),
|
||||
});
|
||||
loadingTitle.value = "正在更新角色数据";
|
||||
roleList.value = res;
|
||||
}
|
||||
loading.value = false;
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.uc-top {
|
||||
background: rgb(0 0 0 / 20%);
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: Genshin, sans-serif;
|
||||
font-size: 20px;
|
||||
color: #faf7e8;
|
||||
}
|
||||
|
||||
.uc-top-title {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.uc-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
||||
grid-gap: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<template>
|
||||
<h1>实时便笺、数据总览、世界探索、尘歌壶、札记跳转</h1>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
45
src/pages/User/Record.vue
Normal file
45
src/pages/User/Record.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<h1>实时便笺、数据总览、世界探索、尘歌壶、札记跳转</h1>
|
||||
<!-- todo Invalid uid -->
|
||||
<v-btn @click="getInfo1">
|
||||
获取用户游戏数据1
|
||||
</v-btn>
|
||||
<v-btn @click="getInfo2">
|
||||
获取用户游戏数据2
|
||||
</v-btn>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { onMounted, ref } from "vue";
|
||||
// store
|
||||
import { useUserStore } from "../../store/modules/user";
|
||||
// utils
|
||||
import TGRequest from "../../web/request/TGRequest";
|
||||
import TGSqlite from "../../utils/TGSqlite";
|
||||
|
||||
// store
|
||||
const userStore = useUserStore();
|
||||
|
||||
// data
|
||||
const user = ref({} as TGApp.Sqlite.Account.Game);
|
||||
|
||||
onMounted(async () => {
|
||||
const curUser = await TGSqlite.getCurAccount();
|
||||
if (curUser) {
|
||||
user.value = curUser;
|
||||
}
|
||||
console.log(user.value);
|
||||
});
|
||||
|
||||
async function getInfo1 () {
|
||||
const ck = userStore.getCookieGroup2() as Record<string, string>;
|
||||
const res = await TGRequest.User.getRecord(ck, user.value);
|
||||
}
|
||||
|
||||
async function getInfo2 () {
|
||||
const ck = userStore.getCookieGroup3() as Record<string, string>;
|
||||
const res = await TGRequest.User.getRecord(ck, user.value);
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
@@ -1,104 +1,112 @@
|
||||
<template>
|
||||
<div v-if="loading">
|
||||
<TLoading title="正在加载卡牌列表" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<v-tabs v-model="tab" align-tabs="start" class="cards-tab">
|
||||
<div v-show="!doSearch">
|
||||
<v-tab value="character">
|
||||
角色牌
|
||||
</v-tab>
|
||||
<v-tab value="action">
|
||||
行动牌
|
||||
</v-tab>
|
||||
<v-tab value="monster">
|
||||
魔物牌
|
||||
</v-tab>
|
||||
</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.contentId" class="card-cls" @click="toOuter(item.name, item.contentId)">
|
||||
<div class="card-border">
|
||||
<img src="/WIKI/GCG/bg/normal.webp" alt="border">
|
||||
</div>
|
||||
<div class="card-cover">
|
||||
<img :src="item.icon" 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.contentId" class="card-cls" @click="toOuter(item.name, item.contentId)">
|
||||
<div class="card-border">
|
||||
<img src="/WIKI/GCG/bg/normal.webp" alt="border">
|
||||
</div>
|
||||
<div class="card-cover">
|
||||
<img :src="item.icon" 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.contentId" class="card-cls" @click="toOuter(item.name, item.contentId)">
|
||||
<div class="card-border">
|
||||
<img src="/WIKI/GCG/bg/normal.webp" alt="border">
|
||||
</div>
|
||||
<div class="card-cover">
|
||||
<img :src="item.icon" alt="cover">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span>{{ item.name }}</span>
|
||||
</div>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
<TOLoading v-model="loading" title="正在加载卡牌列表" />
|
||||
<v-tabs v-model="tab" align-tabs="start" class="cards-tab">
|
||||
<div v-show="!doSearch">
|
||||
<v-tab value="character">
|
||||
角色牌
|
||||
</v-tab>
|
||||
<v-tab value="action">
|
||||
行动牌
|
||||
</v-tab>
|
||||
<v-tab value="monster">
|
||||
魔物牌
|
||||
</v-tab>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="cards-grid">
|
||||
<div v-for="item in CardsInfoS" :key="item.contentId" class="card-cls" @click="toOuter(item.name, item.contentId)">
|
||||
<div class="card-border">
|
||||
<img src="/WIKI/GCG/bg/normal.webp" alt="border">
|
||||
</div>
|
||||
<div class="card-cover">
|
||||
<img :src="item.icon" alt="cover">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span>{{ item.name }}</span>
|
||||
</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-show="!doSearch">
|
||||
<v-window v-model="tab">
|
||||
<v-window-item value="character">
|
||||
<div class="cards-grid">
|
||||
<v-card
|
||||
v-for="item in CardsInfoC" :key="item.contentId" class="card-cls"
|
||||
@click="toOuter(item.name, item.contentId)"
|
||||
>
|
||||
<div class="card-border">
|
||||
<img src="/WIKI/GCG/bg/normal.webp" alt="border">
|
||||
</div>
|
||||
<div class="card-cover">
|
||||
<img :src="item.icon" alt="cover">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span>{{ item.name }}</span>
|
||||
</div>
|
||||
</v-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<v-snackbar v-model="snackbar" timeout="1500" color="error">
|
||||
未找到相关卡牌
|
||||
</v-snackbar>
|
||||
</v-window-item>
|
||||
<v-window-item value="action">
|
||||
<div class="cards-grid">
|
||||
<v-card
|
||||
v-for="item in CardsInfoA" :key="item.contentId" class="card-cls"
|
||||
@click="toOuter(item.name, item.contentId)"
|
||||
>
|
||||
<div class="card-border">
|
||||
<img src="/WIKI/GCG/bg/normal.webp" alt="border">
|
||||
</div>
|
||||
<div class="card-cover">
|
||||
<img :src="item.icon" 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.contentId" class="card-cls"
|
||||
@click="toOuter(item.name, item.contentId)"
|
||||
>
|
||||
<div class="card-border">
|
||||
<img src="/WIKI/GCG/bg/normal.webp" alt="border">
|
||||
</div>
|
||||
<div class="card-cover">
|
||||
<img :src="item.icon" alt="cover">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span>{{ item.name }}</span>
|
||||
</div>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
</div>
|
||||
<div v-show="doSearch">
|
||||
<div class="cards-grid">
|
||||
<v-card
|
||||
v-for="item in CardsInfoS" :key="item.contentId" class="card-cls"
|
||||
@click="toOuter(item.name, item.contentId)"
|
||||
>
|
||||
<div class="card-border">
|
||||
<img src="/WIKI/GCG/bg/special.webp" alt="border">
|
||||
</div>
|
||||
<div class="card-cover">
|
||||
<img :src="item.icon" alt="cover">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span>{{ item.name }}</span>
|
||||
</div>
|
||||
</v-card>
|
||||
</div>
|
||||
</div>
|
||||
<v-snackbar v-model="snackbar" timeout="1500" color="error">
|
||||
未找到相关卡牌
|
||||
</v-snackbar>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { ref, onMounted, computed } from "vue";
|
||||
import TLoading from "../../components/overlay/t-loading.vue";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import TOLoading from "../../components/overlay/to-loading.vue";
|
||||
// utils
|
||||
import { createTGWindow } from "../../utils/TGWindow";
|
||||
import { AppGCGData } from "../../data";
|
||||
@@ -125,21 +133,35 @@ onMounted(async () => {
|
||||
});
|
||||
|
||||
async function loadData () {
|
||||
CardsInfoC.value = allCards.value.filter((item) => item.type === "角色牌");
|
||||
CardsInfoA.value = allCards.value.filter((item) => item.type === "行动牌");
|
||||
CardsInfoM.value = allCards.value.filter((item) => item.type === "魔物牌");
|
||||
await Promise.allSettled(
|
||||
allCards.value.map(async (item) => {
|
||||
if (item.type === "角色牌") CardsInfoC.value.push(item);
|
||||
if (item.type === "行动牌") CardsInfoA.value.push(item);
|
||||
if (item.type === "魔物牌") CardsInfoM.value.push(item);
|
||||
}),
|
||||
);
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
function toOuter (cardName: string, cardId: number) {
|
||||
const url = OBC_CONTENT_API.replace("{content_id}", cardId.toString());
|
||||
createTGWindow(url, "GCG", cardName, 1200, 800, true);
|
||||
}
|
||||
|
||||
async function searchCard () {
|
||||
loading.value = true;
|
||||
if (search.value === "") {
|
||||
setTimeout(() => {
|
||||
doSearch.value = false;
|
||||
loading.value = false;
|
||||
}, 1000);
|
||||
return;
|
||||
}
|
||||
doSearch.value = true;
|
||||
const res: TGApp.App.GCG.WikiBriefInfo[] = [];
|
||||
allCards.value.map((item) => (item.name.includes(search.value) ? res.push(item) : null));
|
||||
await Promise.allSettled(allCards.value.map((item) => (item.name.includes(search.value) ? res.push(item) : null)));
|
||||
res.sort((a, b) => a.name.localeCompare(b.name));
|
||||
console.log(res);
|
||||
loading.value = false;
|
||||
if (res.length === 0) {
|
||||
snackbar.value = true;
|
||||
@@ -151,7 +173,7 @@ async function searchCard () {
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.cards-tab {
|
||||
font-family: Genshin,serif;
|
||||
font-family: Genshin, serif;
|
||||
margin-bottom: 20px;
|
||||
color: var(--content-text-3);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file router modules main.ts
|
||||
* @description 主路由模块
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.5
|
||||
* @since Alpha v0.1.6
|
||||
*/
|
||||
|
||||
// 信息展示
|
||||
@@ -13,7 +13,7 @@ import Achievements from "../../pages/Achievements.vue";
|
||||
// 应用配置相关
|
||||
import Config from "../../pages/Config.vue";
|
||||
// 测试页
|
||||
import Test from "../../pages/test.vue";
|
||||
import Test from "../../pages/Test.vue";
|
||||
|
||||
const mainRoutes = [
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
import Abyss from "../../pages/User/Abyss.vue";
|
||||
import Characters from "../../pages/User/Characters.vue";
|
||||
import Gacha from "../../pages/User/Gacha.vue";
|
||||
import Info from "../../pages/User/Info.vue";
|
||||
import Record from "../../pages/User/Record.vue";
|
||||
// user sub
|
||||
|
||||
const userRoutes = [
|
||||
@@ -29,9 +29,9 @@ const userRoutes = [
|
||||
component: Gacha,
|
||||
},
|
||||
{
|
||||
path: "/user/info",
|
||||
name: "基本信息",
|
||||
component: Info,
|
||||
path: "/user/record",
|
||||
name: "原神战绩",
|
||||
component: Record,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file store modules home.ts
|
||||
* @description Home store module
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.2
|
||||
* @since Alpha v0.1.6
|
||||
*/
|
||||
|
||||
// vue
|
||||
@@ -24,7 +24,7 @@ export const useHomeStore = defineStore(
|
||||
show: true,
|
||||
order: 2,
|
||||
});
|
||||
const hoemShow = ref({
|
||||
const homeShow = ref({
|
||||
calendarShow,
|
||||
poolShow,
|
||||
positionShow,
|
||||
@@ -113,7 +113,7 @@ export const useHomeStore = defineStore(
|
||||
}
|
||||
|
||||
return {
|
||||
hoemShow,
|
||||
homeShow,
|
||||
poolCover,
|
||||
init,
|
||||
getShowItems,
|
||||
|
||||
@@ -32,6 +32,36 @@ export const useUserStore = defineStore(
|
||||
return cookie.value[key] || "";
|
||||
}
|
||||
|
||||
function getCookieGroup1 (): TGApp.BBS.Constant.CookieGroup1 {
|
||||
return {
|
||||
login_ticket: getCookieItem("login_ticket"),
|
||||
login_uid: getCookieItem("login_uid"),
|
||||
};
|
||||
}
|
||||
|
||||
function getCookieGroup2 (): TGApp.BBS.Constant.CookieGroup2 {
|
||||
return {
|
||||
account_id: getCookieItem("account_id"),
|
||||
cookie_token: getCookieItem("cookie_token"),
|
||||
};
|
||||
}
|
||||
|
||||
function getCookieGroup3 (): TGApp.BBS.Constant.CookieGroup3 {
|
||||
return {
|
||||
ltoken: getCookieItem("ltoken"),
|
||||
ltuid: getCookieItem("ltuid"),
|
||||
};
|
||||
}
|
||||
|
||||
function getCookieGroup4 (): TGApp.BBS.Constant.CookieGroup4 {
|
||||
return {
|
||||
account_id: getCookieItem("account_id"),
|
||||
cookie_token: getCookieItem("cookie_token"),
|
||||
ltoken: getCookieItem("ltoken"),
|
||||
ltuid: getCookieItem("ltuid"),
|
||||
};
|
||||
}
|
||||
|
||||
function initCookie (ck: Record<string, string>): void {
|
||||
if (cookie.value !== ck) {
|
||||
cookie.value = ck;
|
||||
@@ -43,6 +73,10 @@ export const useUserStore = defineStore(
|
||||
getBriefInfo,
|
||||
setBriefInfo,
|
||||
getCookieItem,
|
||||
getCookieGroup1,
|
||||
getCookieGroup2,
|
||||
getCookieGroup3,
|
||||
getCookieGroup4,
|
||||
initCookie,
|
||||
};
|
||||
},
|
||||
|
||||
52
src/types/BBS/Constant.d.ts
vendored
52
src/types/BBS/Constant.d.ts
vendored
@@ -2,7 +2,7 @@
|
||||
* @file types BBS Constant.d.ts
|
||||
* @description BBS 常量相关类型定义文件
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.5
|
||||
* @since Alpha v0.1.6
|
||||
*/
|
||||
|
||||
declare namespace TGApp.BBS.Constant {
|
||||
@@ -45,4 +45,54 @@ declare namespace TGApp.BBS.Constant {
|
||||
stuid: string
|
||||
stoken_v2?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @description cookie 组合-1
|
||||
* @interface CookieGroup1
|
||||
* @since Alpha v0.1.6
|
||||
* @property {string} login_ticket 登录凭证
|
||||
* @property {string} login_uid 登录 uid
|
||||
* @return CookieGroup1
|
||||
*/
|
||||
export interface CookieGroup1 {
|
||||
login_ticket: string
|
||||
login_uid: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @description cookie 组合-2
|
||||
* @interface CookieGroup2
|
||||
* @since Alpha v0.1.6
|
||||
* @property {string} account_id 账号 id
|
||||
* @property {string} cookie_token cookie token
|
||||
* @return CookieGroup2
|
||||
*/
|
||||
export interface CookieGroup2 {
|
||||
account_id: string
|
||||
cookie_token: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @description cookie 组合-3
|
||||
* @interface CookieGroup3
|
||||
* @since Alpha v0.1.6
|
||||
* @property {string} ltoken ltoken
|
||||
* @property {string} ltuid ltoken 对应的 uid
|
||||
* @return CookieGroup3
|
||||
*/
|
||||
export interface CookieGroup3 {
|
||||
ltoken: string
|
||||
ltuid: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @description cookie 组合-4
|
||||
* @interface CookieGroup4
|
||||
* @since Alpha v0.1.6
|
||||
* @extends CookieGroup2
|
||||
* @extends CookieGroup3
|
||||
* @return CookieGroup4
|
||||
*/
|
||||
export interface CookieGroup4 extends CookieGroup2, CookieGroup3 {}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file utils TGSqlite.ts
|
||||
* @description 数据库操作类
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.5
|
||||
* @since Alpha v0.1.6
|
||||
*/
|
||||
|
||||
// tauri
|
||||
@@ -263,6 +263,20 @@ class TGSqlite {
|
||||
return res[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取最新成就版本
|
||||
* @since Alpha v0.1.6
|
||||
* @memberOf TGSqlite
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
public async getLatestAchievementVersion (): Promise<string> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
const sql = "SELECT version FROM AchievementSeries ORDER BY version DESC LIMIT 1;";
|
||||
const res: Array<{ version: string }> = await db.select(sql);
|
||||
await db.close();
|
||||
return res[0].version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 查询成就
|
||||
* @memberOf TGSqlite
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<template>
|
||||
<TSwitchTheme />
|
||||
<div v-if="loading">
|
||||
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
||||
</div>
|
||||
<div v-else class="anno-json">
|
||||
<TOLoading v-model="loading" :empty="loadingEmpty" :title="loadingTitle" />
|
||||
<div class="anno-json">
|
||||
<div class="anno-title">
|
||||
活动列表 JSON
|
||||
</div>
|
||||
@@ -19,7 +17,7 @@
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import JsonViewer from "vue-json-viewer";
|
||||
import TLoading from "../components/overlay/t-loading.vue";
|
||||
import TOLoading from "../components/overlay/to-loading.vue";
|
||||
import TSwitchTheme from "../components/main/t-switchTheme.vue";
|
||||
// tauri
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<template>
|
||||
<TSwitchTheme />
|
||||
<div v-if="loading" class="loading">
|
||||
<TLoading :title="loadingTitle" :empty="loadingEmpty" />
|
||||
</div>
|
||||
<div v-else class="anno-body">
|
||||
<TOLoading v-model="loading" :title="loadingTitle" :empty="loadingEmpty" />
|
||||
<div class="anno-body">
|
||||
<div class="anno-title">
|
||||
{{ annoData.title }}
|
||||
</div>
|
||||
@@ -19,7 +17,7 @@
|
||||
// vue
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import TLoading from "../components/overlay/t-loading.vue";
|
||||
import TOLoading from "../components/overlay/to-loading.vue";
|
||||
import TSwitchTheme from "../components/main/t-switchTheme.vue";
|
||||
// tauri
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
@@ -47,6 +45,7 @@ onMounted(async () => {
|
||||
}
|
||||
// 获取数据
|
||||
loadingTitle.value = "正在获取数据...";
|
||||
loading.value = true;
|
||||
try {
|
||||
annoData.value = await TGRequest.Anno.getContent(annoId);
|
||||
loadingTitle.value = "正在渲染数据...";
|
||||
@@ -56,9 +55,7 @@ onMounted(async () => {
|
||||
loadingTitle.value = "公告不存在或解析失败";
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
}, 200);
|
||||
loading.value = false;
|
||||
});
|
||||
</script>
|
||||
<style lang="css" src="../assets/css/anno-parser.css" scoped />
|
||||
|
||||
@@ -1,79 +1,70 @@
|
||||
<template>
|
||||
<TSwitchTheme />
|
||||
<div v-if="loading">
|
||||
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="lottery-div">
|
||||
<div class="lottery-title">
|
||||
抽奖详情
|
||||
<span style="color:#E06C63">{{ timeStatus === "已开奖" ? timeStatus : `待开奖 ${timeStatus}` }}</span>
|
||||
</div>
|
||||
<div 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>
|
||||
</v-list-item>
|
||||
<div class="reward-title">
|
||||
参与方式:{{ participationMethod }}
|
||||
</div>
|
||||
<div class="reward-title">
|
||||
抽奖 ID:{{ lotteryCard.id }}
|
||||
</div>
|
||||
<div class="reward-title">
|
||||
奖品详情
|
||||
<div v-for="reward in lotteryCard.rewards" :key="reward.rewardName" class="reward-subtitle">
|
||||
{{ reward.rewardName }} {{ reward.scheduledWinnerNumber }}份
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<v-btn class="lottery-back" @click="backPost()">
|
||||
<img src="../assets/icons/circle-cancel.svg" alt="back">
|
||||
<span>返回</span>
|
||||
</v-btn>
|
||||
<v-btn v-show="appStore.devMode" class="card-dev-btn" @click="showJson = true">
|
||||
<TOLoading v-model="loading" :empty="loadingEmpty" :title="loadingTitle" />
|
||||
<div v-if="!loading" class="lottery-box">
|
||||
<div class="lottery-title">
|
||||
抽奖详情
|
||||
<span style="color:#E06C63">{{ timeStatus === "已开奖" ? timeStatus : `待开奖 ${timeStatus}` }}</span>
|
||||
</div>
|
||||
<div class="lottery-list">
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<img src="../assets/icons/arrow-right.svg" alt="right">
|
||||
<v-avatar>
|
||||
<v-img :src="lotteryCard.creator.avatar_url" />
|
||||
</v-avatar>
|
||||
</template>
|
||||
JSON
|
||||
</v-btn>
|
||||
</div>
|
||||
<div v-show="showJson" class="lottery-json">
|
||||
<JsonViewer :value="jsonData" copyable boxed />
|
||||
</div>
|
||||
<div v-if="timeStatus === '已开奖'" class="lottery-div">
|
||||
<div class="lottery-title">
|
||||
中奖详情
|
||||
<template #append>
|
||||
<v-btn variant="outlined" @click="backPost()">
|
||||
返回
|
||||
</v-btn>
|
||||
</template>
|
||||
{{ lotteryCard.creator.nickname }}
|
||||
<v-list-item-subtitle>{{ lotteryCard.creator.introduce }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<div class="reward-title">
|
||||
参与方式:{{ participationMethod }}
|
||||
</div>
|
||||
<div v-for="reward in lotteryCard.rewards" :key="reward.rewardName" class="lottery-list">
|
||||
<div class="reward-title">
|
||||
{{ reward.rewardName }} {{ reward.scheduledWinnerNumber }}/{{ reward.winnerNumber }}
|
||||
<div class="reward-title">
|
||||
抽奖 ID:{{ lotteryCard.id }}
|
||||
</div>
|
||||
<div class="reward-title">
|
||||
奖品详情
|
||||
<div v-for="reward in lotteryCard.rewards" :key="reward.rewardName" class="reward-subtitle">
|
||||
{{ reward.rewardName }} {{ reward.scheduledWinnerNumber }}份
|
||||
</div>
|
||||
<div class="lottery-grid">
|
||||
<div v-for="user in reward.users" :key="user.uid" class="lottery-sub-list">
|
||||
<div class="lottery-user-avatar">
|
||||
<img :src="user.avatar_url" alt="avatar">
|
||||
</div>
|
||||
<div class="lottery-user-nickname">
|
||||
{{ user.nickname }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="timeStatus === '已开奖'" class="lottery-box">
|
||||
<div class="lottery-title">
|
||||
中奖详情
|
||||
</div>
|
||||
<div v-for="reward in lotteryCard.rewards" :key="reward.rewardName" class="lottery-list">
|
||||
<div class="reward-title">
|
||||
{{ reward.rewardName }} {{ reward.scheduledWinnerNumber }}/{{ reward.winnerNumber }}
|
||||
</div>
|
||||
<div class="lottery-grid">
|
||||
<div v-for="user in reward.users" :key="user.uid" class="lottery-sub-list">
|
||||
<div class="lottery-user-avatar">
|
||||
<img :src="user.avatar_url" alt="avatar">
|
||||
</div>
|
||||
<div class="lottery-user-nickname">
|
||||
{{ user.nickname }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showJson" class="lottery-json">
|
||||
<JsonViewer :value="jsonData" copyable boxed />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { ref, onMounted, reactive, onUpdated } from "vue";
|
||||
import { computed, onMounted, onUpdated, reactive, ref } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import JsonViewer from "vue-json-viewer";
|
||||
import TLoading from "../components/overlay/t-loading.vue";
|
||||
import TOLoading from "../components/overlay/to-loading.vue";
|
||||
import TSwitchTheme from "../components/main/t-switchTheme.vue";
|
||||
// tauri
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
@@ -91,7 +82,7 @@ const loadingEmpty = ref(false as boolean);
|
||||
|
||||
// store
|
||||
const appStore = useAppStore();
|
||||
|
||||
const showJson = computed(() => appStore.devMode);
|
||||
// 定时器
|
||||
const lotteryTimer = ref(null as any);
|
||||
// 参与方式
|
||||
@@ -115,7 +106,6 @@ function flushTimeStatus () {
|
||||
// 数据
|
||||
const lotteryId = useRoute().params.lottery_id as string;
|
||||
const lotteryCard = ref({} as LotteryCard);
|
||||
const showJson = ref(false as boolean);
|
||||
let jsonData = reactive({} as LotteryData);
|
||||
const timeStatus = ref("未知" as string);
|
||||
|
||||
@@ -174,64 +164,42 @@ onUpdated(() => {
|
||||
|
||||
</script>
|
||||
<style lang="css">
|
||||
.lottery-div {
|
||||
background: var(--content-bg-2);
|
||||
border-radius: 10px;
|
||||
.lottery-box {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
background: rgb(255 255 255 / 10%);
|
||||
box-shadow: 0 0 10px rgb(0 0 0 / 40%);
|
||||
border-radius: 25px 5px 5px;
|
||||
}
|
||||
|
||||
.lottery-title {
|
||||
font-family: Genshin, serif;
|
||||
font-size: 20px;
|
||||
height: 40px;
|
||||
color: var(--content-text-3);
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.reward-title {
|
||||
font-family: Genshin-Light, serif;
|
||||
font-size: 16px;
|
||||
.lottery-list {
|
||||
background: rgb(0 0 0 / 40%);
|
||||
box-shadow: 0 0 10px rgb(255 255 255 / 10%);
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
margin-bottom: 10px;
|
||||
color: #faf7e8;
|
||||
font-family: Genshin-Light, serif;
|
||||
}
|
||||
|
||||
.reward-title {
|
||||
font-size: 16px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.reward-subtitle {
|
||||
font-family: Genshin-Light, serif;
|
||||
font-size: 16px;
|
||||
color: #faf7e8;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.lottery-list {
|
||||
background: var(--content-bg-1);
|
||||
border-radius: 10px;
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
color: #faf7e8;
|
||||
font-family: Genshin-Light, serif;
|
||||
}
|
||||
|
||||
.lottery-back {
|
||||
margin: 5px;
|
||||
height: 30px;
|
||||
border-radius: 40px;
|
||||
font-family: Genshin, serif;
|
||||
background: #4A5366;
|
||||
}
|
||||
|
||||
.lottery-back img {
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.lottery-back span {
|
||||
color: #faf7e8;
|
||||
font-size: 16px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.lottery-grid {
|
||||
border-radius: 10px;
|
||||
display: grid;
|
||||
@@ -272,12 +240,22 @@ onUpdated(() => {
|
||||
}
|
||||
|
||||
.lottery-json {
|
||||
padding: 20px;
|
||||
border-radius: 20px;
|
||||
margin-bottom: 10px;
|
||||
background: rgb(255 255 255 / 10%);
|
||||
box-shadow: 0 0 10px rgb(0 0 0 / 40%);
|
||||
border-radius: 25px 5px;
|
||||
font-family: Consolas, serif;
|
||||
color: #faf7e8;
|
||||
}
|
||||
|
||||
.jv-container {
|
||||
background: var(--content-bg-2) !important;
|
||||
background: rgb(0 0 0 / 60%) !important;
|
||||
border-radius: 25px 5px !important;
|
||||
box-shadow: 0 0 10px rgb(0 0 0 / 40%) !important;
|
||||
}
|
||||
|
||||
.jv-key,
|
||||
.jv-array {
|
||||
color: #f0c674 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,224 +1,220 @@
|
||||
<template>
|
||||
<div v-show="loading">
|
||||
<TLoading :title="loadingTitle" />
|
||||
</div>
|
||||
<div v-show="!loading">
|
||||
<v-tabs v-model="tab" align-tabs="start" class="news-tab">
|
||||
<v-tab value="notice">
|
||||
公告
|
||||
</v-tab>
|
||||
<v-tab value="activity" @click="firstLoad('activity')">
|
||||
活动
|
||||
</v-tab>
|
||||
<v-tab v-if="showNews" value="news" @click="firstLoad('news')">
|
||||
新闻
|
||||
</v-tab>
|
||||
<v-spacer />
|
||||
<v-btn class="switch-btn" @click="switchAnno">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-bullhorn</v-icon>
|
||||
</template>
|
||||
切换游戏内公告
|
||||
</v-btn>
|
||||
<v-btn class="switch-chan" @click="showList=true">
|
||||
<v-icon>mdi-view-list</v-icon>
|
||||
</v-btn>
|
||||
<v-text-field
|
||||
v-show="appStore.devMode"
|
||||
v-model="search"
|
||||
append-icon="mdi-magnify"
|
||||
label="搜索"
|
||||
single-line
|
||||
hide-details
|
||||
@click:append="searchPost"
|
||||
@keyup.enter="searchPost"
|
||||
/>
|
||||
</v-tabs>
|
||||
<v-window v-model="tab">
|
||||
<v-window-item value="notice">
|
||||
<div class="news-grid">
|
||||
<v-card v-for="item in postData.notice" :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('notice')">
|
||||
<template #append>
|
||||
<img src="../assets/icons/arrow-left.svg" alt="right">
|
||||
</template>
|
||||
已加载:{{ rawData.notice.lastId }},加载更多
|
||||
</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>
|
||||
<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('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>
|
||||
<v-overlay v-model="showList">
|
||||
<div class="choice-box">
|
||||
<div class="choice-title">
|
||||
请选择要跳转的频道
|
||||
</div>
|
||||
<div class="choice-list">
|
||||
<div class="choice-item" @click="toChannel('/news/2')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/ys.webp" alt="ys">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
原神
|
||||
</div>
|
||||
<TOLoading v-model="loading" :title="loadingTitle" />
|
||||
<v-tabs v-model="tab" align-tabs="start" class="news-tab">
|
||||
<v-tab value="notice">
|
||||
公告
|
||||
</v-tab>
|
||||
<v-tab value="activity" @click="firstLoad('activity')">
|
||||
活动
|
||||
</v-tab>
|
||||
<v-tab v-if="showNews" value="news" @click="firstLoad('news')">
|
||||
新闻
|
||||
</v-tab>
|
||||
<v-spacer />
|
||||
<v-btn class="switch-btn" @click="switchAnno">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-bullhorn</v-icon>
|
||||
</template>
|
||||
切换游戏内公告
|
||||
</v-btn>
|
||||
<v-btn class="switch-chan" @click="showList=true">
|
||||
<v-icon>mdi-view-list</v-icon>
|
||||
</v-btn>
|
||||
<v-text-field
|
||||
v-show="appStore.devMode"
|
||||
v-model="search"
|
||||
append-icon="mdi-magnify"
|
||||
label="搜索"
|
||||
single-line
|
||||
hide-details
|
||||
@click:append="searchPost"
|
||||
@keyup.enter="searchPost"
|
||||
/>
|
||||
</v-tabs>
|
||||
<v-window v-model="tab">
|
||||
<v-window-item value="notice">
|
||||
<div class="news-grid">
|
||||
<v-card v-for="item in postData.notice" :key="item.post_id" class="news-card" width="340">
|
||||
<div class="news-cover" @click="toPost(item)">
|
||||
<img :src="item.cover" alt="cover">
|
||||
</div>
|
||||
<div class="choice-item" @click="toChannel('/news/6')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/sr.webp" alt="sr">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
崩坏:星穹铁道
|
||||
</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.lastId }},加载更多
|
||||
</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>
|
||||
<div class="choice-item" @click="toChannel('/news/1')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/bh3.webp" alt="bh3">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
崩坏3
|
||||
<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>
|
||||
<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('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>
|
||||
<div class="choice-item" @click="toChannel('/news/3')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/bh2.webp" alt="bh2">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
崩坏2
|
||||
</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>
|
||||
<v-overlay v-model="showList">
|
||||
<div class="choice-box">
|
||||
<div class="choice-title">
|
||||
请选择要跳转的频道
|
||||
</div>
|
||||
<div class="choice-list">
|
||||
<div class="choice-item" @click="toChannel('/news/2')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/ys.webp" alt="ys">
|
||||
</div>
|
||||
<div class="choice-item" @click="toChannel('/news/4')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/wd.webp" alt="wd">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
未定事件簿
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
原神
|
||||
</div>
|
||||
<div class="choice-item" @click="toChannel('/news/8')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/zzz.webp" alt="zzz">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
绝区零
|
||||
</div>
|
||||
</div>
|
||||
<div class="choice-item" @click="toChannel('/news/6')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/sr.webp" alt="sr">
|
||||
</div>
|
||||
<div class="choice-item" @click="toChannel('/news/5')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/dby.webp" alt="sg">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
大别野
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
崩坏:星穹铁道
|
||||
</div>
|
||||
</div>
|
||||
<div class="choice-item" @click="toChannel('/news/1')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/bh3.webp" alt="bh3">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
崩坏3
|
||||
</div>
|
||||
</div>
|
||||
<div class="choice-item" @click="toChannel('/news/3')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/bh2.webp" alt="bh2">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
崩坏2
|
||||
</div>
|
||||
</div>
|
||||
<div class="choice-item" @click="toChannel('/news/4')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/wd.webp" alt="wd">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
未定事件簿
|
||||
</div>
|
||||
</div>
|
||||
<div class="choice-item" @click="toChannel('/news/8')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/zzz.webp" alt="zzz">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
绝区零
|
||||
</div>
|
||||
</div>
|
||||
<div class="choice-item" @click="toChannel('/news/5')">
|
||||
<div class="choice-icon">
|
||||
<img src="/platforms/mhy/dby.webp" alt="sg">
|
||||
</div>
|
||||
<div class="choice-name">
|
||||
大别野
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</v-overlay>
|
||||
</div>
|
||||
</div>
|
||||
</v-overlay>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { onMounted, ref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import TLoading from "../components/overlay/t-loading.vue";
|
||||
import TOLoading from "../components/overlay/to-loading.vue";
|
||||
// store
|
||||
import { useAppStore } from "../store/modules/app";
|
||||
// plugin
|
||||
@@ -259,14 +255,17 @@ const postData = ref({
|
||||
const rawData = ref({
|
||||
notice: {
|
||||
isLast: false,
|
||||
name: "公告",
|
||||
lastId: 0,
|
||||
},
|
||||
activity: {
|
||||
isLast: false,
|
||||
name: "活动",
|
||||
lastId: 0,
|
||||
},
|
||||
news: {
|
||||
isLast: false,
|
||||
name: "咨讯",
|
||||
lastId: 0,
|
||||
},
|
||||
});
|
||||
@@ -278,10 +277,12 @@ onMounted(async () => {
|
||||
rawData.value.notice.lastId = noticeData.list.length;
|
||||
postData.value.notice = MysOper.News.card.notice(noticeData);
|
||||
tab.value = "notice";
|
||||
loading.value = false;
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
}, 1500);
|
||||
});
|
||||
|
||||
async function firstLoad (data:string) {
|
||||
async function firstLoad (data: string) {
|
||||
if (rawData.value.activity.lastId !== 0 && rawData.value.news.lastId !== 0) {
|
||||
return;
|
||||
}
|
||||
@@ -292,7 +293,6 @@ async function firstLoad (data:string) {
|
||||
rawData.value.activity.isLast = activityData.is_last;
|
||||
rawData.value.activity.lastId = activityData.list.length;
|
||||
postData.value.activity = MysOper.News.card.activity(activityData);
|
||||
loading.value = false;
|
||||
}
|
||||
if (data === "news" && rawData.value.news.lastId === 0) {
|
||||
loadingTitle.value = "正在获取咨讯数据...";
|
||||
@@ -301,15 +301,17 @@ async function firstLoad (data:string) {
|
||||
rawData.value.news.isLast = newsData.is_last;
|
||||
rawData.value.news.lastId = newsData.list.length;
|
||||
postData.value.news = MysOper.News.card.news(newsData);
|
||||
loading.value = false;
|
||||
}
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
async function switchAnno () {
|
||||
await router.push("/announcements");
|
||||
}
|
||||
|
||||
async function toChannel (chan:string) {
|
||||
async function toChannel (chan: string) {
|
||||
showList.value = false;
|
||||
await router.push(chan);
|
||||
await window.location.reload();
|
||||
@@ -318,57 +320,32 @@ async function toChannel (chan:string) {
|
||||
// 加载更多
|
||||
async function loadMore (data: string) {
|
||||
loadingSub.value = true;
|
||||
let getData: NewsData;
|
||||
let getCard: NewsCard[];
|
||||
switch (data) {
|
||||
case "notice":
|
||||
if (rawData.value.notice.isLast) {
|
||||
snackbarText.value = "已经是最后一页了";
|
||||
snackbarColor.value = "#35acce";
|
||||
snackbar.value = true;
|
||||
loadingSub.value = false;
|
||||
return;
|
||||
}
|
||||
getData = await MysOper.News.get.notice(gid, 20, rawData.value.notice.lastId);
|
||||
rawData.value.notice.lastId = rawData.value.notice.lastId + getData.list.length;
|
||||
rawData.value.notice.isLast = getData.is_last;
|
||||
getCard = MysOper.News.card.notice(getData);
|
||||
postData.value.notice = postData.value.notice.concat(getCard);
|
||||
loadingSub.value = false;
|
||||
break;
|
||||
case "activity":
|
||||
if (rawData.value.activity.isLast) {
|
||||
snackbarText.value = "已经是最后一页了";
|
||||
snackbarColor.value = "#35acce";
|
||||
snackbar.value = true;
|
||||
loadingSub.value = false;
|
||||
return;
|
||||
}
|
||||
getData = await MysOper.News.get.activity(gid, 20, rawData.value.activity.lastId);
|
||||
rawData.value.activity.lastId = rawData.value.activity.lastId + getData.list.length;
|
||||
rawData.value.activity.isLast = getData.is_last;
|
||||
getCard = MysOper.News.card.activity(getData);
|
||||
postData.value.activity = postData.value.activity.concat(getCard);
|
||||
loadingSub.value = false;
|
||||
break;
|
||||
case "news":
|
||||
if (rawData.value.news.isLast) {
|
||||
snackbarText.value = "已经是最后一页了";
|
||||
snackbarColor.value = "#35acce";
|
||||
snackbar.value = true;
|
||||
loadingSub.value = false;
|
||||
return;
|
||||
}
|
||||
getData = await MysOper.News.get.news(gid, 20, rawData.value.news.lastId);
|
||||
rawData.value.news.lastId = rawData.value.news.lastId + getData.list.length;
|
||||
rawData.value.news.isLast = getData.is_last;
|
||||
getCard = MysOper.News.card.news(getData);
|
||||
postData.value.news = postData.value.news.concat(getCard);
|
||||
loadingSub.value = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (rawData.value[data].isLast) {
|
||||
snackbarText.value = "已经是最后一页了";
|
||||
snackbarColor.value = "#35acce";
|
||||
snackbar.value = true;
|
||||
loadingSub.value = false;
|
||||
return;
|
||||
}
|
||||
loadingTitle.value = `正在获取${rawData.value[data].name}数据...`;
|
||||
loading.value = true;
|
||||
const getData = await MysOper.News.get[data](gid, 20, rawData.value[data].lastId);
|
||||
rawData.value[data].lastId = rawData.value[data].lastId + getData.list.length;
|
||||
rawData.value[data].isLast = getData.is_last;
|
||||
const getCard = MysOper.News.card[data](getData);
|
||||
postData.value[data] = postData.value[data].concat(getCard);
|
||||
if (rawData.value[data].isLast) {
|
||||
snackbarText.value = "已经是最后一页了";
|
||||
snackbarColor.value = "#35acce";
|
||||
snackbar.value = true;
|
||||
loadingSub.value = false;
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
loadingSub.value = false;
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
async function toPost (item: NewsCard | string) {
|
||||
@@ -392,6 +369,7 @@ async function toPost (item: NewsCard | string) {
|
||||
createTGWindow(path, "帖子", item.title, 960, 720, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
async function toJson (item: NewsCard | string) {
|
||||
if (typeof item === "string") {
|
||||
const path = router.resolve({
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<template>
|
||||
<TSwitchTheme />
|
||||
<div v-if="loading">
|
||||
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
||||
</div>
|
||||
<div v-else class="post-json">
|
||||
<TOLoading v-model="loading" :empty="loadingEmpty" :title="loadingTitle" />
|
||||
<div class="post-json">
|
||||
<div class="post-title">
|
||||
帖子返回内容 JSON
|
||||
</div>
|
||||
@@ -15,7 +13,7 @@
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import JsonViewer from "vue-json-viewer";
|
||||
import TLoading from "../components/overlay/t-loading.vue";
|
||||
import TOLoading from "../components/overlay/to-loading.vue";
|
||||
import TSwitchTheme from "../components/main/t-switchTheme.vue";
|
||||
// tauri
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
@@ -41,10 +39,13 @@ onMounted(async () => {
|
||||
}
|
||||
// 获取数据
|
||||
loadingTitle.value = "正在获取数据...";
|
||||
jsonData = await MysOper.Post.get(postId);
|
||||
setTimeout(() => {
|
||||
try {
|
||||
jsonData = await MysOper.Post.get(postId);
|
||||
loading.value = false;
|
||||
}, 200);
|
||||
} catch (e) {
|
||||
loadingTitle.value = "帖子不存在或解析失败";
|
||||
loadingEmpty.value = true;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<template>
|
||||
<TSwitchTheme />
|
||||
<div v-if="loading">
|
||||
<TLoading :empty="loadingEmpty" :title="loadingTitle" />
|
||||
</div>
|
||||
<div v-else class="mys-post-body" v-html="postHtml" />
|
||||
<TOLoading v-model="loading" :empty="loadingEmpty" :title="loadingTitle" />
|
||||
<div class="mys-post-body" v-html="postHtml" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import TLoading from "../components/overlay/t-loading.vue";
|
||||
import TOLoading from "../components/overlay/to-loading.vue";
|
||||
// tauri
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
// plugins
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file web request TGRequest.ts
|
||||
* @description 应用用到的请求函数
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.5
|
||||
* @since Alpha v0.1.6
|
||||
*/
|
||||
|
||||
import { getAbyss } from "./getAbyss";
|
||||
@@ -10,6 +10,7 @@ import { getAnnoList, getAnnoContent } from "./getAnno";
|
||||
import { getCookieTokenBySToken } from "./getCookieToken";
|
||||
// import * from "./getEnkaData.ts";
|
||||
import { getGameAccountsBySToken, getGameAccountsByCookie } from "./getGameAccounts";
|
||||
import { getGameRecord } from "./getGameRecord";
|
||||
import { getLTokenBySToken } from "./getLToken";
|
||||
import { getGameRoleListByLToken } from "./getRoleList";
|
||||
// import * from "./getTickets.ts";
|
||||
@@ -26,6 +27,7 @@ const TGRequest = {
|
||||
},
|
||||
User: {
|
||||
init: initCookie,
|
||||
getRecord: getGameRecord,
|
||||
byLoginTicket: {
|
||||
getTokens: getTokensByLoginTicket,
|
||||
},
|
||||
|
||||
@@ -10,7 +10,6 @@ import { http } from "@tauri-apps/api";
|
||||
// api
|
||||
import TGApi from "../api/TGApi";
|
||||
// utils
|
||||
import { getServerByUid } from "../utils/tools";
|
||||
import { getRequestHeader } from "../utils/getRequestHeader";
|
||||
|
||||
/**
|
||||
@@ -24,7 +23,7 @@ import { getRequestHeader } from "../utils/getRequestHeader";
|
||||
export async function getAbyss (cookie: Record<string, string>, schedule_type: string, account: TGApp.Sqlite.Account.Game): Promise<TGApp.Game.Abyss.FullData | TGApp.BBS.Response.Base> {
|
||||
const url = TGApi.GameData.getAbyss;
|
||||
const role_id = account.gameUid;
|
||||
const params = { role_id, schedule_type, server: getServerByUid(role_id) };
|
||||
const params = { role_id, schedule_type, server: account.region };
|
||||
const header = getRequestHeader(cookie, "GET", params, "common");
|
||||
return await http.fetch<TGApp.Game.Abyss.Response>(url, {
|
||||
method: "GET",
|
||||
|
||||
36
src/web/request/getGameRecord.ts
Normal file
36
src/web/request/getGameRecord.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @file core utils getGameRecord.ts
|
||||
* @description 获取游戏数据的函数
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.2.0
|
||||
*/
|
||||
|
||||
// tauri
|
||||
import { http } from "@tauri-apps/api";
|
||||
// utils
|
||||
import TGApi from "../api/TGApi";
|
||||
import TGUtils from "../utils/TGUtils";
|
||||
|
||||
/**
|
||||
* @description 获取用户游戏数据
|
||||
* @since Alpha v0.2.0
|
||||
* @todo invalid uid
|
||||
* @description 这边的 ck 可以是 cookie_token 和 account_id
|
||||
* @description 也可以是 ltoken 和 ltuid
|
||||
* @param {Record<string, string>} cookie cookie
|
||||
* @param {TGApp.Sqlite.Account.Game} user 用户的基本信息
|
||||
* @returns {Promise<unknown>} 用户基本信息
|
||||
*/
|
||||
export async function getGameRecord (cookie: Record<string, string>, user: TGApp.Sqlite.Account.Game): Promise<unknown> {
|
||||
const url = TGApi.GameData.getUserCard;
|
||||
const params = { role_id: user.gameUid, server: user.region };
|
||||
const header = TGUtils.User.getHeader(cookie, "GET", params, "common");
|
||||
return await http.fetch(url, {
|
||||
method: "GET",
|
||||
headers: header,
|
||||
query: params,
|
||||
}).then((res) => {
|
||||
console.log(res.data);
|
||||
return res.data;
|
||||
});
|
||||
}
|
||||
@@ -18,12 +18,12 @@ import TGUtils from "../utils/TGUtils";
|
||||
* @param {TGApp.Sqlite.Account.Game} account 游戏账号
|
||||
* @returns {Promise<TGApp.Game.Character.ListItem[]|TGApp.BBS.Response.Base>} 用户角色列表
|
||||
*/
|
||||
export async function getGameRoleListByLToken (cookie: Record<string, string>, account: TGApp.Sqlite.Account.Game): Promise<TGApp.Game.Character.ListItem[] | TGApp.BBS.Response.Base> {
|
||||
export async function getGameRoleListByLToken (cookie: TGApp.BBS.Constant.CookieGroup4, account: TGApp.Sqlite.Account.Game): Promise<TGApp.Game.Character.ListItem[] | TGApp.BBS.Response.Base> {
|
||||
const url = TGApi.GameData.byCookie.getCharacter;
|
||||
const uid = account.gameUid;
|
||||
// eslint-disable-next-line camelcase
|
||||
const data = { role_id: uid, server: TGUtils.Tools.getServerByUid(uid) };
|
||||
const header = TGUtils.User.getHeader(cookie, "POST", JSON.stringify(data), "common");
|
||||
const header = TGUtils.User.getHeader(cookie as unknown as Record<string, string>, "POST", JSON.stringify(data), "common");
|
||||
return await http.fetch<TGApp.Game.Character.ListResponse>(url, {
|
||||
method: "POST",
|
||||
headers: header,
|
||||
|
||||
Reference in New Issue
Block a user