Sfoglia il codice sorgente

性能验证评价流程0.1

zhonghuizhen 6 mesi fa
parent
commit
e662ef88e5

+ 2 - 2
src/views/business/performance/components/experimental-desc.vue

@@ -162,8 +162,8 @@ export default {
       default: () => []
     },
     references: {
-      type: String,
-      default: ''
+      type: [String, Array], // 修改为支持 String 和 Array
+      default: () => []
     }
   },
   data() {

+ 167 - 34
src/views/business/performance/experimental.vue

@@ -27,7 +27,7 @@
             :step="configData.step || ''"
             :criterion="configData.criterion || ''"
             :formulas="configData.formulas || []"
-            :references="configData.references || []"
+            :references="configData.references || []" 
             :readonly="readonly"
           />
           <basic-info :info="form" :readonly="readonly" />
@@ -102,7 +102,7 @@
           :step="configData.step || ''"
           :criterion="configData.criterion || ''"
           :formulas="configData.formulas || []"
-          :references="configData.references || []"
+          :references="configData.references || []" 
           :readonly="true"
         />
         <basic-info :info="form" :readonly="true" />
@@ -157,6 +157,14 @@
         </div>
       </div>
     </el-dialog>
+    
+    <flow-diagram-dialog
+      :visible="flowDiagramVisible"
+      :def-id="params &&  (params.instanceId  || params.taskId)? '': '1430598730687447040'"
+      :task-id="params && params.taskId ? params.taskId : ''"
+      :inst-id="params && params.instanceId ? params.instanceId : ''"
+      @close="(visible) => (flowDiagramVisible = visible)"
+    />
   </el-dialog>
 </template>
 
@@ -169,10 +177,13 @@ import {
   getConfigDetail,
   recalculate,
   exportTemplate,
-  importTemplate
+  importTemplate,
 } from '@/api/business/pv'
+import { startFlow,saveDraft } from '@/api/platform/bpmn/bpmInst'
+import { agree, reject } from '@/api/platform/bpmn/bpmTask'
 import html2Canvas from 'html2canvas'
 import JsPDF from 'jspdf'
+import FlowDiagramDialog from '@/business/platform/bpmn/components/flow-diagram/dialog'
 export default {
   components: {
     ExperimentalDesc: () => import('./components/experimental-desc'),
@@ -181,7 +192,8 @@ export default {
     ParamInfo: () => import('./components/param-info'),
     ExperimentalData: () => import('./components/experimental-data'),
     Conclusion: () => import('./components/conclusion'),
-    Precision: () => import('./report/precision')
+    Precision: () => import('./report/precision'),
+    FlowDiagramDialog
   },
   props: {
     visible: {
@@ -190,7 +202,7 @@ export default {
     },
     readonly: {
       type: Boolean,
-      default: false
+      default: true
     },
     params: {
       type: Object,
@@ -200,12 +212,13 @@ export default {
   data() {
     const { userId } = this.$store.getters || {}
     return {
-      dialogVisible: this.visible,
+      dialogVisible: true, // Set to true to always display the component
       dialogFormVisible: false,
+      flowDiagramVisible: false,
       pdf: 'pdf',
       formLabelWidth: '110px',
       configData: { methodName: '' },
-      formId: this.params.recordId,
+      formId: this.params.attrs.id,
       form: {
         xingNengZhiBia: '',
         fangAnLeiXing: '',
@@ -227,7 +240,7 @@ export default {
         shiYanShuJu: [],
         jiSuanJieGuo: {},
         shiYanJieLun: '',
-        shiFouGuoShen: '已暂存',
+        shiFouGuoShen: '',
         fuJian: ''
       },
       rules: formRules,
@@ -259,7 +272,7 @@ export default {
         {
           key: 'submit',
           icon: 'el-icon-s-promotion',
-          label: this.getSubmitLabel,
+          label: '同意',
           type: 'primary',
           hidden: this.showToolBarsBtn('submit')
         },
@@ -290,12 +303,13 @@ export default {
     }
   },
   watch: {
+    /*
     visible: {
       handler(val, oldVal) {
         this.dialogVisible = this.visible
       }
       // immediate: true
-    }
+    }*/
   },
   created() {
     // 如果从myRecord传来了shiFouGuoShen,则使用它
@@ -306,12 +320,15 @@ export default {
       }
       this.form.shiFouGuoShen = this.params.shiFouGuoShen
     }
-    this.getConfigData(this.params)
-    if (!this.params.recordId) {
+   // this.getConfigData(this.params)
+    if (!this.params.attrs.id) {
       this.loadCompleted = true
       return
     }
-    this.loadData()
+    if(this.params.attrs.id ){
+        this.loadData()     
+    }
+    
   },
   methods: {
     getpdf() {
@@ -352,7 +369,7 @@ export default {
     // 获取数据
     loadData() {
       this.loading = true
-      getExperimental({ id: this.params.recordId })
+      getExperimental({ id: this.params.attrs.id })
         .then((res) => {
           this.loading = false
           const data = res.data
@@ -369,6 +386,7 @@ export default {
             ? JSON.parse(data.jiSuanJieGuo)
             : {}
           this.form = Object.assign(this.form, data)
+          this.getConfigData(this.form)
           this.loadCompleted = true
           console.log(data.jiSuanJieGuo)
         })
@@ -376,14 +394,14 @@ export default {
           this.loading = false
         })
     },
-    getConfigData({ targetId, methodId }) {
-      getConfigDetail({ id: targetId }).then((res) => {
+    getConfigData({ zhiBiaoId,fangFaId  }) {
+      getConfigDetail({ id: zhiBiaoId }).then((res) => {
         const {
           target,
           targetKey,
           experimentalConfigDetailPoList: methods
         } = res.data || {}
-        const method = methods.find((i) => i.id === methodId) || {}
+        const method = methods.find((i) => i.id === fangFaId) || {}
         this.configData = {
           target,
           targetKey,
@@ -401,28 +419,103 @@ export default {
     handleActionEvent(key) {
       switch (key) {
         case 'save':
+          //this.handleSave(this.form);
+          this.saveExperimentalData(this.form.id,this.form.shiFouGuoShen)
+          break;
         case 'submit':
-          this.handleSubmit('submit', true)
-          break
+          this.handleAgree({ taskId: this.params.taskId, data: this.form });
+          /*
+          if (this.getSubmitLabel() === '同意') {
+            this.handleAgree({ taskId: this.params.taskId, data: this.form });
+          } else {
+           // this.handleStartFlow(this.form);
+          }*/
+          break;
+        case 'sendBack':
+          this.handleReject({ taskId: this.params.taskId, data: this.form });
+          break;
         case 'generate':
-          this.handleGenerate()
-          break
+          this.handleGenerate();
+          break;
         case 'cancel':
-          this.handleCancel()
-          break
+          this.handleCancel();
+          break;
         case 'test':
-          this.handleTest()
-          break
+          this.handleTest();
+          break;
         case 'pdf':
-          this.dialogFormVisible = true
-          break
+          this.dialogFormVisible = true;
+          break;
+        case 'flowChart':
+          this.flowDiagramVisible = true;
+          break;
         default:
-          break
+          break;
       }
     },
+    /*
+    handleSave(data) {
+      saveDraft(data).then(() => {
+        this.$message.success('保存成功');
+      }).catch(() => {
+        this.$message.error('保存失败');
+      });
+    },
+    validateFormData() {
+      return new Promise((resolve, reject) => {
+        this.$refs.form.validate((valid) => {
+          if (!valid) {
+            this.$message.warning('请完善表单必填项后再进行操作!');
+            reject('Validation failed');
+          } else {
+            const { shiYanXiangMu } = this.form;
+            const regex = /[\/\\]/g;
+            if (regex.test(shiYanXiangMu)) {
+              this.form.shiYanXiangMu = shiYanXiangMu.replace(regex, '_');
+              this.$message.warning('【实验项目】中的【\\】与【/】已被转化为【_】');
+            }
+            resolve();
+          }
+        });
+      });
+    },*/
+    /*
+    handleStartFlow(data) {
+      this.validateFormData()
+        .then(() => {
+          return startFlow({
+            defId: '1430598730687447040',
+            version: '0',
+            data: JSON.stringify(data)
+          });
+        })
+        .then(() => {
+          this.$message.success('提交成功');
+          this.visible = false;
+          return this.saveExperimentalData()
+        })
+        .catch((error) => {
+            this.$message.error('启动失败');
+        });
+    },*/
+    handleAgree(data) {
+      agree(data).then(() => {
+        this.$message.success('操作成功');
+      }).catch(() => {
+        this.$message.error('操作失败');
+      });
+    },
+    handleReject(data) {
+      reject(data).then(() => {
+        this.$message.success('退回成功');
+      }).catch(() => {
+        this.$message.error('退回失败');
+      });
+    },
+    /*
     handleSave(key, callback) {
       this.submitForm(key, callback)
-    },
+    },*/
     handleSubmit(key, showMsg, callback) {
       this.$refs.form.validate((valid) => {
         if (!valid) {
@@ -509,9 +602,9 @@ export default {
           : null,
         xingNengZhiBia: this.configData.target,
         fangAnLeiXing: this.configData.methodName,
-        zhiBiaoId: this.params.targetId,
-        fangFaKey: this.params.methodKey,
-        fangFaId: this.params.methodId,
+        //zhiBiaoId: this.params.targetId,
+        //fangFaKey: this.params.methodKey,
+        //fangFaId: this.params.methodId,
         id: this.formId
       }
       const isEdit = !!this.formId
@@ -533,12 +626,52 @@ export default {
         }
       })
     },
+    saveExperimentalData(idval,statusval) {
+        const {
+          kaiShiShiJian,
+          jieShuShiJian,
+          shiYanCanShu,
+          shiYanShuJu,
+          jiSuanJieGuo,
+          ...rest
+        } = this.form || {};
+        const submitData = {
+          ...rest,
+          kaiShiShiJian,
+          jieShuShiJian,
+          shiFouGuoShen: statusval,
+          id: idval || this.formId,
+          shiYanCanShu: this.$utils.isNotEmpty(shiYanCanShu)
+            ? JSON.stringify(shiYanCanShu)
+            : null,
+          shiYanShuJu: this.$utils.isNotEmpty(shiYanShuJu)
+            ? JSON.stringify(shiYanShuJu)
+            : null,
+          jiSuanJieGuo: this.$utils.isNotEmpty(jiSuanJieGuo)
+            ? JSON.stringify(jiSuanJieGuo)
+            : null,
+          xingNengZhiBia: this.configData.target,
+          fangAnLeiXing: this.configData.methodName,
+          //zhiBiaoId: this.params.targetId,
+          //fangFaKey: this.params.methodKey,
+          //fangFaId: this.params.methodId,
+          //id: this.formId
+        };
+        return saveExperimental(submitData).then((res) => {
+          this.formId = res.data;
+          //this.$message.success('保存成功');
+        }).catch(() => {
+          //this.$message.error('保存失败');
+        });
+    },
     handleCancel() {
       this.closeDialog()
     },
     closeDialog() {
-      this.$emit('update:visible', false)
-      this.$emit('refresh')
+      this.dialogVisible = false
+      this.$emit('close', false)
+      //this.$emit('update:visible', false)
+      //this.$emit('refresh')
     },
     handleUpdateParams(value) {
       this.form.shiYanCanShu = value

+ 1043 - 0
src/views/business/performance/experimentalView.vue

@@ -0,0 +1,1043 @@
+<template>
+    <el-dialog
+      v-loading="loading"
+      :visible.sync="localVisible"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      :show-close="false"
+      append-to-body
+      fullscreen
+      class="dialog experimental-dialog"
+      top="0"
+      @open="loadData"
+      @close="closeDialog"
+    >
+    <div>列表进来</div>
+      <el-form
+        ref="form"
+        :label-width="formLabelWidth"
+        :model.sync="form"
+        :rules="rules"
+        class="config-form"
+        :class="readonly ? 'readonly-form' : ''"
+        @submit.native.prevent
+      >
+        <div v-if="loadCompleted" class="config-form-container">
+          <div class="left">
+            <experimental-desc
+              :step="configData.step || ''"
+              :criterion="configData.criterion || ''"
+              :formulas="configData.formulas || []"
+              :references="configData.references || []"
+              :readonly="readonly"
+            />
+            <basic-info :info="form" :readonly="readonly" />
+            <reagent-info :info="form.reagentPoList" :readonly="readonly" />
+            <param-info
+              v-if="$utils.isNotEmpty(configData && configData.params)"
+              :form-id="formId"
+              :info="form.shiYanCanShu"
+              :config-data="configData.params || []"
+              :readonly="readonly"
+              @updateParams="handleUpdateParams"
+            />
+          </div>
+          <div class="right">
+            <experimental-data
+              :exp="form.jiSuanJieGuo"
+              :form-id="formId"
+              :readonly="readonly"
+              @export="handleExport"
+              @import="handleImport"
+            />
+            <precision
+              v-if="$utils.isNotEmpty(form.jiSuanJieGuo)"
+              :info="form.jiSuanJieGuo"
+              :readonly="readonly"
+              @recalculate="handleRecalculate"
+            />
+            <conclusion
+              :result="form.shiYanJieLun"
+              :files="form.fuJian"
+              :readonly="readonly"
+              @updateData="handleUpdateData"
+            />
+          </div>
+        </div>
+      </el-form>
+      <div slot="title" class="config-dialog-header">
+        <div class="title">{{ configData.methodName || '' }}</div>
+        <div class="operate">
+          <template v-for="btn in toolbars">
+            <el-button
+              v-if="!btn.hidden"
+              :key="btn.key"
+              :type="btn.type"
+              :icon="btn.icon"
+              :size="btn.size || 'mini'"
+              @click="handleActionEvent(btn.key)"
+            >
+              {{ typeof btn.label === "function" ? btn.label() : btn.label }}
+            </el-button>
+          </template>
+        </div>
+      </div>
+      <el-dialog
+        fullscreen
+        :show-close="false"
+        :modal="false"
+        :visible.sync="dialogFormVisible"
+      >
+        <el-form id="pdfDom">
+          <div
+            style="
+              text-align: center;
+              font-size: 20px;
+              font-weight: bold;
+              margin-bottom: 20px;
+            "
+          >
+            {{ configData.methodName || '' }}
+          </div>
+          <experimental-desc
+            :step="configData.step || ''"
+            :criterion="configData.criterion || ''"
+            :formulas="configData.formulas || []"
+            :references="configData.references || []"
+            :readonly="true"
+          />
+          <basic-info :info="form" :readonly="true" />
+          <reagent-info :info="form.reagentPoList" :readonly="true" :pdf="pdf" />
+          <param-info
+            v-if="$utils.isNotEmpty(configData && configData.params)"
+            :form-id="formId"
+            :info="form.shiYanCanShu"
+            :config-data="configData.params || []"
+            :readonly="true"
+            @updateParams="handleUpdateParams"
+          />
+  
+          <experimental-data
+            :exp="form.jiSuanJieGuo"
+            :form-id="formId"
+            :readonly="true"
+            :pdf="pdf"
+            @export="handleExport"
+            @import="handleImport"
+          />
+          <precision
+            v-if="$utils.isNotEmpty(form.jiSuanJieGuo)"
+            :info="form.jiSuanJieGuo"
+            :readonly="true"
+            :pdf="pdf"
+            @recalculate="handleRecalculate"
+          />
+          <conclusion
+            :result="form.shiYanJieLun"
+            :files="form.fuJian"
+            :readonly="true"
+            :pdf="pdf"
+            @updateData="handleUpdateData"
+          />
+        </el-form>
+        <div slot="title" class="config-dialog-header">
+          <div class="title">{{ configData.methodName }}</div>
+          <div class="operate">
+            <template>
+              <el-button style="width: 80px" type="success" @click="getpdf()">
+                导出
+              </el-button>
+              <el-button
+                style="width: 80px"
+                type="danger"
+                @click="dialogFormVisible = false"
+              >
+                取消
+              </el-button>
+            </template>
+          </div>
+        </div>
+      </el-dialog>
+      
+      <flow-diagram-dialog
+        :visible="flowDiagramVisible"
+        :def-id="params &&  (params.instanceId  || params.taskId)? '': '1430598730687447040'"
+        :task-id="params && params.taskId ? params.taskId : ''"
+        :inst-id="params && params.instanceId ? params.instanceId : ''"
+        @close="(visible) => (flowDiagramVisible = visible)"
+      />
+    </el-dialog>
+  </template>
+  
+  <script>
+  import { formRules } from './constants/index'
+  import ActionUtils from '@/utils/action'
+  import {
+    getExperimental,
+    saveExperimental,
+    getConfigDetail,
+    recalculate,
+    exportTemplate,
+    importTemplate,
+  } from '@/api/business/pv'
+  import { startFlow,saveDraft } from '@/api/platform/bpmn/bpmInst'
+ // import { agree, reject } from '@/api/platform/bpmn/bpmTask'
+  import html2Canvas from 'html2canvas'
+  import JsPDF from 'jspdf'
+  import FlowDiagramDialog from '@/business/platform/bpmn/components/flow-diagram/dialog'
+  export default {
+
+    components: {
+      ExperimentalDesc: () => import('./components/experimental-desc'),
+      BasicInfo: () => import('./components/basic-info'),
+      ReagentInfo: () => import('./components/reagent-info'),
+      ParamInfo: () => import('./components/param-info'),
+      ExperimentalData: () => import('./components/experimental-data'),
+      Conclusion: () => import('./components/conclusion'),
+      Precision: () => import('./report/precision'),
+      FlowDiagramDialog
+    },
+    props: {
+      visible: {
+        type: Boolean,
+        default: false
+      },
+      readonly: {
+        type: Boolean,
+        default: false
+      },
+      params: {
+        type: Object,
+        default: () => {}
+      }
+    },
+    data() {
+      const { userId } = this.$store.getters || {}
+      return {
+        localVisible: this.visible, // 定义一个本地变量
+        dialogFormVisible: false,
+        flowDiagramVisible: false,
+        pdf: 'pdf',
+        formLabelWidth: '110px',
+        configData: { methodName: '' },
+        formId: this.params.recordId,
+        form: {
+          xingNengZhiBia: '',
+          fangAnLeiXing: '',
+          bianZhiBuMen: '',
+          shiYanXiangMu: '',
+          shiYanFangFa: '',
+          yangBenLeiXing: '',
+          shiYanYiQi: '',
+          yiQiBianHao: '',
+          kaiShiShiJian: '',
+          jieShuShiJian: '',
+          bianZhiRen: '',
+          createBy: userId,
+          jieGuoDanWei: '',
+          baoLiuXiaoShu: 3,
+          beiZhu: '',
+          reagentPoList: [],
+          shiYanCanShu: {},
+          shiYanShuJu: [],
+          jiSuanJieGuo: {},
+          shiYanJieLun: '',
+          shiFouGuoShen: '',
+          fuJian: ''
+        },
+        rules: formRules,
+        loading: false,
+        loadCompleted: false,
+        toolbars: [
+        {
+            key: 'flowChart',
+            icon: 'ibps-icon-picture',
+            label: '流程图',
+            type: 'primary',
+            hidden: this.showToolBarsBtn('flowChart')
+          },
+          {
+            key: 'pdf',
+            icon: 'ibps-icon-cube',
+            label: '导出为PDF',
+            type: 'primary',
+            hidden: this.showToolBarsBtn('pdf')
+          },
+          // { key: 'test', icon: 'ibps-icon-gg', label: '测试', type: 'warning', hidden: this.readonly },
+          {
+            key: 'save',
+            icon: 'ibps-icon-save',
+            label: '保存',
+            type: 'primary',
+            hidden: this.showToolBarsBtn('save')
+          },
+          {
+            key: 'submit',
+            icon: 'el-icon-s-promotion',
+            label: this.getSubmitLabel,
+            type: 'primary',
+            hidden: this.showToolBarsBtn('submit')
+          },
+          {
+            key: 'sendBack',
+            icon: 'ibps-icon-check-square-o',
+            label: '退回',
+            type: 'primary',
+            hidden: this.showToolBarsBtn('sendBack')
+          },
+          // { key: 'submit', icon: 'ibps-icon-send', label: '提交', type: 'primary', hidden: this.readonly },
+          // { key: 'generate', icon: 'ibps-icon-cube', label: '生成报告', type: 'success', hidden: this.readonly },
+          {
+            key: 'cancel',
+            icon: 'el-icon-close',
+            label: '关闭',
+            type: 'danger',
+            hidden: this.showToolBarsBtn('cancel')
+          }
+        ],
+        validateList: [
+          'specimensName',
+          'targetValue',
+          'allowableSDr',
+          'allowableSDl',
+          'claimValue'
+        ]
+      }
+    },
+    watch: {
+      visible: {
+        handler(val) {
+          this.localVisible = val; // 当父组件的 visible 改变时,同步更新 localVisible
+        },
+        immediate: true
+      }
+    },
+    created() {
+      // 如果从myRecord传来了shiFouGuoShen,则使用它
+      if (this.params && this.params.shiFouGuoShen) {
+        // 确保form对象存在
+        if (!this.form) {
+          this.form = {}
+        }
+        this.form.shiFouGuoShen = this.params.shiFouGuoShen
+      }
+      this.getConfigData(this.params)
+      if (!this.params.recordId) {
+        this.loadCompleted = true
+        return
+      }
+      if(this.params.recordId ){
+          this.loadData()      
+      }
+      
+    },
+    methods: {
+      async fetchInstanceId(dataId) { //获取当前单据对应流程
+        const instres = await this.$common.request('query', {
+          key: 'xnyzkspjcxdylc',
+          params: [dataId]
+        });
+        return instres.variables.data[0]?.id_ || '';
+      },
+      getpdf() {
+        const newDiv = document.querySelector('#pdfDom')
+        const title = this.params.methodKey
+        html2Canvas(newDiv, {
+          allowTaint: false,
+          taintTest: false,
+          logging: false,
+          useCORS: true,
+          dpi: window.devicePixelRatio * 4, // 将分辨率提高到特定的DPI 提高四倍
+          scale: 4 // 按比例增加分辨率
+        }).then(function (canvas) {
+          const contentWidth = canvas.width
+          const contentHeight = canvas.height
+          const pageHeight = (contentWidth / 592.28) * 841.89
+          var leftHeight = contentHeight
+          var position = 0
+          const imgWidth = 595.28
+          const imgHeight = (592.28 / contentWidth) * contentHeight
+          const pageData = canvas.toDataURL('image/jpeg', 1.0)
+          const PDF = new JsPDF('', 'pt', 'a4')
+          if (leftHeight < pageHeight) {
+            PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
+          } else {
+            while (leftHeight > 0) {
+              PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
+              leftHeight -= pageHeight
+              position -= 841.89
+              if (leftHeight > 0) {
+                PDF.addPage()
+              }
+            }
+          }
+          PDF.save(title + '.pdf')
+        })
+      },
+      // 获取数据
+      loadData() {
+        this.loading = true
+        getExperimental({ id: this.params.recordId })
+          .then((res) => {
+            this.loading = false
+            const data = res.data
+            if (!data) {
+              return
+            }
+            data.shiYanCanShu = data.shiYanCanShu
+              ? JSON.parse(data.shiYanCanShu)
+              : {}
+            data.shiYanShuJu = data.shiYanShuJu
+              ? JSON.parse(data.shiYanShuJu)
+              : []
+            data.jiSuanJieGuo = data.jiSuanJieGuo
+              ? JSON.parse(data.jiSuanJieGuo)
+              : {}
+            this.form = Object.assign(this.form, data)
+            this.loadCompleted = true
+            console.log(this.form)
+          })
+          .catch(() => {
+            this.loading = false
+          })
+      },
+      getConfigData({ targetId, methodId }) {
+        getConfigDetail({ id: targetId }).then((res) => {
+          const {
+            target,
+            targetKey,
+            experimentalConfigDetailPoList: methods
+          } = res.data || {}
+          const method = methods.find((i) => i.id === methodId) || {}
+          this.configData = {
+            target,
+            targetKey,
+            ...method,
+            params: this.$utils.isNotEmpty(method.params)
+              ? JSON.parse(method.params)
+              : [],
+            formulas: this.$utils.isNotEmpty(method.formulas)
+              ? JSON.parse(method.formulas)
+              : []
+          }
+          console.log(this.configData)
+        })
+      },
+      handleActionEvent(key) {
+        switch (key) {
+          case 'save':
+            this.handleSaveDraft(this.form);
+            break;
+          case 'submit':
+            this.handleStartFlow(this.form);
+            /*
+            if (this.getSubmitLabel() === '同意') {
+              this.handleAgree({ taskId: this.params.taskId, data: this.form });
+            } else {
+              this.handleStartFlow(this.form);
+            }*/
+            break;
+            /*
+          case 'sendBack':
+            this.handleReject({ taskId: this.params.taskId, data: this.form });
+            break;*/
+          case 'generate':
+            this.handleGenerate();
+            break;
+          case 'cancel':
+            this.handleCancel();
+            break;
+          case 'test':
+            this.handleTest();
+            break;
+          case 'pdf':
+            this.dialogFormVisible = true;
+            break;
+          case 'flowChart':
+            this.flowDiagramVisible = true;
+            break;
+          default:
+            break;
+        }
+      },
+      validateFormData() {
+        return new Promise((resolve, reject) => {
+          this.$refs.form.validate((valid) => {
+            if (!valid) {
+              this.$message.warning('请完善表单必填项后再进行操作!');
+              reject('Validation failed');
+            } else {
+              const { shiYanXiangMu } = this.form;
+              const regex = /[\/\\]/g;
+              if (regex.test(shiYanXiangMu)) {
+                this.form.shiYanXiangMu = shiYanXiangMu.replace(regex, '_');
+                this.$message.warning('【实验项目】中的【\\】与【/】已被转化为【_】');
+              }
+              resolve();
+            }
+          });
+        });
+      },
+      saveExperimentalData(idval,statusval) {
+        const {
+          kaiShiShiJian,
+          jieShuShiJian,
+          shiYanCanShu,
+          shiYanShuJu,
+          jiSuanJieGuo,
+          ...rest
+        } = this.form || {};
+        const submitData = {
+          ...rest,
+          kaiShiShiJian,
+          jieShuShiJian,
+          shiFouGuoShen: statusval,
+          id: idval || this.formId,
+          shiYanCanShu: this.$utils.isNotEmpty(shiYanCanShu)
+            ? JSON.stringify(shiYanCanShu)
+            : null,
+          shiYanShuJu: this.$utils.isNotEmpty(shiYanShuJu)
+            ? JSON.stringify(shiYanShuJu)
+            : null,
+          jiSuanJieGuo: this.$utils.isNotEmpty(jiSuanJieGuo)
+            ? JSON.stringify(jiSuanJieGuo)
+            : null,
+          xingNengZhiBia: this.configData.target,
+          fangAnLeiXing: this.configData.methodName,
+          zhiBiaoId: this.params.targetId,
+          fangFaKey: this.params.methodKey,
+          fangFaId: this.params.methodId,
+          //id: this.formId
+        };
+        return saveExperimental(submitData).then((res) => {
+          this.formId = res.data;
+          //this.$message.success('保存成功');
+        }).catch(() => {
+          //this.$message.error('保存失败');
+        });
+      },
+      async handleSaveDraft(data) {
+        data.pk = data.id;
+        const instid = await this.fetchInstanceId(data.id);
+        saveDraft({ 
+              defId: '1430598730687447040',
+              version: '0',
+              data: JSON.stringify(data),
+              proInstId: instid || ''
+            }).then((res) => {
+          this.$message.success('保存成功');
+          const id = res.variables.bizKey || '';
+          this.saveExperimentalData(id,'已暂存')
+        }).catch(() => {
+          this.$message.error('保存失败');
+        });
+      },
+      handleStartFlow(data) {
+        this.validateFormData()
+          .then(async () => {
+            const instid = await this.fetchInstanceId(data.id);
+            return startFlow({
+              defId: '1430598730687447040',
+              version: '0',
+              data: JSON.stringify(data),
+              proInstId: instid || ''
+            });
+          })
+          .then((res) => {
+            this.$message.success('提交成功');
+            this.visible = false;
+            const id = res.variables.bizKey || '';
+            return this.saveExperimentalData(id,'已编制')
+          })
+          .catch((error) => {
+              this.$message.error('启动失败');
+          });
+      },
+      /*
+      handleAgree(data) {
+        agree(data).then(() => {
+          this.$message.success('操作成功');
+            return this.saveExperimentalData(id,'已编制')
+          })
+          .catch((error) => {
+              this.$message.error('启动失败');
+          });
+      },
+      /*
+      handleAgree(data) {
+        agree(data).then(() => {
+          this.$message.success('操作成功');
+        }).catch(() => {
+          this.$message.error('操作失败');
+        });
+      },
+      handleReject(data) {
+        reject(data).then(() => {
+          this.$message.success('退回成功');
+        }).catch(() => {
+          this.$message.error('退回失败');
+        });
+      },*/
+      handleSave(key, callback) {
+        this.submitForm(key, callback)
+      },
+      handleSubmit(key, showMsg, callback) {
+        this.$refs.form.validate((valid) => {
+          if (!valid) {
+            return this.$message.warning('请完善表单必填项后再进行操作!')
+          }
+          // Excel sheet 不支持正反斜杆,需提前转化
+          const { shiYanXiangMu } = this.form
+          const regex = /[\/\\]/g
+  
+          if (regex.test(shiYanXiangMu)) {
+            this.form.shiYanXiangMu = shiYanXiangMu.replace(regex, '_')
+            this.$message.warning('【实验项目】中的【\\】与【/】已被转化为【_】')
+          }
+          this.submitForm(key, showMsg, callback)
+          // this.$confirm('确定要提交数据吗?', '提示', {
+          //     confirmButtonText: '确定',
+          //     cancelButtonText: '取消',
+          //     type: 'warning',
+          //     showClose: false,
+          //     closeOnClickModal: false,
+          //     closeOnPressEscape: false
+          // }).then(() => {
+          //     this.submitForm('submit', callback)
+          // })
+        })
+      },
+      handleGenerate() {
+        this.$message.info('waiting...')
+      },
+      judgeArrayData(data) {
+        if (!data || !data.length) {
+          return true
+        }
+        return (
+          data.length === data.filter((i) => this.$utils.isNotEmpty(i)).length
+        )
+      },
+      submitForm(key, showMsg, callback) {
+        const {
+          kaiShiShiJian,
+          jieShuShiJian,
+          shiYanCanShu,
+          shiYanShuJu,
+          jiSuanJieGuo,
+          ...rest
+        } = this.form || {}
+        const { rangeValue } = shiYanCanShu || {}
+        shiYanCanShu.range = rangeValue
+          ? [
+              100 - parseFloat(rangeValue) * 100,
+              100 + parseFloat(rangeValue) * 100
+            ]
+          : []
+        // 校验数组数据
+        for (let i = 0; i <= this.validateList.length; i++) {
+          const item = this.validateList[i]
+          if (this.judgeArrayData(shiYanCanShu[item])) {
+            continue
+          }
+          const t = this.configData.params.find((p) => p.key === item)
+          const msg = t
+            ? `${t.label}填写不完整,请补充后再提交`
+            : '性能验证实验参数部分信息填写不完整,请补充后再提交'
+          return this.$message.warning(msg)
+        }
+        if (new Date(kaiShiShiJian) > new Date(jieShuShiJian)) {
+          return this.$message.warning('实验开始时间不能大于实验结束时间!')
+        }
+        // 组装提交数据
+        const submitData = {
+          ...rest,
+          kaiShiShiJian,
+          jieShuShiJian,
+          shiYanCanShu: this.$utils.isNotEmpty(shiYanCanShu)
+            ? JSON.stringify(shiYanCanShu)
+            : null,
+          shiYanShuJu: this.$utils.isNotEmpty(shiYanShuJu)
+            ? shiYanShuJu instanceof Array
+              ? JSON.stringify(shiYanShuJu)
+              : shiYanShuJu
+            : null,
+          jiSuanJieGuo: this.$utils.isNotEmpty(jiSuanJieGuo)
+            ? JSON.stringify(jiSuanJieGuo)
+            : null,
+          xingNengZhiBia: this.configData.target,
+          fangAnLeiXing: this.configData.methodName,
+          zhiBiaoId: this.params.targetId,
+          fangFaKey: this.params.methodKey,
+          fangFaId: this.params.methodId,
+          id: this.formId
+        }
+        const isEdit = !!this.formId
+        // 提交数据
+        saveExperimental(submitData).then((res) => {
+          this.formId = res.data
+          if (showMsg) {
+            this.$message.success('保存成功')
+          }
+          if (callback) {
+            callback()
+          }
+          // 提交时且有实验数据时,重新计算
+          if (key === 'submit' && isEdit && this.$utils.isNotEmpty(shiYanShuJu)) {
+            recalculate({ id: this.formId }).then((res) => {
+              this.form.jiSuanJieGuo = res.data
+              this.form.shiYanJieLun = res.data.reportResult
+            })
+          }
+        })
+      },
+      handleCancel() {
+        this.closeDialog()
+      },
+      closeDialog() {
+        this.$emit('update:visible', false); // 通知父组件更新 visible
+        this.$emit('refresh');
+      },
+      handleUpdateParams(value) {
+        this.form.shiYanCanShu = value
+      },
+      handleUpdateData(value) {
+        this.form = {
+          ...this.form,
+          ...value
+        }
+      },
+      handleExport() {
+        this.handleSubmit('beforeExport', false, () => {
+          exportTemplate({ id: this.formId }).then((res) => {
+            ActionUtils.download(
+              res.data,
+              `${this.configData.methodName}-${this.form.shiYanXiangMu}.xlsx`
+            )
+          })
+        })
+      },
+      handleImport() {
+        this.handleSubmit('beforeImport', false, () => {
+          this.importData()
+        })
+      },
+      importData() {
+        const input = document.createElement('input')
+        input.type = 'file'
+        input.accept = '.xlsx'
+        input.onchange = (event) => {
+          const file = event.target.files[0]
+          const reader = new FileReader()
+          reader.onload = (event) => {
+            const data = new FormData()
+            data.append('id', this.formId)
+            data.append('applyFiles', file)
+            importTemplate(data)
+              .then((res) => {
+                this.$message.success('实验数据导入成功')
+                this.form.jiSuanJieGuo = res.data
+                this.form.shiYanJieLun = res.data.reportResult
+                this.form.shiYanShuJu = res.data.shiYanShuJu
+              })
+              .catch(({ state, cause }) => {
+                const errMsg = JSON.parse(cause)
+                let msgContent = ''
+                Object.keys(errMsg).forEach((key) => {
+                  let msgItem = '<div >'
+                  errMsg[key].forEach((item) => {
+                    msgItem += `<div>${item}</div>`
+                  })
+                  msgContent += `<div><div style="font-weight: bold;">${key}:</div>${msgItem}<div>`
+                })
+                this.$confirm(
+                  `<div style="font-size: 14px;">${msgContent}</div>`,
+                  '数据校验失败,请根据以下提示完善您的数据!',
+                  {
+                    confirmButtonText: '确认',
+                    showClose: false,
+                    showCancelButton: false,
+                    closeOnClickModal: false,
+                    dangerouslyUseHTMLString: true,
+                    customClass: 'errorTips',
+                    type: 'error'
+                  }
+                )
+                  .then(() => {})
+                  .catch(() => {})
+              })
+          }
+          reader.readAsBinaryString(file)
+        }
+        input.click()
+      },
+      handleRecalculate() {
+        this.submitForm('save', () => {
+          recalculate({ id: this.formId }).then((res) => {
+            this.$message.success('重新计算成功')
+            this.form.jiSuanJieGuo = res.data
+            this.form.shiYanJieLun = res.data.reportResult
+            this.form.shiYanShuJu = res.data.shiYanShuJu
+          })
+        })
+      },
+      handleTest() {
+        const o = {
+          xingNengZhiBia: '精密度',
+          fangAnLeiXing: 'EP15-A3精密度评价',
+          bianZhiBuMen: '1166703356459089920',
+          shiYanXiangMu: '测试项目',
+          shiYanFangFa: '测试方法',
+          yangBenLeiXing: '测试样本类型',
+          shiYanYiQi: '测试实验仪器',
+          yiQiBianHao: 'jyk-test-001',
+          kaiShiShiJian: '2024-05-01 09:00',
+          jieShuShiJian: '2024-05-05 17:00',
+          bianZhiRen: '1166772479054577664',
+          createBy: '1166771426615623680',
+          jieGuoDanWei: 'mmol/L',
+          baoLiuXiaoShu: 3,
+          beiZhu: '测试数据',
+          reagentPoList: [
+            {
+              changJia: 'BIO-RIO',
+              leiBie: '质控品',
+              piHao: 'test001',
+              shiJiMingCheng: '生化质控品',
+              youXiaoQi: '2025-05-01'
+            },
+            {
+              changJia: 'BIO-RIO',
+              leiBie: '校准品',
+              piHao: 'test002',
+              shiJiMingCheng: '生化校准品',
+              youXiaoQi: '2025-06-01'
+            },
+            {
+              changJia: 'BIO-RIO',
+              leiBie: '标准物',
+              piHao: 'test001',
+              shiJiMingCheng: '标准物',
+              youXiaoQi: '2025-05-01'
+            }
+          ],
+          shenHeRen: '1166673437578493952',
+          baoGaoShiJian: '2024-05-06',
+          fuJian: '1239940596743798784'
+        }
+        const t = JSON.parse(JSON.stringify(o))
+        this.form = {
+          ...this.form,
+          ...t,
+          shiYanCanShu: this.form.shiYanCanShu
+        }
+      },
+      // 控制工具栏按钮显示
+      showToolBarsBtn(key) {
+        // 在查阅状态时,只显示流程图、导出PDF和关闭按钮
+        if (this.readonly) {
+          // 允许显示的按钮:flowChart(流程图)、pdf(导出PDF)、cancel(关闭)
+          return !['flowChart', 'pdf', 'cancel'].includes(key)
+        }
+        
+        // 非查阅状态,根据shiFouGuoShen状态字段控制按钮显示
+        const status = (this.form && this.form.shiFouGuoShen) || '已暂存'
+        
+        // 已暂存状态显示流程图,导出pdf,关闭,保存,提交按钮
+        if (status === '已暂存' || status === '已退回') {
+          return !['flowChart', 'pdf', 'cancel', 'save', 'submit'].includes(key)
+        }
+        
+        // 已编制状态显示流程图,导出pdf,关闭,保存,退回,提交按钮
+        if (status === '已编制') {
+          return !['flowChart', 'pdf', 'cancel', 'save', 'sendBack', 'submit'].includes(key)
+        }
+        
+        // 已审核状态显示流程图,导出pdf,关闭,保存,退回,提交按钮
+        if (status === '已审核') {
+          return !['flowChart', 'pdf', 'cancel', 'save', 'sendBack', 'submit'].includes(key)
+        }
+        
+        // 已完成,已终止状态和查阅时显示一致
+        if (status === '已完成' || status === '已终止') {
+          return !['flowChart', 'pdf', 'cancel'].includes(key)
+        }
+        
+        // 默认显示流程图,导出pdf,关闭,保存,提交按钮
+        return !['flowChart', 'pdf', 'cancel', 'save', 'submit'].includes(key)
+      },
+      // 获取提交按钮的标签
+      getSubmitLabel() {
+        const status = (this.form && this.form.shiFouGuoShen) || '已暂存'
+        // 已编制和已审核状态下,提交按钮显示为"同意"
+        if (status === '已编制' || status === '已审核') {
+          return '同意'
+        }
+        // 其他状态下显示为"提交"
+        return '提交'
+      }
+    }
+  }
+  </script>
+  <style lang="scss" scoped>
+  .experimental-dialog {
+    ::v-deep {
+      .el-dialog__header {
+        padding: 15px 20px 16px;
+      }
+    }
+  
+    #pdfDom {
+      padding: 60px 100px;
+      box-sizing: border-box;
+  
+      .info-container {
+        margin-bottom: 20px !important;
+      }
+  
+      ::v-deep {
+        .info-item {
+          .title {
+            height: 20px;
+            line-height: 20px;
+            font-size: 16px;
+            font-weight: bold;
+            margin-bottom: 10px;
+  
+            .ibps-icon-star {
+              color: #fb9600;
+              margin-right: 5px;
+            }
+          }
+  
+          .el-form-item {
+            margin-bottom: 0 !important;
+  
+            &__label {
+              font-size: 14px !important;
+              color: #606266;
+            }
+  
+            &__content {
+              .el-input,
+              .el-select,
+              .el-input-number {
+                width: 100%;
+              }
+  
+              .el-textarea .el-input__count {
+                padding: 0 5px;
+                line-height: initial;
+              }
+  
+              .el-radio,
+              .el-checkbox {
+                margin-right: 10px;
+              }
+            }
+          }
+  
+          .el-table th.el-table__cell > .cell,
+          .el-table td.el-table__cell {
+            color: #606266;
+            font-size: 14px !important;
+          }
+  
+          .el-button--mini {
+            padding: 5px 12px;
+          }
+        }
+      }
+    }
+    .config-dialog-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      .title {
+        line-height: 24px;
+        font-size: 18px;
+        color: #303133;
+      }
+    }
+    .config-form {
+      &-container {
+        position: relative;
+        width: 100%;
+        height: calc(100vh - 60px);
+        overflow: auto;
+        display: flex;
+        .left,
+        .right {
+          width: 50%;
+          // min-height: 100%;
+          height: 100%;
+          overflow-y: auto;
+          padding: 15px 20px;
+          box-sizing: border-box;
+          .info-container {
+            margin-bottom: 20px;
+            &:last-child {
+              margin-bottom: 0;
+            }
+          }
+          ::v-deep {
+            .info-item {
+              .title {
+                height: 20px;
+                line-height: 20px;
+                font-size: 16px;
+                font-weight: bold;
+                margin-bottom: 10px;
+                .ibps-icon-star {
+                  color: #fb9600;
+                  margin-right: 5px;
+                }
+              }
+              .el-form-item {
+                margin-bottom: 0 !important;
+                &__label {
+                  font-size: 14px !important;
+                  color: #606266;
+                }
+                &__content {
+                  .el-input,
+                  .el-select,
+                  .el-input-number {
+                    width: 100%;
+                  }
+                  .el-textarea .el-input__count {
+                    padding: 0 5px;
+                    line-height: initial;
+                  }
+                  .el-radio,
+                  .el-checkbox {
+                    margin-right: 10px;
+                  }
+                }
+              }
+              .el-table th.el-table__cell > .cell,
+              .el-table td.el-table__cell {
+                color: #606266;
+                font-size: 14px !important;
+              }
+              .el-button--mini {
+                padding: 5px 12px;
+              }
+            }
+          }
+        }
+        .left {
+          &::before {
+            content: '';
+            width: 0;
+            height: 100%;
+            border-left: 1px dashed #dcdfe6;
+            position: absolute;
+            top: 0;
+            left: 50%;
+          }
+        }
+      }
+    }
+  }
+  </style>

+ 2 - 2
src/views/business/performance/index.vue

@@ -39,7 +39,7 @@
       @close="() => (showConfig = false)"
       @callback="loadData"
     />
-    <experimental
+    <ExperimentalView
       v-if="showExperimental"
       :visible.sync="showExperimental"
       :params="params"
@@ -53,7 +53,7 @@ import { getConfigList } from '@/api/business/pv'
 export default {
   components: {
     Config: () => import('./config'),
-    Experimental: () => import('./experimental')
+    ExperimentalView: () => import('./experimentalView')
   },
   data() {
     return {

+ 8 - 5
src/views/business/performance/myRecord.vue

@@ -21,6 +21,7 @@
           <div>起:{{ scope.row.kaiShiShiJian }}</div>
           <div>止:{{ scope.row.jieShuShiJian }}</div>
         </template>
+        <!--
         <template slot="xingNengZhiBiaSearch">
           <ibps-link-data
             v-model="searchFormData['Q^xing_neng_zhi_bia^SL']"
@@ -29,8 +30,9 @@
             style="width: 100%"
           />
         </template>
+        -->
       </ibps-crud>
-      <Experimental
+      <ExperimentalView
         v-if="showConfig"
         :visible.sync="showConfig"
         :params="params"
@@ -49,7 +51,7 @@
   
   export default {
     components: {
-      Experimental: () => import('./experimental'),
+      ExperimentalView: () => import('./experimentalView'),
       'ibps-link-data': IbpsLinkData
     },
     mixins: [FixHeight],
@@ -80,7 +82,8 @@
             model: this.searchFormData, // 新增:绑定数据模型
             forms: [
               { prop: 'Q^shi_yan_xiang_mu_^SL', label: '实验项目' },
-              { prop: 'Q^xing_neng_zhi_bia^SL', label: '性能指标', fieldType: 'slot', slotName: 'xingNengZhiBiaSearch' },
+              //{ prop: 'Q^xing_neng_zhi_bia^SL', label: '性能指标', fieldType: 'slot', slotName: 'xingNengZhiBiaSearch' },
+              { prop: 'Q^xing_neng_zhi_bia^SL', label: '性能指标' },
               { prop: 'Q^fang_an_lei_xing_^SL', label: '方案类型' },
               { prop: 'Q^shi_yan_fang_fa_^SL', label: '实验方法' },
               { prop: 'Q^yang_ben_lei_xing^SL', label: '样本类型' },
@@ -149,7 +152,7 @@
                 label: '编辑',
                 type: 'primary',
                 icon: 'ibps-icon-edit',
-                //hidden: (row) => row.shiFouGuoShen !== '已暂存'
+                hidden: (row) => row.shiFouGuoShen !== '已暂存'
               },
               {
                 key: 'detail',
@@ -248,7 +251,7 @@
           shiFouGuoShen: shiFouGuoShen
         }
         this.readonly = key === 'detail'
-        this.showConfig = true
+        this.showConfig = true // Ensure only experimentalView is opened
       },
       handleReport(data) {
         console.log('wwww')

+ 4 - 0
src/views/component/personnelFile/index.vue

@@ -203,6 +203,7 @@ export default {
       // const sql1 = `select a.CREATE_BY_ from ibps_bpm_inst a join ibps_bpm_task_pendding b on b.proc_inst_id_=a.id_ where b.PROC_DEF_KEY_ = '${processKey}' and b.task_id_ ='${taskId}'`
       // // const sql1 = `select CREATE_BY_ FROM ibps_bpm_oper_log WHERE PROC_INST_ID_ = (SELECT PROC_INST_ID_ FROM ibps_bpm_bus_rel WHERE BUSINESSKEY_ = "${this.$attrs.params.attrs.id}" LIMIT 1 )AND OPER_TYPE_ IN('start')`
       // const sql2 = `select CREATE_BY_ FROM ibps_bpm_oper_log WHERE PROC_INST_ID_ = '${instanceId}' AND OPER_TYPE_ IN('start') ORDER BY CREATE_TIME_ asc limit 1`
+      debugger
       this.$common.request('query', { key, params }).then((r) => {
         const datas =
           r.variables.data.length > 0 ? r.variables.data[0].CREATE_BY_ : ''
@@ -219,6 +220,7 @@ export default {
   },
   methods: {
     init(val) {
+      debugger
       getInfo({ id: val }).then((res) => {
         this.personInfoData = res.data
         this.stauts =
@@ -348,6 +350,7 @@ export default {
                 callback: (action) => {
                   this.$children[0].buttonShow = true
                   this.infoNumArr = []
+                  debugger
                   this.saveData(this.personInfoData, 'Refresh')
                 }
               })
@@ -446,6 +449,7 @@ export default {
     },
     saveData(val, r) {
       setInfo(val).then((res) => {
+        debugger
         this.showTF(false)
         if (r === 'Refresh') {
           location.reload()