mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-14 09:38:13 +08:00
✨ 添加角色列表数据
This commit is contained in:
@@ -1,172 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="tua-box" @click="showData">
|
|
||||||
<div class="tua-top">
|
|
||||||
<div class="top-item">
|
|
||||||
<div class="top-icon">
|
|
||||||
<div class="ti-bg">
|
|
||||||
<img :src="`/icon/bg/${props.modelValue.rarity===105?5:props.modelValue.rarity}-Star.webp`" alt="rarity">
|
|
||||||
</div>
|
|
||||||
<div class="ti-content">
|
|
||||||
<img :src="props.modelValue.icon" alt="avatar">
|
|
||||||
</div>
|
|
||||||
<div class="ti-level">
|
|
||||||
{{ props.modelValue.actived_constellation_num }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="top-text">
|
|
||||||
Lv.{{ props.modelValue.level }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="top-item">
|
|
||||||
<div class="top-icon">
|
|
||||||
<div class="ti-bg">
|
|
||||||
<img :src="`/icon/bg/${props.modelValue.weapon.rarity}-Star.webp`" alt="rarity">
|
|
||||||
</div>
|
|
||||||
<div class="ti-content">
|
|
||||||
<img :src="props.modelValue.weapon.icon" alt="avatar">
|
|
||||||
</div>
|
|
||||||
<div class="ti-level">
|
|
||||||
{{ props.modelValue.weapon.affix_level }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="top-text">
|
|
||||||
Lv.{{ props.modelValue.level }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="tua-bottom">-->
|
|
||||||
<!-- <div class="bottom-item">A</div>-->
|
|
||||||
<!-- <div class="bottom-item">E</div>-->
|
|
||||||
<!-- <div class="bottom-item">Q</div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
interface TUAProps {
|
|
||||||
modelValue: TGApp.Game.Character.ListItem
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = defineProps<TUAProps>();
|
|
||||||
|
|
||||||
function showData () {
|
|
||||||
console.log(JSON.stringify(props.modelValue, null, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNameCard () {
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="css">
|
|
||||||
.tua-box {
|
|
||||||
padding: 5px;
|
|
||||||
width: 190px;
|
|
||||||
height: 100%;
|
|
||||||
background: rgb(255 255 255 / 10%);
|
|
||||||
box-shadow: 0 0 10px rgb(0 0 0 / 40%);
|
|
||||||
border-radius: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tua-top {
|
|
||||||
width: 180px;
|
|
||||||
height: 110px;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 5px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-item {
|
|
||||||
width: 80px;
|
|
||||||
height: 100%;
|
|
||||||
background: rgb(0 0 0 / 20%);
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-icon {
|
|
||||||
position: relative;
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ti-bg {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ti-bg img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ti-content {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ti-content img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ti-level {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
padding: 5px;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
background: rgb(0 0 0 / 50%);
|
|
||||||
color: #faf7e8;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border-top-right-radius: 5px;
|
|
||||||
border-bottom-left-radius: 5px;
|
|
||||||
font-family: Genshin,sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-text {
|
|
||||||
width: 80px;
|
|
||||||
height: 20px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: #faf7e8;
|
|
||||||
font-family: Genshin-Light,sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-love img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tua-bottom {
|
|
||||||
width: 100%;
|
|
||||||
height: 40%;
|
|
||||||
padding: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-item {
|
|
||||||
width: 32%;
|
|
||||||
height: 100%;
|
|
||||||
background: rgb(0 0 0 / 20%);
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
84
src/components/userCharacter/tuc-role-box.vue
Normal file
84
src/components/userCharacter/tuc-role-box.vue
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tuc-rb-box">
|
||||||
|
<div class="tuc-rb-top">
|
||||||
|
<TItemBox v-model="avatarBox" @click="showAvatarData" />
|
||||||
|
<TItemBox v-model="weaponBox" @click="showWeaponData" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed } from "vue";
|
||||||
|
import TItemBox from "../main/t-itembox.vue";
|
||||||
|
|
||||||
|
interface TucRoleBoxProps {
|
||||||
|
modelValue: TGApp.Sqlite.Character.UserRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<TucRoleBoxProps>();
|
||||||
|
const avatarBox = computed(() => {
|
||||||
|
return {
|
||||||
|
size: "80px",
|
||||||
|
height: "80px",
|
||||||
|
ltSize: "30px",
|
||||||
|
bg: `/icon/bg/${props.modelValue.star}-Star.webp`,
|
||||||
|
icon: `/WIKI/character/icon/${props.modelValue.cid}.webp`,
|
||||||
|
lt: `/icon/element/${props.modelValue.element}.webp`,
|
||||||
|
rt: props.modelValue.activeConstellation.toString() || "0",
|
||||||
|
rtSize: "20px",
|
||||||
|
innerText: `${getAvatarName()}`,
|
||||||
|
innerHeight: 20,
|
||||||
|
display: "inner",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const weaponBox = computed(() => {
|
||||||
|
const weapon = JSON.parse(props.modelValue.weapon) as TGApp.Sqlite.Character.RoleWeapon;
|
||||||
|
return {
|
||||||
|
size: "80px",
|
||||||
|
height: "80px",
|
||||||
|
ltSize: "30px",
|
||||||
|
bg: `/icon/bg/${weapon.star}-Star.webp`,
|
||||||
|
icon: `/WIKI/weapon/icon/${weapon.id}.webp`,
|
||||||
|
lt: `/icon/weapon/${weapon.type}.webp`,
|
||||||
|
rt: weapon.affix.toString() || "0",
|
||||||
|
rtSize: "20px",
|
||||||
|
innerText: `${weapon.name}`,
|
||||||
|
innerHeight: 20,
|
||||||
|
display: "inner",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
function getAvatarName () {
|
||||||
|
return (
|
||||||
|
props.modelValue.cid === 10000005
|
||||||
|
? "旅行者-空"
|
||||||
|
: props.modelValue.cid === 10000007
|
||||||
|
? "旅行者-荧"
|
||||||
|
: props.modelValue.name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAvatarData () {
|
||||||
|
console.log(avatarBox.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showWeaponData () {
|
||||||
|
const weapon = JSON.parse(props.modelValue.weapon) as TGApp.Sqlite.Character.RoleWeapon;
|
||||||
|
console.log(weapon);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.tuc-rb-box {
|
||||||
|
padding: 5px;
|
||||||
|
box-shadow: 0 0 10px var(--common-bg-4);
|
||||||
|
border: 1px inset var(--common-bg-4);
|
||||||
|
border-radius: 5px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tuc-rb-top {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="uc-box">
|
<div class="uc-box">
|
||||||
<div class="uc-top">
|
<div class="uc-top">
|
||||||
<div class="uc-top-title">
|
<div class="uc-top-title">
|
||||||
{{ user.nickname }} UID:{{ user.gameUid }}
|
{{ user.nickname }} UID:{{ user.gameUid }} 更新于 {{ getUpdateTime() }}
|
||||||
</div>
|
</div>
|
||||||
<v-btn variant="outlined" class="uc-top-btn" @click="refresh()">
|
<v-btn variant="outlined" class="uc-top-btn" @click="refresh()">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
@@ -18,27 +18,25 @@
|
|||||||
分享
|
分享
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- grid 布局,参考 Snap.Hutao -->
|
||||||
<div class="uc-grid">
|
<div class="uc-grid">
|
||||||
<TUserAvatar v-for="avatar in roleList" :model-value="avatar" />
|
<TucRoleBox v-for="role in roleList" :model-value="role" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
import { computed, onMounted, ref } from "vue";
|
import { computed, onMounted, onUpdated, ref } from "vue";
|
||||||
import ToLoading from "../../components/overlay/to-loading.vue";
|
import ToLoading from "../../components/overlay/to-loading.vue";
|
||||||
import TUserAvatar from "../../components/mini/t-user-avatar.vue";
|
|
||||||
// tauri
|
|
||||||
import { fs } from "@tauri-apps/api";
|
|
||||||
// store
|
// store
|
||||||
import { useAppStore } from "../../store/modules/app";
|
|
||||||
import { useUserStore } from "../../store/modules/user";
|
import { useUserStore } from "../../store/modules/user";
|
||||||
// utils
|
// utils
|
||||||
|
import TGSqlite from "../../plugins/Sqlite";
|
||||||
import TGRequest from "../../web/request/TGRequest";
|
import TGRequest from "../../web/request/TGRequest";
|
||||||
import { generateShareImg } from "../../utils/TGShare";
|
import { generateShareImg } from "../../utils/TGShare";
|
||||||
|
import TucRoleBox from "../../components/userCharacter/tuc-role-box.vue";
|
||||||
|
|
||||||
// store
|
// store
|
||||||
const appStore = useAppStore();
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
// loading
|
// loading
|
||||||
@@ -46,35 +44,49 @@ const loading = ref(false);
|
|||||||
const loadingTitle = ref("");
|
const loadingTitle = ref("");
|
||||||
|
|
||||||
// data
|
// data
|
||||||
const roleList = ref([] as TGApp.Game.Character.ListItem[]);
|
const isEmpty = ref(true);
|
||||||
const characterCookie = computed(() => userStore.getCookieGroup4());
|
const roleList = ref([] as TGApp.Sqlite.Character.UserRole[]);
|
||||||
|
const roleCookie = computed(() => userStore.getCookieGroup4());
|
||||||
const user = computed(() => userStore.getCurAccount());
|
const user = computed(() => userStore.getCurAccount());
|
||||||
const filePath = computed(() => `${appStore.dataPath.userDataDir}/roleList.json`);
|
|
||||||
|
// grid
|
||||||
|
const gridGap = ref("10px");
|
||||||
|
|
||||||
|
const resizeObserve = new ResizeObserver(() => {
|
||||||
|
getGridGap();
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
loadingTitle.value = "正在获取角色数据";
|
loadingTitle.value = "正在获取角色数据";
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
await loadRole();
|
||||||
const fileGet = await fs.readTextFile(filePath.value);
|
resizeObserve.observe(document.querySelector(".uc-grid"));
|
||||||
roleList.value = JSON.parse(fileGet);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getGridGap () {
|
||||||
|
const width = document.querySelector(".uc-grid")?.clientWidth - 20;
|
||||||
|
const count = Math.floor(width / 180);
|
||||||
|
gridGap.value = `${(width - count * 180) / (count - 1)}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadRole () {
|
||||||
|
const roleData = await TGSqlite.getUserCharacter(user.value.gameUid);
|
||||||
|
if (roleData !== false) {
|
||||||
|
roleList.value = roleData;
|
||||||
|
isEmpty.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function refresh () {
|
async function refresh () {
|
||||||
loadingTitle.value = "正在获取角色数据";
|
loadingTitle.value = "正在获取角色数据";
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const res = await TGRequest.User.byLToken.getRoleList(characterCookie.value, user.value);
|
const res = await TGRequest.User.byLToken.getRoleList(roleCookie.value, user.value);
|
||||||
if (Array.isArray(res)) {
|
if (Array.isArray(res)) {
|
||||||
loadingTitle.value = "正在保存角色数据";
|
loadingTitle.value = "正在保存角色数据";
|
||||||
await fs.writeTextFile({
|
await TGSqlite.saveUserCharacter(user.value.gameUid, res);
|
||||||
path: filePath.value,
|
|
||||||
contents: JSON.stringify(res),
|
|
||||||
});
|
|
||||||
loadingTitle.value = "正在更新角色数据";
|
loadingTitle.value = "正在更新角色数据";
|
||||||
roleList.value = res;
|
await loadRole();
|
||||||
}
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
@@ -84,13 +96,24 @@ async function shareRoles () {
|
|||||||
const fileName = `角色列表-${user.value.gameUid}-${Math.floor(Date.now())}.png`;
|
const fileName = `角色列表-${user.value.gameUid}-${Math.floor(Date.now())}.png`;
|
||||||
await generateShareImg(fileName, rolesBox);
|
await generateShareImg(fileName, rolesBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getUpdateTime () {
|
||||||
|
let lastUpdateTime = 0;
|
||||||
|
roleList.value.forEach((role) => {
|
||||||
|
const updateTime = new Date(role.updated).getTime();
|
||||||
|
if (updateTime > lastUpdateTime) {
|
||||||
|
lastUpdateTime = updateTime;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return new Date(lastUpdateTime).toLocaleString().replace(/\//g, "-");
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.uc-box {
|
.uc-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
box-shadow: 0 0 10px var(--common-bg-4);
|
box-shadow: 0 0 10px var(--common-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.uc-top {
|
.uc-top {
|
||||||
@@ -119,8 +142,8 @@ async function shareRoles () {
|
|||||||
|
|
||||||
.uc-grid {
|
.uc-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
grid-template-columns: repeat(auto-fill, 180px);
|
||||||
grid-gap: 10px;
|
grid-gap: 10px v-bind(gridGap);
|
||||||
margin-top: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
insertAppData,
|
insertAppData,
|
||||||
insertGameAccountData,
|
insertGameAccountData,
|
||||||
insertRecordData,
|
insertRecordData,
|
||||||
|
insertRoleData,
|
||||||
} from "./sql/insertData";
|
} from "./sql/insertData";
|
||||||
|
|
||||||
class Sqlite {
|
class Sqlite {
|
||||||
@@ -39,6 +40,7 @@ class Sqlite {
|
|||||||
"GameAccount",
|
"GameAccount",
|
||||||
"NameCard",
|
"NameCard",
|
||||||
"SpiralAbyss",
|
"SpiralAbyss",
|
||||||
|
"UserCharacters",
|
||||||
"UserRecord",
|
"UserRecord",
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -386,6 +388,35 @@ class Sqlite {
|
|||||||
await db.close();
|
await db.close();
|
||||||
return res[0];
|
return res[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 保存用户角色数据
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @param {string} uid 用户 uid
|
||||||
|
* @param {TGApp.Game.Character.ListItem[]} data 角色数据
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
public async saveUserCharacter (uid: string, data: TGApp.Game.Character.ListItem[]): Promise<void> {
|
||||||
|
const db = await Database.load(this.dbPath);
|
||||||
|
const sql = insertRoleData(uid, data);
|
||||||
|
await db.execute(sql);
|
||||||
|
await db.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取用户角色数据
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @param {string} uid 用户 uid
|
||||||
|
* @returns {Promise<TGApp.Sqlite.Character.UserRole[]|false>}
|
||||||
|
*/
|
||||||
|
public async getUserCharacter (uid: string): Promise<TGApp.Sqlite.Character.UserRole[] | false> {
|
||||||
|
const db = await Database.load(this.dbPath);
|
||||||
|
const sql = `SELECT * FROM UserCharacters WHERE uid = '${uid}'`;
|
||||||
|
const res: TGApp.Sqlite.Character.UserRole[] = await db.select(sql);
|
||||||
|
await db.close();
|
||||||
|
if (res.length === 0) return false;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const TGSqlite = new Sqlite();
|
const TGSqlite = new Sqlite();
|
||||||
|
|||||||
@@ -113,4 +113,25 @@ create table if not exists UserRecord
|
|||||||
worldExplore text,
|
worldExplore text,
|
||||||
homes text,
|
homes text,
|
||||||
updated text
|
updated text
|
||||||
)
|
);
|
||||||
|
|
||||||
|
-- @brief 创建角色数据表
|
||||||
|
create table if not exists UserCharacters
|
||||||
|
(
|
||||||
|
uid integer,
|
||||||
|
cid integer,
|
||||||
|
img text,
|
||||||
|
name text,
|
||||||
|
fetter integer,
|
||||||
|
level integer,
|
||||||
|
element text,
|
||||||
|
star integer,
|
||||||
|
weapon text,
|
||||||
|
reliquary text,
|
||||||
|
constellation text,
|
||||||
|
activeConstellation integer,
|
||||||
|
costume text,
|
||||||
|
talent text, -- todo: 数据获取
|
||||||
|
updated text,
|
||||||
|
primary key (uid, cid)
|
||||||
|
);
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
// utils
|
// utils
|
||||||
import { timeToSecond } from "../utils/transTime";
|
import { timeToSecond } from "../utils/transTime";
|
||||||
import { transCharacterData, transFloorData } from "../utils/transAbyssData";
|
import { transCharacterData, transFloorData } from "../utils/transAbyssData";
|
||||||
|
import { transUserRoles } from "../utils/transUserRoles";
|
||||||
import { transUserRecord } from "../utils/transUserRecord";
|
import { transUserRecord } from "../utils/transUserRecord";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -198,3 +199,39 @@ export function insertRecordData (data: TGApp.Game.Record.FullData, uid: string)
|
|||||||
updated = datetime('now', 'localtime');
|
updated = datetime('now', 'localtime');
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 插入用户角色数据
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @param {string} uid 用户 UID
|
||||||
|
* @param {TGApp.User.Character.Item[]} data 角色数据
|
||||||
|
* @returns {string} sql
|
||||||
|
*/
|
||||||
|
export function insertRoleData (uid: string, data: TGApp.Game.Character.ListItem[]): string {
|
||||||
|
const sql = data.map(item => {
|
||||||
|
const role = transUserRoles(item);
|
||||||
|
return `
|
||||||
|
INSERT INTO UserCharacters (uid, cid, name, img, name, fetter, level, element, star, weapon, reliquary,
|
||||||
|
constellation, activeConstellation, costume, talent, updated)
|
||||||
|
VALUES (${uid}, ${role.cid}, '${role.name}', '${role.img}', '${role.name}', ${role.fetter}, ${role.level},
|
||||||
|
'${role.element}', ${role.star}, '${role.weapon}', '${role.reliquary}', '${role.constellation}',
|
||||||
|
${role.activeConstellation}, '${role.costume}', '${role.talent}', datetime('now', 'localtime'))
|
||||||
|
ON CONFLICT(uid, cid) DO UPDATE
|
||||||
|
SET name = '${role.name}',
|
||||||
|
img = '${role.img}',
|
||||||
|
name = '${role.name}',
|
||||||
|
fetter = ${role.fetter},
|
||||||
|
level = ${role.level},
|
||||||
|
element = '${role.element}',
|
||||||
|
star = ${role.star},
|
||||||
|
weapon = '${role.weapon}',
|
||||||
|
reliquary = '${role.reliquary}',
|
||||||
|
constellation = '${role.constellation}',
|
||||||
|
activeConstellation = ${role.activeConstellation},
|
||||||
|
costume = '${role.costume}',
|
||||||
|
talent = '${role.talent}',
|
||||||
|
updated = datetime('now', 'localtime');
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
return sql.join("");
|
||||||
|
}
|
||||||
|
|||||||
154
src/plugins/Sqlite/utils/transUserRoles.ts
Normal file
154
src/plugins/Sqlite/utils/transUserRoles.ts
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins Sqlite utils transUserRoles.ts
|
||||||
|
* @description 转换用户角色数据格式,用于数据库存储
|
||||||
|
* @author BTMuli <bt-muli@outlook.com>
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum EnumElementEn {
|
||||||
|
pyro = "Pyro",
|
||||||
|
hydro = "Hydro",
|
||||||
|
anemo = "Anemo",
|
||||||
|
electro = "Electro",
|
||||||
|
cryo = "Cryo",
|
||||||
|
geo = "Geo",
|
||||||
|
dendro = "Dendro",
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EnumElement {
|
||||||
|
pyro = "火元素",
|
||||||
|
hydro = "水元素",
|
||||||
|
anemo = "风元素",
|
||||||
|
electro = "雷元素",
|
||||||
|
cryo = "冰元素",
|
||||||
|
geo = "岩元素",
|
||||||
|
dendro = "草元素",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 将通过 api 获取到的用户角色数据转换为数据库中的数据
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @param {TGApp.Game.Character.ListItem} data 用户角色数据
|
||||||
|
* @returns {TGApp.Sqlite.Character.UserRole} 转换后的用户角色数据
|
||||||
|
*/
|
||||||
|
export function transUserRoles (data: TGApp.Game.Character.ListItem): TGApp.Sqlite.Character.UserRole {
|
||||||
|
return {
|
||||||
|
uid: -1,
|
||||||
|
cid: data.id,
|
||||||
|
img: data.image,
|
||||||
|
name: data.name,
|
||||||
|
fetter: data.fetter,
|
||||||
|
level: data.level,
|
||||||
|
element: transElement(data.element as EnumElementEn),
|
||||||
|
star: data.rarity === 105 ? 5 : data.rarity,
|
||||||
|
weapon: transWeapon(data.weapon),
|
||||||
|
reliquary: transReliquary(data.reliquaries),
|
||||||
|
constellation: transConstellation(data.constellations),
|
||||||
|
activeConstellation: data.actived_constellation_num,
|
||||||
|
costume: JSON.stringify(data.costumes),
|
||||||
|
talent: "",
|
||||||
|
updated: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 将角色元素转换为数据库中的数据
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @param {EnumElementEn} data 角色元素
|
||||||
|
* @returns {EnumElement} 转换后的角色元素
|
||||||
|
*/
|
||||||
|
function transElement (data: EnumElementEn): EnumElement {
|
||||||
|
switch (data) {
|
||||||
|
case EnumElementEn.pyro:
|
||||||
|
return EnumElement.pyro;
|
||||||
|
case EnumElementEn.hydro:
|
||||||
|
return EnumElement.hydro;
|
||||||
|
case EnumElementEn.anemo:
|
||||||
|
return EnumElement.anemo;
|
||||||
|
case EnumElementEn.electro:
|
||||||
|
return EnumElement.electro;
|
||||||
|
case EnumElementEn.cryo:
|
||||||
|
return EnumElement.cryo;
|
||||||
|
case EnumElementEn.geo:
|
||||||
|
return EnumElement.geo;
|
||||||
|
case EnumElementEn.dendro:
|
||||||
|
return EnumElement.dendro;
|
||||||
|
default:
|
||||||
|
throw new Error("未知的角色元素类型");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 将角色武器转换为数据库中的数据
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @param {TGApp.Game.Character.LIWeapon} data 角色武器
|
||||||
|
* @returns {string} 转换后的角色武器
|
||||||
|
*/
|
||||||
|
function transWeapon (data: TGApp.Game.Character.LIWeapon): string {
|
||||||
|
const weapon: TGApp.Sqlite.Character.RoleWeapon = {
|
||||||
|
id: data.id,
|
||||||
|
name: data.name,
|
||||||
|
type: data.type_name,
|
||||||
|
star: data.rarity,
|
||||||
|
level: data.level,
|
||||||
|
promote: data.promote_level,
|
||||||
|
description: data.desc,
|
||||||
|
affix: data.affix_level,
|
||||||
|
};
|
||||||
|
return JSON.stringify(weapon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 将角色命座转换为数据库中的数据
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @param {TGApp.Game.Character.LIRelic[]} data 角色命座
|
||||||
|
* @returns {string} 转换后的角色命座
|
||||||
|
*/
|
||||||
|
function transReliquary (data: TGApp.Game.Character.LIRelic[]): string {
|
||||||
|
if (data.length === 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const reliquary: TGApp.Sqlite.Character.RoleReliquary[] = [];
|
||||||
|
for (const item of data) {
|
||||||
|
reliquary.push({
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
pos: item.pos,
|
||||||
|
posName: item.pos_name,
|
||||||
|
star: item.rarity,
|
||||||
|
level: item.level,
|
||||||
|
set: {
|
||||||
|
id: item.set.id,
|
||||||
|
name: item.set.name,
|
||||||
|
effect: item.set.affixes.map((setItem) => {
|
||||||
|
return {
|
||||||
|
active: setItem.activation_number,
|
||||||
|
description: setItem.effect,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return JSON.stringify(reliquary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 将角色命座转换为数据库中的数据
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @param {TGApp.Game.Character.LIConstellation[]} data 角色命座
|
||||||
|
* @returns {string} 转换后的角色命座
|
||||||
|
*/
|
||||||
|
function transConstellation (data: TGApp.Game.Character.LIConstellation[]): string {
|
||||||
|
const constellation: TGApp.Sqlite.Character.RoleConstellation[] = [];
|
||||||
|
for (const item of data) {
|
||||||
|
constellation.push({
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
icon: item.icon,
|
||||||
|
description: item.effect,
|
||||||
|
active: item.is_actived,
|
||||||
|
pos: item.pos,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return JSON.stringify(constellation);
|
||||||
|
}
|
||||||
3
src/types/Game/Character.d.ts
vendored
3
src/types/Game/Character.d.ts
vendored
@@ -1,7 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @file types Game Character.d.ts
|
* @file types Game Character.d.ts
|
||||||
* @description 游戏角色相关类型定义文件
|
* @description 游戏角色相关类型定义文件
|
||||||
* @todo v0.1.5 不使用
|
|
||||||
* @author BTMuli<bt-muli@outlook.com>
|
* @author BTMuli<bt-muli@outlook.com>
|
||||||
* @since Alpha v0.2.0
|
* @since Alpha v0.2.0
|
||||||
*/
|
*/
|
||||||
@@ -55,7 +54,7 @@ declare namespace TGApp.Game.Character {
|
|||||||
level: number
|
level: number
|
||||||
rarity: number
|
rarity: number
|
||||||
weapon: LIWeapon
|
weapon: LIWeapon
|
||||||
reliquaries: LIReliquary[]
|
reliquaries: LIRelic[]
|
||||||
constellations: LIConstellation[]
|
constellations: LIConstellation[]
|
||||||
actived_constellation_num: number
|
actived_constellation_num: number
|
||||||
costumes: LICostume[]
|
costumes: LICostume[]
|
||||||
|
|||||||
133
src/types/Sqlite/Character.d.ts
vendored
133
src/types/Sqlite/Character.d.ts
vendored
@@ -32,4 +32,137 @@ declare namespace TGApp.Sqlite.Character {
|
|||||||
nameCard: string
|
nameCard: string
|
||||||
updated: string
|
updated: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 用户角色列表的角色类型
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @interface UserRole
|
||||||
|
* @property {number} uid- 用户 ID
|
||||||
|
* @property {number} cid - 角色 ID
|
||||||
|
* @property {string} img - 全身像
|
||||||
|
* @property {string} name - 角色名称
|
||||||
|
* @property {number} fetter - 角色好感
|
||||||
|
* @property {number} level - 角色等级
|
||||||
|
* @property {string} element - 角色元素类型
|
||||||
|
* @property {number} star - 角色星级
|
||||||
|
* @property {RoleWeapon} weapon - 角色武器类型 // 数据库中以字符串形式存储
|
||||||
|
* @property {RoleReliquary[]} reliquary - 角色圣遗物套装 // 数据库中以字符串形式存储
|
||||||
|
* @property {RoleConstellation[]} constellation - 角色命座 // 数据库中以字符串形式存储
|
||||||
|
* @property {number} activeConstellation - 角色激活命座
|
||||||
|
* @property {RoleCostume} costume - 角色时装 // 数据库中以字符串形式存储
|
||||||
|
* @property {string} talent - 角色天赋 // TODO: 天赋数据缺失来源
|
||||||
|
* @property {string} updated - 数据更新时间
|
||||||
|
* @return UserRole
|
||||||
|
*/
|
||||||
|
export interface UserRole {
|
||||||
|
uid: number
|
||||||
|
cid: number
|
||||||
|
img: string
|
||||||
|
name: string
|
||||||
|
fetter: number
|
||||||
|
level: number
|
||||||
|
element: string
|
||||||
|
star: number
|
||||||
|
weapon: string
|
||||||
|
reliquary: string
|
||||||
|
constellation: string
|
||||||
|
activeConstellation: number
|
||||||
|
costume: string
|
||||||
|
talent: string
|
||||||
|
updated: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 角色列表的武器数据类型
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @interface RoleWeapon
|
||||||
|
* @property {number} id - 武器 ID
|
||||||
|
* @property {string} name - 武器名称
|
||||||
|
* @property {string} type - 武器类型
|
||||||
|
* @property {number} star - 武器星级
|
||||||
|
* @property {number} level - 武器等级
|
||||||
|
* @property {number} promote - 武器突破
|
||||||
|
* @property {string} description - 武器描述
|
||||||
|
* @property {number} affix - 武器精炼
|
||||||
|
* @return RoleWeapon
|
||||||
|
*/
|
||||||
|
export interface RoleWeapon {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
type: string
|
||||||
|
star: number
|
||||||
|
level: number
|
||||||
|
promote: number
|
||||||
|
description: string
|
||||||
|
affix: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 角色列表的圣遗物数据类型
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @interface RoleReliquary
|
||||||
|
* @property {number} id - 圣遗物 ID
|
||||||
|
* @property {string} name - 圣遗物名称
|
||||||
|
* @property {number} pos - 圣遗物部位
|
||||||
|
* @property {string} posName - 圣遗物部位名称
|
||||||
|
* @property {number} star - 圣遗物星级
|
||||||
|
* @property {number} level - 圣遗物等级
|
||||||
|
* @property {number} set.id - 圣遗物套装 ID
|
||||||
|
* @property {string} set.name - 圣遗物套装名称
|
||||||
|
* @property {number} set.effect[].active - 圣遗物套装效果激活数量
|
||||||
|
* @property {string} set.effect[].description - 圣遗物套装效果描述
|
||||||
|
* @return RoleReliquary
|
||||||
|
*/
|
||||||
|
export interface RoleReliquary {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
pos: number
|
||||||
|
posName: string
|
||||||
|
star: number
|
||||||
|
level: number
|
||||||
|
set: {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
effect: Array<{
|
||||||
|
active: number
|
||||||
|
description: string
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 角色列表的命座数据类型
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @interface RoleConstellation
|
||||||
|
* @property {number} id - 命座 ID
|
||||||
|
* @property {string} name - 命座名称
|
||||||
|
* @property {string} icon - 命座图标
|
||||||
|
* @property {string} description - 命座描述
|
||||||
|
* @property {boolean} active - 命座是否激活
|
||||||
|
* @property {number} pos - 命座位置
|
||||||
|
* @return RoleConstellation
|
||||||
|
*/
|
||||||
|
export interface RoleConstellation {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
icon: string
|
||||||
|
description: string
|
||||||
|
active: boolean
|
||||||
|
pos: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 角色列表的时装数据类型
|
||||||
|
* @since Alpha v0.2.0
|
||||||
|
* @interface RoleCostume
|
||||||
|
* @property {number} id - 时装 ID
|
||||||
|
* @property {string} name - 时装名称
|
||||||
|
* @property {string} icon - 时装图标
|
||||||
|
* @return RoleCostume
|
||||||
|
*/
|
||||||
|
export interface RoleCostume {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
icon: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user