修改看板

master
夜笙歌 2 days ago
parent 7c9a14ef5d
commit ebb008f0f8

@ -60,6 +60,7 @@
"vue-router": "4.3.2", "vue-router": "4.3.2",
"vue-types": "5.1.1", "vue-types": "5.1.1",
"vue3-print-nb": "^0.1.4", "vue3-print-nb": "^0.1.4",
"vue3-scroll-seamless": "^1.0.6",
"vue3-seamless-scroll": "^3.0.2", "vue3-seamless-scroll": "^3.0.2",
"vuedraggable": "4.1.0", "vuedraggable": "4.1.0",
"vxe-table": "4.5.22" "vxe-table": "4.5.22"

@ -143,6 +143,24 @@
</template> </template>
<div class="moduleText">图片</div> <div class="moduleText">图片</div>
</el-card> </el-card>
<el-card class="moduleCard" shadow="never" :draggable="true"
@dragstart="onDragStart($event, 'table')"
:style="{display:'inline-block',margin:'0 4px 4px 0'}"
:body-style="{padding:'4px 0'}">
<template #header>
<StarFilled />
</template>
<div class="moduleText">普通表格</div>
</el-card>
<el-card class="moduleCard" shadow="never" :draggable="true"
@dragstart="onDragStart($event, 'scrollTable')"
:style="{display:'inline-block',margin:'0 4px 4px 0'}"
:body-style="{padding:'4px 0'}">
<template #header>
<StarFilled />
</template>
<div class="moduleText">滚动表格</div>
</el-card>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@ -234,6 +252,14 @@
<StaticDataNode :inputData=getInputData(staticDataNodeProps.id) v-bind="staticDataNodeProps" <StaticDataNode :inputData=getInputData(staticDataNodeProps.id) v-bind="staticDataNodeProps"
@resize="resize"></StaticDataNode> @resize="resize"></StaticDataNode>
</template> </template>
<template #node-table="tableNodeProps">
<TableNode :inputData=getInputData(tableNodeProps.id) v-bind="tableNodeProps"
@resize="resize"></TableNode>
</template>
<template #node-scrollTable="scrollTableNodeProps">
<ScrollTableNode :inputData=getInputData(scrollTableNodeProps.id) v-bind="scrollTableNodeProps"
@resize="resize"></ScrollTableNode>
</template>
</VueFlow> </VueFlow>
</div> </div>
</div> </div>
@ -385,6 +411,11 @@
<el-form-item label="饼图标签" v-if="Object.keys(nodeAttrForm).includes('label')"> <el-form-item label="饼图标签" v-if="Object.keys(nodeAttrForm).includes('label')">
<el-switch v-model="nodeAttrForm.label" active-text="" inactive-text="" /> <el-switch v-model="nodeAttrForm.label" active-text="" inactive-text="" />
</el-form-item> </el-form-item>
<el-form-item label="表格设置" v-if="Object.keys(nodeAttrForm).includes('tableOptions')">
<el-button plain @click="tableOptionsVisible = true">
配置表格
</el-button>
</el-form-item>
</el-form> </el-form>
</el-collapse-item> </el-collapse-item>
<el-collapse-item title="自定义配置" name="3" v-if="customDataForm"> <el-collapse-item title="自定义配置" name="3" v-if="customDataForm">
@ -445,12 +476,61 @@
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
<el-dialog v-model="tableOptionsVisible" title="表格设置" width="800">
<el-table :data="nodeAttrForm.tableOptions">
<el-table-column label="列名称" width="150">
<template #default="scope">
<el-input v-model="scope.row.name" style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="数据字段" width="200">
<template #default="scope">
<el-input v-model="scope.row.field" style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="列宽">
<template #default="scope">
<el-input v-model="scope.row.width" style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="类型">
<template #default="scope">
<el-select
v-model="scope.row.type"
placeholder="请选择"
style="width: 100%"
>
<el-option
label="文本"
value="文本"
/>
<el-option
label="标签"
value="标签"
/>
<el-option
label="图片"
value="图片"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button :icon="Delete" circle @click="nodeAttrForm.tableOptions.splice(scope.$index, 1)" />
</template>
</el-table-column>
</el-table>
<el-button size="small" :icon="Plus" style="width: 100%" @click="nodeAttrForm.tableOptions.push({})">
</el-button>
</el-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { globalHeaders } from '@/utils/request'; import { globalHeaders } from '@/utils/request';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { Check, Close, Plus, Setting, StarFilled } from '@element-plus/icons-vue'; import { Check, Close, Plus, Setting, StarFilled, Delete } from '@element-plus/icons-vue';
import { MarkerType, useVueFlow, VueFlow } from '@vue-flow/core'; import { MarkerType, useVueFlow, VueFlow } from '@vue-flow/core';
import { Background } from '@vue-flow/background'; import { Background } from '@vue-flow/background';
import LineNode from './nodes/board/lineNode.vue'; import LineNode from './nodes/board/lineNode.vue';
@ -470,6 +550,8 @@ import TimeNode from './nodes/form/timeNode.vue';
import TextNode from './nodes/form/textNode.vue'; import TextNode from './nodes/form/textNode.vue';
import ImgNode from './nodes/form/imgNode.vue'; import ImgNode from './nodes/form/imgNode.vue';
import AreaNode from './nodes/other/areaNode.vue'; import AreaNode from './nodes/other/areaNode.vue';
import TableNode from './nodes/form/tableNode.vue';
import ScrollTableNode from './nodes/form/scrollTableNode.vue';
import tool from './tool'; import tool from './tool';
import { getDataSourceList } from '@/views/boardGenerate/api/dataSource'; import { getDataSourceList } from '@/views/boardGenerate/api/dataSource';
import { editBoardApi, getBoardApi } from '@/views/boardGenerate/api/boardList'; import { editBoardApi, getBoardApi } from '@/views/boardGenerate/api/boardList';
@ -492,6 +574,7 @@ const headers = ref(globalHeaders());
const loading = ref(false) const loading = ref(false)
const pageSettingVisible = ref(false); const pageSettingVisible = ref(false);
const pageSettingForm = ref({}); const pageSettingForm = ref({});
const tableOptionsVisible = ref(false);
const pageTitle = ref('页面名称'); const pageTitle = ref('页面名称');
const leftPanelState = ref('1'); const leftPanelState = ref('1');
const pageData = ref({}); const pageData = ref({});

