|
|
@ -1,4 +1,5 @@ |
|
|
<script setup lang="ts"> |
|
|
<script setup lang="ts"> |
|
|
|
|
|
import lodash from "lodash"; |
|
|
import { computed, reactive } from "vue"; |
|
|
import { computed, reactive } from "vue"; |
|
|
import { ElButton, ElDivider, ElFormItem, ElIcon, ElInputNumber, useFormItem } from "element-plus"; |
|
|
import { ElButton, ElDivider, ElFormItem, ElIcon, ElInputNumber, useFormItem } from "element-plus"; |
|
|
import { CopyDocument, Delete } from "@element-plus/icons-vue"; |
|
|
import { CopyDocument, Delete } from "@element-plus/icons-vue"; |
|
|
@ -36,10 +37,15 @@ const props = withDefaults(defineProps<BayEditorProps>(), {}); |
|
|
|
|
|
|
|
|
// 定义 State 类型 |
|
|
// 定义 State 类型 |
|
|
interface BayEditorState { |
|
|
interface BayEditorState { |
|
|
|
|
|
/** 列数 */ |
|
|
numberOfBays: number; |
|
|
numberOfBays: number; |
|
|
|
|
|
/** 层数 */ |
|
|
numberOfLevels: number; |
|
|
numberOfLevels: number; |
|
|
|
|
|
/** 列宽 */ |
|
|
widthOfBays: number; |
|
|
widthOfBays: number; |
|
|
|
|
|
/** 层高 */ |
|
|
heightOfLevels: number; |
|
|
heightOfLevels: number; |
|
|
|
|
|
/** 选中列 */ |
|
|
selectIdx?: number; |
|
|
selectIdx?: number; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -61,26 +67,78 @@ const data: BayEditorData = { |
|
|
labelWidth: 110, |
|
|
labelWidth: 110, |
|
|
}; |
|
|
}; |
|
|
const { formItem } = useFormItem(); |
|
|
const { formItem } = useFormItem(); |
|
|
const list = computed(() => props.modelValue ?? []); |
|
|
const list = computed(getModelValue); |
|
|
const selectDay = computed(() => { |
|
|
const selectDay = computed(() => { |
|
|
if (Typeof.noValue(state.selectIdx)) return; |
|
|
if (Typeof.noValue(state.selectIdx)) return; |
|
|
return props.modelValue?.[state.selectIdx]; |
|
|
return props.modelValue?.[state.selectIdx]; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
function setSelectIdx(idx: number) { |
|
|
function setSelectIdx(idx?: number) { |
|
|
state.selectIdx = idx; |
|
|
state.selectIdx = idx; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function applyBasicSettings() { |
|
|
function applyBasicSettings() { |
|
|
|
|
|
const { numberOfBays, numberOfLevels, widthOfBays, heightOfLevels } = state; |
|
|
|
|
|
const newValue = getModelValue(); |
|
|
|
|
|
newValue.length = 0; |
|
|
|
|
|
for (let idx = 0; idx < numberOfBays; idx++) { |
|
|
|
|
|
const bay: DtBay = { |
|
|
|
|
|
bayWidth: widthOfBays, |
|
|
|
|
|
offset: 0, |
|
|
|
|
|
levelHeight: [], |
|
|
|
|
|
}; |
|
|
|
|
|
for (let i = 0; i < numberOfLevels; i++) { |
|
|
|
|
|
bay.levelHeight.push(heightOfLevels); |
|
|
|
|
|
} |
|
|
|
|
|
newValue.push(bay); |
|
|
|
|
|
} |
|
|
|
|
|
emit("update:modelValue", newValue); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function deleteBay() { |
|
|
function deleteBay() { |
|
|
|
|
|
const selectIdx = state.selectIdx; |
|
|
|
|
|
if (Typeof.noValue(selectIdx)) return; |
|
|
|
|
|
const newValue = getModelValue(); |
|
|
|
|
|
if (selectIdx >= newValue.length) return; |
|
|
|
|
|
newValue.splice(selectIdx, 1); |
|
|
|
|
|
emit("update:modelValue", newValue); |
|
|
|
|
|
if (selectIdx >= newValue.length) { |
|
|
|
|
|
setSelectIdx(undefined); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function copyBay() { |
|
|
function copyBay() { |
|
|
|
|
|
const selectIdx = state.selectIdx; |
|
|
|
|
|
if (Typeof.noValue(selectIdx)) return; |
|
|
|
|
|
const newValue = getModelValue(); |
|
|
|
|
|
const bay = newValue[selectIdx]; |
|
|
|
|
|
if (!bay) return; |
|
|
|
|
|
newValue.splice(selectIdx + 1, 0, lodash.cloneDeep(bay)); |
|
|
|
|
|
emit("update:modelValue", newValue); |
|
|
|
|
|
setSelectIdx(selectIdx + 1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function updateBayWidth(bay: DtBay, bayWidth?: number) { |
|
|
|
|
|
bay.bayWidth = bayWidth; |
|
|
|
|
|
const newValue = getModelValue(); |
|
|
|
|
|
emit("update:modelValue", newValue); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function updateBayOffset(bay: DtBay, offset?: number) { |
|
|
|
|
|
bay.offset = offset; |
|
|
|
|
|
const newValue = getModelValue(); |
|
|
|
|
|
emit("update:modelValue", newValue); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function updateBayLevelHeight(bay: DtBay, idx: number, levelHeight?: number) { |
|
|
|
|
|
if (!bay.levelHeight) bay.levelHeight = []; |
|
|
|
|
|
bay.levelHeight[idx] = levelHeight; |
|
|
|
|
|
const newValue = getModelValue(); |
|
|
|
|
|
emit("update:modelValue", newValue); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function getModelValue(): DtBays { |
|
|
|
|
|
return props.modelValue ?? []; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
interface BayEditorExpose { |
|
|
interface BayEditorExpose { |
|
|
@ -130,10 +188,10 @@ export type { |
|
|
<div class="flex-row-container bay-editor-advanced"> |
|
|
<div class="flex-row-container bay-editor-advanced"> |
|
|
<div class="flex-item-fixed flex-column-container bay-editor-bay-list"> |
|
|
<div class="flex-item-fixed flex-column-container bay-editor-bay-list"> |
|
|
<div class="flex-item-fixed tools-button-container"> |
|
|
<div class="flex-item-fixed tools-button-container"> |
|
|
<ElIcon :class="['tools-button-icon', { 'tools-button-disabled': false }]" @click="copyBay"> |
|
|
<ElIcon :class="['tools-button-icon', { 'tools-button-disabled': !selectDay }]" @click="copyBay"> |
|
|
<CopyDocument/> |
|
|
<CopyDocument/> |
|
|
</ElIcon> |
|
|
</ElIcon> |
|
|
<ElIcon :class="['tools-button-icon', { 'tools-button-disabled': false }]" @click="deleteBay"> |
|
|
<ElIcon :class="['tools-button-icon', { 'tools-button-disabled': !selectDay }]" @click="deleteBay"> |
|
|
<Delete/> |
|
|
<Delete/> |
|
|
</ElIcon> |
|
|
</ElIcon> |
|
|
</div> |
|
|
</div> |
|
|
@ -155,21 +213,34 @@ export type { |
|
|
<div v-if="selectDay" class="flex-item-fill flex-column-container bay-editor-bay-info"> |
|
|
<div v-if="selectDay" class="flex-item-fill flex-column-container bay-editor-bay-info"> |
|
|
<div class="flex-item-fixed"> |
|
|
<div class="flex-item-fixed"> |
|
|
<ElFormItem label="Bay Width" :labelWidth="80"> |
|
|
<ElFormItem label="Bay Width" :labelWidth="80"> |
|
|
<ElInputNumber :controls="false" :modelValue="selectDay.bayWidth"/> |
|
|
<ElInputNumber |
|
|
|
|
|
:controls="false" |
|
|
|
|
|
:modelValue="selectDay.bayWidth" |
|
|
|
|
|
@change="(width: number) => updateBayWidth(selectDay, width)" |
|
|
|
|
|
/> |
|
|
</ElFormItem> |
|
|
</ElFormItem> |
|
|
<div style="height: 8px;"/> |
|
|
<div style="height: 8px;"/> |
|
|
<ElFormItem label="Bay Offset" :labelWidth="80"> |
|
|
<ElFormItem label="Bay Offset" :labelWidth="80"> |
|
|
<ElInputNumber :controls="false" :modelValue="selectDay.offset"/> |
|
|
<ElInputNumber |
|
|
|
|
|
:controls="false" |
|
|
|
|
|
:modelValue="selectDay.offset" |
|
|
|
|
|
@change="(offset: number) => updateBayOffset(selectDay, offset)" |
|
|
|
|
|
/> |
|
|
</ElFormItem> |
|
|
</ElFormItem> |
|
|
</div> |
|
|
</div> |
|
|
<div>Level Heights</div> |
|
|
<div>Level Heights</div> |
|
|
<div class="flex-item-fill bay-editor-bay-info-level-height"> |
|
|
<div class="flex-item-fill bay-editor-bay-info-level-height"> |
|
|
<ElFormItem |
|
|
<ElFormItem |
|
|
v-for="(levelHeight, idx) in selectDay.levelHeight" |
|
|
v-for="(levelHeight, idx) in selectDay.levelHeight" |
|
|
|
|
|
labelPosition="left" |
|
|
:label="`Level ${idx+1}`" |
|
|
:label="`Level ${idx+1}`" |
|
|
:labelWidth="64" |
|
|
:labelWidth="64" |
|
|
> |
|
|
> |
|
|
<ElInputNumber :controls="false" :modelValue="levelHeight"/> |
|
|
<ElInputNumber |
|
|
|
|
|
:controls="false" |
|
|
|
|
|
:modelValue="levelHeight" |
|
|
|
|
|
@change="(height: number) => updateBayLevelHeight(selectDay, idx, height)" |
|
|
|
|
|
/> |
|
|
</ElFormItem> |
|
|
</ElFormItem> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
@ -183,6 +254,7 @@ export type { |
|
|
<style scoped> |
|
|
<style scoped> |
|
|
.bay-editor { |
|
|
.bay-editor { |
|
|
width: 100%; |
|
|
width: 100%; |
|
|
|
|
|
user-select: none; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.bay-editor-title { |
|
|
.bay-editor-title { |
|
|
@ -204,6 +276,7 @@ export type { |
|
|
|
|
|
|
|
|
.bay-editor-bay-list-name { |
|
|
.bay-editor-bay-list-name { |
|
|
border: 1px solid #dddddd; |
|
|
border: 1px solid #dddddd; |
|
|
|
|
|
overflow-y: auto; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.tools-button-container { |
|
|
.tools-button-container { |
|
|
@ -215,6 +288,9 @@ export type { |
|
|
gap: 4px; |
|
|
gap: 4px; |
|
|
cursor: pointer; |
|
|
cursor: pointer; |
|
|
width: 100%; |
|
|
width: 100%; |
|
|
|
|
|
background-color: #f5f5f5; |
|
|
|
|
|
border: 1px solid #dddddd; |
|
|
|
|
|
border-bottom: none; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.tools-button-container > .tools-button-icon { |
|
|
.tools-button-container > .tools-button-icon { |
|
|
@ -247,7 +323,7 @@ export type { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.list-item { |
|
|
.list-item { |
|
|
padding: 4px 0 4px 2px; |
|
|
padding: 0 2px; |
|
|
cursor: pointer; |
|
|
cursor: pointer; |
|
|
border-bottom: 1px solid #f0f0f0; |
|
|
border-bottom: 1px solid #f0f0f0; |
|
|
user-select: none; |
|
|
user-select: none; |
|
|
@ -277,6 +353,7 @@ export type { |
|
|
|
|
|
|
|
|
.bay-editor-bay-info-level-height { |
|
|
.bay-editor-bay-info-level-height { |
|
|
border: 1px solid #dddddd; |
|
|
border: 1px solid #dddddd; |
|
|
|
|
|
overflow-y: auto; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.bay-editor-bay-info-level-height :deep(.el-input__wrapper) { |
|
|
.bay-editor-bay-info-level-height :deep(.el-input__wrapper) { |
|
|
@ -291,6 +368,8 @@ export type { |
|
|
|
|
|
|
|
|
.bay-editor-bay-info-level-height :deep(.el-form-item > .el-form-item__label) { |
|
|
.bay-editor-bay-info-level-height :deep(.el-form-item > .el-form-item__label) { |
|
|
border-right: 1px solid #dddddd; |
|
|
border-right: 1px solid #dddddd; |
|
|
|
|
|
background-color: #f0f0f0; |
|
|
|
|
|
padding: 0 2px; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.bay-editor-bay-info-level-height :deep(.el-input-number) { |
|
|
.bay-editor-bay-info-level-height :deep(.el-input-number) { |
|
|
|