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

求助文心一言帮我用antv x6开发一个直线审批流程设计页面Vue2.0

 之前使用DeepSeek协助开发过类似的页面,这是当时的页面效果:

        这次的客户是某乡的养殖工厂,销售只争取到了供应链模块的定制开发,因为涉及到新的领域,需要做的是新瓶装旧酒,给功能界面提升档次,以便给用户更好的体验,便于推广其他模块。我们决定采用antv框架重新设计模块中的图表与表格,流程审批设计页面当然还是由我来开发的。

开始尝试问询:

帮我把下面的代码用antv x6重写:
<template>
  <div class="approval-flow">
    <a-button type="primary" @click="addNode" style="margin-bottom: 20px">
      添加节点
    </a-button>
 
    <a-steps :current="null" direction="horizontal" class="custom-steps">
      <a-step v-for="(node, index) in nodes" :key="node.id">
        <template #title>
          <div class="node-card">
            <div class="card-header">
              <span>{

。。。。。。

        因为之前并没有使用过antv框架的经验,简直无从问起,索性直接要求将之前的步骤条+表单的页面重写成为x6流程图,结果当然是惨不忍睹,先后尝试了文心一言、豆包、DeepSeek以及360纳米的多种模式,这种提问当时下文心一言、豆包和DeepSeek的答案差不多,都是一个只有一张画布的界面,添加按钮不好使,DeepSeek还是一样的服务器繁忙好多次。360纳米的多种模式只有一个模式给出了包含代码的答案,但是也等的很漫长。
       总结这些答案发现了一点,就是x6的自定义节点和antd表单弹窗之间无法连贯,x6的节点种类繁多,新旧版本之间的注册节点方式有很大不同,导致代码千奇百怪。我需要的提问方式是把涉及到x6的节点的部分尽量的简化,得到一个x6简单节点+antd表单弹窗的代码,然后注册一个自定义节点加入到代码中。

提问文心一言3.5:

帮我用antv x6开发一个直线审批流程设计页面Vue2.0+antd+antv x6实现,节点的添加与编辑通过antd表单弹窗的形式实现,双击节点弹出编辑窗口,右键点击节点删除。

       因为提问的内容比较抽象,失败的可能性很大,我这次使用的是回答速度快的一言。第一次还是给出了vue3.0的代码,再次提交后给出了比较靠谱的答案,竟然直接运行成功,大大超出了我的预期:

<template> 
    <div> 
      <!-- 添加按钮 --> 
      <a-button @click="openAddModal">添加节点</a-button> 
      <!-- 保存按钮 --> 
      <a-button @click="saveProcess">保存流程</a-button> 
      <!-- X6画布容器 --> 
      <div ref="graphContainer" style="width: 100%; height: 800px; border: 1px solid #ccc;"></div> 
      <!-- 添加节点模态框 --> 
      <a-modal 
        :visible="addModalVisible" 
        title="添加节点" 
        @ok="handleAddOk" 
        @cancel="handleAddCancel" 
      > 
        <a-form :form="addForm"> 
          <a-form-item label="节点名称"> 
            <a-input v-decorator="[ 
              'name', 
              { 
                rules: [ 
                  { required: true, message: '请输入节点名称' } 
                ] 
              } 
            ]" /> 
          </a-form-item> 
          <a-form-item label="关联角色"> 
            <a-input v-decorator="[ 
              'role', 
              { 
                rules: [ 
                  { required: true, message: '请输入关联角色' } 
                ] 
              } 
            ]" /> 
          </a-form-item> 
        </a-form> 
      </a-modal> 
      <!-- 修改节点模态框 --> 
      <a-modal 
        :visible="editModalVisible" 
        title="修改节点" 
        @ok="handleEditOk" 
        @cancel="handleEditCancel" 
      > 
        <a-form :form="editForm"> 
          <a-form-item label="节点名称"> 
            <a-input v-decorator="[ 
              'name', 
              { 
                rules: [ 
                  { required: true, message: '请输入节点名称' } 
                ] 
              } 
            ]" /> 
          </a-form-item> 
          <a-form-item label="关联角色"> 
            <a-input v-decorator="[ 
              'role', 
              { 
                rules: [ 
                  { required: true, message: '请输入关联角色' } 
                ] 
              } 
            ]" /> 
          </a-form-item> 
        </a-form> 
      </a-modal> 
    </div> 
  </template> 
   
  <script> 

  import { Graph, Shape } from '@antv/x6'; 
   
  export default { 
    data() { 
      return { 
        graph: null, 
        addModalVisible: false, 
        addForm: this.$form.createForm(this),  
        editModalVisible: false, 
        editForm: this.$form.createForm(this),  
        currentNode: null, 
        nodes: [ 
          { id: 'start', name: '发起人', role: '发起人', x: 50, y: 200 } 
        ] 
      }; 
    }, 
    mounted() { 
      // 初始化X6图形 
      this.initGraph();  
      // 渲染节点 
      this.renderNodes();  
    }, 
    methods: { 
      initGraph() { 
        // 创建X6图形实例 
        this.graph  = new Graph({ 
          container: this.$refs.graphContainer,  
          grid: true, 
          connecting: { 
            snap: true 
          }, 
          interacting: { 
            nodeMovable: false 
          } 
        }); 
   
        // 监听节点点击事件 
        this.graph.on('node:click',  ({ node }) => { 
          this.openEditModal(node);  
        }); 
   
        // 监听节点右键事件 
        this.graph.on('node:contextmenu',  ({ node, e }) => { 
          if (node.id!==  'start') { 
            // 删除节点 
            if (confirm('确定要删除该节点吗?')) { 
              this.nodes  = this.nodes.filter(n  => n.id!==  node.id);  
              this.renderNodes();  
            } 
          } 
        }); 
      }, 
      renderNodes() { 
        // 清空现有图形 
        this.graph.clearCells();  
   
        // 依次添加节点并连线 
        for (let i = 0; i < this.nodes.length;  i++) { 
          const node = this.nodes[i];  
          const x6Node = new Shape.Rect({ 
            id: node.id,  
            x: node.x, 
            y: node.y, 
            width: 100, 
            height: 50, 
            label: `${node.name}\n${node.role}`,  
            attrs: { 
              body: { 
                fill: '#f5f5f5', 
                stroke: '#d9d9d9', 
                strokeWidth: 1 
              } 
            } 
          }); 
          this.graph.addNode(x6Node);  
   
          if (i > 0) { 
            const prevNode = this.nodes[i  - 1]; 
            const edge = new Shape.Edge({ 
              source: prevNode.id,  
              target: node.id  
            }); 
            this.graph.addEdge(edge);  
          } 
        } 
      }, 
      openAddModal() { 
        // 打开添加节点模态框 
        this.addModalVisible  = true; 
      }, 
      handleAddOk() { 
        // 处理添加节点确认 
        this.addForm.validateFields((err,  values) => { 
          if (!err) { 
            const lastNode = this.nodes[this.nodes.length  - 1]; 
            const newNode = { 
              id: `node-${Date.now()}`,  
              name: values.name,  
              role: values.role,  
              x: lastNode.x + 200, 
              y: lastNode.y 
            }; 
            this.nodes.push(newNode);  
            this.renderNodes();  
            this.addModalVisible  = false; 
            this.addForm.resetFields();  
          } 
        }); 
      }, 
      handleAddCancel() { 
        // 处理添加节点取消 
        this.addModalVisible  = false; 
        this.addForm.resetFields();  
      }, 
      openEditModal(node) { 
        // 打开修改节点模态框 
        this.currentNode  = this.nodes.find(n  => n.id  === node.id);  
        this.editForm.setFieldsValue({  
          name: this.currentNode.name,  
          role: this.currentNode.role  
        }); 
        this.editModalVisible  = true; 
      }, 
      handleEditOk() { 
        // 处理修改节点确认 
        this.editForm.validateFields((err,  values) => { 
          if (!err) { 
            this.currentNode.name  = values.name;  
            this.currentNode.role  = values.role;  
            this.renderNodes();  
            this.editModalVisible  = false; 
            this.editForm.resetFields();  
          } 
        }); 
      }, 
      handleEditCancel() { 
        // 处理修改节点取消 
        this.editModalVisible  = false; 
        this.editForm.resetFields();  
      }, 
      saveProcess() { 
        // 保存流程,这里可以添加保存到后端的逻辑 
        console.log(' 保存流程:', this.nodes);  
      } 
    } 
  }; 
  </script> 
   
  <style scoped> 
  /* 可根据需要添加自定义样式 */ 
  </style> 

