mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2026-03-26 05:39:45 +08:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0e781b6b9 | ||
|
|
91fc39b579 | ||
|
|
14fd56fd9c | ||
|
|
b225827ef3 | ||
|
|
f869028fd5 | ||
|
|
317d05aad6 | ||
|
|
fc0c607726 | ||
|
|
a26b7fb053 | ||
|
|
ec55ff69d6 | ||
|
|
3c6587cb73 | ||
|
|
5963e9a153 | ||
|
|
b69ae3b0a3 | ||
|
|
528d4f6e83 | ||
|
|
8cb05dd188 | ||
|
|
3d0a9d57b2 | ||
|
|
501f6bfa0e | ||
|
|
c442a1c5eb | ||
|
|
5ac43c95e5 | ||
|
|
b89c3ac101 | ||
|
|
89d2e214bc | ||
|
|
96018666c5 | ||
|
|
c9bef8927b | ||
|
|
f40d9e61d4 | ||
|
|
27828e3a40 | ||
|
|
35d9382643 | ||
|
|
cc42d1fcb3 | ||
|
|
6b3b9748cd | ||
|
|
d6e60ee264 | ||
|
|
4c8cb39bf6 | ||
|
|
ffc354a319 | ||
|
|
26048dc12e | ||
|
|
ff36275184 | ||
|
|
0c178f8958 | ||
|
|
42f6d7bdaa | ||
|
|
eeba1f9978 | ||
|
|
805b358e6d | ||
|
|
f9199efd03 | ||
|
|
8da4ebdcf5 | ||
|
|
214d1d1090 | ||
|
|
019306d08c | ||
|
|
ceea064d73 | ||
|
|
bbfd608b02 | ||
|
|
8f728808a8 | ||
|
|
8c004a8af9 | ||
|
|
5d180857a3 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,3 +4,5 @@
|
||||
node_modules
|
||||
# Tauri build
|
||||
dist
|
||||
# Secrets
|
||||
.env.sh
|
||||
|
||||
32
CHANGELOG.md
32
CHANGELOG.md
@@ -2,34 +2,52 @@
|
||||
Author: 目棃
|
||||
Date: 2023-03-30
|
||||
Description: CHANGELOG
|
||||
Update: 2023-04-23
|
||||
Update: 2023-05-02
|
||||
---
|
||||
|
||||
> 本文档 [`Front-matter`](https://github.com/BTMuli/Mucli#FrontMatter) 由 [MuCli](https://github.com/BTMuli/Mucli) 自动生成于`2023-03-30 15:39:49`
|
||||
>
|
||||
> 更新于 `2023-04-23 13:33:35`
|
||||
> 更新于 `2023-05-02 18:24:21`
|
||||
|
||||
# CHANGELOG
|
||||
|
||||
## [0.1.4](https://github.com/BTMuli/Tauri.Genshin/releases/v0.1.4) (2023-05-02)
|
||||
|
||||
### Feat
|
||||
|
||||
- 应用:支持资源完整性检测&更新 [`bbfd608`](https://github.com/BTMuli/Tauri.Genshin/commit/bbfd608)
|
||||
- 应用:支持数据备份&恢复 [`214d1d1`](https://github.com/BTMuli/Tauri.Genshin/commit/214d1d10)
|
||||
- 应用:数据源更改为 Sqlite 而非之前的 IndexedDB [`26048dc`](https://github.com/BTMuli/Tauri.Genshin/commit/26048dc) [#11](https://github.com/BTMuli/Tauri.Genshin/issues/11)
|
||||
|
||||
### Fix
|
||||
|
||||
- 成就:使用虚拟列表优化内存占用及浏览体验 [`5963e9a`](https://github.com/BTMuli/Tauri.Genshin/commit/5963e9a) [#13](https://github.com/BTMuli/Tauri.Genshin/issues/13)
|
||||
- 组件:优化 `TConfirm` 组件表现
|
||||
- 应用:优化侧边滚动条表现
|
||||
- 应用:检测更新 Key 更改,下版本更新将提示更新 [`ceea064`](https://github.com/BTMuli/Tauri.Genshin/commit/ceea064)
|
||||
- 应用:添加 `3.6` 版本遗漏数据 [`91fc39b`](https://github.com/BTMuli/Tauri.Genshin/commit/91fc39b)
|
||||
|
||||
FullCommits: [`v0.1.3 ~ v0.1.4`](https://github.com/BTMuli/Tauri.Genshin/compare/v0.1.3...v0.1.4)
|
||||
|
||||
## [0.1.3](https://github.com/BTMuli/Tauri.Genshin/releases/v0.1.3) (2023-04-23)
|
||||
|
||||
### Feat
|
||||
|
||||
- 应用:支持浅色\深色主题切换
|
||||
- 应用:支持检测更新
|
||||
- 图鉴:角色图鉴草创 [`d154b5bd`](https://BTMuli/Tauri.Genshin/commit/d154b5bd)
|
||||
- 图鉴:武器图鉴草创 [`1c309e38`](https://BTMuli/Tauri.Genshin/commit/1c309e38)
|
||||
- 滚动条:样式美化 [`4022504`](https://BTMuli/Tauri.Genshin/commit/4022504)
|
||||
- 图鉴:角色图鉴草创 [`d154b5bd`](https://github.com/BTMuli/Tauri.Genshin/commit/d154b5bd)
|
||||
- 图鉴:武器图鉴草创 [`1c309e38`](https://github.com/BTMuli/Tauri.Genshin/commit/1c309e38)
|
||||
- 滚动条:样式美化 [`4022504`](https://github.com/BTMuli/Tauri.Genshin/commit/4022504)
|
||||
|
||||
### Fix
|
||||
|
||||
- 应用:修复初始化未重新加载资源的问题 [`513be2e`](https://BTMuli/Tauri.Genshin/commit/513be2e)
|
||||
- 应用:修复初始化未重新加载资源的问题 [`513be2e`](https://github.com/BTMuli/Tauri.Genshin/commit/513be2e)
|
||||
- 应用:除成就数据外的 `readonly` 数据直接读取应用内 `json` 文件
|
||||
- 应用:添加游戏新版本资源
|
||||
- GCG:相关资源归到 `WIKI` 下
|
||||
- 首页:素材日历资源采用 WIKI 资源
|
||||
|
||||
FullCommits: [`v0.1.2 ~ v0.1.3`](https://BTMuli/Tauri.Genshin/compare/v0.1.2...v0.1.3)
|
||||
FullCommits: [`v0.1.2 ~ v0.1.3`](https://github.com/BTMuli/Tauri.Genshin/compare/v0.1.2...v0.1.3)
|
||||
|
||||
## [0.1.2](https://github.com/BTMuli/Tauri.Genshin/releases/v0.1.2) (2023-04-12)
|
||||
|
||||
|
||||
38
README.md
38
README.md
@@ -2,12 +2,12 @@
|
||||
Author: 目棃
|
||||
Date: 2023-03-05
|
||||
Description: 说明文档
|
||||
Update: 2023-04-23
|
||||
Update: 2023-05-01
|
||||
---
|
||||
|
||||
> 本文档 [`Front-matter`](https://github.com/BTMuli/Mucli#FrontMatter) 由 [MuCli](https://github.com/BTMuli/Mucli) 自动生成于`2023-03-05 14:41:55`
|
||||
>
|
||||
> 更新于 `2023-04-23 12:55:01`
|
||||
> 更新于 `2023-05-01 21:51:54`
|
||||
|
||||
   
|
||||
|
||||
@@ -22,13 +22,13 @@ Tauri 练手项目
|
||||
|
||||
## 技术栈
|
||||
|
||||
- [Tauri](https://tauri.studio/zh-CN/)
|
||||
- [Vue3](https://v3.cn.vuejs.org/)
|
||||
- [Vite](https://cn.vitejs.dev/)
|
||||
- [TypeScript](https://www.typescriptlang.org/)
|
||||
- [Vuetify](https://vuetifyjs.com/en/)
|
||||
- [Tauri](https://github.com/tauri-apps/tauri)
|
||||
- [Vue3](https://github.com/vuejs/core)
|
||||
- [Vite](https://github.com/vitejs/vite)
|
||||
- [TypeScript](https://github.com/microsoft/TypeScript)
|
||||
- [Vuetify](https://github.com/vuetifyjs/vuetify)
|
||||
|
||||
## 当前进度(v0.1.3 Alpha)
|
||||
## 当前进度
|
||||
|
||||
> 以下进度仅为开发进度,不代表最终版本
|
||||
|
||||
@@ -45,9 +45,17 @@ Tauri 练手项目
|
||||
### 计划中
|
||||
|
||||
- [ ] UIGF 祈愿数据导入导出&展示
|
||||
- [ ] Wiki 详情页
|
||||
- [ ] 游戏数据获取
|
||||
|
||||
### 长期计划
|
||||
|
||||
- [ ] Wiki 详情页
|
||||
- [ ] 游戏资源更新
|
||||
|
||||
## 仓库概况
|
||||
|
||||

|
||||
|
||||
## UI 参考
|
||||
|
||||
- [Snap.Hutao](https://github.com/DGP-Studio/Snap.Hutao)
|
||||
@@ -73,14 +81,14 @@ npm run dev
|
||||
npm run build
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
项目基于 [MIT](LICENSE) 协议开源。
|
||||
|
||||
应用版本号遵循 [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/) 规范。
|
||||
|
||||
# Contributors
|
||||
|
||||
- [BTMuli](https://github.com/BTMuli)
|
||||
- [舰队的偶像岛风酱!](https://github.com/frg2089)
|
||||
- [jerry765](https://github.com/jerry765)
|
||||
|
||||
# License
|
||||
|
||||
项目基于 [MIT](LICENSE) 协议开源。
|
||||
|
||||
应用版本号遵循 [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/) 规范。
|
||||
|
||||
@@ -13,6 +13,8 @@ Update: 2023-04-23
|
||||
|
||||
本文档用于说明项目原始资源来源。
|
||||
|
||||
相关仓库:[TGAssistant](https://github.com/BTMuli/TGAssistant)。
|
||||
|
||||
> 如下 JSON 均经过处理,并未直接作为项目 JSON 数据使用。
|
||||
>
|
||||
> 如下图像均经过 Sharp 处理转换为 webp 格式,并未直接作为项目图像资源使用。
|
||||
|
||||
258
package-lock.json
generated
258
package-lock.json
generated
@@ -1,19 +1,20 @@
|
||||
{
|
||||
"name": "tauri-genshin",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "tauri-genshin",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@mdi/font": "7.2.96",
|
||||
"@tauri-apps/api": "^1.2.0",
|
||||
"clipboard": "^2.0.11",
|
||||
"pinia": "^2.0.33",
|
||||
"pinia": "^2.0.35",
|
||||
"pinia-plugin-persistedstate": "^3.1.0",
|
||||
"tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql",
|
||||
"vue": "^3.2.47",
|
||||
"vue-json-viewer": "^3.0.4",
|
||||
"vue-router": "^4.1.6",
|
||||
@@ -21,26 +22,26 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^1.2.3",
|
||||
"@types/node": "^18.15.11",
|
||||
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
||||
"@typescript-eslint/parser": "^5.57.1",
|
||||
"@types/node": "^18.16.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.0",
|
||||
"@typescript-eslint/parser": "^5.59.0",
|
||||
"@vitejs/plugin-vue": "^4.1.0",
|
||||
"@vue/devtools": "^6.5.0",
|
||||
"concurrently": "^8.0.1",
|
||||
"eslint": "^8.37.0",
|
||||
"eslint": "^8.39.0",
|
||||
"eslint-config-standard-with-typescript": "^34.0.1",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-n": "^15.7.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-vue": "^9.10.0",
|
||||
"prettier": "2.8.7",
|
||||
"stylelint": "^15.4.0",
|
||||
"eslint-plugin-vue": "^9.11.0",
|
||||
"prettier": "2.8.8",
|
||||
"stylelint": "^15.6.0",
|
||||
"stylelint-config-standard-vue": "^1.0.0",
|
||||
"stylelint-declaration-block-no-ignored-properties": "^2.7.0",
|
||||
"stylelint-high-performance-animation": "^1.8.0",
|
||||
"stylelint-order": "^6.0.3",
|
||||
"typescript": "^5.0.3",
|
||||
"vite": "^4.2.1",
|
||||
"typescript": "^5.0.4",
|
||||
"vite": "^4.3.1",
|
||||
"vite-plugin-vuetify": "^1.0.2"
|
||||
}
|
||||
},
|
||||
@@ -162,37 +163,37 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/css-parser-algorithms": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.1.0.tgz",
|
||||
"integrity": "sha512-KP8TicdXpUyeB1NMlbHud/1l39xvLGvqNFWMpG4qC6H1zs9SadGUHe5SO92n/659sDW9aGDvm9AMru0DZkN1Bw==",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.1.1.tgz",
|
||||
"integrity": "sha512-viRnRh02AgO4mwIQb2xQNJju0i+Fh9roNgmbR5xEuG7J3TGgxjnE95HnBLgsFJOJOksvcfxOUCgODcft6Y07cA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^14 || ^16 || >=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@csstools/css-tokenizer": "^2.0.0"
|
||||
"@csstools/css-tokenizer": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/css-tokenizer": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@csstools/css-tokenizer/-/css-tokenizer-2.1.0.tgz",
|
||||
"integrity": "sha512-dtqFyoJBHUxGi9zPZdpCKP1xk8tq6KPHJ/NY4qWXiYo6IcSGwzk3L8x2XzZbbyOyBs9xQARoGveU2AsgLj6D2A==",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz",
|
||||
"integrity": "sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^14 || ^16 || >=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/media-query-list-parser": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.2.tgz",
|
||||
"integrity": "sha512-8V6JD8Av1HttuClYr1ZBu0LRVe5Nnz4qrv8RppO8mobsX/USBHZy5JQOXYIlpOVhl46nzkx3X5cfH6CqUghjrQ==",
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.4.tgz",
|
||||
"integrity": "sha512-GyYot6jHgcSDZZ+tLSnrzkR7aJhF2ZW6d+CXH66mjy5WpAQhZD4HDke2OQ36SivGRWlZJpAz7TzbW6OKlEpxAA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^14 || ^16 || >=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@csstools/css-parser-algorithms": "^2.0.0",
|
||||
"@csstools/css-tokenizer": "^2.0.0"
|
||||
"@csstools/css-parser-algorithms": "^2.1.1",
|
||||
"@csstools/css-tokenizer": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/selector-specificity": {
|
||||
@@ -604,9 +605,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "8.37.0",
|
||||
"resolved": "https://registry.npmmirror.com/@eslint/js/-/js-8.37.0.tgz",
|
||||
"integrity": "sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==",
|
||||
"version": "8.39.0",
|
||||
"resolved": "https://registry.npmmirror.com/@eslint/js/-/js-8.39.0.tgz",
|
||||
"integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
@@ -919,9 +920,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.15.11",
|
||||
"resolved": "https://registry.npmmirror.com/@types/node/-/node-18.15.11.tgz",
|
||||
"integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==",
|
||||
"version": "18.16.0",
|
||||
"resolved": "https://registry.npmmirror.com/@types/node/-/node-18.16.0.tgz",
|
||||
"integrity": "sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ==",
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/@types/normalize-package-data": {
|
||||
@@ -947,15 +948,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "5.57.1",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.57.1.tgz",
|
||||
"integrity": "sha512-1MeobQkQ9tztuleT3v72XmY0XuKXVXusAhryoLuU5YZ+mXoYKZP9SQ7Flulh1NX4DTjpGTc2b/eMu4u7M7dhnQ==",
|
||||
"version": "5.59.0",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.0.tgz",
|
||||
"integrity": "sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.4.0",
|
||||
"@typescript-eslint/scope-manager": "5.57.1",
|
||||
"@typescript-eslint/type-utils": "5.57.1",
|
||||
"@typescript-eslint/utils": "5.57.1",
|
||||
"@typescript-eslint/scope-manager": "5.59.0",
|
||||
"@typescript-eslint/type-utils": "5.59.0",
|
||||
"@typescript-eslint/utils": "5.59.0",
|
||||
"debug": "^4.3.4",
|
||||
"grapheme-splitter": "^1.0.4",
|
||||
"ignore": "^5.2.0",
|
||||
@@ -992,14 +993,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "5.57.1",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-5.57.1.tgz",
|
||||
"integrity": "sha512-hlA0BLeVSA/wBPKdPGxoVr9Pp6GutGoY380FEhbVi0Ph4WNe8kLvqIRx76RSQt1lynZKfrXKs0/XeEk4zZycuA==",
|
||||
"version": "5.59.0",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-5.59.0.tgz",
|
||||
"integrity": "sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "5.57.1",
|
||||
"@typescript-eslint/types": "5.57.1",
|
||||
"@typescript-eslint/typescript-estree": "5.57.1",
|
||||
"@typescript-eslint/scope-manager": "5.59.0",
|
||||
"@typescript-eslint/types": "5.59.0",
|
||||
"@typescript-eslint/typescript-estree": "5.59.0",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
@@ -1015,26 +1016,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "5.57.1",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-5.57.1.tgz",
|
||||
"integrity": "sha512-N/RrBwEUKMIYxSKl0oDK5sFVHd6VI7p9K5MyUlVYAY6dyNb/wHUqndkTd3XhpGlXgnQsBkRZuu4f9kAHghvgPw==",
|
||||
"version": "5.59.0",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.0.tgz",
|
||||
"integrity": "sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.57.1",
|
||||
"@typescript-eslint/visitor-keys": "5.57.1"
|
||||
"@typescript-eslint/types": "5.59.0",
|
||||
"@typescript-eslint/visitor-keys": "5.59.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "5.57.1",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-5.57.1.tgz",
|
||||
"integrity": "sha512-/RIPQyx60Pt6ga86hKXesXkJ2WOS4UemFrmmq/7eOyiYjYv/MUSHPlkhU6k9T9W1ytnTJueqASW+wOmW4KrViw==",
|
||||
"version": "5.59.0",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-5.59.0.tgz",
|
||||
"integrity": "sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/typescript-estree": "5.57.1",
|
||||
"@typescript-eslint/utils": "5.57.1",
|
||||
"@typescript-eslint/typescript-estree": "5.59.0",
|
||||
"@typescript-eslint/utils": "5.59.0",
|
||||
"debug": "^4.3.4",
|
||||
"tsutils": "^3.21.0"
|
||||
},
|
||||
@@ -1051,22 +1052,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "5.57.1",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-5.57.1.tgz",
|
||||
"integrity": "sha512-bSs4LOgyV3bJ08F5RDqO2KXqg3WAdwHCu06zOqcQ6vqbTJizyBhuh1o1ImC69X4bV2g1OJxbH71PJqiO7Y1RuA==",
|
||||
"version": "5.59.0",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-5.59.0.tgz",
|
||||
"integrity": "sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "5.57.1",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.57.1.tgz",
|
||||
"integrity": "sha512-A2MZqD8gNT0qHKbk2wRspg7cHbCDCk2tcqt6ScCFLr5Ru8cn+TCfM786DjPhqwseiS+PrYwcXht5ztpEQ6TFTw==",
|
||||
"version": "5.59.0",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz",
|
||||
"integrity": "sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.57.1",
|
||||
"@typescript-eslint/visitor-keys": "5.57.1",
|
||||
"@typescript-eslint/types": "5.59.0",
|
||||
"@typescript-eslint/visitor-keys": "5.59.0",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
@@ -1083,9 +1084,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
|
||||
"version": "7.3.8",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz",
|
||||
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.5.0.tgz",
|
||||
"integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
@@ -1098,17 +1099,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "5.57.1",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-5.57.1.tgz",
|
||||
"integrity": "sha512-kN6vzzf9NkEtawECqze6v99LtmDiUJCVpvieTFA1uL7/jDghiJGubGZ5csicYHU1Xoqb3oH/R5cN5df6W41Nfg==",
|
||||
"version": "5.59.0",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-5.59.0.tgz",
|
||||
"integrity": "sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@types/semver": "^7.3.12",
|
||||
"@typescript-eslint/scope-manager": "5.57.1",
|
||||
"@typescript-eslint/types": "5.57.1",
|
||||
"@typescript-eslint/typescript-estree": "5.57.1",
|
||||
"@typescript-eslint/scope-manager": "5.59.0",
|
||||
"@typescript-eslint/types": "5.59.0",
|
||||
"@typescript-eslint/typescript-estree": "5.59.0",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"semver": "^7.3.7"
|
||||
},
|
||||
@@ -1142,9 +1143,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils/node_modules/semver": {
|
||||
"version": "7.3.8",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz",
|
||||
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.5.0.tgz",
|
||||
"integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
@@ -1157,12 +1158,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "5.57.1",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.57.1.tgz",
|
||||
"integrity": "sha512-RjQrAniDU0CEk5r7iphkm731zKlFiUjvcBS2yHAg8WWqFMCaCrD0rKEVOMUyMMcbGPZ0bPp56srkGWrgfZqLRA==",
|
||||
"version": "5.59.0",
|
||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz",
|
||||
"integrity": "sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.57.1",
|
||||
"@typescript-eslint/types": "5.59.0",
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2464,15 +2465,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "8.37.0",
|
||||
"resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.37.0.tgz",
|
||||
"integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==",
|
||||
"version": "8.39.0",
|
||||
"resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.39.0.tgz",
|
||||
"integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.4.0",
|
||||
"@eslint/eslintrc": "^2.0.2",
|
||||
"@eslint/js": "8.37.0",
|
||||
"@eslint/js": "8.39.0",
|
||||
"@humanwhocodes/config-array": "^0.11.8",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@nodelib/fs.walk": "^1.2.8",
|
||||
@@ -2482,7 +2483,7 @@
|
||||
"debug": "^4.3.2",
|
||||
"doctrine": "^3.0.0",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"eslint-scope": "^7.1.1",
|
||||
"eslint-scope": "^7.2.0",
|
||||
"eslint-visitor-keys": "^3.4.0",
|
||||
"espree": "^9.5.1",
|
||||
"esquery": "^1.4.2",
|
||||
@@ -2730,9 +2731,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-vue": {
|
||||
"version": "9.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.10.0.tgz",
|
||||
"integrity": "sha512-2MgP31OBf8YilUvtakdVMc8xVbcMp7z7/iQj8LHVpXrSXHPXSJRUIGSPFI6b6pyCx/buKaFJ45ycqfHvQRiW2g==",
|
||||
"version": "9.11.0",
|
||||
"resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.11.0.tgz",
|
||||
"integrity": "sha512-bBCJAZnkBV7ATH4Z1E7CvN3nmtS4H7QUU3UBxPdo8WohRU+yHjnQRALpTbxMVcz0e4Mx3IyxIdP5HYODMxK9cQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.3.0",
|
||||
@@ -2766,9 +2767,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.1.1.tgz",
|
||||
"integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.0.tgz",
|
||||
"integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esrecurse": "^4.3.0",
|
||||
@@ -3247,7 +3248,7 @@
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/function.prototype.name": {
|
||||
"version": "1.1.5",
|
||||
@@ -3555,7 +3556,7 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1"
|
||||
},
|
||||
@@ -3837,7 +3838,7 @@
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz",
|
||||
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
@@ -4410,9 +4411,9 @@
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.4.tgz",
|
||||
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
@@ -4723,7 +4724,7 @@
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
@@ -4771,9 +4772,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/pinia": {
|
||||
"version": "2.0.33",
|
||||
"resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.0.33.tgz",
|
||||
"integrity": "sha512-HOj1yVV2itw6rNIrR2f7+MirGNxhORjrULL8GWgRwXsGSvEqIQ+SE0MYt6cwtpegzCda3i+rVTZM+AM7CG+kRg==",
|
||||
"version": "2.0.35",
|
||||
"resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.0.35.tgz",
|
||||
"integrity": "sha512-P1IKKQWhxGXiiZ3atOaNI75bYlFUbRxtJdhPLX059Z7+b9Z04rnTZdSY8Aph1LA+/4QEMAYHsTQ638Wfe+6K5g==",
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^6.5.0",
|
||||
"vue-demi": "*"
|
||||
@@ -4835,11 +4836,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.21",
|
||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.21.tgz",
|
||||
"integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
|
||||
"version": "8.4.23",
|
||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.23.tgz",
|
||||
"integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.4",
|
||||
"nanoid": "^3.3.6",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
@@ -4941,9 +4942,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.8.7",
|
||||
"resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.8.7.tgz",
|
||||
"integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==",
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.8.8.tgz",
|
||||
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
@@ -5183,7 +5184,7 @@
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz",
|
||||
"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.9.0",
|
||||
"path-parse": "^1.0.7",
|
||||
@@ -5252,9 +5253,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "3.18.0",
|
||||
"resolved": "https://registry.npmmirror.com/rollup/-/rollup-3.18.0.tgz",
|
||||
"integrity": "sha512-J8C6VfEBjkvYPESMQYxKHxNOh4A5a3FlP+0BETGo34HEcE4eTlgCrO2+eWzlu2a/sHs2QUkZco+wscH7jhhgWg==",
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmmirror.com/rollup/-/rollup-3.21.0.tgz",
|
||||
"integrity": "sha512-ANPhVcyeHvYdQMUyCbczy33nbLzI7RzrBje4uvNiTDJGIMtlKoOStmympwr9OtS1LZxiDmE2wvxHyVhoLtf1KQ==",
|
||||
"devOptional": true,
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
@@ -5741,14 +5742,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/stylelint": {
|
||||
"version": "15.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/stylelint/-/stylelint-15.4.0.tgz",
|
||||
"integrity": "sha512-TlOvpG3MbcFwHmK0q2ykhmpKo7Dq892beJit0NPdpyY9b1tFah/hGhqnAz/bRm2PDhDbJLKvjzkEYYBEz7Dxcg==",
|
||||
"version": "15.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/stylelint/-/stylelint-15.6.0.tgz",
|
||||
"integrity": "sha512-Cqzpc8tvJm77KaM8qUbhpJ/UYK55Ia0whQXj4b9IId9dlPICO7J8Lyo15SZWiHxKjlvy3p5FQor/3n6i8ignXg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@csstools/css-parser-algorithms": "^2.1.0",
|
||||
"@csstools/css-tokenizer": "^2.1.0",
|
||||
"@csstools/media-query-list-parser": "^2.0.1",
|
||||
"@csstools/css-parser-algorithms": "^2.1.1",
|
||||
"@csstools/css-tokenizer": "^2.1.1",
|
||||
"@csstools/media-query-list-parser": "^2.0.4",
|
||||
"@csstools/selector-specificity": "^2.2.0",
|
||||
"balanced-match": "^2.0.0",
|
||||
"colord": "^2.9.3",
|
||||
@@ -5762,7 +5763,7 @@
|
||||
"global-modules": "^2.0.0",
|
||||
"globby": "^11.1.0",
|
||||
"globjoin": "^0.1.4",
|
||||
"html-tags": "^3.2.0",
|
||||
"html-tags": "^3.3.1",
|
||||
"ignore": "^5.2.4",
|
||||
"import-lazy": "^4.0.0",
|
||||
"imurmurhash": "^0.1.4",
|
||||
@@ -5773,7 +5774,7 @@
|
||||
"micromatch": "^4.0.5",
|
||||
"normalize-path": "^3.0.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"postcss": "^8.4.21",
|
||||
"postcss": "^8.4.22",
|
||||
"postcss-media-query-parser": "^0.2.3",
|
||||
"postcss-resolve-nested-selector": "^0.1.1",
|
||||
"postcss-safe-parser": "^6.0.0",
|
||||
@@ -5974,7 +5975,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
@@ -6019,6 +6020,14 @@
|
||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tauri-plugin-sql-api": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "git+ssh://git@github.com/tauri-apps/tauri-plugin-sql.git#62b21ef24303d80e9905f57b2b6d27efc8677c23",
|
||||
"license": "MIT or APACHE-2.0",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
|
||||
@@ -6167,9 +6176,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.0.3.tgz",
|
||||
"integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==",
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.0.4.tgz",
|
||||
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
|
||||
"devOptional": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
@@ -6294,15 +6303,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/vite/-/vite-4.2.1.tgz",
|
||||
"integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==",
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/vite/-/vite-4.3.1.tgz",
|
||||
"integrity": "sha512-EPmfPLAI79Z/RofuMvkIS0Yr091T2ReUoXQqc5ppBX/sjFRhHKiPPF/R46cTdoci/XgeQpB23diiJxq5w30vdg==",
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.17.5",
|
||||
"postcss": "^8.4.21",
|
||||
"resolve": "^1.22.1",
|
||||
"rollup": "^3.18.0"
|
||||
"rollup": "^3.20.2"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
|
||||
24
package.json
24
package.json
@@ -2,7 +2,7 @@
|
||||
"name": "tauri-genshin",
|
||||
"description": "A Tauri App Demo",
|
||||
"private": true,
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"author": "BTMuli <bt-muli@outlook.com>",
|
||||
"scripts": {
|
||||
"lint": "concurrently \"npm:lint:*(!fix)\"",
|
||||
@@ -16,6 +16,7 @@
|
||||
"vite:dev": "vite dev",
|
||||
"vite:build": "vite build",
|
||||
"build": "tauri build",
|
||||
"debug": "tauri build --debug",
|
||||
"preview": "vite preview",
|
||||
"tauri": "tauri"
|
||||
},
|
||||
@@ -43,8 +44,9 @@
|
||||
"@mdi/font": "7.2.96",
|
||||
"@tauri-apps/api": "^1.2.0",
|
||||
"clipboard": "^2.0.11",
|
||||
"pinia": "^2.0.33",
|
||||
"pinia": "^2.0.35",
|
||||
"pinia-plugin-persistedstate": "^3.1.0",
|
||||
"tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql",
|
||||
"vue": "^3.2.47",
|
||||
"vue-json-viewer": "^3.0.4",
|
||||
"vue-router": "^4.1.6",
|
||||
@@ -52,26 +54,26 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^1.2.3",
|
||||
"@types/node": "^18.15.11",
|
||||
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
||||
"@typescript-eslint/parser": "^5.57.1",
|
||||
"@types/node": "^18.16.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.0",
|
||||
"@typescript-eslint/parser": "^5.59.0",
|
||||
"@vitejs/plugin-vue": "^4.1.0",
|
||||
"@vue/devtools": "^6.5.0",
|
||||
"concurrently": "^8.0.1",
|
||||
"eslint": "^8.37.0",
|
||||
"eslint": "^8.39.0",
|
||||
"eslint-config-standard-with-typescript": "^34.0.1",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-n": "^15.7.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-vue": "^9.10.0",
|
||||
"prettier": "2.8.7",
|
||||
"stylelint": "^15.4.0",
|
||||
"eslint-plugin-vue": "^9.11.0",
|
||||
"prettier": "2.8.8",
|
||||
"stylelint": "^15.6.0",
|
||||
"stylelint-config-standard-vue": "^1.0.0",
|
||||
"stylelint-declaration-block-no-ignored-properties": "^2.7.0",
|
||||
"stylelint-high-performance-animation": "^1.8.0",
|
||||
"stylelint-order": "^6.0.3",
|
||||
"typescript": "^5.0.3",
|
||||
"vite": "^4.2.1",
|
||||
"typescript": "^5.0.4",
|
||||
"vite": "^4.3.1",
|
||||
"vite-plugin-vuetify": "^1.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 32 KiB |
440
src-tauri/Cargo.lock
generated
440
src-tauri/Cargo.lock
generated
@@ -8,6 +8,17 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||
dependencies = [
|
||||
"getrandom 0.2.8",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.20"
|
||||
@@ -95,6 +106,15 @@ dependencies = [
|
||||
"system-deps 6.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atoi"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic"
|
||||
version = "0.5.1"
|
||||
@@ -420,6 +440,21 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
|
||||
dependencies = [
|
||||
"crc-catalog",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc-catalog"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
@@ -439,6 +474,16 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.15"
|
||||
@@ -630,6 +675,12 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
|
||||
|
||||
[[package]]
|
||||
name = "dotenvy"
|
||||
version = "0.15.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.4.8"
|
||||
@@ -704,6 +755,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.9.0"
|
||||
@@ -759,6 +816,18 @@ dependencies = [
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.10.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project",
|
||||
"spin 0.9.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@@ -840,6 +909,17 @@ dependencies = [
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-intrusive"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"lock_api",
|
||||
"parking_lot 0.11.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.28"
|
||||
@@ -1197,6 +1277,18 @@ name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
@@ -1212,6 +1304,9 @@ name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
@@ -1228,6 +1323,12 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "html5ever"
|
||||
version = "0.25.2"
|
||||
@@ -1420,6 +1521,15 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
@@ -1528,6 +1638,17 @@ dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "line-wrap"
|
||||
version = "0.1.1"
|
||||
@@ -1661,6 +1782,18 @@ version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "minisign-verify"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "933dca44d65cdd53b355d0b73d380a2ff5da71f87f036053188bf1eab6a19881"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.6.2"
|
||||
@@ -1696,7 +1829,7 @@ dependencies = [
|
||||
"log",
|
||||
"memchr",
|
||||
"mime",
|
||||
"spin",
|
||||
"spin 0.9.8",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"version_check",
|
||||
@@ -1760,6 +1893,16 @@ version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify-rust"
|
||||
version = "4.8.0"
|
||||
@@ -1995,6 +2138,17 @@ dependencies = [
|
||||
"system-deps 6.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core 0.8.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
@@ -2002,7 +2156,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
"parking_lot_core 0.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2157,6 +2325,26 @@ dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
@@ -2482,6 +2670,21 @@ dependencies = [
|
||||
"windows 0.37.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin 0.5.2",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rocket"
|
||||
version = "0.5.0-rc.3"
|
||||
@@ -2502,7 +2705,7 @@ dependencies = [
|
||||
"memchr",
|
||||
"multer",
|
||||
"num_cpus",
|
||||
"parking_lot",
|
||||
"parking_lot 0.12.1",
|
||||
"pin-project-lite",
|
||||
"rand 0.8.5",
|
||||
"ref-cast",
|
||||
@@ -2600,6 +2803,27 @@ dependencies = [
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.20.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring",
|
||||
"sct",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
|
||||
dependencies = [
|
||||
"base64 0.21.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.11"
|
||||
@@ -2648,6 +2872,16 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.8.2"
|
||||
@@ -2906,11 +3140,121 @@ dependencies = [
|
||||
"system-deps 5.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlformat"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"nom",
|
||||
"unicode_categories",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188"
|
||||
dependencies = [
|
||||
"sqlx-core",
|
||||
"sqlx-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-core"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"atoi",
|
||||
"bitflags 1.3.2",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"crc",
|
||||
"crossbeam-queue",
|
||||
"dotenvy",
|
||||
"either",
|
||||
"event-listener",
|
||||
"flume",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-intrusive",
|
||||
"futures-util",
|
||||
"hashlink",
|
||||
"hex",
|
||||
"indexmap",
|
||||
"itoa 1.0.6",
|
||||
"libc",
|
||||
"libsqlite3-sys",
|
||||
"log",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"percent-encoding",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
"sqlformat",
|
||||
"sqlx-rt",
|
||||
"stringprep",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio-stream",
|
||||
"url",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-macros"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9"
|
||||
dependencies = [
|
||||
"dotenvy",
|
||||
"either",
|
||||
"heck 0.4.1",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"sqlx-core",
|
||||
"sqlx-rt",
|
||||
"syn 1.0.109",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-rt"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable-pattern"
|
||||
@@ -2944,7 +3288,7 @@ checksum = "7d69e88b23f23030bf4d0e9ca7b07434f70e1c1f4d3ca7e93ce958b373654d9f"
|
||||
dependencies = [
|
||||
"new_debug_unreachable",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"parking_lot 0.12.1",
|
||||
"phf_shared 0.10.0",
|
||||
"precomputed-hash",
|
||||
"serde",
|
||||
@@ -2962,6 +3306,16 @@ dependencies = [
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stringprep"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
@@ -3070,7 +3424,7 @@ dependencies = [
|
||||
"ndk-sys",
|
||||
"objc",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"parking_lot 0.12.1",
|
||||
"paste",
|
||||
"png",
|
||||
"raw-window-handle",
|
||||
@@ -3102,6 +3456,7 @@ checksum = "fe7e0f1d535e7cbbbab43c82be4fc992b84f9156c16c160955617e0260ebc449"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"attohttpc",
|
||||
"base64 0.13.1",
|
||||
"cocoa",
|
||||
"dirs-next",
|
||||
"embed_plist",
|
||||
@@ -3114,6 +3469,7 @@ dependencies = [
|
||||
"heck 0.4.1",
|
||||
"http",
|
||||
"ignore",
|
||||
"minisign-verify",
|
||||
"notify-rust",
|
||||
"objc",
|
||||
"once_cell",
|
||||
@@ -3139,12 +3495,14 @@ dependencies = [
|
||||
"tauri-utils",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
"url",
|
||||
"uuid 1.3.0",
|
||||
"webkit2gtk",
|
||||
"webview2-com",
|
||||
"windows 0.39.0",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3191,13 +3549,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-genshin"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
dependencies = [
|
||||
"rocket",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-sql",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3214,6 +3573,22 @@ dependencies = [
|
||||
"tauri-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-sql"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=dev#7acf865ffbb82c6d00334926a4527dd5ff3163a4"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"tauri",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime"
|
||||
version = "0.12.1"
|
||||
@@ -3425,6 +3800,17 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.23.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"tokio",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.12"
|
||||
@@ -3617,6 +4003,18 @@ version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode_categories"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.3.1"
|
||||
@@ -3836,6 +4234,25 @@ dependencies = [
|
||||
"system-deps 6.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.22.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
|
||||
dependencies = [
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webview2-com"
|
||||
version = "0.19.1"
|
||||
@@ -4271,3 +4688,14 @@ name = "yansi"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"crc32fast",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-genshin"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
description = "A Tauri App"
|
||||
authors = ["BTMuli<bt-muli@outlook.com>"]
|
||||
license = "MIT"
|
||||
@@ -14,10 +14,15 @@ tauri-build = { version = "1.2", features = [] }
|
||||
|
||||
[dependencies]
|
||||
rocket = "0.5.0-rc.1"
|
||||
tauri = { version = "1.2", features = ["api-all"] }
|
||||
tauri = { version = "1.2", features = ["api-all", "updater"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
[dependencies.tauri-plugin-sql]
|
||||
git = "https://github.com/tauri-apps/plugins-workspace"
|
||||
branch = "dev"
|
||||
features = ["sqlite"]
|
||||
|
||||
[features]
|
||||
# this feature is used for production builds or when `devPath` points to the filesystem
|
||||
# DO NOT REMOVE!!
|
||||
|
||||
@@ -74,6 +74,7 @@ fn read_cookie() -> String {
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_sql::Builder::default().build())
|
||||
.invoke_handler(tauri::generate_handler![mys_login, read_cookie])
|
||||
.setup(|_app| {
|
||||
tauri::async_runtime::spawn(
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"package": {
|
||||
"productName": "tauri-genshin",
|
||||
"version": "0.1.3"
|
||||
"version": "0.1.4"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
@@ -52,7 +52,7 @@
|
||||
"active": true,
|
||||
"dialog": true,
|
||||
"endpoints": ["https://github.com/BTMuli/Tauri.Genshin/releases/latest/latest.json"],
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEU5OEE2RkU0QUZCMTMzMUEKUldRYU03R3Y1RytLNlI4bytTRDhpYTNTL2lTOUVZeWQwOTAxNHBock8zY3FrdVliR2kvdHhoN2IK"
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDg2MkVGRjMxQzJDQzFBNTkKUldSWkdzekNNZjh1aHJGRXBEOGtwbUxLaU1wdWNVeUJaeGhoV2ZlZ3VlYmQ0b2tYZWQwODdnTHkK"
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
|
||||
30
src/App.vue
30
src/App.vue
@@ -33,10 +33,6 @@ import TBackTop from "./components/t-backTop.vue";
|
||||
import { fs, window, app, event } from "@tauri-apps/api";
|
||||
// store
|
||||
import { useAppStore } from "./store/modules/app";
|
||||
// utils
|
||||
import { InitTGData, DeleteTGData, WriteTGData } from "./utils/TGIndex";
|
||||
// data
|
||||
import { TGAppDataList, TGGetDataList } from "./data";
|
||||
|
||||
const appStore = useAppStore();
|
||||
const isMain = ref(true as boolean);
|
||||
@@ -72,38 +68,18 @@ async function checkLoad () {
|
||||
console.info("数据已加载!");
|
||||
return;
|
||||
}
|
||||
DeleteTGData();
|
||||
await createDataDir();
|
||||
await writeData();
|
||||
await writeIndex();
|
||||
appStore.loading = true;
|
||||
console.info("数据加载完成!");
|
||||
}
|
||||
// 创建数据文件夹
|
||||
async function createDataDir () {
|
||||
console.info("开始创建数据文件夹...");
|
||||
await fs.createDir("appData", { dir: fs.BaseDirectory.AppLocalData, recursive: true });
|
||||
await fs.createDir("userData", { dir: fs.BaseDirectory.AppLocalData, recursive: true });
|
||||
await fs.createDir("tempData", { dir: fs.BaseDirectory.AppLocalData, recursive: true });
|
||||
// 如果不存在则创建
|
||||
if (!await fs.exists("userData", { dir: fs.BaseDirectory.AppLocalData })) { await fs.createDir("userData", { dir: fs.BaseDirectory.AppLocalData, recursive: true }); }
|
||||
if (!await fs.exists("tempData", { dir: fs.BaseDirectory.AppLocalData })) { await fs.createDir("tempData", { dir: fs.BaseDirectory.AppLocalData, recursive: true }); }
|
||||
console.info("数据文件夹创建完成!");
|
||||
}
|
||||
// 将数据写入文件夹
|
||||
async function writeData () {
|
||||
console.info("开始写入数据...");
|
||||
TGAppDataList.map(async (item) => {
|
||||
await fs.writeFile(`${appStore.dataPath.appDataDir}\\${item.name}`, JSON.stringify(item.data));
|
||||
});
|
||||
console.info("数据写入完成!");
|
||||
}
|
||||
// 写入 IndexedDB
|
||||
async function writeIndex () {
|
||||
console.info("开始写入 IndexedDB...");
|
||||
await InitTGData();
|
||||
TGGetDataList.map(async (item) => {
|
||||
await WriteTGData(item.name, item.data);
|
||||
});
|
||||
console.info("IndexedDB 写入完成!");
|
||||
}
|
||||
</script>
|
||||
<style lang="css">
|
||||
.app-main {
|
||||
|
||||
@@ -2,24 +2,30 @@
|
||||
@import url("themes/default.css");
|
||||
@import url("themes/dark.css");
|
||||
|
||||
/*
|
||||
* @description 让滚动条在内侧显示
|
||||
* @since Alpha v0.1.0
|
||||
*/
|
||||
html {
|
||||
overflow: overlay;
|
||||
}
|
||||
/*
|
||||
* @description 侧边滚动条样式
|
||||
* @since Alpha v0.1.3
|
||||
*/
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 10px;
|
||||
width: 8px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 10px;
|
||||
background: var(--scroll-bg);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #888;
|
||||
border-radius: 10px;
|
||||
background: #96979A;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file assets themes light.css
|
||||
* @description 主题样式文件
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.3
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
/* 主题色 */
|
||||
@@ -10,6 +10,8 @@ html.dark {
|
||||
--sidebar-bg: #1e1e1e;
|
||||
--sidebar-icon: #e1e1e1;
|
||||
--page-bg:#2a2a2a;
|
||||
--scroll-bg: #ECE5D8;
|
||||
--calendar-btn-bg: #1e1e1e;
|
||||
--back-top-shadow: #000000;
|
||||
--theme-switch-icon: #e1e1e1;
|
||||
--post-default-text: #faf7e8;
|
||||
@@ -22,7 +24,7 @@ html.dark {
|
||||
--content-text-3: #e1e1e1;
|
||||
|
||||
--btn-bg-1: #3b3d3b;
|
||||
--btn-bg-2: #000000;
|
||||
--btn-bg-2: #e1e1e1;
|
||||
--btn-bg-3: #1e1e1e;
|
||||
--btn-text-1: #393b40;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file assets themes dark.css
|
||||
* @description 主题样式文件
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.3
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
/* 主题色 */
|
||||
@@ -10,6 +10,8 @@ html.default {
|
||||
--sidebar-bg: #485466;
|
||||
--sidebar-icon: #ece5d8;
|
||||
--page-bg:#ece5d8;
|
||||
--scroll-bg: #2A2A2A;
|
||||
--calendar-btn-bg: #393b40;
|
||||
--back-top-shadow: #546d8b;
|
||||
--theme-switch-icon: #393b40;
|
||||
--post-default-text: #1e1e1e;
|
||||
|
||||
@@ -51,8 +51,8 @@ onMounted(() => {
|
||||
<style scoped>
|
||||
.back-top {
|
||||
position: fixed;
|
||||
right: 0.4rem;
|
||||
bottom: 1rem;
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
class="calendar-btn"
|
||||
:style="{
|
||||
border: text.week === weekNow ? '2px solid var(--btn-bg-1)' : '0',
|
||||
background: text.week === btnNow ? 'var(--btn-bg-1)' : 'var(--btn-bg-2)',
|
||||
color: '#faf7e8'
|
||||
background: text.week === btnNow ? 'var(--btn-bg-1)' : 'var(--calendar-btn-bg)',
|
||||
color: '#faf7e8',
|
||||
marginBottom: '1px'
|
||||
}"
|
||||
@click="getContents(text.week)"
|
||||
>
|
||||
@@ -102,7 +103,6 @@
|
||||
<div
|
||||
v-for="item of weapon.contents"
|
||||
:key="item.id"
|
||||
alt="content.content_id"
|
||||
class="card-box"
|
||||
@click="showContent(item)"
|
||||
>
|
||||
@@ -138,7 +138,7 @@
|
||||
// vue
|
||||
import { ref, onMounted } from "vue";
|
||||
// data
|
||||
import { TGAppData } from "../data/index";
|
||||
import { TGAppData } from "../data";
|
||||
// interface
|
||||
import { OBC_CONTENT_API } from "../plugins/Mys/interface/utils";
|
||||
import { createTGWindow } from "../utils/TGWindow";
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
<div class="confirm-title">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div v-show="subtitle!==''" class="confirm-subtitle">
|
||||
{{ subtitle }}
|
||||
</div>
|
||||
<div class="confirm-btn-box">
|
||||
<button class="confirm-btn" @click="onCancel">
|
||||
<img class="btn-icon" src="../assets/icons/circle-cancel.svg" alt="cancel">
|
||||
@@ -30,6 +33,7 @@ import { computed } from "vue";
|
||||
|
||||
interface TConfirmProps {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
cancel?: string;
|
||||
confirm?: string;
|
||||
/** 此值为 true 时显示对话框 */
|
||||
@@ -46,6 +50,7 @@ interface TConfirmEmits {
|
||||
const emits = defineEmits<TConfirmEmits>();
|
||||
const props = withDefaults(defineProps<TConfirmProps>(), {
|
||||
title: "确认",
|
||||
subtitle: "",
|
||||
cancel: "取消",
|
||||
confirm: "确定",
|
||||
});
|
||||
@@ -93,12 +98,24 @@ const onConfirm = () => {
|
||||
height: 20%;
|
||||
width: 100%;
|
||||
color: var(--content-text-2);
|
||||
margin: 20px;
|
||||
margin: 10px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.confirm-subtitle {
|
||||
border-top: 1px solid var(--btn-bg-2);
|
||||
font-family: Genshin-Light, serif;
|
||||
text-align: center;
|
||||
height: 20%;
|
||||
width: 100%;
|
||||
color: var(--content-text-2);
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.confirm-btn-box {
|
||||
height: 60%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 40%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
<v-list style="background: var(--content-bg-2); color: #546d8b">
|
||||
<v-list-item :title="pool.title" :subtitle="pool.subtitle">
|
||||
<template #prepend>
|
||||
<v-img :src="pool.voice.icon" style="transform: translate(0, -10px); width: 60px; height: 60px" />
|
||||
<v-img :src="pool.voice.icon" class="pool-sideIcon" />
|
||||
</template>
|
||||
<template #append>
|
||||
<template v-if="pool.voice.url" #append>
|
||||
<audio :src="pool.voice.url" controls />
|
||||
</template>
|
||||
</v-list-item>
|
||||
@@ -29,7 +29,7 @@
|
||||
<img :src="character.icon" class="pool-icon" alt="character">
|
||||
</div>
|
||||
<div class="pool-clock">
|
||||
<v-progress-circular :model-value="poolTimePass[pool.post_id]" size="100" width="10" :color="poolColor">
|
||||
<v-progress-circular :model-value="poolTimePass[pool.post_id]" size="100" width="10" :color="poolColor[pool.post_id]">
|
||||
{{ poolTimeGet[pool.post_id] }}
|
||||
</v-progress-circular>
|
||||
</div>
|
||||
@@ -47,8 +47,10 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { ref, onMounted, onUpdated } from "vue";
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
// tauri
|
||||
import { dialog } from "@tauri-apps/api";
|
||||
// store
|
||||
import { useHomeStore } from "../store/modules/home";
|
||||
// utils
|
||||
@@ -71,37 +73,38 @@ const loading = ref(true as boolean);
|
||||
const poolCards = ref([] as GachaCard[]);
|
||||
const poolTimeGet = ref({} as Record<number, string>);
|
||||
const poolTimePass = ref({} as Record<number, number>);
|
||||
const poolColor = ref("#90caf9" as string);
|
||||
const timer = ref(null as any);
|
||||
const poolColor = ref({} as Record<number, string>);
|
||||
const timer = ref({} as Record<number, any>);
|
||||
// expose
|
||||
defineExpose({
|
||||
name: "限时祈愿",
|
||||
loading,
|
||||
});
|
||||
|
||||
function poolLastInterval () {
|
||||
poolCards.value.map((pool) => {
|
||||
poolTimeGet.value[pool.post_id] = getLastPoolTime(pool.time.end_stamp - Date.now());
|
||||
poolTimePass.value[pool.post_id] =
|
||||
function poolLastInterval (postId: number) {
|
||||
const pool = poolCards.value.find((pool) => pool.post_id === postId);
|
||||
if (!pool) return;
|
||||
if (poolTimeGet.value[postId] === "未开始") {
|
||||
const isStart = pool.time.start_stamp - Date.now();
|
||||
if (isStart > 0) return;
|
||||
poolTimeGet.value[postId] = getLastPoolTime(pool.time.end_stamp - Date.now());
|
||||
poolTimePass.value[postId] = pool.time.end_stamp - Date.now();
|
||||
poolColor.value[postId] = "#90caf9";
|
||||
} else {
|
||||
const isEnd = pool.time.end_stamp - Date.now();
|
||||
poolTimeGet.value[postId] = getLastPoolTime(isEnd);
|
||||
poolTimePass.value[postId] =
|
||||
((pool.time.end_stamp - Date.now()) / (pool.time.end_stamp - pool.time.start_stamp)) * 100;
|
||||
return pool;
|
||||
});
|
||||
if (isEnd >= 0) return;
|
||||
clearInterval(timer.value[postId]);
|
||||
timer.value[postId] = null;
|
||||
poolTimePass.value[postId] = 100;
|
||||
poolTimeGet.value[postId] = "已结束";
|
||||
poolColor.value[postId] = "#f44336";
|
||||
}
|
||||
return pool;
|
||||
}
|
||||
|
||||
// 监听 poolTimePass
|
||||
onUpdated(() => {
|
||||
poolCards.value.map((pool) => {
|
||||
if (poolTimePass.value[pool.post_id] <= 0) {
|
||||
clearInterval(timer.value);
|
||||
timer.value = null;
|
||||
poolTimeGet.value[pool.post_id] = "已结束";
|
||||
poolTimePass.value[pool.post_id] = 100;
|
||||
poolColor.value = "#f44336";
|
||||
}
|
||||
return pool;
|
||||
});
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const gachaData = await MysOper.Gacha.get();
|
||||
if (!gachaData) {
|
||||
@@ -122,11 +125,22 @@ onMounted(async () => {
|
||||
poolCards.value.map((pool) => {
|
||||
poolTimeGet.value[pool.post_id] = getLastPoolTime(pool.time.end_stamp - Date.now());
|
||||
poolTimePass.value[pool.post_id] = pool.time.end_stamp - Date.now();
|
||||
if (poolTimePass.value[pool.post_id] <= 0) {
|
||||
poolTimeGet.value[pool.post_id] = "已结束";
|
||||
poolTimePass.value[pool.post_id] = 100;
|
||||
poolColor.value[pool.post_id] = "#f44336";
|
||||
} else if (pool.time.start_stamp - Date.now() > 0) {
|
||||
poolTimeGet.value[pool.post_id] = "未开始";
|
||||
poolTimePass.value[pool.post_id] = 100;
|
||||
poolColor.value[pool.post_id] = "#32A9CA";
|
||||
} else {
|
||||
poolColor.value[pool.post_id] = "#90caf9";
|
||||
}
|
||||
timer.value[pool.post_id] = setInterval(() => {
|
||||
poolLastInterval(pool.post_id);
|
||||
}, 1000);
|
||||
return pool;
|
||||
});
|
||||
timer.value = setInterval(() => {
|
||||
poolLastInterval();
|
||||
}, 1000);
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
@@ -155,8 +169,15 @@ function checkCover (data: GachaData[]) {
|
||||
});
|
||||
}
|
||||
|
||||
function toOuter (url: string, title: string) {
|
||||
createTGWindow(url, "祈愿", title, 1200, 800, true, false);
|
||||
async function toOuter (url: string, title: string) {
|
||||
if (!url) {
|
||||
await dialog.message("该角色池暂无详情", {
|
||||
title,
|
||||
type: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
createTGWindow(url, "祈愿", title, 1200, 800, true, true);
|
||||
}
|
||||
|
||||
function getLastPoolTime (time: number) {
|
||||
@@ -176,6 +197,12 @@ function toPost (pool: GachaCard) {
|
||||
}).href;
|
||||
createTGWindow(path, "限时祈愿", pool.title, 960, 720, false, false);
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
Object.keys(timer.value).forEach((key) => {
|
||||
clearInterval(timer.value[Number(key)]);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
@@ -200,6 +227,20 @@ function toPost (pool: GachaCard) {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.pool-sideIcon {
|
||||
margin-top: 10px;
|
||||
transform: translate(0, -10px);
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.pool-sideIcon img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.pool-cover {
|
||||
margin: 0 20px 10px;
|
||||
width: calc(100% - 40px);
|
||||
|
||||
@@ -83,7 +83,7 @@ onMounted(async () => {
|
||||
positionTimeGet.value[card.post_id] = getLastPositionTime(card.time.end_stamp - Date.now());
|
||||
positionTimeEnd.value[card.post_id] = card.time.end_stamp;
|
||||
});
|
||||
await setInterval(() => {
|
||||
setInterval(() => {
|
||||
positionCards.value.forEach((card) => {
|
||||
const time = card.time.end_stamp - Date.now();
|
||||
if (time <= 0) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<v-navigation-drawer permanent :rail="rail" style="background: var(--sidebar-bg); color: #faf7e8">
|
||||
<v-list v-model:opened="open" class="side-list" density="compact" nav>
|
||||
<!-- 负责收缩侧边栏 -->
|
||||
<v-list-item @click="collapse">
|
||||
<v-list-item @click="collapse()">
|
||||
<template v-if="rail" #prepend>
|
||||
<v-list-item-action>
|
||||
<v-icon style="color:var(--sidebar-icon)">
|
||||
@@ -120,7 +120,7 @@
|
||||
<img :src="userInfo.avatar" alt="userIcon" class="side-icon">
|
||||
</template>
|
||||
</v-list-item> -->
|
||||
<v-list-item :title="themeTitle" value="theme" @click="switchTheme">
|
||||
<v-list-item :title="themeTitle" value="theme" @click="switchTheme()">
|
||||
<template #prepend>
|
||||
<v-icon style="color:var(--sidebar-icon)">
|
||||
{{ themeGet === 'default' ? 'mdi-weather-night' : 'mdi-weather-sunny' }}
|
||||
|
||||
@@ -1,507 +1,330 @@
|
||||
{
|
||||
"0": {
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"order": 1,
|
||||
"name": "天地万象",
|
||||
"version": "3.6",
|
||||
"achievements": [
|
||||
80091, 80127, 80128, 80129, 80142, 80143, 80144, 81000, 81001, 81002, 81003, 81004, 81005, 81010, 81014, 81015,
|
||||
81016, 81017, 81018, 81019, 81020, 81021, 81022, 81023, 81024, 81025, 80092, 81026, 81027, 81028, 81029, 81030,
|
||||
81031, 81032, 81033, 81034, 81035, 81036, 81037, 81038, 81039, 81040, 81041, 81042, 81043, 81044, 81045, 81046,
|
||||
81047, 81048, 81074, 81075, 81076, 81077, 81078, 81096, 81097, 81098, 81099, 81100, 81104, 81105, 81106, 81108,
|
||||
81109, 81111, 81112, 81113, 81114, 81115, 81116, 81117, 81118, 81119, 81120, 81121, 81122, 81123, 81124, 81125,
|
||||
81130, 81141, 81142, 81150, 81151, 81152, 81153, 81154, 81155, 81156, 81157, 81158, 81159, 81160, 81161, 81162,
|
||||
81163, 81164, 81165, 81167, 81168, 81170, 81171, 81172, 81173, 81174, 81175, 81176, 81177, 81179, 81180, 81181,
|
||||
81182, 81183, 81184, 81185, 81186, 81187, 81188, 81189, 81191, 81192, 81193, 81194, 81195, 81196, 81197, 81198,
|
||||
81199, 81200, 81201, 81202, 81203, 81204, 81205, 81206, 81207, 81208, 81209, 81210, 81211, 81212, 81213, 81214,
|
||||
81215, 81216, 81217, 81218, 81220, 81221, 81222, 81223, 81224, 81225, 81226, 81227, 81228, 81229, 81230, 81231,
|
||||
81232, 81233, 81234, 81235, 81236, 81237, 81238, 81239, 81240, 81241, 81242, 81243, 81244, 81245, 81246, 81247,
|
||||
81248, 81249, 81250, 81251, 81252, 81253, 81254, 81255, 81256, 81257, 81258, 81259, 81260, 81261, 81262, 81263,
|
||||
81264, 81265, 81266, 81267, 81268, 81269, 81270, 81271, 81272, 81273, 81274, 81275, 81276, 81277, 81278, 81280,
|
||||
81281, 81282, 81283, 81284, 81285, 81286, 81288, 81289, 81290, 81291, 81292, 81293, 81295, 81296, 81297, 81298,
|
||||
81299, 81300, 81301, 81302, 81303, 81304, 81306, 81307, 81308, 81309, 81310, 81311, 81312, 81313, 82008, 82009,
|
||||
82010, 82012, 82013, 82014, 82015, 82017, 82040, 82041, 82042, 82043, 82052, 82063, 82064, 82065, 82074, 82075,
|
||||
82076, 82077, 82078, 82079, 82080, 82081, 82082, 82083, 82084, 82085, 82086, 82087, 82088, 82089, 82090, 82099,
|
||||
82100, 82101, 82102, 82103, 82104, 82105, 82106, 82107, 82108, 82110, 82111, 82112, 82113, 82114, 82121, 82122,
|
||||
82123, 82124, 82125, 82127, 82129, 82130, 82131, 82132, 82133, 82142, 82143, 82144, 82145, 82155, 82156, 82157,
|
||||
82158, 82160, 84000, 84001, 84002, 84003, 84004, 84005, 84006, 84007, 84008, 84009, 84010, 84011, 84012, 84013,
|
||||
84014, 84015, 84016, 84017, 84018, 84019, 84020, 84021, 84022, 84023, 84024, 84025, 84029, 84030, 84031, 84032,
|
||||
84033, 84034, 84035, 84036, 84037, 84038, 84039, 84040, 84041, 84042, 84043, 84044, 84045, 84046, 84047, 84048,
|
||||
84049, 84050, 84051, 84052, 84053, 84056, 84057, 84058, 84059, 84060, 84061, 84062, 84063, 84064, 84065, 84066,
|
||||
84067, 84068, 84069, 84070, 84071, 84072, 84073, 84074, 84075, 84076, 84077, 84078, 84079, 84080, 84081, 84082,
|
||||
84083, 84084, 84085, 84086, 84087, 84088, 84089, 84090, 84091, 84092, 84093, 84094, 84095, 84508, 84509, 84510,
|
||||
84512, 84513, 84514, 84515, 84516, 84518, 84519, 84520, 84522, 84523, 84524, 84525, 84526, 84527, 84528, 84529,
|
||||
84530, 84531, 84532, 84533, 84534, 84535, 84536, 84537, 84538, 84539, 84540, 84541, 84542, 84054, 84055, 84543,
|
||||
84544, 84545, 84546, 84547, 84548, 84549, 84550, 84551, 84552, 84553, 84554, 84555, 84556, 84557, 84558, 84559,
|
||||
84560, 84561, 84562, 84563, 84564, 84565, 85000, 85001, 85002, 85003, 85004, 85005, 85006, 81314, 81315, 81316,
|
||||
81317, 81318, 81319, 81320, 81321, 81322, 81323, 81324, 81325, 81326, 81327, 81328, 81329, 81339, 81331, 81332,
|
||||
81333, 81334, 81335, 81336, 81337, 81338, 82168
|
||||
],
|
||||
"total_count": 487,
|
||||
"completed_count": 0,
|
||||
"version": 3.6,
|
||||
"card": "",
|
||||
"icon": "/source/achievementSeries/0.webp"
|
||||
},
|
||||
"1": {
|
||||
{
|
||||
"id": 1,
|
||||
"order": 3,
|
||||
"name": "尘世巡游·第一辑",
|
||||
"version": "1.0",
|
||||
"achievements": [80001, 80002, 80003, 80004, 80005, 80006],
|
||||
"total_count": 6,
|
||||
"completed_count": 0,
|
||||
"card": "成就·游遍",
|
||||
"icon": "/source/achievementSeries/1.webp"
|
||||
},
|
||||
"2": {
|
||||
{
|
||||
"id": 2,
|
||||
"order": 6,
|
||||
"name": "冒险手艺",
|
||||
"version": "1.0",
|
||||
"achievements": [80007, 80008, 80009, 80010, 80011, 80012, 80013],
|
||||
"total_count": 7,
|
||||
"completed_count": 0,
|
||||
"card": "成就·殊技",
|
||||
"icon": "/source/achievementSeries/2.webp"
|
||||
},
|
||||
"3": {
|
||||
{
|
||||
"id": 3,
|
||||
"order": 7,
|
||||
"name": "英雄之旅",
|
||||
"version": "1.0",
|
||||
"achievements": [
|
||||
80014, 80015, 80016, 80017, 80018, 80019, 80020, 80021, 80022, 80023, 80024, 80025, 80026, 80027, 80028, 80029
|
||||
],
|
||||
"total_count": 16,
|
||||
"completed_count": 0,
|
||||
"card": "成就·侠行",
|
||||
"icon": "/source/achievementSeries/3.webp"
|
||||
},
|
||||
"4": {
|
||||
{
|
||||
"id": 4,
|
||||
"order": 8,
|
||||
"name": "蒙德·风与牧歌的城邦",
|
||||
"version": "1.0",
|
||||
"achievements": [80030, 80031, 80032, 80033, 80034, 80035, 80036, 80037, 80038, 80039, 80040, 80041, 80042],
|
||||
"total_count": 13,
|
||||
"completed_count": 0,
|
||||
"card": "蒙德·风吟",
|
||||
"icon": "/source/achievementSeries/4.webp"
|
||||
},
|
||||
"5": {
|
||||
{
|
||||
"id": 5,
|
||||
"order": 9,
|
||||
"name": "璃月·岩与契约的海港",
|
||||
"version": "1.0",
|
||||
"achievements": [80043, 80044, 80045, 80046, 80047, 80048, 80049, 80050, 80051, 80052, 80053, 80054, 80055],
|
||||
"total_count": 13,
|
||||
"completed_count": 0,
|
||||
"card": "璃月·岩寂",
|
||||
"icon": "/source/achievementSeries/5.webp"
|
||||
},
|
||||
"6": {
|
||||
{
|
||||
"id": 6,
|
||||
"order": 10,
|
||||
"name": "元素专家·第一辑",
|
||||
"version": "1.0",
|
||||
"achievements": [
|
||||
82019, 82020, 82021, 82022, 82023, 82024, 82025, 82026, 82027, 82028, 82029, 82030, 82031, 82032, 82033, 82034,
|
||||
82035, 82036, 82037, 82038, 82039
|
||||
],
|
||||
"total_count": 21,
|
||||
"completed_count": 0,
|
||||
"card": "成就·虹色",
|
||||
"icon": "/source/achievementSeries/6.webp"
|
||||
},
|
||||
"7": {
|
||||
{
|
||||
"id": 7,
|
||||
"order": 12,
|
||||
"name": "神射手",
|
||||
"version": "1.0",
|
||||
"achievements": [82001, 82002, 82003],
|
||||
"total_count": 3,
|
||||
"completed_count": 0,
|
||||
"card": "成就·强弓",
|
||||
"icon": "/source/achievementSeries/7.webp"
|
||||
},
|
||||
"8": {
|
||||
{
|
||||
"id": 8,
|
||||
"order": 13,
|
||||
"name": "挑战者·第一辑",
|
||||
"version": "1.0",
|
||||
"achievements": [82004, 82005, 82006, 82007],
|
||||
"total_count": 4,
|
||||
"completed_count": 0,
|
||||
"card": "成就·挑战",
|
||||
"icon": "/source/achievementSeries/8.webp"
|
||||
},
|
||||
"9": {
|
||||
{
|
||||
"id": 9,
|
||||
"order": 20,
|
||||
"name": "秘境与深境螺旋·第一辑",
|
||||
"version": "1.0",
|
||||
"achievements": [82044, 82045, 82046, 82047, 82048, 82049, 82050, 82051],
|
||||
"total_count": 8,
|
||||
"completed_count": 0,
|
||||
"card": "成就·深秘",
|
||||
"icon": "/source/achievementSeries/9.webp"
|
||||
},
|
||||
"10": {
|
||||
{
|
||||
"id": 10,
|
||||
"order": 21,
|
||||
"name": "Olah!第一辑",
|
||||
"version": "1.0",
|
||||
"achievements": [84501, 84502],
|
||||
"total_count": 2,
|
||||
"completed_count": 0,
|
||||
"card": "成就·山民",
|
||||
"icon": "/source/achievementSeries/10.webp"
|
||||
},
|
||||
"11": {
|
||||
{
|
||||
"id": 11,
|
||||
"order": 22,
|
||||
"name": "至冬国不相信眼泪·第一辑",
|
||||
"version": "1.0",
|
||||
"achievements": [84503, 84504],
|
||||
"total_count": 2,
|
||||
"completed_count": 0,
|
||||
"card": "成就·雪乡",
|
||||
"icon": "/source/achievementSeries/11.webp"
|
||||
},
|
||||
"12": {
|
||||
{
|
||||
"id": 12,
|
||||
"order": 23,
|
||||
"name": "岩港往事·第一辑",
|
||||
"version": "1.0",
|
||||
"achievements": [84505, 84506, 84507],
|
||||
"total_count": 3,
|
||||
"completed_count": 0,
|
||||
"card": "成就·合扇",
|
||||
"icon": "/source/achievementSeries/12.webp"
|
||||
},
|
||||
"13": {
|
||||
{
|
||||
"id": 13,
|
||||
"order": 24,
|
||||
"name": "异世相逢·第一辑",
|
||||
"version": "1.0",
|
||||
"achievements": [86001, 86002, 86003, 86004, 86005, 86006, 86007, 86008, 86009, 86010, 86011, 86012, 86013],
|
||||
"total_count": 13,
|
||||
"completed_count": 0,
|
||||
"card": "成就·相逢",
|
||||
"icon": "/source/achievementSeries/13.webp"
|
||||
},
|
||||
"14": {
|
||||
{
|
||||
"id": 14,
|
||||
"order": 14,
|
||||
"name": "挑战者·第二辑",
|
||||
"version": "1.1",
|
||||
"achievements": [82053, 82054, 82055, 82056, 82057, 82058, 82059, 82060, 82061, 82062],
|
||||
"total_count": 10,
|
||||
"completed_count": 0,
|
||||
"version": 1.1,
|
||||
"card": "成就·挑战·其二",
|
||||
"icon": "/source/achievementSeries/14.webp"
|
||||
},
|
||||
"15": {
|
||||
{
|
||||
"id": 15,
|
||||
"order": 15,
|
||||
"name": "挑战者·第三辑",
|
||||
"version": "1.2",
|
||||
"achievements": [82066, 82067, 82068, 82069, 82070, 82071, 82072, 82073],
|
||||
"total_count": 8,
|
||||
"completed_count": 0,
|
||||
"version": 1.2,
|
||||
"card": "成就·挑战·其三",
|
||||
"icon": "/source/achievementSeries/15.webp"
|
||||
},
|
||||
"16": {
|
||||
{
|
||||
"id": 16,
|
||||
"order": 27,
|
||||
"name": "雪山上的来客",
|
||||
"version": "1.2",
|
||||
"achievements": [80056, 80057, 80058, 80059, 80060, 80061, 80062, 80063, 80064, 80065, 80066, 80067, 80068],
|
||||
"total_count": 13,
|
||||
"completed_count": 0,
|
||||
"version": 1.2,
|
||||
"card": "成就·雪峰",
|
||||
"icon": "/source/achievementSeries/16.webp"
|
||||
},
|
||||
"17": {
|
||||
{
|
||||
"id": 17,
|
||||
"order": 2,
|
||||
"name": "心跳的记忆",
|
||||
"version": "3.6",
|
||||
"achievements": [
|
||||
84026, 84100, 84101, 84104, 84028, 84107, 84102, 84108, 84105, 84103, 84106, 84109, 84110, 84111, 84112, 84113,
|
||||
84114, 84115, 84116, 84117, 84118, 84119, 84120, 84121, 84122, 84123, 84124, 84125, 84126, 84127, 84128, 84129,
|
||||
84130, 84131, 84132, 84133, 84134, 84135, 84136, 84137, 84138, 84139, 84140, 84141, 84142, 84143, 84144, 84145
|
||||
],
|
||||
"total_count": 48,
|
||||
"completed_count": 0,
|
||||
"version": 3.6,
|
||||
"card": "",
|
||||
"icon": "/source/achievementSeries/17.webp"
|
||||
},
|
||||
"18": {
|
||||
{
|
||||
"id": 18,
|
||||
"order": 28,
|
||||
"name": "世外洞天·第一辑",
|
||||
"version": "1.5",
|
||||
"achievements": [
|
||||
81049, 81050, 81051, 81052, 81053, 81054, 81055, 81056, 81057, 81058, 81059, 81060, 81061, 81062, 81063, 81064,
|
||||
81065, 81066, 81067, 81068, 81069, 81070, 81071, 81072, 81073
|
||||
],
|
||||
"total_count": 25,
|
||||
"completed_count": 0,
|
||||
"version": 1.5,
|
||||
"card": "成就·壶歌",
|
||||
"icon": "/source/achievementSeries/18.webp"
|
||||
},
|
||||
"19": {
|
||||
{
|
||||
"id": 19,
|
||||
"order": 29,
|
||||
"name": "世外洞天·第二辑",
|
||||
"version": "1.6",
|
||||
"achievements": [81079, 81080, 81081, 81082, 81083, 81084, 81085],
|
||||
"total_count": 7,
|
||||
"completed_count": 0,
|
||||
"version": 1.6,
|
||||
"card": "成就·旅居",
|
||||
"icon": "/source/achievementSeries/19.webp"
|
||||
},
|
||||
"20": {
|
||||
{
|
||||
"id": 20,
|
||||
"order": 16,
|
||||
"name": "挑战者·第四辑",
|
||||
"version": "2.0",
|
||||
"achievements": [82091, 82092, 82093, 82094, 82095, 82096, 82097, 82098, 82109],
|
||||
"total_count": 9,
|
||||
"completed_count": 0,
|
||||
"card": "成就·石龙",
|
||||
"icon": "/source/achievementSeries/20.webp"
|
||||
},
|
||||
"21": {
|
||||
{
|
||||
"id": 21,
|
||||
"order": 25,
|
||||
"name": "异世相逢·第二辑",
|
||||
"version": "2.1",
|
||||
"achievements": [86021, 86015, 86016, 86017, 86018, 86019, 86020],
|
||||
"total_count": 7,
|
||||
"completed_count": 0,
|
||||
"version": 2.1,
|
||||
"card": "成就·门扉",
|
||||
"icon": "/source/achievementSeries/21.webp"
|
||||
},
|
||||
"22": {
|
||||
{
|
||||
"id": 22,
|
||||
"order": 4,
|
||||
"name": "尘世巡游·第二辑",
|
||||
"version": "2.0",
|
||||
"achievements": [80069, 80070, 80071, 80072, 80073],
|
||||
"total_count": 5,
|
||||
"completed_count": 0,
|
||||
"card": "成就·遍历",
|
||||
"icon": "/source/achievementSeries/22.webp"
|
||||
},
|
||||
"23": {
|
||||
{
|
||||
"id": 23,
|
||||
"order": 30,
|
||||
"name": "世外洞天·第三辑",
|
||||
"version": "2.0",
|
||||
"achievements": [81086, 81087, 81088, 81089, 81090, 81091, 81092, 81093, 81094, 81095],
|
||||
"total_count": 10,
|
||||
"completed_count": 0,
|
||||
"card": "成就·繁花",
|
||||
"icon": "/source/achievementSeries/23.webp"
|
||||
},
|
||||
"24": {
|
||||
{
|
||||
"id": 24,
|
||||
"order": 31,
|
||||
"name": "稻妻·雷与永恒的群岛·其之一",
|
||||
"version": "2.0",
|
||||
"achievements": [
|
||||
80074, 80075, 80076, 80077, 80078, 80079, 80080, 80081, 80082, 80083, 80084, 80085, 80086, 80087, 80088, 80089,
|
||||
80090, 80093, 80094, 80095
|
||||
],
|
||||
"total_count": 20,
|
||||
"completed_count": 0,
|
||||
"card": "稻妻·九条之纹",
|
||||
"icon": "/source/achievementSeries/24.webp"
|
||||
},
|
||||
"25": {
|
||||
{
|
||||
"id": 25,
|
||||
"order": 34,
|
||||
"name": "提瓦特钓鱼指南·第一辑",
|
||||
"version": "2.1",
|
||||
"achievements": [81131, 81132, 81133, 81134, 81135, 81136, 81137, 81138, 81139, 81140, 81143, 81144],
|
||||
"total_count": 12,
|
||||
"completed_count": 0,
|
||||
"version": 2.1,
|
||||
"card": "成就·敲针",
|
||||
"icon": "/source/achievementSeries/25.webp"
|
||||
},
|
||||
"26": {
|
||||
{
|
||||
"id": 26,
|
||||
"order": 32,
|
||||
"name": "稻妻·雷与永恒的群岛·其之二",
|
||||
"version": "2.1",
|
||||
"achievements": [
|
||||
80096, 80097, 80098, 80099, 80100, 80101, 80102, 80105, 80106, 80107, 80110, 80111, 80112, 80108, 80109
|
||||
],
|
||||
"total_count": 15,
|
||||
"completed_count": 0,
|
||||
"version": 2.1,
|
||||
"card": "稻妻·珊瑚宫之纹",
|
||||
"icon": "/source/achievementSeries/26.webp"
|
||||
},
|
||||
"27": {
|
||||
{
|
||||
"id": 27,
|
||||
"order": 33,
|
||||
"name": "雾海纪行",
|
||||
"version": "2.2",
|
||||
"achievements": [80113, 80114, 80115, 80116, 80119, 80120, 80121, 80122, 80123, 80124, 80125, 80126],
|
||||
"total_count": 12,
|
||||
"completed_count": 0,
|
||||
"version": 2.2,
|
||||
"card": "稻妻·鹫羽",
|
||||
"icon": "/source/achievementSeries/27.webp"
|
||||
},
|
||||
"28": {
|
||||
{
|
||||
"id": 28,
|
||||
"order": 35,
|
||||
"name": "白昼之光",
|
||||
"version": "2.4",
|
||||
"achievements": [80130, 80131, 80132, 80133, 80134, 80135, 80136, 80137, 80138, 80139, 80140, 80141],
|
||||
"total_count": 12,
|
||||
"completed_count": 0,
|
||||
"version": 2.4,
|
||||
"card": "稻妻·常世",
|
||||
"icon": "/source/achievementSeries/28.webp"
|
||||
},
|
||||
"29": {
|
||||
{
|
||||
"id": 29,
|
||||
"order": 17,
|
||||
"name": "挑战者·第五辑",
|
||||
"version": "2.6",
|
||||
"achievements": [82115, 82116, 82117, 82118, 82119, 82120, 82126, 82128],
|
||||
"total_count": 8,
|
||||
"completed_count": 0,
|
||||
"version": 2.6,
|
||||
"card": "成就·雷音",
|
||||
"icon": "/source/achievementSeries/29.webp"
|
||||
},
|
||||
"30": {
|
||||
{
|
||||
"id": 30,
|
||||
"order": 36,
|
||||
"name": "岩窟流明",
|
||||
"version": "2.6",
|
||||
"achievements": [
|
||||
80145, 80146, 80147, 80148, 80149, 80150, 80151, 80152, 80153, 80154, 80155, 80156, 80157, 80158, 80159
|
||||
],
|
||||
"total_count": 15,
|
||||
"completed_count": 0,
|
||||
"version": 2.6,
|
||||
"card": "成就·层岩",
|
||||
"icon": "/source/achievementSeries/30.webp"
|
||||
},
|
||||
"31": {
|
||||
{
|
||||
"id": 31,
|
||||
"order": 37,
|
||||
"name": "须弥·玄识深藏的雨林",
|
||||
"version": "3.0",
|
||||
"achievements": [
|
||||
80160, 80161, 80162, 80163, 80164, 80165, 80166, 80167, 80168, 80169, 80170, 80171, 80172, 80173, 80174
|
||||
],
|
||||
"total_count": 15,
|
||||
"completed_count": 0,
|
||||
"card": "须弥·瑶林",
|
||||
"icon": "/source/achievementSeries/31.webp"
|
||||
},
|
||||
"32": {
|
||||
{
|
||||
"id": 32,
|
||||
"order": 5,
|
||||
"name": "尘世巡游·第三辑",
|
||||
"version": "3.0",
|
||||
"achievements": [80175, 80176, 80177, 80178],
|
||||
"total_count": 4,
|
||||
"completed_count": 0,
|
||||
"card": "成就·漫行",
|
||||
"icon": "/source/achievementSeries/32.webp"
|
||||
},
|
||||
"33": {
|
||||
{
|
||||
"id": 33,
|
||||
"order": 26,
|
||||
"name": "异世相逢·第三辑",
|
||||
"version": "3.0",
|
||||
"achievements": [86022, 86023, 86024, 86025, 86026, 86027, 86028, 86029],
|
||||
"total_count": 8,
|
||||
"completed_count": 0,
|
||||
"card": "成就·逢缘",
|
||||
"icon": "/source/achievementSeries/33.webp"
|
||||
},
|
||||
"34": {
|
||||
{
|
||||
"id": 34,
|
||||
"order": 18,
|
||||
"name": "挑战者·第六辑",
|
||||
"version": "3.1",
|
||||
"achievements": [82134, 82135, 82136, 82137, 82138, 82139, 82140, 82141],
|
||||
"total_count": 8,
|
||||
"completed_count": 0,
|
||||
"version": 3.1,
|
||||
"card": "成就·镜梦",
|
||||
"icon": "/source/achievementSeries/34.webp"
|
||||
},
|
||||
"35": {
|
||||
{
|
||||
"id": 35,
|
||||
"order": 38,
|
||||
"name": "须弥·饰金砂原·其之一",
|
||||
"version": "3.1",
|
||||
"achievements": [80179, 80180, 80181, 80182, 80183, 80184, 80185, 80186, 80187, 80188, 80189, 80190, 80191],
|
||||
"total_count": 13,
|
||||
"completed_count": 0,
|
||||
"version": 3.1,
|
||||
"card": "须弥·踏沙",
|
||||
"icon": "/source/achievementSeries/35.webp"
|
||||
},
|
||||
"36": {
|
||||
{
|
||||
"id": 36,
|
||||
"order": 11,
|
||||
"name": "元素专家·第二辑",
|
||||
"version": "3.1",
|
||||
"achievements": [82146, 82147, 82148, 82149, 82150, 82151, 82159],
|
||||
"total_count": 7,
|
||||
"completed_count": 0,
|
||||
"version": 3.1,
|
||||
"card": "成就·七芒",
|
||||
"icon": "/source/achievementSeries/36.webp"
|
||||
},
|
||||
"37": {
|
||||
{
|
||||
"id": 37,
|
||||
"order": 40,
|
||||
"name": "七圣召唤",
|
||||
"version": "3.3",
|
||||
"achievements": [
|
||||
80192, 80193, 80197, 80198, 80199, 80203, 80204, 80205, 80206, 80207, 80208, 80209, 80210, 80211, 80212, 80213,
|
||||
80214, 80215, 80216, 80217, 80218, 80219, 80220, 80221, 80222, 80223
|
||||
],
|
||||
"total_count": 26,
|
||||
"completed_count": 0,
|
||||
"version": 3.3,
|
||||
"card": "成就·七圣",
|
||||
"icon": "/source/achievementSeries/37.webp"
|
||||
},
|
||||
"38": {
|
||||
{
|
||||
"id": 38,
|
||||
"order": 39,
|
||||
"name": "须弥·饰金砂原·其之二",
|
||||
"version": "3.4",
|
||||
"achievements": [80224, 80225, 80226, 80228, 80229, 80230, 80231, 80232, 80233, 80234, 80235, 80236, 80227],
|
||||
"total_count": 13,
|
||||
"completed_count": 0,
|
||||
"version": 3.4,
|
||||
"card": "须弥·砂岚",
|
||||
"icon": "/source/achievementSeries/38.webp"
|
||||
},
|
||||
"39": {
|
||||
{
|
||||
"id": 39,
|
||||
"order": 19,
|
||||
"name": "挑战者·第七辑",
|
||||
"version": "3.6",
|
||||
"achievements": [82161, 82162, 82163, 82164, 82165, 82166, 82167, 82169],
|
||||
"total_count": 8,
|
||||
"completed_count": 0,
|
||||
"version": 3.6,
|
||||
"card": "成就·槿暮",
|
||||
"icon": "/source/achievementSeries/39.webp"
|
||||
},
|
||||
"41": {
|
||||
{
|
||||
"id": 41,
|
||||
"order": 41,
|
||||
"name": "佑灵砾漠",
|
||||
"version": "3.6",
|
||||
"achievements": [80237, 80238, 80239, 80240, 80241, 80242, 80243, 80244, 80245, 80246, 80247, 80248, 80250, 80249],
|
||||
"total_count": 14,
|
||||
"completed_count": 0,
|
||||
"version": 3.6,
|
||||
"card": "成就·万种",
|
||||
"icon": "/source/achievementSeries/41.webp"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -413,7 +413,7 @@
|
||||
},
|
||||
{
|
||||
"id": 10000082,
|
||||
"content_id": null,
|
||||
"content_id": 6489,
|
||||
"name": "白术",
|
||||
"star": 5,
|
||||
"bg": "/icon/bg/5-Star.webp",
|
||||
@@ -885,7 +885,7 @@
|
||||
},
|
||||
{
|
||||
"id": 10000081,
|
||||
"content_id": null,
|
||||
"content_id": 6490,
|
||||
"name": "卡维",
|
||||
"star": 4,
|
||||
"bg": "/icon/bg/4-Star.webp",
|
||||
@@ -3367,7 +3367,7 @@
|
||||
},
|
||||
{
|
||||
"id": 10000081,
|
||||
"content_id": null,
|
||||
"content_id": 6490,
|
||||
"name": "卡维",
|
||||
"star": 4,
|
||||
"bg": "/icon/bg/4-Star.webp",
|
||||
@@ -3988,7 +3988,7 @@
|
||||
},
|
||||
{
|
||||
"id": 10000082,
|
||||
"content_id": null,
|
||||
"content_id": 6489,
|
||||
"name": "白术",
|
||||
"star": 5,
|
||||
"bg": "/icon/bg/5-Star.webp",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"id": 10000082,
|
||||
"content_id": null,
|
||||
"content_id": 6489,
|
||||
"name": "白术",
|
||||
"star": 5,
|
||||
"bg": "/icon/bg/5-Star.webp",
|
||||
@@ -331,7 +331,7 @@
|
||||
},
|
||||
{
|
||||
"id": 10000081,
|
||||
"content_id": null,
|
||||
"content_id": 6490,
|
||||
"name": "卡维",
|
||||
"star": 4,
|
||||
"bg": "/icon/bg/4-Star.webp",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file data app index
|
||||
* @description data app index
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.3
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
// Data
|
||||
@@ -17,11 +17,11 @@ import weapon from "./weapon.json";
|
||||
export const AppDataList = [
|
||||
{
|
||||
name: "achievements.json",
|
||||
data: achievements as Record<number, BTMuli.Genshin.Achievement>,
|
||||
data: achievements as BTMuli.Genshin.Achievement[],
|
||||
},
|
||||
{
|
||||
name: "achievementSeries.json",
|
||||
data: achievementSeries as Record<number, BTMuli.Genshin.AchievementSeries>,
|
||||
data: achievementSeries as BTMuli.Genshin.AchievementSeries[],
|
||||
},
|
||||
{
|
||||
name: "calendar.json",
|
||||
@@ -37,7 +37,7 @@ export const AppDataList = [
|
||||
},
|
||||
{
|
||||
name: "nameCards.json",
|
||||
data: nameCards as Record<number, BTMuli.Genshin.NameCard[]>,
|
||||
data: nameCards as BTMuli.Genshin.NameCard[],
|
||||
},
|
||||
{
|
||||
name: "weapon.json",
|
||||
@@ -46,11 +46,11 @@ export const AppDataList = [
|
||||
];
|
||||
|
||||
export const AppData = {
|
||||
achievements: achievements as Record<number, BTMuli.Genshin.Achievement>,
|
||||
achievementSeries: achievementSeries as Record<number, BTMuli.Genshin.AchievementSeries>,
|
||||
achievements: achievements as BTMuli.Genshin.Achievement[],
|
||||
achievementSeries: achievementSeries as BTMuli.Genshin.AchievementSeries[],
|
||||
calendar: calendar as Record<number, BTMuli.Genshin.Calendar.Data>,
|
||||
character: character as BTMuli.Genshin.Wiki.Character.BriefInfo[],
|
||||
GCG: GCG as BTMuli.Genshin.Wiki.GCG.BriefInfo[],
|
||||
nameCards: nameCards as Record<number, BTMuli.Genshin.NameCard[]>,
|
||||
nameCards: nameCards as BTMuli.Genshin.NameCard[],
|
||||
weapon: weapon as BTMuli.Genshin.Wiki.Weapon.BriefInfo[],
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -332,15 +332,6 @@
|
||||
"type": "/icon/weapon/单手剑.webp",
|
||||
"icon": "/WIKI/weapon/icon/11501.webp"
|
||||
},
|
||||
{
|
||||
"id": 15419,
|
||||
"content_id": null,
|
||||
"name": "鹮穿之喙",
|
||||
"star": 4,
|
||||
"bg": "/icon/bg/4-Star.webp",
|
||||
"type": "/icon/weapon/弓.webp",
|
||||
"icon": "/WIKI/weapon/icon/15419.webp"
|
||||
},
|
||||
{
|
||||
"id": 15418,
|
||||
"content_id": 4437,
|
||||
|
||||
@@ -2,13 +2,9 @@
|
||||
* @file data index
|
||||
* @description data index
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
import { AppData, AppDataList } from "./app";
|
||||
import { ConfigList, getDataList } from "./init";
|
||||
import { AppData } from "./app";
|
||||
|
||||
export const TGAppData = AppData;
|
||||
export const TGAppDataList = AppDataList;
|
||||
export const TGConfigList = ConfigList;
|
||||
export const TGGetDataList = getDataList;
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* @file data init achievementSeries
|
||||
* @description data init achievementSeries
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.2
|
||||
*/
|
||||
import { AppData } from "../app";
|
||||
|
||||
/**
|
||||
* @description 成就系列表参数
|
||||
* @since Alpha v0.1.2
|
||||
* @returns {BTMuli.Genshin.Base.DBConfig}
|
||||
*/
|
||||
export const Config: BTMuli.Genshin.Base.DBConfig = {
|
||||
storeName: "AchievementSeries",
|
||||
keyPath: "id",
|
||||
indexes: ["order", "name", "card"],
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 成就系列数据
|
||||
* @since Alpha v0.1.2
|
||||
* @return {BTMuli.Genshin.AchievementSeries[]}
|
||||
*/
|
||||
export function getData (): BTMuli.Genshin.AchievementSeries[] {
|
||||
const data: Record<number, BTMuli.Genshin.AchievementSeries> = AppData.achievementSeries;
|
||||
return Object.keys(data).map((key) => {
|
||||
return data[Number(key)];
|
||||
});
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* @file data init achievement
|
||||
* @description data init achievement
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.2
|
||||
*/
|
||||
import { AppData } from "../app";
|
||||
|
||||
/**
|
||||
* @description 成就表参数
|
||||
* @since Alpha v0.1.2
|
||||
* @returns {BTMuli.Genshin.Base.DBConfig}
|
||||
*/
|
||||
export const Config: BTMuli.Genshin.Base.DBConfig = {
|
||||
storeName: "Achievements",
|
||||
keyPath: "id",
|
||||
indexes: ["name", "description", "series", "order", "reward", "version"],
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 成就数据
|
||||
* @since Alpha v0.1.2
|
||||
* @return {BTMuli.Genshin.Achievement[]}
|
||||
*/
|
||||
export function getData (): BTMuli.Genshin.Achievement[] {
|
||||
const data: Record<number, BTMuli.Genshin.Achievement> = AppData.achievements;
|
||||
return Object.keys(data).map((key) => {
|
||||
return data[Number(key)];
|
||||
});
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* @file data init index
|
||||
* @description data init index
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.3
|
||||
*/
|
||||
import { Config as AchievementsConfig, getData as getAchievementsData } from "./achievements";
|
||||
import { Config as SeriesConfig, getData as getSeriesData } from "./achievementSeries";
|
||||
|
||||
export const ConfigList = [AchievementsConfig, SeriesConfig];
|
||||
|
||||
export const getDataList = [
|
||||
{
|
||||
name: "Achievements",
|
||||
data: getAchievementsData(),
|
||||
},
|
||||
{
|
||||
name: "AchievementSeries",
|
||||
data: getSeriesData(),
|
||||
},
|
||||
];
|
||||
@@ -28,7 +28,7 @@
|
||||
<div v-show="!loading" class="wrap">
|
||||
<!-- 左侧菜单 -->
|
||||
<div class="left-wrap">
|
||||
<v-list v-for="(series, index) in seriesList" :key="series.id" class="card-left" @click="selectSeries(index)">
|
||||
<v-list v-for="series in seriesList" :key="series.id" class="card-left" @click="selectSeries(series.id)">
|
||||
<div class="version-icon-series">
|
||||
v{{ series.version }}
|
||||
</div>
|
||||
@@ -39,14 +39,14 @@
|
||||
<v-list-item-title>
|
||||
{{ series.name }}
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle> {{ series.completed_count }} / {{ series.total_count }} </v-list-item-subtitle>
|
||||
<v-list-item-subtitle> {{ series.finCount }} / {{ series.totalCount }} </v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</div>
|
||||
<!-- 右侧内容-->
|
||||
<div class="right-wrap">
|
||||
<div class="right-wrap" @scroll="handleScroll">
|
||||
<v-list
|
||||
v-if="selectedIndex !== -1 && selectedSeries !== 0 && selectedSeries !== 17"
|
||||
v-if="selectedSeries !== 0 && selectedSeries !== 17 && selectedSeries !== -1"
|
||||
:style="{
|
||||
backgroundImage: 'url(' + getCardInfo.bg || null + ')',
|
||||
backgroundPosition: 'right',
|
||||
@@ -57,6 +57,7 @@
|
||||
color: '#485466',
|
||||
fontFamily: 'Genshin,serif',
|
||||
cursor: 'pointer',
|
||||
position: 'relative',
|
||||
}"
|
||||
@click="openImg()"
|
||||
>
|
||||
@@ -66,33 +67,38 @@
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<v-list v-for="achievement in selectedAchievement" :key="achievement.id" class="card-right">
|
||||
<div v-if="achievement.progress !== 0" class="achievement-progress">
|
||||
{{ achievement.progress }}
|
||||
</div>
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<v-icon :color="achievement.completed ? '#fec90b' : '#485466'">
|
||||
<!-- todo 图标替换 -->
|
||||
{{ achievement.completed ? "mdi-check-circle" : "mdi-circle" }}
|
||||
</v-icon>
|
||||
</template>
|
||||
<v-list-item-title>
|
||||
{{ achievement.name }}
|
||||
<span class="version-icon-single">v{{ achievement.version }}</span>
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ achievement.description }}</v-list-item-subtitle>
|
||||
<template #append>
|
||||
<span v-show="achievement.completed" class="right-time">{{ achievement.completed_time }}</span>
|
||||
<v-card class="reward-card" @click="showMaterial('/source/material/原石.webp')">
|
||||
<v-img src="/source/material/原石.webp" sizes="32" />
|
||||
<div class="reward-num">
|
||||
<span>{{ achievement.reward }}</span>
|
||||
</div>
|
||||
</v-card>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<div
|
||||
class="list-empty"
|
||||
:style="{height: `${emptyHeight}px`}"
|
||||
>
|
||||
<v-list v-for="achievement in renderAchievement" :key="achievement.id" class="card-right" :style="{Transform:`translateY(${translateY})`}">
|
||||
<div v-if="achievement.progress !== 0" class="achievement-progress">
|
||||
{{ achievement.progress }}
|
||||
</div>
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<v-icon :color="achievement.isCompleted ? '#fec90b' : '#485466'">
|
||||
<!-- todo 图标替换 -->
|
||||
{{ achievement.isCompleted ? "mdi-check-circle" : "mdi-circle" }}
|
||||
</v-icon>
|
||||
</template>
|
||||
<v-list-item-title>
|
||||
{{ achievement.name }}
|
||||
<span class="version-icon-single">v{{ achievement.version }}</span>
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ achievement.description }}</v-list-item-subtitle>
|
||||
<template #append>
|
||||
<span v-show="achievement.isCompleted" class="right-time">{{ achievement.completedTime }}</span>
|
||||
<v-card class="reward-card">
|
||||
<v-img src="/source/material/原石.webp" sizes="32" />
|
||||
<div class="reward-num">
|
||||
<span>{{ achievement.reward }}</span>
|
||||
</div>
|
||||
</v-card>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 弹窗提示 -->
|
||||
<v-snackbar v-model="snackbar" timeout="1500" :color="snackbarColor" top>
|
||||
@@ -103,17 +109,16 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { onMounted, ref } from "vue";
|
||||
import { onMounted, ref, onBeforeMount, computed } from "vue";
|
||||
import TLoading from "../components/t-loading.vue";
|
||||
// tauri
|
||||
import { dialog, fs } from "@tauri-apps/api";
|
||||
// Store
|
||||
import { useAchievementsStore } from "../store/modules/achievements";
|
||||
// Utils
|
||||
import { TGAppData } from "../data";
|
||||
import { createTGWindow } from "../utils/TGWindow";
|
||||
import { ReadAllTGData, ReadTGDataByIndex, ReadTGDataByKey, UpdateTGDataByKey } from "../utils/TGIndex";
|
||||
import { getUiafHeader, readUiafData, verifyUiafData } from "../utils/UIAF";
|
||||
import TGSqlite from "../utils/TGSqlite";
|
||||
|
||||
// Store
|
||||
const achievementsStore = useAchievementsStore();
|
||||
@@ -124,81 +129,105 @@ const loadingTitle = ref("正在加载数据" as string);
|
||||
|
||||
// data
|
||||
const title = ref(achievementsStore.title as string);
|
||||
const CardsInfo = ref([] as BTMuli.Genshin.NameCard[]);
|
||||
const getCardInfo = ref({} as BTMuli.Genshin.NameCard);
|
||||
const getCardInfo = ref({} as BTMuli.SQLite.NameCard);
|
||||
// series
|
||||
const seriesList = ref([] as BTMuli.Genshin.AchievementSeries[]);
|
||||
const selectedIndex = ref(-1 as number);
|
||||
const seriesList = ref([] as BTMuli.SQLite.AchievementSeries[]);
|
||||
const selectedSeries = ref(-1 as number);
|
||||
const selectedAchievement = ref([] as BTMuli.Genshin.Achievement[]);
|
||||
|
||||
const selectedAchievement = ref([] as BTMuli.SQLite.Achievements[]);
|
||||
const renderAchievement = computed(() => {
|
||||
return selectedAchievement.value.slice(start.value, start.value + itemCount.value + 1);
|
||||
});
|
||||
// virtual list
|
||||
const start = ref(0 as number);
|
||||
const itemCount = computed(() => {
|
||||
return Math.ceil((window.innerHeight - 100) / 76);
|
||||
});
|
||||
const emptyHeight = computed(() => {
|
||||
return selectedAchievement.value.length * 76;
|
||||
});
|
||||
const translateY = ref("0px" as string);
|
||||
// render
|
||||
const search = ref("" as string);
|
||||
const snackbar = ref(false as boolean);
|
||||
const snackbarText = ref("" as string);
|
||||
const snackbarColor = ref("#F5810A" as string);
|
||||
|
||||
onMounted(async () => {
|
||||
await loadData();
|
||||
onBeforeMount(async () => {
|
||||
const { total, fin } = await TGSqlite.getAchievementsOverview();
|
||||
achievementsStore.flushData(total, fin);
|
||||
title.value = achievementsStore.title;
|
||||
});
|
||||
|
||||
// 加载数据,数据源:合并后的本地数据
|
||||
async function loadData () {
|
||||
onMounted(async () => {
|
||||
loading.value = true;
|
||||
loadingTitle.value = "正在获取成就系列数据";
|
||||
const seriesDB: BTMuli.Genshin.AchievementSeries[] = await ReadAllTGData("AchievementSeries");
|
||||
CardsInfo.value = TGAppData.nameCards[1];
|
||||
seriesList.value = seriesDB.sort((a, b) => a.order - b.order);
|
||||
seriesList.value = await TGSqlite.getAchievementSeries();
|
||||
loadingTitle.value = "正在获取成就数据";
|
||||
const getAchievements = await ReadAllTGData("Achievements");
|
||||
getAchievements.sort((a, b) => {
|
||||
if (a.completed === b.completed) {
|
||||
return a.id - b.id;
|
||||
} else {
|
||||
return a.completed ? 1 : -1;
|
||||
}
|
||||
});
|
||||
selectedAchievement.value = getAchievements;
|
||||
title.value = achievementsStore.title;
|
||||
selectedAchievement.value = await TGSqlite.getAchievements();
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
function handleScroll (e: Event) {
|
||||
// 如果 scrollTop 到底部了
|
||||
if ((e.target as HTMLElement).scrollTop + (e.target as HTMLElement).offsetHeight >= (e.target as HTMLElement).scrollHeight) {
|
||||
// 如果 selectedAchievement 的长度小于 itemCount,不进行偏移
|
||||
if (selectedAchievement.value.length <= itemCount.value) {
|
||||
window.requestAnimationFrame(() => {
|
||||
start.value = 0;
|
||||
translateY.value = "0px";
|
||||
});
|
||||
return;
|
||||
}
|
||||
window.requestAnimationFrame(() => {
|
||||
start.value = selectedAchievement.value.length - itemCount.value;
|
||||
translateY.value = `${(selectedAchievement.value.length - itemCount.value) * 76}px`;
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (selectedSeries.value !== 0 && selectedSeries.value !== 17 && selectedSeries.value !== -1) {
|
||||
window.requestAnimationFrame(() => {
|
||||
const { scrollTop } = e.target as HTMLElement;
|
||||
if (scrollTop < 86.8) {
|
||||
start.value = 0;
|
||||
translateY.value = "0px";
|
||||
} else {
|
||||
start.value = Math.floor((scrollTop - 86.8) / 76);
|
||||
translateY.value = `${scrollTop - 86.8}px`;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
window.requestAnimationFrame(() => {
|
||||
const { scrollTop } = e.target as HTMLElement;
|
||||
start.value = Math.floor(scrollTop / 76);
|
||||
translateY.value = `${scrollTop}px`;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染选中的成就系列
|
||||
async function selectSeries (index: number) {
|
||||
// 如果选中的是已经选中的系列,则不进行操作
|
||||
if (selectedIndex.value === index) {
|
||||
if (selectedSeries.value === index) {
|
||||
snackbarText.value = "已经选中该系列";
|
||||
snackbar.value = true;
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
loadingTitle.value = "正在获取对应的成就数据";
|
||||
const getAchievements = await ReadTGDataByIndex("Achievements", "series", seriesList.value[index].id);
|
||||
selectedIndex.value = index;
|
||||
selectedSeries.value = seriesList.value[index].id;
|
||||
selectedSeries.value = index;
|
||||
selectedAchievement.value = await TGSqlite.getAchievements(index);
|
||||
loadingTitle.value = "正在查找对应的成就名片";
|
||||
let getCard: BTMuli.Genshin.NameCard;
|
||||
if (selectedSeries.value !== 0 && selectedSeries.value !== 17) {
|
||||
getCard = CardsInfo.value.find((card) => card.name === seriesList.value[index].card)!;
|
||||
} else {
|
||||
getCard = {} as BTMuli.Genshin.NameCard;
|
||||
getCardInfo.value = await TGSqlite.getNameCard(index);
|
||||
}
|
||||
getAchievements.sort((a, b) => {
|
||||
if (a.completed === b.completed) {
|
||||
return a.id - b.id;
|
||||
} else {
|
||||
return a.completed ? 1 : -1;
|
||||
}
|
||||
});
|
||||
selectedAchievement.value = getAchievements;
|
||||
getCardInfo.value = getCard;
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
// 打开图片
|
||||
function openImg () {
|
||||
createTGWindow(getCardInfo.value.profile, "nameCard", getCardInfo.value.name, 840, 400, false);
|
||||
}
|
||||
function showMaterial (path: string) {
|
||||
createTGWindow(path, "material", "原石", 256, 256, false);
|
||||
}
|
||||
|
||||
async function searchCard () {
|
||||
if (search.value === "") {
|
||||
snackbarColor.value = "#F5810A";
|
||||
@@ -206,35 +235,16 @@ async function searchCard () {
|
||||
snackbar.value = true;
|
||||
return;
|
||||
}
|
||||
selectedSeries.value = -1;
|
||||
loadingTitle.value = "正在搜索";
|
||||
loading.value = true;
|
||||
const res: BTMuli.Genshin.Achievement[] = [];
|
||||
const allAchievements = await ReadAllTGData("Achievements");
|
||||
allAchievements.map((achievement) => {
|
||||
if (achievement.name.includes(search.value) || achievement.description.includes(search.value)) {
|
||||
return res.push(achievement);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
selectedIndex.value = -1;
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
}, 500);
|
||||
if (res.length === 0) {
|
||||
selectedAchievement.value = await TGSqlite.searchAchievements(search.value);
|
||||
if (selectedAchievement.value.length === 0) {
|
||||
snackbarColor.value = "#F5810A";
|
||||
snackbarText.value = "没有找到对应的成就";
|
||||
snackbar.value = true;
|
||||
selectedAchievement.value = allAchievements;
|
||||
} else {
|
||||
res.sort((a, b) => {
|
||||
if (a.completed === b.completed) {
|
||||
return a.id - b.id;
|
||||
} else {
|
||||
return a.completed ? 1 : -1;
|
||||
}
|
||||
});
|
||||
selectedAchievement.value = res;
|
||||
}
|
||||
loading.value = false;
|
||||
}
|
||||
// 导入 UIAF 数据,进行数据合并、刷新
|
||||
async function importJson () {
|
||||
@@ -256,70 +266,15 @@ async function importJson () {
|
||||
}
|
||||
loadingTitle.value = "正在解析数据";
|
||||
loading.value = true;
|
||||
const remoteData: TGPlugin.UIAF.BaseData = JSON.parse(remoteRaw);
|
||||
loadingTitle.value = "正在合并成就数据";
|
||||
await Promise.allSettled(
|
||||
remoteData.list.map(async (data) => {
|
||||
const id = data.id;
|
||||
const localData: BTMuli.Genshin.Achievement = (await ReadTGDataByKey("Achievements", [id]))[0];
|
||||
// 获取 timeStamp 2023-03-15 00:00:00
|
||||
const localTime = localData.completed_time;
|
||||
// 如果本地数据不存在,或者本地数据的 timeStamp 小于远程数据的 timeStamp,更新数据
|
||||
if (data.timestamp !== 0) {
|
||||
const finishTime = new Date(data.timestamp * 1000).toLocaleString("zh", {
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
});
|
||||
if (finishTime !== localTime || localData.progress !== data.current) {
|
||||
// eslint-disable-next-line camelcase
|
||||
localData.completed_time = finishTime;
|
||||
localData.progress = data.current;
|
||||
localData.completed = true;
|
||||
// 更新数据
|
||||
await UpdateTGDataByKey("Achievements", localData);
|
||||
}
|
||||
} else {
|
||||
if (localData.progress !== data.current) {
|
||||
// eslint-disable-next-line camelcase
|
||||
localData.completed_time = "";
|
||||
localData.progress = data.current;
|
||||
localData.completed = false;
|
||||
// 更新数据
|
||||
await UpdateTGDataByKey("Achievements", localData);
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
loadingTitle.value = "正在更新成就系列数据";
|
||||
let seriesDB = await ReadAllTGData("AchievementSeries");
|
||||
await Promise.allSettled(
|
||||
seriesDB.map(async (data) => {
|
||||
const seriesId = data.id;
|
||||
const achievementsDB = await ReadTGDataByIndex("Achievements", "series", seriesId);
|
||||
// eslint-disable-next-line camelcase
|
||||
data.completed_count = achievementsDB.filter((data) => {
|
||||
return data.completed === true;
|
||||
}).length;
|
||||
await UpdateTGDataByKey("AchievementSeries", data);
|
||||
}),
|
||||
);
|
||||
loadingTitle.value = "正在刷新数据";
|
||||
seriesDB = await ReadAllTGData("AchievementSeries");
|
||||
const finishAchievments = seriesDB.reduce((a, b) => {
|
||||
return a + b.completed_count;
|
||||
}, 0);
|
||||
const totalAchievements = seriesDB.reduce((a, b) => {
|
||||
return a + b.total_count;
|
||||
}, 0);
|
||||
achievementsStore.flushData(totalAchievements, finishAchievments);
|
||||
// 刷新数据
|
||||
await loadData();
|
||||
await TGSqlite.mergeUIAF(JSON.parse(remoteRaw).list);
|
||||
loadingTitle.value = "即将刷新页面";
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// 导出
|
||||
async function exportJson () {
|
||||
// 判断是否有数据
|
||||
@@ -330,35 +285,10 @@ async function exportJson () {
|
||||
return;
|
||||
}
|
||||
// 获取本地数据
|
||||
const achievements = (await ReadAllTGData("Achievements")).filter((data) => {
|
||||
return data.progress !== 0 || data.completed === true;
|
||||
});
|
||||
const UiafData = {
|
||||
info: await getUiafHeader(),
|
||||
list: [] as TGPlugin.UIAF.Achievement[],
|
||||
list: await TGSqlite.getUIAF(),
|
||||
};
|
||||
// 转换数据
|
||||
UiafData.list = achievements.map((data) => {
|
||||
let status;
|
||||
// 计算点数但是没有完成
|
||||
if (data.progress !== 0 && data.completed === false) {
|
||||
status = 1;
|
||||
// 已完成且未计算点数
|
||||
} else if (data.progress === 0 && data.completed === true) {
|
||||
status = 2;
|
||||
// 已完成且已计算点数
|
||||
} else if (data.progress !== 0 && data.completed === true) {
|
||||
status = 3;
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
return {
|
||||
id: data.id,
|
||||
timestamp: data.completed ? Math.round(new Date(data.completed_time).getTime() / 1000) : 0,
|
||||
current: data.progress,
|
||||
status,
|
||||
};
|
||||
});
|
||||
const isSave = await dialog.save({
|
||||
// TODO: 设置保存文件名
|
||||
filters: [
|
||||
@@ -370,10 +300,14 @@ async function exportJson () {
|
||||
});
|
||||
if (isSave) {
|
||||
await fs.writeTextFile(isSave, JSON.stringify(UiafData));
|
||||
snackbarColor.value = "#00BFA5";
|
||||
snackbarText.value = "导出成功";
|
||||
snackbar.value = true;
|
||||
} else {
|
||||
snackbarColor.value = "#F5810A";
|
||||
snackbarText.value = "导出已取消";
|
||||
snackbar.value = true;
|
||||
}
|
||||
snackbarColor.value = "#00BFA5";
|
||||
snackbarText.value = "导出成功";
|
||||
snackbar.value = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -403,12 +337,25 @@ async function exportJson () {
|
||||
|
||||
/* 右侧成就 */
|
||||
.right-wrap {
|
||||
position: relative;
|
||||
float: right;
|
||||
width: 75%;
|
||||
max-height: calc(100vh - 100px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.list-empty {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.list-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: calc(100vh - 100px);
|
||||
}
|
||||
|
||||
/* 版本信息 */
|
||||
.version-icon-series {
|
||||
font-family: Genshin, serif;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div v-if="loading">
|
||||
<TLoading />
|
||||
<TLoading :title="loadingTitle" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<v-list class="config-list">
|
||||
@@ -61,11 +61,24 @@
|
||||
<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 prepend-icon="mdi-folder" title="打开用户数据目录" @click="openMergeData" />
|
||||
<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')" />
|
||||
@@ -115,13 +128,19 @@
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item title="删除 IndexedDB" prepend-icon="mdi-delete" @click="tryConfirm('delDB')" />
|
||||
<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.appDataDir }}</v-list-item-subtitle>
|
||||
<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>
|
||||
@@ -133,7 +152,7 @@
|
||||
{{ snackbarText }}
|
||||
</v-snackbar>
|
||||
<!-- 确认弹窗 -->
|
||||
<TConfirm v-model="confirmShow" :title="confirmText" @confirm="doConfirm(confirmOper)" />
|
||||
<TConfirm v-model="confirmShow" :title="confirmText" :subtitle="confirmSub" @confirm="doConfirm(confirmOper)" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -141,20 +160,18 @@
|
||||
// vue
|
||||
import { onMounted, ref } from "vue";
|
||||
import { getBuildTime } from "../utils/TGBuild";
|
||||
|
||||
import TLoading from "../components/t-loading.vue";
|
||||
import TConfirm from "../components/t-confirm.vue";
|
||||
// tauri
|
||||
import { dialog, fs, app, os, tauri } from "@tauri-apps/api";
|
||||
import { fs, app, os, tauri } from "@tauri-apps/api";
|
||||
// store
|
||||
import { useAppStore } from "../store/modules/app";
|
||||
import { useHomeStore } from "../store/modules/home";
|
||||
import { useHk4eStore } from "../store/modules/hk4e";
|
||||
import { useAchievementsStore } from "../store/modules/achievements";
|
||||
// utils
|
||||
import { WriteTGData, DeleteTGData } from "../utils/TGIndex";
|
||||
// data
|
||||
import { getDataList } from "../data/init";
|
||||
import { backupUiafData, restoreUiafData } from "../utils/UIAF";
|
||||
import TGSqlite from "../utils/TGSqlite";
|
||||
|
||||
// Store
|
||||
const appStore = useAppStore();
|
||||
@@ -169,9 +186,11 @@ const buildTime = ref(getBuildTime());
|
||||
// About OS
|
||||
const osPlatform = ref("" as string);
|
||||
const osVersion = ref("" as string);
|
||||
const dbInfo = ref([] as { key: string, value: string, updated: string }[]);
|
||||
|
||||
// loading
|
||||
const loading = ref(true as boolean);
|
||||
const loadingTitle = ref("正在加载..." as string);
|
||||
|
||||
// data
|
||||
const showHome = ref(homeStore.getShowValue() as string[]);
|
||||
@@ -184,6 +203,7 @@ const snackbarColor = ref("success" as string);
|
||||
|
||||
// confirm
|
||||
const confirmText = ref("" as string);
|
||||
const confirmSub = ref("" as string);
|
||||
const confirmOper = ref("" as string);
|
||||
const confirmShow = ref(false as boolean);
|
||||
|
||||
@@ -193,9 +213,8 @@ onMounted(async () => {
|
||||
versionTauri.value = await app.getTauriVersion();
|
||||
osPlatform.value = `${await os.platform()}`;
|
||||
osVersion.value = await os.version();
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
}, 1000);
|
||||
dbInfo.value = await TGSqlite.getAppData();
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
// 打开外部链接
|
||||
@@ -203,17 +222,22 @@ function toOuter (url: string) {
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
// 打开用户数据目录
|
||||
async function openMergeData () {
|
||||
await dialog.open({
|
||||
defaultPath: appStore.dataPath.userDataDir,
|
||||
filters: [],
|
||||
});
|
||||
}
|
||||
|
||||
// open confirm
|
||||
function tryConfirm (oper: string) {
|
||||
confirmSub.value = "";
|
||||
switch (oper) {
|
||||
case "backup":
|
||||
confirmText.value = "确认备份数据吗?";
|
||||
confirmSub.value = "若已备份将会被覆盖";
|
||||
confirmOper.value = "backup";
|
||||
confirmShow.value = true;
|
||||
break;
|
||||
case "restore":
|
||||
confirmText.value = "确认恢复数据吗?";
|
||||
confirmSub.value = "请确保存在备份数据";
|
||||
confirmOper.value = "restore";
|
||||
confirmShow.value = true;
|
||||
break;
|
||||
case "delTemp":
|
||||
confirmText.value = "确认清除临时数据吗?";
|
||||
confirmOper.value = "delTemp";
|
||||
@@ -221,6 +245,7 @@ function tryConfirm (oper: string) {
|
||||
break;
|
||||
case "delUser":
|
||||
confirmText.value = "确认清除用户缓存吗?";
|
||||
confirmSub.value = "备份数据也将被清除";
|
||||
confirmOper.value = "delUser";
|
||||
confirmShow.value = true;
|
||||
break;
|
||||
@@ -241,15 +266,34 @@ function tryConfirm (oper: string) {
|
||||
break;
|
||||
case "delDB":
|
||||
confirmText.value = "确认清除 IndexedDB 吗?";
|
||||
confirmSub.value = "Alpha v0.1.4 后不再支持 IndexedDB";
|
||||
confirmOper.value = "delDB";
|
||||
confirmShow.value = true;
|
||||
break;
|
||||
case "checkDB":
|
||||
confirmText.value = "将检测数据库表单完整性";
|
||||
confirmSub.value = "数据库版本与更新时间也会进行检测";
|
||||
confirmOper.value = "checkDB";
|
||||
confirmShow.value = true;
|
||||
break;
|
||||
case "resetDB":
|
||||
confirmText.value = "确认重置数据库吗?";
|
||||
confirmSub.value = "请确认已经备份关键数据";
|
||||
confirmOper.value = "resetDB";
|
||||
confirmShow.value = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// transfer confirm oper
|
||||
async function doConfirm (oper: string) {
|
||||
switch (oper) {
|
||||
case "backup":
|
||||
await backupData();
|
||||
break;
|
||||
case "restore":
|
||||
await restoreData();
|
||||
break;
|
||||
case "delTemp":
|
||||
await delTempData();
|
||||
break;
|
||||
@@ -269,12 +313,48 @@ async function doConfirm (oper: string) {
|
||||
case "delDB":
|
||||
delDB();
|
||||
break;
|
||||
case "checkDB":
|
||||
await checkDB();
|
||||
break;
|
||||
case "resetDB":
|
||||
await resetDB();
|
||||
break;
|
||||
case "updateDB":
|
||||
await updateDB();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// confirmOper
|
||||
async function backupData () {
|
||||
loadingTitle.value = "正在备份数据...";
|
||||
loading.value = true;
|
||||
const achievements = await TGSqlite.getUIAF();
|
||||
await backupUiafData(achievements);
|
||||
loading.value = false;
|
||||
snackbarText.value = "数据已备份!";
|
||||
snackbarColor.value = "success";
|
||||
snackbar.value = true;
|
||||
}
|
||||
|
||||
async function restoreData () {
|
||||
loadingTitle.value = "正在恢复数据...";
|
||||
loading.value = true;
|
||||
const res = await restoreUiafData();
|
||||
loading.value = false;
|
||||
if (res !== false) {
|
||||
snackbarText.value = "数据已恢复!";
|
||||
snackbarColor.value = "success";
|
||||
snackbar.value = true;
|
||||
} else {
|
||||
snackbarText.value = "未检测到备份数据!";
|
||||
snackbarColor.value = "error";
|
||||
snackbar.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
async function delTempData () {
|
||||
await fs.removeDir("tempData", {
|
||||
dir: fs.BaseDirectory.AppLocalData,
|
||||
@@ -290,18 +370,10 @@ async function delUserData () {
|
||||
dir: fs.BaseDirectory.AppLocalData,
|
||||
recursive: true,
|
||||
});
|
||||
await fs.removeDir("tempData", {
|
||||
dir: fs.BaseDirectory.AppLocalData,
|
||||
recursive: true,
|
||||
});
|
||||
getDataList.map(async (item) => {
|
||||
await WriteTGData(item.name, item.data);
|
||||
});
|
||||
snackbarText.value = "用户数据已删除!";
|
||||
snackbar.value = true;
|
||||
achievementsStore.init();
|
||||
await fs.createDir("userData", { dir: fs.BaseDirectory.AppLocalData });
|
||||
await fs.createDir("tempData", { dir: fs.BaseDirectory.AppLocalData });
|
||||
}
|
||||
|
||||
// 恢复默认配置
|
||||
@@ -309,7 +381,7 @@ function initAppData () {
|
||||
appStore.init();
|
||||
homeStore.init();
|
||||
achievementsStore.init();
|
||||
snackbarText.value = "已恢复默认配置!";
|
||||
snackbarText.value = "已恢复默认配置!即将刷新页面...";
|
||||
snackbar.value = true;
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
@@ -364,11 +436,73 @@ async function readCookie () {
|
||||
|
||||
// 删除 IndexedDB
|
||||
function delDB () {
|
||||
DeleteTGData();
|
||||
window.indexedDB.deleteDatabase("TGData");
|
||||
snackbarText.value = "IndexedDB 已清除!若无法正常使用,请初始化配置。";
|
||||
snackbarColor.value = "success";
|
||||
snackbar.value = true;
|
||||
}
|
||||
|
||||
// 检查 SQLite 数据库
|
||||
async function checkDB () {
|
||||
loadingTitle.value = "正在检查数据库表单完整性...";
|
||||
loading.value = true;
|
||||
const res = await TGSqlite.check();
|
||||
if (!res) {
|
||||
confirmOper.value = "resetDB";
|
||||
confirmText.value = "数据库表单不完整,是否重置数据库?";
|
||||
loading.value = false;
|
||||
confirmShow.value = true;
|
||||
} else {
|
||||
const appVersion = await app.getVersion();
|
||||
const dbVersion = dbInfo.value.find((item) => item.key === "appVersion")?.value;
|
||||
const dbUpdatedTime = dbInfo.value.find((item) => item.key === "dataUpdated")?.value;
|
||||
if (!dbVersion || dbVersion < appVersion) {
|
||||
confirmOper.value = "updateDB";
|
||||
confirmText.value = "数据库版本过低,是否更新数据库?";
|
||||
loading.value = false;
|
||||
confirmShow.value = true;
|
||||
return;
|
||||
} else if (!buildTime.value.startsWith("dev")) {
|
||||
if (!dbUpdatedTime || dbUpdatedTime < buildTime.value) {
|
||||
confirmOper.value = "updateDB";
|
||||
confirmText.value = "数据库可能过时,是否更新数据库?";
|
||||
loading.value = false;
|
||||
confirmShow.value = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
loading.value = false;
|
||||
snackbarText.value = "数据库已是最新!";
|
||||
snackbarColor.value = "success";
|
||||
snackbar.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 重置 SQLite 数据库
|
||||
async function resetDB () {
|
||||
loadingTitle.value = "正在重置数据库...";
|
||||
loading.value = true;
|
||||
await TGSqlite.reset();
|
||||
loading.value = false;
|
||||
snackbarText.value = "数据库已重置!请进行再次检查。";
|
||||
snackbarColor.value = "success";
|
||||
snackbar.value = true;
|
||||
// 刷新
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// 更新 SQLite 数据库
|
||||
async function updateDB () {
|
||||
loadingTitle.value = "正在更新数据库...";
|
||||
loading.value = true;
|
||||
await TGSqlite.update();
|
||||
loading.value = false;
|
||||
snackbarText.value = "数据库已是最新!";
|
||||
snackbarColor.value = "success";
|
||||
snackbar.value = true;
|
||||
// 刷新
|
||||
window.location.reload();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
|
||||
@@ -12,6 +12,8 @@ import TPosition from "../components/t-position.vue";
|
||||
import TCalendar from "../components/t-calendar.vue";
|
||||
// store
|
||||
import { useHomeStore } from "../store/modules/home";
|
||||
// utils
|
||||
import TGSqlite from "../utils/TGSqlite";
|
||||
|
||||
// store
|
||||
const homeStore = useHomeStore();
|
||||
@@ -40,6 +42,12 @@ function readLoading (): void {
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadingTitle.value = "正在检测数据完整性";
|
||||
const isOK = await TGSqlite.check();
|
||||
if (!isOK) {
|
||||
loadingTitle.value = "正在修复数据";
|
||||
await TGSqlite.reset();
|
||||
}
|
||||
loadingTitle.value = "正在加载首页";
|
||||
const showItems = homeStore.getShowValue();
|
||||
await Promise.allSettled(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file plugins Mys utils gacha.ts
|
||||
* @description Mys 插件抽卡工具
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.2
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
import { getPostData } from "../request/post";
|
||||
@@ -10,7 +10,7 @@ import { type GachaCard, type GachaData } from "../interface/gacha";
|
||||
|
||||
/**
|
||||
* @description 根据卡池信息转为渲染用的卡池信息
|
||||
* @since Alpha v0.1.2
|
||||
* @since Alpha v0.1.4
|
||||
* @param {GachaData[]} gachaData 卡池信息
|
||||
* @param {Map<string>} poolCover 卡池封面
|
||||
* @returns {Promise<GachaCard[]>}
|
||||
@@ -42,19 +42,22 @@ export async function getGachaCard (
|
||||
title: data.title,
|
||||
subtitle: data.content_before_act,
|
||||
cover,
|
||||
// eslint-disable-next-line camelcase
|
||||
post_id: postId,
|
||||
characters: data.pool.map((character) => ({
|
||||
icon: character.icon,
|
||||
url: character.url,
|
||||
})),
|
||||
voice: {
|
||||
icon: data.voice_icon,
|
||||
icon: data.voice_icon || "/source/UI/defaultUser.webp",
|
||||
url: data.voice_url,
|
||||
},
|
||||
time: {
|
||||
start: data.start_time,
|
||||
// eslint-disable-next-line camelcase
|
||||
start_stamp: new Date(data.start_time).getTime(),
|
||||
end: data.end_time,
|
||||
// eslint-disable-next-line camelcase
|
||||
end_stamp: new Date(data.end_time).getTime(),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file store modules app.ts
|
||||
* @description App store module
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.3
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
// vue
|
||||
@@ -12,18 +12,20 @@ import { defineStore } from "pinia";
|
||||
// tauri
|
||||
import { path } from "@tauri-apps/api";
|
||||
|
||||
// 用于存储原生数据的路径
|
||||
const appDataDir = `${await path.appLocalDataDir()}appData`;
|
||||
// 用于存储用户数据的路径
|
||||
const userDataDir = `${await path.appLocalDataDir()}userData`;
|
||||
// 用于各种临时数据的路径
|
||||
const tempDataDir = `${await path.appLocalDataDir()}tempData`;
|
||||
// 用于存放数据库的路径
|
||||
const dbDataPath = `${await path.appConfigDir()}tauri-genshin.db`;
|
||||
|
||||
export const useAppStore = defineStore(
|
||||
"app",
|
||||
() => {
|
||||
// 应用加载状态
|
||||
const loading = ref(false);
|
||||
// 应用打包时间
|
||||
const buildTime = ref("");
|
||||
// 侧边栏设置
|
||||
const sidebar = reactive({
|
||||
// 是否折叠
|
||||
@@ -42,20 +44,13 @@ export const useAppStore = defineStore(
|
||||
const theme = ref("default");
|
||||
|
||||
const dataPath = reactive({
|
||||
appDataDir,
|
||||
userDataDir,
|
||||
tempDataDir,
|
||||
dbDataPath,
|
||||
});
|
||||
|
||||
// 应用数据路径
|
||||
const appPath = ref({
|
||||
achievements: `${dataPath.appDataDir}/achievements.json`,
|
||||
achievementSeries: `${dataPath.appDataDir}/achievementSeries.json`,
|
||||
nameCards: `${dataPath.appDataDir}/nameCards.json`,
|
||||
});
|
||||
// 用户数据路径
|
||||
// 用户数据路径
|
||||
const userPath = ref({
|
||||
achievements: `${dataPath.userDataDir}/achievements.json`,
|
||||
UIAF: `${dataPath.userDataDir}/UIAF.json`,
|
||||
});
|
||||
|
||||
// 初始化
|
||||
@@ -82,10 +77,10 @@ export const useAppStore = defineStore(
|
||||
return {
|
||||
theme,
|
||||
loading,
|
||||
buildTime,
|
||||
sidebar,
|
||||
devMode,
|
||||
dataPath,
|
||||
appPath,
|
||||
userPath,
|
||||
init,
|
||||
getSubmenu,
|
||||
@@ -97,12 +92,12 @@ export const useAppStore = defineStore(
|
||||
{
|
||||
key: "appPath",
|
||||
storage: window.localStorage,
|
||||
paths: ["dataPath", "appPath", "userPath"],
|
||||
paths: ["dataPath", "userPath"],
|
||||
},
|
||||
{
|
||||
key: "app",
|
||||
storage: window.localStorage,
|
||||
paths: ["devMode", "loading"],
|
||||
paths: ["devMode", "loading", "buildTime"],
|
||||
},
|
||||
{
|
||||
key: "sidebar",
|
||||
|
||||
80
src/types/Achievement.d.ts
vendored
80
src/types/Achievement.d.ts
vendored
@@ -2,13 +2,13 @@
|
||||
* @file types Achievement.d.ts
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @description 成就相关类型定义
|
||||
* @since Alpha v0.1.2
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
declare namespace BTMuli.Genshin {
|
||||
/**
|
||||
* @description 本应用的成就类型
|
||||
* @since Alpha v0.1.2
|
||||
* @since Alpha v0.1.4
|
||||
* @interface Achievement
|
||||
* @property {number} id - 成就 ID
|
||||
* @property {number} series - 成就系列 ID
|
||||
@@ -16,9 +16,6 @@ declare namespace BTMuli.Genshin {
|
||||
* @property {string} name - 成就名称
|
||||
* @property {string} description - 成就描述
|
||||
* @property {number} reward - 成就奖励
|
||||
* @property {boolean} completed - 成就是否完成
|
||||
* @property {string} completed_time - 成就完成时间
|
||||
* @property {number} progress - 成就进度
|
||||
* @property {string} version - 成就版本
|
||||
* @return Achievement
|
||||
*/
|
||||
@@ -29,22 +26,16 @@ declare namespace BTMuli.Genshin {
|
||||
name: string
|
||||
description: string
|
||||
reward: number
|
||||
completed: boolean
|
||||
completed_time: string | null
|
||||
progress: number
|
||||
version: string
|
||||
}
|
||||
/**
|
||||
* @description 本应用的成就系列类型
|
||||
* @since Alpha v0.1.2
|
||||
* @since Alpha v0.1.4
|
||||
* @interface AchievementSeries
|
||||
* @property {number} id - 成就系列 ID
|
||||
* @property {number} order - 成就系列排列顺序,用于展示全部成就系列
|
||||
* @property {string} name - 成就系列名称
|
||||
* @property {string} version - 成就系列版本
|
||||
* @property {number[]} achievements - 成就系列包含的成就
|
||||
* @property {number} total_count - 成就系列包含的成就数
|
||||
* @property {number} completed_count - 成就系列已完成的成就数
|
||||
* @property {string} card - 成就系列对应名片
|
||||
* @property {string} icon - 成就系列图标
|
||||
* @return AchievementSeries
|
||||
@@ -54,10 +45,7 @@ declare namespace BTMuli.Genshin {
|
||||
order: number
|
||||
name: string
|
||||
version: string
|
||||
achievements: number[]
|
||||
total_count: number
|
||||
completed_count: number
|
||||
card?: string
|
||||
card: string
|
||||
icon: string
|
||||
}
|
||||
}
|
||||
@@ -109,3 +97,63 @@ declare namespace TGPlugin.UIAF {
|
||||
status: number
|
||||
}
|
||||
}
|
||||
|
||||
declare namespace BTMuli.SQLite {
|
||||
/**
|
||||
* @description 数据库-成就表
|
||||
* @since Alpha v0.1.4
|
||||
* @interface Achievements
|
||||
* @property {number} id - 成就 ID
|
||||
* @property {number} series - 成就系列 ID
|
||||
* @property {number} order - 成就排列顺序,用于展示全部成就
|
||||
* @property {string} name - 成就名称
|
||||
* @property {string} description - 成就描述
|
||||
* @property {number} reward - 成就奖励
|
||||
* @property {number} isCompleted - 成就是否完成
|
||||
* @property {string} completedTime - 成就完成时间
|
||||
* @property {number} progress - 成就进度
|
||||
* @property {string} version - 成就版本
|
||||
* @property {string} updated - 数据库更新时间
|
||||
* @return Achievements
|
||||
*/
|
||||
export interface Achievements {
|
||||
id: number
|
||||
series: number
|
||||
order: number
|
||||
name: string
|
||||
description: string
|
||||
reward: number
|
||||
isCompleted: 0 | 1
|
||||
completedTime: string
|
||||
progress: number
|
||||
version: string
|
||||
updated: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 数据库-成就系列表
|
||||
* @since Alpha v0.1.4
|
||||
* @interface AchievementSeries
|
||||
* @property {number} id - 成就系列 ID
|
||||
* @property {number} order - 成就系列排列顺序,用于展示全部成就系列
|
||||
* @property {string} name - 成就系列名称
|
||||
* @property {string} version - 成就系列版本
|
||||
* @property {number} totalConut - 成就系列包含的成就数
|
||||
* @property {number} finCount - 成就系列已完成的成就数
|
||||
* @property {string} icon - 成就系列图标
|
||||
* @property {string} nameCard - 成就系列对应名片
|
||||
* @property {string} updated - 数据库更新时间
|
||||
* @returns AchievementSeries
|
||||
*/
|
||||
export interface AchievementSeries {
|
||||
id: number
|
||||
order: number
|
||||
name: string | null
|
||||
version: string | null
|
||||
totalCount: number
|
||||
finCount: number
|
||||
icon: string
|
||||
nameCard: string | null
|
||||
updated: string | null
|
||||
}
|
||||
}
|
||||
|
||||
31
src/types/NameCard.d.ts
vendored
31
src/types/NameCard.d.ts
vendored
@@ -2,7 +2,7 @@
|
||||
* @file core types TGNameCard.d.ts
|
||||
* @description 本应用的名片类型定义
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.2
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
declare namespace BTMuli.Genshin {
|
||||
@@ -29,3 +29,32 @@ declare namespace BTMuli.Genshin {
|
||||
source: string
|
||||
}
|
||||
}
|
||||
|
||||
declare namespace BTMuli.SQLite {
|
||||
/**
|
||||
* @description 数据库内的名片类型
|
||||
* @since Alpha v0.1.4
|
||||
* @interface NameCard
|
||||
* @property {number} id - 名片 ID
|
||||
* @property {string} name - 名片名称
|
||||
* @property {string} description - 名片描述
|
||||
* @property {string} icon - 名片图标路径
|
||||
* @property {string} bg - 名片背景图路径
|
||||
* @property {string} profile - 名片 Profile 图路径
|
||||
* @property {number} type - 名片类型 (0: 其他,1: 成就,2:角色,3:纪行,4:活动)
|
||||
* @property {string} source - 名片来源
|
||||
* @property {string} updated - 名片更新时间
|
||||
* @returns {NameCard}
|
||||
*/
|
||||
export interface NameCard {
|
||||
id: number
|
||||
name: string
|
||||
description: string
|
||||
icon: string
|
||||
bg: string
|
||||
profile: string
|
||||
type: number
|
||||
source: string
|
||||
updated: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @description 用于获取 vite 打包时间
|
||||
* @see https://gitee.com/lihanspace/vite-plugin-build-time
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.2
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
import { type Plugin } from "vite";
|
||||
@@ -21,7 +21,7 @@ const buildTimePlugin = (modes: string[] = []): Plugin => {
|
||||
if (_mode !== "production" && !modes.includes(_mode)) return;
|
||||
return [{
|
||||
tag: "script",
|
||||
children: `window.${buildTimeKey} = ${Math.floor(Date.now() / 1000)}`,
|
||||
children: `window.${buildTimeKey} = '${Math.floor(Date.now() / 1000)}'`,
|
||||
}];
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
/**
|
||||
* @file utils TGIndex.ts
|
||||
* @description IndexedDB utils
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.2
|
||||
*/
|
||||
|
||||
import { TGConfigList } from "../data";
|
||||
|
||||
// 数据库参数
|
||||
export const DB_NAME = "TGData";
|
||||
export const DB_VERSION = 1;
|
||||
|
||||
/**
|
||||
* @description 初始化数据库
|
||||
* @description 只会在第一次打开游戏时执行
|
||||
* @since Alpha v0.1.2
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function InitTGData (): Promise<void> {
|
||||
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
||||
request.onupgradeneeded = () => {
|
||||
const db = request.result;
|
||||
// 创建表
|
||||
TGConfigList.forEach((config) => {
|
||||
const store = db.createObjectStore(config.storeName, {
|
||||
keyPath: config.keyPath,
|
||||
});
|
||||
config.indexes.forEach((index) => {
|
||||
store.createIndex(index, index, { unique: false });
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 删除数据库
|
||||
* @since Alpha
|
||||
* @returns {void}
|
||||
*/
|
||||
export function DeleteTGData (): void {
|
||||
window.indexedDB.deleteDatabase(DB_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 向数据库中写入数据
|
||||
* @since Alpha
|
||||
* @param {string} storeName 表名
|
||||
* @param {any[]} data 数据
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function WriteTGData (storeName: string, data: any[]): Promise<void> {
|
||||
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
||||
request.onsuccess = () => {
|
||||
const db = request.result;
|
||||
const transaction = db.transaction(storeName, "readwrite");
|
||||
const store = transaction.objectStore(storeName);
|
||||
data.forEach((item) => {
|
||||
store.put(item);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 更新数据库中的单条数据-根据主键
|
||||
* @since Alpha
|
||||
* @param {string} storeName 表名
|
||||
* @param {any} data 数据
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function UpdateTGDataByKey (storeName: string, data: any): Promise<void> {
|
||||
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
||||
request.onsuccess = () => {
|
||||
const db = request.result;
|
||||
const transaction = db.transaction(storeName, "readwrite");
|
||||
const store = transaction.objectStore(storeName);
|
||||
store.put(data);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 更新数据库中的单条数据-根据索引
|
||||
* @since Alpha
|
||||
* @param {string} storeName 表名
|
||||
* @param {string} indexName 索引名
|
||||
* @param {any} key 索引值
|
||||
* @param {any} data 数据
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function UpdateTGDataByIndex (storeName: string, indexName: string, key: any, data: any): Promise<void> {
|
||||
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
||||
request.onsuccess = () => {
|
||||
const db = request.result;
|
||||
const transaction = db.transaction(storeName, "readwrite");
|
||||
const store = transaction.objectStore(storeName);
|
||||
const index = store.index(indexName);
|
||||
const requestData = index.getAll(key);
|
||||
requestData.onsuccess = () => {
|
||||
const result = requestData.result;
|
||||
result.forEach((item) => {
|
||||
Object.keys(data).forEach((key) => {
|
||||
item[key] = data[key];
|
||||
});
|
||||
store.put(item);
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 从数据库中读取某些数据-按照主键
|
||||
* @since Alpha
|
||||
* @param {string} storeName 表名
|
||||
* @param {any[]} keys 主键值
|
||||
* @returns {Promise<any[]>}
|
||||
*/
|
||||
export async function ReadTGDataByKey (storeName: string, keys: any[]): Promise<any[]> {
|
||||
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
||||
return await new Promise((resolve, reject) => {
|
||||
request.onsuccess = () => {
|
||||
const db = request.result;
|
||||
const transaction = db.transaction(storeName, "readonly");
|
||||
const store = transaction.objectStore(storeName);
|
||||
const requestData = store.getAll();
|
||||
requestData.onsuccess = () => {
|
||||
const result = requestData.result;
|
||||
const data = result.filter((item) => {
|
||||
return keys.includes(item.id);
|
||||
});
|
||||
resolve(data);
|
||||
};
|
||||
requestData.onerror = () => {
|
||||
reject(requestData.error);
|
||||
};
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 从数据库中读取某些数据-按照索引
|
||||
* @since Alpha
|
||||
* @param {string} storeName 表名
|
||||
* @param {string} indexName 索引名
|
||||
* @param {any} key 索引值
|
||||
* @returns {Promise<any[]>}
|
||||
*/
|
||||
export async function ReadTGDataByIndex (storeName: string, indexName: string, key: any): Promise<any[]> {
|
||||
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
||||
return await new Promise((resolve, reject) => {
|
||||
request.onsuccess = () => {
|
||||
const db = request.result;
|
||||
const transaction = db.transaction(storeName, "readonly");
|
||||
const store = transaction.objectStore(storeName);
|
||||
const index = store.index(indexName);
|
||||
const requestData = index.getAll(key);
|
||||
requestData.onsuccess = () => {
|
||||
resolve(requestData.result);
|
||||
};
|
||||
requestData.onerror = () => {
|
||||
reject(requestData.error);
|
||||
};
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 从数据库中读取所有数据
|
||||
* @since Alpha
|
||||
* @param {string} storeName 表名
|
||||
* @returns {Promise<any[]>}
|
||||
*/
|
||||
export async function ReadAllTGData (storeName: string): Promise<any[]> {
|
||||
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
||||
return await new Promise((resolve, reject) => {
|
||||
request.onsuccess = () => {
|
||||
const db = request.result;
|
||||
const transaction = db.transaction(storeName, "readonly");
|
||||
const store = transaction.objectStore(storeName);
|
||||
const requestData = store.getAll();
|
||||
requestData.onsuccess = () => {
|
||||
resolve(requestData.result);
|
||||
};
|
||||
requestData.onerror = () => {
|
||||
reject(requestData.error);
|
||||
};
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
}
|
||||
265
src/utils/TGSql.ts
Normal file
265
src/utils/TGSql.ts
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @file utils TGSql.ts
|
||||
* @description 数据库sql语句
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
import { app } from "@tauri-apps/api";
|
||||
import { getBuildTime } from "./TGBuild";
|
||||
import { TGAppData } from "../data";
|
||||
|
||||
/**
|
||||
* @description 初始化应用数据表
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {string[]} sql
|
||||
*/
|
||||
function initAppTable (): string[] {
|
||||
const sqlRes = [];
|
||||
// 创建应用数据表
|
||||
sqlRes.push(`
|
||||
CREATE TABLE IF NOT EXISTS AppData
|
||||
(
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT DEFAULT NULL,
|
||||
updated TEXT DEFAULT NULL
|
||||
);
|
||||
`);
|
||||
return sqlRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 初始化成就系列数据表
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {string[]} sql
|
||||
*/
|
||||
function initAchievementSeriesTable (): string[] {
|
||||
const sqlRes = [];
|
||||
// 创建成就系列数据表
|
||||
sqlRes.push(`
|
||||
CREATE TABLE IF NOT EXISTS AchievementSeries
|
||||
(
|
||||
id INTEGER PRIMARY KEY,
|
||||
"order" INTEGER,
|
||||
name TEXT DEFAULT NULL,
|
||||
version TEXT DEFAULT NULL,
|
||||
totalCount INTEGER DEFAULT 0,
|
||||
finCount INTEGER DEFAULT 0,
|
||||
icon TEXT NOT NULL,
|
||||
nameCard TEXT NOT NULL,
|
||||
updated TEXT DEFAULT NULL
|
||||
);
|
||||
`);
|
||||
return sqlRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 初始化成就数据表
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {string[]} sql
|
||||
*/
|
||||
function initAchievementTable (): string[] {
|
||||
const sqlRes = [];
|
||||
// 创建成就数据表
|
||||
sqlRes.push(`
|
||||
CREATE TABLE IF NOT EXISTS Achievements
|
||||
(
|
||||
id INTEGER PRIMARY KEY,
|
||||
series INTEGER,
|
||||
"order" INTEGER,
|
||||
name TEXT DEFAULT NULL,
|
||||
description TEXT DEFAULT NULL,
|
||||
reward INTEGER DEFAULT 0,
|
||||
isCompleted BOOLEAN DEFAULT 0,
|
||||
completedTime TEXT DEFAULT NULL,
|
||||
progress INTEGER DEFAULT 0,
|
||||
version TEXT DEFAULT NULL,
|
||||
updated TEXT DEFAULT NULL
|
||||
);
|
||||
`);
|
||||
// 创建触发器
|
||||
sqlRes.push(`
|
||||
CREATE TRIGGER IF NOT EXISTS updateAchievement
|
||||
AFTER UPDATE ON Achievements
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE AchievementSeries SET finCount = finCount + 1, updated = datetime('now', 'localtime')
|
||||
WHERE id = NEW.series AND NEW.isCompleted = 1 AND OLD.isCompleted = 0;
|
||||
UPDATE AchievementSeries SET finCount = finCount - 1, updated = datetime('now', 'localtime')
|
||||
WHERE id = NEW.series AND NEW.isCompleted = 0 AND OLD.isCompleted = 1;
|
||||
END;
|
||||
`);
|
||||
sqlRes.push(`
|
||||
CREATE TRIGGER IF NOT EXISTS insertAchievement
|
||||
AFTER INSERT ON Achievements
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE AchievementSeries SET totalCount = totalCount + 1, updated = datetime('now', 'localtime')
|
||||
WHERE id = NEW.series;
|
||||
UPDATE AchievementSeries SET version = NEW.version, updated = datetime('now', 'localtime')
|
||||
WHERE id = NEW.series AND NEW.version > version;
|
||||
END;
|
||||
`);
|
||||
return sqlRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 初始化名片数据表
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {string[]} sql
|
||||
*/
|
||||
function initNameCardTable (): string[] {
|
||||
const sqlRes = [];
|
||||
// 创建名片数据表
|
||||
sqlRes.push(`
|
||||
CREATE TABLE IF NOT EXISTS NameCard
|
||||
(
|
||||
name TEXT PRIMARY KEY,
|
||||
description TEXT DEFAULT NULL,
|
||||
icon TEXT NOT NULL,
|
||||
bg TEXT NOT NULL,
|
||||
profile TEXT NOT NULL,
|
||||
type INTEGER DEFAULT 0,
|
||||
source TEXT DEFAULT NULL,
|
||||
updated TEXT DEFAULT NULL
|
||||
);
|
||||
`);
|
||||
return sqlRes;
|
||||
}
|
||||
/**
|
||||
* @description 初始化数据库表
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {string[]} sql
|
||||
*/
|
||||
export function initSQLiteTable (): string[] {
|
||||
const sqlRes = [];
|
||||
sqlRes.push(...initAppTable());
|
||||
sqlRes.push(...initAchievementSeriesTable());
|
||||
sqlRes.push(...initAchievementTable());
|
||||
sqlRes.push(...initNameCardTable());
|
||||
return sqlRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 初始化应用数据
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<string[]>} sql
|
||||
*/
|
||||
async function initAppData (): Promise<string[]> {
|
||||
const sqlRes = [];
|
||||
const appVersion = await app.getVersion();
|
||||
const buildTime = getBuildTime();
|
||||
const dataUpdated = buildTime.startsWith("dev") ? buildTime.slice(4) : buildTime;
|
||||
// 初始化应用版本
|
||||
sqlRes.push(`
|
||||
INSERT INTO AppData (key, value, updated)
|
||||
VALUES ('appVersion', '${appVersion}', datetime('now', 'localtime'))
|
||||
ON CONFLICT(key) DO UPDATE SET value = '${appVersion}', updated = datetime('now', 'localtime');
|
||||
`);
|
||||
// 初始化应用数据更新时间
|
||||
sqlRes.push(`
|
||||
INSERT INTO AppData (key, value, updated)
|
||||
VALUES ('dataUpdated', '${dataUpdated}', datetime('now', 'localtime'))
|
||||
ON CONFLICT(key) DO UPDATE SET value = '${dataUpdated}', updated = datetime('now', 'localtime');
|
||||
`);
|
||||
return sqlRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 初始化成就系列数据
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {string[]} sql
|
||||
*/
|
||||
function initAchievementSeriesData (): string[] {
|
||||
const sqlRes: string[] = [];
|
||||
const oriData = TGAppData.achievementSeries;
|
||||
oriData.map((data) => {
|
||||
const sql = `
|
||||
INSERT OR IGNORE INTO AchievementSeries (id, "order", name, version, icon, nameCard, updated)
|
||||
VALUES (${data.id}, ${data.order}, '${data.name}', '${data.version}', '${data.icon}', '${data.card}', datetime('now', 'localtime'));
|
||||
`;
|
||||
return sqlRes.push(sql);
|
||||
});
|
||||
return sqlRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 初始化成就数据
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {string[]} sql
|
||||
*/
|
||||
function initAchievementData (): string[] {
|
||||
const sqlRes: string[] = [];
|
||||
const oriData = TGAppData.achievements;
|
||||
oriData.map((data) => {
|
||||
const sql = `
|
||||
INSERT OR IGNORE INTO Achievements (id, series, "order", name, description, reward, version, updated)
|
||||
VALUES (${data.id}, ${data.series}, ${data.order}, '${data.name}', '${data.description}', ${data.reward}, '${data.version}', datetime('now', 'localtime'));
|
||||
`;
|
||||
return sqlRes.push(sql);
|
||||
});
|
||||
return sqlRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 初始化名片数据
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {string[]} sql
|
||||
*/
|
||||
function initNameCardData (): string[] {
|
||||
const sqlRes: string[] = [];
|
||||
const oriData = TGAppData.nameCards;
|
||||
oriData.map((data) => {
|
||||
const sql = `
|
||||
INSERT OR IGNORE INTO NameCard (name, description, icon, bg, profile, type, source, updated)
|
||||
VALUES ('${data.name}', '${data.description}', '${data.icon}', '${data.bg}', '${data.profile}', ${data.type}, '${data.source}', datetime('now', 'localtime'));
|
||||
`;
|
||||
return sqlRes.push(sql);
|
||||
});
|
||||
return sqlRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 初始化数据库数据
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<string[]>} sql
|
||||
*/
|
||||
export async function initSQLiteData (): Promise<string[]> {
|
||||
const sqlRes = [];
|
||||
sqlRes.push(...initAchievementSeriesData());
|
||||
sqlRes.push(...initAchievementData());
|
||||
sqlRes.push(...initNameCardData());
|
||||
sqlRes.push(...await initAppData());
|
||||
return sqlRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 导入UIAF数据
|
||||
* @since Alpha v0.1.4
|
||||
* @param {TGPlugin.UIAF.Achievement[]} data
|
||||
* @returns {string[]} sql
|
||||
*/
|
||||
export function importUIAFData (data: TGPlugin.UIAF.Achievement[]): string[] {
|
||||
const sqlRes: string[] = [];
|
||||
data.map((achievement) => {
|
||||
let sql;
|
||||
// 获取完成状态
|
||||
const isCompleted = achievement.status === 2 || achievement.status === 3;
|
||||
if (isCompleted) {
|
||||
const completedTime = new Date(achievement.timestamp * 1000).toISOString().replace("T", " ").slice(0, 19);
|
||||
sql = `
|
||||
UPDATE Achievements
|
||||
SET isCompleted = 1, completedTime = '${completedTime}', progress = ${achievement.current}, updated = datetime('now', 'localtime')
|
||||
WHERE id = ${achievement.id} AND (isCompleted = 0 OR completedTime != '${completedTime}' OR progress != ${achievement.current});
|
||||
`;
|
||||
} else {
|
||||
sql = `
|
||||
UPDATE Achievements
|
||||
SET progress = ${achievement.current}, updated = datetime('now', 'localtime')
|
||||
WHERE id = ${achievement.id} AND progress != ${achievement.current};
|
||||
`;
|
||||
}
|
||||
return sqlRes.push(sql);
|
||||
});
|
||||
return sqlRes;
|
||||
}
|
||||
265
src/utils/TGSqlite.ts
Normal file
265
src/utils/TGSqlite.ts
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @description 数据库操作类
|
||||
* @class TGSqlite
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
// tauri
|
||||
import Database from "tauri-plugin-sql-api";
|
||||
// utils
|
||||
import { importUIAFData, initSQLiteData, initSQLiteTable } from "./TGSql";
|
||||
import { getUiafStatus } from "./UIAF";
|
||||
class TGSqlite {
|
||||
/**
|
||||
* @description 数据库地址
|
||||
* @private
|
||||
* @type {string}
|
||||
* @memberof TGSqlite
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
private readonly dbPath: string = "sqlite:tauri-genshin.db";
|
||||
/**
|
||||
* @description 数据库包含的表
|
||||
* @private
|
||||
* @type {string[]}
|
||||
* @memberof TGSqlite
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
private readonly tables: string[] = [
|
||||
"AppData",
|
||||
"Achievements",
|
||||
"AchievementSeries",
|
||||
"NameCard",
|
||||
];
|
||||
|
||||
/**
|
||||
* @description 初始化数据库
|
||||
* @memberof TGSqlite
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<void>}
|
||||
* @memberof TGSqlite
|
||||
*/
|
||||
public async init (): Promise<void> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
const sqlT = initSQLiteTable();
|
||||
for (const item of sqlT) {
|
||||
await db.execute(item);
|
||||
}
|
||||
const sqlD = await initSQLiteData();
|
||||
for (const item of sqlD) {
|
||||
await db.execute(item);
|
||||
}
|
||||
await db.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取数据库信息
|
||||
* @memberof TGSqlite
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<{ key: string, value: string, updated: string }[]>}
|
||||
*/
|
||||
public async getAppData (): Promise<Array<{ key: string, value: string, updated: string }>> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
const sql = "SELECT * FROM AppData;";
|
||||
const res: Array<{ key: string, value: string, updated: string }> = await db.select(sql);
|
||||
await db.close();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 已有数据表跟触发器不变的情况下,更新数据库数据
|
||||
* @memberof TGSqlite
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public async update (): Promise<void> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
const sqlD = await initSQLiteData();
|
||||
for (const item of sqlD) {
|
||||
await db.execute(item);
|
||||
}
|
||||
await db.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 检测数据库完整性
|
||||
* @memberof TGSqlite
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
public async check (): Promise<boolean> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
let isVertified = false;
|
||||
// 检测数据表是否都存在
|
||||
const sqlT = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;";
|
||||
const res: Array<{ name: string }> = await db.select(sqlT);
|
||||
// 考虑到 sqlite_sequence 表,所以需要 +1
|
||||
if (res.length === this.tables.length + 1) {
|
||||
if (this.tables.every((item) => res.map((i) => i.name).includes(item))) {
|
||||
isVertified = true;
|
||||
}
|
||||
}
|
||||
await db.close();
|
||||
return isVertified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 重置数据库
|
||||
* @memberof TGSqlite
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public async reset (): Promise<void> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
this.tables.map(async (item) => {
|
||||
const sql = `DROP TABLE IF EXISTS ${item};`;
|
||||
await db.execute(sql);
|
||||
});
|
||||
await db.close();
|
||||
await this.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取数据库版本及构建时间
|
||||
* @memberof TGSqlite
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<{ version: string, buildTime: string }>}
|
||||
*/
|
||||
public async getMetadata (): Promise<{ version: string, buildTime: string }> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
const sql = "SELECT * FROM AppData WHERE key='appVersion' OR key='dataUpdated';";
|
||||
const res: Array<{ key: string, value: string }> = await db.select(sql);
|
||||
const version = res.find((item) => item.key === "appVersion")?.value ?? "0.0.0";
|
||||
const buildTime = res.find((item) => item.key === "dataUpdated")?.value ?? "1970-01-01 00:00:00";
|
||||
await db.close();
|
||||
return { version, buildTime };
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取成就系列列表
|
||||
* @memberof TGSqlite
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<BTMuli.SQLite.AchievementSeries[]>}
|
||||
*/
|
||||
public async getAchievementSeries (): Promise<BTMuli.SQLite.AchievementSeries[]> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
const sql = "SELECT * FROM AchievementSeries ORDER BY `order` ASC;";
|
||||
const res: BTMuli.SQLite.AchievementSeries[] = await db.select(sql);
|
||||
await db.close();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取成就系列对应的名片
|
||||
* @memberof TGSqlite
|
||||
* @since Alpha v0.1.4
|
||||
* @param {number} seriesId 系列 ID
|
||||
* @returns {Promise<BTMuli.SQLite.NameCard>}
|
||||
*/
|
||||
public async getNameCard (seriesId: number): Promise<BTMuli.SQLite.NameCard> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
const sql = `SELECT * FROM NameCard WHERE name=(SELECT nameCard FROM AchievementSeries WHERE id=${seriesId});`;
|
||||
const res: BTMuli.SQLite.NameCard[] = await db.select(sql);
|
||||
await db.close();
|
||||
return res[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取成就列表
|
||||
* @memberof TGSqlite
|
||||
* @param {number} [seriesId] 系列 ID
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<BTMuli.SQLite.Achievements[]>}
|
||||
*/
|
||||
public async getAchievements (seriesId?: number): Promise<BTMuli.SQLite.Achievements[]> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
let sql;
|
||||
if (seriesId) {
|
||||
sql = `SELECT * FROM Achievements WHERE series=${seriesId} ORDER BY isCompleted ASC, \`order\` ASC;`;
|
||||
} else {
|
||||
sql = "SELECT * FROM Achievements ORDER BY isCompleted ASC, `order` ASC;";
|
||||
}
|
||||
const res: BTMuli.SQLite.Achievements[] = await db.select(sql);
|
||||
await db.close();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取成就概况
|
||||
* @since Alpha v0.1.4
|
||||
* @memberof TGSqlite
|
||||
* @returns {Promise<{total:number,fin:number}>}
|
||||
*/
|
||||
public async getAchievementsOverview (): Promise<{ total: number, fin: number }> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
const sql = "SELECT SUM(totalCount) AS total, SUM(finCount) AS fin FROM AchievementSeries;";
|
||||
const res: Array<{ total: number, fin: number }> = await db.select(sql);
|
||||
await db.close();
|
||||
return res[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 查询成就
|
||||
* @memberof TGSqlite
|
||||
* @param {string} keyword 关键词
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<BTMuli.SQLite.Achievements[]>}
|
||||
*/
|
||||
public async searchAchievements (keyword: string): Promise<BTMuli.SQLite.Achievements[]> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
let sql;
|
||||
if (keyword.startsWith("v")) {
|
||||
const version = keyword.replace("v", "");
|
||||
sql = `SELECT * FROM Achievements WHERE version LIKE '%${version}%' ORDER BY isCompleted ASC, \`order\` ASC;`;
|
||||
} else {
|
||||
sql = `SELECT * FROM Achievements WHERE name LIKE '%${keyword}%' OR description LIKE '%${keyword}%' ORDER BY isCompleted ASC, \`order\` ASC;`;
|
||||
}
|
||||
const res: BTMuli.SQLite.Achievements[] = await db.select(sql);
|
||||
await db.close();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 合并 UIAF 数据
|
||||
* @memberof TGSqlite
|
||||
* @param {BTMuli.UIAF.Achievement[]} achievements UIAF 数据
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public async mergeUIAF (achievements: TGPlugin.UIAF.Achievement[]): Promise<void> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
const sql = importUIAFData(achievements);
|
||||
for (const item of sql) {
|
||||
await db.execute(item);
|
||||
}
|
||||
await db.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取 UIAF 数据
|
||||
* @memberof TGSqlite
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<TGPlugin.UIAF.Achievement[]>}
|
||||
*/
|
||||
public async getUIAF (): Promise<TGPlugin.UIAF.Achievement[]> {
|
||||
const db = await Database.load(this.dbPath);
|
||||
const sql = "SELECT * FROM Achievements WHERE isCompleted = 1 OR progress > 0";
|
||||
const res: BTMuli.SQLite.Achievements[] = await db.select(sql);
|
||||
await db.close();
|
||||
const achievements: TGPlugin.UIAF.Achievement[] = [];
|
||||
for (const item of res) {
|
||||
const completed = item.isCompleted === 1;
|
||||
const status = getUiafStatus(completed, item.progress);
|
||||
achievements.push({
|
||||
id: item.id,
|
||||
status,
|
||||
timestamp: completed && item.completedTime ? new Date(item.completedTime).getTime() / 1000 : 0,
|
||||
current: item.progress,
|
||||
});
|
||||
}
|
||||
return achievements;
|
||||
}
|
||||
}
|
||||
|
||||
export default new TGSqlite();
|
||||
@@ -2,10 +2,49 @@
|
||||
* @file utils UIAF.ts
|
||||
* @description UIAF工具类
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha v0.1.3
|
||||
* @since Alpha v0.1.4
|
||||
*/
|
||||
|
||||
import { app, fs } from "@tauri-apps/api";
|
||||
// tauri
|
||||
import { app, fs, path } from "@tauri-apps/api";
|
||||
// utils
|
||||
import TGSqlite from "./TGSqlite";
|
||||
|
||||
/**
|
||||
* @description 时间戳转换为日期
|
||||
* @since Alpha v0.1.4
|
||||
* @param {number} timestamp - 时间戳
|
||||
* @returns {string} 日期 2021-01-01 00:00:00
|
||||
*/
|
||||
export function timestampToDate (timestamp: number): string {
|
||||
return new Date(timestamp * 1000).toLocaleString("zh", {
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 根据 completed 跟 progress 获取 status
|
||||
* @since Alpha v0.1.4
|
||||
* @param {boolean} completed - 是否完成
|
||||
* @param {number} progress - 进度
|
||||
* @returns {number} status
|
||||
*/
|
||||
export function getUiafStatus (completed: boolean, progress: number): number {
|
||||
if (progress !== 0 && !completed) {
|
||||
return 1;
|
||||
} else if (progress === 0 && completed) {
|
||||
return 2;
|
||||
} else if (progress !== 0 && completed) {
|
||||
return 3;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取 UIAF 头部信息
|
||||
@@ -56,3 +95,30 @@ export async function readUiafData (userPath: string): Promise<string | false> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 根据成就数据导出 UIAF 数据
|
||||
* @since Alpha v0.1.4
|
||||
* @param {TGPlugin.UIAF.Achievement[]} achievementData - 成就数据
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function backupUiafData (achievementData: TGPlugin.UIAF.Achievement[]): Promise<void> {
|
||||
const savePath = `${await path.appLocalDataDir()}\\userData\\UIAF.json`;
|
||||
await fs.writeTextFile(savePath, JSON.stringify(achievementData, null, 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 根据 UIAF 数据恢复成就数据
|
||||
* @since Alpha v0.1.4
|
||||
* @returns {Promise<boolean>} 恢复的成就数量
|
||||
*/
|
||||
export async function restoreUiafData (): Promise<boolean> {
|
||||
const uiafPath = `${await path.appLocalDataDir()}\\userData\\UIAF.json`;
|
||||
// 检测是否存在 UIAF 数据
|
||||
if (!await fs.exists(uiafPath)) {
|
||||
return false;
|
||||
}
|
||||
const uiafData = JSON.parse(await fs.readTextFile(uiafPath)) as TGPlugin.UIAF.Achievement[];
|
||||
await TGSqlite.mergeUIAF(uiafData);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ onUpdated(() => {
|
||||
.lottery-user-nickname {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
font-family: Genshin-Light, "仿宋";
|
||||
font-family: Genshin-Light, "仿宋", serif;
|
||||
color: var(--content-text-3);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user