This commit is contained in:
2025-03-12 09:36:26 +08:00
parent b98464d8b5
commit 6053fba1da
22 changed files with 286 additions and 228 deletions
+7 -19
View File
@@ -34,7 +34,7 @@ def dict2obj(dictObj):
return d
async def createToken(alter: str, equVersion: str, expire=86400 / 24 * 2, redis=None, env=''):
def createToken(alter: str, equVersion: str, redis = None, expire=86400 / 24 * 2)->str:
ts_str = str(time.time() + expire)
ts_byte = ts_str.encode('utf-8')
sha1_tshex_str = hmac.new(alter.encode('utf-8'), ts_byte, 'sha1').hexdigest()
@@ -42,15 +42,16 @@ async def createToken(alter: str, equVersion: str, expire=86400 / 24 * 2, redis=
token = base64.urlsafe_b64encode(token.encode('utf-8')).decode('utf-8')
# character = createCharacter(alter)
character = {}
await redis.set(f'token:{token}', json.dumps(AlterState(alter, token, character, equVersion).to_dict()), int(expire))
redis.set(f'token:{token}', json.dumps(AlterState(alter, token, character, equVersion).to_dict()), int(expire))
return token
async def readToken(token: str, redis, env) -> AlterState:
def readToken(token: str, redis) -> AlterState:
info = None
try:
info = dict2obj(json.loads(await redis.get(f'token:{token}')))
except Exception:
info = dict2obj(json.loads(redis.get(f'token:{token}')))
except Exception as ex:
print(ex)
ResponseException('登录过期或无效Token,请刷新后重试')
if info is None:
raise ResponseException('登录过期或无效Token,请刷新后重试')
@@ -62,20 +63,7 @@ def deleteToken(token, redis, env):
return token
async def authorize(request: Request, access_token: Optional[str] = Header(None)):
if access_token is not None:
info = await readToken(access_token, request.app.state.redis, request.app.state.env)
return info
else:
raise ResponseException('登录过期或无效Token,请刷新后重试')
def unauthorize(request: Request, access_token: Optional[str] = Header(None)):
if access_token is not None:
return deleteToken(access_token, request.app.state.redis, request.app.state.env)
async def uid(request: Request, access_uid: Optional[str] = Header(None)):
def uid(access_uid: Optional[str] = Header(None)):
try:
return int(access_uid)
except Exception:
+19 -2
View File
@@ -1,9 +1,26 @@
from typing import Annotated
from typing import Annotated, Optional
from redis import Redis
from sqlalchemy.orm import Session
from fastapi import Depends
from fastapi import Depends, Header
from api.core.exception import ResponseException
from database.connect import get_db,get_redis
from api.core.Auth import AlterState, deleteToken, readToken
SessionDep = Annotated[Session, Depends(get_db)]
RedisDep = Annotated[Redis, Depends(get_redis)]
def authorize(redis:RedisDep, access_token: Optional[str] = Header(None)):
if access_token is not None:
info = readToken(access_token, redis)
return info
else:
raise ResponseException('登录过期或无效Token,请刷新后重试')
def unauthorize(redis:RedisDep, access_token: Optional[str] = Header(None)):
if access_token is not None:
return deleteToken(access_token, redis)
AltersDep = Annotated[AlterState, Depends(authorize)]
+17 -18
View File
@@ -4,7 +4,8 @@ import json
from fastapi import APIRouter,Request
from api.core.Response import Return, response
from api.core.Redis import get_redis_info
from api.dp import RedisDep
from api.dp import RedisDep,AltersDep
from core.basic.character import createCharacter
router = APIRouter()
@@ -20,22 +21,20 @@ async def get_adventure_info(request: Request,redis:RedisDep):
return response(data=adventure_info)
@router.get('/equipment/list')
async def get_equipment_list(request: Request,redis:RedisDep):
def get_equipment_list():
with open('./dataFiles/equipment-list.json', encoding='utf-8') as fp:
return json.load(fp)
equipment_list = get_redis_info(redis, 'dcalc:equipment', get_equipment_list)
return response(data=equipment_list)
@router.get("/token/get/{alter}", response_model=Return[str])
async def getToken(
alter: str, request: Request, version: str = None, equVersion: str = ""
@router.get("/token/get/{alter}")
async def getToken(redis:RedisDep,
alter: str, request: Request, version: str = None, equVersion: str = "0"
):
if version is not None and version != "default" and version != "":
alter = version + "." + alter
token = createToken(
alter, equVersion, redis=request.app.state.redis, env=request.app.state.env
)
token = createToken(alter, equVersion, redis)
return response(data=token)
@router.get("/character")
async def get_character_info(
request: Request, state: AltersDep ,redis:RedisDep
):
character = createCharacter(state.alter, state.equVersion)
def get_character():
return character.getInfo()
info = get_redis_info(redis, f"dcalc:character:{state.alter}", get_character)
return response(data=info)
+3 -1
View File
@@ -569,7 +569,9 @@ class Character:
def createCharacter(alter: str, equVersion: str = '0'):
character: Character = None
module_name = 'core.characters.' + alter
module_name = 'core.character.' + alter
if equVersion is None or equVersion == '':
equVersion = '0'
try:
character = importlib.import_module(module_name).classChange(equVersion)
except Exception as ex:
+1 -1
View File
@@ -77,7 +77,7 @@ class Skill:
icon = icon.replace('$common', '/characters/common')
icon = icon.replace('$name', f'{self.name}')
icon = icon.replace('$id', f'{self.id}')
return icon
return f'{icon}.png'
def _calculate_lv(self):
return min(int((characterLv - self.learnLv) / self.rangeLv + 1), self.masterLv) if self._lv == 0 else self._lv
+68 -68
View File
@@ -3,32 +3,32 @@
"name": "swordman_male",
"title": "鬼剑士(男)",
"children": [
{ "title": "极诣·剑魂", "name": "weapon_master", "open": true },
{ "name": "soul_bender", "title": "极诣·鬼泣", "open": true },
{ "name": "berserker", "title": "极诣·狂战士", "open": true },
{ "name": "asura", "title": "极诣·阿修罗", "open": true },
{ "name": "ghostblade", "title": "极诣·剑影", "open": true }
{ "title": "极诣·剑魂", "name": "weapon_master", "open": false },
{ "name": "soul_bender", "title": "极诣·鬼泣", "open": false },
{ "name": "berserker", "title": "极诣·狂战士", "open": false },
{ "name": "asura", "title": "极诣·阿修罗", "open": false },
{ "name": "ghostblade", "title": "极诣·剑影", "open": false }
]
},
{
"name": "swordman_female",
"title": "鬼剑士(女)",
"children": [
{ "name": "sword_master", "title": "极诣·驭剑士", "open": true },
{ "name": "dark_templar", "title": "极诣·暗殿骑士", "open": true },
{ "name": "demon_slayer", "title": "极诣·契魔者", "open": true },
{ "name": "vegabond", "title": "极诣·流浪武士", "open": true },
{ "name": "spectre", "title": "极诣·刃影", "open": true }
{ "name": "sword_master", "title": "极诣·驭剑士", "open": false },
{ "name": "dark_templar", "title": "极诣·暗殿骑士", "open": false },
{ "name": "demon_slayer", "title": "极诣·契魔者", "open": false },
{ "name": "vegabond", "title": "极诣·流浪武士", "open": false },
{ "name": "spectre", "title": "极诣·刃影", "open": false }
]
},
{
"name": "fighter_male",
"title": "格斗家(男)",
"children": [
{ "name": "nenmaster_male", "title": "归元·气功师", "open": true },
{ "name": "striker_male", "title": "归元·散打", "open": true },
{ "name": "brawler_male", "title": "归元·街霸", "open": true },
{ "name": "grappler_male", "title": "归元·柔道家", "open": true },
{ "name": "nenmaster_male", "title": "归元·气功师", "open": false },
{ "name": "striker_male", "title": "归元·散打", "open": false },
{ "name": "brawler_male", "title": "归元·街霸", "open": false },
{ "name": "grappler_male", "title": "归元·柔道家", "open": false },
{ "name": "empty", "title": "", "comment": "首页" }
]
},
@@ -36,10 +36,10 @@
"name": "fighter_female",
"title": "格斗家(女)",
"children": [
{ "name": "nenmaster_female", "title": "归元·气功师", "open": true },
{ "name": "striker_female", "title": "归元·散打", "open": true },
{ "name": "brawler_female", "title": "归元·街霸", "open": true },
{ "name": "grappler_female", "title": "归元·柔道家", "open": true },
{ "name": "nenmaster_female", "title": "归元·气功师", "open": false },
{ "name": "striker_female", "title": "归元·散打", "open": false },
{ "name": "brawler_female", "title": "归元·街霸", "open": false },
{ "name": "grappler_female", "title": "归元·柔道家", "open": false },
{ "name": "empty", "title": "", "comment": "设置" }
]
},
@@ -47,26 +47,26 @@
"name": "gunner_male",
"title": "神枪手(男)",
"children": [
{ "name": "ranger_male", "title": "重霄·漫游枪手", "open": true },
{ "name": "launcher_male", "title": "重霄·枪炮师", "open": true },
{ "name": "mechanic_male", "title": "重霄·机械师", "open": true },
{ "name": "spitfire_male", "title": "重霄·弹药专家", "open": true },
{ "name": "assault", "title": "重霄·合金战士", "open": true }
{ "name": "ranger_male", "title": "重霄·漫游枪手", "open": false },
{ "name": "launcher_male", "title": "重霄·枪炮师", "open": false },
{ "name": "mechanic_male", "title": "重霄·机械师", "open": false },
{ "name": "spitfire_male", "title": "重霄·弹药专家", "open": false },
{ "name": "assault", "title": "重霄·合金战士", "open": false }
]
},
{
"name": "gunner_female",
"title": "神枪手(女)",
"children": [
{ "name": "ranger_female", "title": "重霄·漫游枪手", "open": true },
{ "name": "launcher_female", "title": "重霄·枪炮师", "open": true },
{ "name": "mechanic_female", "title": "重霄·机械师", "open": true },
{ "name": "spitfire_female", "title": "重霄·弹药专家", "open": true },
{ "name": "ranger_female", "title": "重霄·漫游枪手", "open": false },
{ "name": "launcher_female", "title": "重霄·枪炮师", "open": false },
{ "name": "mechanic_female", "title": "重霄·机械师", "open": false },
{ "name": "spitfire_female", "title": "重霄·弹药专家", "open": true, "class": "GF.gunner_female.spitfire_female" },
{
"name": "sponsor",
"url": "https://bbs.colg.cn",
"title": "",
"open": true
"open": false
}
]
},
@@ -74,25 +74,25 @@
"name": "mage_male",
"title": "魔法师(男)",
"children": [
{ "name": "elemental_bomber", "title": "知源·元素爆破师", "open": true },
{ "name": "glacial_master", "title": "知源·冰结师", "open": true },
{ "name": "blood_mage", "title": "知源·血法师", "open": true },
{ "name": "swift_master", "title": "知源·逐风者", "open": true },
{ "name": "dimension_walker", "title": "知源·次元行者", "open": true }
{ "name": "elemental_bomber", "title": "知源·元素爆破师", "open": false },
{ "name": "glacial_master", "title": "知源·冰结师", "open": false },
{ "name": "blood_mage", "title": "知源·血法师", "open": false },
{ "name": "swift_master", "title": "知源·逐风者", "open": false },
{ "name": "dimension_walker", "title": "知源·次元行者", "open": false }
]
},
{
"name": "mage_female",
"title": "魔法师(女)",
"children": [
{ "name": "elementalist", "title": "知源·元素师", "open": true },
{ "name": "summoner", "title": "知源·召唤师", "open": true },
{ "name": "battle_mage", "title": "知源·战斗法师", "open": true },
{ "name": "witch", "title": "知源·魔道学者", "open": true },
{ "name": "elementalist", "title": "知源·元素师", "open": false },
{ "name": "summoner", "title": "知源·召唤师", "open": false },
{ "name": "battle_mage", "title": "知源·战斗法师", "open": false },
{ "name": "witch", "title": "知源·魔道学者", "open": false },
{
"name": "enchantress",
"title": "知源·小魔女",
"open": true,
"open": false,
"options": [
{ "name": "default", "title": "奶", "class": "enchantress" },
{ "name": "default", "title": "输出", "class": "enchantress_carry" }
@@ -107,15 +107,15 @@
{
"name": "crusader_male",
"title": "神启·圣骑士",
"open": true,
"open": false,
"options": [
{ "name": "default", "title": "奶", "class": "crusader_male" },
{ "name": "default", "title": "审判", "class": "crusader_male_carry" }
]
},
{ "name": "infighter", "title": "神启·蓝拳圣使", "open": true },
{ "name": "exorcist", "title": "神启·驱魔师", "open": true },
{ "name": "avenger", "title": "神启·复仇者", "open": true },
{ "name": "infighter", "title": "神启·蓝拳圣使", "open": false },
{ "name": "exorcist", "title": "神启·驱魔师", "open": false },
{ "name": "avenger", "title": "神启·复仇者", "open": false },
{ "name": "empty", "title": "" }
]
},
@@ -126,7 +126,7 @@
{
"name": "crusader_female",
"title": "神启·圣骑士",
"open": true,
"open": false,
"options": [
{ "name": "default", "title": "奶", "class": "crusader_female" },
{
@@ -136,9 +136,9 @@
}
]
},
{ "name": "inquistor", "title": "神启·异端审判者", "open": true },
{ "name": "sorceress", "title": "神启·巫女", "open": true },
{ "name": "mistress", "title": "神启·诱魔者", "open": true },
{ "name": "inquistor", "title": "神启·异端审判者", "open": false },
{ "name": "sorceress", "title": "神启·巫女", "open": false },
{ "name": "mistress", "title": "神启·诱魔者", "open": false },
{ "name": "empty", "title": "" }
]
},
@@ -146,10 +146,10 @@
"name": "thief",
"title": "暗夜使者",
"children": [
{ "name": "rogue", "title": "隐夜·刺客", "open": true },
{ "name": "necro", "title": "隐夜·死灵术士", "open": true },
{ "name": "kunoichi", "title": "隐夜·忍者", "open": true },
{ "name": "shadow_dancer", "title": "隐夜·影舞者", "open": true },
{ "name": "rogue", "title": "隐夜·刺客", "open": false },
{ "name": "necro", "title": "隐夜·死灵术士", "open": false },
{ "name": "kunoichi", "title": "隐夜·忍者", "open": false },
{ "name": "shadow_dancer", "title": "隐夜·影舞者", "open": false },
{ "name": "empty", "title": "" }
]
},
@@ -157,10 +157,10 @@
"name": "knight",
"title": "守护者",
"children": [
{ "name": "elven_knight", "title": "皓曦·精灵骑士", "open": true },
{ "name": "chaos", "title": "皓曦·混沌魔灵", "open": true },
{ "name": "paladin", "title": "皓曦·帕拉丁", "open": true },
{ "name": "dragon_knight", "title": "皓曦·龙骑士", "open": true },
{ "name": "elven_knight", "title": "皓曦·精灵骑士", "open": false },
{ "name": "chaos", "title": "皓曦·混沌魔灵", "open": false },
{ "name": "paladin", "title": "皓曦·帕拉丁", "open": false },
{ "name": "dragon_knight", "title": "皓曦·龙骑士", "open": false },
{ "name": "empty", "title": "" }
]
},
@@ -168,10 +168,10 @@
"name": "demonic_lancer",
"title": "魔枪士",
"children": [
{ "name": "vanguard", "title": "千魂·征战者", "open": true },
{ "name": "skirmisher", "title": "千魂·决战者", "open": true },
{ "name": "dragoon", "title": "千魂·狩猎者", "open": true },
{ "name": "impaler", "title": "千魂·暗枪士", "open": true },
{ "name": "vanguard", "title": "千魂·征战者", "open": false },
{ "name": "skirmisher", "title": "千魂·决战者", "open": false },
{ "name": "dragoon", "title": "千魂·狩猎者", "open": false },
{ "name": "impaler", "title": "千魂·暗枪士", "open": false },
{ "name": "empty", "title": "" }
]
},
@@ -179,10 +179,10 @@
"name": "gunblader",
"title": "枪剑士",
"children": [
{ "name": "hitman", "title": "苍暮·暗刃", "open": true },
{ "name": "agent", "title": "苍暮·特工", "open": true },
{ "name": "trouble_shooter", "title": "苍暮·战线佣兵", "open": true },
{ "name": "specialist", "title": "苍暮·源能专家", "open": true },
{ "name": "hitman", "title": "苍暮·暗刃", "open": false },
{ "name": "agent", "title": "苍暮·特工", "open": false },
{ "name": "trouble_shooter", "title": "苍暮·战线佣兵", "open": false },
{ "name": "specialist", "title": "苍暮·源能专家", "open": false },
{ "name": "empty", "title": "" }
]
},
@@ -190,10 +190,10 @@
"name": "archer",
"title": "弓箭手",
"children": [
{ "name": "muse", "title": "聆风·缪斯", "open": true },
{ "name": "traveler", "title": "聆风·旅人", "open": true },
{ "name": "hunter", "title": "聆风·猎人", "open": true },
{ "name": "vigilante", "title": "聆风·妖护使", "open": true },
{ "name": "muse", "title": "聆风·缪斯", "open": false },
{ "name": "traveler", "title": "聆风·旅人", "open": false },
{ "name": "hunter", "title": "聆风·猎人", "open": false },
{ "name": "vigilante", "title": "聆风·妖护使", "open": false },
{ "name": "empty", "title": "" }
]
},
@@ -201,8 +201,8 @@
"name": "extra",
"title": "外传",
"children": [
{ "name": "creator", "title": "知源·缔造者", "open": true },
{ "name": "dark_knight", "title": "极诣·黑暗武士", "open": true },
{ "name": "creator", "title": "知源·缔造者", "open": false },
{ "name": "dark_knight", "title": "极诣·黑暗武士", "open": false },
{ "name": "empty", "title": "" },
{ "name": "empty", "title": "" },
{ "name": "empty", "title": "" }
+1 -1
View File
@@ -20,6 +20,6 @@ if __name__ == '__main__':
application.include_router(api_router)
uvicorn.run(application, host='127.0.0.1', port=config.PORT)
uvicorn.run(app = application, host='127.0.0.1', port=config.PORT)
+2 -8
View File
@@ -2,6 +2,7 @@ import type { AxiosInstance, AxiosResponse } from 'axios'
import axios from 'axios'
import { h } from 'vue'
import { gzip, ungzip } from 'pako'
import { useInfoStore } from '@/stores'
// import { useAppStore, useConfigStore } from '@/store'
// import { useDialog } from '@/components/hooks/dialog'
@@ -58,19 +59,12 @@ export function defineRequest<T>(fn: (ax: AxiosInstance) => T) {
// const token = configStore.token
// const uid = useAppStore().uid
const token = 'test'
const token = useInfoStore().token
if (token) {
request.headers['Access-Token'] = token
}
// 在网页端,会添加token
const accessToken = localStorage.getItem('dcalc/access_token')
if (accessToken) {
request.headers.Authorization = `Bearer ${accessToken}`
}
return request
},
(error) => {
+12 -3
View File
@@ -1,10 +1,19 @@
import { defineRequest } from '../common'
import type { IAdventureInfo } from './type'
import type { IAdventureInfo, ICharacterInfo } from './type'
export default defineRequest((request) => {
return {
adventures() {
return request.get<IAdventureInfo[]>('/adventure').then((res) => res.data)
async adventures() {
const res = await request.get<IAdventureInfo[]>('/adventure')
return res.data
},
async createToken(alter: string, equVersion?: string) {
const res = await request.get<string>(`/token/get/${alter}`, { params: { equVersion } })
return res.data
},
async characterInfo() {
const res = await request.get<ICharacterInfo>('/character')
return res.data
},
}
})
+23 -14
View File
@@ -3,20 +3,6 @@ export interface IAdventureInfo {
name: string
children: IAlterInfo[]
}
export interface ITools {
name: string
tooltips: string
link: string
end?: Date
target: '_blank' | '_self'
}
export interface IMonster {
id: number
name: string
}
export interface IAlterOption {
name: string
title: string
@@ -31,4 +17,27 @@ export interface IAlterInfo {
options?: IAlterOption[]
open?: boolean
comment?: string
class?:string
}
export interface ICharacterInfo {
alter: string
name: string
equVersion: string
equips: IEquipment[]
weapons: string[]
skills: ISkill[]
suits: ISuit[]
}
export interface IEquipment {}
export interface ISkill {
icon: string
name: string
id: number
learnLv:number
positon:number
}
export interface ISuit {}
+3 -2
View File
@@ -1,7 +1,8 @@
import '@/style/index.scss'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { pinia } from "@/stores"
import App from '@/pages/IndexView.vue'
import router from './router'
@@ -13,7 +14,7 @@ document.body.appendChild(appContainer)
const app = createApp(App)
app.use(createPinia())
app.use(pinia)
app.use(router)
app.mount(appContainer)
+19
View File
@@ -0,0 +1,19 @@
<template>
<div class="h-90vh w-560px overflow-y-auto overflow-x-hidden">
<SkillTree></SkillTree>
</div>
</template>
<script lang="ts" setup name="Index">
import { useInfoStore } from '@/stores/info'
import { getImageURL } from '@/utils/images'
import SkillTree from './Skill/SkillTree.vue';
const props = defineProps<{
alter: string
}>()
const infoStore = useInfoStore()
onMounted(() => {
infoStore.createCharacter(props.alter, '0')
})
</script>
@@ -0,0 +1,47 @@
<template>
<div class="relative w-550px h-auto">
<template v-for="item in infoStore.skills" :key="item.id">
<div
class="absolute w-34px h-auto flex flex-col gap-2px py-2px items-center bg-#2c2d2c rounded-2px"
:style="skillPositon(item.learnLv, item.positon)"
>
<img class="w-30px h-30px" :src="getImageURL(item.icon)" :alt="item.name" />
<div class="flex-1 bg-black text-white">100级</div>
</div>
</template>
<template v-for="lv of 21" :key="lv">
<div class="skill-tree-line flex items-center px-20px text-#373837">
{{ lv % 2 === 1 ? Math.max(1, (lv - 1) * 5) :'' }}
</div>
</template>
</div>
</template>
<script lang="ts" setup>
import { useInfoStore } from '@/stores'
import { getImageURL } from '@/utils/images'
const infoStore = useInfoStore()
const skillPositon = (learnLv: number, positon: number) => {
return {
positon: 'absolute',
left: `${positon * 50 + 50}px`,
top: `${Math.floor(learnLv / 5) * 80 + 8}px`,
}
}
</script>
<style lang="scss" scoped>
.skill-tree-line {
height: 80px;
width: auto;
&:nth-child(n + 1) {
background-color: #000000;
}
&:nth-child(2n + 1) {
background-color: #202020;
backdrop-filter: blur(1px);
}
}
</style>
@@ -24,82 +24,22 @@ export default defineComponent(async () => {
// 获取角色相关信息,判定是否开放
function choose_job(child: IAlterInfo) {
return async () => {
// if (child.comment == '首页') {
// return openUrl('https://dnftools.com/')
// }
// if (child.comment == '设置') {
// return openUrl('/set', { width: 600, height: 500, scale: zoom.value })
// }
// if (ignores.includes(child.name)) {
// return
// }
// if (child.name == 'sponsor') {
// return openUrl(child.url ?? '')
// }
// if (child.open || import.meta.env.DEV) {
// const options = child.options ?? []
// if (options.length > 0) {
// const id = randomId()
// return await show({
// // id,
// scale: zoom.value,
// content: '请选择职业平衡版本',
// action: () => {
// return (
// <>
// <div class="flex items-center justify-around flex-wrap" style="width:200px">
// {renderList(options, (option) =>
// !option.class ? (
// <calc-button
// class="!w-40% !mb-2"
// onClick={() => {
// openUrl('/character', {
// query: { alter: child.name },
// width: 1100,
// height: 775,
// scale: zoom.value,
// })
// close(id, 'ok')
// }}
// >
// {option.title}
// </calc-button>
// ) : (
// <calc-button
// class="!w-40% !mb-2"
// onClick={() => {
// openUrl('/character', {
// query: { alter: option.class ?? '' },
// width: 1100,
// height: 775,
// scale: zoom.value,
// })
// close(id, 'ok')
// }}
// >
// {option.title}
// </calc-button>
// ),
// )}
// </div>
// </>
// )
// },
// })
// }
// return openUrl('/character', {
// query: { alter: child.name },
// width: 1100,
// height: 775,
// title: child.title,
// scale: zoom.value,
// })
// } else {
// return alert({
// content: '未开放的角色!',
// })
// }
if (child.comment == '首页') {
return window.open("https://dnftools.com","_blank")
}
if (child.name == 'sponsor') {
return window.open((child.url ?? ''),"_blank")
}
if (child.open) {
const options = child.options ?? []
if (options.length > 0) {
return
}
else{
return window.open("/character/" + (child.class || child.name),"_self")
}
}
}
// router.push("/character/" + alter)
}
+7 -1
View File
@@ -7,8 +7,14 @@ const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'home',
component: defineAsyncComponent(() => import('@/pages/Home/HomeView.vue')),
component: defineAsyncComponent(() => import('@/pages/Home/Index.vue')),
},
{
path:'/character/:alter',
name:'character',
props: true,
component: defineAsyncComponent(() => import('@/pages/Character/Index.vue')),
}
]
const router = createRouter({
+4
View File
@@ -0,0 +1,4 @@
import {defineStore} from 'pinia'
const config = defineStore('config', ()=>{
})
-12
View File
@@ -1,12 +0,0 @@
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, doubleCount, increment }
})
+5
View File
@@ -0,0 +1,5 @@
import { createPinia } from "pinia"
export * from "./info"
export const pinia = createPinia()
+29
View File
@@ -0,0 +1,29 @@
import api from "@/api"
import type { ICharacterInfo } from "@/api/info/type"
import { defineStore } from "pinia"
export const useInfoStore = defineStore("infoStore", ()=>{
const token = ref<string>("")
const infos = ref<ICharacterInfo | null>(null)
const skills = computed(()=>infos.value?.skills ?? [])
const equips = computed(()=>infos.value?.equips ?? [])
const suits = computed(()=>infos.value?.suits ?? [])
const createCharacter = async (alter: string, equVersion?: string) => {
token.value = await api.createToken(alter, equVersion)
infos.value = await api.characterInfo()
}
return {
token,
infos,
skills,
equips,
suits,
createCharacter,
}
})
+3 -2
View File
@@ -1,4 +1,4 @@
let baseURL = '/img'
let baseURL = 'https://image.dnftools.com'
// 避免远程开发的时候冲突
if (process.env.NODE_ENV == 'development') {
@@ -10,5 +10,6 @@ if (import.meta.env.MODE == 'web' || import.meta.env.MODE == 'show') {
}
export const getImageURL = (image: string) => {
return `${baseURL}/${image}`
image = image.startsWith('/') ? image : `/${image}`
return `${baseURL}${image}`
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+1 -1
View File
@@ -9,7 +9,7 @@ const ImageServer = http.createServer((req, res) => {
// 图片存储的文件夹路径
const directoryPath = path.join(__dirname, '../images');
// 请求的图片文件名
const filePath = path.join(directoryPath, req.url);
const filePath = path.join(directoryPath, decodeURIComponent(req.url));
// 确保文件存在且是文件,不是目录
fs.access(filePath, fs.constants.F_OK | fs.constants.R_OK, (err) => {
if (err) {