Browse Source

Merge remote-tracking branch 'origin/master'

master
修宁 6 months ago
parent
commit
94ad354d54
  1. 43
      src/base.css
  2. 282
      src/editor/propEditors/InOutCenterEditor.vue
  3. 11
      src/editor/widgets/property/PropertyPanelConstant.ts
  4. 49
      src/modules/charger/ChargerMeta.ts
  5. 20
      src/modules/charger/ChargerPropertySetter.ts
  6. 12
      src/modules/charger/index.ts
  7. 49
      src/modules/clx/ClxMeta.ts
  8. 20
      src/modules/clx/ClxPropertySetter.ts
  9. 12
      src/modules/clx/index.ts
  10. 49
      src/modules/ptr/PtrMeta.ts

43
src/base.css

@ -382,3 +382,46 @@ body {
opacity: 1; opacity: 1;
} }
} }
/** flex多行容器 */
.flex-column-container {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
/** flex多列容器 */
.flex-row-container {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
/** flex自动填充 */
.flex-item-fill {
flex-grow: 1;
overflow: hidden;
}
/** flex固定大小 */
.flex-item-fixed {
flex-shrink: 0;
}
/** flex主轴上对齐方式 */
.flex-justify-content-center {
justify-content: center;
}
/** flex交叉轴上对齐方式 */
.flex-align-items-center {
align-items: center;
}
/** 内容居中 */
.content-center {
display: flex;
align-items: center;
justify-content: center;
}

282
src/editor/propEditors/InOutCenterEditor.vue

@ -0,0 +1,282 @@
<script setup lang="ts">
import { computed, reactive } from "vue";
import { ElIcon, ElRadioButton, ElRadioGroup, useFormItem } from "element-plus";
import { ArrowDown, ArrowUp, Delete, EditPen } from "@element-plus/icons-vue";
import { Typeof } from "@ease-forge/shared";
defineOptions({
name: 'InOutCenterEditor',
});
//
const emit = defineEmits<{
/** 更新内联表格数据 */
"update:modelValue": [value: ItemJson["dt"]];
}>();
// Props
interface InOutCenterEditorProps {
modelValue: ItemJson["dt"];
}
// props
const props = withDefaults(defineProps<InOutCenterEditorProps>(), {});
// State
interface InOutCenterEditorState {
portsType: "center" | "in" | "out";
selectCenterIdx?: number;
selectInIdx?: number;
selectOutIdx?: number;
}
// state
const state = reactive<InOutCenterEditorState>({
portsType: "in",
});
// Data
interface InOutCenterEditorData {
}
//
const data: InOutCenterEditorData = {};
const { formItem } = useFormItem();
const list = computed<Array<string>>(() => {
const portsType = state.portsType;
if (portsType === "center") return props.modelValue?.center ?? [];
if (portsType === "in") return props.modelValue?.in ?? [];
if (portsType === "out") return props.modelValue?.out ?? [];
return [];
});
const selectIdx = computed<number | undefined>({
set: newValue => {
const portsType = state.portsType;
if (portsType === "center") state.selectCenterIdx = newValue;
if (portsType === "in") state.selectInIdx = newValue;
if (portsType === "out") state.selectOutIdx = newValue;
},
get: oldValue => {
const portsType = state.portsType;
if (portsType === "center") return state.selectCenterIdx;
if (portsType === "in") return state.selectInIdx;
if (portsType === "out") return state.selectOutIdx;
},
});
const canUpItem = computed(() => selectIdx.value > 0);
const canDownItem = computed(() => selectIdx.value < (list.value.length - 1));
const canDeleteItem = computed(() => selectIdx.value < list.value.length);
function setSelectIdx(idx: number) {
selectIdx.value = idx;
}
function addItem() {
const [list, modelValue] = getListAndModelValue();
list.push(`D_${Date.now()}`);
emit("update:modelValue", modelValue);
}
function upItem() {
if (!canUpItem.value) return;
const idx = selectIdx.value;
if (Typeof.noValue(idx)) return;
if (idx <= 0) return;
const [list, modelValue] = getListAndModelValue();
const idxUp = idx - 1;
const tmp = list[idxUp];
list[idxUp] = list[idx];
list[idx] = tmp;
emit("update:modelValue", modelValue);
selectIdx.value--;
}
function downItem() {
if (!canDownItem.value) return;
const idx = selectIdx.value;
if (Typeof.noValue(idx)) return;
const [list, modelValue] = getListAndModelValue();
if (idx >= (list.length - 1)) return;
const idxDown = idx + 1;
const tmp = list[idxDown];
list[idxDown] = list[idx];
list[idx] = tmp;
emit("update:modelValue", modelValue);
selectIdx.value++;
}
function deleteItem() {
if (!canDeleteItem.value) return;
if (Typeof.noValue(selectIdx.value)) return;
const [list, modelValue] = getListAndModelValue();
list.splice(selectIdx.value, 1);
emit("update:modelValue", modelValue);
if (selectIdx.value >= list.length) {
setSelectIdx(Math.max(0, selectIdx.value - 1));
}
}
function getListAndModelValue() {
const modelValue = props.modelValue ?? {};
const portsType = state.portsType;
let list: Array<string> = [];
if (portsType === "center") {
if (!modelValue.center) modelValue.center = [];
list = modelValue.center;
} else if (portsType === "in") {
if (!modelValue.in) modelValue.in = [];
list = modelValue.in;
} else if (portsType === "out") {
if (!modelValue.out) modelValue.out = [];
list = modelValue.out;
}
return [list, modelValue];
}
interface InOutCenterEditorExpose {
state: InOutCenterEditorState;
data: InOutCenterEditorData;
}
const expose: InOutCenterEditorExpose = {
state,
data,
};
//
defineExpose(expose);
export type {
InOutCenterEditorProps,
InOutCenterEditorState,
}
</script>
<template>
<div class="flex-column-container in-out-center-editor">
<ElRadioGroup class="flex-item-fixed flex-justify-content-center" v-model="state.portsType" size="small">
<ElRadioButton label="Input Ports" value="in"/>
<ElRadioButton label="Central Ports" value="center"/>
<ElRadioButton label="Output Ports" value="out"/>
</ElRadioGroup>
<div class="flex-item-fill flex-row-container in-out-center-editor-data">
<div class="flex-item-fixed in-out-center-editor-tools">
<div class="tools-button-container">
<ElIcon class="tools-button-icon" @click="addItem">
<EditPen/>
</ElIcon>
<ElIcon :class="['tools-button-icon', { 'tools-button-disabled': !canUpItem }]" @click="upItem">
<ArrowUp/>
</ElIcon>
<ElIcon :class="['tools-button-icon', { 'tools-button-disabled': !canDownItem }]" @click="downItem">
<ArrowDown/>
</ElIcon>
<ElIcon :class="['tools-button-icon', { 'tools-button-disabled': !canDeleteItem }]" @click="deleteItem">
<Delete/>
</ElIcon>
</div>
</div>
<div class="flex-item-fill in-out-center-editor-data-list">
<div
v-for="(item, idx) in list"
:class="[
'list-item',
{
'list-item-select': selectIdx === idx,
},
]"
@click="setSelectIdx(idx)"
>
{{ item }}
</div>
</div>
</div>
</div>
</template>
<style scoped>
.in-out-center-editor {
width: 100%;
height: 160px;
}
.in-out-center-editor-data {
margin-top: 6px;
border: 1px solid #dddddd;
}
.in-out-center-editor-tools {
background-color: #f5f5f5;
border-right: 1px solid #dddddd;
width: 28px;
padding: 4px 0;
}
.tools-button-container {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
justify-content: center;
gap: 4px;
cursor: pointer;
height: 100%;
}
.tools-button-container > .tools-button-icon {
color: #8c8c8c;
padding: 4px;
font-size: 22px;
border-radius: 2px;
}
.tools-button-container > .tools-button-icon:hover {
color: #595959;
background-color: #d9d9d9;
}
.tools-button-container > .tools-button-icon:active {
color: #434343;
background-color: #bfbfbf;
}
.tools-button-container > .tools-button-disabled {
cursor: not-allowed;
}
.tools-button-container > .tools-button-disabled.tools-button-icon,
.tools-button-container > .tools-button-disabled.tools-button-icon:hover,
.tools-button-container > .tools-button-disabled.tools-button-icon:active {
color: #d9d9d9;
background-color: unset;
pointer-events: none;
}
.in-out-center-editor-data-list {
overflow-y: auto;
}
.list-item {
padding: 4px 0 4px 2px;
cursor: pointer;
border-bottom: 1px solid #f0f0f0;
user-select: none;
color: #262626;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.list-item:hover {
background-color: #f0f0f0;
}
.list-item:active {
background-color: #dddddd;
}
.list-item.list-item-select,
.list-item.list-item-select:hover,
.list-item.list-item-select:active {
background-color: #d9d9d9;
}
</style>

11
src/editor/widgets/property/PropertyPanelConstant.ts

@ -3,6 +3,7 @@ import type { DataFormProps } from "@/components/data-form/DataFormTypes.ts";
import type { PropertyFieldSetter } from "@/core/base/PropertyTypes.ts"; import type { PropertyFieldSetter } from "@/core/base/PropertyTypes.ts";
import { dataFormInputComponents } from "@/components/data-form/DataFormConstant.ts"; import { dataFormInputComponents } from "@/components/data-form/DataFormConstant.ts";
import TransformEditor from "@/editor/propEditors/TransformEditor.vue"; import TransformEditor from "@/editor/propEditors/TransformEditor.vue";
import InOutCenterEditor from "@/editor/propEditors/InOutCenterEditor.vue";
const defDataFormProps: DataFormProps = { const defDataFormProps: DataFormProps = {
columnCount: 1, columnCount: 1,
@ -12,6 +13,7 @@ const defDataFormProps: DataFormProps = {
}; };
dataFormInputComponents.TransformEditor = markRaw<any>(TransformEditor); dataFormInputComponents.TransformEditor = markRaw<any>(TransformEditor);
dataFormInputComponents.InOutCenterEditor = markRaw<any>(InOutCenterEditor);
const basicFieldsSetter: Array<PropertyFieldSetter> = [ const basicFieldsSetter: Array<PropertyFieldSetter> = [
{ {
@ -48,11 +50,10 @@ const basicFieldsSetter: Array<PropertyFieldSetter> = [
dataPath: 'tf', input: 'TransformEditor', dataPath: 'tf', input: 'TransformEditor',
inputProps: {}, inputProps: {},
}, },
// { {
// dataPath: 'dt', input: 'InOutCenterEditor', dataPath: 'dt', input: 'InOutCenterEditor',
// inputProps: { inputProps: {},
// }, },
// },
]; ];

49
src/modules/charger/ChargerMeta.ts

@ -1,49 +0,0 @@
import type { IMeta } from '@/core/base/IMeta.ts'
export default [
{ field: 'uuid', editor: 'UUID', label: 'uuid', readonly: true, category: 'basic' },
{ field: 'name', editor: 'TextInput', label: '名称', category: 'basic' },
{ field: 'dt.label', editor: 'TextInput', label: '标签', category: 'basic' },
{ editor: 'TransformEditor', category: 'basic' },
{ field: 'dt.color', editor: 'Color', label: '颜色', category: 'basic' },
{ editor: '-', category: 'basic' },
{ field: 'dt.chargerWidth', editor: 'NumberInput', label: '充电桩宽度', category: 'basic' },
{ field: 'dt.chargerDepth', editor: 'NumberInput', label: '充电桩深度', category: 'basic' },
/**
* dt.bays 53
* {
* dt: {
* rackDepth: 1.1, // 货架深度
* levelCount: 3, // 总层数
* bayCount: 5, // 总列数
* hideFloor: false, // 隐藏底板
* extendColumns: true, // 扩展挡板
* columnSpacing: 1, // 支脚跨越
* bays: [ // 每列的配置
* {
* bayWidth: 1.6, // 列的宽度
* levelHeight: [ 1.4, 1.4, 1.4 ] // 每层的高度
* },
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* ]
* }
* }
*
*
*
*
*
*
*
*/
{ field: 'tf', editor: 'InOutCenterEditor', category: 'basic' },
{ field: 'dt.selectable', editor: 'Switch', label: '可选中', category: 'basic' },
{ field: 'dt.protected', editor: 'Switch', label: '受保护', category: 'basic' },
{ field: 'visible', editor: 'Switch', label: '可见', category: 'basic' }
] as IMeta

20
src/modules/charger/ChargerPropertySetter.ts

@ -0,0 +1,20 @@
import type { PropertySetter } from "@/core/base/PropertyTypes.ts";
import { basicFieldsSetter } from "@/editor/widgets/property/PropertyPanelConstant.ts";
const propertySetter: PropertySetter = {
flatten: {
fields: [
...basicFieldsSetter,
{
dataPath: 'dt.chargerWidth', label: '充电桩宽度', input: 'InputNumber',
inputProps: {},
},
{
dataPath: 'dt.chargerDepth', label: '充电桩深度', input: 'InputNumber',
inputProps: {},
},
],
},
};
export default propertySetter;

12
src/modules/charger/index.ts

@ -1,15 +1,15 @@
import { defineModule } from '@/core/manager/ModuleManager.ts' import { defineModule } from '@/core/manager/ModuleManager.ts'
import ChargerRenderer from './ChargerRenderer.ts' import ChargerRenderer from './ChargerRenderer.ts'
import ChargerEntity from './ChargerEntity.ts' import ChargerEntity from './ChargerEntity.ts'
import ChargerMeta from './ChargerMeta.ts'
import ChargerInteraction from './ChargerInteraction.ts' import ChargerInteraction from './ChargerInteraction.ts'
import propertySetter from "@/modules/charger/ChargerPropertySetter.ts";
export const ITEM_TYPE_NAME = 'charger' export const ITEM_TYPE_NAME = 'charger'
export default defineModule({ export default defineModule({
name: ITEM_TYPE_NAME, name: ITEM_TYPE_NAME,
renderer: new ChargerRenderer(ITEM_TYPE_NAME), renderer: new ChargerRenderer(ITEM_TYPE_NAME),
interaction: new ChargerInteraction(ITEM_TYPE_NAME), interaction: new ChargerInteraction(ITEM_TYPE_NAME),
meta: ChargerMeta, setter: propertySetter,
entity: ChargerEntity entity: ChargerEntity,
}) })

49
src/modules/clx/ClxMeta.ts

@ -1,49 +0,0 @@
import type { IMeta } from '@/core/base/IMeta.ts'
export default [
{ field: 'uuid', editor: 'UUID', label: 'uuid', readonly: true, category: 'basic' },
{ field: 'name', editor: 'TextInput', label: '名称', category: 'basic' },
{ field: 'dt.label', editor: 'TextInput', label: '标签', category: 'basic' },
{ editor: 'TransformEditor', category: 'basic' },
{ field: 'dt.color', editor: 'Color', label: '颜色', category: 'basic' },
{ editor: '-', category: 'basic' },
{ field: 'dt.clxWidth', editor: 'NumberInput', label: 'CLX宽度', category: 'basic' },
{ field: 'dt.clxDepth', editor: 'NumberInput', label: 'CLX深度', category: 'basic' },
/**
* dt.bays 53
* {
* dt: {
* rackDepth: 1.1, // 货架深度
* levelCount: 3, // 总层数
* bayCount: 5, // 总列数
* hideFloor: false, // 隐藏底板
* extendColumns: true, // 扩展挡板
* columnSpacing: 1, // 支脚跨越
* bays: [ // 每列的配置
* {
* bayWidth: 1.6, // 列的宽度
* levelHeight: [ 1.4, 1.4, 1.4 ] // 每层的高度
* },
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* ]
* }
* }
*
*
*
*
*
*
*
*/
{ field: 'tf', editor: 'InOutCenterEditor', category: 'basic' },
{ field: 'dt.selectable', editor: 'Switch', label: '可选中', category: 'basic' },
{ field: 'dt.protected', editor: 'Switch', label: '受保护', category: 'basic' },
{ field: 'visible', editor: 'Switch', label: '可见', category: 'basic' }
] as IMeta

20
src/modules/clx/ClxPropertySetter.ts

@ -0,0 +1,20 @@
import type { PropertySetter } from "@/core/base/PropertyTypes.ts";
import { basicFieldsSetter } from "@/editor/widgets/property/PropertyPanelConstant.ts";
const propertySetter: PropertySetter = {
flatten: {
fields: [
...basicFieldsSetter,
{
dataPath: 'dt.clxWidth', label: 'CLX宽度', input: 'InputNumber',
inputProps: {},
},
{
dataPath: 'dt.clxDepth', label: 'CLX深度', input: 'InputNumber',
inputProps: {},
},
],
},
};
export default propertySetter;

12
src/modules/clx/index.ts

@ -1,15 +1,15 @@
import { defineModule } from '@/core/manager/ModuleManager.ts' import { defineModule } from '@/core/manager/ModuleManager.ts'
import ClxRenderer from './ClxRenderer.ts' import ClxRenderer from './ClxRenderer.ts'
import ClxEntity from './ClxEntity.ts' import ClxEntity from './ClxEntity.ts'
import ClxMeta from './ClxMeta.ts'
import ClxInteraction from './ClxInteraction.ts' import ClxInteraction from './ClxInteraction.ts'
import propertySetter from "@/modules/clx/ClxPropertySetter.ts";
export const ITEM_TYPE_NAME = 'clx' export const ITEM_TYPE_NAME = 'clx'
export default defineModule({ export default defineModule({
name: ITEM_TYPE_NAME, name: ITEM_TYPE_NAME,
renderer: new ClxRenderer(ITEM_TYPE_NAME), renderer: new ClxRenderer(ITEM_TYPE_NAME),
interaction: new ClxInteraction(ITEM_TYPE_NAME), interaction: new ClxInteraction(ITEM_TYPE_NAME),
meta: ClxMeta, setter: propertySetter,
entity: ClxEntity entity: ClxEntity
}) })

49
src/modules/ptr/PtrMeta.ts

@ -1,49 +0,0 @@
import type { IMeta } from '@/core/base/IMeta.ts'
export default [
{ field: 'uuid', editor: 'UUID', label: 'uuid', readonly: true, category: 'basic' },
{ field: 'name', editor: 'TextInput', label: '名称', category: 'basic' },
{ field: 'dt.label', editor: 'TextInput', label: '标签', category: 'basic' },
{ editor: 'TransformEditor', category: 'basic' },
{ field: 'dt.color', editor: 'Color', label: '颜色', category: 'basic' },
{ editor: '-', category: 'basic' },
{ field: 'dt.ptrWidth', editor: 'NumberInput', label: 'PTR宽度', category: 'basic' },
{ field: 'dt.ptrDepth', editor: 'NumberInput', label: 'PTR深度', category: 'basic' },
/**
* dt.bays 53
* {
* dt: {
* rackDepth: 1.1, // 货架深度
* levelCount: 3, // 总层数
* bayCount: 5, // 总列数
* hideFloor: false, // 隐藏底板
* extendColumns: true, // 扩展挡板
* columnSpacing: 1, // 支脚跨越
* bays: [ // 每列的配置
* {
* bayWidth: 1.6, // 列的宽度
* levelHeight: [ 1.4, 1.4, 1.4 ] // 每层的高度
* },
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* {bayWidth: 1.6, levelHeight: [ 1.4, 1.4, 1.4 ]},
* ]
* }
* }
*
*
*
*
*
*
*
*/
{ field: 'tf', editor: 'InOutCenterEditor', category: 'basic' },
{ field: 'dt.selectable', editor: 'Switch', label: '可选中', category: 'basic' },
{ field: 'dt.protected', editor: 'Switch', label: '受保护', category: 'basic' },
{ field: 'visible', editor: 'Switch', label: '可见', category: 'basic' }
] as IMeta
Loading…
Cancel
Save