dev
This commit is contained in:
@@ -26,6 +26,8 @@ export interface ICharacterInfo {
|
||||
name: string
|
||||
equVersion: string
|
||||
equips: IEquipment[]
|
||||
enchantings: IEnchantingInfo[]
|
||||
emblems: IEnchantingInfo[]
|
||||
weapons: string[]
|
||||
skills: ISkill[]
|
||||
suits: ISuit[]
|
||||
@@ -59,3 +61,14 @@ export interface ISuit {
|
||||
imageUrl: string
|
||||
suitId: number
|
||||
}
|
||||
|
||||
|
||||
export interface IEnchantingInfo {
|
||||
id: string | number
|
||||
maxFame: number | undefined
|
||||
position: string[]
|
||||
props: string
|
||||
type: string | undefined
|
||||
rarity: string | undefined
|
||||
rate: number
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogOverlay,
|
||||
DialogPortal,
|
||||
DialogRoot,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from 'reka-ui'
|
||||
import { Icon } from '@iconify/vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogRoot>
|
||||
<DialogPortal>
|
||||
<DialogOverlay class="bg-blackA9 data-[state=open]:animate-overlayShow fixed inset-0 z-30" />
|
||||
<DialogContent
|
||||
class="data-[state=open]:animate-contentShow fixed top-[50%] left-[50%] max-h-[85vh] w-[90vw] max-w-[450px] translate-x-[-50%] translate-y-[-50%] rounded-[6px] bg-white p-[25px] shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] focus:outline-none z-[100]"
|
||||
>
|
||||
<DialogTitle class="text-mauve12 m-0 text-[17px] font-semibold">
|
||||
Edit profile
|
||||
</DialogTitle>
|
||||
<DialogDescription class="text-mauve11 mt-[10px] mb-5 text-sm leading-normal">
|
||||
Make changes to your profile here. Click save when you're done.
|
||||
</DialogDescription>
|
||||
<fieldset class="mb-[15px] flex items-center gap-5">
|
||||
<label
|
||||
class="text-grass11 w-[90px] text-right text-sm"
|
||||
for="name"
|
||||
> Name </label>
|
||||
<input
|
||||
id="name"
|
||||
class="text-grass11 bg-stone-50 shadow-green7 focus:shadow-green8 inline-flex h-[35px] w-full flex-1 items-center justify-center rounded-lg px-[10px] text-sm leading-none shadow-[0_0_0_1px] outline-none focus:shadow-[0_0_0_2px]"
|
||||
defaultValue="Pedro Duarte"
|
||||
>
|
||||
</fieldset>
|
||||
<fieldset class="mb-[15px] flex items-center gap-5">
|
||||
<label
|
||||
class="text-grass11 w-[90px] text-right text-sm"
|
||||
for="username"
|
||||
> Username </label>
|
||||
<input
|
||||
id="username"
|
||||
class="text-grass11 bg-stone-50 shadow-green7 focus:shadow-green8 inline-flex h-[35px] w-full flex-1 items-center justify-center rounded-lg px-[10px] text-sm leading-none shadow-[0_0_0_1px] outline-none focus:shadow-[0_0_0_2px]"
|
||||
defaultValue="@peduarte"
|
||||
>
|
||||
</fieldset>
|
||||
<div class="mt-[25px] flex justify-end">
|
||||
<DialogClose as-child>
|
||||
<button
|
||||
class="bg-green4 text-green11 text-sm hover:bg-green5 focus:shadow-green7 inline-flex h-[35px] items-center justify-center rounded-lg px-[15px] font-semibold leading-none focus:shadow-[0_0_0_2px] focus:outline-none"
|
||||
>
|
||||
Save changes
|
||||
</button>
|
||||
</DialogClose>
|
||||
</div>
|
||||
<DialogClose
|
||||
class="text-grass11 hover:bg-green4 focus:shadow-green7 absolute top-[10px] right-[10px] inline-flex h-[25px] w-[25px] appearance-none items-center justify-center rounded-full focus:shadow-[0_0_0_2px] focus:outline-none"
|
||||
aria-label="Close"
|
||||
>
|
||||
<Icon icon="lucide:x" />
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
</DialogPortal>
|
||||
</DialogRoot>
|
||||
</template>
|
||||
@@ -170,7 +170,7 @@ export default defineComponent({
|
||||
z-index: 888;
|
||||
|
||||
$hoverColor: #002947;
|
||||
$activeColor: lighten($hoverColor, 5%);
|
||||
$activeColor: color.scale($hoverColor, $lightness: 5%);
|
||||
color: $text-color;
|
||||
|
||||
.i-autocomplete-dropdown-item {
|
||||
|
||||
@@ -25,6 +25,7 @@ export default defineComponent({
|
||||
default: "primary"
|
||||
}
|
||||
},
|
||||
emits: ["click"],
|
||||
setup(props, { slots }) {
|
||||
return () => {
|
||||
const proerpties = {
|
||||
|
||||
@@ -156,6 +156,7 @@ export default defineComponent({
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use 'sass:color';
|
||||
$text-color: #937639;
|
||||
.i-cascader {
|
||||
min-width: 80px;
|
||||
@@ -241,7 +242,7 @@ $text-color: #937639;
|
||||
z-index: 888;
|
||||
|
||||
$hoverColor: #002947;
|
||||
$activeColor: lighten($hoverColor, 5%);
|
||||
$activeColor: color.scale($hoverColor, $lightness: 5%);
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
<script lang="tsx">
|
||||
import type { EmitsOptions, SetupContext } from "vue";
|
||||
import { computed, defineComponent, inject, nextTick, renderSlot } from "vue"
|
||||
import { selectionProps, switchEmits, switchProps, useSelectionItem, useSwitch } from "hoci"
|
||||
import { CHECKBOX_GROUP } from "../shared"
|
||||
import type { EmitsOptions, SetupContext } from 'vue'
|
||||
import { computed, defineComponent, inject, nextTick, renderSlot } from 'vue'
|
||||
import { selectionProps, switchEmits, switchProps, useSelectionItem, useSwitch } from 'hoci'
|
||||
import { CHECKBOX_GROUP } from '../shared'
|
||||
|
||||
export default defineComponent({
|
||||
name: "ICheckbox",
|
||||
name: 'ICheckbox',
|
||||
components: {},
|
||||
props: {
|
||||
...switchProps,
|
||||
...selectionProps,
|
||||
label: {
|
||||
type: String
|
||||
type: String,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
round: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
}
|
||||
default: () => false,
|
||||
},
|
||||
},
|
||||
emits: [...switchEmits],
|
||||
|
||||
@@ -29,18 +29,23 @@ export default defineComponent({
|
||||
return inject(CHECKBOX_GROUP, false)
|
||||
})
|
||||
|
||||
const { toggle, switchClass } = useSwitch(
|
||||
const { toggle, className: switchClass } = useSwitch(
|
||||
() => ({
|
||||
...props,
|
||||
class: props.round ? "i-switch text-xs h-auto cursor-pointer" : "i-checkbox text-xs h-auto cursor-pointer",
|
||||
activeClass: "checked"
|
||||
class: props.round
|
||||
? 'i-switch text-xs h-auto cursor-pointer'
|
||||
: 'i-checkbox text-xs h-auto cursor-pointer',
|
||||
activeClass: 'checked',
|
||||
}),
|
||||
context
|
||||
context,
|
||||
)
|
||||
|
||||
const { activate, itemClass } = useSelectionItem(props, context as SetupContext<EmitsOptions>)
|
||||
const { activate, className: itemClass } = useSelectionItem(
|
||||
props,
|
||||
context as SetupContext<EmitsOptions>,
|
||||
)
|
||||
|
||||
const baseClass = computed(() => (props.round ? "i-switch" : "i-checkbox"))
|
||||
const baseClass = computed(() => (props.round ? 'i-switch' : 'i-checkbox'))
|
||||
|
||||
const { slots } = context
|
||||
|
||||
@@ -59,153 +64,163 @@ export default defineComponent({
|
||||
})
|
||||
|
||||
return () => (
|
||||
<div onClick={onClick} class={["flex", baseClass.value, className.value]}>
|
||||
<span class={!props.disabled ? "i-checkbox-icon" : "i-checkbox-icon-disable"}></span>
|
||||
<div class={["i-checkbox-label h-auto"]}>{props.label ?? renderSlot(slots, "default")}</div>
|
||||
<div onClick={onClick} class={['flex', baseClass.value, className.value]}>
|
||||
<span class={!props.disabled ? 'i-checkbox-icon' : 'i-checkbox-icon-disable'}></span>
|
||||
<div class={['i-checkbox-label h-auto']}>{props.label ?? renderSlot(slots, 'default')}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.i-checkbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: baseline;
|
||||
&.checked {
|
||||
.i-checkbox-icon {
|
||||
background-image: url("@/assets/img/control/checkbox_checked.png");
|
||||
}
|
||||
}
|
||||
|
||||
.i-checkbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: baseline;
|
||||
&.checked {
|
||||
.i-checkbox-icon {
|
||||
width: 12px;
|
||||
min-width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 4px;
|
||||
background-image: url("@/assets/img/control/checkbox_uncheck.png");
|
||||
}
|
||||
|
||||
.i-checkbox-icon-disable {
|
||||
width: 12px;
|
||||
min-width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 4px;
|
||||
background-image: url("@/assets/img/control/checkbox_disable.png");
|
||||
}
|
||||
|
||||
&:hover:not(.checked) {
|
||||
.i-checkbox-icon {
|
||||
background-image: url("@/assets/img/control/checkbox_hover.png");
|
||||
}
|
||||
}
|
||||
|
||||
.i-checkbox-label {
|
||||
line-height: 24px;
|
||||
color: #937639;
|
||||
background-image: url('@/assets/img/control/checkbox_checked.png');
|
||||
}
|
||||
}
|
||||
|
||||
.i-switch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// justify-content: center;
|
||||
.i-checkbox-icon {
|
||||
width: 12px;
|
||||
min-width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 4px;
|
||||
background-image: url('@/assets/img/control/checkbox_uncheck.png');
|
||||
}
|
||||
|
||||
&.checked {
|
||||
.i-checkbox-icon {
|
||||
background-image: linear-gradient(to right, #8f6e29, #8f6e29), linear-gradient(rgb(110, 89, 61), rgb(60, 46, 30));
|
||||
}
|
||||
|
||||
.i-checkbox-icon::after {
|
||||
left: 100%;
|
||||
margin-left: -14.8px;
|
||||
}
|
||||
}
|
||||
.i-checkbox-icon-disable {
|
||||
width: 12px;
|
||||
min-width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 4px;
|
||||
background-image: url('@/assets/img/control/checkbox_disable.png');
|
||||
}
|
||||
|
||||
&:hover:not(.checked) {
|
||||
.i-checkbox-icon {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 18px;
|
||||
background-image: url('@/assets/img/control/checkbox_hover.png');
|
||||
}
|
||||
}
|
||||
|
||||
outline: none;
|
||||
border-radius: 10px;
|
||||
box-sizing: border-box;
|
||||
background: #dcdfe6;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.3s, background-color 0.3s;
|
||||
vertical-align: middle;
|
||||
// border-radius: 16px;
|
||||
border: 1.5px solid transparent;
|
||||
background-clip: padding-box, border-box;
|
||||
background-origin: padding-box, border-box;
|
||||
background-image: linear-gradient(to right, #141414, #141414), linear-gradient(rgb(110, 89, 61), rgb(60, 46, 30));
|
||||
box-shadow: inset 0 0 2px 1.5px black;
|
||||
.i-checkbox-label {
|
||||
line-height: 24px;
|
||||
color: #937639;
|
||||
}
|
||||
}
|
||||
|
||||
.i-switch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// justify-content: center;
|
||||
|
||||
&.checked {
|
||||
.i-checkbox-icon {
|
||||
background-image:
|
||||
linear-gradient(to right, #8f6e29, #8f6e29),
|
||||
linear-gradient(rgb(110, 89, 61), rgb(60, 46, 30));
|
||||
}
|
||||
|
||||
.i-checkbox-icon::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 1.6px;
|
||||
left: 1px;
|
||||
border-radius: 100%;
|
||||
transition: all 0.3s;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
outline: 0.8px solid black;
|
||||
background: linear-gradient(rgb(15, 61, 116), rgb(8, 37, 71));
|
||||
box-shadow: inset 0 0 2px 0.5px rgb(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.i-checkbox-icon-disable {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 18px;
|
||||
|
||||
outline: none;
|
||||
border-radius: 10px;
|
||||
box-sizing: border-box;
|
||||
background: #dcdfe6;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.3s, background-color 0.3s;
|
||||
vertical-align: middle;
|
||||
// border-radius: 16px;
|
||||
border: 1.5px solid transparent;
|
||||
background-clip: padding-box, border-box;
|
||||
background-origin: padding-box, border-box;
|
||||
background-image: linear-gradient(to right, #dcdfe6, #dcdfe6), linear-gradient(rgb(110, 89, 61), rgb(60, 46, 30));
|
||||
box-shadow: inset 0 0 2px 1.5px black;
|
||||
}
|
||||
|
||||
.i-checkbox-icon-disable::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 1.6px;
|
||||
left: 1px;
|
||||
border-radius: 100%;
|
||||
transition: all 0.3s;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
// outline: 0.8px solid black;
|
||||
background: white;
|
||||
// box-shadow: inset 0 0 2px 0.5px rgb(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.i-checkbox-icon::after {
|
||||
background: linear-gradient(#15549f, #0e3c72);
|
||||
}
|
||||
}
|
||||
|
||||
.i-checkbox-label {
|
||||
line-height: 18px;
|
||||
height: 18px;
|
||||
padding-left: 2px;
|
||||
color: #937639;
|
||||
left: 100%;
|
||||
margin-left: -14.8px;
|
||||
}
|
||||
}
|
||||
|
||||
.i-checkbox-icon {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 18px;
|
||||
|
||||
outline: none;
|
||||
border-radius: 10px;
|
||||
box-sizing: border-box;
|
||||
background: #dcdfe6;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
border-color 0.3s,
|
||||
background-color 0.3s;
|
||||
vertical-align: middle;
|
||||
// border-radius: 16px;
|
||||
border: 1.5px solid transparent;
|
||||
background-clip: padding-box, border-box;
|
||||
background-origin: padding-box, border-box;
|
||||
background-image:
|
||||
linear-gradient(to right, #141414, #141414),
|
||||
linear-gradient(rgb(110, 89, 61), rgb(60, 46, 30));
|
||||
box-shadow: inset 0 0 2px 1.5px black;
|
||||
}
|
||||
|
||||
.i-checkbox-icon::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 1.6px;
|
||||
left: 1px;
|
||||
border-radius: 100%;
|
||||
transition: all 0.3s;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
outline: 0.8px solid black;
|
||||
background: linear-gradient(rgb(15, 61, 116), rgb(8, 37, 71));
|
||||
box-shadow: inset 0 0 2px 0.5px rgb(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.i-checkbox-icon-disable {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 18px;
|
||||
|
||||
outline: none;
|
||||
border-radius: 10px;
|
||||
box-sizing: border-box;
|
||||
background: #dcdfe6;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
border-color 0.3s,
|
||||
background-color 0.3s;
|
||||
vertical-align: middle;
|
||||
// border-radius: 16px;
|
||||
border: 1.5px solid transparent;
|
||||
background-clip: padding-box, border-box;
|
||||
background-origin: padding-box, border-box;
|
||||
background-image:
|
||||
linear-gradient(to right, #dcdfe6, #dcdfe6),
|
||||
linear-gradient(rgb(110, 89, 61), rgb(60, 46, 30));
|
||||
box-shadow: inset 0 0 2px 1.5px black;
|
||||
}
|
||||
|
||||
.i-checkbox-icon-disable::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 1.6px;
|
||||
left: 1px;
|
||||
border-radius: 100%;
|
||||
transition: all 0.3s;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
// outline: 0.8px solid black;
|
||||
background: white;
|
||||
// box-shadow: inset 0 0 2px 0.5px rgb(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.i-checkbox-icon::after {
|
||||
background: linear-gradient(#15549f, #0e3c72);
|
||||
}
|
||||
}
|
||||
|
||||
.i-checkbox-label {
|
||||
line-height: 18px;
|
||||
height: 18px;
|
||||
padding-left: 2px;
|
||||
color: #937639;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -123,6 +123,7 @@ export default defineComponent({
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use 'sass:color';
|
||||
$text-color: #e9c556;
|
||||
.i-icon-select {
|
||||
width: 28px;
|
||||
@@ -173,7 +174,7 @@ export default defineComponent({
|
||||
min-height: 28px;
|
||||
|
||||
$hoverColor: #002947;
|
||||
$activeColor: lighten($hoverColor, 5%);
|
||||
$activeColor: color.scale($hoverColor, $lightness: 5%);
|
||||
color: $text-color;
|
||||
|
||||
.i-option {
|
||||
|
||||
@@ -170,6 +170,7 @@ export default defineComponent({
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use "sass:color";
|
||||
$text-color: #937639;
|
||||
.i-select {
|
||||
min-width: 80px;
|
||||
@@ -244,7 +245,7 @@ export default defineComponent({
|
||||
z-index: 888;
|
||||
|
||||
$hoverColor: #002947;
|
||||
$activeColor: lighten($hoverColor, 5%);
|
||||
$activeColor: color.scale($hoverColor, $lightness: 5%);
|
||||
color: $text-color;
|
||||
|
||||
.i-select-dropdown-item {
|
||||
|
||||
@@ -16,14 +16,5 @@ import { useConfigStore } from '@/stores'
|
||||
const props = defineProps<{
|
||||
alter: string
|
||||
}>()
|
||||
const infoStore = useInfoStore()
|
||||
const configStore = useConfigStore()
|
||||
|
||||
onMounted(async () => {
|
||||
await infoStore.createCharacter(props.alter, '0')
|
||||
configStore.loadConfig()
|
||||
window.addEventListener('beforeunload', () => {
|
||||
configStore.saveConfig()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
<script lang="tsx">
|
||||
import { computed, defineComponent, ref, renderList } from "vue"
|
||||
import type { IEnchantingInfo } from "@/api/info/type"
|
||||
import { useInfoStore, useConfigStore } from "@/stores"
|
||||
export default defineComponent({
|
||||
name: "Equip",
|
||||
props: {
|
||||
part: {
|
||||
type: String,
|
||||
default: "头肩"
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const configStore = useConfigStore()
|
||||
const can_upgrade = computed(() => {
|
||||
return !["称号", "宠物"].includes(props.part as string)
|
||||
})
|
||||
|
||||
// const globalStore = useGlobalStore()
|
||||
|
||||
/** 是否有徽章 */
|
||||
const has_socket = computed(() => !["称号", "宠物", "耳环", "武器"].includes(props.part as string))
|
||||
/** 是否有右侧徽章 */
|
||||
const has_socket_right = computed(() => has_socket.value && !["辅助装备", "魔法石"].includes(props.part as string))
|
||||
const basicInfoStore = useInfoStore()
|
||||
|
||||
const enchanting_list = computed<IEnchantingInfo[] | undefined>(() => {
|
||||
return basicInfoStore.enchantings
|
||||
?.filter(item => item.position.includes(props.part) && !item.position.includes("武器装扮") && !item.position.includes("宠物装备"))
|
||||
.sort((a, b) => b.rate - a.rate)
|
||||
})
|
||||
|
||||
const emblem_list = computed<IEnchantingInfo[] | undefined>(() => {
|
||||
return basicInfoStore.emblems.filter(item => item.position.includes(props.part))
|
||||
})
|
||||
|
||||
const global_change = ref(false)
|
||||
|
||||
const currentInfo = function<T>(name: string, defaultValue?: T) {
|
||||
return computed<string | number>({
|
||||
get() {
|
||||
return (configStore.config.equips?.[props.part] as Record<string, any>)?.[name] ?? defaultValue ?? 0
|
||||
},
|
||||
set(val) {
|
||||
console.log(name, val)
|
||||
if (val == undefined) {
|
||||
return
|
||||
}
|
||||
if (name == "socket_right" && !has_socket_right.value) {
|
||||
// configStore.setForge(props.part, name, 0)
|
||||
return
|
||||
}
|
||||
|
||||
let parts: string[] = []
|
||||
|
||||
if (global_change.value) {
|
||||
if (name === "enchanting") {
|
||||
const enchant = basicInfoStore?.enchantings?.find(item => item.id == val) as IEnchantingInfo | undefined
|
||||
if (enchant?.position) {
|
||||
parts = enchant.position
|
||||
}
|
||||
}
|
||||
if (["socket_left", "socket_right"].includes(name)) {
|
||||
const emblem = basicInfoStore?.emblems?.find(item => item.id.toString() == val.toString()) as IEnchantingInfo | undefined
|
||||
if (emblem?.position) {
|
||||
parts = emblem.position.filter(item => !["皮肤", "武器装扮", "光环"].includes(item))
|
||||
}
|
||||
}
|
||||
if (["cursed_type", "cursed_number"].includes(name)) {
|
||||
parts = basicInfoStore.parts.filter(e => !["称号", "宠物"].includes(e))
|
||||
}
|
||||
} else {
|
||||
parts = [props.part]
|
||||
}
|
||||
console.log(parts,val)
|
||||
|
||||
for (const part of parts) {
|
||||
if (configStore.config.equips[part]) {
|
||||
(configStore.config.equips[part] as Record<string, any>)[name] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 附魔
|
||||
const enchanting = currentInfo<string | number>("enchanting")
|
||||
|
||||
// 镶嵌栏1
|
||||
const socket_left = currentInfo<string | number>("socket_left", 0)
|
||||
|
||||
// 镶嵌栏2
|
||||
const socket_right = currentInfo<string | number>("socket_right")
|
||||
|
||||
// 增幅
|
||||
const reinforce_type = currentInfo<string | number>("reinforce_type", 1)
|
||||
|
||||
// 增幅数值
|
||||
const reinforce = currentInfo<string | number>("reinforce")
|
||||
|
||||
|
||||
// 锻造数值
|
||||
const dz_number = currentInfo<string | number>("dz_number")
|
||||
|
||||
/**
|
||||
* 同步徽章1到徽章2
|
||||
* @param val
|
||||
*/
|
||||
function changeSocket(val: number) {
|
||||
if (has_socket_right.value) {
|
||||
socket_right.value = val
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<div class="flex flex-wrap equ-profile">
|
||||
<div class="equ-profile-item">
|
||||
<div class="mr-10px row-name">当前部位</div>
|
||||
<span> {props.part}</span>
|
||||
{can_upgrade.value ? <calc-checkbox style="margin-left:auto" v-model={global_change.value} label="全局修改"></calc-checkbox> : <div></div>}
|
||||
</div>
|
||||
{can_upgrade.value ? (
|
||||
<div class="equ-profile-item">
|
||||
<div class="row-name">增幅</div>
|
||||
<calc-select v-model={reinforce_type.value} class="flex-1 !h-20px">
|
||||
<calc-option value={1}>增幅</calc-option>
|
||||
<calc-option value={2}>强化</calc-option>
|
||||
</calc-select>
|
||||
<calc-select v-model={reinforce.value} class="flex-1 !h-20px">
|
||||
{renderList(32, i => (
|
||||
<calc-option value={i - 1}>{i - 1}</calc-option>
|
||||
))}
|
||||
</calc-select>
|
||||
{props.part == '武器' && (<calc-select v-model={dz_number.value} class="flex-1 !h-20px">
|
||||
{renderList(9, i => (
|
||||
<calc-option value={i - 1}>锻造+ {i - 1}</calc-option>
|
||||
))}
|
||||
</calc-select>)}
|
||||
</div>
|
||||
) : (
|
||||
<div></div>
|
||||
)}
|
||||
<div class="equ-profile-item">
|
||||
<div class="row-name">附魔</div>
|
||||
<calc-select v-model={enchanting.value} class="flex-1 !h-20px">
|
||||
<calc-option value={0}>无</calc-option>
|
||||
{renderList(enchanting_list.value ?? [], item => (
|
||||
<calc-option value={item.id}>{item.props}</calc-option>
|
||||
))}
|
||||
</calc-select>
|
||||
</div>
|
||||
{has_socket.value ? (
|
||||
<div class="equ-profile-item">
|
||||
<div class="row-name">徽章</div>
|
||||
<calc-select onChange={changeSocket} v-model={socket_left.value} class="flex-1 !h-20px">
|
||||
<calc-option value={0}>无</calc-option>
|
||||
{renderList(emblem_list.value ?? [], item => (
|
||||
<calc-option value={item.id}>{`${item.rarity}${item.type}徽章[${item.props}]`}</calc-option>
|
||||
))}
|
||||
</calc-select>
|
||||
{has_socket_right.value && (
|
||||
<calc-select v-model={socket_right.value} class="flex-1 !h-20px">
|
||||
<calc-option value={0}>无</calc-option>
|
||||
{renderList(emblem_list.value ?? [], item => (
|
||||
<calc-option value={item.id}>{`${item.rarity}${item.type}徽章[${item.props}]`}</calc-option>
|
||||
))}
|
||||
</calc-select>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div></div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss"></style>
|
||||
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div>
|
||||
<calc-collapse class="w-510px" title="装备打造(点击人物部位切换)">
|
||||
<equipment />
|
||||
</calc-collapse>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import equipment from './components/equipment.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.equ-profile{
|
||||
width: 100%;
|
||||
.equ-profile-item {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
align-items: center;
|
||||
|
||||
.row-name {
|
||||
flex: 0 0 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
:not(:last-child) {
|
||||
margin-right: 10px !important;
|
||||
}
|
||||
|
||||
.i-select-label {
|
||||
margin-right: 0px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@
|
||||
<calc-tabs route>
|
||||
<calc-tab :value="`/character/equipment/${props.alter}`">装备设置</calc-tab>
|
||||
<calc-tab :value="`/character/skill/${props.alter}`">技能设置</calc-tab>
|
||||
<calc-tab :value="`/character/forge/${props.alter}`">打造设置</calc-tab>
|
||||
</calc-tabs>
|
||||
</div>
|
||||
<div class="content flex">
|
||||
@@ -24,6 +25,7 @@ const configStore = useConfigStore()
|
||||
onMounted(async () => {
|
||||
await infoStore.createCharacter(props.alter, '0')
|
||||
configStore.loadConfig()
|
||||
console.log("~~~~~~~~")
|
||||
window.addEventListener('beforeunload', () => {
|
||||
configStore.saveConfig()
|
||||
})
|
||||
|
||||
@@ -2,6 +2,7 @@ import { getImageURL } from '@/utils/images'
|
||||
import type { ISkill } from '@/api/info/type'
|
||||
import { useVModel } from '@vueuse/core'
|
||||
import './style.scss'
|
||||
import CalcButton from '@/components/calc/button/index.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'SkillTree',
|
||||
@@ -106,10 +107,10 @@ export default defineComponent({
|
||||
<div class="absolute">
|
||||
<div class="w-36px h-55px bg-gradient-linear bg-gradient-[180deg,#f8e26c_0%,#f87c43_94.34%] z-1"></div>
|
||||
<div class="flex bottom--5px relative z-2 transform -translate-x-1/4">
|
||||
<button onClick={(e) => actionSkillLv(skill, 'subMax')}><</button>
|
||||
<button onClick={(e) => actionSkillLv(skill, 'sub')}>-</button>
|
||||
<button onClick={(e) => actionSkillLv(skill, 'add')}>+</button>
|
||||
<button onClick={(e) => actionSkillLv(skill, 'addMax')}>></button>
|
||||
<CalcButton onClick={(e:Event) => {e.stopPropagation();actionSkillLv(skill, 'subMax')}}><</CalcButton>
|
||||
<CalcButton onClick={(e:Event) => {e.stopPropagation();actionSkillLv(skill, 'sub')}}>-</CalcButton>
|
||||
<CalcButton icon="plus" onClick={(e:Event) => {e.stopPropagation();actionSkillLv(skill, 'add')}}></CalcButton>
|
||||
<CalcButton icon="next" onClick={(e:Event) => {e.stopPropagation();actionSkillLv(skill, 'addMax')}}></CalcButton>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -7,7 +7,7 @@ const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: defineAsyncComponent(() => import('@/pages/Home/Index.vue')),
|
||||
component: (() => import('@/pages/Home/Index.vue')),
|
||||
},
|
||||
{
|
||||
path:'/character/:alter',
|
||||
@@ -16,18 +16,23 @@ const routes: RouteRecordRaw[] = [
|
||||
},
|
||||
props: true,
|
||||
name:'character',
|
||||
component: defineAsyncComponent(() => import('@/pages/Character/Index.vue')),
|
||||
component: (() => import('@/pages/Character/Index.vue')),
|
||||
children: [
|
||||
{
|
||||
path: '/character/equipment/:alter',
|
||||
name: 'equipment',
|
||||
props: true,
|
||||
component: defineAsyncComponent(() => import('@/pages/Character/Equipment/Index.vue')),
|
||||
component: (() => import('@/pages/Character/Equipment/Index.vue')),
|
||||
},{
|
||||
path: '/character/skill/:alter',
|
||||
name: 'skill',
|
||||
props: true,
|
||||
component: defineAsyncComponent(() => import('@/pages/Character/Skill/index.vue')),
|
||||
component: (() => import('@/pages/Character/Skill/index.vue')),
|
||||
},{
|
||||
path: '/character/forge/:alter',
|
||||
name: 'forge',
|
||||
props: true,
|
||||
component: (() => import('@/pages/Character/Forge/index.vue')),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ export const useConfigStore = defineStore('configStore', () => {
|
||||
equips: {}
|
||||
})
|
||||
|
||||
|
||||
const loadConfig = () => {
|
||||
const infoStore = useInfoStore()
|
||||
const alter = infoStore.infos?.alter
|
||||
@@ -62,7 +63,7 @@ export const useConfigStore = defineStore('configStore', () => {
|
||||
if(!config.value?.equips) config.value.equips = {}
|
||||
if(!config.value?.skills) config.value.skills = {}
|
||||
|
||||
const part = ['上衣', '头肩', '下装', '腰带', '鞋', '手镯', '项链', '戒指', '耳环', '辅助装备', '魔法石', '武器'].filter(a => !config.value?.equips.hasOwnProperty(a))
|
||||
const part = infoStore.parts.filter(a => !config.value?.equips.hasOwnProperty(a))
|
||||
|
||||
const skillIDs = infoStore.skills.map(skill => skill.id.toString()).filter(a => !config.value?.skills.hasOwnProperty(a))
|
||||
|
||||
|
||||
@@ -13,6 +13,12 @@ export const useInfoStore = defineStore("infoStore", ()=>{
|
||||
|
||||
const suits = computed(()=>infos.value?.suits ?? [])
|
||||
|
||||
const enchantings = computed(()=>infos.value?.enchantings?? [])
|
||||
|
||||
const emblems = computed(()=>infos.value?.emblems?? [])
|
||||
|
||||
const parts = ['上衣', '头肩', '下装', '腰带', '鞋', '手镯', '项链', '戒指', '耳环', '辅助装备', '魔法石', '武器']
|
||||
|
||||
const createCharacter = async (alter: string, equVersion?: string) => {
|
||||
const time = new Date().getTime()
|
||||
alter_token.value = btoa(JSON.stringify({alter, equVersion, time}))
|
||||
@@ -26,5 +32,8 @@ export const useInfoStore = defineStore("infoStore", ()=>{
|
||||
equips,
|
||||
suits,
|
||||
createCharacter,
|
||||
enchantings,
|
||||
emblems,
|
||||
parts
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user