运行效果:
1)初始界面

2)添加节点


3)删除节点,右键点击节点

有几个小问题
①我的提问中“添加与编辑通过antd表单弹窗的形式”这句导致一言给出代码中使用了两个表单来处理编辑与删除,这很好解决,参照之前版本的代码,去掉一个表单,然后通过node.id判断当前操作是编辑还是删除就可以了。
②表单中的角色使用的input而不是select,也是提问中没有声明的原因,这不影响,参照之前版本的代码,改一下就可以了。
③相比于上个版本的步骤条+卡片来说节点展示方式过于简单,需要自定义节点。

打开antv x6的图表示例,找到自定义节点,发现第一个例子就是我所需要的:
自定义节点 | X6

将代码中的节点替换为我的自定义节点就可以了,这是完善之后的代码:

<template> 
  <div> 
    <!-- 添加按钮 --> 
    <a-button @click="openEditModal">添加节点</a-button> 
    <!-- 保存按钮 --> 
    <a-button @click="saveProcess">保存流程</a-button> 
    <!-- X6画布容器 --> 
    <div ref="graphContainer" style="width: 100%; height: 800px; border: 1px solid #ccc;"></div> 
    <!-- 修改节点模态框 --> 
    <a-modal 
      :visible="editModalVisible" 
      :title="title" 
      @ok="handleEditOk" 
      @cancel="handleEditCancel" 
    > 
      <a-form :form="editForm"> 
        <a-form-item label="节点名称"> 
          <a-input v-decorator="[ 
            'name', 
            { 
              rules: [ 
                { required: true, message: '请输入节点名称' } 
              ] 
            } 
          ]" /> 
        </a-form-item> 
        <a-form-item label="关联角色">
          <a-select @change="handleRoleChange" v-decorator="[ 
            'role', 
            { 
              rules: [ 
                { required: true, message: '请输入关联角色' } 
              ] 
            } 
          ]" placeholder="请选择角色">
            <a-select-option
              v-for="role in roles"
              :key="role.value"
              :value="role.value"
            >
              {{ role.label }}
            </a-select-option>
          </a-select>
        </a-form-item> 
      </a-form> 
    </a-modal> 
  </div> 
