当前位置: 首页 > news >正文

VUE条件树查询 自定义条件节点

之前实现过的简单的条件树功能如下图:

 经过最新客户需求确认,上述条件树还需要再次改造,以满足正常需要!

最新暴改后的功能如下红框所示:

 

页面功能

主页面逻辑代码:

<template><div class="flex-col"><div id="container" class="c-view"></div><el-button type="primary" plain style="width: 120px;" @click="doQuery">开始搜索</el-button></div>
</template>
<script>
import { Graph } from '@antv/x6'
import Hierarchy from '@antv/hierarchy'
import '@antv/x6-vue-shape'
import querytrees from './queryCondition.vue' //这是我的vue组件,作为子节点展示在思维导图上
import queryrelative from './queryRelative.vue'import { findItem, lastChild, setData, addChildNode, removeNode, randomId } from './fun'export default {data() {return {graphData: {'id': '1','type': 'original—add','width': 80,'height': 30,"children": [// {//     "id": 0.28207584597793156,//     "type": "queryrelative", //关系节点//     "width": 44,//     "height": 44,//     "data": {//         "relative": "and" //and并且 or或者//     },//     "children": [//         {//             "id": 0.32858917851150116,//             "type": "condition-text", //条件节点//             "width": 90,//             "height": 44,//             "level": 1, //判断它是第几级的条件节点//             "edgeText": "",//             "data": {//                 "complete": true,//                 "form": {} //你的业务数据//             }//         },//         {//             "id": 0.30546487070416783,//             "type": "vue-shape", //自定义组件 业务节点//             "width": 744,//             "height": 44,//             "level": 1,//             "edgeText": "",//             "data": {//                 "complete": false,//                 "form": {} //你的业务数据//             }//         }//     ]// }]} //默认只有一个根节点}},mounted() {this.init()},methods: {//初始化⽅法doQuery() {let vft = (obj) => {let empty = obj.children.length == 0if (obj.type == 'relative') {empty = false}else {if (obj.data) {empty = !obj.data.complete}else {for (let i = 0; i < obj.children.length; i++) {empty = vft(obj.children[i])if (empty) {break}}}}return empty}if (vft(this.graphData)) {this.$modal.msgError("请先确认查询条件")}else {//组装查询语句// let cft = (obj) => {//     let stms = null//     if (obj.type == 'relative') {//         obj.children.forEach(e => {//             if (e.children && e.children.length > 0) {//                 e.children.forEach(p => {//                     let at = cft(p)//                     if (!stms) {//                         stms = at//                     }//                     else {//                         stms = stms + ' ' + e.data.relative + ' ' + at//                     }//                 })//             }//             else {//                 if (!stms) {//                     stms = e.data.form.topForm.value + e.data.form.conditionForm.value + e.data.form.valueForm.value//                 }//                 else {//                     let t = e.data.form.topForm.value + e.data.form.conditionForm.value + e.data.form.valueForm.value//                     stms = stms + ' ' + obj.data.relative + ' ' + t//                 }//             }//         })//     }//     else {//         obj.children.forEach(p => {//             debugger//             let at = cft(p)//             if (!stms) {//                 stms = at//             }//             else {//                 stms = stms + p.data.relative + at//             }//         })//     }//     return stms// }this.$emit('input', { sql: "", tree: this.graphData.children })}},init() {let self = thisGraph.registerNode('original—add',{inherit: 'rect',width: 80,height: 30,label: '+纳入条件',attrs: { //样式代码body: {rx: 4,ry: 4,stroke: '#037AFB',fill: '#037AFB',strokeWidth: 1,event: 'add:original' //根节点点击事件},label: {fontSize: 14,fill: 'white',event: 'add:original'//根节点点击事件}}},true,)//自定义vue 业务节点Graph.registerVueComponent('queryrelative',{template: `<queryrelative/>`,components: {queryrelative}},true)//自定义vue 业务节点Graph.registerVueComponent('querytrees',{template: `<querytrees/>`,components: {querytrees}},true)// 弯的边Graph.registerEdge('mindmap-edge',{inherit: 'edge',router: {name: 'manhattan',args: {startDirections: ['right'],endDirections: ['left']}},connector: {name: 'rounded'},attrs: {line: {targetMarker: '',stroke: '#A2B1C3',strokeWidth: 2}}, //样式代码zIndex: 0},true,)// 直的边Graph.registerEdge('straight-edge',{inherit: 'edge',attrs: {}, //样式代码zIndex: 0},true,)//新增限定条件Graph.registerNodeTool('add-condition',{inherit: 'button', // 基类名称,使用已经注册的工具名称。markup: [{tagName: 'rect',selector: 'button',attrs: {fill: '#296FFF',cursor: 'pointer',width: 32,height: 28}},{tagName: 'image',selector: 'icon',attrs: {'xlink:href': 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*SYCuQ6HHs5cAAAAAAAAAAAAAARQnAQ',cursor: 'pointer',width: 16,height: 16,x: 8,y: 6}}],x: '100%',y: '100%',offset: { x: -32, y: -72 },onClick({ cell }) {const { id } = cellconst dataItem = findItem(this.graphData, id).nodeconst lastNode = lastChild(dataItem)//找到当前node的最后一级,添加if (addChildNode(lastNode.id, '并且', graphData)) {render(graph, this.graphData)}}}, true)//关系节点 点击增加条件事件Graph.registerNodeTool('relative:add-condition', {inherit: 'button', // 基类名称,使用已经注册的工具名称。markup: [{tagName: 'rect',selector: 'button',attrs: {fill: '#296FFF',cursor: 'pointer',width: 32,height: 28}},{tagName: 'image',selector: 'icon',attrs: {'xlink:href': 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*SYCuQ6HHs5cAAAAAAAAAAAAAARQnAQ',cursor: 'pointer',width: 16,height: 16,x: 8,y: 6}}],x: '100%',y: '100%',offset: { x: -32, y: -72 },onClick({ cell }) {const { id } = cellif (addChildNode(id, '', this.graphData)) render(graph, this.graphData)}}, true)//边增加条件Graph.registerEdgeTool('edge:add-condition', {inherit: 'button', // 基类名称,使用已经注册的工具名称。markup: [{tagName: 'rect',selector: 'button',attrs: {fill: '#296FFF',cursor: 'pointer',fontSize: 16,width: 20,height: 20,rx: 2,ry: 2,stroke: '#296FFF',strokeWidth: 1}},{tagName: 'text',selector: 'label',textContent: '+',attrs: {x: 5,y: 15,fontSize: 16,cursor: 'pointer',fill: '#ffff'}}],distance: '100%',offset: { y: -10, x: -10 },onClick({ cell }) {debuggerconst { node, parent } = findItem(self.graphData, cell.target.cell)const newId = randomId()const childP = {children: [node],id: newId,type: 'vue-shape',width: 80,height: 40,level: 2,component: 'queryrelative',data: { relative: 'and', type: 'document', options: [{ label: '同病人', value: '1' }, { label: '同病历', value: '2' }, { label: '同报告', value: '3' }], defaultValue: '1' }}const currentIndex = parent.children.findIndex(item => item.id === node.id)parent.children[currentIndex] = childPlet anode = addChildNode(newId, '', self.graphData)anode.width = 550anode.component = 'querytrees'if (anode) {render(graph, self.graphData)}}}, true)let graph = new Graph({background: { color: '#fff' },container: document.getElementById('container'),panning: { enabled: true },selecting: { enabled: true },keyboard: { enabled: true },grid: true,mousewheel: {enabled: true,modifiers: ['ctrl', 'meta']},interacting: { nodeMovable: false }})const render = (graph, graphData) => {const result = Hierarchy.mindmap(graphData, {direction: 'H',getHeight(d) {return d.height},getWidth(d) {return d.width},getHGap() {return 40},getVGap() {return 20},getSide: () => {return 'right'}})const cells = []const traverse = (hierarchyItem, parentId) => {if (hierarchyItem) {const { data, children } = hierarchyItemconst node = graph.createNode({...data,shape: data.type,x: hierarchyItem.x,y: hierarchyItem.y,component: data.component})if (parentId) {//有父级则插入父级const parent = graph.getCellById(parentId)parent && parent.addChild(node)}cells.push(node)//子节点边if (children) {children.forEach((item) => {const { id, data: itemData } = itemcells.push(graph.createEdge({shape: itemData.edgeText ? 'straight-edge' : 'mindmap-edge',source: {cell: hierarchyItem.id,anchor: {name: itemData.type === 'topic-child' ? 'right' : 'center',args: {dx: itemData.type === 'topic-child' ? -16 : '25%'}}},target: { cell: id, anchor: { name: 'left' } },labels: [{ attrs: { text: { text: itemData.edgeText || '' } } }]}),)traverse(item, node.id)})}}}traverse(result)graph.resetCells(cells)// graph.scaleContentToFit({ maxScale: 1 })graph.centerContent()}//根结点添加graph.on('add:original', ({ node }) => {debuggerif (this.graphData.children.length == 0) {const { id } = nodelet anode = addChildNode(id, '', this.graphData)anode.id = randomId()anode.type = "vue-shape" //自定义组件 业务节点anode.width = 550anode.height = 44anode.level = 1anode.edgeText = ""anode.data = {complete: false,form: {formType: 1,topForm: {label: '',value: ''},conditionForm: {},valueForm: {label: '',value: ''},extra: {}} //你的业务数据}anode.component = 'querytrees'anode.children = []if (anode) {render(graph, this.graphData)}}else if (this.graphData.children.lastObject().type != 'relative') {const { id } = nodelet tlist = this.graphData.childrenthis.graphData.children = []let anode = addChildNode(id, '', this.graphData)anode.type = "vue-shape"anode.width = 80;anode.height = 40;anode.level = 1;anode.component = 'queryrelative';anode.data = {"relative": "and" //and并且 or或者, options: [{ label: '同病人', value: '1' }, { label: '同病历', value: '2' }, { label: '同报告', value: '3' }], defaultValue: '1'}let xlist = []tlist.forEach(element => {element.id = randomId(),xlist.push(element)});xlist.push({id: randomId(),type: "vue-shape", //自定义组件 业务节点width: 550,height: 44,level: 1,edgeText: "",component: 'querytrees',data: {complete: false,form: {formType: 1,topForm: {label: '',value: ''},conditionForm: {},valueForm: {label: '',value: ''},extra: {}} //你的业务数据}})anode.children = xlistif (anode) {render(graph, this.graphData)}}else {const { id } = nodelet tlist = this.graphData.childrenthis.graphData.children = []let anode = addChildNode(id, '', this.graphData)anode.type = "vue-shape"anode.component = 'queryrelative'anode.width = 80;anode.height = 40;anode.level = 1;anode.data = {"relative": "and" //and并且 or或者}let xlist = []tlist.forEach(x => {xlist.push(x)})xlist.push({id: randomId(),type: "vue-shape", //自定义组件 业务节点width: 550,height: 44,level: 1,edgeText: "",component: 'querytrees',data: {complete: false,form: {formType: 1,topForm: {label: '',value: ''},conditionForm: {},valueForm: {label: '',value: ''},extra: {}} //你的业务数据}})anode.children = xlist// tlist.push(anode)this.graphData.children = [anode]if (anode) {render(graph, this.graphData)}}})//节点数据变化graph.on('node:change:data', ({ cell, node }) => {debuggersetData(self.graphData, node.id, node.data)const dataItem = node.getData()cell.setData({ ...dataItem, complete: dataItem.complete, isEdit: true })})graph.on('node:removed', ({ cell, node }) => {removeNode(node.id, self.graphData)render(graph, self.graphData)})//节点聚焦 增加工具栏目graph.on('node:mouseenter', ({ node }) => {// if (['condition-text', 'relative'].includes(node.shape)) {//     if (!this.isExistUnComplete()) { //判断当前是否有未填写完成的vue组件节点//         if (node.shape === 'condition-text') {//             node.setAttrs({ body: { fill: '#E9F0FF', stroke: '#296FFF' } })//         }//         this.addTool(node)//     }// }})//节点失焦 移除工具栏graph.on('node:mouseleave', ({ node }) => {// if (['condition-text', 'relative'].includes(node.shape)) {//     if (node.shape === 'condition-text') {//         node.setAttrs({ body: { stroke: '#CCC', fill: '#fff' } })//     }//     this.removeTool(node)// }})//边 悬浮事件graph.on('edge:mouseenter', ({ edge }) => {//不是 根结点下第一个关系节点 并且 没有未完成的节点 可添加const targetNode = graph.getCellById(edge.target.cell)const targetNodeData = findItem(this.graphData, edge.target.cell).nodeconst isChild = targetNodeData.level ? targetNodeData.level === 1 : true //不是限定节点 可添加if (!(edge.source.cell === '1' && targetNode.shape === 'relative') && isChild && !this.isExistUnComplete()) {edge.addTools(['edge:add-condition'])}})//边 失焦graph.on('edge:mouseleave', ({ edge }) => {if (!this.isExistUnComplete()) {//判断当前是否有未填写完成的vue组件节点edge.removeTools(['edge:add-condition'])}})render(graph, this.graphData)},isExistUnComplete() {return false}}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.flex-col {width: 100%;height: 310px;display: flex;flex-direction: column;justify-content: center;align-items: center;
}.c-view {height: 260px;width: 100%;
}.topic-image {visibility: hidden;cursor: pointer;
}.x6-node:hover .topic-image {visibility: visible;
}.x6-node-selected rect {stroke-width: 2px;
}
</style>

涉及到的组件一 

queryCondition.vue

<template><div class="condition" :class="[complete ? 'ny-view' : 'dy-view']" :style="{ width: lineTextWidth + 'px' }"><el-form v-if="!complete" ref="form" :model="form" label-width="0" inline><el-row :gutter="10"><el-col :span="(form.formType != 2) ? 9 : 6"><el-form-item class="w-100 flex-row"><el-select class="search-options" v-model="form.topForm.value" filterable clearableplaceholder="请选择" :loading="remoteLoading" remote :remote-method="searchKeysAction"><el-option v-for="item in topFormOptions" :key="item.formItemId" :label="item.label":value="item.formItemId"></el-option></el-select><el-button class="search-icon" icon="el-icon-plus" @click="showCheck = true"></el-button></el-form-item></el-col><el-col :span=5><el-form-item class="w-100"><el-select v-model="form.conditionForm.value" placeholder="关系" @change="conditionFormChanged"><el-option v-for="item in optionsList()" :key="item.label" :label="item.label":value="item.value"></el-option></el-select></el-form-item></el-col><el-col :span="(form.formType != 2) ? 5 : 8"><el-form-item class="w-100"><el-select v-if="form.formType == 3" v-model="form.valueForm.value" placeholder="请选择"><el-option v-for="item in valuesOptions" :key="item.value" :label="item.label":value="item.value"></el-option></el-select><div v-else-if="form.formType == 2" :key="renderKey"><el-date-picker class="w-100"v-if="(form.conditionForm.value != '9' && form.conditionForm.value != '10')"v-model="form.valueForm.value" format="yyyy.MM.dd" type="date"placeholder="选择日期"></el-date-picker><el-date-picker class="w-100" v-else v-model="form.valueForm.value" format="yy.MM.dd"type="daterange" range-separator="-" start-placeholder="开始时间" end-placeholder="结束时间"></el-date-picker></div><el-input class="w-100" v-else v-model="form.valueForm.value" placeholder="对比值"></el-input></el-form-item></el-col><el-col :span=5><el-form-item class="w-100"><div class="flex-row w-100"><el-button type="danger" @click="onDelAction">删除</el-button><el-button type="primary" @click="onSubmit">确定</el-button></div></el-form-item></el-col></el-row></el-form><div v-else :style="{ width: lineTextWidth + 'px' }" @click="reEditAction"><span class="top-view">{{ topText }}</span><span class="con-view">{{ conditionText }}</span><span class="val-view">{{ valueText }}</span></div><check-crf v-if="showCheck" @input="itemSelected" :inTreeQuery="true" :workSingle="true" /></div>
</template><script>// import { elForm, elFormItem, elInput, elSelect, elOption } from 'element-ui'//在这需要再次按需引入对应组件
import { getTextWidth, setData, removeNode, randomId } from "./fun"
import CheckCrf from '../crf/components/check-crf.vue'
import project from '../../api/project/project'export default {name: 'queryCondition',inject: ["getGraph", "getNode"],components: { CheckCrf },data() {return {showCheck: false,complete: false,form: {//1数值型条件 conditionForm为等于、不等于、大于、大于等于、小于、小于等于、为空、不为空//2日期条件 conditionForm为晚于、不晚于、早于、不早于、时间段内、时间段外、为空、不为空//3复选框 conditionForm为是、否//4其他类型 conditionForm为包含、不包含、等于、不等于、为空、不为空formType: 1,topForm: {label: '',value: ''},conditionForm: {label: '',value: ''},valueForm: {label: '',value: '',},//原始组件所有属性extra: {}},topFormOptions: [],lineTextWidth: 550,topText: '用户姓名',conditionText: '包含',valueText: 'dudu',renderKey: randomId(),valuesOptions: [],remoteLoading: false}},mounted() {const self = this;let node = this.getNode()const data = node.getData();if (data) {this.complete = data.completethis.form = data.formthis.topText = this.form.topForm.labelthis.conditionText = this.form.conditionForm.labelif (this.form.formType == 3) {this.valueText = this.form.valueForm.label}else {this.valueText = this.form.valueForm.value}}// 监听数据改变事件// node.on("change:data", ({ current }) => {//     debugger// });this.renderUI()},methods: {conditionFormChanged(e) {if (this.form.formType == 2) {//必须强制刷新一下对应的DOM,否则会出现日期选择框弹出位置错误或者无法弹出的问题this.renderKey = randomId()this.form.valueForm.value = ""}},searchKeysAction(query) {if (query !== '') {this.remoteLoading = true;project.getCrfKeys(query).then(res => {res.forEach(element => {element.formItemId = element.code});this.remoteLoading = falsethis.topFormOptions = res})} else {this.options = [];}},itemSelected(raw) {let e = raw.firstObject()let cp = e.componentlet label = cp.config.labellet fid = e.codethis.form.topForm.label = labelthis.form.topForm.value = fidthis.form.extra = eif (!this.topFormOptions.containsObject(fid)) {let p = { ...e, label: label, formItemId: fid }this.topFormOptions.addObject(p)}if (cp.typeId === 'INPUT') {this.form.formType = 1}else if (cp.typeId === 'DATE') {this.form.formType = 2}else if (cp.typeId === 'SELECT' || cp.typeId === 'CHECKBOX' || cp.typeId === 'RADIO') {this.form.formType = 3this.valuesOptions = cp.config.options}else {this.form.formType = 4}this.showCheck = false},renderUI() {let width = getTextWidth(this.topText + this.conditionText + this.valueText, 14, "Arial, Helvetica, sans-serif")this.lineTextWidth = width;this.lineTextWidth += 10;this.lineTextWidth += 20;},optionsList() {if (this.form.formType == 1) {let opList = [{ label: '包含', value: '11' },{ label: '等于', value: '7' },{ label: '不等于', value: '8' },{ label: '大于', value: '3' },{ label: '大于等于', value: '4' },{ label: '小于', value: '5' },{ label: '小于等于', value: '6' },{ label: '为空', value: '2' },{ label: '不为空', value: '1' }]return opList}else if (this.form.formType == 2) {let opList = [{ label: '等于', value: '7' },{ label: '不等于', value: '8' },{ label: '晚于', value: '5' },{ label: '不晚于', value: '4' },{ label: '早于', value: '3' },{ label: '不早于', value: '6' },{ label: '时间段内', value: '9' },{ label: '时间段外', value: '10' },{ label: '为空', value: '2' },{ label: '不为空', value: '1' }]return opList}else if (this.form.formType == 3) {let opList = [{ label: '等于', value: '7' },{ label: '不等于', value: '8' },]return opList}else {let opList = [{ label: '包含', value: '11' },{ label: '不包含', value: '12' },{ label: '等于', value: '7' },{ label: '不等于', value: '8' },{ label: '为空', value: '2' },{ label: '不为空', value: '1' }]return opList}},onSubmit() {let flabel = this.optionsList().filter(p => p.value == this.form.conditionForm.value).firstObject()?.labellet ext = this.topFormOptions.filter(p => p.formItemId == this.form.topForm.value)let topText = ext.firstObject()?.labellet vtext = this.form.valueForm.valuelet tipText = nullif (!topText || topText.length == 0) {tipText = '未选择条件字段'}else if (!flabel || flabel.length == 0) {tipText = '未选择条件关系'}else if (!vtext || vtext.length == 0) {tipText = '未选择条件对比值'}if (tipText) {this.$modal.msgError(tipText)}else {this.form.conditionForm.label = flabelthis.topText = topTextthis.conditionText = flabelif (this.form.formType == 3) {vtext = this.valuesOptions.filter(p => p.value == this.form.valueForm.value)[0].labelthis.form.valueForm.label = vtext}this.valueText = vtextthis.form.extra = ext.firstObject()this.complete = truelet node = this.getNode()const dataItem = {complete: this.complete,form: {...this.form}}let graphData = node.parentsetData(graphData, node.id, dataItem)this.renderUI()let data = {mapDbName: this.form.extra.mapDbName,mapTblName: this.form.extra.mapTblName,dataDbName: this.form.extra.dataDbName,dataTblName: this.form.extra.dataTblName,dataColName: this.form.extra.dataColName,fieldType: this.form.extra.fieldType,fieldSource: this.form.extra.fieldSource,code: this.form.topForm.value,operator: this.form.conditionForm.value,value: this.form.valueForm.value}let cv = parseInt(this.form.conditionForm.value)if (this.form.formType == 2 && ((cv == 9 || cv == 10))){data.start = this.form.valueForm.value[0].date2text("yyyy-MM-dd") + " 00:00:00"data.end = this.form.valueForm.value[1].date2text("yyyy-MM-dd") + " 23:59:59"}project.queryTreeAction(data).then(res => {})}},onDelAction() {let graph = this.getGraph()let node = this.getNode()this.$confirm('确定删除此条件?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then((cmd) => {if (cmd == 'confirm') {graph.removeNode(node.id)}})},reEditAction() {this.complete = false},checkBtnGroupClose() {this.showCheck = false}}
}
</script><style lang="scss" scoped>
.condition {padding: 0px 10px;height: 100%;background: white;border-radius: 6px;border: 1px solid #EFF4FF;display: flex;flex-direction: row;justify-content: center;align-items: center;
}.dy-view {min-width: 550px;background: #EFF4FF;border: 1px solid #5F95FF;
}.ny-view {width: auto;
}.flex-row {display: flex;flex-direction: row;justify-content: center;align-items: center;
}.top-view {white-space: nowrap;color: black;font-size: 14px;font-family: Arial, Helvetica, sans-serif;
}.con-view {color: gray;font-size: 14px;padding: 0px 5px;font-family: Arial, Helvetica, sans-serif;
}.val-view {color: black;font-size: 14px;font-family: Arial, Helvetica, sans-serif;
}.search-options {width: calc(100% - 34px);
}.search-icon {position: absolute;border-left: none;width: 32px;height: 32px;margin-left: -4px;background-color: #F5F7FA;
}::v-deep {.el-form-item--small {margin: 0px;vertical-align: middle !important;}.el-button--small {padding-left: 10px;padding-right: 10px;}.el-input-group__append {padding-right: 15px;}.el-range__close-icon {display: none;}.el-checkbox--small {height: auto !important;}
}
</style>

涉及到组件二

queryRelative.vue

<template><div class="condition dy-view flex-row"><div class="flex-row l-flex l-hover" style="position: relative;" :class="{ 'nl-flex': relative == 'or' }"><el-popover placement="bottom" ref="refPop" width="80" trigger="hover" class="h-100 flex-row"popper-class="pop-grid-view"><el-radio-group v-model="radio" @input="radioChanged"><el-radio :label="item.value" v-for="item in optionsList">{{ item.label }}</el-radio></el-radio-group><el-image slot="reference" style="width: 20px; height: 20px":src="require('@/assets/images/sameR.png')"></el-image></el-popover><el-image class="m-view" :src="require('@/assets/images/downArrow.png')"></el-image></div><div class="flex-row r-flex label-text" :class="{ 'nr-flex': relative == 'or' }" @click="relativeChanged">{{ relative == 'or' ? '或者' : '并且' }}</div></div>
</template><script>// import { elForm, elFormItem, elInput, elSelect, elOption } from 'element-ui'//在这需要再次按需引入对应组件
import { getTextWidth, setData, removeNode, randomId } from "./fun"export default {name: 'queryRelative',inject: ["getGraph", "getNode"],components: {},data() {return {radio: '1',relative: 'and',optionsList: [],}},mounted() {let node = this.getNode()const data = node.getData();this.relative = data.relativethis.optionsList = data.optionsthis.radio = data.defaultValue},methods: {radioChanged() {this.$refs['refPop'][0].doClose()},relativeChanged() {this.relative = this.relative == 'and' ? 'or' : 'and'let node = this.getNode()const dataItem = {relative:this.relative,defaultValue:this.radio}let graphData = node.parentsetData(graphData, node.id, dataItem)}}
}
</script><style lang="scss" scoped>
.condition {padding: 0px;height: 100%;border-radius: 5px;width: 80px;height: 40px;background-color: white;overflow: hidden;display: flex;flex-direction: row;justify-content: center;align-items: center;
}.flex-row {display: flex;flex-direction: row;justify-content: center;align-items: center;
}.l-flex {width: 35px;height: 100%;background-color: rgb(109, 162, 243);&:hover {background-color: rgb(129, 182, 255);}
}.r-flex {width: 45px;height: 100%;background-color: rgb(154, 188, 247);&:hover {background-color: rgb(129, 182, 255);}
}.nl-flex {background-color: rgb(41, 195, 193);&:hover {background-color: rgb(61, 215, 213);}
}.nr-flex {background-color: rgb(102, 213, 233);&:hover {background-color: rgb(61, 215, 213);}
}.label-text {color: white;font-size: 13px;
}.m-view {position: absolute;right: 3px;bottom: 3px;width: 6px;height: 6px;
}::v-deep {.el-form-item--small {margin: 0px;vertical-align: middle !important;}.el-button--small {padding-left: 10px;padding-right: 10px;}.el-input-group__append {padding-right: 15px;}.el-range__close-icon {display: none;}.el-checkbox--small {height: auto !important;}.el-radio {line-height: 1.5;}.el-radio__label {padding-left: 5px;}
}
</style><style lang="scss">
.pop-grid-view.el-popper {min-width: 90px;
}
</style>

 

相关文章:

VUE条件树查询 自定义条件节点

之前实现过的简单的条件树功能如下图&#xff1a; 经过最新客户需求确认&#xff0c;上述条件树还需要再次改造&#xff0c;以满足正常需要&#xff01; 最新暴改后的功能如下红框所示&#xff1a; 页面功能 主页面逻辑代码&#xff1a; <template><div class"…...

什么是打流,怎么用iperf3打流

什么是打流 在网络安全和黑灰产领域&#xff0c;“打流”具有不同的含义&#xff0c;常用于形容通过技术手段制造流量假象或发起流量攻击。 流量攻击&#xff08;DDoS&#xff09;中的“打流”&#xff1a; “打流”指向目标服务器或网络发起 大规模的数据请求&#xff0c;造…...

使用MySQL APT源在Linux上安装MySQL

全新安装MySQL的步骤 以下说明假定您的系统上尚未安装任何版本的MySQL&#xff08;无论是由Oracle还是其他方分发&#xff09; 添加MySQL的Apt源。 将MySQL的APT存储库添加到系统的软件存储库列表中。 1、转到MySQL APT存储库的下载页面MySQL :: Download MySQL APT Reposi…...

redux react-redux @reduxjs/toolkit

redux团队先后推出了redux、react-redux、reduxjs/toolkit&#xff0c;这三个库的api各有不同。本篇文章就来梳理一下当我们需要在项目中集成redux&#xff0c;从直接使用redux&#xff0c;到使用react-redux&#xff0c;再到react-redux和reduxjs/toolkit配合使用&#xff0c;…...

【偏好对齐】通过ORM直接推导出PRM

论文地址&#xff1a;https://arxiv.org/pdf/2412.01981 相关博客 【自然语言处理】【大模型】 ΨPO&#xff1a;一个理解人类偏好学习的统一理论框架 【强化学习】PPO&#xff1a;近端策略优化算法 【偏好对齐】PRM应该奖励单个步骤的正确性吗&#xff1f; 【偏好对齐】通过OR…...

Python与其他编程语言的区别是什么?

Python是一种广泛使用的高级编程语言&#xff0c;以其简洁的语法、强大的库支持和广泛的应用领域而著称。与其他编程语言相比&#xff0c;Python具有许多独特的特点和优势。以下将从多个方面详细探讨Python与其他编程语言的区别&#xff0c;并通过示例进行说明。 一、语法简洁…...

cuda11.6和对应的cudnn(windows)

因为每次不同的torch版本要下对应的cuda&#xff0c;这次刚好在Windows上下好了一个cuda11.6和对应的cudnn&#xff0c;直接放到网盘中&#xff0c;大家有需要对应版本的可以直接下载&#xff1a; 链接&#xff1a;https://pan.quark.cn/s/f153a53830d4 大家自取&#xff0c;c…...

24年无人机行业资讯 | 12.23-12.29

24年无人机行业资讯 | 12.23-12.29 1、 国家发改委新设低空经济司&#xff0c;助力低空经济规范发展2、商务部支持无人机民用国际贸易&#xff0c;强调出口管制与安全并重3、滨州高新区首架无人机成功下线4、 2025第九届世界无人机大会筹备推进会顺利召开5、2024年世界无人机竞…...

uniapp:微信小程序文本长按无法出现复制菜单

一、问题描述 在集成腾讯TUI后&#xff0c;为了能让聊天文本可以复制&#xff0c;对消息组件的样式进行修改&#xff0c;主要是移除下面的user-select属性限制&#xff1a; user-select: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms…...

qml Item详解

1、概述 Item是QML&#xff08;Qt Modeling Language&#xff09;的基础元素&#xff0c;所有其他可视化元素都继承自它。它代表了一个可视化的对象&#xff0c;虽然Item对象本身没有可视外观&#xff0c;但它定义了所有可视项之间通用的属性&#xff0c;比如位置、大小、旋转…...

【Java回顾】Day4 反射机制

反射机制 之前学过一部分&#xff0c;笔记在20250103Java包_网络编程.md里,这里在之前的笔记的基础上做一些补充。 反射&#xff1a;得到class对象后反向获取对象的各种信息。 包 Field 类或接口中的字段(成员变量)&#xff0c;动态访问和修改类的字段 模板 获取Class 对象 …...

【沉默的羔羊心理学】汉尼拔的“移情”游戏:操纵与理解的艺术,精神分析学视角下的角色互动

终极解读《沉默的羔羊》&#xff1a;弗洛伊德精神分析学视角下的深层剖析 关键词 沉默的羔羊弗洛伊德精神分析学角色心理意识与潜意识性别与身份 弗洛伊德精神分析学简介 弗洛伊德的精神分析学是心理学的一个重要分支&#xff0c;主要关注人类行为背后的无意识动机和冲突。…...

[深度学习] 大模型学习1-大语言模型基础知识

大语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;是一类基于Transformer架构的深度学习模型&#xff0c;主要用于处理与自然语言相关的各种任务。简单来说&#xff0c;当用户输入文本时&#xff0c;模型会生成相应的回复或结果。它能够完成许多任务&…...

如何解决数据库和缓存不一致的问题

目录 一、Cache-Aside模式&#xff08;旁路缓存模式&#xff09; 二、Write-Through模式&#xff08;写透缓存模式&#xff09; 三、Write-Behind模式&#xff08;写回缓存模式&#xff09; 四、先删除缓存再更新数据库&#xff08;不推荐&#xff0c;存在风险&#xff09;…...

剑指Offer|LCR 021. 删除链表的倒数第 N 个结点

LCR 021. 删除链表的倒数第 N 个结点 给定一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;head [1], n 1…...

【NX入门篇】

NX入门篇 一、UG NX 由来二、软件如何启动&#xff08;UG NX 12.0&#xff09;三、使用步骤四、常用命令 一、UG NX 由来 UG NX由来&#xff1a; 1969 年&#xff1a;UG 的开发始于美国麦道航空公司&#xff0c;基于 C 语言开发实现&#xff1b;1976 年&#xff1a;UG问世&am…...

ubuntu如何禁用 Snap 更新

.禁用 Snap 更新&#xff08;通过修改 snapd 配置&#xff09; 打开并编辑 /etc/apt/apt.conf.d/50unattended-upgrades文件。 这个文件控制自动更新的行为。 sudo vim /etc/apt/apt.conf.d/50unattended-upgrades 里面有一行将里面的auto改为false即可禁用更新&#xff1a;…...

Spring AI Alibaba-对话模型(Chat Model)

对话模型&#xff08;Chat Model&#xff09;接收一系列消息&#xff08;Message&#xff09;作为输入&#xff0c;与模型 LLM 服务进行交互&#xff0c;并接收返回的聊天消息&#xff08;Chat Message&#xff09;作为输出。相比于普通的程序输入&#xff0c;模型的输入与输出…...

HTML——79.代码快捷输入方式

!DOCTYPE html> <html><head><meta charset"UTF-8"><title>代码快捷输入方式</title></head><body><!--1.父子关系&#xff1a;--><!--div>p 加Tab键--><div><p></p></div><…...

李宏毅机器学习课程笔记01 | 1.Introduction of Machine/Deep Learning

笔记是在语雀上面做的&#xff0c;粘贴在CSND上可能存在格式错误 机器学习的本质就是借助机器寻找一个转换函数 根据函数的输出类型&#xff0c;可以将机器学习进行分类 regression 回归任务&#xff1a;函数输出时一个数值classification 分类任务&#xff1a;人类设定好选项…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...