feat: 完成英雄配置编辑器全流程功能开发

本次提交实现了完整的英雄配置管理系统:
1.  新增服务器端英雄数据持久化接口,支持读取和保存英雄配置
2.  重构前端英雄编辑器UI,替换侧边栏为下拉选择器适配移动端
3.  统一调整前端页面样式,压缩间距适配更多内容
4.  修复Tooltip组件显示逻辑,优化技能飘字效果
5.  导入CSV英雄配置数据,补全全职业技能配置
6.  调整多个英雄预制体的尺寸和位置参数
7.  生成完整的英雄配置导出文件hexport.ts
This commit is contained in:
pan
2026-09-03 16:47:49 +08:00
parent 6a09ae2954
commit 87f771edd1
16 changed files with 1248 additions and 330 deletions

View File

@@ -4,32 +4,28 @@
<h1>英雄配置编辑器</h1>
<div class="actions">
<el-button size="small" @click="refreshMeta" :loading="loadingMeta">刷新配置数据</el-button>
<el-button size="small" type="success" @click="doSave" :disabled="!heroes.length">保存到服务器</el-button>
<el-button size="small" type="warning" @click="doExport" :disabled="!heroes.length">导出 hexport.ts</el-button>
</div>
</header>
<div class="hero-main">
<aside class="hero-sidebar">
<div class="side-head">
<span>英雄列表 ({{ heroes.length }})</span>
<el-button size="small" type="primary" text @click="addHero">+ 新增</el-button>
</div>
<div class="hero-list">
<div
v-for="(h, i) in heroes"
:key="i"
class="hero-item"
:class="{ active: i === activeIdx }"
@click="activeIdx = i"
>
<div>
<div>{{ h.uuid }} {{ h.name || '(未命名)' }}</div>
<div class="meta">{{ roleLabel(h.roleKey) }} · {{ typeLabel(h.typeKey) }} · ★{{ h.rarity }}</div>
</div>
<el-button type="danger" size="small" text @click.stop="removeHero(i)">删</el-button>
</div>
<div v-if="!heroes.length" class="empty">点击右上角"新增"创建英雄</div>
</div>
</aside>
<!-- 英雄选择工具栏:下拉选择,适配手机竖屏 -->
<div class="hero-toolbar">
<el-select
v-model="activeIdx"
class="hero-select"
:placeholder="`选择英雄(共 ${heroes.length} 个)`"
filterable
:disabled="!heroes.length"
>
<el-option v-for="(h, i) in heroes" :key="i" :label="`${h.uuid} ${h.name || '(未命名)'}`" :value="i">
<span>{{ h.uuid }} {{ h.name || '(未命名)' }}</span>
<span class="hero-option-meta">{{ roleLabel(h.roleKey) }} · {{ typeLabel(h.typeKey) }} · ★{{ h.rarity }}</span>
</el-option>
</el-select>
<el-button type="primary" @click="addHero">+ 新增</el-button>
<el-button type="danger" plain :disabled="activeIdx < 0" @click="removeHero(activeIdx)">删当前</el-button>
</div>
<section class="hero-editor" v-if="current">
<!-- 基础属性 -->
<div class="panel">
@@ -256,6 +252,27 @@ function addUltSkill() {
current.value.skills[1] = sk
}
async function loadHeroes() {
try {
const r = await api.fetchHeroes()
if (Array.isArray(r.heroes) && r.heroes.length) {
heroes.value = r.heroes
activeIdx.value = 0
}
} catch (e) {
ElMessage.error('加载英雄数据失败: ' + (e?.response?.data?.error || e.message))
}
}
async function doSave() {
try {
const r = await api.saveHeroes(heroes.value)
ElMessage.success(`已保存 ${r.count} 个英雄 → ${r.path}`)
} catch (e) {
ElMessage.error('保存失败: ' + (e?.response?.data?.error || e.message))
}
}
async function doExport() {
try {
await ElMessageBox.confirm(
@@ -272,5 +289,8 @@ async function doExport() {
}
}
onMounted(loadMeta)
onMounted(() => {
loadMeta()
loadHeroes()
})
</script>