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
+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}`
}