如下图所有,有个需求更新, 实现拖拽。
1,当新增了测点类型的时候每个对应的回路子数据都会新增对应的测点类型。
2,当拖动测点类型结束的时候对应的回路里面的内容也会跟着测点类型的排序自动排序
其实很简单,只要会了拖拽,然后再定的数据处理里面加上对应的处理逻辑就好了。
我这边直接展示代码了。
template><div class="box"><div class="assembly-wrap"><div class="assembly-div"><div class="assemblyimg"><img v-show="Number(dataInfos.assembly.value) === 1" src="../../../assets/images/switch/onAssembly.png" alt=""><img v-show="Number(dataInfos.assembly.value) !== 1" src="../../../assets/images/switch/assembly.png" alt=""></div><div class="flexCloum"><div class="title" :class="{'title2': dataInfos.title.position === 2}">{{ dataInfos.title.value }}</div><div v-show="dataInfos.networkVoltageFlag" class="network-voltage" :class="{'title2': dataInfos.title.position === 2}">电网电压 <span>{{ dataInfos?.networkVoltageInfo?.value }} v </span></div></div><div class="switch-line"></div><div class="switch-wrap"><div v-for="(item, i) in dataInfos.loopList" :key="i" class="switch-row"><div class="loop">回路{{ i+1 }}</div><div v-show="Number(item.value) === 1" class="loopimgwrap"><img class="loopimg1" src="../../../assets/images/switch/on.png" alt=""></div><img v-show="Number(item.value) !== 1" :class="{'loopimg2': i+1 !== dataInfos.loopList.length}" src="../../../assets/images/switch/off.png" alt=""><div class="label" :class="{'label2': item.value !== 1}" :title="item.label">{{ item.label }}</div><div class="switchmine"><div v-for="(item2, i) in item.list" :key="i"><span @dblclick="triggerDblclick(item, item2)">{{ item2.value | isNull }}{{ item2.unit }}</span></div></div></div></div><div class="labellist"><div v-for="(item, i) in dataInfos.options" :key="i"><el-tooltip v-if="item.label.length > 4 " class="item" effect="dark" :content="item.label" placement="top"><span>{{ item.label }}</span></el-tooltip><span v-else>{{ item.label }}</span></div></div></div></div><zmjdialog ref="zmjdialog" top="10vh" width="1000px" @confirm="confirm" @cancel="cancel" ><el-form ref="ruleForm" :model="formData" label-width="150px"><div class="df"><!-- :rules="[{ required: true, message: '请输入测点', trigger: ['blur', 'change'] }]" --><el-form-itemlabel="组件标题"><el-input v-model="formData.title.value" placeholder="请输入组件标题"></el-input></el-form-item><el-form-itemlabel="标题位置"><el-radio v-model="formData.title.position" :label="1">左</el-radio><el-radio v-model="formData.title.position" :label="2">右</el-radio></el-form-item></div><div class="df" ><!-- :label="`${formData.title.value}测点`" --><el-form-itemlabel="测点"><el-input v-model="formData.assembly.site" placeholder="请输入标题测点"></el-input></el-form-item></div><div class="df" ><el-form-itemlabel="电网电压"><el-switch v-model="formData.networkVoltageFlag" /></el-form-item></div><div class="df" v-show="formData.networkVoltageFlag"><el-form-itemlabel="电网电压测点"><el-input v-model="formData.networkVoltageInfo.site" placeholder="请输入电网电压测点"></el-input></el-form-item></div><div class="pump-list"><div class="title"><span>回路</span><ul><!-- <li @click="pumpcancel">取消</li> --><li @click="addpump">添加回路</li></ul></div><div class="df site-wrap" style="margin-top: 20px;"><el-form-itemlabel-width="100px"label="测点类型"><el-input v-model="sitetypes" placeholder="请输入测点类型"></el-input></el-form-item><div class="addsitetype" @click="addsitetype()">添加测点类型</div></div><div class="optionsList"><div v-for="(item, i) in formData.options":key="i"draggable="true"@dragstart="dragStart(i, item)"@dragover.prevent="dragOver(i)"@dragend="dragEnd()">{{ item.label }}<i class="el-tag__close el-icon-close" @click="optionclose(i)"></i></div></div><div class="ulmine"><el-collapse v-model="activeNames" @change="handleChange"><el-collapse-item v-for="(item, i) in formData.loopList" :key="i" :name="i"><template slot="title">回路{{ i+1 }}<div class="pumpdelete" @click.stop="pumpdelete(i)">删除</div></template><div class="ulmine-div"><!-- <div class="addpumpsite" @click="addpumpsite(i)">添加测点</div> --><div class="df"><el-form-itemlabel-width="100px"label="回路名称"><el-input v-model="item.label" placeholder="请输入名称"></el-input></el-form-item><el-form-itemlabel-width="120px"label="回路测点"><el-input v-model="item.site" placeholder="请输入测点"></el-input></el-form-item></div><div v-for="(item2, j) in item.list":key="j"draggable="true"ref="optionsRef"><div class="df"><el-form-itemlabel-width="100px"label="测点类型:"><div class="typetext">{{ item2.type }}</div></el-form-item><el-form-itemlabel-width="50px"label="测点"><el-input v-model="item2.site" :style="{width: '120px'}" placeholder="请输入测点"></el-input></el-form-item><el-form-itemlabel-width="80px"label="单位"><el-input v-model="item2.unit" :style="{width: '120px'}" placeholder="请输入单位"></el-input></el-form-item><el-form-item label-width="20px" label="" class="ponits_value"><el-radio v-model="item2.state" :label="1">初始值</el-radio><el-radio v-model="item2.state" :label="2">转换值</el-radio></el-form-item><div v-show="item2.state === 2"><div class="add_point conversion" @click="addConversion(item2)">添加转换值</div></div></div><div v-show="item2.state === 2"><div v-for="(item3,indexs) in item2.children" :key="indexs"><div class="points_items" style="margin-bottom:20px"><el-form-item label-width="100px" label="转换标识"><el-input v-model="item3.value" placeholder="转换标识"></el-input></el-form-item><el-form-item label-width="100px" label="转换值"><el-input v-model="item3.label" placeholder="转换值"></el-input></el-form-item><i class="el-icon-remove" style="margin-left:30px;font-size:25px;cursor: pointer;" @click="deleteConversion(item2,indexs)"></i></div></div></div><!-- <div class="el-icon-remove" @click="deletepumpsite(i,j)"></div> --></div></div></el-collapse-item></el-collapse></div></div></el-form></zmjdialog><zmjdialog ref="childInfoDialog" width="850px" top="30vh" :title="`${label}&${labelItem}历史数据`" @confirm="childInfoDialog"><zmj-echarts :ref="`historicalLineEcharts${chartId}`" :echarts-id="`historicalLineEcharts${chartId}`" :height="'200px'"></zmj-echarts></zmjdialog></div></template><script>import ZmjEcharts from '@/components/zmjEcharts.vue'import { shearerOptions } from '../../components/echarts/Historicalline.js'export default {components: {ZmjEcharts},props: {dataInfo:{type: Object,default (){return {}}}},data () {return {sitetypes: null,formData: {},activeNames: [0],dataInfos: {},groupName: '', // 测点大类dataName: '', // 测名称deviceIdList: 1, // 设备号label: null,labelItem: null,chartId: `Id${new Date().getTime()}`,dragStartIndex: '',dragStartData: '',copyStartData:''}},watch: {dataInfo: {immediate: true,deep: true,handler (val) {this.formData = JSON.parse(JSON.stringify(val))this.dataInfos = JSON.parse(JSON.stringify(val))// 处理后加入字段this.formData.loopList.forEach(v => {v.list&&v.list.forEach(v2 => {if(!v2.state){v2.state = 1}if(!v2.children){v2.children = []}})})console.log(this.formData, 'this.formData')}}},computed: {},created () {},filters: {isNull (val) {return val === null ? '--' : val}},mounted () {window.$eventBus.$on('wsMessage', message => {let dataType = message.dataType// message.data.forEach(val => {})for(let i in this.dataInfos){if(i === 'loopList'){this.dataInfos[i].forEach(v => {if(this.sifn(v.site) === dataType){this.messagefn(message.data, v)}v.list && v.list.forEach(v2 => {if(this.sifn(v2.site) === dataType){this.messagefn(message.data, v2)}})})}if(i === 'assembly'){if(this.sifn(this.dataInfos[i].site) === dataType){this.messagefn(message.data, this.dataInfos[i])}}if(i === 'networkVoltageInfo'){if(this.sifn(this.dataInfos[i].site) === dataType){this.messagefn(message.data, this.dataInfos[i])}}}})},beforeDestroy () {window.$eventBus.$off('wsMessage')},methods: {// 拖拽逻辑在这里。dragStart (index, item) {console.log(index, item);this.dragStartIndex = indexthis.dragStartData = item// 拿到测点类型 的第 index 个 数据对应的listthis.formData.loopList.forEach(item => {this.copyStartData = item.list[index]})},// 只要拖拽元素进入到放置区域就触发,这里实际是鼠标指针进入放置区域才触发dragOver (index) {this.dragOverIndex = index},// 结束拖拽逻辑的时候进行对应的子向排序。dragEnd () {const copyTodolist = [...this.formData.options]// 删除老的节点copyTodolist.splice(this.dragStartIndex, 1)// 在列表中目标位置增加新的节点copyTodolist.splice(this.dragOverIndex, 0, this.dragStartData)// ... 上边是测点类型的排序,结束后对应的回路跟着类型调整位置this.formData.options = [...copyTodolist] // 获取测点类型调整后的顺序// console.log('drag end', this.formData.loopList, '所有的对应类型loopList');this.formData.loopList.map((item, v) => {const copyList = [...item.list] // 所有的对应类型loopList的对应测点list// 删除对应的老的节点copyList.splice(this.dragStartIndex, 1)// 在列表中目标位置增加新的节点copyList.splice(this.dragOverIndex, 0, this.copyStartData)return item.list = [...copyList]})this.dragOverIndex = ''},// '双击事件 展示折线图triggerDblclick (info, info2) {console.log(info, info2, '双击事件');this.$refs.childInfoDialog.open()this.label = info.labelthis.labelItem = info2.typeif(info2.site){let arr = info2?.site?.split('/') || []console.log(arr);this.groupName = `${arr[0]}` // 测点大类this.deviceIdList = `${arr[1]}` // 设备号this.dataName = `${arr[2]}` // 测名称}let params = {workFaceCode: window.$getStorage('workFaceInfo').workFaceCode,startTime: window.$dayjs().format('YYYY-MM-DD 00:00:00'),endTime: window.$dayjs().add(1, 'day').format('YYYY-MM-DD 00:00:00'),aggregateType : 'none', // 聚合类型 传none获取原始历史值groupName: this.groupName, // 测点大类dataName: this.dataName, // 测名称deviceIdList: this.deviceIdList // 设备号}let thisDataList = nullwindow.$axiosGet('deviceHistory', params).then((res) => {if(!res.length){this.$refs[`historicalLineEcharts${this.chartId}`] && this.$refs[`historicalLineEcharts${this.chartId}`].upDataEcharts(shearerOptions(res || [], params, this.dataInfos))return}thisDataList = res.map(item => {return item.data})this.$nextTick(() => {this.$refs[`historicalLineEcharts${this.chartId}`] && this.$refs[`historicalLineEcharts${this.chartId}`].getEchartsLiving();this.$refs[`historicalLineEcharts${this.chartId}`] && this.$refs[`historicalLineEcharts${this.chartId}`].upDataEcharts(shearerOptions(thisDataList || [], params, this.dataInfos))})}).catch(() => {this.$refs[`historicalLineEcharts${this.chartId}`] && this.$refs[`historicalLineEcharts${this.chartId}`].upDataEcharts(shearerOptions(thisDataList || [], params, this.dataInfos))})},childInfoDialog () {this.$refs.childInfoDialog.close()},messagefn (e, v){e.forEach(val => {if(val.deviceId === this.sifn(v.site, 2)){v.value = val.valueif(v.state === 2){v.children&&v.children.forEach(v2 => {if(String(val.value) === String(v2.value)){v.value = v2.label}})}}})},sifn (v, i = 1) {if(v){let arr = v.split('/')if(arr.length === 3){if(i === 1){return `${arr[0]}_${arr[2]}`}else if(i === 2) {return Number(arr[1])}}else{return v}}else{return v}},deleteConversion (items, indexs){items.children.splice(indexs, 1)},// 添加转换值addConversion (item){item.children?.push({label:'',value:''})},handleChange (val) {console.log(val)},// 回路删除pumpdelete (i) {if(this.formData.loopList.length <= 2){this.$message.warning('回路最少有2个')return}this.formData.loopList.splice(i, 1)},// 添加回路addpump () {this.formData.loopList.push({site: null,value: null,label: null,list: this.formData.options.map(v => {return {site: null,value: null,type: v.label,unit: null,state: 1,children: []}})})},// 回路类型添加addsitetype () {if(this.sitetypes === '' || this.sitetypes === null|| this.sitetypes === undefined){return this.$message.warning('请添加测点类型')}this.formData.options.push({label: this.sitetypes})this.formData.loopList.forEach(v => {v.list.push({site: null,value: null,type: this.sitetypes,unit: null,state: 1,children: []})})this.sitetypes = ''},// 回路类型添加删除optionclose (i) {this.formData.options.splice(i, 1)this.formData.loopList.forEach(v => {v.list.splice(i, 1)})},// 乳化泵测点添加// addpumpsite (i) {// this.formData.loopList[i].list.push({// site: null,// value: null,// type: null,// unit: null// })// },// 乳化泵测点删除// deletepumpsite (i, j) {// this.formData.loopList[i].list.splice(j, 1)// },edit () {// this.formData = window.$utils.cloneDeep(this.formData)this.$refs.zmjdialog.open()},confirm (){this.dragStartIndex = '';this.$refs.ruleForm.validate((valid) => {if (valid) {this.$refs.zmjdialog.close()// let arr = [ this.formData.assembly.site, this.formData.networkVoltageInfo.site]let arr = [ this.formData.assembly.site]this.formData.loopList.forEach(v => {arr.push(v.site)v.list && v.list.forEach(v2 => {arr.push(v2.site)})})let newArr = []newArr.push(this.formData.networkVoltageInfo.site, ...arr)this.$emit('update:dataTypeList', newArr)this.$emit('update:dataInfo', this.formData)this.$message.success('保存成功')} else {return false}})},cancel () {this.dragStartIndex = '';console.log('取消')}}}</script><style lang="scss" scoped>.box{padding-top: 20px;font-size: 14px;}.assembly-wrap{border: 1px solid #707070;border-radius: 2px;width: 100%;height: 100%;}.assembly-div{width: calc(100% - 80px);margin-left: 80px;position: relative;.assemblyimg{width: 95%;position: relative;>img{position: absolute;top: -20px;left: 50%;margin-left: -32px;}}.network-voltage{position: absolute;top: 60px;font-size: 12px;width: 60%;left: -20%;text-align: right;padding: 0 60px 0 0;span{margin-left: 10px;color: #31E8B4;}}.flexCloum{display: flex;flex-direction: column;}.title{position: absolute;top: 30px;font-size: 20px;color: #FFBB00;width: 60%;left: -10%;text-align: right;padding:0 60px 0 0;}.title2{text-align: left;width: 50%;padding:0 0 0 30px;left: auto;right: 0;}.switch-line{width: calc(95% - 11px);height: 2px;position: absolute;top: 102px;left: 5px;background: #31E8B4;}.switch-wrap{position: absolute;top: 104px;width: 95%;display: flex;justify-content: space-between;.switch-row{position: relative;.loopimgwrap{width: 21px;}.loopimg2{position: relative;left: -8px;}}.switch-row:last-child{.loopimg1{position: relative;left: 4px;}}.switch-row:first-child{.loopimg1{position: relative;left: -7px;}}.loop{position: absolute;width: 70px;text-align: left;top: -25px;}.label{position: absolute;width:70px;bottom: -40px;left: -31px;}.label2{left: -22px;// height: 40px;// line-height: 16px;// overflow: hidden;// text-overflow: ellipsis;// white-space: nowrap;}.switchmine{position: absolute;top: 160px;left: -25px;>div{width: 70px;line-height: 20px;height: 20px;margin-bottom: 10px;color: #31E8B4;}}}.labellist{position: absolute;left: -80px;top: 264px;line-height: 20px;>div{width: 60px;overflow: hidden;white-space:nowrap;text-overflow: ellipsis;margin-bottom: 10px;}}}.pump-list{position: relative;color: #fff;border:1px solid #999;border-radius: 5px;.title{display: flex;justify-content: space-between;align-items: center;padding: 0 16px;width: 100%;height: 36px;background: rgba(238, 238, 238, 0.08);border-bottom: 1px solid #314150;box-sizing: border-box;ul{display: flex;li{margin-left: 8px;width: 64px;line-height: 24px;font-size: 14px;text-align: center;border-radius: 3px;user-select: none;cursor: pointer;}// >li:nth-child(1){// border: 1px solid rgba(255, 255, 255, 0.24);// }>li:nth-child(1){border: 1px solid #0088FF;}}}.ulmine{padding:0 20px 10px 20px;height: 400px;overflow: hidden;overflow-y: scroll;.ulmine-div{position: relative;padding: 15px 0;}.el-icon-remove{cursor: pointer;height: 36px;line-height: 36px;font-size: 20px;padding-left: 15px;color: #999;}.pumpdelete{width: 64px;line-height: 24px;font-size: 14px;text-align: center;border-radius: 3px;cursor: pointer;border: 1px solid #B23B3B;margin-left: 620px;}.addpumpsite{position: absolute;line-height: 24px;font-size: 14px;text-align: center;border-radius: 3px;cursor: pointer;right: 10px;top: 20px;width: 84px;right: 30px;border: 1px solid #0088FF;}::v-deep{.el-collapse{border: none;}.el-collapse-item__header{padding-left: 20px;background: transparent;color: #fff;border-bottom:none;background: rgba(238, 238, 238, 0.08);}.el-collapse-item__wrap{background: transparent;border-bottom: 1px dashed #7a7d80;}.el-collapse-item__content{color: #fff;padding-bottom: 0;}}}.ulmine::-webkit-scrollbar {display: none;}}.addsitetype{position: absolute;line-height: 24px;font-size: 14px;text-align: center;border-radius: 3px;cursor: pointer;top: 62px;width: 104px;left: 370px;border: 1px solid #0088FF;}.optionsList{display: flex;flex-wrap:wrap;padding-bottom: 5px;margin-left: 80px;>div{margin-left: 20px;background-color: #f4f4f5;border-color: #e9e9eb;color: #909399;padding:7px 12px;border-radius: 4px;position: relative;margin-bottom: 10px;.el-tag__close{color: #909399;background-color: #c0c4cc;border-radius: 50%;font-size: 15px;text-align: center;margin-left: 5px;cursor: pointer;}}}.site-wrap{::v-deep{.el-form-item{margin-bottom: 10px;}}}.typetext{width: 100px;overflow: hidden;}.add_point{display: inline-block;margin-left: 30px;width: 80px;height: 32px;border-radius: 4px;font-size: 14px;color: #fff;line-height: 30px;border: 1px solid #409EFF;cursor: pointer;text-align: center;user-select: none;}.conversion{margin-left: 20px;margin-top: 5px;font-size: 13px;height: 28px;line-height: 26px;}.points_items{display: flex;align-items: center;::v-deep{.el-form-item{margin-bottom: 0;}}}</style>
保存后的图例对比