From 0db8c9b94a9ac655549d5eba5c2a6c92ac386c06 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期四, 08 十月 2026 11:20:56 +0800
Subject: [PATCH] 提交最新代码

---
 culture/src/views/pedigree-chart/add.vue |  778 +++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 615 insertions(+), 163 deletions(-)

diff --git a/culture/src/views/pedigree-chart/add.vue b/culture/src/views/pedigree-chart/add.vue
index 5f50548..42bf693 100644
--- a/culture/src/views/pedigree-chart/add.vue
+++ b/culture/src/views/pedigree-chart/add.vue
@@ -1,64 +1,72 @@
 <template>
   <div>
-    <el-form
-      :model="form"
-      :rules="rules"
-      ref="pedigreeForm"
-      label-position="top"
-      class="strain-form"
-    >
+    <div class="header-title" style="width: 100%;">
+      <div class="header-title-left">
+        <img src="@/assets/public/headercard.png" />
+        <div>所属项目组</div>
+      </div>
+      <div class="header-title-right">
+        <el-button @click="showChoose = true" :disabled="!!$route.query.id" class="el-icon-circle-plus-outline" type="primary">
+          选择项目组</el-button>
+      </div>
+    </div>
+    <Table :height="null" :queryForm="queryForm" :total="0" :data="projectData" style="margin-bottom: 20px">
+      <template>
+        <el-table-column prop="teamName" label="项目组名称" />
+        <el-table-column prop="personCharge" label="项目负责人" />
+        <el-table-column prop="staff" label="项目组成员" />
+        <el-table-column prop="createTime" label="创建时间" />
+      </template>
+    </Table>
+    <el-form :model="form" :rules="rules" ref="pedigreeForm" label-position="top" class="strain-form">
       <div class="card">
         <div class="form-items-row">
           <el-form-item label="菌种源" required>
             <div class="flex-row">
               <div class="input-wrapper">
                 <el-form-item prop="strainSourceStart" style="margin-bottom: 0">
-                  <el-input
-                    v-model="form.strainSourceStart"
-                    placeholder="请输入"
-                    class="fixed-width-input"
-                  ></el-input>
+                  <el-input v-model="form.strainSourceStart" placeholder="请输入" :disabled="!!$route.query.id"
+                    class="fixed-width-input"></el-input>
                 </el-form-item>
               </div>
               <span class="form-text">代—</span>
               <div class="input-wrapper">
                 <el-form-item prop="strainSourceEnd" style="margin-bottom: 0">
-                  <el-input
-                    v-model="form.strainSourceEnd"
-                    placeholder="请输入"
-                    class="fixed-width-input"
-                  ></el-input>
+                  <el-input v-model="form.strainSourceEnd" placeholder="请输入" :disabled="!!$route.query.id"
+                    class="fixed-width-input"></el-input>
                 </el-form-item>
               </div>
               <span class="form-text">细胞库</span>
             </div>
           </el-form-item>
           <el-form-item label="传代菌种编号" prop="strainCode" required>
-            <el-input
-              v-model="form.strainCode"
-              placeholder="请输入"
-              class="fixed-width-input"
-            ></el-input>
+            <el-input v-model="form.strainCode" placeholder="请输入" :disabled="!!$route.query.id"
+              class="fixed-width-input"></el-input>
           </el-form-item>
           <el-form-item label="传代菌种名称" prop="strainName" required>
-            <el-input
-              v-model="form.strainName"
-              placeholder="请输入"
-              class="fixed-width-input"
-            ></el-input>
+            <el-input v-model="form.strainName" placeholder="请输入" :disabled="!!$route.query.id"
+              class="fixed-width-input"></el-input>
           </el-form-item>
         </div>
       </div>
-      <div class="card" style="margin-top: 30px; display: block">
-        <Table
-          :height="null"
-          :total="total"
-          :data="tableData"
-          :queryForm="queryForm"
-          @handleCurrentChange="handleCurrentChange"
-          @handleSizeChange="handleSizeChange"
-        >
-          <el-table-column label="菌种实验员" prop="experimenter" />
+      <div class="card" v-if="roleType != 4" style="margin-top: 30px; display: block">
+        <div class="title" style="padding: 25px 0">待确认传代计划数</div>
+        <Table :height="null" :total="newTotal" :data="newTableData" :queryForm="newQueryForm"
+          @handleCurrentChange="handleNewCurrentChange" @handleSizeChange="handleNewSizeChange">
+          <el-table-column label="菌种工程师" prop="createBy" />
+          <el-table-column label="菌种编号" prop="strainCode" />
+          <el-table-column label="菌种名称" prop="strainName" />
+          <el-table-column label="传代计划数量" prop="generationCount" />
+          <el-table-column label="操作" v-if="roleType == 2">
+            <template #default="{ row }">
+              <el-button type="text" @click="handleNewConfirm(row)">确认</el-button>
+            </template>
+          </el-table-column>
+        </Table>
+        <div class="title" style="padding: 25px 0">待确认入库菌种列表</div>
+        <Table :height="null" :total="total" :data="tableData" :queryForm="queryForm"
+          @handleCurrentChange="handleCurrentChange" @handleSizeChange="handleSizeChange">
+          <el-table-column label="菌种工程师" prop="experimenter" />
           <el-table-column label="菌种编号" prop="strainCode" />
           <el-table-column label="菌种名称" prop="strainName" />
           <el-table-column label="保存/废弃">
