修复编辑器不同步bug
This commit is contained in:
481
src/App.vue
481
src/App.vue
@@ -144,6 +144,7 @@
|
|||||||
theme="vs"
|
theme="vs"
|
||||||
:options="editorOptions"
|
:options="editorOptions"
|
||||||
:disabled="!isParsed"
|
:disabled="!isParsed"
|
||||||
|
@change="onJsonEditorChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -175,10 +176,11 @@
|
|||||||
<button
|
<button
|
||||||
class="btn btn-success flex-1"
|
class="btn btn-success flex-1"
|
||||||
@click="updateDataFromJson"
|
@click="updateDataFromJson"
|
||||||
:disabled="!isParsed"
|
:disabled="!isParsed || !hasJsonChanges"
|
||||||
>
|
>
|
||||||
<i class="fas fa-save mr-2"></i>
|
<span v-if="isDataSyncing" class="loading loading-spinner"></span>
|
||||||
更新数据
|
{{ isDataSyncing ? '更新中...' : '更新数据' }}
|
||||||
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -188,6 +190,15 @@
|
|||||||
<i class="fas fa-info-circle text-info mr-2"></i> {{ exportStatus }}
|
<i class="fas fa-info-circle text-info mr-2"></i> {{ exportStatus }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- JSON编辑状态(整合错误信息) -->
|
||||||
|
<div v-if="jsonEditStatus" class="mt-4 rounded-xl p-4" :class="jsonValidationError ? 'bg-error bg-opacity-10' : 'bg-base-100'">
|
||||||
|
<h3 class="font-bold text-lg mb-2" :class="jsonValidationError ? 'text-error' : ''">JSON编辑状态:</h3>
|
||||||
|
<div class="text-sm" :class="jsonValidationError ? 'text-error' : ''">
|
||||||
|
<i class="fas mr-2" :class="jsonValidationError ? 'fa-exclamation-triangle' : 'fa-info-circle text-info'"></i>
|
||||||
|
{{ jsonValidationError || jsonEditStatus }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -236,6 +247,7 @@
|
|||||||
class="input input-bordered"
|
class="input input-bordered"
|
||||||
v-model="blueprintData.name"
|
v-model="blueprintData.name"
|
||||||
placeholder="输入蓝图名称"
|
placeholder="输入蓝图名称"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -249,18 +261,21 @@
|
|||||||
class="input input-bordered dimension-input"
|
class="input input-bordered dimension-input"
|
||||||
v-model.number="blueprintData.header.designerDimension.x"
|
v-model.number="blueprintData.header.designerDimension.x"
|
||||||
placeholder="X"
|
placeholder="X"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
class="input input-bordered dimension-input"
|
class="input input-bordered dimension-input"
|
||||||
v-model.number="blueprintData.header.designerDimension.y"
|
v-model.number="blueprintData.header.designerDimension.y"
|
||||||
placeholder="Y"
|
placeholder="Y"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
class="input input-bordered dimension-input"
|
class="input input-bordered dimension-input"
|
||||||
v-model.number="blueprintData.header.designerDimension.z"
|
v-model.number="blueprintData.header.designerDimension.z"
|
||||||
placeholder="Z"
|
placeholder="Z"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -294,6 +309,7 @@
|
|||||||
type="number"
|
type="number"
|
||||||
class="input input-bordered"
|
class="input input-bordered"
|
||||||
v-model.number="blueprintData.config.iconID"
|
v-model.number="blueprintData.config.iconID"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -306,6 +322,7 @@
|
|||||||
class="input input-bordered"
|
class="input input-bordered"
|
||||||
v-model="blueprintData.config.referencedIconLibrary"
|
v-model="blueprintData.config.referencedIconLibrary"
|
||||||
placeholder="输入图标库路径"
|
placeholder="输入图标库路径"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -318,6 +335,7 @@
|
|||||||
class="input input-bordered"
|
class="input input-bordered"
|
||||||
v-model="blueprintData.config.iconLibraryType"
|
v-model="blueprintData.config.iconLibraryType"
|
||||||
placeholder="输入图标库类型"
|
placeholder="输入图标库类型"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -329,6 +347,7 @@
|
|||||||
class="textarea textarea-bordered"
|
class="textarea textarea-bordered"
|
||||||
v-model="blueprintData.config.description"
|
v-model="blueprintData.config.description"
|
||||||
placeholder="输入蓝图描述"
|
placeholder="输入蓝图描述"
|
||||||
|
@change="onBasicDataChange"
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -346,6 +365,7 @@
|
|||||||
max="1"
|
max="1"
|
||||||
step="0.01"
|
step="0.01"
|
||||||
placeholder="R"
|
placeholder="R"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
@@ -355,6 +375,7 @@
|
|||||||
max="1"
|
max="1"
|
||||||
step="0.01"
|
step="0.01"
|
||||||
placeholder="G"
|
placeholder="G"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
@@ -364,6 +385,7 @@
|
|||||||
max="1"
|
max="1"
|
||||||
step="0.01"
|
step="0.01"
|
||||||
placeholder="B"
|
placeholder="B"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
@@ -373,6 +395,7 @@
|
|||||||
max="1"
|
max="1"
|
||||||
step="0.01"
|
step="0.01"
|
||||||
placeholder="A"
|
placeholder="A"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -403,6 +426,7 @@
|
|||||||
class="input input-bordered"
|
class="input input-bordered"
|
||||||
v-model="blueprintData.config.lastEditedBy[0].accountId"
|
v-model="blueprintData.config.lastEditedBy[0].accountId"
|
||||||
placeholder="输入账户ID"
|
placeholder="输入账户ID"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -415,6 +439,7 @@
|
|||||||
class="input input-bordered"
|
class="input input-bordered"
|
||||||
v-model="blueprintData.config.lastEditedBy[0].displayName"
|
v-model="blueprintData.config.lastEditedBy[0].displayName"
|
||||||
placeholder="输入显示名称"
|
placeholder="输入显示名称"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -427,6 +452,7 @@
|
|||||||
class="input input-bordered"
|
class="input input-bordered"
|
||||||
v-model="blueprintData.config.lastEditedBy[0].platformName"
|
v-model="blueprintData.config.lastEditedBy[0].platformName"
|
||||||
placeholder="输入平台名称"
|
placeholder="输入平台名称"
|
||||||
|
@change="onBasicDataChange"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -490,9 +516,9 @@
|
|||||||
class="fieldset bg-base-200 border-base-300 rounded-box border p-4"
|
class="fieldset bg-base-200 border-base-300 rounded-box border p-4"
|
||||||
>
|
>
|
||||||
<div class="join">
|
<div class="join">
|
||||||
<input type="text" class="input join-item flex-grow" v-model="item[0].pathName" />
|
<input type="text" class="input join-item flex-grow" v-model="item[0].pathName" @change="onBasicDataChange" />
|
||||||
|
|
||||||
<input type="number" class="input join-item w-20" v-model.number="item[1]" />
|
<input type="number" class="input join-item w-20" v-model.number="item[1]" @change="onBasicDataChange" />
|
||||||
<button class="btn join-item btn-error "@click="removeItemCost(index)">删除</button>
|
<button class="btn join-item btn-error "@click="removeItemCost(index)">删除</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -520,7 +546,7 @@
|
|||||||
>
|
>
|
||||||
|
|
||||||
<div class="join ">
|
<div class="join ">
|
||||||
<input class="input join-item flex-grow" type="text" v-model="recipe.pathName" placeholder="输入路径名称"/>
|
<input class="input join-item flex-grow" type="text" v-model="recipe.pathName" placeholder="输入路径名称" @change="onBasicDataChange" />
|
||||||
<button class="btn join-item btn-error" @click="removeRecipe(index)">删除</button>
|
<button class="btn join-item btn-error" @click="removeRecipe(index)">删除</button>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -536,7 +562,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 进阶编辑区域 - 使用第一个文件的编辑器 -->
|
<!-- 进阶编辑区域 -->
|
||||||
<div v-show="activeVisualTab === 'advanced'">
|
<div v-show="activeVisualTab === 'advanced'">
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-1">
|
<div class="grid grid-cols-1 lg:grid-cols-4 gap-1">
|
||||||
<!-- 左侧实体列表 -->
|
<!-- 左侧实体列表 -->
|
||||||
@@ -590,6 +616,7 @@
|
|||||||
language="json"
|
language="json"
|
||||||
theme="vs"
|
theme="vs"
|
||||||
:options="editorOptions"
|
:options="editorOptions"
|
||||||
|
@change="onEntityJsonChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3 flex justify-end">
|
<div class="mt-3 flex justify-end">
|
||||||
@@ -608,25 +635,25 @@
|
|||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">X</span>
|
<span class="label-text">X</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="number" v-model.number="selectedEntity.transform.rotation.x" class="input input-bordered">
|
<input type="number" v-model.number="selectedEntity.transform.rotation.x" class="input input-bordered" @change="onEntityDataChange">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">Y</span>
|
<span class="label-text">Y</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="number" v-model.number="selectedEntity.transform.rotation.y" class="input input-bordered">
|
<input type="number" v-model.number="selectedEntity.transform.rotation.y" class="input input-bordered" @change="onEntityDataChange">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">Z</span>
|
<span class="label-text">Z</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="number" v-model.number="selectedEntity.transform.rotation.z" class="input input-bordered">
|
<input type="number" v-model.number="selectedEntity.transform.rotation.z" class="input input-bordered" @change="onEntityDataChange">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">W</span>
|
<span class="label-text">W</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="number" v-model.number="selectedEntity.transform.rotation.w" class="input input-bordered">
|
<input type="number" v-model.number="selectedEntity.transform.rotation.w" class="input input-bordered" @change="onEntityDataChange">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -638,19 +665,19 @@
|
|||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">X</span>
|
<span class="label-text">X</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="number" v-model.number="selectedEntity.transform.translation.x" class="input input-bordered">
|
<input type="number" v-model.number="selectedEntity.transform.translation.x" class="input input-bordered" @change="onEntityDataChange">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">Y</span>
|
<span class="label-text">Y</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="number" v-model.number="selectedEntity.transform.translation.y" class="input input-bordered">
|
<input type="number" v-model.number="selectedEntity.transform.translation.y" class="input input-bordered" @change="onEntityDataChange">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">Z</span>
|
<span class="label-text">Z</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="number" v-model.number="selectedEntity.transform.translation.z" class="input input-bordered">
|
<input type="number" v-model.number="selectedEntity.transform.translation.z" class="input input-bordered" @change="onEntityDataChange">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -662,19 +689,19 @@
|
|||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">X</span>
|
<span class="label-text">X</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="number" v-model.number="selectedEntity.transform.scale3d.x" class="input input-bordered">
|
<input type="number" v-model.number="selectedEntity.transform.scale3d.x" class="input input-bordered" @change="onEntityDataChange">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">Y</span>
|
<span class="label-text">Y</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="number" v-model.number="selectedEntity.transform.scale3d.y" class="input input-bordered">
|
<input type="number" v-model.number="selectedEntity.transform.scale3d.y" class="input input-bordered" @change="onEntityDataChange">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">Z</span>
|
<span class="label-text">Z</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="number" v-model.number="selectedEntity.transform.scale3d.z" class="input input-bordered">
|
<input type="number" v-model.number="selectedEntity.transform.scale3d.z" class="input input-bordered" @change="onEntityDataChange">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -701,6 +728,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
v-model="value.name"
|
v-model="value.name"
|
||||||
class="input input-bordered input-sm"
|
class="input input-bordered input-sm"
|
||||||
|
@change="onEntityDataChange"
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -709,6 +737,7 @@
|
|||||||
v-model="value.ueType"
|
v-model="value.ueType"
|
||||||
class="input input-bordered input-sm"
|
class="input input-bordered input-sm"
|
||||||
placeholder="输入类型"
|
placeholder="输入类型"
|
||||||
|
@change="onEntityDataChange"
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -719,6 +748,7 @@
|
|||||||
language="json"
|
language="json"
|
||||||
theme="vs"
|
theme="vs"
|
||||||
:options="smallEditorOptions"
|
:options="smallEditorOptions"
|
||||||
|
@change="(val) => onObjectPropertyChange(key, val)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
@@ -727,6 +757,7 @@
|
|||||||
:value="getPropertyDisplayValue(value)"
|
:value="getPropertyDisplayValue(value)"
|
||||||
@input="setPropertyValue(value, $event.target.value)"
|
@input="setPropertyValue(value, $event.target.value)"
|
||||||
class="input input-bordered input-sm"
|
class="input input-bordered input-sm"
|
||||||
|
@change="onEntityDataChange"
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -770,6 +801,7 @@
|
|||||||
language="json"
|
language="json"
|
||||||
theme="vs"
|
theme="vs"
|
||||||
:options="editorOptions"
|
:options="editorOptions"
|
||||||
|
@change="onComponentsJsonChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3 flex justify-end">
|
<div class="mt-3 flex justify-end">
|
||||||
@@ -799,6 +831,7 @@
|
|||||||
language="json"
|
language="json"
|
||||||
theme="vs"
|
theme="vs"
|
||||||
:options="editorOptions"
|
:options="editorOptions"
|
||||||
|
@change="(val) => onAttachedComponentChange(index, val)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
@@ -834,7 +867,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, computed, watch } from 'vue';
|
import { ref, computed, watch, nextTick } from 'vue';
|
||||||
import { Parser } from '@etothepii/satisfactory-file-parser';
|
import { Parser } from '@etothepii/satisfactory-file-parser';
|
||||||
import { CodeEditor } from 'monaco-editor-vue3';
|
import { CodeEditor } from 'monaco-editor-vue3';
|
||||||
|
|
||||||
@@ -853,16 +886,24 @@ export default {
|
|||||||
const progress = ref(0);
|
const progress = ref(0);
|
||||||
const error = ref('');
|
const error = ref('');
|
||||||
const exportStatus = ref('');
|
const exportStatus = ref('');
|
||||||
|
const jsonEditStatus = ref('');
|
||||||
|
const jsonValidationError = ref('');
|
||||||
const isParsing = ref(false);
|
const isParsing = ref(false);
|
||||||
const isExporting = ref(false);
|
const isExporting = ref(false);
|
||||||
const showObjects = ref(false);
|
const showObjects = ref(false);
|
||||||
const activeVisualTab = ref('basic');
|
const activeVisualTab = ref('basic');
|
||||||
const isParsed = ref(false);
|
const isParsed = ref(false);
|
||||||
|
const isDataSyncing = ref(false);
|
||||||
|
const hasJsonChanges = ref(false);
|
||||||
|
|
||||||
|
// JSON编辑器内容缓存
|
||||||
|
const jsonEditorContent = ref('');
|
||||||
|
const lastValidJson = ref('');
|
||||||
|
|
||||||
// 默认的 sbpcfg 十六进制数据
|
// 默认的 sbpcfg 十六进制数据
|
||||||
const defaultSbpcfgHex = '04000000e5ffffff5300610074006900730066006100630074006f00720079002000dd84fe56167f918f6856d89ea48b73006200700063006600670000000e0300000000803f0000803f0000803f0000803f300000002f47616d652f466163746f727947616d652f2d5368617265642f426c75657072696e742f49636f6e4c696272617279000c00000049636f6e4c69627261727900010000000000000000000000000000000000000000';
|
const defaultSbpcfgHex = '04000000e5ffffff5300610074006900730066006100630074006f00720079002000dd84fe56167f918f6856d89ea48b73006200700063006600670000000e0300000000803f0000803f0000803f0000803f300000002f47616d652f466163746f727947616d652f2d5368617265642f426c75657072696e742f49636f6e4c696272617279000c00000049636f6e4c69627261727900010000000000000000000000000000000000000000';
|
||||||
|
|
||||||
// 编辑器选项 - 调整行号宽度
|
// 编辑器选项
|
||||||
const editorOptions = ref({
|
const editorOptions = ref({
|
||||||
automaticLayout: true,
|
automaticLayout: true,
|
||||||
minimap: { enabled: false },
|
minimap: { enabled: false },
|
||||||
@@ -877,7 +918,6 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const smallEditorOptions = ref({
|
const smallEditorOptions = ref({
|
||||||
...editorOptions.value,
|
...editorOptions.value,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@@ -886,7 +926,7 @@ export default {
|
|||||||
tabSize: 2,
|
tabSize: 2,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 蓝图数据对象
|
// 蓝图数据对象 - 统一管理所有数据
|
||||||
const blueprintData = ref({
|
const blueprintData = ref({
|
||||||
name: '',
|
name: '',
|
||||||
compressionInfo: {
|
compressionInfo: {
|
||||||
@@ -924,13 +964,10 @@ export default {
|
|||||||
displayName: "",
|
displayName: "",
|
||||||
platformName: ""
|
platformName: ""
|
||||||
}]
|
}]
|
||||||
}
|
},
|
||||||
|
objects: [] // 统一管理所有对象数据
|
||||||
});
|
});
|
||||||
|
|
||||||
// Objects 数据
|
|
||||||
const rawObjects = ref([]);
|
|
||||||
const newObjects = ref([]);
|
|
||||||
|
|
||||||
// 使用轻量级对象存储文件信息
|
// 使用轻量级对象存储文件信息
|
||||||
const fileInfo = ref({
|
const fileInfo = ref({
|
||||||
blueprintName: '',
|
blueprintName: '',
|
||||||
@@ -938,7 +975,7 @@ export default {
|
|||||||
configFileName: ''
|
configFileName: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
// 第一个文件编辑器的状态
|
// 实体编辑器状态
|
||||||
const selectedEntityIndex = ref(null);
|
const selectedEntityIndex = ref(null);
|
||||||
const activeTab = ref('raw');
|
const activeTab = ref('raw');
|
||||||
const newProperty = ref({
|
const newProperty = ref({
|
||||||
@@ -965,9 +1002,39 @@ export default {
|
|||||||
const configFileName = computed(() => fileInfo.value.configFileName);
|
const configFileName = computed(() => fileInfo.value.configFileName);
|
||||||
const blueprintName = computed(() => fileInfo.value.blueprintName);
|
const blueprintName = computed(() => fileInfo.value.blueprintName);
|
||||||
|
|
||||||
// 第一个文件编辑器的计算属性
|
// 计算属性:根据开关状态决定显示的JSON内容
|
||||||
|
const displayedJson = computed({
|
||||||
|
get: () => {
|
||||||
|
if (!isParsed.value) return '';
|
||||||
|
|
||||||
|
// 如果有JSON验证错误,显示当前编辑器内容
|
||||||
|
if (jsonValidationError.value && jsonEditorContent.value) {
|
||||||
|
return jsonEditorContent.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有未保存的JSON编辑器内容,优先使用
|
||||||
|
if (jsonEditorContent.value && hasJsonChanges.value) {
|
||||||
|
return jsonEditorContent.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 否则使用当前数据生成JSON
|
||||||
|
const jsonObj = {
|
||||||
|
...blueprintData.value,
|
||||||
|
objects: showObjects.value ? blueprintData.value.objects : undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
const currentJson = JSON.stringify(jsonObj, null, 2);
|
||||||
|
lastValidJson.value = currentJson;
|
||||||
|
return currentJson;
|
||||||
|
},
|
||||||
|
set: (value) => {
|
||||||
|
jsonEditorContent.value = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 实体编辑器计算属性
|
||||||
const filteredEntities = computed(() => {
|
const filteredEntities = computed(() => {
|
||||||
return newObjects.value.filter(entity =>
|
return blueprintData.value.objects.filter(entity =>
|
||||||
entity && entity.type === 'SaveEntity'
|
entity && entity.type === 'SaveEntity'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -1002,42 +1069,18 @@ export default {
|
|||||||
const attachedComponents = computed(() => {
|
const attachedComponents = computed(() => {
|
||||||
if (!selectedEntity.value) return [];
|
if (!selectedEntity.value) return [];
|
||||||
|
|
||||||
return newObjects.value.filter(e =>
|
return blueprintData.value.objects.filter(e =>
|
||||||
e && e.type === 'SaveComponent' &&
|
e && e.type === 'SaveComponent' &&
|
||||||
e.parentEntityName === selectedEntity.value.instanceName
|
e.parentEntityName === selectedEntity.value.instanceName
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 计算属性:根据开关状态决定显示的JSON内容
|
// 辅助函数
|
||||||
const displayedJson = computed({
|
|
||||||
get: () => {
|
|
||||||
if (!isParsed.value) return '';
|
|
||||||
|
|
||||||
const jsonObj = {
|
|
||||||
...blueprintData.value,
|
|
||||||
objects: showObjects.value ? newObjects.value : undefined
|
|
||||||
};
|
|
||||||
|
|
||||||
return JSON.stringify(jsonObj, null, 2);
|
|
||||||
},
|
|
||||||
set: (value) => {
|
|
||||||
// 仅存储JSON字符串,不自动更新数据模型
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 辅助函数:检查是否为复杂对象需要JSON编辑器
|
|
||||||
const isComplexValue = (value) => {
|
const isComplexValue = (value) => {
|
||||||
if (value === null || value === undefined) return false;
|
if (value === null || value === undefined) return false;
|
||||||
return typeof value === 'object' && !(value instanceof Array);
|
return typeof value === 'object' && !(value instanceof Array);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 辅助函数:获取属性显示类型
|
|
||||||
const getPropertyDisplayType = (property) => {
|
|
||||||
if (!property) return '';
|
|
||||||
return property.ueType || property.type || '';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 辅助函数:获取属性值用于显示
|
|
||||||
const getPropertyDisplayValue = (property) => {
|
const getPropertyDisplayValue = (property) => {
|
||||||
if (!property) return '';
|
if (!property) return '';
|
||||||
|
|
||||||
@@ -1053,7 +1096,6 @@ export default {
|
|||||||
return property.value;
|
return property.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 辅助函数:设置属性值
|
|
||||||
const setPropertyValue = (property, newValue) => {
|
const setPropertyValue = (property, newValue) => {
|
||||||
if (!property) return;
|
if (!property) return;
|
||||||
|
|
||||||
@@ -1068,24 +1110,98 @@ export default {
|
|||||||
property.value = newValue;
|
property.value = newValue;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// 如果JSON解析失败,保持原值
|
|
||||||
console.warn('JSON解析失败,保持原值:', e);
|
console.warn('JSON解析失败,保持原值:', e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 方法:处理显示名称
|
|
||||||
const getDisplayName = (instanceName) => {
|
const getDisplayName = (instanceName) => {
|
||||||
if (!instanceName) return '';
|
if (!instanceName) return '';
|
||||||
return instanceName.replace(/^Persistent_Level:PersistentLevel\./, '');
|
return instanceName.replace(/^Persistent_Level:PersistentLevel\./, '');
|
||||||
};
|
};
|
||||||
|
|
||||||
// 方法:处理类型名称
|
|
||||||
const getTypeName = (typePath) => {
|
const getTypeName = (typePath) => {
|
||||||
if (!typePath) return '';
|
if (!typePath) return '';
|
||||||
return typePath.split('/').pop() || typePath;
|
return typePath.split('/').pop() || typePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 方法
|
// JSON验证函数
|
||||||
|
const validateJson = (jsonString) => {
|
||||||
|
if (!jsonString || jsonString.trim() === '') {
|
||||||
|
return { isValid: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 尝试解析JSON
|
||||||
|
const parsed = JSON.parse(jsonString);
|
||||||
|
return { isValid: true, data: parsed };
|
||||||
|
} catch (error) {
|
||||||
|
return { isValid: false, error: error.message };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// JSON编辑器变化处理
|
||||||
|
const onJsonEditorChange = (value) => {
|
||||||
|
jsonEditorContent.value = value;
|
||||||
|
|
||||||
|
// 验证JSON格式
|
||||||
|
const validationResult = validateJson(value);
|
||||||
|
if (validationResult.isValid) {
|
||||||
|
jsonValidationError.value = '';
|
||||||
|
hasJsonChanges.value = true;
|
||||||
|
jsonEditStatus.value = 'JSON已修改,点击"更新数据"保存更改';
|
||||||
|
} else {
|
||||||
|
jsonValidationError.value = validationResult.error;
|
||||||
|
jsonEditStatus.value = 'JSON格式错误,请修复后再更新';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 数据同步方法
|
||||||
|
const syncJsonDisplay = () => {
|
||||||
|
// 在下一次DOM更新后刷新JSON显示
|
||||||
|
nextTick(() => {
|
||||||
|
jsonEditorContent.value = ''; // 清空缓存,强制使用最新数据
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onBasicDataChange = () => {
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '数据已修改,JSON将自动更新';
|
||||||
|
};
|
||||||
|
|
||||||
|
const onEntityDataChange = () => {
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '实体数据已修改,JSON将自动更新';
|
||||||
|
};
|
||||||
|
|
||||||
|
const onEntityJsonChange = () => {
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '实体JSON已修改,JSON将自动更新';
|
||||||
|
};
|
||||||
|
|
||||||
|
const onObjectPropertyChange = (key, value) => {
|
||||||
|
if (selectedEntity.value && selectedEntity.value.properties && selectedEntity.value.properties[key]) {
|
||||||
|
try {
|
||||||
|
selectedEntity.value.properties[key].value = JSON.parse(value);
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '属性已修改,JSON将自动更新';
|
||||||
|
} catch (e) {
|
||||||
|
console.error('JSON解析错误:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onComponentsJsonChange = () => {
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '组件已修改,JSON将自动更新';
|
||||||
|
};
|
||||||
|
|
||||||
|
const onAttachedComponentChange = (index, value) => {
|
||||||
|
attachedComponentJson.value[index] = value;
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '附属组件已修改,JSON将自动更新';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 文件操作方法
|
||||||
const triggerFileInput = () => {
|
const triggerFileInput = () => {
|
||||||
fileInput.value.click();
|
fileInput.value.click();
|
||||||
};
|
};
|
||||||
@@ -1135,15 +1251,61 @@ export default {
|
|||||||
progress.value = 0;
|
progress.value = 0;
|
||||||
error.value = '';
|
error.value = '';
|
||||||
exportStatus.value = '';
|
exportStatus.value = '';
|
||||||
|
jsonEditStatus.value = '';
|
||||||
|
jsonValidationError.value = '';
|
||||||
isParsing.value = false;
|
isParsing.value = false;
|
||||||
isExporting.value = false;
|
isExporting.value = false;
|
||||||
|
isDataSyncing.value = false;
|
||||||
|
hasJsonChanges.value = false;
|
||||||
showObjects.value = false;
|
showObjects.value = false;
|
||||||
activeVisualTab.value = 'basic';
|
activeVisualTab.value = 'basic';
|
||||||
isParsed.value = false;
|
isParsed.value = false;
|
||||||
rawObjects.value = [];
|
|
||||||
newObjects.value = [];
|
|
||||||
selectedEntityIndex.value = null;
|
selectedEntityIndex.value = null;
|
||||||
activeTab.value = 'raw';
|
activeTab.value = 'raw';
|
||||||
|
jsonEditorContent.value = '';
|
||||||
|
lastValidJson.value = '';
|
||||||
|
|
||||||
|
// 重置蓝图数据
|
||||||
|
blueprintData.value = {
|
||||||
|
name: '',
|
||||||
|
compressionInfo: {
|
||||||
|
chunkHeaderVersion: 0,
|
||||||
|
packageFileTag: 0,
|
||||||
|
maxUncompressedChunkContentSize: 0,
|
||||||
|
compressionAlgorithm: 0
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
headerVersion: 0,
|
||||||
|
saveVersion: 0,
|
||||||
|
buildVersion: 0,
|
||||||
|
designerDimension: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
},
|
||||||
|
recipeReferences: [],
|
||||||
|
itemCosts: []
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
configVersion: 0,
|
||||||
|
description: '',
|
||||||
|
color: {
|
||||||
|
r: 0,
|
||||||
|
g: 0,
|
||||||
|
b: 0,
|
||||||
|
a: 1
|
||||||
|
},
|
||||||
|
iconID: 0,
|
||||||
|
referencedIconLibrary: '',
|
||||||
|
iconLibraryType: '',
|
||||||
|
lastEditedBy: [{
|
||||||
|
accountId: "",
|
||||||
|
displayName: "",
|
||||||
|
platformName: ""
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
objects: []
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseBlueprint = async () => {
|
const parseBlueprint = async () => {
|
||||||
@@ -1154,10 +1316,12 @@ export default {
|
|||||||
statusMessages.value = [];
|
statusMessages.value = [];
|
||||||
progress.value = 0;
|
progress.value = 0;
|
||||||
error.value = '';
|
error.value = '';
|
||||||
|
jsonEditStatus.value = '';
|
||||||
|
jsonValidationError.value = '';
|
||||||
selectedEntityIndex.value = null;
|
selectedEntityIndex.value = null;
|
||||||
activeTab.value = 'raw';
|
activeTab.value = 'raw';
|
||||||
rawObjects.value = [];
|
jsonEditorContent.value = '';
|
||||||
newObjects.value = [];
|
hasJsonChanges.value = false;
|
||||||
|
|
||||||
const sbpFile = uploadedFiles.value.find(f => f.name.endsWith('.sbp'));
|
const sbpFile = uploadedFiles.value.find(f => f.name.endsWith('.sbp'));
|
||||||
const sbpcfgFile = uploadedFiles.value.find(f => f.name.endsWith('.sbpcfg'));
|
const sbpcfgFile = uploadedFiles.value.find(f => f.name.endsWith('.sbpcfg'));
|
||||||
@@ -1202,9 +1366,7 @@ export default {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
rawObjects.value = blueprint.objects || [];
|
// 统一设置所有数据到主蓝图数据对象
|
||||||
newObjects.value = JSON.parse(JSON.stringify(rawObjects.value));
|
|
||||||
|
|
||||||
blueprintData.value = {
|
blueprintData.value = {
|
||||||
name: blueprint.name || '',
|
name: blueprint.name || '',
|
||||||
compressionInfo: {
|
compressionInfo: {
|
||||||
@@ -1242,17 +1404,27 @@ export default {
|
|||||||
displayName: "",
|
displayName: "",
|
||||||
platformName: ""
|
platformName: ""
|
||||||
}]
|
}]
|
||||||
}
|
},
|
||||||
|
objects: blueprint.objects || [] // 统一管理对象数据
|
||||||
};
|
};
|
||||||
|
|
||||||
statusMessages.value.push('蓝图文件解析完成!');
|
statusMessages.value.push('蓝图文件解析完成!');
|
||||||
isParsed.value = true;
|
isParsed.value = true;
|
||||||
progress.value = 100;
|
progress.value = 100;
|
||||||
|
jsonEditStatus.value = '数据解析完成,可以开始编辑';
|
||||||
|
|
||||||
|
// 初始化lastValidJson
|
||||||
|
const jsonObj = {
|
||||||
|
...blueprintData.value,
|
||||||
|
objects: showObjects.value ? blueprintData.value.objects : undefined
|
||||||
|
};
|
||||||
|
lastValidJson.value = JSON.stringify(jsonObj, null, 2);
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('解析错误:', err);
|
console.error('解析错误:', err);
|
||||||
error.value = `解析错误: ${err.message}`;
|
error.value = `解析错误: ${err.message}`;
|
||||||
statusMessages.value.push('解析失败!');
|
statusMessages.value.push('解析失败!');
|
||||||
|
jsonEditStatus.value = '解析失败,请检查文件格式';
|
||||||
} finally {
|
} finally {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
isParsing.value = false;
|
isParsing.value = false;
|
||||||
@@ -1270,18 +1442,15 @@ export default {
|
|||||||
// 创建当前时间戳
|
// 创建当前时间戳
|
||||||
const timestamp = Date.now().toString();
|
const timestamp = Date.now().toString();
|
||||||
|
|
||||||
// 准备导出的数据 - 深拷贝避免修改原始数据
|
// 准备导出的数据
|
||||||
const exportData = JSON.parse(JSON.stringify({
|
const exportData = JSON.parse(JSON.stringify(blueprintData.value));
|
||||||
...blueprintData.value,
|
|
||||||
objects: newObjects.value
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 确保 lastEditedBy 数组存在
|
// 确保 lastEditedBy 数组存在
|
||||||
if (!exportData.config.lastEditedBy) {
|
if (!exportData.config.lastEditedBy) {
|
||||||
exportData.config.lastEditedBy = [];
|
exportData.config.lastEditedBy = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在数组尾部添加新的编辑者信息(第二位)
|
// 在数组尾部添加新的编辑者信息
|
||||||
exportData.config.lastEditedBy.push({
|
exportData.config.lastEditedBy.push({
|
||||||
accountId: timestamp,
|
accountId: timestamp,
|
||||||
displayName: "LinXingLuo",
|
displayName: "LinXingLuo",
|
||||||
@@ -1333,44 +1502,111 @@ export default {
|
|||||||
|
|
||||||
const formatJson = () => {
|
const formatJson = () => {
|
||||||
try {
|
try {
|
||||||
const obj = JSON.parse(displayedJson.value);
|
if (!jsonEditorContent.value) {
|
||||||
displayedJson.value = JSON.stringify(obj, null, 2);
|
jsonEditStatus.value = '没有内容可格式化';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const validationResult = validateJson(jsonEditorContent.value);
|
||||||
|
if (!validationResult.isValid) {
|
||||||
|
jsonValidationError.value = validationResult.error;
|
||||||
|
jsonEditStatus.value = 'JSON格式错误,无法格式化';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const obj = validationResult.data;
|
||||||
|
const formattedJson = JSON.stringify(obj, null, 2);
|
||||||
|
jsonEditorContent.value = formattedJson;
|
||||||
|
jsonEditStatus.value = 'JSON已格式化';
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error.value = 'JSON格式错误,无法格式化';
|
error.value = 'JSON格式错误,无法格式化';
|
||||||
|
jsonEditStatus.value = '格式化失败:JSON格式错误';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const refreshJson = () => {
|
const refreshJson = () => {
|
||||||
const jsonObj = {
|
// 只有有更改时才提示刷新
|
||||||
...blueprintData.value,
|
if (hasJsonChanges.value) {
|
||||||
objects: showObjects.value ? newObjects.value : undefined
|
if (confirm('刷新将丢失当前的更改,是否继续?')) {
|
||||||
|
forceRefreshJson();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
forceRefreshJson();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
displayedJson.value = JSON.stringify(jsonObj, null, 2);
|
const forceRefreshJson = () => {
|
||||||
|
// 清空缓存,强制使用最新数据
|
||||||
|
jsonEditorContent.value = '';
|
||||||
|
jsonValidationError.value = '';
|
||||||
|
hasJsonChanges.value = false;
|
||||||
|
jsonEditStatus.value = 'JSON已刷新到最新数据';
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateDataFromJson = () => {
|
const updateDataFromJson = () => {
|
||||||
try {
|
if (!jsonEditorContent.value || !hasJsonChanges.value) {
|
||||||
const editedObj = JSON.parse(displayedJson.value);
|
jsonEditStatus.value = '没有要更新的内容或内容无变化';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const key in editedObj) {
|
// 首先验证JSON
|
||||||
if (key !== 'objects') {
|
const validationResult = validateJson(jsonEditorContent.value);
|
||||||
|
if (!validationResult.isValid) {
|
||||||
|
jsonValidationError.value = validationResult.error;
|
||||||
|
jsonEditStatus.value = 'JSON格式错误,无法更新数据';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
isDataSyncing.value = true;
|
||||||
|
jsonEditStatus.value = '正在更新数据...';
|
||||||
|
|
||||||
|
const editedObj = validationResult.data;
|
||||||
|
|
||||||
|
// 更新所有数据到主蓝图数据对象
|
||||||
|
Object.keys(editedObj).forEach(key => {
|
||||||
|
if (key === 'objects') {
|
||||||
|
// 特殊处理objects字段
|
||||||
|
if (editedObj.objects !== undefined) {
|
||||||
|
blueprintData.value.objects = editedObj.objects;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 简单赋值
|
||||||
blueprintData.value[key] = editedObj[key];
|
blueprintData.value[key] = editedObj[key];
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 确保objects字段始终存在
|
||||||
|
if (!blueprintData.value.objects) {
|
||||||
|
blueprintData.value.objects = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (editedObj.objects) {
|
// 保存当前状态为有效状态
|
||||||
newObjects.value = editedObj.objects;
|
lastValidJson.value = jsonEditorContent.value;
|
||||||
|
hasJsonChanges.value = false;
|
||||||
|
|
||||||
|
statusMessages.value.push('数据更新成功!');
|
||||||
|
jsonEditStatus.value = '数据更新成功!';
|
||||||
|
|
||||||
|
// 如果当前有选中的实体,重新初始化相关数据
|
||||||
|
if (selectedEntityIndex.value !== null) {
|
||||||
|
initObjectProperties();
|
||||||
|
initAttachedComponentJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
statusMessages.value.push('数据已从JSON更新!');
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('JSON更新错误:', e);
|
console.error('JSON更新错误:', e);
|
||||||
error.value = '更新数据失败:JSON解析错误';
|
error.value = '更新数据失败:' + e.message;
|
||||||
|
jsonEditStatus.value = '更新失败:' + e.message;
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
isDataSyncing.value = false;
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 第一个文件编辑器的方法
|
// 实体编辑器方法
|
||||||
const selectEntity = (index) => {
|
const selectEntity = (index) => {
|
||||||
selectedEntityIndex.value = index;
|
selectedEntityIndex.value = index;
|
||||||
activeTab.value = 'raw';
|
activeTab.value = 'raw';
|
||||||
@@ -1381,16 +1617,19 @@ export default {
|
|||||||
const updateEntityFromJson = () => {
|
const updateEntityFromJson = () => {
|
||||||
try {
|
try {
|
||||||
const updatedEntity = JSON.parse(entityJson.value);
|
const updatedEntity = JSON.parse(entityJson.value);
|
||||||
const originalIndex = newObjects.value.findIndex(
|
const originalIndex = blueprintData.value.objects.findIndex(
|
||||||
e => e.instanceName === selectedEntity.value.instanceName
|
e => e.instanceName === selectedEntity.value.instanceName
|
||||||
);
|
);
|
||||||
|
|
||||||
if (originalIndex !== -1) {
|
if (originalIndex !== -1) {
|
||||||
newObjects.value[originalIndex] = updatedEntity;
|
blueprintData.value.objects[originalIndex] = updatedEntity;
|
||||||
initObjectProperties();
|
initObjectProperties();
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '实体更新成功,JSON已同步';
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert('更新实体错误: ' + error.message);
|
alert('更新实体错误: ' + error.message);
|
||||||
|
jsonEditStatus.value = '实体更新失败:' + error.message;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1399,25 +1638,31 @@ export default {
|
|||||||
const updatedComponents = JSON.parse(componentsJson.value);
|
const updatedComponents = JSON.parse(componentsJson.value);
|
||||||
if (selectedEntity.value) {
|
if (selectedEntity.value) {
|
||||||
selectedEntity.value.components = updatedComponents;
|
selectedEntity.value.components = updatedComponents;
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '组件更新成功,JSON已同步';
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert('更新组件错误: ' + error.message);
|
alert('更新组件错误: ' + error.message);
|
||||||
|
jsonEditStatus.value = '组件更新失败:' + error.message;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateAttachedComponent = (index) => {
|
const updateAttachedComponent = (index) => {
|
||||||
try {
|
try {
|
||||||
const updatedComponent = JSON.parse(attachedComponentJson.value[index]);
|
const updatedComponent = JSON.parse(attachedComponentJson.value[index]);
|
||||||
const compIndex = newObjects.value.findIndex(e =>
|
const compIndex = blueprintData.value.objects.findIndex(e =>
|
||||||
e && e.instanceName === attachedComponents.value[index].instanceName
|
e && e.instanceName === attachedComponents.value[index].instanceName
|
||||||
);
|
);
|
||||||
|
|
||||||
if (compIndex !== -1) {
|
if (compIndex !== -1) {
|
||||||
newObjects.value[compIndex] = updatedComponent;
|
blueprintData.value.objects[compIndex] = updatedComponent;
|
||||||
attachedComponentJson.value[index] = JSON.stringify(updatedComponent, null, 2);
|
attachedComponentJson.value[index] = JSON.stringify(updatedComponent, null, 2);
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '附属组件更新成功,JSON已同步';
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert('更新附属组件错误: ' + error.message);
|
alert('更新附属组件错误: ' + error.message);
|
||||||
|
jsonEditStatus.value = '附属组件更新失败:' + error.message;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1425,6 +1670,8 @@ export default {
|
|||||||
if (selectedEntity.value && selectedEntity.value.properties && selectedEntity.value.properties[key]) {
|
if (selectedEntity.value && selectedEntity.value.properties && selectedEntity.value.properties[key]) {
|
||||||
delete selectedEntity.value.properties[key];
|
delete selectedEntity.value.properties[key];
|
||||||
delete objectProperties.value[key];
|
delete objectProperties.value[key];
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '属性已删除,JSON已同步';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1451,6 +1698,9 @@ export default {
|
|||||||
type: 'FloatProperty',
|
type: 'FloatProperty',
|
||||||
value: 0
|
value: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '属性已添加,JSON已同步';
|
||||||
};
|
};
|
||||||
|
|
||||||
const initObjectProperties = () => {
|
const initObjectProperties = () => {
|
||||||
@@ -1477,10 +1727,14 @@ export default {
|
|||||||
blueprintData.value.header.recipeReferences.push({
|
blueprintData.value.header.recipeReferences.push({
|
||||||
pathName: ""
|
pathName: ""
|
||||||
});
|
});
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '配方已添加,JSON已同步';
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeRecipe = (index) => {
|
const removeRecipe = (index) => {
|
||||||
blueprintData.value.header.recipeReferences.splice(index, 1);
|
blueprintData.value.header.recipeReferences.splice(index, 1);
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '配方已删除,JSON已同步';
|
||||||
};
|
};
|
||||||
|
|
||||||
const addItemCost = () => {
|
const addItemCost = () => {
|
||||||
@@ -1488,19 +1742,36 @@ export default {
|
|||||||
{ pathName: "" },
|
{ pathName: "" },
|
||||||
0
|
0
|
||||||
]);
|
]);
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '物品成本已添加,JSON已同步';
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeItemCost = (index) => {
|
const removeItemCost = (index) => {
|
||||||
blueprintData.value.header.itemCosts.splice(index, 1);
|
blueprintData.value.header.itemCosts.splice(index, 1);
|
||||||
|
syncJsonDisplay();
|
||||||
|
jsonEditStatus.value = '物品成本已删除,JSON已同步';
|
||||||
};
|
};
|
||||||
|
|
||||||
// 监听newObjects变化
|
// 监听对象变化
|
||||||
watch(newObjects, () => {
|
watch(() => blueprintData.value.objects, () => {
|
||||||
if (selectedEntity.value) {
|
if (selectedEntity.value) {
|
||||||
initAttachedComponentJson();
|
initAttachedComponentJson();
|
||||||
}
|
}
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
|
|
||||||
|
// 监听showObjects变化,确保JSON显示同步
|
||||||
|
watch(showObjects, (newVal) => {
|
||||||
|
// 当切换Objects段显示时,如果有未保存的更改,提示用户
|
||||||
|
if (hasJsonChanges.value) {
|
||||||
|
jsonEditStatus.value = `Objects段显示${newVal ? '开启' : '关闭'} - 注意:有未保存的更改`;
|
||||||
|
} else {
|
||||||
|
jsonEditStatus.value = `Objects段显示${newVal ? '开启' : '关闭'}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新JSON显示,但不标记为有更改
|
||||||
|
jsonEditorContent.value = '';
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// 文件操作相关
|
// 文件操作相关
|
||||||
fileInput,
|
fileInput,
|
||||||
@@ -1511,8 +1782,12 @@ export default {
|
|||||||
progress,
|
progress,
|
||||||
error,
|
error,
|
||||||
exportStatus,
|
exportStatus,
|
||||||
|
jsonEditStatus,
|
||||||
|
jsonValidationError,
|
||||||
isParsing,
|
isParsing,
|
||||||
isExporting,
|
isExporting,
|
||||||
|
isDataSyncing,
|
||||||
|
hasJsonChanges,
|
||||||
showObjects,
|
showObjects,
|
||||||
activeVisualTab,
|
activeVisualTab,
|
||||||
blueprintData,
|
blueprintData,
|
||||||
@@ -1523,7 +1798,7 @@ export default {
|
|||||||
editorOptions,
|
editorOptions,
|
||||||
smallEditorOptions,
|
smallEditorOptions,
|
||||||
|
|
||||||
// 第一个文件编辑器相关
|
// 实体编辑器相关
|
||||||
filteredEntities,
|
filteredEntities,
|
||||||
selectedEntityIndex,
|
selectedEntityIndex,
|
||||||
activeTab,
|
activeTab,
|
||||||
@@ -1538,7 +1813,6 @@ export default {
|
|||||||
|
|
||||||
// 辅助函数
|
// 辅助函数
|
||||||
isComplexValue,
|
isComplexValue,
|
||||||
getPropertyDisplayType,
|
|
||||||
getPropertyDisplayValue,
|
getPropertyDisplayValue,
|
||||||
setPropertyValue,
|
setPropertyValue,
|
||||||
|
|
||||||
@@ -1559,13 +1833,22 @@ export default {
|
|||||||
getDisplayName,
|
getDisplayName,
|
||||||
getTypeName,
|
getTypeName,
|
||||||
|
|
||||||
// 第一个文件编辑器方法
|
// 实体编辑器方法
|
||||||
selectEntity,
|
selectEntity,
|
||||||
updateEntityFromJson,
|
updateEntityFromJson,
|
||||||
updateComponents,
|
updateComponents,
|
||||||
updateAttachedComponent,
|
updateAttachedComponent,
|
||||||
deleteProperty,
|
deleteProperty,
|
||||||
addProperty
|
addProperty,
|
||||||
|
|
||||||
|
// 数据同步方法
|
||||||
|
onJsonEditorChange,
|
||||||
|
onBasicDataChange,
|
||||||
|
onEntityDataChange,
|
||||||
|
onEntityJsonChange,
|
||||||
|
onObjectPropertyChange,
|
||||||
|
onComponentsJsonChange,
|
||||||
|
onAttachedComponentChange
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,7 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@plugin "daisyui";
|
@plugin "daisyui";
|
||||||
|
|
||||||
|
/* 修复JSON编辑状态的颜色问题 */
|
||||||
|
.text-error {
|
||||||
|
color: #18181B !important;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user