Browse Source

Merge remote-tracking branch 'origin/test-dev' into test-dev

chenr 1 month ago
parent
commit
b51c001238

+ 4 - 2
src/api/manager/AdjustForm.js

@@ -75,13 +75,15 @@ export const saveDdefual = (data) => {
 }
 
 // 删除信息
-export const remove = (ids,tabId) => {
+export const remove = (ids,tabId,type,colKey) => {
   return request({
     url: '/api/blade-manager/textdictinfo/remove',
     method: 'post',
     params: {
       ids,
-      tabId
+      tabId,
+      type,
+      colKey
     }
   })
 }

+ 9 - 0
src/api/manager/wbstree.js

@@ -368,4 +368,13 @@ export const getQueryValueByType = (params) => {
         method: 'get',
         params
     })
+}
+
+//过滤
+export const getQueryValueByNodeType = (params) => {
+    return request({
+        url: '/api/blade-manager/wbsTree/getQueryValueByNodeType',
+        method: 'get',
+        params
+    })
 }

+ 45 - 0
src/api/ruleManage/codeRule.js

@@ -0,0 +1,45 @@
+import request from '@/router/axios';
+//获取试验编号规则
+export const getTrialNumberRule = (params) => {
+    return request({
+        url: '/api/blade-business/trialnumberrule/getTrialNumberRule',
+        method: 'get',
+        params
+    })
+}
+export const save = (data) => {
+    return request({
+        url: '/api/blade-business/trialnumberrule/save',
+        method: 'post',
+        data
+    });
+}
+export const submitList = (data) => {
+    return request({
+        url: '/api/blade-business/trialnumberrule/submitList',
+        method: 'post',
+        data
+    });
+}
+export const update = (data) => {
+    return request({
+        url: '/api/blade-business/trialnumberrule/update',
+        method: 'post',
+        data
+    });
+}
+export const remove = (data) => {
+    return request({
+        url: '/api/blade-business/trialnumberrule/remove',
+        method: 'post',
+
+        params:data
+    });
+}
+export const sort = (data) => {
+    return request({
+        url: '/api/blade-business/trialnumberrule/sort',
+        method: 'post',
+        data
+    });
+}

+ 159 - 0
src/api/ruleManage/fileRule.js

@@ -0,0 +1,159 @@
+import request from '@/router/axios';
+//获取规范文件夹分页
+export const getPage = (params) => {
+    return request({
+        url: '/api/blade-business/PrivateStandard/page',
+        method: 'get',
+        params
+    })
+}
+//获取规范文件夹详情
+export const getById = (params) => {
+    return request({
+        url: '/api/blade-business/PrivateStandard/getById',
+        method: 'get',
+        params
+    })
+}
+//新增数据
+export const add = (data) => {
+    return request({
+        url: '/api/blade-business/PrivateStandard/add',
+        method: 'post',
+    
+        data,
+         headers: {
+        'Content-Type': 'multipart/form-data'
+        },
+    });
+}
+export const edit = (data) => {
+    return request({
+        url: '/api/blade-business/PrivateStandard/edit',
+        method: 'post',
+        data,
+    });
+}
+
+export const deleteItem = (data) => {
+    return request({
+        url: '/api/blade-business/PrivateStandard/delete',
+        method: 'get',
+        params:data
+    });
+}
+
+//规范参数
+
+export const getInfoPage = (params) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/page',
+        method: 'get',
+        params
+    })
+}
+
+export const getInfoById = (params) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/getById',
+        method: 'get',
+        params
+    })
+}
+
+
+//新增数据
+export const addInfo = (data) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/add',
+        method: 'post',
+        data
+    });
+}
+export const editInfo = (data) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/edit',
+        method: 'post',
+        data
+    });
+}
+
+export const deleteItemInfo = (data) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/delete',
+        method: 'get',
+        params:data
+    });
+}
+//条件设置
+export const saveConditionSet = (data,id) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/saveConditionSet'+'?id='+id,
+        method: 'post',
+        data
+    });
+}
+//关联元素
+export const saveElementJoin = (data,id) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/saveElementJoin'+'?id='+id,
+        method: 'post',
+        data
+    });
+}
+
+//删除条件设置
+export const deleteConditionSet = (data) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/deleteConditionSet',
+        method: 'get',
+        params:data
+    });
+}
+//删除关联元素
+export const deleteElementJoin = (data) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/deleteElementJoin',
+        method: 'get',
+        params:data
+    });
+}
+//查询条件设置
+export const getConditionSet = (params) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/getConditionSet',
+        method: 'get',
+        params
+    })
+}
+//查询关联元素
+export const getElementJoin = (params) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/getElementJoin',
+        method: 'get',
+        params
+    })
+}
+
+//效果预览
+//查询关联元素
+export const effectPreview = (params) => {
+    return request({
+        url: '/api/blade-business/uStandardInfo/effectPreview',
+        method: 'get',
+        params
+    })
+}
+
+//新增数据
+export const updateTypeByTwo = (data) => {
+    return request({
+        url: '/api/blade-business/PrivateStandard/updateTypeByTwo',
+        method: 'post',
+    
+        data,
+         headers: {
+        'Content-Type': 'multipart/form-data'
+        },
+    });
+}

+ 3 - 3
src/config/index.json