@@ -66,12 +74,10 @@
               {{ row.status === 1 ? "保存" : "废弃" }}
             </template>
           </el-table-column>
-          <el-table-column label="菌种保存/废弃时间" prop="storageTime" />
-          <el-table-column label="操作">
+          <el-table-column label="菌种入库时间/菌种废弃时间" prop="createTime" />
+          <el-table-column v-if="roleType == 2" label="操作">
             <template #default="{ row }">
-              <el-button type="text" @click="handleConfirm(row)"
-                >确认入库</el-button
-              >
+              <el-button type="text" @click="handleConfirm(row)">确认入库</el-button>
             </template>
           </el-table-column>
         </Table>
@@ -80,26 +86,25 @@
         <div class="header">
           <div class="title">菌种传代生产谱系图</div>
           <div class="option-btn">
-            <el-button type="primary" class="el-icon-plus" @click="addNode">
-              新增</el-button
-            >
-            
-            <el-button type="primary" @click="setGenerationPlan"
-              >设置传代计划数</el-button
-            >
+            <el-button type="primary" v-if="!isReadOnly && (roleType == 3 || roleType == 1)" class="el-icon-plus" @click="addNode" :disabled="editBoolean">
+              新增</el-button>
+
+            <el-button type="primary" v-if="!isReadOnly && (roleType == 3 || roleType == 1)"
+              @click="setGenerationPlan" :disabled="editBoolean">设置传代计划数</el-button>
             <el-button type="primary" @click="showDetail">详情</el-button>
-            <el-button type="primary" @click="handleEdit">编辑</el-button>
-            <el-button type="primary" @click="handleDelete">删除</el-button>
+            <el-button type="primary" @click="handleEdit" v-if="!isReadOnly && (roleType == 1 || roleType == 3)" :disabled="editBoolean">编辑</el-button>
+            <el-button type="primary" @click="handleDelete" v-if="!isReadOnly && (roleType == 1 || roleType == 3)" :disabled="editBoolean">删除</el-button>
           </div>
         </div>
 
         <div class="strain-flow-chart">
-          <div id="mountNode"></div>
+          <div ref="mountNode" class="mount-node"></div>
         </div>
-          
-          <el-button type="primary" v-if="!$route.query.id" @click="handleSubmit" style="width: 150px"
-          >保存</el-button
-        >
+        <!-- v-if="!$route.query.id || (roleType == 1 && $route.query.id)" -->
+        <div v-if="!isReadOnly && (roleType == 1 || roleType == 3)">
+          <el-button type="primary" @click="handleSubmit('1')" style="width: 150px" :disabled="editBoolean">保存</el-button>
+          <el-button type="primary" @click="handleSubmit('2')" style="width: 150px; margin-left: 20px" :disabled="editBoolean">提交</el-button>
+        </div>
       </div>
       <div class="end-btn">
         <!-- <el-button @click="handleDraft">存草稿</el-button>
@@ -107,22 +112,20 @@
       </div>
     </el-form>
 
-    <ParentForm ref="parentForm" @addNodeSign="addNodeSign" />
-    <PlanForm ref="planForm" @addNodeSign="addNodeSign" />
-    <AddSublevelForm ref="addSublevelForm" @addNodeSign="addNodeSign" />
-    <AddSublevelPlan ref="addSublevelPlan" @addNodeSign="addNodeSign" />
-    <ConfirmStorageDialog
-      name="接种操作人签字"
-      :visible.sync="confirmStorageDialogVisible"
-      @confirm="handleSignatureConfirm"
-    />
+    <ParentForm :key="pageInstanceKey" ref="parentForm" @addNodeSign="addNodeSign" />
+    <PlanForm :key="pageInstanceKey" ref="planForm" @addNodeSign="addNodeSign" />
+    <AddSublevelForm :key="pageInstanceKey" ref="addSublevelForm" @addNodeSign="addNodeSign" />
+    <AddSublevelPlan :key="pageInstanceKey" ref="addSublevelPlan" @addNodeSign="addNodeSign" />
+    <ConfirmStorageDialog :key="`signature-${pageInstanceKey}`" name="接种操作人签字" :visible.sync="confirmStorageDialogVisible"
+      @confirm="handleSignatureConfirm" />
     <!-- 菌种工程师 -->
-    <ConfirmStorageDialog
-      name="菌种保藏人签字"
-      text="是否确认该项菌种信息入库"
-      :visible.sync="storageVisible"
-      @confirm="handleSignatureConfirm1"
-    />
+    <ConfirmStorageDialog :key="`storage-${pageInstanceKey}`" name="菌种保藏人签字" text="是否确认该项菌种信息入库" :visible.sync="storageVisible"
+      @confirm="handleSignatureConfirm1" />
+
+    <!-- 传代数审批 -->
+    <ApprovalCount :key="`approval-${pageInstanceKey}`" ref="approvalCount" @addNodeSign="sureApprovalCountSign" />
+
+    <chooseProject :key="`project-${pageInstanceKey}`" @submit="getProjectData" :show="showChoose" @close="showChoose = false"></chooseProject>
   </div>
 </template>
 
@@ -133,27 +136,37 @@
 import AddSublevelForm from "./components/AddSublevelForm.vue";
 import AddSublevelPlan from "./components/AddSublevelPlan.vue";
 import ConfirmStorageDialog from "@/components/confirm-storage-dialog";