</template> 
 
<script> 

import { Graph, Shape } from '@antv/x6'; 

Graph.registerNode(
  'custom-node',
  {
    width: 200,
    height: 60,
    attrs: {
      body: {
        stroke: '#5F95FF',
        strokeWidth: 1,
        fill: 'rgba(95,149,255,0.05)',
        refWidth: 1,
        refHeight: 1,
      },
      image: {
        'xlink:href': require('../assets/shenqingren.png'),
        width: 16,
        height: 16,
        x: 12,
        y: 12,
      },
      title: {
        text: '123',
        refX: 40,
        refY: 14,
        fill: 'rgba(0,0,0,0.85)',
        fontSize: 12,
        'text-anchor': 'start',
      },
      text: {
        text: '456',
        refX: 40,
        refY: 38,
        fontSize: 12,
        fill: 'rgba(0,0,0,0.6)',
        'text-anchor': 'start',
      },
    },
    markup: [
      {
        tagName: 'rect',
        selector: 'body',
      },
      {
        tagName: 'image',
        selector: 'image',
      },
      {
        tagName: 'text',
        selector: 'title',
      },
      {
        tagName: 'text',
        selector: 'text',
      },
    ],
  },
  true,
)

export default { 
  data() { 
    return { 
      graph: null, 
      editModalVisible: false, 
      editForm: this.$form.createForm(this),  
      currentNode: {},
      title: '修改节点',
      roles: [
        { label: "发起人角色", value: "applicant", icon: require('../assets/shenqingren.png') },
        { label: "部门主管", value: "manager", icon: require('../assets/bumenshenhe.png') },
        { label: "财务", value: "finance", icon: require('../assets/caiwushenhe.png') },
        { label: "总经理", value: "ceo", icon: require('../assets/zongjinglishenhe.png') },
      ],
      selectedIcon: '', // 用于存储选中的角色的图标
      nodes: [ 
        { id: 'start', name: '发起人', role: 'applicant', icon: require('../assets/shenqingren.png'), x: 100, y: 50 } 
      ] 
    }; 
  }, 
  mounted() { 
    // 初始化X6图形 
    this.initGraph();  
    // 渲染节点 
    this.renderNodes();
    
    this.editForm = this.$form.createForm(this);
  }, 
  methods: { 
    initGraph() { 
      // 创建X6图形实例 
      this.graph  = new Graph({ 
        container: this.$refs.graphContainer,  
        grid: true, 
        connecting: { 
          snap: true 
        }, 
        interacting: { 
          nodeMovable: false 
        } 
      }); 
 
      // 监听节点点击事件 
      this.graph.on('node:dblclick',  ({ node }) => {
        this.openEditModal(node);  
      }); 
 
      // 监听节点右键事件 
      this.graph.on('node:contextmenu',  ({ node, e }) => { 
        console.log(e)
        if (node.id ===  'start') { 
          return
        } 

        // 删除节点 
        if (confirm('确定要删除该节点吗?')) { 
            this.nodes  = this.nodes.filter(n  => n.id!==  node.id);  
            this.renderNodes();  
        } 
      }); 
    }, 
    renderNodes() { 
      // 清空现有图形 
      this.graph.clearCells();  
 
      // 依次添加节点并连线 
      for (let i = 0; i < this.nodes.length;  i++) { 
        const node = this.nodes[i]

        this.graph.addNode({
          id: node.id,
          x: node.x,
          y: node.y,
          shape: 'custom-node',
          attrs: {
            title: {
              text: `${node.name}`,  // 直接设置 text 属性
            },
            text: {
              text: `${node.role}`,  // 直接设置 text 属性
            },
            image: {
              'xlink:href': node.icon, // 使用节点的 icon 属性
              width: 16,
              height: 16,
              x: 12,
              y: 12,
            },
          },
        })
 
        if (i > 0) { 
          const prevNode = this.nodes[i  - 1]; 
          const edge = new Shape.Edge({ 
            source: prevNode.id,  
            target: node.id  
          }); 
          this.graph.addEdge(edge);  
        } 
      } 
    }, 
    handleRoleChange(value) {
      // 当用户选择角色时,根据值查找角色对象
      this.selectedIcon = this.roles.find(role => role.value === value).icon;
    },
    openEditModal(node) { 
      // 打开修改节点模态框 
      this.editModalVisible  = true; 
      this.title = '修改节点';
      if(!node.id){
        this.title = '添加节点';
        this.currentNode = {};
        return
      }

      this.currentNode  = this.nodes.find(n  => n.id  === node.id);  
      this.selectedIcon = this.currentNode.icon

      this.$nextTick(() => {
        this.editForm.setFieldsValue({
          name: this.currentNode.name,
          role: this.currentNode.role
        });
      });
      
    }, 
    handleEditOk() { 
      // 处理修改节点确认 
      this.editForm.validateFields((err,  values) => { 
        if (err) { 
          return
        } 

        if(this.currentNode.id){
          this.currentNode.name = values.name;  
          this.currentNode.role = values.role;
          this.currentNode.icon = this.selectedIcon;  
          this.renderNodes();  
          this.editModalVisible  = false; 
          this.editForm.resetFields();
        }
        else{ 
          const lastNode = this.nodes[this.nodes.length  - 1]; 
          const newNode = { 
            id: `node-${Date.now()}`,  
            name: values.name,  
            role: values.role,
            icon: this.selectedIcon,  
            x: lastNode.x + 300, 
            y: lastNode.y 
          }; 
          this.nodes.push(newNode); 
        }
        this.renderNodes();  
        this.editModalVisible  = false; 
        this.editForm.resetFields();
      }); 
    }, 
    handleEditCancel() { 
      // 处理修改节点取消 
      this.editModalVisible  = false; 
      this.editForm.resetFields();  
    }, 
    saveProcess() { 
      // 保存流程,这里可以添加保存到后端的逻辑 
      console.log(' 保存流程:', this.nodes);  
    } 
  } 
}; 
</script> 
 