@@ -1,9 +1,9 @@
 {
   "target22": "http://39.108.216.210:8090",
-  "target7": "http://192.168.0.109:8090",
-  "target2": "http://192.168.0.101:8090",
+  "target1": "http://192.168.0.109:8090",
+  "target": "http://219.151.181.73:8090",
   "target3": "http://183.247.216.148:28090",
-  "target": "http://192.168.0.109:8090",
+  "target2": "http://192.168.0.109:8090",
   "dev": {
     "port": 1888
   }

+ 21 - 1
src/router/views/index.js

@@ -77,6 +77,16 @@ export default [{
             component: () =>
               import ( /* webpackChunkName: "views" */ '@/views/manager/projectinfo/detail.vue')
           },
+                {
+            path: '/manager/projectinfo/ledger',
+            name: '同步台账',
+            meta: {
+              i18n: 'projectinfoledger',
+              menu: false,
+            },
+            component: () =>
+              import ( /* webpackChunkName: "views" */ '@/views/manager/projectinfo/ledger.vue')
+          },
           
           //归档树配置规则
           {
@@ -101,7 +111,17 @@ export default [{
             component: () =>
                 import ( /* webpackChunkName: "views" */'@/views/digital/signer.vue')
             },
-          
+                //电签角色库
+            {
+            path: '/rule/manager',
+            name: '规范参数管理',
+            meta: {
+                i18n: 'ruleManager',
+                menu: false,
+            },
+            component: () =>
+                import ( /* webpackChunkName: "views" */'@/views/codeRule/ruleManage.vue')
+            },
         ]
     }, {
         path: '/test',

+ 722 - 0
src/views/codeRule/ConditionsSet.vue

@@ -0,0 +1,722 @@
+<template>
+  <el-dialog
+   class="dialog-set"
+    :visible.sync="visible"
+    width="70%"
+    append-to-body
+  >
+    <div slot="title" class="dialog-title">
+        <div>
+             <i class="el-icon-s-tools" ></i>
+             <span style="margin-left: 10px;">条件设置</span>
+        </div>
+      <div class="marginTop-10">设置样品信息和技术指标的关联关系,满足条件时回显对应参数</div>
+
+    </div>
+    <div class="conditions-container">
+      <!-- 左侧条件列表 -->
+      <div class="conditions-left">
+        <div class="condition-header">
+            <i class="el-icon-s-operation" style="color: rgb(46, 123, 115);"></i>
+          <span>参数列表</span>
+          
+        </div>
+        <div class="condition-list">
+          <div class="condition-item">
+           <span 
+                v-for="(item, index) in paramList" 
+                :key="index"
+                :class="{ active: activeIndex === index }"
+                @click="handleSelect1(index, item)"
+               
+
+                >
+                {{ item.symbolName }}
+            </span>
+          </div>
+        </div>
+      </div>
+
+      <!-- 右侧操作列表 -->
+      <div class="conditions-right">
+       <div class="condition-header1">
+            <div class="header-left">
+                <i class="el-icon-s-operation" style="color: rgb(46, 123, 115);"></i>
+                <span>条件列表</span>
+            </div>
+            <div class="header-right">
+                <el-button 
+                type="primary"
+                size="small"
+                :style="{ background: 'rgb(37, 80, 162)', borderColor: 'rgb(37, 80, 162)' }"
+                @click="addCondition"
+                >
+                <i class="el-icon-plus"></i>
+                添加条件
+                </el-button>
+                <el-button 
+                type="success" 
+                size="small"
+                @click="saveCondition"
+                >
+                <i class="el-icon-check"></i>
+                保存条件
+                </el-button>
+            </div>
+            </div>
+        <div class="condition-list">
+          <div class="condition-item1">
+           <div 
+                v-for="(item, index) in paramList[activeIndex].standardInfos" 
+                :key="index"
+              
+                >
+          <div>
+            <span>
+                <div class="condition-header-content">
+                <div style="color: black;">
+                    {{item.name}}
+                </div>
+                <i class="el-icon-close" @click.stop="handleDeleteItem(item,index)"></i>
+                </div>
+                <div class="code-list">
+                <div  class="code-item">
+                    {{ item.standardInfoGroupNameVO.name }}
+                </div>
+                </div>
+            </span>
+            </div>
+                
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="result-container">
+            <div class="condition-header">
+               <i class="el-icon-connection" style="color: rgb(46, 123, 115);"></i>
+            <span>关联关系</span>
+            </div>
+            <div class="link-list">
+                <div v-for="(item, index) in linkListData" :key="index" class="link-item" :class="{ clicked: item.clicked }" @click="toggleClick(item, index)">
+                    <i class="el-icon-close" @click.stop="handleDeleteLinkItem(item,index)"></i>
+                    <div class="link-name">
+                        <span>{{ item.name }}</span>
+                    </div>
+                  <div>
+                       <i class="el-icon-connection" style="color: black; font-size: larger;"></i>
+                  </div>
+                  <div class="code-list">
+                    <div v-for="(codeItem, codeIndex) in item.standardInfos" :key="codeIndex" class="code-item">
+                        <div class="code-title">{{ codeItem.name }}</div>
+                        <div class="code-detail">{{ codeItem.standardInfoGroupNameVO.name }}</div>
+                    </div>
+
+                  </div>
+                 
+                </div>
+            </div>
+            
+          </div>
+
+    
+    <div slot="footer" class="dialog-footer">
+   
+      <el-button type="primary" @click="handleConfirm" :style="{ background: 'rgb(37, 80, 162)', borderColor: 'rgb(37, 80, 162)' }">保存</el-button>
+    </div>
+
+     <el-dialog
+        class="dialog-set"
+        :visible.sync="addDialogVisible"
+        width="30%"
+        append-to-body
+        close-on-click-modal="false"
+        >
+         <div slot="title" class="dialog-title">
+        <div>
+             <i class="el-icon-plus" ></i>
+             <span style="margin-left: 10px;">添加条件</span>
+        </div>
+      <div class="marginTop-10">同次设置的条件为“或者”关系,不同次设置的条件为“并且”关系</div>
+
+    </div>
+        <el-form ref="addForm" :model="addForm" label-width="80px">
+            <el-form-item label="样品信息">
+            <el-select v-model="addForm.codeNameId" placeholder="请选择"  style="width: 100%;"  @change="handleSelectCodeName">
+                <el-option
+                v-for="item in sampleOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+                </el-option>
+            </el-select>
+            </el-form-item>
+            <el-form-item label="基础信息">
+            <el-select v-model="addForm.codeValueList" placeholder="请选择" multiple style="width: 100%;" @change="handleSelectCode">
+                <el-option
+                v-for="item in basicOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+                </el-option>
+            </el-select>
+            </el-form-item>
+        </el-form>
+        <div slot="footer" class="dialog-footer">
+           
+       
+            <el-button type="primary" @click="confirmAdd" :style="{ background: 'rgb(37, 80, 162)', borderColor: 'rgb(37, 80, 162)' }">确认添加</el-button>
+        </div>
+    </el-dialog>  
+  </el-dialog>
+      
+       
+</template>
+
+<script>
+import {getInfoPage,saveConditionSet,getConditionSet,deleteConditionSet } from "@/api/ruleManage/fileRule.js";
+export default {
+  name: 'ConditionsSet',
+  data() {
+    return {
+      visible: false,
+       paramList: [
+        {
+          symbolName: '<0.75',
+          standardInfos:[
+            {name: 'C3A', 
+            rightStandardInfos: [
+              {name:'矿渣硅酸盐水泥',id:'1'}
+            ],
+            standardInfoGroupNameVO:{
+              name: '矿渣硅酸盐水泥'
+            }
+
+            
+          },
+            {codeName: 'C3S', codeValue: []},
+          ]
+
+        }
+       ] , // 参数列表数据
+       activeIndex: 0, // 当前选中的参数索引
+       addDialogVisible: false,
+        addForm: {
+            codeName: '',
+            codeValueList: [],
+            codeValueName: '',
+            codeNameId: ''
+        },
+        sampleOptions: [
+          
+            // 添加更多选项...
+        ],
+        basicOptions: [],
+      linkListData: [
+       
+           
+      ], // 关联关系数据
+      id:'', // 传入的ID规范文件id
+
+    }
+  },
+  methods: {
+    show(val,id) {
+      this.id = id
+      this.getSampleOptions(id)
+      this.visible = true
+      if(val.length > 0&&val[0].symbolName) {
+       this.paramList=val
+       val.forEach((item,index)=>{
+          this.handleSelect(index)
+       })
+       this.activeIndex = 0
+
+
+       
+      }else{
+        this.paramList = []
+      }
+      //获取关联关系数据
+
+      this.getLinkSetData(this.id);
+    },
+    //获取样品信息列表
+     getSampleOptions(id){
+             getInfoPage({
+                current:1,
+                size:100,
+                type: 1,
+                standardId: id,
+              }).then((res) => {
+                this.ruleLoading = false;
+                if (res.data.code === 200) {
+                  this.sampleOptions= res.data.data.records.map(item => ({
+                    value: item.id,
+                    label: item.name,
+                    info:item.info
+                  }));
+                  // 
+                } else {
+                  this.sampleOptions = [];
+                }
+              });
+      },
+    hide() {
+      this.visible = false  
+    },
+    handleCancel() {
+      this.hide()
+      this.$emit('cancel')
+    },
+    handleConfirm() {
+
+      saveConditionSet(this.linkListData,this.id).then((res)=>{
+        if(res.data.code === 200) {
+          this.$message({
+            type: 'success',
+            message: res.data.msg,
+          })
+        }else{
+          this.$message({
+            type: 'error',
+            message: res.data.msg,
+          })
+        }
+      })
+      this.hide()
+      this.$emit('confirm')
+    },
+    handleDeleteLinkItem(item,index){
+        this.$confirm('删除后,数据将无法恢复,是否确认删除!', '提示', {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning'
+          }).then(() => {
+  
+            deleteConditionSet({leftId:item.id}).then((res) => {
+              if(res.data.code==200){
+                this.$message.success(res.data.msg);
+              
+                this.linkListData.splice(index, 1);
+                this.getLinkSetData(this.id);
+              }else{
+                this.$message.error(res.data.msg);
+              }
+            });
+          }).catch(() => {
+            this.$message.info('已取消删除');
+          })
+    },
+    addCondition() {
+      // 添加条件逻辑
+           this.addDialogVisible = true
+           this.addForm = {}
+   
+           this.basicOptions = []
+
+    },
+    addOperation() {
+      // 添加操作逻辑
+    },
+  async handleSelect(index) {
+      this.activeIndex = index
+      let leftId = this.paramList[index].id
+     let arr= await this.getConditionSetData(this.id,leftId)
+     
+      if(arr.length>0){
+          this.$nextTick(()=>{
+              // this.paramList[index].standardInfos = arr[0]['standardInfos']
+              this.$set(this.paramList, index, { ...this.paramList[index], standardInfos: arr[0]['standardInfos'] });
+          })
+
+      }else{
+        this.paramList[index].standardInfos = []
+      }
+      
+    },
+    async handleSelect1(index) {
+      this.activeIndex = index
+ 
+      
+    },
+    handleSelectCode(values) {
+      if (!values || values.length === 0) {
+        this.addForm.codeValueName = '';
+        return;
+      }
+      
+      // 根据选中的value值找到对应的label
+      const selectedLabels = values.map(value => {
+        const option = this.basicOptions.find(opt => opt.value === value);
+        return option ? option.label : '';
+      });
+
+      this.addForm.codeValueName = selectedLabels.join('/');
+         this.addForm.codeValue = values
+    },
+    handleSelectCodeName(value) {
+      if (!value) {
+        this.addForm.codeName = '';
+        return;
+      }
+      this.basicOptions = []
+      this.sampleOptions.forEach(option => {
+        if (option.value === value) {
+          this.addForm.codeName = option.label;
+       
+        }
+      });
+       const selectedOption = this.sampleOptions.find(option => option.value === value);
+       this.basicOptions = selectedOption ? selectedOption.info.map(item => ({
+         value: item.id,
+         label: item.name
+       })) : [];
+       
+    },
+    handleDeleteItem(item, index) {
+      this.paramList[this.activeIndex].standardInfos.splice(index, 1)
+     
+    },
+    confirmAdd() {
+      if (!this.addForm.codeName || !this.addForm.codeValue) return this.$message.error('请选择样品信息和基础信息')
+      this.paramList[this.activeIndex].standardInfos.push(
+        {name: this.addForm.codeName,
+         standardInfoGroupNameVO: 
+              {name:this.addForm.codeValueName,ids:this.addForm.codeValue}
+       },
+      )
+      this.addDialogVisible = false
+      this.addForm = {
+        codeName: '',
+        codeValue: []
+      }
+   
+    },
+          //保存条件
+      saveCondition() {
+
+        const filteredArr = this.paramList.filter(item => item.standardInfos.length !== 0);
+        this.linkListData = JSON.parse(JSON.stringify(filteredArr));
+
+   
+      },
+     toggleClick(item, index) {
+        this.linkListData.forEach(listItem => {
+          this.$set(listItem, 'clicked', false);
+        });
+        this.$set(item, 'clicked', !item.clicked);
+        let clickedIndex = this.paramList.findIndex(listItem => listItem.id === item.id);
+        console.log(clickedIndex, 'clickedIndex');
+        this.activeIndex = clickedIndex;
+        
+      },
+    // 获取条件设置
+      async getConditionSetData(id, leftId) {
+        try {
+          const res = await getConditionSet({ id, leftId });
+          if (res.data.code === 200) {
+            console.log(res.data.data, '获取的条件设置数据');
+            return res.data.data; // 直接返回数据
+          } else {
+            this.$message.error(res.data.msg);
+            throw new Error(res.data.msg); // 抛出错误,以便在调用处处理
+          }
+        } catch (error) {
+          // 这里可以添加额外的错误处理逻辑,例如记录日志
+          throw error; // 重新抛出错误,以便在调用处捕获
+        }
+      },
+      //获取关联关系数据
+     
+      async getLinkSetData(id, leftId) {
+        try {
+          const res = await getConditionSet({ id, leftId });
+          if (res.data.code === 200) {
+            console.log(res.data.data, '获取的关系数据');
+            this.linkListData = res.data.data; // 直接返回数据
+
+           
+          } else {
+            this.$message.error(res.data.msg);
+            throw new Error(res.data.msg); // 抛出错误,以便在调用处处理
+          }
+        } catch (error) {
+          // 这里可以添加额外的错误处理逻辑,例如记录日志
+          throw error; // 重新抛出错误,以便在调用处捕获
+        }
+      }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.conditions-container {
+  display: flex;
+  gap: 20px;
+  font-weight: bold;
+//   height: 200px;
+.green-txt{
+    color: rgb(46, 123, 115);;
+}
+  .conditions-left,
+  .conditions-right {
+    flex: 1;
+    border: 1px solid #EBEEF5;
+    border-radius: 4px;
+      background: #f5f7fa;
+  }
+
+
+
+  .condition-list,
+  .condition-content {
+    padding: 10px;
+  }
+
+  .condition-item {
+    span {
+      display: inline-block;
+      padding: 8px 8px;
+      margin: 5px;
+      background: white;
+      color: #409EFF;
+      border-radius: 4px;
+      cursor: pointer;  // 添加指针样式
+      transition: all 0.3s;  // 添加过渡效果
+       &.active {  // 选中状态
+        background:  #67C23A;;
+        color: white;
+        }
+    }
+  }
+
+  .content-item {
+    margin-bottom: 10px;
+    padding: 10px;
+    border: 1px solid #EBEEF5;
+    border-radius: 4px;
+
+    .item-title {
+      display: flex;
+      gap: 10px;
+      align-items: center;
+      
+      span {
+        &:first-child {
+          color: #666;
+        }
+        &:nth-child(2) {
+          color: #409EFF;
+        }
+        &:last-child {
+          color: #666;
+        }
+      }
+    }
+  }
+}
+.dialog-title {
+  display: flex;
+  flex-direction: column;
+  color:white ;
+  padding: 10px;
+   font-size: 14px;
+
+ .marginTop-20{
+    margin-top: 10px;
+ }
+      background: rgb(37, 80, 162);
+      .el-dialog__header{
+        padding: 0px;
+         
+      
+      }
+}
+.condition-header1 {
+  display: flex;
+  justify-content: space-between; // 两端对齐
+  align-items: center;
+  padding: 10px;
+  border-bottom: 1px solid #EBEEF5;
+
+  .header-left {
+    display: flex;
+    align-items: center;
+    
+    span {
+      font-weight: bold;
+      margin-left: 10px;
+     
+    }
+  }
+
+  .header-right {
+    display: flex;
+    gap: 10px; // 按钮间距
+
+    .el-button {
+      padding: 7px 15px;
+      
+      &:hover {
+        opacity: 0.8;
+      }
+    }
+  }
+}
+.code-list{
+    display: flex;
+            font-weight: bold;
+    .code-item{
+        margin-right: 5px;
+        margin-top: 5px;
+
+    }
+}
+
+  .condition-item1 {
+    display: flex;
+    span {
+        margin-left: 5px;
+      display: inline-block;
+      padding: 8px 8px;
+    
+     
+    background: rgb(213, 222, 255);;
+          color:  rgba(37,80,162,1);
+      border-radius: 4px;
+      cursor: pointer;  // 添加指针样式
+      transition: all 0.3s;  // 添加过渡效果
+      height: 40px;
+      
+    }
+  }
+.condition-header-content {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 100%;
+  
+  .delete-icon {
+    color: #F56C6C;
+    cursor: pointer;
+    font-size: 16px;
+    
+    &:hover {
+      opacity: 0.8;
+    }
+  }
+}
+.result-container{
+  width: 100%;
+  border: 1px solid #EBEEF5;
+  border-radius: 4px;
+  background: #f5f7fa;
+  margin-top: 10px;
+}
+  .condition-header {
+    display: flex;
+    // justify-content: space-between;
+    align-items: center;
+    padding: 10px;
+    border-bottom: 1px solid #EBEEF5;
+  
+
+    span {
+      font-weight: bold;
+      margin-left: 10px;
+    }
+  }
+  .link-list{
+    max-height: 350px;
+    overflow-y: auto;
+    padding: 10px;
+    font-weight: bold;
+   
+    .link-item{
+      display: flex;
+      align-items: center;
+      padding: 10px;
+      background-color: white;
+      border-radius: 10px;
+      cursor: pointer; // 添加指针样式
+      position: relative; // 添加相对定位
+      margin-bottom: 10px;
+        &.clicked {
+          background-color: #e0e0e0; // 点击时的背景色
+        }
+       
+       .el-icon-close {
+                    position: absolute; // 绝对定位
+                    top: 30%; // 垂直居中
+                    right: 10px; // 距离右侧10px
+                    transform: translateY(-50%); // 垂直方向上的偏移量,确保图标垂直居中
+                    color: #F56C6C; // 删除图标的颜色
+                    cursor: pointer; // 添加指针样式
+                    font-size: 16px; // 图标大小
+
+                    &:hover {
+                      opacity: 0.8; // 悬停效果
+                  }
+          }
+      .link-name{
+        flex-shrink: 0;
+        background-color: rgb(167, 224, 218);
+        color: rgba(46, 123, 115, 1);
+        border-radius: 5px;
+        text-align: center;
+    
+        padding:8px;
+        margin-right: 15px;
+
+      }
+      .code-list{
+        margin-left: 15px;
+        display: flex;
+
+       
+        overflow-x: auto;
+           font-weight: bold;
+          .code-item {
+              // display: flex;
+              margin-bottom: 10px;
+              flex-shrink: 0;
+                  margin-left: 5px;
+       
+                padding:8px;
+              
+              
+              background: rgb(213, 222, 255);;
+                color: #409EFF;
+                border-radius: 4px;
+           
+                transition: all 0.3s;  // 添加过渡效果
+                height: 50px;
+                
+              .code-title{
+                color: black;
+                margin-bottom: 10px;
+              }
+              .code-detail{
+                color:  rgba(37,80,162,1);
+              }
+            }
+      }
+    }
+  }
+</style>
+<style lang="scss">
+.dialog-set {
+
+
+      .el-dialog__header{
+        padding: 0px;
+              background: rgb(37, 80, 162);
+              font-family: 16px;
+      
+      }
+      .dialog-footer{
+        text-align: center;
+      }
+}
+</style>

+ 806 - 0
src/views/codeRule/LinkEle.vue

@@ -0,0 +1,806 @@
+<template>
+  <el-dialog
+   class="dialog-set"
+    :visible.sync="visible"
+    width="70%"
+    append-to-body
+  >
+    <div slot="title" class="dialog-title">
+        <div>
+             <i class="el-icon-connection" ></i>
+             <span style="margin-left: 10px;">关联元素</span>
+        </div>
+      <div class="marginTop-10">设置获取数据的元素位置,用于回显数据到相应位置</div>
+
+    </div>
+    <div class="conditions-container">
+      <!-- 左侧条件列表 -->
+      <div class="conditions-left">
+        <div class="condition-header">
+            <i class="el-icon-s-operation" style="color: rgb(46, 123, 115);"></i>
+          <span>参数列表</span>
+          
+        </div>
+        <div class="condition-list">
+          <div class="condition-item">
+           <span 
+                v-for="(item, index) in paramList" 
+                :key="index"
+                :class="{ active: activeIndex === index }"
+                @click="handleSelect1(index, item)"
+
+                >
+                {{ item.symbolName }}
+            </span>
+          </div>
+        </div>
+      </div>
+
+      <!-- 右侧操作列表 -->
+      <div class="conditions-right">
+       <div class="condition-header1">
+            <div class="header-left">
+                <i class="el-icon-s-operation" style="color: rgb(46, 123, 115);"></i>
+                <span>条件列表</span>
+            </div>
+            <div class="header-right">
+                <el-button 
+                type="primary"
+                size="small"
+                :style="{ background: 'rgb(37, 80, 162)', borderColor: 'rgb(37, 80, 162)' }"
+                @click="addCondition"
+                >
+                <i class="el-icon-plus"></i>
+                添加元素
+                </el-button>
+                <el-button 
+                type="success" 
+                size="small"
+                @click="saveEle"
+                >
+                <i class="el-icon-check"></i>
+                保存元素
+                </el-button>
+            </div>
+            </div>
+        <div class="condition-list">
+          <div class="condition-item1">
+           <div 
+                 v-for="(item, index) in paramList[activeIndex].group" 
+                :key="index"
+              
+                >
+          <div>
+            <span>
+                <div class="condition-header-content">
+                <div style="color: black;">
+                    {{item.privateName}}
+                </div>
+                <i class="el-icon-close" @click.stop="handleDeleteItem(item,index)"></i>
+                </div>
+                <div class="code-list">
+                <div class="code-item">
+                     {{ item.elementNames}}
+                </div>
+                </div>
+            </span>
+            </div>
+                
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+     <div class="result-container">
+            <div class="condition-header">
+               <i class="el-icon-connection" style="color: rgb(46, 123, 115);"></i>
+            <span>关联关系</span>
+            </div>
+             <div class="link-list">
+                <div v-for="(item, index) in linkListData" :key="index" class="link-item" :class="{ clicked: item.clicked }" @click="toggleClick(item, index)">
+                    <i class="el-icon-close" @click.stop="handleDeleteLinkItem(item,index)"></i>
+                    <div class="link-name">
+                        <span>{{ item.name }}</span>
+                    </div>
+                  <div>
+                       <i class="el-icon-connection" style="color: black; font-size: larger;"></i>
+                  </div>
+                  <div class="code-list">
+                    <div v-for="(codeItem, codeIndex) in item.group" :key="codeIndex" class="code-item">
+                        <div class="code-title">{{ codeItem.privateName }}</div>
+                        <div class="code-detail">{{ codeItem.elementNames }}</div>
+                    </div>
+
+                  </div>
+                 
+                </div>
+            </div>
+            
+            
+          </div>
+    <div slot="footer" class="dialog-footer">
+   
+      <el-button type="primary" @click="handleConfirm" :style="{ background: 'rgb(37, 80, 162)', borderColor: 'rgb(37, 80, 162)' }">保存</el-button>
+    </div>
+
+    <div style="height: 100%;">
+       <el-drawer
+        class="dialog-set"
+            :visible.sync="addDialogVisible"
+          width="80%"
+          height="80%"
+
+          append-to-body
+            direction="ttb"
+
+            >
+            <div slot="title" class="dialog-title">
+                <div>
+                    <i class="el-icon-plus" ></i>
+                    <span style="margin-left: 10px;">添加元素</span>
+                </div>
+              <div class="marginTop-10">根据表单选择回显的元素位置。根据条件判定后,自动将满足条件的数据回显到选择的元素位置</div>
+
+            </div>
+            <div class="condition-header1-title">
+              <span>选择表单</span>
+            </div>
+            <div class="condition-header1-table">
+                  <el-table
+                    :data="tableData"
+                    height="250"
+                    border
+                    style="width: 100%">
+                    <el-table-column
+                      prop="tableName"
+                      label="表单名称"
+                    >
+                    </el-table-column>
+                    <el-table-column
+                      align="center"
+                      prop="tableType"
+                      :formatter="formatTableType"
+                      width="100"
+                      label="表单类型"
+                    ></el-table-column>
+                  <el-table-column
+                      width="150"
+                      label="操作"
+                    >
+                      <template slot-scope="scope">
+                        <el-button
+                          v-if="!scope.row.isSelected"
+                          type="text"
+                          size="small"
+                          @click="handleRowSelect(scope.row)"
+                        >
+                          选择
+                        </el-button>
+                        <el-button
+                          v-else
+                          type="text"
+                          size="small"
+                          style="color: #F56C6C;"
+                          @click="handleCancelSelect(scope.row)"
+                        >
+                          取消选择
+                        </el-button>
+                      </template>
+                    </el-table-column>
+                  </el-table>
+            </div>
+            <div class="condition-header1-title" style="margin-top: 10px;">
+              <span>选择元素</span>
+            </div>
+
+            <div class="condition-header1-html-box">
+              <check-ele-html 
+              :key="pkeyId"
+                :pkeyId="pkeyId"
+                @element-selected="handleElementSelected"
+              ></check-ele-html>
+            </div>
+            <div class="dialog-footer">
+              
+          
+                <el-button type="primary" @click="confirmAdd" :style="{ background: 'rgb(37, 80, 162)', borderColor: 'rgb(37, 80, 162)' }">确认添加</el-button>
+            </div>
+        </el-drawer> 
+    </div>
+  </el-dialog>
+      
+       
+</template>
+
+<script>
+import { getDictionary } from "@/api/system/dict";
+import { findNodeTableByCondition as selectByNodeTable} from "@/api/manager/wbsprivate";
+import checkEleHtml from "./checkEleHtml.vue";
+import {saveElementJoin,deleteElementJoin,getElementJoin } from "@/api/ruleManage/fileRule.js";
+export default {
+  name: 'ConditionsSet',
+  components: {
+    checkEleHtml
+  },
+  data() {
+    return {
+      visible: false,
+      treeId: '', // 树节点ID
+      deatailId: '', // 详情ID
+
+      paramList: [
+        {
+          symbolName: '<0.75',
+          group:[
+            {name: 'C3A', 
+          
+            standardInfoGroupNameVO:{
+              name: '矿渣硅酸盐水泥'
+            }
+
+            
+          },
+            {codeName: 'C3S', codeValue: []},
+          ]
+
+        }
+       ] , // 参数列表数据
+       activeIndex: 0, // 当前选中的参数索引
+
+       addDialogVisible: false,
+      tableData: [
+        
+      ],
+      tableTypelist: [],
+      pkeyId: '', // 主键ID
+      id:'',
+      projectid:'',
+      checkTableRow: {}, // 当前选中的表单行数据
+      checkEleList: [], // 存储选中的元素
+      linkListData: [
+       
+      
+           
+      ], // 关联关系数据
+
+    
+   
+
+    }
+  },
+  methods: {
+    show(val,treeId,id,projectid,deatailId) {
+      this.getTableTypelist();
+      this.visible = true
+      if(val.length > 0&&val[0].name) {
+        this.treeId = treeId
+        this.id = id
+        this.deatailId = deatailId
+        this.projectid = projectid
+        this.paramList=val
+        val.forEach((item,index)=>{
+          this.handleSelect(index)
+       })
+       this.activeIndex = 0
+      }else{
+        this.paramList = []
+          this.treeId = ''
+      }
+      
+      this.getLinkSetData(this.deatailId);
+    },
+     async getLinkSetData(id, leftId) {
+        try {
+          const res = await getElementJoin({ id, leftId });
+          if (res.data.code === 200) {
+            console.log(res.data.data, '获取的关系数据');
+            this.linkListData = res.data.data; // 直接返回数据
+
+           
+          } else {
+            this.$message.error(res.data.msg);
+            throw new Error(res.data.msg); // 抛出错误,以便在调用处处理
+          }
+        } catch (error) {
+          // 这里可以添加额外的错误处理逻辑,例如记录日志
+          throw error; // 重新抛出错误,以便在调用处捕获
+        }
+      },
+    async handleSelect(index) {
+      this.activeIndex = index
+      let leftId = this.paramList[index].id
+     let arr= await this.getRelationData(this.deatailId,leftId)
+     
+      if(arr.length>0){
+          this.$nextTick(()=>{
+              // this.paramList[index].group = arr[0]['group']
+              this.$set(this.paramList, index, { ...this.paramList[index], group: arr[0]['group'] });
+          })
+
+      }else{
+        this.paramList[index].group = []
+      }
+      
+    },
+   async getRelationData(id,leftId){
+          try {
+          const res = await getElementJoin({ id, leftId });
+          if (res.data.code === 200) {
+            console.log(res.data.data, '获取的条件设置数据');
+            return res.data.data; // 直接返回数据
+          } else {
+            this.$message.error(res.data.msg);
+            throw new Error(res.data.msg); // 抛出错误,以便在调用处处理
+          }
+        } catch (error) {
+          // 这里可以添加额外的错误处理逻辑,例如记录日志
+          throw error; // 重新抛出错误,以便在调用处捕获
+        }
+    },
+     getTableTypelist() {
+      getDictionary({
+        code:'trial_table_type',
+      }).then((res) => {
+        res.data.data.forEach((element) => {
+          element.dictKey = Number(element.dictKey);
+        });
+        this.tableTypelist = res.data.data;
+      });
+    },
+    async getTableData(){
+        const { data: res } = await selectByNodeTable( this.treeId,this.projectid, this.id);
+          if (res.code === 200) {
+            console.log(Array.isArray(res.data));
+            if (Array.isArray(res.data)) {
+              this.tableData = res.data
+            
+            } else {
+              this.tableData = []
+              this.$message.error('获取表单数据失败,请先关联清表');
+            }
+          }
+    },
+    hide() {
+      this.visible = false  
+    },
+  
+    handleConfirm() {
+      
+      saveElementJoin(this.linkListData,this.deatailId).then((res)=>{
+        if(res.data.code === 200) {
+          this.$message({
+            type: 'success',
+            message: res.data.msg,
+          })
+        }else{
+          this.$message({
+            type: 'error',
+            message: res.data.msg,
+          })
+        }
+      })
+      this.hide()
+      this.$emit('confirm')
+    },
+    toggleClick(item, index) {
+        this.linkListData.forEach(listItem => {
+          this.$set(listItem, 'clicked', false);
+        });
+        this.$set(item, 'clicked', !item.clicked);
+        let clickedIndex = this.paramList.findIndex(listItem => listItem.id === item.id);
+        console.log(clickedIndex, 'clickedIndex');
+        this.activeIndex = clickedIndex;
+        
+    },
+    handleDeleteLinkItem(item,index){
+        this.$confirm('删除后,数据将无法恢复,是否确认删除!', '提示', {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning'
+          }).then(() => {
+  
+            deleteElementJoin({leftId:item.id}).then((res) => {
+              if(res.data.code==200){
+                this.$message.success(res.data.msg);
+              
+                this.linkListData.splice(index, 1);
+                this.getLinkSetData(this.deatailId);
+              }else{
+                this.$message.error(res.data.msg);
+              }
+            });
+          }).catch(() => {
+            this.$message.info('已取消删除');
+          })
+    },
+    addCondition() {
+      // 添加条件逻辑
+           this.addDialogVisible = true
+           this.pkeyId = ''
+
+      this.getTableData();
+    },
+   handleSelect1(index) {
+      this.activeIndex = index
+    },
+
+ 
+    handleDeleteItem(item, index) {
+      this.paramList[this.activeIndex].group.splice(index, 1)
+     
+    },
+    confirmAdd() {
+      if (this.checkEleList.length === 0) {
+        this.$message.error('请先选择元素');
+        return;
+      }
+      if (this.checkTableRow.pkeyId === undefined || this.checkTableRow.pkeyId === '') {
+        this.$message.error('请先选择表单');
+        return;
+      }
+      const selectedCodes = this.checkEleList.map(ele => ({
+        colName: ele.keyName,
+        colKey: ele.elementId 
+      }));
+      console.log(selectedCodes,'selectedCodes');
+      console.log(this.paramList,'this.paramList');
+      let objArr={}
+       const elementNames = selectedCodes.map(code => code.colName).join(' ');
+        objArr={
+          
+          privateName: this.checkTableRow.tableName,
+          privateId: this.checkTableRow.pkeyId,
+          elementNames: elementNames,
+          keys: selectedCodes,
+        
+        }
+  
+        
+        this.paramList[this.activeIndex].group.push(objArr);
+    
+  
+         
+
+      this.addDialogVisible = false;
+      this.$message.success('添加成功');
+    },
+    handleElementSelected(val) {
+      console.log(val, '选中的元素');
+      this.checkEleList = val;
+      
+    },
+    //保存条件
+    saveEle(){
+      console.log(this.paramList,'保存条件');
+      
+        const filteredArr = this.paramList.filter(item => item.group.length !== 0);
+        this.linkListData = JSON.parse(JSON.stringify(filteredArr));
+
+    },
+    formatTableType(row, column, cellValue) {
+      for (let i = 0; i < this.tableTypelist.length; i++) {
+        if (this.tableTypelist[i].dictKey == cellValue) {
+          return this.tableTypelist[i].dictValue;
+        }
+      }
+      return cellValue;
+    
+    },
+    handleRowSelect(row) {
+      // 设置选中状态
+     // 先取消其他行的选中状态
+      this.tableData.forEach(item => {
+        if(item !== row) {
+          this.$set(item, 'isSelected', false)
+        }
+      })
+      this.pkeyId = row.pkeyId; // 更新主键ID
+      this.checkTableRow = row; // 更新当前选中的表单行数据
+
+      // 设置当前行选中状态
+      this.$set(row, 'isSelected', true)
+
+    },
+
+    handleCancelSelect(row) {
+       this.checkTableRow = {}; // 清除当前选中的表单行数据
+      this.pkeyId = ''; // 清除主键ID
+      // 取消选中状态
+      this.$set(row, 'isSelected', false)
+
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.conditions-container {
+  display: flex;
+  gap: 20px;
+  font-weight: bold;
+//   height: 200px;
+.green-txt{
+    color: rgb(46, 123, 115);;
+}
+  .conditions-left,
+  .conditions-right {
+    flex: 1;
+    border: 1px solid #EBEEF5;
+    border-radius: 4px;
+      background: #f5f7fa;
+  }
+
+
+
+  .condition-list,
+  .condition-content {
+    padding: 10px;
+  }
+
+  .condition-item {
+    span {
+      display: inline-block;
+      padding: 8px 8px;
+      margin: 5px;
+      background: white;
+      color: #409EFF;
+      border-radius: 4px;
+      cursor: pointer;  // 添加指针样式
+      transition: all 0.3s;  // 添加过渡效果
+       &.active {  // 选中状态
+        background:  #67C23A;;
+        color: white;
+        }
+    }
+  }
+
+  .content-item {
+    margin-bottom: 10px;
+    padding: 10px;
+    border: 1px solid #EBEEF5;
+    border-radius: 4px;
+
+    .item-title {
+      display: flex;
+      gap: 10px;
+      align-items: center;
+      
+      span {
+        &:first-child {
+          color: #666;
+        }
+        &:nth-child(2) {
+          color: #409EFF;
+        }
+        &:last-child {
+          color: #666;
+        }
+      }
+    }
+  }
+}
+.dialog-title {
+  display: flex;
+  flex-direction: column;
+  color:white ;
+  padding: 10px;
+   font-size: 14px;
+
+ .marginTop-20{
+    margin-top: 10px;
+ }
+      background: rgb(37, 80, 162);
+      .el-dialog__header{
+        padding: 0px;
+         
+      
+      }
+}
+.condition-header1 {
+  display: flex;
+  justify-content: space-between; // 两端对齐
+  align-items: center;
+  padding: 10px;
+  border-bottom: 1px solid #EBEEF5;
+
+  .header-left {
+    display: flex;
+    align-items: center;
+    
+    span {
+      font-weight: bold;
+      margin-left: 10px;
+     
+    }
+  }
+
+  .header-right {
+    display: flex;
+    gap: 10px; // 按钮间距
+
+    .el-button {
+      padding: 7px 15px;
+      
+      &:hover {
+        opacity: 0.8;
+      }
+    }
+  }
+}
+.code-list{
+    display: flex;
+            font-weight: bold;
+    .code-item{
+        margin-right: 5px;
+        margin-top: 5px;
+
+    }
+}
+
+  .condition-item1 {
+    display: flex;
+    span {
+        margin-left: 5px;
+      display: inline-block;
+      padding: 8px 8px;
+    
+     
+    background: rgb(213, 222, 255);;
+          color:  rgba(37,80,162,1);
+      border-radius: 4px;
+      cursor: pointer;  // 添加指针样式
+      transition: all 0.3s;  // 添加过渡效果
+      height: 40px;
+      
+    }
+  }
+.condition-header-content {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 100%;
+  
+  .delete-icon {
+    color: #F56C6C;
+    cursor: pointer;
+    font-size: 16px;
+    
+    &:hover {
+      opacity: 0.8;
+    }
+  }
+}
+.result-container{
+  width: 100%;
+  border: 1px solid #EBEEF5;
+  border-radius: 4px;
+  background: #f5f7fa;
+  margin-top: 10px;
+}
+  .condition-header {
+    display: flex;
+    // justify-content: space-between;
+    align-items: center;
+    padding: 10px;
+    border-bottom: 1px solid #EBEEF5;
+  
+
+    span {
+      font-weight: bold;
+      margin-left: 10px;
+    }
+  }
+  .link-list{
+    max-height: 350px;
+    overflow-y: auto;
+    padding: 10px;
+    font-weight: bold;
+   
+    .link-item{
+      display: flex;
+      align-items: center;
+      padding: 10px;
+      background-color: white;
+      border-radius: 10px;
+      cursor: pointer; // 添加指针样式
+      position: relative; // 添加相对定位
+      margin-bottom: 10px;
+        &.clicked {
+          background-color: #e0e0e0; // 点击时的背景色
+        }
+       
+       .el-icon-close {
+                    position: absolute; // 绝对定位
+                    top: 30%; // 垂直居中
+                    right: 10px; // 距离右侧10px
+                    transform: translateY(-50%); // 垂直方向上的偏移量,确保图标垂直居中
+                    color: #F56C6C; // 删除图标的颜色
+                    cursor: pointer; // 添加指针样式
+                    font-size: 16px; // 图标大小
+
+                    &:hover {
+                      opacity: 0.8; // 悬停效果
+                  }
+          }
+      .link-name{
+        flex-shrink: 0;
+        background-color: rgb(167, 224, 218);
+        color: rgba(46, 123, 115, 1);
+        border-radius: 5px;
+        text-align: center;
+    
+        padding:8px;
+        margin-right: 15px;
+
+      }
+      .code-list{
+        margin-left: 15px;
+        display: flex;
+
+       
+        overflow-x: auto;
+           font-weight: bold;
+          .code-item {
+              // display: flex;
+              margin-bottom: 10px;
+              flex-shrink: 0;
+                  margin-left: 5px;
+       
+                padding:8px;
+              
+              
+              background: rgb(213, 222, 255);;
+                color: #409EFF;
+                border-radius: 4px;
+           
+                transition: all 0.3s;  // 添加过渡效果
+                height: 50px;
+                
+              .code-title{
+                color: black;
+                margin-bottom: 10px;
+              }
+              .code-detail{
+                color:  rgba(37,80,162,1);
+              }
+            }
+      }
+    }
+  }
+</style>
+<style lang="scss">
+.dialog-set {
+
+
+      .el-drawer__header{
+        padding: 0px;
+              background: rgb(37, 80, 162);
+              font-family: 16px;
+      
+      }
+        // ...现有样式...
+  .el-drawer {
+    height: 95% !important; // 增加抽屉高度
+
+    .el-drawer__body {
+      height: calc(100% - 100px); // 减去头部和底部的高度
+      overflow-y: auto; // 添加滚动
+      padding: 20px;
+    }
+
+    
+    .dialog-footer {
+      position: absolute;
+      bottom: 0;
+      width: 100%;
+      padding: 10px 20px;
+      text-align: center;
+      background: white;
+      border-top: 1px solid #EBEEF5;
+    }
+  }
+      
+      
+}
+
+</style>

+ 253 - 0
src/views/codeRule/PreviewResult.vue

@@ -0,0 +1,253 @@
+<template>
+  <el-dialog
+    title="效果预览"
+    :visible.sync="visible"
+    width="60%"
+    append-to-body
+  >
+    <div class="title-container">
+            <span>样品信息</span>
+    </div>
+    <div class="preview-container">
+      <!-- 样品信息区域 -->
+        
+      <div class="sample-info">
+       <div class="info-grid">
+         <div class="info-row" v-for="(item,index) in ypList" :key="item.id">
+          <el-select  v-model="selectedValues[index]" placeholder="请选择" class="info-select" clearable   @change="handleSelectChange(index, $event)">
+            <el-option  v-for="(item1,index1) in item.info" :label="item1.name" :value="item1.id" :key="item1.id"></el-option>
+          </el-select>
+        </div>
+       </div>
+
+      </div>
+
+      <!-- 技术指标区域 -->
+      <div class="tech-specs">
+           <div class="title-container">
+                    <span>技术指标</span>
+            </div>
+        <div class="tech-content" v-for="item in jsList" :key="item.id" >
+          <div class="tech-item">
+            <div class="tech-label">{{ item.name }}</div>
+            <div class="tech-val">{{ item.symbolName }}</div>
+          </div>
+
+          <div class="tech-item-list"  v-for="item1 in item.group" :key="item1.id">
+            <div class="tech-item-1">
+                <div  class="tech-label">表单名称</div>
+                <div class="tech-val">{{ item1.privateName }}</div>
+            </div>
+             <div class="tech-item-1">
+                <div class="tech-label">回显位置</div>
+                <div  class="tech-val">{{ item1.elementNames }}</div>
+            </div>
+           
+          </div>
+
+        
+        </div>
+      </div>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import {effectPreview } from "@/api/ruleManage/fileRule.js";
+export default {
+  name: 'PreviewResult',
+  props: {
+    ypList: {
+      type: Array,
+      required: true,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      visible: false,
+      jsList:[],
+      selectedValues: [],
+      preViewLoad:false,
+    }
+  },
+  created() {
+    // 在组件创建时初始化 selectedValues
+    this.initializeSelectedValues();
+  },
+  methods: {
+      show() {
+        this.visible = true
+         this.initializeSelectedValues();
+          this.jsList = [];
+          
+      },
+       initializeSelectedValues() {
+          // 根据 ypList 的长度初始化 selectedValues
+           this.selectedValues = new Array(this.ypList.length).fill('');
+       
+          
+        },
+         handleSelectChange(index, value) {
+          this.selectedValues[index] = value;
+            const ids = this.selectedValues.filter(val => val !== '').join(',');
+            
+            
+            if (ids !== '') {
+              this.getPreviewData(ids);
+            }else{
+              this.jsList = [];
+            }
+
+
+         
+        },
+        getPreviewData(ids){
+          this.preViewLoad = true;
+            effectPreview({
+              ids: ids
+            
+            }).then((res) => {
+                  this.preViewLoad = false;
+              if (res.data.code === 200) {
+                this.jsList = res.data.data;
+            
+              
+               
+                
+
+              } else {
+                  this.preViewLoad = false;
+                this.jsList = [];
+                this.$message.error(res.data.msg);
+              }
+            });
+         },
+   },
+
+
+    watch: {
+    // 如果 ypList 是异步加载的,您可以在这里监听它的变化并更新 selectedValues
+    ypList(newVal) {
+    
+      if (newVal.length !== this.selectedValues.length) {
+        this.initializeSelectedValues();
+      }
+    }
+  
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.title-container{
+    color:  rgba(130, 130, 130, 1);
+    margin-bottom: 10px;
+    font-weight: bold;
+    background: rgb(240, 240, 240);
+ 
+    padding: 10px 20px;
+    border-radius: 5px;
+
+}
+.preview-container {
+ 
+
+  .sample-info {
+    padding: 20px;
+    
+    .info-grid {
+      display: grid;
+      grid-template-columns: repeat(3, 1fr); // 每行3列
+      gap: 20px; // 设置间距
+      width: 100%;
+    }
+
+    .info-row {
+      display: flex;
+      align-items: center;
+
+      .info-select {
+        width: 100%; // 让select填满容器
+        max-width: 300px; // 限制最大宽度
+      }
+    }
+  }
+  .info-row {
+    display: flex;
+    align-items: center;
+    margin-bottom: 1px;
+
+
+    .label {
+      width: 80px;
+      color: #606266;
+    }
+
+    .info-select {
+      width: 300px
+    }
+  }
+
+  .tech-specs {
+    .tech-title {
+      font-size: 16px;
+      font-weight: bold;
+      margin-bottom: 20px;
+      color: #303133;
+    }
+     .tech-label {
+        
+          color:rgba(130, 130, 130, 1);
+        }
+        .tech-val{
+            color: black;
+            font-family: SourceHanSansSC;
+        }
+    .tech-content {
+      .tech-item {
+        display: flex;
+        align-items: center;
+        margin-bottom: 15px;
+        justify-content: space-between;
+        border: 1px solid rgb(187, 187, 187);
+        border-radius: 5px;
+        padding: 10px;
+
+   
+
+        .tech-input {
+          width: 300px;
+
+          ::v-deep .el-input-group__append {
+            background-color: #f5f7fa;
+            color: #909399;
+            min-width: 120px;
+          }
+        }
+      }
+      .tech-item-list{
+        display: flex;
+        flex-direction: column;
+        margin-top: 10px;
+        background-color: #f5f7fa;
+         border: 1px solid rgb(187, 187, 187);
+        border-radius: 5px;
+        padding: 8px;
+        max-height: 300px;
+        overflow-y: auto;
+        .tech-item-1 {
+          display: flex;
+          justify-content: space-between;
+         align-items: center;
+         line-height: 30px;
+        
+        
+
+        
+        }
+      }
+    }
+  }
+}
+</style>

+ 227 - 0
src/views/codeRule/checkEleHtml.vue

@@ -0,0 +1,227 @@
+<template>
+  <div class="excelHtnl">
+
+    <div
+      class="excelBox hc-excel-table-form"
+      style="margin-top:40px;height: 100%;"
+      @click="parentClick($event)"
+    >
+      <div style="width:100%;height: 100%;overflow: scroll;" class='parent' id='parent'></div>
+      
+    </div>
+  </div>
+</template>
+
+<script>
+
+import Vue from 'vue'
+import {getExcelHtml} from '@/api/exctab/excelmodel'
+
+
+export default {
+  props: ['pkeyId'],
+  data() {
+    return {
+      selectedElements: [] ,// 存储已选中的元素
+      exHtml:''
+    }
+  },
+  watch: {
+    pkeyId: {
+      immediate: true,
+      deep: true,
+      handler(newVal) {
+        if(newVal) {
+          this.exHtml = ''
+          this.getExcelHtml(newVal)// 重新初始化数据
+        
+        }else {
+          this.exHtml = ''
+           this.clearForm()
+        }
+      }
+    }
+  },
+  mounted() {
+
+  
+  },
+
+
+  methods: {
+
+    async getExcelHtml(pkeyId) {
+      const {data: res} = await getExcelHtml({pkeyId})
+      if (res.code === 200) {
+        this.exHtml = res.data
+        this.cop();
+      }
+    },
+      // 新增清空表单方法
+  clearForm() {
+    const parentElement = document.getElementById('parent')
+    console.log(parentElement, 'parentElement');
+    
+    if(parentElement) {
+      // 清空父元素内容
+      parentElement.innerHTML = ''
+    }
+    // 清空已选中元素
+    this.clearAllSelected()
+  },
+    async cop() {
+      let _that = this
+      var MyComponent = await Vue.extend({
+        template: this.exHtml ,
+        data() {
+          return {
+            formData: {},
+            getTokenHeader: {},
+            dap_site_data: {}
+          }
+        },
+        methods: {
+          contextmenuClick(tr, td, x1, x2, y1, y2, event) {
+          },
+          getInformation(name, tr, td) {//鼠标右键事件
+            
+          },
+          formUploadSuccess() {
+          },
+          formUploadExceed() {
+          },
+          formUploadLoading() {
+          },
+          delTableFormFile() {
+          },
+          formUploadError() {
+          },
+          uploadprogress() {
+          },
+          formRemoteMethod() {
+          },
+          getRegularExpression() {
+          },
+          checkboxGroupChange() {
+          },
+          formRemoteChange() {
+          },
+          dateKeydown() {
+          },
+          keyupShiftUp() {
+          },
+          keyupShiftDown() {
+          },
+          keyupShiftLeft() {
+          },
+          keyupShiftRight() {
+          },
+          inputLeftClick() {
+          },
+        }
+      })
+      var component = new MyComponent().$mount()
+      document.getElementById('parent').appendChild(component.$el);
+    },
+
+
+
+ 
+    //excel父节点点击检测
+      async parentClick(e) {
+      let target = e.target;
+        const elementId = target.id;
+        const keyName = target.placeholder;
+        // 判断元素是否已选中
+        const index = this.selectedElements.findIndex(item => item.elementId === elementId);
+        if (index === -1) {
+          // 添加选中效果
+          target.style.backgroundColor = '#ffa500'; // 橙色背景
+          this.selectedElements.push({elementId, keyName}); // 存储选中元素的id和keyName
+        } else {  
+          // 取消选中效果
+          target.style.backgroundColor = ''; // 恢复默认背景
+          this.selectedElements.splice(index, 1);
+        }
+        
+        // 触发选中元素变化事件
+        this.$emit('element-selected', this.selectedElements);
+
+      
+    },
+        // 清除所有选中状态的方法
+    clearAllSelected() {
+      this.selectedElements.forEach(item => {
+        const element = document.getElementById(item.elementId);
+        if (element) {
+          element.style.backgroundColor = '';
+        }
+      });
+      this.selectedElements = [];
+    },
+
+    getParentTD(ele) {
+      let targetParent = ele.parentNode;
+      while (targetParent.nodeName !== "TD") {
+        if (targetParent.id == 'parent') {
+          return null;
+        }
+        targetParent = targetParent.parentNode;
+      }
+      return targetParent;
+    },
+
+
+
+
+  },
+
+}
+</script>
+
+<style lang="scss" scoped>
+.excelHtnl {
+  margin: 0 0 0 10px;
+  background-color: #fff;
+  box-sizing: border-box;
+  padding: 0 20px 100px 20px;
+  height: 100%;
+}
+
+// 设置图片样式
+.hc-upload-table-form {
+  position: relative;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.hc-upload-table-form .el-upload {
+  position: relative;
+  flex: 1;
+  height: 100%;
+  color: #ccc;
+}
+.hc-upload-table-form .el-upload .hc-table-form-icon {
+  font-size: 24px;
+  font-weight: 100;
+}
+.hc-upload-table-form .el-upload .hc-table-form-img {
+  width: 100%;
+  height: 100%;
+}
+
+.excelBox {
+  ::v-deep .oldlace-bg {
+    background-color: oldlace;
+  }
+  ::v-deep .select-td {
+    border-width: 4px;
+    border-color: #E6A23C;
+    border-style: solid;
+  }
+}
+</style>
+
+
+

+ 1567 - 0
src/views/codeRule/ruleManage.vue

@@ -0,0 +1,1567 @@
+<template>
+  <div class="container-box">
+     <el-row :gutter="20" class="h-100">
+        <el-col :span="6" class="h-100">
+                <div class="h-100">
+                <el-card class="box-card h-100">
+                    <div class="tree-container">
+                    <el-scrollbar>
+                        <el-tree 
+                        lazy
+                        :load="loadNode"
+                        @node-click="handleNodeClick"
+                        :props="defaultProps"
+                        :expand-on-click-node="false"
+                        :default-expanded-keys="defaultExpandedKeys"
+                        :current-node-key="curreenttid"
+                        highlight-current
+                        node-key="id"
+                        ref="tree"
+                        ></el-tree>
+                    </el-scrollbar>
+                    </div>
+                </el-card>
+                </div>
+        </el-col>
+      <template v-if="!isShowDetail">
+          <el-col :span="18" class="h-100" v-if="isShowList">
+            <div class="h-100 rule-box-all">
+               
+                <el-card class="box-card  h-100">
+                <div slot="header" class="clearfix">
+                 
+                      <el-link type="primary" @click="goBackFirst">   
+                        <i class="el-icon-arrow-left" style="margin-right: 5px; "></i>
+                        <span>退出</span>
+                  </el-link>
+                        <div style="float: right;">
+                            <el-button
+                            :disabled="!treeId"
+                            icon="el-icon-plus"
+                            size="small"
+                            style="background-color:#2550A2;color:white;font-weight:bold;"
+                            plain
+                            @click="addRule"
+                            >新增
+                            </el-button>
+                            <el-button
+                             :disabled="!treeId"
+                            icon="el-icon-document-copy"
+                            size="small"
+                            style="background-color:#FFA042;color:white;font-weight:bold;"
+                            plain
+                            @click="manageFolder"
+                            >管理
+                            </el-button>
+                            
+                         
+                        </div>
+                </div>
+                <div v-if="ruleItemOptions.length>0">
+                  <div class="rule-box" v-loading="ruleLoading">
+                      <div class="rule-box-item" v-for="(item,index) in ruleItemOptions" :key="index" @click="ruleDetailClick(item)" >
+                          <div class="rule-box-item-icon">
+                            <i class="el-icon-folder" style=" cursor: pointer; font-size: 48px;color:orange"></i>
+                          </div>
+                          <div class="rule-box-item-title">{{ item.name }}</div>
+                      </div>
+                      
+                  </div>
+                  
+                  <el-pagination
+                  style="margin-top: 30px;text-align: center;"
+                        @size-change="handleSizeChange"
+                        @current-change="handleCurrentChange"
+                        :current-page="currentPage"
+                        :page-size="pageSize"
+                        :total="ruleItemOptions.length"
+                        layout="prev, pager, next"
+                        class="pagination"
+                      >
+                  </el-pagination>
+
+                </div>
+                <el-empty description="暂无数据" v-else class="empty-container"></el-empty>
+                </el-card>
+            </div>
+        </el-col>
+         <el-col :span="18" class="h-100" v-if="!isShowList">
+            <div class="h-100 rule-box-all">
+               
+                <el-card class="box-card  h-100">
+                <div slot="header" class="clearfix">
+                  <el-link type="primary" @click="goBack">
+                    <i class="el-icon-arrow-left" style="margin-right: 5px;"></i>
+                    <span >返回上一级</span>
+                  </el-link>
+                        <div style="float: right;">
+                            <el-button
+                           
+                            icon="el-icon-plus"
+                            size="small"
+                            style="background-color:#2550A2;color:white;font-weight:bold;"
+                            plain
+                            @click="addFile"
+                            >新增
+                            </el-button>
+                            <el-button
+                            
+                            icon="el-icon-document-copy"
+                            size="small"
+                            style="background-color:#FFA042;color:white;font-weight:bold;"
+                            plain
+                            @click="manageFolder"
+                            >管理
+                            </el-button>
+                            
+                         
+                        </div>
+                </div>
+                <div class="rule-box" v-loading="ruleItemOptionsDetailLoading" v-if="ruleItemOptionsDetail.length>0">
+                    <div class="rule-box-item" v-for="item in ruleItemOptionsDetail" :key="item.id" @click="ruleDetailClick1(item)">
+                        <div class="rule-box-item-icon">
+                          <i class="el-icon-tickets" style=" cursor: pointer; font-size: 48px;color:#2550A2"></i>
+                        </div>
+                        <div class="rule-box-item-title">{{ item.name }}</div>
+                    </div>
+                    
+                </div>
+                 <el-empty description="暂无数据" v-else class="empty-container"></el-empty>
+                <el-pagination
+                    style="margin-top: 30px;text-align: center;"
+                      @size-change="handleSizeChange1"
+                      @current-change="handleCurrentChange1"
+                      :current-page="currentPage1"
+                      :page-size="pageSize1"
+                      :total="total"
+                      layout="prev, pager, next"
+                      class="pagination"
+                    >
+                    </el-pagination>
+                </el-card>
+            </div>
+        </el-col>
+      </template>
+        <el-col :span="18" class="h-100" v-if="isShowDetail">
+             
+            <el-card class="box-card  h-100" v-if="isShowYpList">
+                <div slot="header" class="clearfix">
+                
+                    <el-link type="primary" @click="goBack1">
+                    <i class="el-icon-arrow-left" style="margin-right: 5px;"></i>
+                    <span >返回上一级</span>
+                  </el-link>
+                </div>
+                <div class="box-card-title">
+                {{ ruleDataDetail.name }}
+                </div>
+                <div class="box-card-content1">
+                    <div  class="box-card-content1-left">
+                      <div class="box-card-content1-left-item">
+                        下达日期:{{ ruleDataDetail.issueDate }}
+                      </div>
+                      <div class="box-card-content1-left-item">
+                        实施日期:{{ ruleDataDetail.actualizeDate }}
+                      </div>
+                      <div>
+                      <i class="el-icon-document"></i>
+
+                      <el-link v-for="item in ruleDataDetail.standardFiles" :key="item.id" type="primary" :href="item.standardFileUrl"  style="margin-right: 5px;">{{ item.fileName }}</el-link>
+                      
+
+                      </div>
+                    </div>
+                    <div  class="box-card-content1-right">
+                        <el-button type="danger" size="small" @click="previewRes">效果预览</el-button>
+                        <el-button type="warning" size="small">规范更新</el-button>
+                    </div>
+                </div>
+                <div class="box-card-content2">
+                  <div class="box-card-content2-top">
+                    <div class="box-card-content2-title">
+                     <div class="title-container">
+                      <span>样品信息</span>
+                      <i class="el-icon-circle-plus" @click="addYp"></i>
+                    </div>
+                    </div>
+                    <div class="box-card-content2-list">
+                      <div class="box-card-content2-list-item" v-for="(item, index) in ypList" :key="index">
+                        <div class="box-card-content2-list-item-title">
+                           <span class="eg">if()</span>
+                          <span>{{ item.name }}</span>
+                        </div>
+                        <div class="box-card-content2-list-item-list">
+                                <span class="basic-info">基础信息</span>
+                                <div class="box-card-content2-list-item-list-basic">
+                                    <div class="basic-item-info" v-for="(item1,index1) in item.info":key="index1" >
+                                      {{ item1.name }}
+                                    </div>
+                                    <div class="operation-icons">
+                                      <i class="el-icon-edit" @click.stop="handleEdit(item, index)"></i>
+                                      <i class="el-icon-delete" @click.stop="handleDelete(item,index)"></i>
+                                    </div>
+                                </div>
+                        </div>
+
+                      </div>
+
+                    </div>
+                  </div>
+                        <div class="box-card-content2-top">
+                    <div class="box-card-content2-title">
+                     <div class="title-container">
+                      <span>技术指标</span>
+                      <i class="el-icon-circle-plus" @click="addJs"></i>
+                    </div>
+                    </div>
+                    <div class="box-card-content2-list">
+                      <div class="box-card-content2-list-item" v-for="(item, index) in jsList" :key="index">
+                        <div class="box-card-content2-list-item-title">
+                           <span class="eg">else()</span>
+                          <span>{{ item.name }}</span>
+                        </div>
+                        <div class="box-card-content2-list-item-list">
+                                <span class="basic-info">内容</span>
+                                <div class="box-card-content2-list-item-list-basic">
+                                    <div class="basic-item-info" v-for="(item1,index1) in item.info":key="index1" >
+                                      {{ item1.symbolName }}
+                                    </div>
+                                    <div class="operation-icons">
+                                      <i class="el-icon-edit" @click.stop="handleEditJs1(item, index)"></i>
+                                      <i class="el-icon-delete" @click.stop="handleDelete1(item,index)"></i>
+                                    </div>
+                                </div>
+                        </div>
+
+                      </div>
+
+                    </div>
+                  </div>
+                  
+                </div>
+           
+                </el-card>
+              <el-card class="box-card  h-100" v-if="!isShowYpList&&!isShowJsList">
+                <template >
+                  <div slot="header" class="clearfix" >
+                   <el-link type="primary"  @click="showYpList">
+                       <i class="el-icon-arrow-left" style="margin-right: 5px; cursor: pointer;" ></i>
+                      <span  >退出</span>
+                    </el-link>
+                </div>
+                <div class="add-yp-title">
+                  <span>{{ isEditYp?'编辑':'新增' }}</span>
+                </div>
+                <div class="add-yp-detail">
+                  <el-form label-position="left" label-width="80px" :model="ypDetail"  :rules="ypRuleForm" ref="ypFormRef">
+                    <el-form-item label="样品信息" prop="name">
+                      <el-input v-model="ypDetail.name"></el-input>
+                    </el-form-item>
+                    <el-form-item label="基础信息">
+                      <div class="input-with-icon"  v-for="(item, index) in ypDetail.info" :key="index">
+                        <el-input v-model="item.name"></el-input>
+                        <i class="el-icon-circle-plus-outline" @click="addBasicInfo(index)" ></i>
+                        <i class="el-icon-remove-outline" @click="removeBasicInfo(item,index)"  v-if="index!==0"></i>
+                      </div>
+                    </el-form-item>
+                    
+                  </el-form>
+                </div>
+                <div class="add-yp-footer">
+                   <el-button type="primary" @click="saveYpForm" :loading="saveYpLoad">保存</el-button>
+                </div>
+                </template>
+    
+            </el-card>
+            <el-card v-if="isShowJsList&&!isShowYpList">
+              <div slot="header" class="clearfix" >
+                    <el-link type="primary"  @click="showYpList">
+                      <i class="el-icon-arrow-left" style="margin-right: 5px; cursor: pointer;" ></i>
+                      <span >退出</span>
+                    </el-link>
+                </div>
+                <div class="add-yp-title">
+                  <span>{{ isEditJs?'编辑':'新增' }}</span>
+                  <div v-if="isEditJs">
+                     <el-button  size="small" style="background: rgb(168, 86, 248);color: white;" icon="el-icon-office-building" @click="conditionsSet">条件设置</el-button>
+                         <el-button  size="small" style="background:rgb(37, 80, 162);;color: white;" icon="el-icon-connection" @click="linkEle">关联元素</el-button>
+                  </div>
+                </div>
+                <div class="add-yp-detail">
+                  <el-form label-position="left" label-width="80px" :model="jsDetail"  :rules="jsRuleForm" ref="jsFormRef">
+                    <el-form-item label="检测项" prop="name">
+                      <el-input v-model="jsDetail.name"></el-input>
+                    </el-form-item>
+                    <el-form-item label="技术指标">
+                      <div class="input-with-icon"  v-for="(item, index) in jsDetail.info" :key="index">
+                        <el-input placeholder="请输入内容" v-model="item.name" class="input-with-select">
+                          <el-select v-model="item.symbol" slot="prepend" placeholder="请选择符号" style="width: 150px;">
+                            <el-option  v-for="(item1,index) in fqOptions" :key="index" :label="item1.dictKey" :value="item1.dictKey"></el-option>
+                          </el-select>
+                          
+                        </el-input>
+                        <i class="el-icon-circle-plus-outline" @click="addBasicInfo1(index)"  ></i>
+                        <i class="el-icon-remove-outline" @click="removeBasicInfo1(item,index)" v-if="index!==0"></i>
+                      </div>
+                    </el-form-item>
+                    
+                  </el-form>
+                </div>
+                <div class="add-yp-footer">
+                   <el-button type="primary" @click="addJsForm" :loading="addJsFormLoad">保存</el-button>
+                </div>
+            </el-card>
+              
+         </el-col>
+    </el-row>
+    <!-- 新增文件夹 -->
+    <el-dialog
+      title="新增"
+      :visible.sync="addDialogVisible"
+      width="30%"
+      append-to-body
+
+      >
+      <div class="input-container">
+        <span>规范文件夹名称</span>
+        <el-input v-model="titleInput" placeholder="请输入内容" style="width: 300px;"></el-input>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="addDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="addSaveFileClick" :loading="addSaveFileLoad">确 定</el-button>
+      </span>
+    </el-dialog>
+    <!-- 管理规范 -->
+     <el-dialog title="管理" :visible.sync="manageVisible" width="50%" append-to-body>
+        <el-table :data="manageData" border   height="550">
+          <el-table-column property="name" label="规范名称" >
+            <template slot-scope="scope">
+              
+              <el-input v-model="scope.row.name" placeholder="请输入内容"></el-input>
+            </template>
+
+          </el-table-column>
+          <el-table-column property="name" label="文件名称" v-if="!isShowList" >
+            <template slot-scope="scope">
+              
+              <el-input v-model="scope.row.standardFile.fileName" placeholder="请输入内容"></el-input>
+              <el-button
+                type="text"
+                size="small"
+                style="color: rgb(219, 55, 55);"
+                @click="delFile(scope.row,scope.$index )"
+              >
+                <i class="el-icon-delete"></i> 删除
+    </el-button>
+            </template>
+
+          </el-table-column>
+          
+          <el-table-column label="操作" width="200">
+            <template slot-scope="scope">
+        
+       
+           
+              <el-upload
+              v-if="!isShowList"
+                class="upload-demo"
+                action="#"
+                 :on-change="file => handleFileUpload(file, scope.row, scope.$index)"
+                :before-upload="beforeUpload"
+                :show-file-list="false"
+                :auto-upload="false"
+              >
+                 <el-button size="small" type="text">文件上传</el-button>
+              </el-upload>
+             
+         
+              <el-button type="text" size="small" style="color: rgb(219, 55, 55);" @click="delManange(scope.$index,scope.row)">删除</el-button>
+            </template>
+
+          </el-table-column>
+         
+        </el-table>
+          <div slot="footer" class="dialog-footer">
+          <el-button @click="manageVisible = false">取 消</el-button>
+          <el-button type="primary" @click="manageSave" :loading="manageLoad">确 定</el-button>
+        </div>
+      </el-dialog>
+
+      <!-- 新增规范文件 -->
+       <el-dialog title="新增" :visible.sync="addFileDialogVisible"  append-to-body width="30%">
+        <el-form :model="fileForm" label-position="left" label-width="80px" :rules="fileRuleForm" ref="fileFormRef">
+          <el-form-item label="规范名称" prop="name" >
+            <el-input v-model="fileForm.name" ></el-input>
+          </el-form-item>
+          <el-form-item label="下达日期" >
+            <el-date-picker
+            style="width: 100%;"
+              format="yyyy 年 MM 月 dd 日"
+              value-format="yyyy-MM-dd"
+              v-model="fileForm.issueDate"
+              type="date"
+              placeholder="选择日期">
+            </el-date-picker>
+          </el-form-item>
+          <el-form-item label="实施日期" >
+            <el-date-picker
+               format="yyyy 年 MM 月 dd 日"
+              value-format="yyyy-MM-dd"
+            style="width: 100%;"
+              v-model="fileForm.actualizeDate"
+              type="date"
+              placeholder="选择日期">
+            </el-date-picker>
+          </el-form-item>
+          <el-form-item label="规范文件" >
+            <el-upload
+              :auto-upload="false"
+              multiple
+              class="upload-demo"
+              action="#"
+              :file-list="fileForm.standardFileUrl"
+              :on-change="uploadImportData"
+           
+              >
+              <el-button size="small" type="primary">点击上传</el-button>
+              <div slot="tip" class="el-upload__tip">允许文件格式.pdf</div>
+            </el-upload>
+          </el-form-item>
+          
+        </el-form>
+        <div slot="footer" class="dialog-footer">
+          <el-button @click="addFileDialogVisible = false">取 消</el-button>
+          <el-button type="primary" @click="addFileRoleForm" :loading="addFileRuleLoad">确 定</el-button>
+        </div>
+      </el-dialog>
+
+      <!-- 条件设置 -->
+        <ConditionsSet ref="conditionsSetRef" @confirm="handleConditionsConfirm" />
+        <!-- 关联元素 -->
+        <LinkEle ref="linkEleRef" @confirm="confirmLinkEle" />
+        <!-- 效果预览 -->
+          <PreviewResult ref="previewResultRef" :ypList="ypList"/>
+   </div>
+</template>
+<script>
+import {getLazytree} from "@/api/manager/wbsprivate";
+import ConditionsSet from './ConditionsSet.vue'
+import LinkEle from "./LinkEle.vue";
+import PreviewResult from './PreviewResult.vue'
+import {getPage,edit,add,deleteItem,getById, addInfo,editInfo,getInfoPage,deleteItemInfo,updateTypeByTwo } from "@/api/ruleManage/fileRule.js";
+import { getStore, setStore } from "@/util/store";
+ import { getDictionary } from "@/api/system/dict";
+  export default {
+  components: {
+    ConditionsSet,
+    LinkEle,
+    PreviewResult
+  },
+    data() {
+      return {
+        id: '',
+        parentId: '',
+        tenant_id:'',
+        projectid:'',
+        treeId: '',
+
+        defaultProps: {
+            children: "children",
+            label: "title",
+            isLeaf: function (data) {
+            return !data.hasChildren || (data.isExistForm==1);
+            },
+        },
+        defaultExpandedKeys: [],
+        curreenttid: '',
+         expandName: this.$route.fullPath,
+        ruleItemOptions:[
+          
+         
+   
+        ],
+        total: 0,
+        ruleLoading: false,
+        addDialogVisible:false,
+        addSaveFileLoad:false,
+        titleInput:'',
+        isShowList:true,
+        ruleItemOptionsDetail:[],
+        ruleItemOptionsDetailLoading: false,
+        currentPage: 1,
+        pageSize: 40, // 8列 * 5行 = 40
+        currentPage1: 1,
+        ruleItem: {},
+        ruleItemDetail: {},
+        pageSize1: 40, // 8列 * 5行 = 40
+        isShowYpList:true,
+        isShowDetail:false,
+        ruleDataDetail: {},
+        ypDetail: {
+          name: '',
+          info: [{ name: '' }]
+        },
+        saveYpLoad: false,
+        ypRuleForm: {
+          name: [
+            { required: true, message: '请输入样品名称', trigger: 'blur' }
+          ],
+        
+        },
+        manageVisible: false,
+        manageData: [],
+        manageLoad: false,
+        addFileDialogVisible:false,
+        addFileRuleLoad:false,
+        fileForm:{
+          standardFileUrl: [], // 用于展示的文件列表
+          files: [] // 存储实际的文件对象
+        },
+        fileRuleForm:{
+          name: [
+            { required: true, message: '请输入规范名称', trigger: 'blur' }
+          ],
+        },
+        ypList:[
+          {id:1,name:'样品名称',
+          info:
+          [{}]
+          },  
+        ],
+        jsList:[
+          {id:1,name:'技术指标名称',
+          info:
+          []
+          },  
+        ],
+        isShowJsList:false,
+        isEditYp: false,
+        isEditJs: false,
+
+        jsDetail: {
+          name: '',
+          info: [{ name: '',symbol:'' }, ]
+        },
+        addJsFormLoad: false,
+        jsRuleForm: {
+          name: [
+            { required: true, message: '请输入技术指标名称', trigger: 'blur' }
+          ],
+        },
+        fqOptions: [
+        ],
+        conditionsSetVisible:false,//条件设置弹窗是否显示
+        isUploadVisible:false,//上传文件弹窗是否显示
+        delIds:[],
+        delFileIds:[]
+
+
+       
+      };
+    },
+
+    created(){
+        this.getFqOptions()
+        const { id, tenant_id,projectid} = this.$route.query;
+        this.id = id;
+        this.parentId = 0;
+        this.tenant_id = tenant_id;
+        this.projectid = projectid;
+        this.defaultExpandedKeys = getStore({ name: this.expandName });
+        this.curreenttid= getStore({ name:'curreenttid' });
+        if (this.curreenttid) {
+          this.treeId = this.curreenttid;
+          this.getRuleItemOptions();
+        } 
+    },
+    methods: {
+      //获取符号字典
+      getFqOptions(){
+            getDictionary({
+                    code: "u_standard_symbol",
+                }).then((res) => {
+                    this.fqOptions = res.data.data;
+                });
+      },
+      //获取规范文件夹数据
+      getRuleItemOptions() {
+        this.ruleLoading = true;
+        getPage({
+          privateId:this.treeId,
+          current:this.currentPage,
+          size:this.pageSize,
+          type: 1,
+        }).then((res) => {
+           this.ruleLoading = false;
+          if (res.data.code === 200) {
+            this.ruleItemOptions = res.data.data.records;
+            this.total = res.data.data.total;
+        
+            
+          } else {
+             this.ruleItemOptions=[]
+            this.$message.error(res.data.msg);
+          }
+        });
+      },
+
+      handleNodeClick(data,node) {
+       
+        this.treeId = data.primaryKeyId;
+        
+        this.getRuleItemOptions()
+          //获取节点展开路径
+        this.getExpandedKeys(node);
+        setStore({
+          name: 'curreenttid',
+          content: data.id,
+          type: true, //sessionStorage
+        });
+          this.isShowList = true;
+          this.isShowDetail=false
+      },
+     getExpandedKeys(node) {
+      let expandedKeys = [];
+      while (node.parent) {
+        expandedKeys.push(node.data.id);
+        node = node.parent;
+      }
+      setStore({
+        name: this.expandName,
+        content: expandedKeys,
+        type: true,
+      });
+
+    },
+      loadNode(node, resolve) {
+                let pid = 0;
+                if (node.level != 0) {
+                    pid = node.data.id;
+                }
+                getLazytree(this.id, pid, this.tenant_id, this.projectid, {
+                    wbsType: 2,
+                }).then((res) => {
+                    let arr = [];
+                    if (Array.isArray(res.data.data)) {
+                    arr = res.data.data;
+                    }
+
+                    return resolve(arr);
+                });
+        },
+        goBackFirst() {
+                this.isShowList = true;
+                this.$router.go(-1);
+         },
+        
+        goBack() {
+                this.isShowList = true;
+         },
+         goBack1() {
+          
+          this.isShowDetail = false;
+         },
+         addRule(){
+          this.titleInput = '';
+          this.manageLoad=false
+          this.addDialogVisible = true;
+         },
+         addSaveFileClick() {
+          this.addSaveFileLoad = true;
+          if (!this.titleInput) {
+            this.$message.error('请输入规范文件夹名称');
+            this.addSaveFileLoad = false;
+            return;
+          }
+
+           const formData = new FormData();
+          // 添加基本信息
+          let objData={
+              name: this.titleInput,
+              type:1,
+              privateId: this.treeId,
+          }
+         
+          formData.append('data', new Blob([JSON.stringify(objData)], {
+              type: 'application/json'
+            }));
+           add(
+            formData
+            ).then((res) => {
+              this.addSaveFileLoad = false;
+            if(res.data.code==200){
+                this.$message.success(res.data.msg)
+              
+                this.addDialogVisible=false
+                this.getRuleItemOptions();
+            }else{
+                this.$message.error(res.data.msg)
+            }
+            }).finally(() => {
+                this.saveBatchLoading = false;
+            });
+
+         },
+         ruleDetailClick(item){
+          this.isShowList = false;
+          this.getRuleDetail(item);
+          this.ruleItem=item
+         },
+          //点击规范文件夹详情
+          getRuleDetail(item) {
+            this.ruleItemOptionsDetailLoading = true;
+            getPage({
+              current: this.currentPage1,
+              size: this.pageSize1,
+              type: 2,
+              parentId: item.id,
+              privateId: this.treeId,
+            }).then((res) => {
+
+              
+              this.ruleItemOptionsDetailLoading = false;
+              if (res.data.code === 200) {
+                this.ruleItemOptionsDetail = res.data.data.records;
+            
+              } else {
+                this.$message.error(res.msg);
+              }
+            });
+          },
+          //
+
+
+         ruleDetailClick1(item){
+            this.getRuleDataDetail(item);
+            this.getRuleDataDetail1(item);
+            this.ruleItemDetail=item
+
+          this.isShowDetail = true;
+         },
+         //获取规范数据详情
+         getRuleDataDetail(item){
+            getById({
+              id: item.id,
+            
+            }).then((res) => {
+              if (res.data.code === 200) {
+                this.ruleDataDetail = res.data.data;
+                console.log( this.ruleDataDetail,' this.ruleDataDetail');
+                
+              } else {
+                this.$message.error(res.data.msg);
+              }
+            });
+         },
+         //获取规范数据详情
+         getRuleDataDetail1(item,type){
+             getInfoPage({
+                current:1,
+                size:100,
+                type, 
+                standardId: item.id,
+              }).then((res) => {
+                this.ruleLoading = false;
+                if (res.data.code === 200) {
+            
+                  // 
+                  if(type===1){
+                    this.ypList = res.data.data.records;
+                  }else if(type===2){
+                    this.jsList = res.data.data.records;
+                  }else{
+                     const records = res.data.data.records;
+                     // 根据 type 分类数据
+                    this.ypList = records.filter(record => record.type === 1);
+                    this.jsList = records.filter(record => record.type === 2);
+                  }
+                } else {
+                 this.ypList = [];
+                    this.jsList = [];
+                  this.$message.error(res.data.msg);
+                }
+              });
+         },
+         addFile(){
+         //新增规范文件
+         this.addFileDialogVisible = true;
+         },
+         
+     uploadImportData(file) {
+          // 验证文件类型
+       
+
+          // 将文件对象存入 files 数组
+          if (!this.fileForm.files) {
+            this.fileForm.files = [];
+          }
+          this.fileForm.files.push(file.raw);
+
+          // 更新显示的文件列表
+          this.fileForm.standardFileUrl = this.fileForm.files.map(file => ({
+            name: file.name,
+          }));
+      },
+        async addFileRoleForm(){
+          const isValid = await this.$refs.fileFormRef.validate()
+          if (!isValid) {
+            this.$message.error('请填写完整的规范信息');
+            return;
+          }
+          const formData = new FormData();
+          // 添加基本信息
+          let objData={
+            name: this.fileForm.name,
+            issueDate: this.fileForm.issueDate,
+            actualizeDate: this.fileForm.actualizeDate,
+            type: 2,
+            privateId: this.treeId,
+            parentId: this.ruleItem.id,
+          }
+          let data = JSON.stringify(objData);
+          formData.append('data', new Blob([JSON.stringify(objData)], {
+              type: 'application/json'
+            }));
+
+        // 添加文件
+        if (this.fileForm.files && this.fileForm.files.length > 0) {
+          this.fileForm.files.forEach(file => {
+            formData.append('files', file);
+          });
+        }
+                // add({
+          //   ...this.fileForm,
+          //   type: 2,
+          //   privateId: this.treeId,
+          //   parentId: this.ruleItem.id,
+          // })
+          console.log(formData,'formData');
+          
+           add(formData)
+          .then((res) => {
+            if(res.data.code==200){
+                this.$message.success(res.data.msg)
+              
+                this.addFileDialogVisible=false
+                this.getRuleDetail(this.ruleItem);
+            }else{
+                this.$message.error(res.data.msg)
+            }
+            }).finally(() => {
+                this.saveBatchLoading = false;
+            });
+          
+          
+          
+
+         },
+      handleCurrentChange(val) {
+        this.currentPage = val
+        this.getRuleItemOptions(); // 刷新数据
+      },
+      handleSizeChange(val) {
+        this.pageSize = val
+        this.currentPage = 1
+         this.getRuleItemOptions(); // 刷新数据
+      },
+      handleCurrentChange1(val) {
+        this.currentPage = val
+         this.getRuleDetail(item);
+      },
+      handleSizeChange1(val) {
+        this.pageSize1 = val
+        this.currentPage1= 1
+        this.getRuleDetail(this.ruleItem); // 刷新数据
+      },
+      addYp(){
+        this.isShowYpList = false;
+        this.isShowJsList = false;
+        this.isEditYp = false;
+        this.ypDetail = {
+          name: '',
+          info: [{ name: '' }]
+        };
+
+
+
+      },
+      showYpList() {
+        this.isShowYpList = true;
+      },
+       // 添加基础信息行
+    addBasicInfo(index) {
+      this.ypDetail.info.splice(index + 1, 0, { name: '' });
+    },
+
+    // 删除基础信息行
+    removeBasicInfo(item,index) {
+     if(item.id==''){
+        this.ypDetail.info.splice(index, 1);
+     }else{
+        this.$confirm('删除后,数据将无法恢复,是否确认删除!', '提示', {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning'
+          }).then(() => {
+         
+            deleteItemInfo({id:item.id}).then((res) => {
+              if(res.data.code==200){
+                this.$message.success(res.data.msg);
+                this.getRuleDataDetail(this.ruleItemDetail);
+                this.getRuleDataDetail1(this.ruleItemDetail,1);
+                    this.ypDetail.info.splice(index, 1);
+              }else{
+                this.$message.error(res.data.msg);
+              }
+            });
+          }).catch(() => {
+            this.$message.info('已取消删除');
+          })
+     }
+
+    },
+  async  saveYpForm(){
+        const isValid = await this.$refs.ypFormRef.validate()
+        if (!isValid) {
+          this.$message.error('请填写完整的样品信息');
+          return;
+        }
+        this.saveYpLoad = true;
+        this.ypDetail.info.forEach((item)=>{
+          item.type=1
+        })
+        if(!this.isEditYp){
+               addInfo({
+          ...this.ypDetail,
+            type: 1,
+            standardId: this.ruleItemDetail.id,
+            // parentId: this.ruleItemDetail.id,
+          }).then((res) => {
+            if(res.data.code==200){
+                this.$message.success(res.data.msg)
+                 this.getRuleDataDetail(this.ruleItemDetail);
+                  this.getRuleDataDetail1(this.ruleItemDetail,1);
+                 this.isShowYpList= true;
+                 this.isShowJsList=true
+            }else{
+                this.$message.error(res.data.msg)
+            }
+            }).finally(() => {
+                this.saveYpLoad = false;
+            });
+        }else{
+                 editInfo({
+                  ...this.ypDetail,
+                    type: 1,
+                    standardId: this.ruleItemDetail.id,
+                    // parentId: this.ruleItemDetail.id,
+                  }).then((res) => {
+                    if(res.data.code==200){
+                        this.$message.success(res.data.msg)
+                        this.getRuleDataDetail(this.ruleItemDetail);
+                          this.getRuleDataDetail1(this.ruleItemDetail,1);
+                        this.isShowYpList= true;
+                        this.isShowJsList=true
+                    }else{
+                        this.$message.error(res.data.msg)
+                    }
+                    }).finally(() => {
+                        this.saveYpLoad = false;
+                    });
+        }
+       
+          
+
+    },
+    
+    // 管理文件夹
+    manageFolder(){
+       this.delFileIds=[];
+       this.delIds=[];
+       
+
+      this.manageVisible = true;
+      if(!this.isShowList){
+         this.manageData=JSON.parse(JSON.stringify(this.ruleItemOptionsDetail));
+         this.manageData.forEach(item=>{
+          item.filesCount=0;
+         })
+      }else{
+         this.manageData=JSON.parse(JSON.stringify(this.ruleItemOptions));
+      }
+     
+    },
+    delManange(index,row){
+          console.log(this.isShowList,'isShowList');
+    
+          if(this.isShowList){
+                   this.$confirm('删除后,数据将无法恢复,是否确认删除!', '提示', {
+                  confirmButtonText: '确定',
+                  cancelButtonText: '取消',
+                  type: 'warning'
+                }).then(() => {
+                //  this.manageData.splice(index, 1);
+                  deleteItem({id:row.id}).then((res) => {
+                    if(res.data.code==200){
+                      this.$message.success(res.data.msg);
+                      this.getRuleItemOptions();
+                      this.manageData.splice(index, 1);
+                    }else{
+                      this.$message.error(res.data.msg);
+                    }
+                  });
+                }).catch(() => {
+                  this.$message.info('已取消删除');
+                })
+          }else{
+            //记录每次删除文件的id,记录到数组里面
+            this.delIds.push(row.id)
+              this.manageData.splice(index, 1);
+              row.filesCount = 0; // 设置文件大小
+
+
+
+          }
+    },
+    putFile(item,index){
+
+      this.isUploadVisible = true;
+    },
+    handleFileUpload(file,row,index) {
+    
+      
+      if(!file) return
+  
+      row.file=file.raw; // 获取原始文件对象
+      row.standardFile.fileName = file.name; // 设置文件名
+      row.filesCount = 1; // 设置文件大小
+
+
+
+      // 在这里处理文件上传逻辑
+    },
+    delFile(row,id){
+      console.log(row,'row');
+      const {standardFile}=row;
+    console.log(standardFile,'standardFile');
+    if(standardFile&&standardFile.id){
+      this.delFileIds.push(standardFile.id)
+     
+
+    }
+    row.filesCount = 0; // 设置文件大小
+
+     row.file=null; // 获取原始文件对象
+      row.standardFile.fileName = ''; // 设置文件名
+// 如果有文件ID,则执行删除操作
+
+
+      
+    },
+    manageSave(){
+      this.manageLoad = true;
+ 
+  
+      const arr = this.manageData.map(item => ({ id: item.id, name: item.name,type:this.isShowList?1:2 }));
+      console.log(arr,'arr');
+      if(this.isShowList){
+               edit(arr ).then((res) => {
+                if (res.data.code === 200) {
+                  this.$message.success(res.data.msg);
+                  this.manageVisible = false;
+                  if(!this.isShowList){
+                    this.getRuleDetail(this.ruleItem);
+                    this.manageData = JSON.parse(JSON.stringify(this.ruleItemOptionsDetail));
+                  }else{
+                    this.getRuleItemOptions();
+                      this.manageData = JSON.parse(JSON.stringify(this.ruleItemOptions));
+                  }
+                } else {
+                  this.$message.error(res.data.msg);
+                }
+              }).finally(() => {
+                this.manageLoad = false;
+              });
+        }else{
+        let objData=this.manageData.map(item => ({ id: item.id, name: item.name,filesCount: item.filesCount,file:item.file }));
+        let filesArr=this.manageData.map(item => item.file);
+        const formData = new FormData();
+       console.log(objData,'objData');
+        let objData1=this.manageData.map(item => ({ id: item.id, name: item.name,filesCount: item.filesCount}));
+        formData.append('data', new Blob([JSON.stringify(objData1)], {
+              type: 'application/json'
+        }))
+        let ids=this.delIds
+        formData.append('delIds', new Blob([JSON.stringify(ids)], {
+              type: 'application/json'
+        }))
+        let delFileIds=this.delFileIds;
+          formData.append('delFileIds', new Blob([JSON.stringify(delFileIds)], {
+              type: 'application/json'
+        }))
+        console.log(filesArr,'filesArr');
+        
+        if(filesArr.length>0){
+              for(let i=0;i<filesArr.length;i++){
+                formData.append('files', filesArr[i]);
+            }
+
+        }
+        console.log(formData,'formData');
+        console.log(this.delFileIds,'this.delFileIds;');
+           console.log(this.delIds,'this.delIds;');
+        
+          updateTypeByTwo(formData ).then((res) => {
+                if (res.data.code === 200) {
+                  this.$message.success(res.data.msg);
+                  this.manageVisible = false;
+                  if(!this.isShowList){
+                    this.getRuleDetail(this.ruleItem);
+                    this.manageData = JSON.parse(JSON.stringify(this.ruleItemOptionsDetail));
+                  }else{
+                    this.getRuleItemOptions();
+                      this.manageData = JSON.parse(JSON.stringify(this.ruleItemOptions));
+                  }
+                } else {
+                  this.$message.error(res.data.msg);
+                }
+              }).finally(() => {
+                this.manageLoad = false;
+              });
+
+      }
+ 
+    },
+      handleEdit(item, index) {
+  
+        this.isShowYpList = false;
+        this.isShowJsList = false;
+        this.ypDetail = JSON.parse(JSON.stringify(item));
+        this.isEditYp = true;
+      },
+
+      handleDelete(item,index) {
+        this.$confirm('删除后,数据无法恢复,是否确认删除?', '删除确认', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          // this.ypList.splice(index, 1);
+          deleteItemInfo({ id: item.id }).then((res) => {
+            if(res.data.code==200){
+                this.$message.success(res.data.msg)
+                 this.getRuleDataDetail(this.ruleItemDetail);
+                  this.getRuleDataDetail1(this.ruleItemDetail,1);
+            }else{
+                this.$message.error(res.data.msg)
+            }
+          });
+         
+        }).catch(() => {});
+      },
+  
+
+      handleDelete1(item,index) {
+        this.$confirm('删除后,数据无法恢复,是否确认删除?', '删除确认', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          // this.jsList.splice(index, 1);
+       deleteItemInfo({ id: item.id }).then((res) => {
+            if(res.data.code==200){
+                this.$message.success(res.data.msg)
+                 this.getRuleDataDetail(this.ruleItemDetail);
+                  this.getRuleDataDetail1(this.ruleItemDetail,2);
+            }else{
+                this.$message.error(res.data.msg)
+            }
+          });
+       
+        }).catch(() => {});
+      },
+      //新增技术指标
+      addJs(){
+        this.isShowJsList = true;
+         this.isShowYpList = false;
+        this.isEditJs = false;
+        this.jsDetail = {
+          name: '',
+          info: [{ name: '',select:'' }]
+        };
+        
+      },
+      handleEditJs1(item, index) {
+        // 处理编辑逻辑
+        this.jsDetail = JSON.parse(JSON.stringify(item));
+        this.isEditJs = true;
+          this.isShowJsList = true;
+         this.isShowYpList = false;
+      },
+      addBasicInfo1(index) {
+       this.jsDetail.info.splice(index + 1, 0, { name: '', select: '' });
+      },
+      addJsForm() {
+        const isValid = this.$refs.jsFormRef.validate();
+        if (!isValid) {
+          this.$message.error('请填写完整的技术指标信息');
+          return;
+        }
+        this.addJsFormLoad = true;
+        this.jsDetail.info.forEach((item)=>{
+          item.type=2
+        })
+        if(!this.isEditJs){
+             addInfo({
+          ...this.jsDetail,
+          type: 2,
+          standardId: this.ruleItemDetail.id,
+        }).then((res) => {
+          if(res.data.code==200){
+              this.$message.success(res.data.msg)
+              this.getRuleDataDetail(this.ruleItemDetail);
+              this.getRuleDataDetail1(this.ruleItemDetail,2);
+              this.isShowYpList= true;
+              this.isShowJsList=false
+               
+          }else{
+              this.$message.error(res.data.msg)
+          }
+          }).finally(() => {
+              this.addJsFormLoad = false;
+          });
+        }else{
+           editInfo({
+          ...this.jsDetail,
+          type: 2,
+          standardId: this.ruleItemDetail.id,
+        }).then((res) => {
+          if(res.data.code==200){
+              this.$message.success(res.data.msg)
+              this.getRuleDataDetail(this.ruleItemDetail);
+              this.getRuleDataDetail1(this.ruleItemDetail,2);
+              this.isShowYpList= true;
+              this.isShowJsList=false
+               
+          }else{
+              this.$message.error(res.data.msg)
+          }
+          }).finally(() => {
+              this.addJsFormLoad = false;
+          });
+        }
+          //新增技术指标
+          
+       
+      },
+    
+    // 删除基础信息行
+    removeBasicInfo1(item,index) {
+
+       if(item.id==''){
+        this.jsDetail.info.splice(index, 1);
+     }else{
+        this.$confirm('删除后,数据将无法恢复,是否确认删除!', '提示', {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning'
+          }).then(() => {
+         
+            deleteItemInfo({id:item.id}).then((res) => {
+              if(res.data.code==200){
+                this.$message.success(res.data.msg);
+                      this.jsDetail.info.splice(index, 1);
+                this.getRuleDataDetail(this.ruleItemDetail);
+                this.getRuleDataDetail1(this.ruleItemDetail,1);
+                    this.ypDetail.info.splice(index, 2);
+              }else{
+                this.$message.error(res.data.msg);
+              }
+            });
+          }).catch(() => {
+            this.$message.info('已取消删除');
+          })
+     }
+    },
+    //条件设置
+    conditionsSet(){
+      if(this.jsDetail.info[0].name === '') {
+        this.$message.error('请先添加技术指标内容');
+        return;
+      }
+      this.$refs.conditionsSetRef.show(this.jsDetail.info,this.ruleItemDetail.id);
+
+    },
+    // 添加确认取消处理方法
+    handleConditionsConfirm() {
+      console.log('确认条件设置')
+    },
+    handleConditionsCancel() {
+      console.log('取消条件设置') 
+    },
+    //关联元素
+    linkEle() {
+      if(this.jsDetail.info[0].name === '') {
+        this.$message.error('请先添加技术指标内容');
+        return;
+      }
+        this.$refs.linkEleRef.show(this.jsDetail.info, this.treeId,this.id,  this.projectid,this.ruleItemDetail.id);
+    },
+    confirmLinkEle() {
+      console.log('确认关联元素')
+
+    
+    },
+    //效果预览
+    previewRes() {
+      this.$refs.previewResultRef.show()
+    }
+  }
+  }
+</script>
+
+<style scoped lang="scss">
+.container-box {
+  height: calc(100vh - 120px);
+
+  box-sizing: border-box;
+}
+
+.h-100 {
+  height: 100%;
+}
+.tree-container {
+  height: calc(100vh - 120px);
+  overflow-y: auto;
+}
+
+.box-card {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  // 内容区域
+  .el-card__body {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+  }
+}
+.rule-box{
+  width: 100%;
+  display: grid;
+  grid-template-columns: repeat(8, 1fr); 
+    grid-template-rows: repeat(4, 1fr);
+   gap: 50px;
+  padding: 20px;
+  height: 600px;
+  overflow-y:hidden;
+
+  .rule-box-item{
+      text-align: center;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+  }
+  .rule-box-item-icon {
+      margin-bottom: 8px;
+ 
+  }
+    .rule-box-item-title {
+      font-size: 14px;
+      width: 100%;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+
+}
+.input-container {
+  display: flex;
+  align-items: center;
+}
+
+.input-container span {
+  margin-right: 10px; /* 根据需要调整间距 */
+}
+.box-card-title{
+  font-weight: bolder;
+  font-size: 24px;
+}
+.box-card-content1{
+  margin-top: 10px;
+  display: flex;
+  justify-content: space-between;
+  width: 100%;
+  .box-card-content1-left{
+    display: flex;
+    .box-card-content1-left-item{
+      margin-right: 25px;
+    }
+    
+  }
+}
+.box-card-content2{
+  margin-top: 10px;
+
+
+  .box-card-content2-title{
+    color:  rgba(130, 130, 130, 1);
+    font-size: 10px;;
+    width: 98%;
+    padding-left: 20px;
+    font-size: 18px;
+    line-height: 40px;
+    background: rgb(240, 240, 240);
+      .title-container {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding-right: 20px;
+
+    i {
+      cursor: pointer;
+      font-size: 22px;
+      color: #2550A2;
+      // 添加过渡效果
+      &:hover {
+        color: #409EFF;
+      }
+    }
+  }
+  }
+}
+
+.box-card-content2-bottom{
+  margin-top: 20px;
+}
+.add-yp-title{
+  font-size: 20px;
+  font-weight: bold;
+  padding: 10px;
+  display: flex;
+  justify-content: space-between;
+ 
+}
+.input-with-icon {
+  display: flex;
+  align-items: center;
+  margin-bottom: 15px;
+  
+  .el-input {
+    flex: 1;
+  }
+  
+  i {
+    margin-left: 10px;
+    font-size: 20px;
+    cursor: pointer;
+    
+    &.el-icon-circle-plus-outline {
+      color: #409EFF;
+      &:hover {
+        color: #66b1ff;
+      }
+    }
+    
+    &.el-icon-remove-outline {
+      color: #F56C6C;
+      &:hover {
+        color: #f78989;
+      }
+    }
+  }
+}
+.add-yp-detail{
+    flex: 1;
+    overflow-y: auto;
+   padding: 20px;
+   height: calc(100vh - 342px); /* 减去标题和底部按钮的高度 */
+}
+// 新增底部按钮容器样式
+.add-yp-footer {
+  display: flex;
+  justify-content: center;
+  padding: 20px 0;
+  // 可选: 添加上边框
+  border-top: 1px solid #EBEEF5;
+}
+.box-card-content2-list{
+  margin-top: 20px;
+  max-height: 300px;
+  overflow-y: auto;
+  
+  .eg{
+    color:rgba(37, 80, 162, 1);
+    margin-right: 10px;
+  }
+
+  .box-card-content2-list-item{
+    height: 80px;
+    padding: 10px;
+    border: 2px solid #EBEEF5;
+    margin-bottom: 10px;
+
+
+   
+  }
+  .box-card-content2-list-item-list{
+    display: flex;
+    margin-top: 20px;
+    align-items: center;
+    position: relative;
+    .operation-icons {
+    position: absolute;
+    right: 10px;
+    top: 10px;
+    display: flex;
+    gap: 10px;
+
+    i {
+      cursor: pointer;
+      font-size: 16px;
+
+      &.el-icon-edit {
+        color: #409EFF;
+        &:hover {
+          color: #66b1ff;
+        }
+      }
+      
+      &.el-icon-delete {
+        color: #F56C6C;
+        &:hover {
+          color: #f78989;
+        }
+      }
+    }
+  }
+    .basic-info{
+      color: gray;
+      font-size: 14px;
+    }
+    .box-card-content2-list-item-list-basic{
+      display: flex;
+      margin-left: 10px;
+      width: 100%;
+      overflow-x: auto;
+      flex: 1;
+
+      .basic-item-info{
+        margin-right: 10px;
+        margin-right: 20px; 
+            flex-shrink: 0; // 防止项目被压缩
+
+        
+      }
+    }
+  }
+}
+.empty-container{
+  height: 600px;
+}
+.dialog-footer{
+  text-align: center;
+
+}
+</style>

+ 37 - 7
src/views/digital/signer.vue

@@ -53,6 +53,7 @@
                         </div>
                         <div class="table-box">
                             <el-table
+                            height="600"
                                 v-loading="tableLoading"
                                 ref="multipleTable"
                                 :data="tableData"
@@ -127,7 +128,7 @@
         <el-dialog
         class="dialog-footer-center"
             append-to-body
-            title="新增电签配置信息"
+            :title="addDialogVisibleTitle"
             :visible.sync="addDialogVisible"
             width="80%"
             :before-close="handleAddClose">
@@ -197,7 +198,7 @@
                                     <el-button type="text" @click="handleAdd(scope.row,scope.$index)">
                                         <i class="el-icon-circle-plus-outline" style="font-size: 20px;color:#67C23A"></i>
                                     </el-button>
-                                    <el-button type="text" @click="handleDelete(scope.row,row,scope.$index)">
+                                    <el-button type="text" @click="handleDelete(scope.row,scope.$index)">
                                         <i class="el-icon-remove-outline" style="font-size: 20px;color:red"></i>
                                     </el-button>
                                 </template>
@@ -393,6 +394,7 @@
                 total: 0,
 
                 addDialogVisible: false,
+                addDialogVisibleTitle: '新增电签配置信息',
                 saveBatchLoading: false,
                 checkedList: [],
                 tableData1: [{}],
@@ -503,6 +505,8 @@
             //获取岗位列表
             getRoleData() {
                 this.roleListLoading = true;
+                this.selectedItem = {};
+
                 getRoleList({
                     type: this.tabPosition,
                     roleName: this.postText
@@ -517,6 +521,7 @@
                         this.roleData = [];
                     }
                 })
+                  this.getTableData();
             },
             positionClick(event, item){
                 this.selectedItem = item; 
@@ -531,8 +536,9 @@
                 getListPage({
                     size: this.pageSize,
                     current: this.currentPage,
-                    keyword: this.postText,
-                    roleId: this.selectedItem.roleId||''
+                    keyword: '',
+                    roleId: this.selectedItem.roleId||'',
+                    type: this.tabPosition
                 }).then(res => {
                     this.tableLoading = false;
                     if (res.data.code == 200) {
@@ -554,12 +560,14 @@
             },
             addEleClick() {
                 this.addDialogVisible = true;
+                this.addDialogVisibleTitle = '新增电签配置信息';
                 this.tableData1=[{}]
             },
             editEleClick(row) {
                 
                 this.addDialogVisible = true;
-                this.tableData1 = [...this.checkedList]
+                this.addDialogVisibleTitle = '编辑电签配置信息';
+              this.tableData1 = JSON.parse(JSON.stringify(this.checkedList));
                 console.log( this.tableData1,' this.tableData1');
                 this.isPosView=false
                 this.isEleView=false
@@ -649,14 +657,35 @@
             },
             handleDelete(row,index) {
                 console.log('删除', row);
-                if(this.tableData1.length==1){
+                if(this.tableData1.length==1&&this.addDialogVisibleTitle=='新增电签配置信息'){
                     this.$message({
                         type: "warning",
                         message: "请至少保留一条数据",
                     });
                     return;
                 }
-                this.tableData1.splice(index, 1);
+                if(this.addDialogVisibleTitle=='新增电签配置信息'){
+                     this.tableData1.splice(index, 1);
+                }else{
+                    let _that = this;
+                    let ids = row.id;
+                    this.$confirm("删除后,项目级表单电签信息将同步删除,请确认是否删除", "提示", {
+                        confirmButtonText: "确定",
+                        cancelButtonText: "取消",
+                        type: "warning",
+                    })
+                        .then(() => {
+                        _that.remove({ ids });
+                         _that.tableData1.splice(index, 1);
+                        })
+                        .catch(() => {
+                        this.$message({
+                            type: "info",
+                            message: "已取消删除",
+                        });
+                        })
+                }
+              
                 // 删除操作的逻辑
             },
             rowDel() {
@@ -679,6 +708,7 @@
                 })
                     .then(() => {
                     _that.remove({ ids });
+                     
                     })
                     .catch(() => {
                     this.$message({

+ 484 - 0
src/views/manager/projectinfo/codeSet.vue

@@ -0,0 +1,484 @@
+<template>
+  <el-dialog
+    title="编号配置" 
+    :visible.sync="dialogVisible"
+    width="70%"
+    append-to-body
+    :close-on-click-modal="false"
+
+  >
+
+   <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
+    <el-tab-pane  v-for="item in activeOptions"  :label="item.label" :name="item.value">
+    <div class="file-rule-container">
+         
+     <div class="header-box">
+       <div class="preview-box">
+        <span>生成预览</span>
+        <el-input v-model="dataNumber" placeholder="预览编号" style="width: 300px; margin-left: 10px;" disabled size="small"></el-input>
+      </div>
+        <div class="header-tools">
+            
+            <el-button type="text" icon="el-icon-plus" @click="addRow">新增</el-button>
+            <el-button type="text" icon="el-icon-sort" @click="sortData">排序</el-button>
+            <el-button type="text" icon="el-icon-delete" @click="delBatchData" style="color: #F56C6C;" :loading="delLoad">删除</el-button>
+        </div>
+     </div>
+      
+      <el-table
+        :data="tableData"
+        style="width: 100%"
+        v-loading="loading"
+        ref="multipleTable"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column label="序号" type="index" width="50"></el-table-column>
+        <el-table-column
+          type="selection"
+          width="55">
+        </el-table-column>
+        <el-table-column label="规则">
+          <template slot-scope="scope">
+            <el-select 
+              v-if="scope.row.isEdit"
+              v-model="scope.row.rule" 
+              @change="handleNumberChange($event,scope.row)"
+              placeholder="请选择"
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item in numberOptions"
+                :key="item.dictKey"
+                :label="item.dictValue"
+                :value="item.dictKey"
+              >
+              </el-option>
+            </el-select>
+             <span v-else>{{ getDictValueByRule(scope.row.rule) }}</span>
+           
+          </template>
+        </el-table-column>
+
+        <el-table-column label="数据填充">
+          <template slot-scope="scope">
+           <div  v-if="scope.row.isEdit">
+             <el-input v-model="scope.row.data" placeholder="*输入生成编号时包含的固定字符" v-if="scope.row.rule===1"></el-input>
+            <el-input v-model="scope.row.data" placeholder="*自动获取当前合同段编号" v-if="scope.row.rule===2" disabled></el-input>
+            <el-input v-model="scope.row.data" placeholder="*自动获取各试验参数掩码" v-if="scope.row.rule===3" disabled></el-input>
+            <el-input v-model="scope.row.data" placeholder="*自动获取当前年份" v-if="scope.row.rule===4" disabled></el-input>
+             <el-input v-model="scope.row.data" placeholder="*自动获取当前月份" v-if="scope.row.rule===5" disabled></el-input>
+             <el-input
+              v-model="scope.row.data"
+              v-if="scope.row.rule === 6"
+              @input="scope.row.data = scope.row.data.replace(/[^0-9]/g, '')"></el-input>
+
+             
+           </div>
+            <!-- <span v-else>{{ scope.row.data }}</span> -->
+             <div v-else>
+               <span v-if="scope.row.rule===1">*输入生成编号时包含的固定字符</span>
+               <span v-if="scope.row.rule===2">*自动获取当前合同段编号</span>
+                <span v-if="scope.row.rule===3">*自动获取各试验参数掩码</span>
+                <span v-if="scope.row.rule===4">*自动获取当前年份</span>
+                  <span v-if="scope.row.rule===5">*自动获取当前月份</span>
+                    <span v-if="scope.row.rule===6">*{{ scope.row.data }}</span>
+             </div>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="是否自增">
+          <template slot-scope="scope">
+             <el-checkbox v-model="scope.row.isAutoIncrement" v-if="scope.row.rule==6&&scope.row.isEdit" :true-label="1" :false-label="0" ></el-checkbox >
+                  <span v-else>{{scope.row.isAutoIncrement===1?'是':'否'}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="150">
+          <template slot-scope="scope">
+            <el-button
+              type="text"
+              @click="handleEdit(scope.$index, scope.row)"
+              v-if="!scope.row.isEdit"
+            >
+              编辑
+            </el-button>
+            <el-button
+              type="text"
+              @click="handleSave(scope.$index, scope.row)"
+              :loading="scope.row.loading"
+              v-else
+            >
+              保存
+            </el-button>
+            <el-button
+              type="text"
+              @click="handleDelete(scope.$index, scope.row)"
+            >
+              删除
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    </el-tab-pane>
+    
+  </el-tabs>
+   
+<template>
+  <!-- 省略其他代码 -->
+  
+  <el-dialog
+    title="排序"
+    :visible.sync="sortDialogVisible"
+    width="50%"
+    append-to-body
+
+  >
+       <el-table
+        :data="sortedTableData"
+        style="width: 100%"
+      >
+        <el-table-column label="序号" type="index" width="50"></el-table-column>
+        <el-table-column label="规则">
+          <template slot-scope="scope">
+             <span >{{ getDictValueByRule(scope.row.rule) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="数据填充">
+          <template  slot-scope="scope">
+              <span>{{ scope.row.data }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="是否自增">
+          <template slot-scope="scope">
+             <el-checkbox v-model="scope.row.isAutoIncrement" v-if="scope.row.rule==6" :true-label="1" :false-label="0"></el-checkbox>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="150">
+            <template slot-scope="scope">
+              <el-button
+                type="text"
+                icon="el-icon-arrow-up"
+                @click="handleSortUp(scope.$index)"
+                style="margin-right: 5px;"
+              ></el-button>
+              <el-button
+                type="text"
+                icon="el-icon-arrow-down"
+                @click="handleSortDown(scope.$index)"
+              ></el-button>
+            </template>
+          </el-table-column>
+      </el-table>
+      <div slot="footer" class="dialog-footer">
+          <el-button @click="sortDialogVisible = false">取 消</el-button>
+          <el-button type="primary" @click="sortSave" :loading="sortLoad">确 定</el-button>
+        </div>
+  </el-dialog>
+</template>
+     <span slot="footer" class="dialog-footer">
+    <el-button @click="dialogVisible = false">取 消</el-button>
+    <el-button type="primary" @click="saveCodeSet" :loading="saveCodeLoad">确 定</el-button>
+  </span>
+  </el-dialog>
+</template>
+
+<script>
+import {getTrialNumberRule,save,update,remove,sort,submitList } from "@/api/ruleManage/codeRule.js";
+import { getDictionary } from "@/api/system/dict";
+export default {
+  name: 'FileRuleDialog',
+  
+  data() {
+    return {
+      projectId: '',
+      saveCodeLoad: false,
+      dialogVisible: false,
+      loading: false,
+      tableData: [],
+      tableLoading: false,
+
+      numberOptions: [
+       
+      ],
+      dataNumber: '',
+      activeName:'1',
+      activeOptions: [
+        { label: '试验编号', value: '1' },
+        { label: '样品编号', value: '2' },
+        { label: '委托单编号', value: '3' },
+        { label: '记录表编号', value: '4' },
+        { label: '报告表编号', value: '5' },
+      ],
+      multipleSelection:[],
+      delLoad: false,
+      sortDialogVisible: false, // 控制排序弹窗的显示与隐藏
+      sortedTableData: [], // 排序弹窗的表格数据,为tableData的深拷贝
+      sortLoad: false, // 排序保存按钮的loading状态
+
+    }
+  },
+
+  methods: {
+    show(pid) {
+      this.dialogVisible = true
+      this.projectId = pid
+      this.getTableData()
+      this.getNumberOptions()
+    },
+
+    handleClick(tab, event) {
+      this.dataNumber=''
+      this.getTableData()
+    },
+    addRow() {
+      this.tableData.push({
+        isEdit: true,
+      })
+    },
+    sortData() {
+      this.sortedTableData = JSON.parse(JSON.stringify(this.tableData)); // 深拷贝tableData
+      this.sortDialogVisible = true; // 显示排序弹窗
+    },
+  handleSortUp(index) {
+    if (index > 0) { // 确保不是第一行
+      const temp = this.sortedTableData.splice(index, 1)[0]; // 移除当前行
+      this.sortedTableData.splice(index - 1, 0, temp); // 在上一行插入
+   
+    } else {
+      this.$message.warning('已经是第一行,无法上移');
+    }
+  },
+
+  handleSortDown(index) {
+    if (index < this.sortedTableData.length - 1) { // 确保不是最后一行
+      const temp = this.sortedTableData.splice(index, 1)[0]; // 移除当前行
+      this.sortedTableData.splice(index + 1, 0, temp); // 在下一行插入
+    
+    } else {
+      this.$message.warning('已经是最后一行,无法下移');
+    }
+  },
+  sortSave(){
+    this.sortLoad = true;
+    let params=this.sortedTableData
+       sort(params).then((res) => {
+          if (res.data.code === 200) {
+            this.dataNumber = res.data.data;
+            this.$message.success(res.data.msg);
+            this.getTableData();
+          } else {
+            this.dataNumber = '';
+            this.$message.error(res.data.msg);
+           
+            
+          }
+        }).catch(() => {
+          this.$message.error('操作失败');
+        }).finally(() => {
+          this.sortLoad = false;
+           this.sortDialogVisible = false; // 关闭排序弹窗
+        });
+
+  },
+
+    getNumberOptions(){
+       getDictionary({
+        code:'trial_number_rule',
+      }).then((res) => {
+       
+        this.numberOptions = res.data.data;
+        this.numberOptions.forEach(item=>{
+         item.dictKey=Number(item.dictKey)
+
+        })
+      });
+    },
+    getTableData() 
+    {
+      this.tableLoading = true;
+                getTrialNumberRule({
+                   projectId:this.projectId,
+                   contractId:0,
+                   type:this.activeName,
+             
+                   pageSize:20
+                }).then(res => {
+                    this.tableLoading = false;
+                    if (res.data.code == 200) {
+                       
+                        this.tableData = res.data.data['list'];
+                        this.total = res.data.data['total'];
+                        this.dataNumber=res.data.data['trialNumber']
+                    }else{
+                        this.tableData = [];
+                         this.dataNumber='';
+                    }
+                })
+    },
+
+
+    refreshData() {
+      this.loading = true
+      // TODO: 调用接口刷新数据
+      setTimeout(() => {
+        this.loading = false 
+      }, 500)
+    },
+    delBatchData(){
+      if(this.multipleSelection.length===0){
+        this.$message.warning('请选择要删除的规则!')
+        return;
+      }
+     let ids = this.multipleSelection.map(item => item.id).join(',');
+
+      this.$confirm('删除后,数据将无法恢复,是否确认删除?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.delLoad = true;
+          return remove({ids: ids});
+        }).then((res) => {
+          if (res.data.code === 200) {
+            this.$message.success(res.data.msg);
+            this.dataNumber = res.data.data;
+            this.getTableData();
+          } else {
+            this.$message.error(res.data.msg);
+          }
+        }).catch(() => {
+          this.$message.info('已取消删除');
+        }).finally(() => {
+          this.delLoad = false;
+        });
+    },
+
+    handleEdit(index, row) {
+      this.$set(row, 'isEdit', true)
+    },
+
+   handleSave(index, row) {
+    if(!row.rule) {
+      this.$message.warning('请选择规则!')
+      return;
+    }
+     row.isEdit = false;
+        // row.loading = true;
+        // const apiMethod = row.id ? update : save;
+        // const params = {
+        //   ...row,
+        //   type: this.activeName,
+        //   projectId: this.projectId,
+        //   contractId: 0
+        // };
+
+        // apiMethod(params).then((res) => {
+        //   if (res.data.code === 200) {
+        //     this.dataNumber = res.data.data;
+        //     this.$message.success(res.data.msg);
+        //     this.getTableData();
+        //   } else {
+        //     this.dataNumber = '';
+        //     this.$message.error(res.data.msg);
+        //   }
+        // }).catch(() => {
+        //   this.$message.error('操作失败');
+        // }).finally(() => {
+        //   row.loading = false;
+        //   row.isEdit = false;
+        // });
+    },
+    saveCodeSet(){
+          for (let row of this.tableData) {
+              // 检查 row.rule 是否有值
+              if (!row.rule) {
+                  // 显示警告信息
+                  this.$message.warning('请选择规则!');
+                  return;
+              }
+          }
+          this.saveCodeLoad = true;
+                  submitList(this.tableData).then((res) => {
+                      if (res.data.code === 200) {
+                        this.dataNumber = res.data.data;
+                        this.$message.success(res.data.msg);
+                        this.getTableData();
+                      } else {
+                        this.dataNumber = '';
+                        this.$message.error(res.data.msg);
+                      }
+                    }).catch(() => {
+                      this.$message.error('操作失败');
+                    }).finally(() => {
+                            this.saveCodeLoad = false;
+                    });
+    },
+    handleDelete(index, row) {
+      if(!row.id) {
+        this.tableData.splice(index, 1)
+        return
+      }
+      this.$confirm('确认删除该规则?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        remove({ ids: row.id }).then((res) => {
+          if (res.data.code === 200) {
+            this.dataNumber = res.data.data;
+            this.$message.success(res.data.msg);
+            this.getTableData();
+          } else {
+            this.$message.error(res.data.msg);
+          }
+        })
+        // this.tableData.splice(index, 1)
+      })
+    },
+
+    handleNumberChange(data,row) {
+      this.numberOptions.forEach(item => {
+        if (item.dictKey === data) {
+          row.ruleName = item.dictValue
+        }
+      })
+    },
+    getDictValueByRule(ruleKey) {
+      const item = this.numberOptions.find(item => item.dictKey == ruleKey);
+      return item ? item.dictValue : '未知';
+    },
+    handleSelectionChange(val) {
+        this.multipleSelection = val;
+    },
+
+
+
+  
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.file-rule-container {
+  .header-box{
+    display: flex;
+    justify-content: flex-end;
+    align-items: center;
+    margin-bottom: 20px;
+     margin-right: 10px;
+  }
+  .header-tools {
+    // display: flex;
+    
+    text-align: right;
+  }
+
+  .node-tree {
+    margin-top: 10px;
+    max-height: 200px;
+    overflow-y: auto;
+    border: 1px solid #EBEEF5;
+    padding: 10px;
+  }
+}
+</style>

+ 135 - 52
src/views/manager/projectinfo/tree.vue

@@ -14,6 +14,16 @@
               @click="fileTitleHandle"
               >文件题名(全局)
             </el-button>
+
+            <el-dropdown   style="margin-right: 10px"  @command	="handleBasicClick" v-if="wbsType == 2">
+              <el-button  size="medium">
+                基础数据管理<i class="el-icon-arrow-down el-icon--right"></i>
+              </el-button>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item command="code">编号管理</el-dropdown-item>
+                <el-dropdown-item command="rule">规范参数配置</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
             <!-- 同步按钮 -->
             <el-button
               size="medium"
@@ -21,10 +31,6 @@
               @click="proSyncbtn"
               >项目数据同步
             </el-button>
-           
-          
-    
-
             <el-button
               size="medium"
               icon="el-icon-s-grid"
@@ -71,6 +77,14 @@
               class="flex"
               style="align-items: center; justify-content: space-between"
             >
+            <div>
+               <div>
+                 <el-radio v-model="searchType" label="1">节点</el-radio>
+               </div>
+                <div>
+                  <el-radio v-model="searchType" label="2">表名</el-radio>
+                </div>
+            </div>
               <el-input
                 placeholder="输入关键字进行过滤"
                 v-model="filterText"
@@ -78,17 +92,14 @@
                 style="width: 65%; margin-right: 15px"
                 @clear="clearSearch"
               ></el-input>
-              <el-switch
-                v-model="searchType"
-                active-value="1"
-                inactive-value="2"
-                inline-prompt
-                active-text="按节点"
-                inactive-text="按表名"
-              />
+             
               <el-button type="primary" @click="searchTreeClick"
                 >搜索</el-button
               >
+             
+              <el-tooltip content="查询工序节点无内业资料类型" placement="top">
+                <el-button type="success" @click="filterSearchClick" >过滤</el-button>
+              </el-tooltip>
             </div>
             <div class="flex1 ov-hidden">
               <el-scrollbar class="h-100p" v-if="isShowTree">
@@ -630,7 +641,7 @@
           </el-table-column>
           <el-table-column prop="nodeType" label="节点类型" v-if="wbsType == 5">
             <template slot-scope="scope">
-              <el-select v-model="scope.row.nodeType" placeholder="请选择">
+              <el-select v-model="scope.row.nodeType" placeholder="请选择" >
                 <el-option
                   v-for="item in nodeTypelist"
                   :key="item.id"
@@ -663,7 +674,7 @@
       />
     </div>
 
-   
+
     <el-dialog
       title="调整排序"
       :visible.sync="sortTag"
@@ -798,6 +809,7 @@
             placeholder="请选择"
             class="w-100p"
             @change="nodeTypeChange"
+            clearable
           >
             <el-option
               v-for="item in nodeTypelist"
@@ -810,7 +822,10 @@
         <el-form-item label="划分编号" v-if="wbsType !== 2 && wbsType !== 5">
           <el-input v-model="nodeDetail.partitionCode"></el-input>
         </el-form-item>
-        <el-form-item label="唯一编码" v-if="wbsType !== 5">
+        <!-- <el-form-item label="唯一编码" v-if="wbsType !== 5">
+          <el-input v-model="nodeDetail.uniqueCode"></el-input>
+        </el-form-item> -->
+        <el-form-item label="参数掩码" v-if="wbsType !== 5">
           <el-input v-model="nodeDetail.uniqueCode"></el-input>
         </el-form-item>
         <template v-if="nodeDetail.nodeType == 6">
@@ -836,6 +851,7 @@
             v-model="nodeDetail.majorDataType"
             placeholder="请选择"
             class="w-100p"
+            clearable
           >
             <el-option
               v-for="item in majorDataTypeList"
@@ -851,6 +867,7 @@
             placeholder="请选择"
             class="w-100p"
             @change="changeStandType"
+            clearable
           >
             <el-option
               v-for="item in standardTypeOptions"
@@ -865,6 +882,7 @@
             v-model="nodeDetail.unitName"
             placeholder="请选择"
             class="w-100p"
+            clearable
           >
             <el-option
               v-for="item in unitOptions"
@@ -1919,7 +1937,7 @@
           <el-scrollbar style="height: 100%;">
                 <div v-loading="treeLoad">
                   <el-tree
-                
+                check-strictly
                     class="filter-tree"
                     lazy
                     :load="loadNode"
@@ -1979,23 +1997,7 @@
                       </el-option>
                     </el-select>
                 </el-form-item>
-                  <!-- <el-form-item label="选择同步范围(节点状态)" prop="contractRange" v-if="syncForm.range==='2'">
-                    <el-checkbox-group v-model="syncForm.contractRange">
-                      <el-checkbox label="全选" name="1"></el-checkbox>
-                      <el-checkbox v-for="(item,index) in checkIdList"  :label="item.dictKey" :key="item.id">{{ item.dictValue}}</el-checkbox>
-                    
-                    </el-checkbox-group>
-                  </el-form-item>
-                  <el-form-item label="选择同步源" prop="templateId" v-else>
-                    <el-select v-model="syncForm.templateId" placeholder="请选择同步源" style="width: 100%;" size="small" @change="changeTemplateId">
-                      <el-option
-                        v-for="item in templateIdList"
-                        :key="item.id"
-                        :label="item.name"
-                        :value="item.id">
-                      </el-option>
-                    </el-select>
-                </el-form-item> -->
+                
             </el-form>
             <div class="table-box" v-if="isShowTable">
               <h4 style="margin-left: 4px;">表单预览</h4>
@@ -2045,6 +2047,7 @@
       width="30%"
       append-to-body
       :close-on-click-modal="false"
+      @close="closeSyncListTag"
     >
     <div class="content-box" v-loading="refreshLoading||refreshLoading1">
       <el-image
@@ -2084,7 +2087,7 @@
                     lazy
                     :load="loadNode"
                    @node-click="handleNodeClick"
-                   
+                    :default-expanded-keys="defaultExpandedKeys"
                     :props="defaultProps"
                     :expand-on-click-node="false"
                     highlight-current
@@ -2107,6 +2110,7 @@
                   style="width: 100%"
                   max-height="300"
                   @selection-change="handleSelectionChange1"
+                  
                   >
                   <el-table-column
                     type="selection"
@@ -2137,7 +2141,8 @@
         <el-button type="primary" @click="saveTableSync" :loading="saveTableSyncLoad">确 定</el-button>
       </span>
     </el-dialog>
-
+    <!-- 编号设置弹窗 -->
+     <CodeSet ref="codeSetRef"  ></CodeSet>
   </div>
 </template>
 
@@ -2147,6 +2152,7 @@ import dynamicExcel from "./treeTemplate/dynamicExcel.vue";
 import FormulaEdit from "@/views/formula/edit.vue";
 import FormulaEditone from "@/views/formula/edit1.vue";
 import EditElement from "@/views/manager/projectinfo/editElement/editElement.vue";
+import CodeSet from "./codeSet.vue";
 import {
   saveFormAndElement,
   selectFormElements,
@@ -2164,6 +2170,7 @@ import {
   selectPrivateFormElements,
   syncCurrentFormInProject,
   getQueryValueByType,
+  getQueryValueByNodeType
 } from "@/api/manager/wbstree";
 import {
   saveElement,
@@ -2210,6 +2217,7 @@ import { selectByNodeTable   as findNodeTableByCondition1 } from "@/api/manager/
 
 
 export default {
+
   data() {
     var checkMajorDataType = (rule, value, callback) => {
       //console.log(this.nodeDetail.nodeType)
@@ -2553,8 +2561,8 @@ export default {
       typeOptions:[],
       checkAll: false,
       checkAll1: false,
-      isIndeterminate: true,
-      isIndeterminate1: true,
+      isIndeterminate: false,
+      isIndeterminate1: false,
       syncForm:{
         range:'',
         rangeName:'',
@@ -2588,6 +2596,10 @@ export default {
       },
       isAdd:'',
       refreshLoading1:false,
+      codeDialog:false,
+ 
+      codeSetRef: null,
+      typeTem:''
       
     };
   },
@@ -3118,6 +3130,27 @@ export default {
         this.isSearch = false;
       }
 
+      this.searchtreeLoad = false;
+    },
+    filterSearchClick(){
+    
+        this.isSearch = true;
+        this.searchtreeLoad = true;
+        getQueryValueByNodeType({
+          queryValue: this.filterText,
+          wbsId: this.id,
+          projectId: this.projectid,
+        }).then((res) => {
+          let arr = [];
+          if (Array.isArray(res.data.data)) {
+            arr = res.data.data;
+            this.searchTreeData = arr;
+          } else {
+            this.searchTreeData = [];
+          }
+        });
+      
+
       this.searchtreeLoad = false;
     },
     clearSearch() {
@@ -3389,7 +3422,10 @@ export default {
           element.dictKey = Number(element.dictKey);
     
         });
-        this.majorDataTypeList = res.data.data;
+        // this.majorDataTypeList = res.data.data;
+        this.majorDataTypeList = res.data.data.filter(
+          (item) => item.dictKey != 0
+        );
        
         
       });
@@ -4250,7 +4286,7 @@ export default {
      console.log('后管数据同步',data);
      this.curTreeData=data
      this.isShowLeft=false
-     await  this.getNodeStatusData()
+    //  await  this.getNodeStatusData()
       if(this.syncListDialog){
         return
       }
@@ -4312,7 +4348,7 @@ export default {
       if(this.syncListDialog){
         return
       }
-      await  this.getNodeStatusData()
+      // await  this.getNodeStatusData()
        this.syncForm.range='2'
        
        this.proSyncTag=true
@@ -4323,7 +4359,7 @@ export default {
    
       this.getCheckIdList()
       selectByNodeTable(data.id, this.projectid, this.id).then((res) => {
-          if (res.data.data.length) {
+          if (res.data.data.length>0) {
             this.preTableData = res.data.data;
           } else {
             this.preTableData = [];
@@ -4941,6 +4977,7 @@ export default {
             const elemet = this.templateIdList[index];
             if(elemet.id==val){
               type = elemet.type;
+              this.typeTem=elemet.type
               projectId=elemet.id
               wbsId=elemet.wbsId
              
@@ -4949,7 +4986,7 @@ export default {
         }
         if(type===2){
           selectByNodeTable(this.curTreeData.id, projectId, wbsId).then((res) => {
-          if (res.data.data.length) {
+          if (res.data.data&&res.data.data.length > 0) {
             this.preTableData = res.data.data;
           } else {
             this.preTableData = [];
@@ -5004,6 +5041,10 @@ export default {
       if(this.isShowLeft){
         let ids=this.$refs.syncProTree.getCheckedKeys()
         this.syncForm.nodeId=ids.join(',')
+        if(this.syncForm.nodeId===''){
+         this.$message.warning('请选择节点')
+         return
+       }
       }else{
         this.syncForm.nodeId=this.curTreeData.primaryKeyId
       }
@@ -5072,6 +5113,10 @@ export default {
         this.saveProTagLoading = false;
       });
     },
+    closeSyncListTag(){
+      this.syncListDialog=false;
+       this.updateNodeTable()
+    },
     handleCheckAllChange(val) {
         this.syncForm.type = val ? this.typeOptions.map(item => item.dictKey) : [];
         this.isIndeterminate = false;
@@ -5095,14 +5140,20 @@ export default {
       if(val.length>0){
         for (let index = 0; index < val.length; index++) {
           let i = val[index];
-         arr.push(i.id)
+          if( this.typeTem===2){
+             arr.push(i.pkeyId)
+          }else{
+             arr.push(i.id)
+          }
+           
+        //  arr.push(i.id)
         }
 
         this.syncForm.formIds=arr.join(',')
       }
     },
   async  handleCommand(command,row){
-  await  this.getNodeStatusData()
+  // await  this.getNodeStatusData()
   if(this.syncListDialog){
     return
   }
@@ -5136,6 +5187,8 @@ export default {
      
         
         this.syncTableDialog=true
+        this.isShowLeft=true
+
         if(this.$refs.proTable1){
           this.$refs.proTable1.clearSelection()
         }
@@ -5160,6 +5213,7 @@ export default {
                     this.$message.success(res.data.msg)
                     this.syncTableDialog=false
                     this.$refs.proTable1.clearSelection()
+                    this.updateNodeTable()
                    
                     }else{
                       this.$message.error(res.data.msg)
@@ -5179,16 +5233,22 @@ export default {
      
     },
     handleSelectionChange1(val) {
-      let arr = []
-      if(val.length>0){
-        for (let index = 0; index < val.length; index++) {
-          let i = val[index];
-         arr.push(i.id)
-        }
-        this.formIds=arr.join(',')
 
-        // this.syncForm.formIds=arr.join(',')
+      
+        if (val.length > 1) {
+          // 如果选择了多个,只保留最后一个
+          this.$nextTick(() => {
+            this.$refs.proTable1.clearSelection();
+            this.$refs.proTable1.toggleRowSelection(val.pop());
+          });
       }
+      if(val.length>0){
+        this.formIds=val[0].pkeyId
+      }else{
+        this.formIds=''
+      }
+       
+  
     },
    async refreshData(){
     this.refreshLoading=true
@@ -5292,6 +5352,28 @@ export default {
                       this.$message.error(res.data.msg)
                     }
         });
+    },
+    //基础数据管理
+    handleBasicClick(command) {
+    
+      if (command === "code") {
+        this.codeDialog = true;
+      
+        this.$refs.codeSetRef.show(this.projectid)
+      }else if(command === "rule") {
+          this.$router.push({
+            path: "/rule/manager",
+            query: {
+              id: this.id,
+              parentId:this.nodeDetail.parentId,
+              tenant_id: this.userInfo.tenant_id,
+              projectid: this.projectid,
+
+            },
+          
+          });
+
+      }
     }
   },
   watch: {
@@ -5373,6 +5455,7 @@ export default {
     FormulaEdit,
     EditElement,
     FormulaEditone,
+    CodeSet
   },
 };
 </script>

+ 3 - 3
src/views/manager/projectinfo/treeTemplate/template/editDefault.vue

@@ -62,7 +62,7 @@
         <tr v-for="(item,key) in setsignaTable" :key="key" v-on:click="">
           <td>{{ item.colName }}</td>
           <td>{{ item.sigRoleName }}</td>
-          <td align="center"><span style="color:red;cursor: pointer;" v-on:click="deleteTableSig(item.id)">删除</span></td>
+          <td align="center"><span style="color:red;cursor: pointer;" v-on:click="deleteTableSig(item.id,item.type,item.colKey)">删除</span></td>
         </tr>
         </tbody>
       </table>
@@ -135,8 +135,8 @@ export default {
 // }
 
     },
-    async deleteTableSig (ids) {//删除数据
-      const {data: res} = await remove(ids, this.pkeyId1);
+    async deleteTableSig (ids,type,colKey) {//删除数据
+      const {data: res} = await remove(ids, this.pkeyId1,type,colKey);
       this.getSingInfo();
       if (res.code === 200) {
         this.$message({

+ 6 - 4
src/views/manager/projectinfo/treeTemplate/template/electronicSignature.vue

@@ -111,12 +111,12 @@
     <div style="border: 1px dotted rgb(187, 187, 187);box-sizing: border-box;padding: 0px 15px;" class="martop20 marbottom10">
       <el-tabs v-model="activeName" @tab-click="handleActiveClick">
         <el-tab-pane label="电签配置" name="tab1">
-          <table @click class="table martop20 copyTable" width='100%' border='1px ' bordercolor="#E5E5E5" cellpadding='2px'>
+             <table @click class="table martop20 copyTable" width='100%' border='1px ' bordercolor="#E5E5E5" cellpadding='2px'>
             <thead cellpadding='2px' height='40px'>
             <tr>
               <th >元素位置</th>
               <th>签字岗位</th>
-              <th>是否引用系统级电签</th>
+              <th>电签来源</th>
               <th>签字时间元素位置</th>
               <th >偏移x</th>
               <th>偏移y</th>
@@ -128,8 +128,10 @@
               <td>{{ item.colName }}</td>
               <td>{{ item.sigRoleName }}</td>
               <td align="center">
-                  <i class="el-icon-success" style="font-size: 20px;color:#67C23A" v-if="item.isSystem==1"></i>
-                  <i class="el-icon-error" style="font-size: 20px;color:red" v-else></i>
+            
+                    <el-tag type="success"  v-if="item.isSystem==1">电签角色库</el-tag>
+                    <el-tag type="info" v-if="item.isSystem==2">项目匹配</el-tag>
+                    <el-tag type="warning"  v-if="item.isSystem==0">本表配置</el-tag>
               </td>
               <td>{{ item.timeName }}</td>
               <td>{{ item.pyzbx }}</td>

+ 16 - 2
src/views/manager/wbsinfo/edit.vue

@@ -522,6 +522,7 @@
             placeholder="请选择"
             class="w-100p"
             @change="nodeTypeChange"
+            clearable
           >
             <el-option
               v-for="item in nodeTypelist"
@@ -537,7 +538,10 @@
         >
           <el-input v-model="nodeDetail.partitionCode"></el-input>
         </el-form-item>
-        <el-form-item label="唯一编码" v-if="(wbsType !== 5) & (wbsType !== 3)">
+        <!-- <el-form-item label="唯一编码" v-if="(wbsType !== 5) & (wbsType !== 3)">
+          <el-input v-model="nodeDetail.uniqueCode"></el-input>
+        </el-form-item> -->
+         <el-form-item label="参数掩码" v-if="wbsType !== 5">
           <el-input v-model="nodeDetail.uniqueCode"></el-input>
         </el-form-item>
         <template v-if="nodeDetail.nodeType == 6 && wbsType !== 3">
@@ -563,6 +567,7 @@
             v-model="nodeDetail.majorDataType"
             placeholder="请选择"
             class="w-100p"
+              clearable
           >
             <el-option
               v-for="item in majorDataTypeList"
@@ -604,6 +609,7 @@
             placeholder="请选择"
             class="w-100p"
             @change="changeStandType"
+              clearable
           >
             <el-option
               v-for="item in standardTypeOptions"
@@ -618,6 +624,7 @@
             v-model="nodeDetail.unitName"
             placeholder="请选择"
             class="w-100p"
+              clearable
           >
             <el-option
               v-for="item in unitOptions"
@@ -1204,7 +1211,7 @@
           <i
             class="el-icon-refresh-right marbottom10"
             @click="refreshnfoTable()"
-            style="font-size: 24px; color: rgb(37, 193, 99); cursor: pointer"
+            style="font-size: 24px; color: rgb(37, 193, 99); cursor: pointer" v-loading="nodeInfoTableLoad"
           ></i>
         </div>
         <el-table :data="nodeInfoTable" border style="width: 100%" height="400">
@@ -1543,6 +1550,8 @@ export default {
 
     return {
       loding: false,
+      nodeInfoTableLoad: false,
+
       formDatass: [],
       editElementFormTag: false,
       ImportElementdata: {},
@@ -2750,8 +2759,13 @@ export default {
         nodeId: this.jiedianId,
         type: 0,
       };
+      this.nodeInfoTableLoad = true;
       refrehPram(prams).then((res) => {
         console.log(res);
+         if (res.data.code == 200) {
+           this.nodeInfoTableLoad = false;
+          this.$message.success("刷新成功");
+        }
       });
     },
     delNodeInfo(key, obj) {

+ 23 - 3
src/views/manager/wbsinfo/element.vue

@@ -286,10 +286,29 @@
       :close-on-click-modal="false"
     >
       <p class="font-c-warning">编辑元素信息(请谨慎操作)</p>
-        <div style="display:flex;margin-bottom:10px">
-                      <el-input placeholder="请输入你想编辑的元素名称" v-model="searchinput" :size="size"  clearable  @clear="clearsearchinput" >  </el-input>
+        <div style="display:flex;margin-bottom:10px;">
+          <el-input placeholder="请输入你想编辑的元素名称" v-model="searchinput"  clearable  @clear="clearsearchinput"  style="width:300px;margin-right:10px">  </el-input>
+                        
+          <el-select
+              v-model="eTypeVal"
+            style="width:200px;margin-right:10px;"
+            clearable
+
+
+             
+              placeholder="请选择数据类型"
+            >
+              <el-option
+                v-for="item in dataTypeList"
+                :key="item.id"
+                :label="item.dictValue"
+                :value="item.dictKey"
+              ></el-option>
+            </el-select>
+        
                       <el-button type="primary" icon="el-icon-search"  size="small"  @click="searchinputChange">搜索</el-button>
         </div>
+
       <el-table
         :data="editEleList"
         border
@@ -743,6 +762,7 @@ export default {
       sortTag2: false,
       sort:[],
       searchinput:'',
+      eTypeVal:''
 
     }
   },
@@ -1099,7 +1119,7 @@ export default {
     //获取编辑元素信息
     getselectPrivateFormElements(){
        this.editEleloading=true
-            selectPrivateFormElements(this.curEleTable.id,{eName:this.searchinput}).then((res) => {
+            selectPrivateFormElements(this.curEleTable.id,{eName:this.searchinput,eType:this.eTypeVal}).then((res) => {
                 this.editEleloading=false
                 res.data.data.forEach((element) => {
                 this.eleReg.exec(element.eAllowDeviation);

+ 2 - 1
src/views/system/announcement.vue

@@ -275,7 +275,8 @@ export default {
       isSystemUpdateShow: false,
       updateFormModel: {
         updateServerType: [],
-        pushSystem: []
+        pushSystem: [],
+        msgContent:'【系统维护公告】为提升系统安全性及运行效率,系统将于今日((需填写更新时间))进行更新升级,请您提前保存好工作数据。维护期间系统将暂停访问,给您带来不便,敬请谅解!如有疑问,请联系系统工作人员处理。'
       },
       updateFormRules: {
         msgContent: [

+ 14 - 5
src/views/system/user.vue

@@ -583,6 +583,12 @@ export default {
             prop: "userTypeName",
             slot: true,
             display: false
+          },
+            {
+            label: "密码",
+            prop: "plaintextPassword",
+            slot: true,
+            display: false
           },
           {
             label: "用户平台",
@@ -752,6 +758,7 @@ export default {
                 label: "参建项目",
                 prop: "projectAndUserList",
                 span: 24,
+                addDisplay: false, // 新增时不显示
                 // rules: [{
                 //   required: true,
                 //   validator: projectAndUserListRules,
@@ -762,23 +769,28 @@ export default {
                 label: "参与项目",
                 prop: "projectId",
                 span: 16,
+                addDisplay: false, // 新增时不显示
               },
               {
                 label: "合同段",
                 prop: "contractId",
                 span: 16,
+                 addDisplay: false, // 新增时不显示
               }, {
                 label: "用户类型",
                 prop: "roleIds",
                 span: 16,
+                 addDisplay: false, // 新增时不显示
               }, {
                 label: "单位名称",
                 prop: "companyName",
                 span: 16,
+                 addDisplay: false, // 新增时不显示
               }, {
                 label: "职位",
                 prop: "position",
                 span: 16,
+                 addDisplay: false, // 新增时不显示
               },
               {
                 label: "允许登录",
@@ -1317,7 +1329,7 @@ export default {
     },
     rowSave(row, done, loading) { //新增保存
       console.log('保存',this.fromss.projectAndUserList);
-      if (this.fromss.projectAndUserList.length > 0) {
+
         let projectAndUserList = []
         this.fromss.projectAndUserList.forEach(val => {
           if (val.dataInfo.length > 0) {
@@ -1341,10 +1353,7 @@ export default {
         }, () => {
           loading();
         });
-      } else {
-        this.$message.warning('请完善参与项目、合同段、并确认添加用户类型')
-        loading()
-      }
+      
     },
     rowUpdate(row, index, done, loading) {//修改按钮
       // row.roleId = row.roleId.join(",");