+import ApprovalCount from "./progenitorComponents/approvalCount.vue";
 import {
   add,
   getDetail,
+  addCount,
   addProgenitorChild,
   addProgenitor,
   pageListDetail,
   confirmStorage,
   deleteNode,
   updateChild,
+  edit,
+  confirmCount,
+  pageListCountDetail
 } from "./service";
+import ChooseProject from "@/components/chooseProject/index.vue";
 export default {
   name: "AddPedigree",
   components: {
+    ChooseProject,
     ParentForm,
     PlanForm,
     AddSublevelForm,
     AddSublevelPlan,
     ConfirmStorageDialog,
+    ApprovalCount,
   },
   data() {
     return {
+      showChoose: false,
+      projectData: [], // 存储选中的项目组数据
       queryForm: {
         pageSize: 10,
         pageNum: 1,
@@ -198,13 +211,33 @@
       nodeData: {},
       nodeType: "", //1母代 2计划数 3子孙代
       tableData: [],
+      cacheData: null,  // 👈 添加这一行
+      activeRouteKey: "",
+      graphLoadId: 0,
+      pageInstanceKey: 0,
       confirmStorageDialogVisible: false,
       storageVisible: false,
+      editBoolean: false,
       treeData: [],
       total: 0,
+      roleType: JSON.parse(sessionStorage.getItem("userInfo")).roleType || 1, // 1.超级管理员 2.审批人 3.工程师 4.实验员
+
+      // 新增2.0
+      nodeTreeStatus: 1, //1.未提交 2.已提交
+      newTotal: 0,
+      newCurrent: 1,
+      newSize: 10,
+      newTableData: [],
+      newQueryForm: {
+        pageSize: 10,
+        pageNum: 1,
+      },
     };
   },
   computed: {
+    isReadOnly() {
+      return this.$route.path.includes('detail') || this.$route.query.mode === 'detail';
+    },
     canAddNode() {
       // 如果没有节点,可以新增母代
       if (this.graphData.nodes.length === 0) {
@@ -218,39 +251,198 @@
     },
   },
   mounted() {
-    this.initGraph();
-    this.initEvents();
+    this.resetMountNode();
   },
-  created() {
+  deactivated() {
+    // 缓存数据
+    this.cacheData = {
+      form: JSON.parse(JSON.stringify(this.form)),
+      graphData: JSON.parse(JSON.stringify(this.graphData)),
+      nodeCount: this.nodeCount,
+      selectedNode: this.selectedNode ? JSON.parse(JSON.stringify(this.selectedNode)) : null,
+      tableData: JSON.parse(JSON.stringify(this.tableData)),
+      newTableData: JSON.parse(JSON.stringify(this.newTableData)),
+      total: this.total,
+      newTotal: this.newTotal,
+      projectData: JSON.parse(JSON.stringify(this.projectData)),
+      treeData: JSON.parse(JSON.stringify(this.treeData)),
+      nodeTreeStatus: this.nodeTreeStatus,
+      routeKey: this.activeRouteKey
+    };
+  },
+  activated() {
+    if (this.cacheData && this.cacheData.routeKey === this.$route.fullPath) {
+      // 恢复数据
+      this.form = JSON.parse(JSON.stringify(this.cacheData.form));
+      this.graphData = JSON.parse(JSON.stringify(this.cacheData.graphData));
+      this.nodeCount = this.cacheData.nodeCount;
+      this.selectedNode = this.cacheData.selectedNode;
+      this.tableData = this.cacheData.tableData || [];
+      this.newTableData = this.cacheData.newTableData || [];
+      this.total = this.cacheData.total || 0;
+      this.newTotal = this.cacheData.newTotal || 0;
+      this.projectData = this.cacheData.projectData || [];
+      this.treeData = this.cacheData.treeData || [];
+      this.nodeTreeStatus = this.cacheData.nodeTreeStatus || 1;
+
+      // 更新图表
+      this.resetMountNode();
+      if (this.graphData.nodes.length > 0) {
+        this.updateGraphData();
+      }
+      return;
+    }
+    this.cacheData = null;
     if (this.$route.query.id) {
       this.reloadData();
+    } else {
+      this.resetPageState();
+    }
+    if (this.$route.query.status !== undefined && this.$route.query.status != 1 && this.roleType != 1){
+      this.editBoolean = true
+    }else {
+      this.editBoolean = false
+    }
+  },
+  watch: {
+    '$route': {
+      immediate: true,
+      handler(to) {
+        if (!["AddPedigree", "DetailPedigree"].includes(to.name)) {
+          return;
+        }
+        console.log('变动');
+        const routeKey = to.fullPath;
+        const routeChanged = this.activeRouteKey && this.activeRouteKey !== routeKey;
+        this.activeRouteKey = routeKey;
+        if (routeChanged || !to.query.id) {
+          this.cacheData = null;
+          this.resetPageState();
+        }
+        if (to.query.id) {
+          this.reloadData();
+        }
+
+        this.editBoolean = this.shouldDisableEditing(to.query);
+      }
     }
   },
   beforeDestroy() {
-    this.graph?.destroy();
-    window.removeEventListener("resize", this.handleResize);
+    this.destroyGraph();
   },
   methods: {
+    shouldDisableEditing(query = this.$route.query) {
+      const status = query && query.status;
+      return Number(this.roleType) !== 1
+          && status !== undefined
+          && status !== null
+          && status !== ""
+          && Number(status) !== 1;
+    },
+    destroyGraph() {
+      window.removeEventListener("resize", this.handleResize);
+      if (this.graph && !this.graph.get("destroyed")) {
+        this.graph.destroy();
+      }
+      this.graph = null;
+
+      const container = this.$refs.mountNode;
+      if (container) {
+        while (container.firstChild) {
+          container.removeChild(container.firstChild);
+        }
+      }
+    },
+    resetMountNode() {
+      this.destroyGraph();
+      if (!this.$refs.mountNode) return;
+      this.initGraph();
+      this.initEvents();
+    },
+    resetPageState() {
+      this.pageInstanceKey += 1;
+      this.form = {
+        strainSourceStart: "",
+        strainSourceEnd: "",
+        cellBank: "",
+        strainCode: "",
+        strainName: "",
+        remarks: "",
+      };
+      this.projectData = [];
+      this.tableData = [];
+      this.newTableData = [];
+      this.total = 0;
+      this.current = 1;
+      this.size = 10;
+      this.newTotal = 0;
+      this.newCurrent = 1;
+      this.newSize = 10;
+      this.queryForm = { pageSize: 10, pageNum: 1 };
+      this.newQueryForm = { pageSize: 10, pageNum: 1 };
+      this.showChoose = false;
+      this.dialogVisible = false;
+      this.confirmStorageDialogVisible = false;
+      this.storageVisible = false;
+      this.nodeData = {};
+      this.nodeType = "";
+      this.isAddingNode = false;
+      this.showDiscarded = false;
+      this.nodeTreeStatus = 1;
+      this.editBoolean = this.shouldDisableEditing();
+      this.resetGraphData();
+      this.$nextTick(() => {
+        this.$refs.pedigreeForm && this.$refs.pedigreeForm.clearValidate();
+      });
+    },
+    resetGraphData() {
+      this.graphLoadId += 1;
+      this.graphData = {
+        nodes: [],
+        edges: [],
+      };
+      this.treeData = [];
+      this.selectedNode = null;
+      this.nodeCount = 0;
+
+      if (this.graph) {
+        this.graph.changeData({ nodes: [], edges: [] });
+        this.graph.render();
+      }
+    },
+    getProjectData(data) {
+      this.projectData = [data]; // 将选中的项目组数据存储到数组中
+      this.showChoose = false;
+      this.form.projectId = this.projectData[0].id;
+    },
     handleEdit() {
       if (!this.selectedNode) {
         this.$message.warning("请先选择节点");
         return;
       }
+      if (
+        this.selectedNode &&
+        this.selectedNode.data &&
+        this.selectedNode.data.codeStatus != null &&
+        this.selectedNode.data.codeStatus == 2
+      ) {
+        this.$message.warning("谱系图已提交,不能编辑");
+        return
+      }
       const nodeModel = this.selectedNode;
-      console.log(nodeModel);
-      
+
       if (nodeModel.label === "母代") {
         this.$refs.parentForm.openInitData({
           strainSourceStart: this.form.strainSourceStart,
           strainSourceEnd: this.form.strainSourceEnd,
           ...nodeModel.data,
-          status: "edit",
+          formStatus: "edit",
         });
       } else if (nodeModel.label === "子代" || nodeModel.label === "孙代") {
         this.dialogTitle = `${nodeModel.label}详情`;
         this.$refs.addSublevelForm.openInitData({
           strainCode1: this.form.strainCode,
-            strainName1: this.form.strainName,
+          strainName1: this.form.strainName,
           title: `编辑${nodeModel.label}`,
           form: { ...nodeModel.data },
           formStatus: "edit",
@@ -261,12 +453,14 @@
         );
         if (this.graphData.nodes[nodeIndex - 1].label === "子代") {
           this.$refs.addSublevelPlan.openInitData({
+            ...nodeModel.data,
             strainSourceStart: this.form.strainSourceStart,
             strainCode1: this.form.strainCode,
             strainName1: this.form.strainName,
             strainSourceEnd: this.form.strainSourceEnd,
             confirmTime: this.form.confirmTime,
             parentId: nodeModel.id,
+            generationCount: nodeModel.data.generationCount || nodeModel.planCount,
             formStatus: "edit",
           });
         } else {
@@ -276,7 +470,8 @@
             strainCode1: this.form.strainCode,
             strainName1: this.form.strainName,
             ...nodeModel.data,
-            status: "edit",
+            generationCount: nodeModel.data.generationCount || nodeModel.planCount,
+            formStatus: "edit",
           });
         }
       }
@@ -286,18 +481,84 @@
         this.$message.warning("请先选择节点");
         return;
       }
+      if (
+        this.selectedNode &&
+        this.selectedNode.data &&
+        this.selectedNode.data.codeStatus != null &&
+        this.selectedNode.data.codeStatus == 2
+      ) {
+        this.$message.warning("谱系图已提交,不能删除");
+        return
+      }
+
       this.$confirm("确定删除该节点吗?", "提示", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
         type: "warning",
       }).then(() => {
-        deleteNode({ id: this.selectedNode.id }).then((res) => {
-          if (res.code == 200) {
-            this.$message.success("删除成功");
-            this.reloadData();
-          }
-        });
+        // 判断是新增模式还是编辑模式
+        if (!this.$route.query.id) {
+          // 新增模式:前端直接删除节点
+          this.deleteNodeFromGraph(this.selectedNode.nodeId);
+          this.$message.success("删除成功");
+        } else {
+          // 编辑模式:调用后端删除接口
+          deleteNode({ id: this.selectedNode.id }).then((res) => {
+            if (res.code == 200) {
+              this.$message.success("删除成功");
+              this.reloadData();
+            }
+          });
+        }
       });
+    },
+
+    // 前端删除节点方法
+    deleteNodeFromGraph(nodeId) {
+      // 找到要删除的节点
+      const nodeIndex = this.graphData.nodes.findIndex(n => n.nodeId === nodeId);
+      if (nodeIndex === -1) {
+        return;
+      }
+
+      // 递归收集所有需要删除的节点ID(包括子节点)
+      const collectNodeIds = (currentNodeId) => {
+        const nodeIds = [currentNodeId];
+        const childEdges = this.graphData.edges.filter(e => e.source === currentNodeId);
+        childEdges.forEach(edge => {
+          nodeIds.push(...collectNodeIds(edge.target));
+        });
+        return nodeIds;
+      };
+
+      const nodeIdsToDelete = collectNodeIds(nodeId);
+
+      // 删除所有相关的边
+      this.graphData.edges = this.graphData.edges.filter(edge => {
+        return !nodeIdsToDelete.includes(edge.source) && !nodeIdsToDelete.includes(edge.target);
+      });
+
+      // 删除所有相关的节点
+      this.graphData.nodes = this.graphData.nodes.filter(node => {
+        return !nodeIdsToDelete.includes(node.nodeId);
+      });
+
+      // 如果删除的节点的父节点是传代计划数,需要更新其当前数量
+      const parentEdge = this.graphData.edges.find(e => e.target === nodeId);
+      if (parentEdge) {
+        const parentNode = this.graphData.nodes.find(n => n.nodeId === parentEdge.source);
+        if (parentNode && parentNode.label === '传代计划数') {
+          // 重新计算当前数量
+          const childCount = this.graphData.edges.filter(e => e.source === parentNode.nodeId).length;
+          parentNode.currentCount = childCount;
+        }
+      }
+
+      // 清空选中节点
+      this.selectedNode = null;
+
+      // 更新图表显示
+      this.updateGraphData();
     },
     handleConfirm(row) {
       this.comfirmId = row.id;
@@ -349,11 +610,59 @@
         this.$message.error("数据加载失败");
       }
     },
+    handleNewConfirm(row) {
+      console.log("row row", row);
+      this.$refs.approvalCount.openInitData(row);
+    },
+    // 处理每页显示数量变化
+    handleNewSizeChange(val) {
+      this.newSize = val;
+      this.newQueryForm.pageSize = val;
+      this.getNewList();
+    },
+
+    // 处理页码变化
+    handleNewCurrentChange(val) {
+      this.newCurrent = val;
+      this.newQueryForm.pageNum = val;
+      this.getNewList();
+    },
+    async getNewList() {
+      try {
+        // 获取列表数据
+        const listRes = await pageListCountDetail({
+          id: this.$route.query.id,
+          current: this.current,
+          size: this.size,
+        });
+        console.log("待确认传代计划数 待确认传代计划数", listRes);
+        if (listRes.code === 200) {
+          this.newTableData = listRes.data.records;
+          this.newTotal = listRes.data.total;
+          this.newCurrent = listRes.data.current;
+          this.newSize = listRes.data.size;
+        }
+
+        // ... 其他现有的 reloadData 代码 ...
+      } catch (error) {
+        console.error("Failed to reload data:", error);
+        this.$message.error("数据加载失败");
+      }
+    },
     reloadData() {
+      this.resetPageState();
+      this.resetMountNode();
+      const graphLoadId = this.graphLoadId;
+      const routeKey = this.$route.fullPath;
       this.getList();
+      this.getNewList()
+      if (!this.$route.query.id) {
+        return
+      }
       getDetail({ id: this.$route.query.id }).then((res) => {
-        console.log(JSON.stringify(res.pedigreeChartParentAllDetailDTO));
-        
+        if (graphLoadId !== this.graphLoadId || routeKey !== this.$route.fullPath) {
+          return;
+        }
         const nodeMap = new Map();
         const calculateLevel = (node) => {
           if (node.parentId === "0") return 0;
@@ -399,7 +708,14 @@
             currentCount: 0,
             style: {
               fill: node.status === 1 ? "#00B5AA" : "#999",
-              opacity: node.status === 1 ? (level === 0 ? 1 : level === 1 ? 0.6 : 0.4) : 0.3,
+              opacity:
+                node.status === 1
+                  ? level === 0
+                    ? 1
+                    : level === 1
+                      ? 0.6
+                      : 0.4
+                  : 0.3,
             },
           };
         };
@@ -408,30 +724,35 @@
         this.graphData.nodes = [];
         this.graphData.edges = [];
 
-        if (res.pedigreeChartParentAllDetailDTO && res.pedigreeChartParentAllDetailDTO.one) {
+        if (
+          res.pedigreeChartParentAllDetailDTO &&
+          res.pedigreeChartParentAllDetailDTO.one
+        ) {
           // 创建节点映射
           createNodeMap(res.pedigreeChartParentAllDetailDTO.one);
 
           // 处理所有节点
           const processAllNodes = (nodes) => {
-            nodes.forEach(node => {
-              const processedNode = processNode(node);
-              this.graphData.nodes.push(processedNode);
-              
-              // 根据parentId创建边,直接使用原始id
-              if (node.parentId !== "0") {
-                this.graphData.edges.push({
-                  source: node.parentId,
-                  target: node.id,
-                  style: {
-                    stroke: "rgba(4, 156, 154, 1)",
-                    lineWidth: 1,
-                  },
-                });
-              }
+            nodes.forEach((node) => {
+              if (Number(this.roleType) === 2 || node.codeStatus == 2 || (node.codeStatus == 1 && Number(this.roleType) === 3)) {
+                const processedNode = processNode(node);
+                this.graphData.nodes.push(processedNode);
 
-              if (node.children) {
-                processAllNodes(node.children);
+                // 根据parentId创建边,直接使用原始id
+                if (node.parentId !== "0") {
+                  this.graphData.edges.push({
+                    source: node.parentId,
+                    target: node.id,
+                    style: {
+                      stroke: "rgba(4, 156, 154, 1)",
+                      lineWidth: 1,
+                    },
+                  });
+                }
+
+                if (node.children) {
+                  processAllNodes(node.children);
+                }
               }
             });
           };
@@ -446,17 +767,37 @@
           strainCode: res.strainCode,
           strainName: res.strainName,
         };
+        this.nodeTreeStatus = res.status
+
+        this.projectData = res.tprojectTeamList
 
         // 更新图表
         this.updateGraphData();
+        this.cacheData = null;
       });
     },
     addNodeSign(value, type) {
       this.nodeData = value;
       this.nodeType = type;
+      // this.$refs.addAncestor.closeDialog()
+      // this.$refs.addSublevelForm.close()
       this.confirmStorageDialogVisible = true;
     },
-    handleSubmit() {
+    // 传代计划数  审批
+    sureApprovalCountSign(value) {
+      console.log("value", value);
+      confirmCount({
+        id: value.id,
+        preserveSignature: value.preserveSignature,
+      }).then((res) => {
+        if (res.code == 200) {
+          this.$message.success("审批传代计划数成功");
+          this.$refs.approvalCount.closeDialog();
+          this.reloadData();
+        }
+      });
+    },
+    handleSubmit(type) {
       this.$refs.pedigreeForm.validate((valid) => {
         if (valid) {
           if (this.treeData.length === 0) {
@@ -465,10 +806,12 @@
           }
 
           // 处理节点数据,将data字段中的数据提升到根级别
-          const processNodeData = (node) => {
+          const processNodeData = (node, type) => {
+            console.log('node.codeStatus',node)
             const processedNode = {
               ...node,
               ...node.data,
+              codeStatus: type == 2 ? '2' : node.data.codeStatus || type,
               children: [],
             };
             delete processedNode.data;
@@ -479,7 +822,7 @@
           const buildTree = (nodes, edges) => {
             // 创建节点映射,提升性能
             const nodeMap = new Map(
-              nodes.map((node) => [node.nodeId, processNodeData(node)])
+              nodes.map((node) => [node.nodeId, processNodeData(node, type)])
             );
 
             // 创建子节点ID集合,用于快速查找根节点
@@ -501,21 +844,35 @@
           };
 
           // 获取基础表单数据
-          const baseData = {
+          let baseData = {
             parent: {
               generationType: 1,
               strainSourceStart: this.form.strainSourceStart,
               strainSourceEnd: this.form.strainSourceEnd,
               strainCode: this.form.strainCode,
               strainName: this.form.strainName,
+              status: type,
             },
             one: buildTree(this.graphData.nodes, this.graphData.edges),
           };
-          console.log("提交的数据:", baseData, this.graphData);
+          console.log('这是提交数据', baseData)
+          if (this.$route.query.id) {
+            baseData.parent.id = this.$route.query.id;
+
+            edit({ ...baseData }).then((res) => {
+              if (res.code == 200) {
+                this.$message.success("编辑成功");
+                this.cacheData = null;  // 👈 添加这一行
+                this.$closeCurrentView('/strain/pedigree-vhart');
+              }
+            });
+            return;
+          }
           add(baseData).then((res) => {
             if (res.code == 200) {
               this.$message.success("保存成功");
-              this.$router.back();
+              this.cacheData = null;
+              this.$closeCurrentView('/strain/pedigree-vhart');
             }
           });
         }
@@ -523,10 +880,9 @@
     },
     handleDraft() {
       // 实现存草稿逻辑
-      console.log("save draft", this.form);
     },
     handleCancel() {
-      this.$router.back();
+      this.$closeCurrentView('/strain/pedigree-vhart');
     },
     handleSignatureConfirm(signatureImage) {
       this.confirmStorageDialogVisible = false;
@@ -553,7 +909,8 @@
       // 处理提交逻辑
     },
     initGraph() {
-      const container = document.getElementById("mountNode");
+      const container = this.$refs.mountNode;
+      if (!container) return;
       const width = container.scrollWidth;
       const height = container.scrollHeight || 600;
 
@@ -571,19 +928,19 @@
           const titleFill = isDiscarded
             ? "rgba(245, 248, 250, 1)"
             : cfg.selected
-            ? "l(0) 0:#0ACBCA 1:#049C9A"
-            : "l(0) 0:#0ACBCA 1:#049C9A";
+              ? "l(0) 0:#0ACBCA 1:#049C9A"
+              : "l(0) 0:#0ACBCA 1:#049C9A";
           const contentFill = isDiscarded
             ? "rgba(245, 248, 250, 1)"
             : cfg.selected
-            ? "rgba(4,156,154,0.2)"
-            : "rgba(4,156,154,0.1)";
+              ? "rgba(4,156,154,0.2)"
+              : "rgba(4,156,154,0.1)";
           const textFill = isDiscarded ? "rgba(144, 147, 153, 1)" : "#049C9A";
           const stroke = isDiscarded
             ? "#DCDFE6"
             : cfg.selected
-            ? "#049C9A"
-            : "transparent";
+              ? "#049C9A"
+              : "transparent";
 
           // 创建渐变
           const gradient = group.addShape("rect", {
@@ -625,7 +982,7 @@
                 x: 0,
                 y: -totalHeight / 2 + titleHeight / 2,
                 fill: isDiscarded ? "rgba(144, 147, 153, 1)" : "#fff",
-                fontSize: 12,
+                fontSize: 14,
                 textAlign: "center",
                 textBaseline: "middle",
                 fontWeight: "bold",
@@ -640,10 +997,24 @@
           if (cfg.label === "传代计划数") {
             content = `${cfg.planCount || 0}`;
           } else if (cfg.number) {
-            content =
-              cfg.label === "母代"
-                ? `代传菌种编号:${cfg.number}`
-                : `接种菌种编号:${cfg.number}`;
+            console.log("qweqweqweqw", cfg.data);
+
+            // 获取类型名称
+            let typeName = "传代菌种";
+            // if (cfg.data && cfg.data.strainType) {
+            //   const typeMap = {
+            //     "1": "原始祖代菌株SO",
+            //     "2": "分离菌落 CO",
+            //     "3": "祖代菌株 O",
+            //   };
+            //   typeName = typeMap[cfg.data.strainType] || "接种菌种";
+            // }
+
+            if (cfg.data.parentId) {
+              typeName = "接代菌种";
+            }
+
+            content = `${typeName}编号:${cfg.number}`;
           }
 
           if (content) {
@@ -653,7 +1024,7 @@
                 x: 0,
                 y: -totalHeight / 2 + titleHeight + gap + contentHeight / 2,
                 fill: textFill,
-                fontSize: 10,
+                fontSize: 12,
                 textAlign: "center",
                 textBaseline: "middle",
                 cursor: "move",
@@ -678,7 +1049,7 @@
       });
 
       this.graph = new G6.Graph({
-        container: "mountNode",
+        container,
         width,
         height,
         fitView: true,
@@ -843,7 +1214,7 @@
             ...node,
             id: node.nodeId,
             level: 0, // 添加层级标记
-            children: [] // 添加children数组
+            children: [], // 添加children数组
           });
         });
 
@@ -955,13 +1326,26 @@
     },
     handleResize() {
       if (this.graph) {
-        const container = document.getElementById("mountNode");
+        const container = this.$refs.mountNode;
+        if (!container) return;
         const width = container.scrollWidth;
         const height = container.scrollHeight || 600;
         this.graph.changeSize(width, height);
       }
     },
     addNode() {
+      // 如果没有节点,新增祖代
+      console.log("选择的节点", this.selectedNode);
+      if (
+        this.selectedNode &&
+        this.selectedNode.data &&
+        this.selectedNode.data.auditStatus !== undefined &&
+        this.selectedNode.data.auditStatus != 2
+      ) {
+        this.$message.warning("该传代计划数未审核,请先审核");
+        return;
+      }
+
       // 如果没有节点,新增母代
       if (this.graphData.nodes.length === 0) {
         this.$refs.pedigreeForm.validate((valid) => {
@@ -971,9 +1355,19 @@
               strainCode: this.form.strainCode,
               strainSourceStart: this.form.strainSourceStart,
               strainSourceEnd: this.form.strainSourceEnd,
+              formStatus: "add",
             });
           }
         });
+        return;
+      }
+      //
+      if (
+        !this.$route.query.id &&
+        this.selectedNode &&
+        this.selectedNode.label === "传代计划数"
+      ) {
+        this.$message.warning("一次只能添加一个传代");
         return;
       }
 
@@ -1010,7 +1404,7 @@
           parentId: nodeModel.id,
           title: `新增${nextLevel}`,
           strainName1: this.form.strainName,
-            strainCode1: this.form.strainCode,
+          strainCode1: this.form.strainCode,
           form: {
             isDiscarded: true,
           },
@@ -1053,18 +1447,21 @@
       this.$refs.form.resetFields();
     },
     handleAddSublevel(value) {
-      if (value.formStatus == 'edit') {
-        updateChild(value).then((res) => {
+      console.log('11111111111111111', value)
+      if (value.formStatus == "edit") {
+        // let params = { ...value, id:value.parentId, codeStatus: '1' };
+        // delete params.parentId
+        updateChild({ ...value, codeStatus: '1' }).then((res) => {
           if (res.code === 200) {
             this.$message.success("操作成功");
             this.$refs.addSublevelForm.closeDialog();
             this.reloadData();
           }
         });
-        return
+        return;
       }
       if (this.$route.query.id) {
-        addProgenitor(value).then((res) => {
+        addProgenitor({ ...value, codeStatus: '1' }).then((res) => {
           if (res.code === 200) {
             this.$message.success("操作成功");
             this.$refs.addSublevelForm.closeDialog();
@@ -1203,6 +1600,7 @@
           strainCode1: this.form.strainCode,
           strainSourceStart: this.form.strainSourceStart,
           strainSourceEnd: this.form.strainSourceEnd,
+          formStatus: "addCount",
         });
       } else {
         this.$refs.planForm.openInitData({
@@ -1212,14 +1610,16 @@
           strainCode: this.form.strainCode,
           strainSourceStart: this.form.strainSourceStart,
           strainSourceEnd: this.form.strainSourceEnd,
+          formStatus: "addCount",
         });
       }
     },
     handleAddPlan(value) {
-      if (value.formStatus == 'edit') {
-       
-        console.log(value,'params');
-        updateChild(value).then((res) => {
+      console.log('2222222222222222222', value)
+      if (value.formStatus == "edit") {
+        let params = { ...value, id: value.parentId, codeStatus: '1' };
+        delete params.parentId
+        updateChild({ ...params }).then((res) => {
           if (res.code === 200) {
             this.$message.success("操作成功");
             this.$refs.planForm.closeDialog();
@@ -1227,22 +1627,41 @@
             this.reloadData();
           }
         });
-        return
+        return;
       }
       if (this.$route.query.id) {
-        let params = {
-          parentId: value.id,
-          generationCount: value.generationCount,
-          vaccinateSignature: value.vaccinateSignature,
-        };
-        addProgenitorChild(params).then((res) => {
-          if (res.code === 200) {
-            this.$message.success("操作成功");
-            this.$refs.planForm.closeDialog();
-            this.$refs.addSublevelPlan.closeDialog();
-            this.reloadData();
-          }
-        });
+        if (value.formStatus == "addCount") {
+          let params = {
+            parentId: value.id,
+            generationCount: value.generationCount,
+            vaccinateSignature: value.vaccinateSignature,
+            codeStatus: '1'
+          };
+          addCount(params).then((res) => {
+            if (res.code === 200) {
+              this.$message.success("操作成功");
+              this.$refs.planForm.closeDialog();
+              this.$refs.addSublevelPlan.closeDialog();
+              this.reloadData();
+            }
+          });
+        } else {
+          let params = {
+            id: value.id,
+            generationCount: value.generationCount,
+            vaccinateSignature: value.vaccinateSignature,
+            codeStatus: '1'
+          };
+          addProgenitorChild(params).then((res) => {
+            if (res.code === 200) {
+              this.$message.success("操作成功");
+              this.$refs.planForm.closeDialog();
+              this.$refs.addSublevelPlan.closeDialog();
+              this.reloadData();
+            }
+          });
+        }
+
         return;
       }
       const nodeModel = this.selectedNode;
@@ -1286,24 +1705,22 @@
           strainSourceStart: this.form.strainSourceStart,
           strainSourceEnd: this.form.strainSourceEnd,
           ...nodeModel.data,
-          status: "detail",
+          formStatus: "detail",
         });
       } else if (nodeModel.label === "子代" || nodeModel.label === "孙代") {
         this.dialogTitle = `${nodeModel.label}详情`;
         this.$refs.addSublevelForm.openInitData({
           strainCode1: this.form.strainCode,
-            strainName1: this.form.strainName,
+          strainName1: this.form.strainName,
           title: `${nodeModel.label}详情`,
           form: { ...nodeModel.data },
         });
       } else if (nodeModel.label === "传代计划数") {
-        return
+        return;
         const nodeIndex = this.graphData.nodes.findIndex(
           (n) => n.nodeId === nodeModel.nodeId
         );
         if (this.graphData.nodes[nodeIndex - 1].label === "子代") {
-          console.log(123);
-
           this.$refs.addSublevelPlan.openInitData({
             strainSourceStart: this.form.strainSourceStart,
             strainCode1: this.form.strainCode,
@@ -1313,8 +1730,6 @@
             status: "detail",
           });
         } else {
-          console.log(123);
-          
           this.$refs.planForm.openInitData({
             strainSourceStart: this.form.strainSourceStart,
             strainSourceEnd: this.form.strainSourceEnd,
@@ -1340,6 +1755,10 @@
   padding: 0 20px;
   display: flex;
   align-items: center;
+}
+
+.title {
+  font-size: 18px;
 }
 
 .chart {
@@ -1396,6 +1815,39 @@
     flex-direction: column;
     align-items: flex-start;
     width: 100%;
+  }
+}
+
+.header-title {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  gap: 13px;
+
+  .header-title-left {
+    display: flex;
+    align-items: center;
+    gap: 13px;
+
+    img {
+      width: 12px;
+      height: 19px;
+    }
+
+    div {
+      flex-shrink: 0;
+      font-weight: bold;
+      font-size: 18px;
+      color: #222222;
+      line-height: 27px;
+      font-family: 'Source Han Sans CN Bold Bold';
+
+      &:before {
+        content: '*';
+        color: #F56C6C;
+        margin-right: 4px;
+      }
+    }
   }
 }
 
@@ -1481,7 +1933,7 @@
     }
   }
 
-  #mountNode {
+  .mount-node {
     flex: 1;
     width: 100%;
     min-height: 500px;

--
Gitblit v1.7.1