From 77cc5e113426f28d1cc3df2b401c51abe6f9f6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A5=BF=E7=93=9C=C2=B0?= Date: Sat, 5 Apr 2025 14:39:32 +0800 Subject: [PATCH] dev --- backend/core/basic/character.py | 4 + backend/core/basic/equipment.py | 5 +- frontend/src/api/info/type.ts | 10 + .../pages/Character/Forge/components/jade.vue | 75 ++-- frontend/src/stores/config.ts | 4 +- frontend/src/stores/info.ts | 3 +- frontend/src/types/global.d.ts | 22 ++ frontend/src/utils/index.ts | 330 ++++++++++++++++++ 8 files changed, 412 insertions(+), 41 deletions(-) create mode 100644 frontend/src/types/global.d.ts create mode 100644 frontend/src/utils/index.ts diff --git a/backend/core/basic/character.py b/backend/core/basic/character.py index 97410d06..bb98b8ee 100644 --- a/backend/core/basic/character.py +++ b/backend/core/basic/character.py @@ -449,6 +449,8 @@ class Character: suits = [] stones = [] for i in equInfos.equs: + if i.itemType == '武器' and i.itemDetailType not in self.武器选项: + continue equs.append(i.__dict__) for i in equInfos.suits: suits.append(i.__dict__) @@ -460,6 +462,7 @@ class Character: info['enchants'] = equInfos.enchants info['emblems'] = equInfos.emblems info["avatar"] = equInfos.funs.get_dress_list(skill_clothes) + info['jades'] = equInfos.jades for skill in platinum: info['emblems'].append({ 'id': skill, @@ -726,6 +729,7 @@ class Character: # 角色基础属性 self.SetBaseStatus() # 辟邪玉计算 + self.calc_jade(setInfo.get('jades', [])) # 时装计算 self.calc_avatar(setInfo.get('avatar', {})) # 精通、增幅、强化计算 diff --git a/backend/core/basic/equipment.py b/backend/core/basic/equipment.py index fa594d95..77de2289 100644 --- a/backend/core/basic/equipment.py +++ b/backend/core/basic/equipment.py @@ -73,6 +73,7 @@ class Equipments: self.funs = self.init_func() self.equ_dict: dict[str, Equ] = {} self.stone_dict: dict[str, Equ] = {} + self.jades = [] self.enchants = [] self.emblems = [] self.suits: list[Suit] = [] @@ -82,6 +83,7 @@ class Equipments: self.init_enchants() self.init_stones() self.init_emblem() + self.init_jades() self.engine.dispose() def init_equs(self): @@ -170,9 +172,6 @@ class Equipments: db_list = session.query(JadeData).all() for item in db_list: jade = {k: v for k, v in item.__dict__.items() if not k.startswith('_')} - jade['position'] = [] if jade['itemType'] is None else jade['itemType'].split(',') - jade['categorize'] = [] if jade['categorize'] is None else jade['categorize'].split(',') - del jade['itemType'] self.jades.append(jade) pass pass diff --git a/frontend/src/api/info/type.ts b/frontend/src/api/info/type.ts index f9a92a8a..03704d9f 100644 --- a/frontend/src/api/info/type.ts +++ b/frontend/src/api/info/type.ts @@ -33,6 +33,7 @@ export interface ICharacterInfo { skills: ISkill[] suits: ISuit[] avatar: Record + jades:IJade[] } export interface IEquipment { @@ -82,3 +83,12 @@ export interface IAvatarInfo { suit?: string name: string } + +export interface IJade { + name:string + id:number + max:number + min:number + pre:number + unit:string +} diff --git a/frontend/src/pages/Character/Forge/components/jade.vue b/frontend/src/pages/Character/Forge/components/jade.vue index 72d9fed9..9581e24c 100644 --- a/frontend/src/pages/Character/Forge/components/jade.vue +++ b/frontend/src/pages/Character/Forge/components/jade.vue @@ -3,53 +3,58 @@ diff --git a/frontend/src/stores/config.ts b/frontend/src/stores/config.ts index 5d3d45ca..e8efeaf5 100644 --- a/frontend/src/stores/config.ts +++ b/frontend/src/stores/config.ts @@ -32,7 +32,7 @@ export interface IConfig { } > jades: Record avatar: Record< @@ -124,7 +124,7 @@ export const useConfigStore = defineStore('configStore', () => { (["0", "1", "2", "3"].filter((key) => !Object.keys(config.value.jades).includes(key)) ?? []).forEach((key) => { config.value.jades[key] = { - id: '', + id: -1, value: 0, } } diff --git a/frontend/src/stores/info.ts b/frontend/src/stores/info.ts index dc6c7df9..70415c13 100644 --- a/frontend/src/stores/info.ts +++ b/frontend/src/stores/info.ts @@ -21,7 +21,7 @@ export const useInfoStore = defineStore('infoStore', () => { const avatars = computed(() => infos.value?.avatar ?? {}) - // const jades = computed(() => infos.value?.jades ?? []) + const jades = computed(() => infos.value?.jades ?? []) const parts = [ '头肩', @@ -78,5 +78,6 @@ export const useInfoStore = defineStore('infoStore', () => { stones, avatarParts, avatars, + jades } }) diff --git a/frontend/src/types/global.d.ts b/frontend/src/types/global.d.ts new file mode 100644 index 00000000..edb6e38b --- /dev/null +++ b/frontend/src/types/global.d.ts @@ -0,0 +1,22 @@ +interface Number { + plus(value: number): number + + minus(value: number): number + + multiply(value: number): number + + divide(value: number): number + + perMulti(value: number): number + + round(digit?: number): number + + floor(digit?: number): number + + exactlyDivide(value: number): number +} + +interface Array { + min(callback: (t: T) => number): [number, T | undefined] + max(callback: (t: T) => number): [number, T | undefined] +} diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts new file mode 100644 index 00000000..5bc853f3 --- /dev/null +++ b/frontend/src/utils/index.ts @@ -0,0 +1,330 @@ +export function in_range(num: number, start: number, end: number) { + return start <= num && num <= end +} + +export function to_percent(num?: number, defaultValue: number = 0, suffix = "", withPlus = false) { + num = num ?? defaultValue + return (num > 0 && withPlus ? "+" : "") + num?.multiply(100).round(2).toString().concat(suffix) +} + +export function get_num(num?: number, defaultValue: number = 0) { + return num ?? defaultValue +} + +export function format_string(str: string, params: any = {}, ...args: any[]) { + let num = 0 + str = str.replace(/{}/g, match => { + return args[num++] ?? match + }) + str = str.replace(/{\d+}/g, match => { + const i = Number.parseInt(match.slice(1, -1)) + return args[i] ?? match + }) + str = str.replace(/{\w+}/g, match => { + const name = match.slice(1, -1) + return params[name] ?? match + }) + return str +} + +export function format_bytes(bytes: number, decimals = 2) { + if (bytes === 0) { + return "0 Bytes" + } + const k = 1024 + const dm = decimals < 0 ? 0 : decimals + const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] + + const i = Math.floor(Math.log(bytes) / Math.log(k)) + + return `${Number.parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}` +} + +export function getFloat(value: any, n: any) { + value = Number(value) + n = n ? Number.parseInt(n) : 0 + if (n <= 0) { + return Math.round(value) + } + value = Math.round(value * 10 ** n) / 10 ** n + value = Number(value).toFixed(n) + return value +} + +export function cartesian(...arr: T[][]): T[][] { + if (arr.length < 2) { + return arr + } + return arr.reduce( + (a, b) => { + const ret: T[][] = [] + a.forEach(a => { + b.forEach(b => { + ret.push(a.concat([b])) + }) + }) + return ret + }, + [[]] as T[][] + ) +} + +export function groupBy(array: T[], callback: (t: T) => K) { + const map = new Map() + for (let i = 0; i < array.length; i++) { + const t = array[i] + const key = callback(t) + const temp: T[] = map.get(key) || [] + if (!map.has(key)) { + map.set(key, temp) + } + temp.push(t) + } + + return Array.from(map.values()) +} + +export function debounce_last(func: Function, wait: number) { + let timer = Number.NaN + return function () { + if (timer) { + clearTimeout(timer) + } + timer = setTimeout(func, wait) + } +} + +export function padding(num: number | string, length: number): string { + if ((`${num}`).length >= length) { + return `${num}` + } + return padding(`0${num}`, length) +} + +export function format_float(f: number, digit: number = 2) { + const m = 10 ** digit + return (f * m).round(10) / m +} + +export function mapRecord(status: Record, callback: (value: K, key: T) => K) { + const new_status = {} as Record + for (const key in status) { + const value = callback(status[key], key) + if (value) { + new_status[key] = value + } + } + return new_status +} + +Array.prototype.max = function(callback: (t: T) => number): [number, T | undefined] { + let rs: [number, T | undefined] = [-1, undefined] + let max = -1 + for (let i = 0; i < this.length; i++) { + const item = this.at(i) as T + const count = callback(item) + if (count > max) { + max = count + rs = [i, item] + } + } + return rs +} + +Array.prototype.min = function(callback: (t: T) => number): [number, T | undefined] { + let rs: [number, T | undefined] = [-1, undefined] + let min = -1 + for (let i = 0; i < this.length; i++) { + const item = this.at(i) as T + const count = callback(item) + if (count < min) { + min = count + rs = [i, item] + } + } + return rs +} + +Number.prototype.multiply = function (value: number) { + return Number(this) * value +} + +Number.prototype.round = function (digit?: number) { + const m = 10 ** (digit ?? 0) + return Math.round(Number(this) * m) / m +} + +export function formatStr(template: string, ...params: any) { + let str = template + + if (params.length == 1 && params[0].length > 0) { + params = params[0] + } + + for (let i = 0; i < params.length; i++) { + str = str.replaceAll(`{${i}}`, params[i]) + } + + return str +} + +export function toObj(data: any): any { + const temp = {} + for (const key in data) { + try { + if (typeof data[key] === "number" || typeof data[key] === "string") { + Object.defineProperty(temp, key, { + value: data[key], + writable: true, + enumerable: true, + configurable: true + }) + } else { + Object.defineProperty(temp, key, { + value: RecordToObj(data[key]), + writable: true, + enumerable: true, + configurable: true + }) + } + } catch { + Object.defineProperty(temp, key, { + value: data[key], + writable: true, + enumerable: true, + configurable: true + }) + } + } + return temp +} + +export function toMap(data: any, except: string[] = []) { + const temp = {} + for (const key in data) { + if (typeof data[key] === "object" && data[key].constructor != Array && !except.includes(key)) { + // 需要转换部分,不能是Array,也会被转换 + const sub = {} + for (const subkey in data[key]) { + Object.defineProperty(sub, subkey, { + value: new Map(Object.entries(data[key][subkey])), + writable: true, + enumerable: true, + configurable: true + }) + } + Object.defineProperty(temp, key, { + value: sub, + writable: true, + enumerable: true, + configurable: true + }) + } else { + Object.defineProperty(temp, key, { + value: data[key], + writable: true, + enumerable: true, + configurable: true + }) + } + } + return temp +} + +export function RecordToObj(todo: Record>) { + const temp = {} + for (const key in todo) { + Object.defineProperty(temp, key, { + value: Object.fromEntries(todo[key]), + writable: true, + enumerable: true, + configurable: true + }) + } + return temp +} + +export function getUuid() { + if (typeof crypto === "object") { + if (typeof crypto.randomUUID === "function") { + return crypto.randomUUID() + } + if (typeof crypto.getRandomValues === "function" && typeof Uint8Array === "function") { + const callback = (c: any) => { + const num = Number(c) + return (num ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (num / 4)))).toString(16) + } + return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, callback) + } + } + let timestamp = new Date().getTime() + let perforNow = (typeof performance !== "undefined" && performance.now && performance.now() * 1000) || 0 + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => { + let random = Math.random() * 16 + if (timestamp > 0) { + random = Math.trunc((timestamp + random) % 16) + timestamp = Math.floor(timestamp / 16) + } else { + random = Math.trunc((perforNow + random) % 16) + perforNow = Math.floor(perforNow / 16) + } + return (c === "x" ? random : (random & 0x3) | 0x8).toString(16) + }) +} + + +export function rarityClass(type: string) { + switch (type) { + case "太初": + return "primeval" + case "史诗": + return "epic" + case "神话": + return "myth" + case "智慧产物": + return "epic" + case "神器": + return "artifact" + case "稀有": + return "rare" + case "传说": + return "legend" + case "勇者": + return "chronicle" + case "高级": + return "advanced" + default: + return "epic" + } +} + + +export const decrypt = (encryptedData:string)=>{ + try{ + encryptedData = decodeURIComponent(encryptedData).split("").map(a=>{ + if(a=='='){ + return a + } + else{ + return String.fromCharCode(a.charCodeAt(0) - 1) + } + }).join("") + const decryptedData = atob(encryptedData); + + const len = decryptedData.length; + const decryptedBinaryOffset = decryptedData.slice(0, len-13); + const decryptedTimestamp = decryptedData.slice(len-13, len); + + return { + uid:parseInt(decryptedBinaryOffset,2), + time:parseInt(decryptedTimestamp) + } + } + catch(e){ + console.log(e) + return { + uid:-1, + time:0 + } + } +}