<style scoped> 
/* 可根据需要添加自定义样式 */ 
</style> 

运行效果:

1)点击按钮添加节点



2)双击节点弹出编辑

3)右击节点删除


http://www.kler.cn/a/547016.html

相关文章:

  • 数据结构:哈夫曼树
  • Ubuntu 上安装 MySQL 8.0.22
  • Redis常用的五种数据结构详解
  • #渗透测试#批量漏洞挖掘#AJ-Report开源数据大屏存在远程命令执行漏洞
  • vue3 怎么自动全局注册某个目录下的所有 vue 和 tsx 组件
  • ESP32无线Wi-Fi蓝牙方案,设备智能连接控制,物联网通信应用
  • Node.js 中的 Event 模块详解
  • SpringCloud - Seata 分布式事务
  • 2月14日笔记
  • Java中如何高效地合并多个对象的List数据:方法与案例解析!
  • 2025年AI免费大战:从DeepSeek到GPT-5的商业逻辑与行业变革
  • 数据库与表的基本操作
  • 在香橙派5 NPU上使用Yolov5
  • 轮子项目--消息队列的实现(3)
  • 如何优化React应用的性能?
  • 常见的 Web 攻击方式有哪些,如何防御?
  • 技术评测:MaxCompute MaxFrame——阿里云自研分布式计算框架的Python编程接口
  • 每日温度问题:如何高效解决?
  • SAP-ABAP:SAP的Screen Layout Designer屏幕布局设计器详解及示例
  • 【后端面试总结】什么是堆,什么是栈