@ -0,0 +1,125 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">
<div style="background-color: #094170">
<div class="scrollTable" style="font-weight: bold;" :style="`width: ${i.width || '100px'} `"
v-for="i in props.data.options.tableOptions">
{{ i.name }}
</div>
</div>
{{ props.inputData.tableData }}
<vue3ScrollSeamless
:classOptions="classOptions"
:dataList="list"
>
<div class="scrollTable" style="font-weight: bold;" :style="`width: ${i.width || '100px'} `"
v-for="(i,k) in props.data.options.tableOptions">
{{ ((props.inputData.tableData || [])[k] || {})[i.field] }}
</div>
</vue3ScrollSeamless>
</div>
<Handle v-if="!props.isView" :id="`${props.id}.-t`" type="target" :position="Position.Left" />
</div>
</template>
<script setup>
import { defineEmits, defineProps, ref } from 'vue';
import { NodeResizer } from '@vue-flow/node-resizer';
import { Handle, Position } from '@vue-flow/core';
import { vue3ScrollSeamless } from 'vue3-scroll-seamless';
let a = {
table: [
{
a: 1,
b: 2
},
{
a: 1,
b: 2
},
{
a: 1,
b: 2
}
]
};
console.log(JSON.stringify(a));
let list = ref([{
'title': '水调歌头·明月几时有'
}, {
'title': '苏轼 〔宋代〕'
}, {
'title': '明月几时有?把酒问青天。'
}, {
'title': '不知天上宫阙,今夕是何年。'
}, {
'title': '我欲乘风归去,又恐琼楼玉宇,高处不胜寒'
}, {
'title': '起舞弄清影,何似在人间。'
}, {
'title': '转朱阁,低绮户,照无眠。'
}, {
'title': '不应有恨,何事长向别时圆?'
}, {
'title': '人有悲欢离合,月有阴晴圆缺,此事古难全。'
}, {
'title': '但愿人长久,千里共婵娟。'
}
]);
const classOptions = ref({
limitMoveNum: 6
});
const props = defineProps({
isView: {
type: Boolean,
required: false
},
inputData: {
type: Object,
required: false
},
id: {
type: String,
required: true
},
isHideHandle: {
type: Boolean,
required: false
},
selected: {
type: Boolean,
required: false
},
data: {
type: Object,
required: true
},
dimensions: {
type: Object,
required: true
}
});
console.log(props.inputData);
const emit = defineEmits(['resize']);
const resize = (e) => {
emit('resize', e, props.id);
};
</script>
<style scoped>
.custom-node {
position: absolute;
}
.scrollTable {
display: inline-block;
color: #fff
}
</style>

