diff --git a/src/components/mini/t-user-avatar.vue b/src/components/mini/t-user-avatar.vue deleted file mode 100644 index 250dfa36..00000000 --- a/src/components/mini/t-user-avatar.vue +++ /dev/null @@ -1,172 +0,0 @@ - - - diff --git a/src/components/userCharacter/tuc-role-box.vue b/src/components/userCharacter/tuc-role-box.vue new file mode 100644 index 00000000..0dc62942 --- /dev/null +++ b/src/components/userCharacter/tuc-role-box.vue @@ -0,0 +1,84 @@ + + + diff --git a/src/pages/User/Characters.vue b/src/pages/User/Characters.vue index ecc6737d..1d965fab 100644 --- a/src/pages/User/Characters.vue +++ b/src/pages/User/Characters.vue @@ -3,7 +3,7 @@
- {{ user.nickname }} UID:{{ user.gameUid }} + {{ user.nickname }} UID:{{ user.gameUid }} 更新于 {{ getUpdateTime() }}
diff --git a/src/plugins/Sqlite/index.ts b/src/plugins/Sqlite/index.ts index 0656f4e8..3b04ad52 100644 --- a/src/plugins/Sqlite/index.ts +++ b/src/plugins/Sqlite/index.ts @@ -17,6 +17,7 @@ import { insertAppData, insertGameAccountData, insertRecordData, + insertRoleData, } from "./sql/insertData"; class Sqlite { @@ -39,6 +40,7 @@ class Sqlite { "GameAccount", "NameCard", "SpiralAbyss", + "UserCharacters", "UserRecord", ]; @@ -386,6 +388,35 @@ class Sqlite { await db.close(); return res[0]; } + + /** + * @description 保存用户角色数据 + * @since Alpha v0.2.0 + * @param {string} uid 用户 uid + * @param {TGApp.Game.Character.ListItem[]} data 角色数据 + * @returns {Promise} + */ + public async saveUserCharacter (uid: string, data: TGApp.Game.Character.ListItem[]): Promise { + 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} + */ + public async getUserCharacter (uid: string): Promise { + 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(); diff --git a/src/plugins/Sqlite/sql/createTable.sql b/src/plugins/Sqlite/sql/createTable.sql index c4dda190..83c1001e 100644 --- a/src/plugins/Sqlite/sql/createTable.sql +++ b/src/plugins/Sqlite/sql/createTable.sql @@ -113,4 +113,25 @@ create table if not exists UserRecord worldExplore text, homes 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) +); \ No newline at end of file diff --git a/src/plugins/Sqlite/sql/insertData.ts b/src/plugins/Sqlite/sql/insertData.ts index fc4133da..5780421c 100644 --- a/src/plugins/Sqlite/sql/insertData.ts +++ b/src/plugins/Sqlite/sql/insertData.ts @@ -8,6 +8,7 @@ // utils import { timeToSecond } from "../utils/transTime"; import { transCharacterData, transFloorData } from "../utils/transAbyssData"; +import { transUserRoles } from "../utils/transUserRoles"; import { transUserRecord } from "../utils/transUserRecord"; /** @@ -118,7 +119,7 @@ export function insertNameCardData (data: TGApp.App.NameCard.Item): string { export function insertCharacterData (data: TGApp.App.Character.WikiBriefInfo): string { return ` INSERT INTO AppCharacters (id, name, star, element, weapon, nameCard, birthday, updated) - VALUES (${data.id}, '${data.name}', ${data.star}, '${data.element}', '${data.weapon}', + VALUES (${data.id}, '${data.name}', ${data.star}, '${data.element}', '${data.weapon}', '${data.nameCard}', '${data.birthday}', datetime('now', 'localtime')) ON CONFLICT(id) DO UPDATE SET name = '${data.name}', @@ -186,15 +187,51 @@ export function insertRecordData (data: TGApp.Game.Record.FullData, uid: string) const transData = transUserRecord(data); transData.uid = uid; return ` - INSERT INTO UserRecord(uid, role, avatars, stats, worldExplore, homes, updated) + INSERT INTO UserRecord(uid, role, avatars, stats, worldExplore, homes, updated) VALUES ('${transData.uid}', '${transData.role}', '${transData.avatars}', '${transData.stats}', '${transData.worldExplore}', '${transData.homes}', datetime('now', 'localtime')) ON CONFLICT(uid) DO UPDATE - SET role = '${transData.role}', - avatars = '${transData.avatars}', - stats = '${transData.stats}', - worldExplore = '${transData.worldExplore}', - homes = '${transData.homes}', - updated = datetime('now', 'localtime'); + SET role = '${transData.role}', + avatars = '${transData.avatars}', + stats = '${transData.stats}', + worldExplore = '${transData.worldExplore}', + homes = '${transData.homes}', + 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(""); +} diff --git a/src/plugins/Sqlite/utils/transUserRoles.ts b/src/plugins/Sqlite/utils/transUserRoles.ts new file mode 100644 index 00000000..73b07e1f --- /dev/null +++ b/src/plugins/Sqlite/utils/transUserRoles.ts @@ -0,0 +1,154 @@ +/** + * @file plugins Sqlite utils transUserRoles.ts + * @description 转换用户角色数据格式,用于数据库存储 + * @author BTMuli + * @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); +} diff --git a/src/types/Game/Character.d.ts b/src/types/Game/Character.d.ts index 27120ec3..90b7574a 100644 --- a/src/types/Game/Character.d.ts +++ b/src/types/Game/Character.d.ts @@ -1,7 +1,6 @@ /** * @file types Game Character.d.ts * @description 游戏角色相关类型定义文件 - * @todo v0.1.5 不使用 * @author BTMuli * @since Alpha v0.2.0 */ @@ -55,7 +54,7 @@ declare namespace TGApp.Game.Character { level: number rarity: number weapon: LIWeapon - reliquaries: LIReliquary[] + reliquaries: LIRelic[] constellations: LIConstellation[] actived_constellation_num: number costumes: LICostume[] diff --git a/src/types/Sqlite/Character.d.ts b/src/types/Sqlite/Character.d.ts index fdbcccd6..a88ed742 100644 --- a/src/types/Sqlite/Character.d.ts +++ b/src/types/Sqlite/Character.d.ts @@ -32,4 +32,137 @@ declare namespace TGApp.Sqlite.Character { nameCard: 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 + } }