Browse Source

feat(editor): 添加批量复制功能

- 新增 BulkCopy 组件用于批量复制操作
- 在 Model2DEditor 中集成批量复制功能
- 实现了行数、列数、行间距、列间距等配置选项
- 添加了批量复制的逻辑,包括复制对象的坐标计算
master
lizw-2015 6 months ago
parent
commit
a2e0c3fa40
  1. 127
      src/editor/BulkCopy.vue
  2. 59
      src/editor/Model2DEditor.vue
  3. 8
      src/editor/widgets/property/PropertyPanel.vue

127
src/editor/BulkCopy.vue

@ -0,0 +1,127 @@
<script setup lang="ts">
import { reactive } from "vue";
import DataForm from "@/components/data-form/DataForm.vue";
import type { FormField } from "@/components/data-form/DataFormTypes.ts";
defineOptions({
name: 'BulkCopy',
});
interface BulkCopyConfig {
/** 行数 */
numberOfRows?: number;
/** 列数 */
numberOfColumns?: number;
/** 行间距 */
rowSpace?: number;
/** 列间距 */
columnSpacing?: number;
/** 双排 */
doubleRow?: boolean;
}
// Props
interface BulkCopyProps {
config: BulkCopyConfig;
}
// props
const props = withDefaults(defineProps<BulkCopyProps>(), {});
// State
interface BulkCopyState {
}
// state
const state = reactive<BulkCopyState>({});
// Data
interface BulkCopyData {
formFields?: Array<FormField>;
}
//
const data: BulkCopyData = {
formFields: [
{
dataPath: 'numberOfRows', label: '行数', input: 'InputNumber',
inputProps: {
placeholder: '请输入',
controlsPosition: 'right',
min: 1,
precision: 0,
},
},
{
dataPath: 'numberOfColumns', label: '列数', input: 'InputNumber',
inputProps: {
placeholder: '请输入',
controlsPosition: 'right',
min: 1,
precision: 0,
},
},
{
dataPath: 'rowSpace', label: '行间距', input: 'InputNumber',
inputProps: {
placeholder: '请输入',
controlsPosition: 'right',
min: 0,
// precision:
},
},
{
dataPath: 'columnSpacing', label: '列间距', input: 'InputNumber',
inputProps: {
placeholder: '请输入',
controlsPosition: 'right',
min: 0,
// precision:
},
},
{
dataPath: 'doubleRow', label: '单双排', input: 'Switch',
inputProps: {
// trueValue: true,
// falseValue: false,
inlinePrompt: true,
inactiveText: "单排",
activeText: "双排",
},
},
],
};
interface BulkCopyExpose {
state: BulkCopyState;
data: BulkCopyData;
}
const expose: BulkCopyExpose = {
state,
data,
};
//
defineExpose(expose);
export type {
BulkCopyConfig,
BulkCopyProps,
BulkCopyState,
}
</script>
<template>
<DataForm
:data="props.config"
:formFields="data.formFields"
:columnCount="2"
layout="onlyLabelFixed"
labelWidth="80px"
inputWidth=""
/>
</template>
<style scoped>
</style>

59
src/editor/Model2DEditor.vue

@ -17,6 +17,9 @@
:type="state?.view3DMode===Constract.Mode3D?'primary':''"
@click="state.view3DMode = Constract.Mode3D">3D
</el-button>
<el-button :icon="renderIcon('element Files')" link @click="showBulkCopy" :disabled="!selectedObject">
批量复制
</el-button>
</el-button-group>
</div>
<div class="section-content">
@ -92,13 +95,14 @@
</template>
<script>
import * as THREE from 'three'
import $ from 'jquery'
import { getQueryParams, renderIcon, setQueryParam } from '@/utils/webutils'
import { defineComponent, markRaw } from 'vue'
import { renderIcon, setQueryParam } from '@/utils/webutils'
import { createVNode, defineComponent, markRaw } from 'vue'
import Viewport from '@/core/engine/Viewport'
import Constract from '@/core/Constract'
import EventBus from '@/runtime/EventBus'
import SceneHelp from '@/core/engine/SceneHelp'
import BulkCopy from './BulkCopy.vue'
import lodash from "lodash";
export default defineComponent({
name: 'Model2DEditor',
@ -242,7 +246,51 @@ export default defineComponent({
})
},
showBulkCopy() {
const viewport = this.viewport;
const selectedItem = viewport?.state?.selectedItem;
if(!viewport || !selectedItem) return;
const config = {
numberOfRows: 1,
numberOfColumns: 1,
rowSpace: 0,
columnSpacing: 0,
doubleRow: false,
};
system.showDialog(createVNode(BulkCopy, {
config,
}), {
title: '批量复制',
width: 520,
height: 240,
showClose: true,
showMax: true,
showCancelButton: false,
showOkButton: true,
}).then(() => {
if(!config.numberOfRows || !config.numberOfColumns) return;
viewport.stateManager.update(({ getEntity, addEntity }) => {
const xAxle = selectedItem.tf[0][0];
const zAxle = selectedItem.tf[0][2];
const xSize = selectedItem.tf[2][0];
const zSize = selectedItem.tf[2][2];
console.log("item", JSON.stringify(selectedItem.tf));
for (let rCount = 0; rCount < config.numberOfRows; rCount++) {
for (let cCount = 0; cCount < config.numberOfColumns; cCount++) {
if(rCount===0 && cCount===0) continue;
const item = lodash.cloneDeep(selectedItem);
item.id = system.createUUID();
item.tf[0][0] = xAxle + cCount * (xSize + config.columnSpacing);
item.tf[0][2] = zAxle + rCount * (zSize + config.rowSpace);
addEntity(item);
console.log("item", JSON.stringify(item.tf));
}
}
});
console.log("config", config, selectedItem);
}).finally();
},
},
computed: {
state() {
@ -268,7 +316,10 @@ export default defineComponent({
label: item.label
}))
}))
}
},
selectedObject() {
return this.state?.selectedObject;
},
}
})
</script>

8
src/editor/widgets/property/PropertyPanel.vue

@ -76,11 +76,11 @@ function onDataChange(newData: any) {
const viewport = props.viewport
if (!viewport) return
viewport.stateManager.update(({ getEntity, putEntity }) => {
const data = getEntity(props.data.id)
lodash.assign(data, newData)
const data = getEntity(props.data.id);
lodash.assign(data, newData);
// console.log('onDataChange@1', JSON.stringify(data.dt))
putEntity(data)
})
putEntity(data);
});
}
interface PropertyPanelExpose {

Loading…
Cancel
Save