@ -0,0 +1,97 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">
<div class="tableTh"></div>
<vue3ScrollSeamless
class="scroll-wrap"
:classOptions="classOptions"
:dataList="list">
<ul class="ui-wrap">
<li class="li-item" v-for="(item,i) of list" :key="i">
<p style="color: #fff">{{ item.title }}</p>
</li>
</ul>
</vue3ScrollSeamless>
</div>
<Handle v-if="!props.isView" :id="`${props.id}.-t`" type="target" :position="Position.Left" />
</div>
</template>
<script setup>
import { defineEmits, defineProps, ref } from 'vue';
import { NodeResizer } from '@vue-flow/node-resizer';
import { Handle, Position } from '@vue-flow/core';
import { vue3ScrollSeamless } from 'vue3-scroll-seamless';
let list = ref([{
'title': '水调歌头·明月几时有'
}, {
'title': '苏轼 〔宋代〕'
}, {
'title': '明月几时有?把酒问青天。'
}, {
'title': '不知天上宫阙,今夕是何年。'
}, {
'title': '我欲乘风归去,又恐琼楼玉宇,高处不胜寒'
}, {
'title': '起舞弄清影,何似在人间。'
}, {
'title': '转朱阁,低绮户,照无眠。'
}, {
'title': '不应有恨,何事长向别时圆?'
}, {
'title': '人有悲欢离合,月有阴晴圆缺,此事古难全。'
}, {
'title': '但愿人长久,千里共婵娟。'
}
]);
const classOptions = ref({
limitMoveNum: 6
});
const props = defineProps({
isView: {
type: Boolean,
required: false
},
inputData: {
type: Object,
required: false
},
id: {
type: String,
required: true
},
isHideHandle: {
type: Boolean,
required: false
},
selected: {
type: Boolean,
required: false
},
data: {
type: Object,
required: true
},
dimensions: {
type: Object,
required: true
}
});
const emit = defineEmits(['resize']);
const resize = (e) => {
emit('resize', e, props.id);
};
</script>
<style scoped>
.custom-node {
position: absolute;
}
</style>

@ -35,6 +35,8 @@ const getOption = (e) => {
return { text: '文字', align: '', color: '#fff' }; return { text: '文字', align: '', color: '#fff' };
} else if (e === 'img') { } else if (e === 'img') {
return { imgSrc: '' }; return { imgSrc: '' };
} else if (e === 'scrollTable' || e === 'table') {
return { tableOptions: [] };
} else { } else {
return {}; return {};
} }
@ -56,6 +58,8 @@ const getNodeSize = (e) => {
return { width: 300, height: 300 }; return { width: 300, height: 300 };
} else if (e === 'map') { } else if (e === 'map') {
return { width: 100, height: 30 }; return { width: 100, height: 30 };
} else if (e === 'scrollTable' || e === 'table') {
return { width: 500, height: 300 };
} else { } else {
return { width: 100, height: 100 }; return { width: 100, height: 100 };
} }

@ -1,7 +1,8 @@
<template> <template>
<div class="content" <div class="content"
:style='`width:${area?.width || "100%"};height:${area?.height || "100%"};background-image:url(${area?.bg})`'> :style='`width:${area?.width || "100%"};height:${area?.height || "100%"};background-image:url(${area?.bg})`'>
<div v-for="i in nodes" class="node" :style="{left:i.position?.x+'px',top: i.position?.y+'px'}"> <div v-for="i in nodes" class="node"
:style="{left: (i.position?.x / (area?.width|| 1920))*100 +'%',top: (i.position?.y / (area?.height || 1080))*100 +'%'}">
<template v-if="i.type === 'customBoard'"> <template v-if="i.type === 'customBoard'">
<CustomBoardNode :isView="true" :inputData=getInputData(i.id) v-bind="i"></CustomBoardNode> <CustomBoardNode :isView="true" :inputData=getInputData(i.id) v-bind="i"></CustomBoardNode>
</template> </template>
@ -79,10 +80,7 @@ const router = useRouter();
const nodes = ref([]); const nodes = ref([]);
const edges = ref([]); const edges = ref([]);
const area = ref({ const area = ref({});
width: 1910,
height: 970
});
const getInputData = (e) => { const getInputData = (e) => {
let outputData = {}; let outputData = {};
let nodeIds = edges.value.map(v => { let nodeIds = edges.value.map(v => {
@ -158,8 +156,6 @@ onMounted(async () => {
}) || []; }) || [];
area.value = JSON.parse(data.customContent) || {}; area.value = JSON.parse(data.customContent) || {};
}); });
// area.value = nodes.value.find(e=>e.type==='area')
// console.log('area.value',area.value);
}); });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

Loading…
Cancel
Save