董国庆
2025-05-23 4d4e8cd36377fa24cdda7a560dfc42fd2c9334b4
实验结果汇报
1个文件已删除
8个文件已修改
2个文件已添加
2445 ■■■■ 已修改文件
laboratory/src/components/EvaluateTable/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/components/SelectMember/index.vue 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/sampleSubmissionList/submission.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/schemeManagement/list.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/testResultReport/components/checkout-result.vue 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/testResultReport/components/evaluation-dialog.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/testResultReport/components/experimentResultDialog.vue 793 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/testResultReport/components/experimental-scheduling.vue 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/testResultReport/detail.vue 1005 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/testResultReport/list.vue 411 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/testResultReport/service.js 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/components/EvaluateTable/index.vue
@@ -151,7 +151,7 @@
        },
        viewJson: {
            handler(newVal, oldVal) {
                if (newVal && this.isReadonly) {
                if (newVal) {
                    try {
                        const parsedData = JSON.parse(newVal)
                        this.activeIndex = parsedData
@@ -205,7 +205,17 @@
        },
        sort(num, index) {
            return (index + 1) * 3 - num
        },
        resetData() {
            this.total = null
            this.activeIndex = this.activeIndex.map(() => ({
                num: null,
                score: 0
            }))
        }
    },
    beforeDestroy() {
        this.resetData()
    }
}
</script>
laboratory/src/components/SelectMember/index.vue
@@ -82,12 +82,14 @@
        setSelection(selected) {
            this.selectData = selected
            this.$nextTick(() => {
                // 设置新选中
                this.tableData.forEach(row => {
                    if (selected.some(i => i.userId === row.userId)) {
                        this.$refs.memberTable.toggleRowSelection(row, true)
                    }
                })
                // 确保 tableData 和 memberTable 都存在
                if (this.tableData && this.$refs.memberTable) {
                    this.tableData.forEach(row => {
                        if (selected.some(i => i.userId === row.userId)) {
                            this.$refs.memberTable.toggleRowSelection(row, true)
                        }
                    })
                }
            })
        },
        openDialog() {
@@ -108,7 +110,7 @@
        async searchUserList(roleId) {
            this.roleId = roleId
            // 根据是否有项目组ID来决定调用不同的接口
            const params = {
            let params = {
                roleIds: roleId ? [roleId] : [],
                nickNameOrPhone: this.searchName,
                pageSize: 9999,
@@ -116,10 +118,15 @@
            };
            
            if (this.projectId) {
                params.projectId = this.projectId;
                params={
                    ...params,
                    roleId: roleId?roleId:'',
                    projectId: this.projectId
                }
                delete params.roleIds;
                // TODO: 这里需要替换为新的接口调用
                const res = await listByRole(params);
                this.tableData = res.records;
                this.tableData = res;
            } else {
                const res = await getUserList(params);
                this.tableData = res.records;
laboratory/src/views/dataManagement/sampleSubmissionList/submission.vue
@@ -187,7 +187,7 @@
    },
    async confirmSend(signature) {
      try {
        const recordOperationIds = this.selectedSamples.map(item => item.id).join(',');
        const recordOperationIds = this.selectedSamples.map(item => item.id);
        const res = await batchSendSamples({ 
          recordOperationId: recordOperationIds,
          sendSign: signature
laboratory/src/views/dataManagement/schemeManagement/list.vue
@@ -1,6 +1,6 @@
<template>
  <div class="list">
    <TableCustom :queryForm="form" :tableData="tableData" :total="total" @handlePageChange="handlePageChange" @handleSizeChange="handleSizeChange">
    <TableCustom :queryForm="form" :tableData="tableData" :height="null" :total="total" @handlePageChange="handlePageChange" @handleSizeChange="handleSizeChange">
      <template #search>
        <el-form :model="form" labelWidth="auto" inline>
          <el-form-item label="项目课题方案名称:">
@@ -96,7 +96,8 @@
            <!-- 实验员(5) -->
            <template v-if="userRole == '5'">
              <el-button type="text" @click="handleEdit(scope.row)" v-if="scope.row.status == 1">编辑</el-button>
              <el-button type="text" @click="handleEdit(scope.row)" v-if="scope.row.status == 1 ">编辑</el-button>
              <el-button type="text" @click="handleDetail(scope.row)" v-if="scope.row.status == 6">详情</el-button>
            </template>
          </template>
        </el-table-column>
laboratory/src/views/dataManagement/testResultReport/components/checkout-result.vue
@@ -1,7 +1,7 @@
<template>
    <el-dialog
      title="检验数据结果汇总"
      :visible.sync="visible"
      :visible="dialogVisible"
      width="80%"
      :close-on-click-modal="false"
      @close="handleClose"
@@ -16,12 +16,31 @@
                  <span>本次检验结果总表</span>
                </div>
              </div>
              <div class="content-box">
                <AiEditor
                  ref="descriptionEditor"
                  :readOnly="true"
                  :value="data?.testReason || ''"
                  height="200px"
                  placeholder="暂无检验说明..."
                />
              </div>
              
              <div class="header-title">
                <div class="header-title-left">
                  <img src="@/assets/public/headercard.png" />
                  <span>本次检验说明</span>
                </div>
              </div>
              <div class="content-box">
                <AiEditor
                  ref="descriptionEditor"
                  :readOnly="true"
                  :value="data?.testReason || ''"
                  height="200px"
                  placeholder="暂无检验说明..."
                />
              </div>
            </template>
          </Card>
@@ -31,21 +50,39 @@
  </template>
  
  <script>
  import AiEditor from "@/components/AiEditor";
  export default {
    name: "CheckoutResult",
    components: {
      AiEditor
    },
    props: {
      visible: {
        type: Boolean,
        default: false,
      },
      content: {
      data: {
        type: Object,
        default: () => ({}),
      },
    },
    data() {
      return {
        dialogVisible: false
      }
    },
    watch: {
      visible: {
        handler(val) {
          this.dialogVisible = val;
        },
        immediate: true
      }
    },
    methods: {
      handleClose() {
        this.$emit("update:visible", false);
        this.$emit("close");
      },
    },
  };
@@ -58,7 +95,7 @@
  
  .approval-dialog {
    display: flex;
    height: 300px;
    height: 600px;
  
    .approval-content {
      flex: 1;
@@ -77,12 +114,12 @@
    align-items: center;
    flex-wrap: wrap;
    gap: 13px;
    margin-top: 38px;
  
    .header-title-left {
      display: flex;
      align-items: center;
      gap: 13px;
      margin-top: 38px;
  
      img {
        width: 12px;
@@ -101,8 +138,18 @@
  }
  
  .header-title:first-child {
    margin-top: 0;
    .header-title-left {
      margin-top: 0;
    }
  }
  .rwuTable {
    width: 100%;
    margin: 20px 0;
  }
  .content-box {
    margin: 20px 0;
  }
  </style>
laboratory/src/views/dataManagement/testResultReport/components/evaluation-dialog.vue
@@ -5,7 +5,7 @@
    width="79.17%"
    @close="handleClose"
  >
    <EvaluateTable ref="evaluateTable" />
    <EvaluateTable ref="evaluateTable" :viewJson="viewJson" />
    <div slot="footer" class="dialog-footer">
      <el-button type="primary" @click="handleSubmit" class="submit-btn">确认评定结果</el-button>
    </div>
@@ -26,6 +26,10 @@
      type: String,
      default: 'labTechnician'
    },
    viewJson: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
@@ -34,7 +38,7 @@
  },
  computed: {
    dialogTitle() {
      return this.type === 'labTechnician' ? '化验师工作评定' : '实验员工作评定';
      return this.type === 'labTechnician' ? '化验师工作评定' : this.type === 'experimenter' ? '实验员工作评定' : '工艺工程师工作评定';
    }
  },
  watch: {
laboratory/src/views/dataManagement/testResultReport/components/experimentResultDialog.vue
New file
@@ -0,0 +1,793 @@
<template>
  <div>
    <el-dialog title="实验方案详情" :visible="dialogVisible" width="80%" :close-on-click-modal="false" @close="handleClose">
      <div class="approval-dialog">
        <!-- 左侧审批内容 -->
        <div class="approval-content">
          <Card class="approval-content-card">
            <template style="position: relative">
              <el-form ref="form" :model="form" :rules="rules" inline label-position="top">
                <div>
                  <div class="header-title" style="margin-bottom: 18px">
                    <div class="header-title-left">
                      <img src="@/assets/public/headercard.png" />
                      <div>所属项目课题方案</div>
                    </div>
                  </div>
                  <div class="content-box">
                    <div class="content-box-left">
                      <div>项目课题方案名称:{{ dispatchData && dispatchData.length > 0 ? dispatchData[0].projectName : ''
                      }}</div>
                      <div>实验编号:{{ dispatchData && dispatchData.length > 0 ? dispatchData[0].experimentCode : ''
                      }}</div>
                    </div>
                    <div class="content-box-right">
                      <div>项目课题方案编号: {{ dispatchData && dispatchData.length > 0 ? dispatchData[0].projectCode : ''
                      }}</div>
                      <div>实验名称: {{ dispatchData && dispatchData.length > 0 ? dispatchData[0].experimentName : ''
                      }}</div>
                    </div>
                  </div>
                </div>
                <div class="add-group">
                  <span>实验人员</span>
                </div>
                <div class="member-list">
                  <div class="member-list-card">
                    <div class="member-item">
                      <div class="member-title">实验员</div>
                      <div class="flex">
                        <div class="member-name-box-2">
                          <div v-for="i in selectedParticipants" :key="i.id" class="member-name">
                            {{ i.nickName }}
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
                <template v-if="groupData && groupData.length > 0">
                  <div class="add-group">
                    <span>组别列表</span>
                  </div>
                  <Table :data="groupData" :total="0" :height="null" class="groupTable">
                    <el-table-column type="index" label="序号" width="80"></el-table-column>
                    <el-table-column prop="groupName" label="组别"></el-table-column>
                    <el-table-column prop="remark" label="备注"></el-table-column>
                  </Table>
                </template>
                <div class="header-title" style="margin-bottom: 38px">
                  <div class="header-title-left">
                    <img src="@/assets/public/headercard.png" />
                    <div>一、实验目的</div>
                  </div>
                </div>
                <div class="content-box">
                  <AiEditor ref="purposeEditor" :readOnly="true" :value="form.experimentObjective" height="200px"
                    placeholder="请输入实验目的..." />
                </div>
                <div class="header-title" style="margin-bottom: 38px">
                  <div class="header-title-left">
                    <img src="@/assets/public/headercard.png" />
                    <div>二、工艺参数及路线</div>
                  </div>
                </div>
                <div class="content-box">
                  <AiEditor ref="processEditor" :readOnly="true" :value="form.experimentParamRoute" height="200px"
                    placeholder="请输入工艺参数及路线..." />
                </div>
                <div class="header-title" style="margin-bottom: 38px">
                  <div class="header-title-left">
                    <img src="@/assets/public/headercard.png" />
                    <div>三、实验材料及设备</div>
                  </div>
                </div>
                <DynamicComponent ref="materialComponent" title="实验材料" :dialogCanEdit="false"
                  :dataSource="form.experimentMaterial" :editable="false" />
                <DynamicComponent ref="equipmentComponent" title="实验所用设备" :dialogCanEdit="false"
                  :dataSource="form.experimentDevice" :editable="false" />
                <div class="header-title" style="margin-bottom: 38px">
                  <div class="header-title-left">
                    <img src="@/assets/public/headercard.png" />
                    <div>四、实验操作步骤记录</div>
                  </div>
                </div>
                <div class="step-list" v-for="(item, idx) in stepList" :key="idx">
                  <div class="step-list-item">
                    <div class="step-list-item-title">
                      步骤{{ idx + 1 }}:{{ item.stepName }}
                    </div>
                  </div>
                  <DynamicComponent :dialogCanEdit="false" :ref="'stepContent' + idx" :dataSource="item.content"
                    :editable="false" />
                </div>
              </el-form>
            </template>
          </Card>
        </div>
      </div>
    </el-dialog>
    <SignatureCanvas :visible="signatureDialogVisible" @confirm="handleSignatureConfirm" />
  </div>
</template>
<script>
import ApprovalProcess from "@/components/approvalProcess";
import SignatureCanvas from "@/components/SignatureCanvas.vue";
import DynamicComponent from "@/components/DynamicComponent";
import AiEditor from "@/components/AiEditor";
import { getExperimentDetail, getGroupByDispatchId } from "../service";
export default {
  name: "ApprovalDialog",
  components: {
    ApprovalProcess,
    SignatureCanvas,
    DynamicComponent,
    AiEditor,
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    type: {
      type: String,
      default: "approve", // approve-审批,view-查看
    },
    data: {
      type: Object,
      default: () => ({}),
    },
  },
  data() {
    return {
      dialogVisible: false,
      form: {
        projectName: "", // 项目课题方案名称
        projectCode: "", // 项目课题方案编号
        experimentCode: "", // 实验编号
        experimentName: "", // 实验名称
        experimentDate: "", // 实验日期
        experimentMaterial: [], // 实验材料
        experimentDevice: [], // 实验设备
        experimentObjective: "", // 实验目的
        experimentParamRoute: "", // 工艺参数及路线
        createBy: "", // 创建人
        createTime: "", // 创建时间
        status: "", // 状态
        approver: "", // 审批人
        approveTime: "", // 审批时间
      },
      rules: {
        testTime: [
          { required: true, message: "请选择试验时间", trigger: "change" },
        ],
      },
      imgSrc: "",
      signatureDialogVisible: false,
      remark: "",
      groupData: [],
      dispatchData: [], // 实验调度数据
      stepList: [],
      selectedParticipants: [], // 实验参与人员
      showApprovalFlow: false,
      approvalProcessData: [],
    };
  },
  watch: {
    visible: {
      handler(val) {
        this.dialogVisible = val;
        if (val && this.data && this.data.id) {
          // 弹窗打开时,确保数据已获取
          this.getPlanDetail(this.data.id);
        }
      },
      immediate: true,
    },
    data: {
      handler(val) {
        if (val && val.id) {
          // 当接收到数据且有ID时,调用获取详情接口
          this.getPlanDetail(val.id);
        }
      },
      immediate: true,
      deep: true,
    },
  },
  methods: {
    handleStopExperiment() {
      this.$router.push("/dataManagement/scheme-management/stop-experiment?id=" + this.data.id);
    },
    getStatusType(status) {
      const statusMap = {
        "-1": "info",
        "1": "warning",
        "2": "success",
        "3": "info"
      };
      return statusMap[status] || "info";
    },
    getStatusText(status) {
      const statusMap = {
        "-1": "草稿箱",
        "1": "待确认",
        "2": "已确认",
        "3": "已封存"
      };
      return statusMap[status] || "未知";
    },
    handleClose() {
      this.$emit('update:visible', false);
    },
    handleApprove() {
      if (!this.form.approvalComment) {
        this.$message.warning("请输入审批意见");
        return;
      }
      this.$emit("approve", {
        ...this.form,
        status: "approved",
      });
    },
    handleReject() {
      if (!this.form.approvalComment) {
        this.$message.warning("请输入审批意见");
        return;
      }
      this.$emit("reject", {
        ...this.form,
        status: "rejected",
      });
    },
    openSignature() {
      this.signatureDialogVisible = true;
    },
    handleSignatureConfirm(imageData) {
      console.log("imageData imageData", imageData);
      this.signatureDialogVisible = false;
      this.imgSrc = imageData;
    },
    // 获取方案详情
    async getPlanDetail(id) {
      try {
        const res = await getExperimentDetail({ id });
        if (!res) {
          this.$message.error('获取方案详情失败');
          this.handleClose();
          return;
        }
        if (res.stopReason) {
          this.showApprovalFlow = true;
          //中止实验申请
          let processData = [];
          processData.push({
            type: "primary",
            mode: "list",
            fields: [
              { label: "提交人:", value: res.updateBy || "" },
              { label: "提交时间:", value: res.createTime || "" },
            ],
          });
          if (res.status == 4 || res.status == 3) {
            processData.push({
              type: 'primary',
              mode: "list",
              fields: [
                {
                  label: "审核结果:",
                  value:
                    res.status == 3
                      ? "通过"
                      : res.status == 4
                        ? "驳回"
                        : "待审批",
                },
                { label: "审批意见:", value: res.auditRemark || "" },
                { label: "审核人:", value: res.auditPersonName || "" },
                { label: "审核时间:", value: res.auditTime || "" },
              ],
            });
          } else {
            processData.push({
              type: "warning",
              mode: "list",
              fields: [
                { label: "等待审核" },
              ],
            });
          }
          this.approvalProcessData = processData;
        }
        // 填充基本表单数据
        this.form = {
          ...this.form,
          projectName: res.projectName,
          projectCode: res.projectCode,
          experimentCode: res.experimentCode,
          experimentName: res.experimentName,
          experimentDate: res.experimentDate,
          createBy: res.createBy,
          createTime: res.createTime,
          status: res.status,
          experimentObjective: res.experimentObjective || '',
          experimentParamRoute: res.experimentParamRoute || '',
        };
        // 构建实验调度数据
        if (res.experimentDispatch) {
          this.dispatchData = [res.experimentDispatch];
        }
        // 填充组别数据
        if (res.dispatchId) {
          try {
            const groupRes = await getGroupByDispatchId({ dispatchId: res.dispatchId });
            if (groupRes) {
              this.groupData = groupRes || [];
            }
          } catch (err) {
            console.error('获取组别列表失败:', err);
          }
        }
        // 填充实验材料和设备
        if (res.experimentMaterial) {
          try {
            const materialData = typeof res.experimentMaterial === 'string'
              ? JSON.parse(res.experimentMaterial)
              : res.experimentMaterial;
            this.form.experimentMaterial = materialData;
            // 为DynamicComponent设置初始数据
            // this.$nextTick(() => {
            //   if (this.$refs.materialComponent) {
            //     this.$refs.materialComponent.setInitialData(materialData);
            //   }
            // });
          } catch (err) {
            console.error('解析实验材料数据失败:', err);
          }
        }
        if (res.experimentDevice) {
          try {
            const deviceData = typeof res.experimentDevice === 'string'
              ? JSON.parse(res.experimentDevice)
              : res.experimentDevice;
            this.form.experimentDevice = deviceData;
            // 为DynamicComponent设置初始数据
            this.$nextTick(() => {
              // if (this.$refs.equipmentComponent) {
              //   this.$refs.equipmentComponent.setInitialData(deviceData);
              // }
            });
          } catch (err) {
            console.error('解析实验设备数据失败:', err);
          }
        }
        // 填充实验步骤
        if (res.experimentStepRecord) {
          try {
            const stepsData = typeof res.experimentStepRecord === 'string'
              ? JSON.parse(res.experimentStepRecord)
              : res.experimentStepRecord;
            this.stepList = (stepsData || []).map(step => ({
              stepName: step.stepName,
              content: step.content
            }));
            // 设置步骤内容的初始数据
            this.$nextTick(() => {
              // this.stepList.forEach((step, index) => {
              //   const stepContentRef = this.$refs['stepContent' + index];
              //   if (stepContentRef && step.content) {
              //     const editor = Array.isArray(stepContentRef) ? stepContentRef[0] : stepContentRef;
              //     if (editor && typeof editor.setInitialData === 'function') {
              //       editor.setInitialData(step.content);
              //     }
              //   }
              // });
            });
          } catch (err) {
            console.error('解析实验步骤数据失败:', err);
            this.stepList = [];
          }
        }
        // 设置实验人员
        if (res.experimentSchemePersons) {
          try {
            const participantsData = typeof res.experimentSchemePersons === 'string'
              ? JSON.parse(res.experimentSchemePersons)
              : res.experimentSchemePersons;
            this.selectedParticipants = participantsData || [];
          } catch (err) {
            console.error('解析实验人员数据失败:', err);
            this.selectedParticipants = [];
          }
        }
        // 更新编辑器内容
        this.$nextTick(() => {
          if (this.$refs.purposeEditor) {
            this.$refs.purposeEditor.setContent(this.form.experimentObjective);
          }
          if (this.$refs.processEditor) {
            this.$refs.processEditor.setContent(this.form.experimentParamRoute);
          }
        });
      } catch (error) {
        console.error("获取方案详情失败:", error);
        this.$message.error("获取方案详情失败");
        this.handleClose();
      }
    },
  },
};
</script>
<style scoped lang="less">
::v-deep .el-dialog__header {
  border-bottom: 1px solid #e4e7ed;
}
::v-deep .el-dialog__body {
  padding: 20px;
  max-height: 80vh;
  overflow: hidden;
}
@media screen and (max-width: 1200px) {
  ::v-deep .el-dialog__body {
    max-height: none;
    overflow: auto;
  }
}
.approval-dialog {
  display: flex;
  height: 60vh;
  padding: 20px;
  overflow: hidden;
  @media screen and (max-width: 1200px) {
    flex-direction: column;
    height: auto;
    .approval-content,
    .approval-flow {
      width: 100%;
      margin-right: 0;
      margin-bottom: 20px;
      height: 50vh;
    }
  }
  .approval-content {
    flex: 7;
    margin-right: 20px;
    background: #ffffff;
    box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08);
    border-radius: 10px;
    overflow-y: auto;
  }
  .approval-flow {
    flex: 3;
    min-width: 350px;
    padding: 40px 20px;
    background: #ffffff;
    box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08);
    border-radius: 10px;
    overflow-y: auto;
    .flow-title {
      font-size: 16px;
      font-weight: bold;
      margin-bottom: 20px;
      color: #303133;
    }
    .flow-content {
      height: calc(100% - 40px);
      overflow-y: auto;
      .el-form--inline .el-form-item {
        margin-right: 83px;
      }
    }
  }
}
.approval-dialog-approve {
  margin-top: 26px;
}
.approval-content-card {
  height: calc(100% - 100px) !important;
  box-shadow: none !important;
}
.header-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 13px;
  margin-top: 38px;
  .header-title-left {
    display: flex;
    align-items: center;
    gap: 13px;
    img {
      width: 12px;
      height: 19px;
    }
    div {
      flex-shrink: 0;
      font-weight: bold;
      font-size: 18px;
      color: #222222;
      line-height: 27px;
      font-family: "Source Han Sans CN Bold Bold";
      &:before {
        content: "*";
        color: #f56c6c;
        margin-right: 4px;
      }
    }
    span {
      flex-shrink: 0;
      font-weight: bold;
      font-size: 18px;
      color: #222222;
      line-height: 27px;
      font-family: "Source Han Sans CN Bold Bold";
    }
  }
  .header-title-left :first-child {
    margin-top: 0;
  }
}
.header-title:first-child {
  margin-top: 0 !important;
  .header-title-left {
    margin-top: 0;
  }
}
.item-title {
  padding-left: 25px;
  span {
    flex-shrink: 0;
    font-weight: bold;
    font-size: 14px;
    color: #222222;
    line-height: 27px;
    font-family: "Source Han Sans CN Bold Bold";
    margin: 18px 0;
    &:before {
      content: "*";
      color: #f56c6c;
      margin-right: 4px;
    }
  }
}
.approval-dialog-approve {
  img {
    border: 2px dashed #049c9a;
  }
}
.add-group {
  padding-left: 25px;
  margin-top: 14px;
  display: flex;
  align-items: center;
  margin-bottom: 19px;
  div {
    color: #f56c6c;
  }
  span {
    font-weight: 500;
    font-size: 14px;
    color: #222222;
    line-height: 21px;
    margin: 0 32px 0 8px;
  }
}
.groupTable {
  width: 85%;
  padding-left: 40px;
}
.rwuTable {
  width: 85%;
  padding-left: 40px;
}
.member-list {
  margin-top: 18px;
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  margin-left: 38px;
  .member-list-card {
    width: 340px;
    height: 400px;
    border-radius: 8px;
    border: 1px solid #dcdfe6;
    &:nth-child(1) {
      background: linear-gradient(to bottom,
          rgba(4, 156, 154, 0.2) 0%,
          rgba(5, 242, 194, 0) 70%);
    }
    &:nth-child(2) {
      background: linear-gradient(to bottom,
          rgba(5, 160, 193, 0.2) 0%,
          rgba(5, 242, 194, 0) 70%);
    }
    &:nth-child(3) {
      background: linear-gradient(to bottom,
          rgba(255, 77, 79, 0.2) 0%,
          rgba(255, 242, 194, 0) 70%);
    }
    &:nth-child(4) {
      background: linear-gradient(to bottom,
          rgba(250, 199, 20, 0.21) 0%,
          rgba(255, 242, 194, 0) 70%);
    }
    .member-item {
      height: 100%;
      display: flex;
      flex-direction: column;
      .member-title {
        margin-top: 20px;
        width: 100%;
        font-family: "Source Han Sans CN Bold Bold";
        font-weight: bold;
        font-size: 16px;
        color: rgba(0, 0, 0, 0.8);
        line-height: 16px;
        text-align: center;
      }
      .flex1 {
        flex: 1;
      }
      .member-name-box {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
      }
      .member-name-box-2 {
        flex: 1;
        padding: 0 20px;
        padding-top: 40px;
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 20px;
        justify-items: center;
        align-items: start;
      }
      .member-name {
        width: 60px;
        height: 60px;
        background: #7d8b79;
        border-radius: 50%;
        text-align: center;
        line-height: 60px;
        font-weight: 500;
        font-size: 16px;
        color: #ffffff;
        margin: 0;
      }
      .member-change {
        display: flex;
        justify-content: center;
        padding: 10px 0;
        margin-top: auto;
        cursor: pointer;
        .member-change-btn {
          background: #fff1f0;
          border-radius: 4px;
          border: 1px solid #ffccc7;
          padding: 1px 8px;
          font-weight: 400;
          font-size: 12px;
          color: #ff4d4f;
        }
      }
    }
  }
}
.step-list {
  background: #eff8fa;
  padding: 20px;
  .step-list-item {
    display: flex;
    justify-content: space-between;
    padding: 25px;
    background: #ffffff;
    .step-list-item-title {
      font-weight: 500;
      font-size: 14px;
      color: rgba(0, 0, 0, 0.8);
      line-height: 20px;
      flex-wrap: wrap;
      flex: 1;
    }
  }
}
.content-box {
  padding: 0 25px;
  margin-bottom: 20px;
  width: 65%;
  display: flex;
  .content-box-left {
    flex: 1;
    div {
      padding: 10px 0;
    }
  }
  .content-box-right {
    flex: 1;
    div {
      padding: 10px 0;
    }
  }
}
</style>
laboratory/src/views/dataManagement/testResultReport/components/experimental-scheduling.vue
File was deleted
laboratory/src/views/dataManagement/testResultReport/detail.vue
@@ -1,71 +1,29 @@
<template>
  <Card>
    <el-form
      ref="form"
      :model="form"
      :rules="rules"
      inline
      label-position="top"
    >
      <div class="header-title">
    <el-form ref="form" :model="form" :rules="rules" inline label-position="top">
      <div class="header-title" style="margin-bottom: 38px">
        <div class="header-title-left">
          <img src="@/assets/public/headercard.png" />
          <div>一 、所属实验调度</div>
          <div>所属实验调度</div>
        </div>
        <el-button
          type="primary"
          class="el-icon-plus"
          @click="handleSelectScheduling"
          >选择实验调度</el-button
        >
        <el-button type="primary" class="el-icon-plus" @click="handleAddTask" v-if="!isView">选择实验调度</el-button>
      </div>
      <Table
        :data="[selectedScheduling].filter(Boolean)"
        :total="0"
        :height="null"
        class="rwuTable"
      >
        <el-table-column
          prop="planName"
          label="所属项目课题方案"
          min-width="180"
        ></el-table-column>
        <el-table-column
          prop="planCode"
          label="实验编号"
          min-width="120"
        ></el-table-column>
        <el-table-column
          prop="experimentName"
          label="实验名称"
          min-width="120"
        ></el-table-column>
        <el-table-column
          prop="noticeTime"
          label="通知时间"
          min-width="150"
        ></el-table-column>
        <el-table-column
          prop="startTime"
          label="实验开始时间"
          min-width="150"
        ></el-table-column>
        <el-table-column
          prop="endTime"
          label="实验结束时间"
          min-width="150"
        ></el-table-column>
        <el-table-column
          prop="participants"
          label="参加人员"
          min-width="180"
        ></el-table-column>
        <el-table-column
          prop="status"
          label="状态"
          min-width="100"
        ></el-table-column>
      <Table :data="taskTableData" :total="0" :height="null" class="rwuTable">
        <el-table-column prop="projectName" label="所属项目课题方案" width="200"></el-table-column>
        <el-table-column prop="experimentCode" label="实验编号"></el-table-column>
        <el-table-column prop="experimentName" label="实验名称"></el-table-column>
        <el-table-column prop="experimentDate" label="通知时间"></el-table-column>
        <el-table-column prop="experimentStartTime" label="实验开始时间"></el-table-column>
        <el-table-column prop="experimentEndTime" label="实验结束时间"></el-table-column>
        <el-table-column prop="participantsName" label="参加人员"></el-table-column>
        <el-table-column prop="status" label="状态">
          <template slot-scope="scope">
            <el-tag :type="getStatusType(scope.row.status)">
              {{ getStatusText(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>
      </Table>
      <div class="header-title">
@@ -74,57 +32,24 @@
          <div>一 、实验结果</div>
        </div>
      </div>
      <Table
        :data="experimentResultData"
        :total="0"
        :height="null"
        class="rwuTable"
      >
        <el-table-column
          prop="planName"
          label="所属项目课题方案"
          min-width="180"
        ></el-table-column>
        <el-table-column
          prop="experimentCode"
          label="实验编号"
          min-width="120"
        ></el-table-column>
        <el-table-column
          prop="experimentName"
          label="实验名称"
          min-width="120"
        ></el-table-column>
        <el-table-column
          prop="experimentDate"
          label="实验日期"
          min-width="120"
        ></el-table-column>
        <el-table-column
          prop="experimenter"
          label="实验员"
          min-width="100"
        ></el-table-column>
        <el-table-column
          prop="createTime"
          label="创建日期"
          min-width="150"
        ></el-table-column>
        <el-table-column
          prop="creator"
          label="创建人"
          min-width="100"
        ></el-table-column>
        <el-table-column
          prop="status"
          label="当前状态"
          min-width="120"
        ></el-table-column>
      <Table :data="experimentResultData" :total="0" :height="null" class="rwuTable">
        <el-table-column prop="projectName" label="项目课题方案名称"></el-table-column>
        <el-table-column prop="experimentCode" label="实验编号"></el-table-column>
        <el-table-column prop="experimentName" label="实验名称"></el-table-column>
        <el-table-column prop="experimentDate" label="实验日期"></el-table-column>
        <el-table-column prop="schemePersonName" label="实验员"></el-table-column>
        <el-table-column prop="createTime" label="创建日期"></el-table-column>
        <el-table-column prop="createBy" label="创建人"></el-table-column>
        <el-table-column prop="status" label="当前状态">
          <template slot-scope="scope">
            <el-tag :type="getResultStatusType(scope.row.status)">
              {{ getResultStatusText(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" min-width="100" fixed="right">
          <template slot-scope="scope">
            <el-button type="text" @click="handleViewDetail(scope.row)"
              >详情</el-button
            >
            <el-button type="text" @click="handleViewDetail(scope.row)">详情</el-button>
          </template>
        </el-table-column>
      </Table>
@@ -135,44 +60,22 @@
          <div>二 、检验结果</div>
        </div>
      </div>
      <Table
        :data="inspectionResultData"
        :total="0"
        :height="null"
        class="rwuTable"
      >
        <el-table-column
          prop="planName"
          label="所属项目课题方案"
          min-width="180"
        ></el-table-column>
        <el-table-column
          prop="experimentCode"
          label="所属实验编号"
          min-width="120"
        ></el-table-column>
        <el-table-column
          prop="createTime"
          label="创建时间"
          min-width="150"
        ></el-table-column>
        <el-table-column
          prop="creator"
          label="创建人"
          min-width="100"
        ></el-table-column>
        <el-table-column
          prop="status"
          label="状态"
          min-width="100"
        ></el-table-column>
      <Table :data="inspectionResultData" :total="0" :height="null" class="rwuTable">
        <el-table-column prop="projectName" label="所属课题方案"></el-table-column>
        <el-table-column prop="experimentCode" label="所属实验编号"></el-table-column>
        <el-table-column prop="experimentName" label="实验名称"></el-table-column>
        <el-table-column prop="createTime" label="创建时间"></el-table-column>
        <el-table-column prop="createBy" label="创建人"></el-table-column>
        <el-table-column prop="status" label="状态">
          <template slot-scope="scope">
            <el-tag :type="getCheckoutStatusType(scope.row.status)">
              {{ getCheckoutStatusText(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" min-width="100" fixed="right">
          <template slot-scope="scope">
            <el-button
              type="text"
              @click="handleViewInspectionDetail(scope.row)"
              >详情</el-button
            >
            <el-button type="text" @click="handleViewInspectionDetail(scope.row)">详情</el-button>
          </template>
        </el-table-column>
      </Table>
@@ -184,6 +87,11 @@
        </div>
      </div>
      <div class="content-box">
        <AiEditor ref="analysisEditor" :readOnly="isView" :value="form.experimentResult" height="200px"
          placeholder="暂无实验数据分析及结论..." />
      </div>
      <div class="header-title">
        <div class="header-title-left">
          <img src="@/assets/public/headercard.png" />
@@ -193,25 +101,19 @@
      <div class="evaluate-card">
        <div class="evaluate-card-people">
          <div
            v-for="technician in labTechnicians"
            :key="technician.id"
            class="evaluate-card-people-item"
            :class="{ 'active-people': selectedLabTechnician?.id === technician.id }"
            @click="handleSelectLabTechnician(technician)"
          >
            {{ technician.name }}
          <div v-for="technician in labTechnicians" :key="technician.id" class="evaluate-card-people-item"
            :class="{ 'active-people': selectedLabTechnician?.id == technician.id }"
            @click="handleSelectLabTechnician(technician)">
            {{ technician.nickName }}
          </div>
        </div>
        <div class="evaluate-card-cotent">
          <template v-if="selectedLabTechnician">
            <template v-if="selectedLabTechnician.data">
              <EvaluateTable
                class="evaluate-table"
                :isReadonly="true"
                :type="1"
                :viewJson="JSON.stringify(selectedLabTechnician.data)"
              />
              <div class="evaluate-table-wrapper" @click="handleEvaluate('labTechnician')">
                <EvaluateTable class="evaluate-table" :isReadonly="true" :type="1"
                  :viewJson="selectedLabTechnician.data.resultEvaluateJson" />
              </div>
            </template>
            <template v-else>
              <div class="no-data">暂未评定</div>
@@ -230,25 +132,19 @@
      <div class="evaluate-card">
        <div class="evaluate-card-people">
          <div
            v-for="experimenter in experimenters"
            :key="experimenter.id"
            class="evaluate-card-people-item"
            :class="{ 'active-people': selectedExperimenter?.id === experimenter.id }"
            @click="handleSelectExperimenter(experimenter)"
          >
            {{ experimenter.name }}
          <div v-for="experimenter in experimenters" :key="experimenter.id" class="evaluate-card-people-item"
            :class="{ 'active-people': selectedExperimenter?.id == experimenter.id }"
            @click="handleSelectExperimenter(experimenter)">
            {{ experimenter.nickName }}
          </div>
        </div>
        <div class="evaluate-card-cotent">
          <template v-if="selectedExperimenter">
            <template v-if="selectedExperimenter.data">
              <EvaluateTable
                ref="experimenterEvaluateTable"
                class="evaluate-table"
                :isReadonly="true"
                :viewJson="JSON.stringify(selectedExperimenter.data)"
              />
              <div class="evaluate-table-wrapper" @click="handleEvaluate('experimenter')">
                <EvaluateTable ref="experimenterEvaluateTable" class="evaluate-table" :isReadonly="true"
                  :viewJson="selectedExperimenter.data.resultEvaluateJson" />
              </div>
            </template>
            <template v-else>
              <div class="no-data">暂未评定</div>
@@ -257,44 +153,76 @@
          </template>
        </div>
      </div>
      <div class="header-title" v-if="isView">
        <div class="header-title-left">
          <img src="@/assets/public/headercard.png" />
          <div>六 、工艺工程师工作评定</div>
        </div>
      </div>
      <div class="add-project-footer">
        <el-button type="primary" class="save-btn">发送</el-button>
        <el-button>存草稿</el-button>
      <div class="evaluate-card" v-if="isView">
        <div class="evaluate-card-people">
          <div v-for="engineer in processEngineers" :key="engineer.id" class="evaluate-card-people-item"
            :class="{ 'active-people': selectedProcessEngineer?.id == engineer.id }"
            @click="handleSelectProcessEngineer(engineer)">
            {{ engineer.nickName }}
          </div>
        </div>
        <div class="evaluate-card-cotent">
          <template v-if="selectedProcessEngineer">
            <template v-if="selectedProcessEngineer.data">
              <div class="evaluate-table-wrapper" @click="handleEvaluate('processEngineer')">
                <EvaluateTable class="evaluate-table" :isReadonly="true" :type="1"
                  :viewJson="selectedProcessEngineer.data.resultEvaluateJson" />
              </div>
            </template>
            <template v-else>
              <div class="no-data">暂未评定</div>
              <!-- <div v-if="canEvaluate" class="to-evaluate" >去评价</div> -->
            </template>
          </template>
        </div>
      </div>
      <div class="add-project-footer" v-if="!isView">
        <el-button type="primary" class="save-btn" @click="handleSubmit(1)">提交</el-button>
        <el-button @click="handleSubmit(-1)">存草稿</el-button>
      </div>
      <div class="add-project-footer" v-if="isView && form.status == 2">
        <el-button type="primary" class="save-btn" @click="handleEvaluate('processEngineer')">工艺工程师评定</el-button>
        <!-- <el-button @click="handleSubmit(-1)">存草稿</el-button> -->
      </div>
    </el-form>
    <!-- 选择实验调度弹窗 -->
    <experimental-scheduling
      :show.sync="schedulingDialogVisible"
      @select="handleSchedulingSelect"
    />
    <experimental-scheduling :show="schedulingDialogVisible" @close="handleSchedulingClose"
      @submit="handleSchedulingSelect" />
    <!-- 评价弹窗 -->
    <evaluation-dialog
      :modelValue="evaluationDialogVisible"
      :type="currentEvaluationType"
      @update:modelValue="updateEvaluationDialogVisible"
      @submit="handleEvaluationSubmit"
    />
    <evaluation-dialog :modelValue="evaluationDialogVisible" :type="currentEvaluationType"
      :viewJson="currentEvaluationData ? currentEvaluationData : ''" @update:modelValue="updateEvaluationDialogVisible"
      @submit="handleEvaluationSubmit" />
    <!-- 检验结果详情弹窗 -->
    <checkout-result
      :visible.sync="checkoutResultVisible"
      :data="currentCheckoutResult"
    />
    <checkout-result :visible="checkoutResultVisible" :data="currentCheckoutResult"
      @close="handleCheckoutResultClose" />
    <!-- 新增组件弹窗 -->
    <add-component-dialog
    <!-- <add-component-dialog
      v-if="showNewDialog"
      :visible.sync="showNewDialog"
      @confirm="handleAddComponent"
    />
    /> -->
    <!-- 实验结果详情 -->
    <ExperimentResultDialog :visible.sync="experimentResultDialogVisible" :type="'view'"
      :data="currentExperimentResult" />
  </Card>
</template>
<script>
import ExperimentalScheduling from "./components/experimental-scheduling.vue";
import ExperimentResultDialog from "./components/experimentResultDialog.vue";
import ExperimentalScheduling from "../sampleManage/components/experimental-scheduling.vue";
import moment from "moment";
import EvaluationDialog from "./components/evaluation-dialog.vue";
import CheckoutResult from "./components/checkout-result.vue";
import AddComponentDialog from "@/components/AddComponentDialog";
import AiEditor from "@/components/AiEditor";
// import AddComponentDialog from "@/components/AddComponentDialog";
import { getOtherInfoByDispatchId, add, update, getDetail,evaluateProcess } from './service'
export default {
  name: "AddProject",
@@ -302,118 +230,70 @@
    ExperimentalScheduling,
    EvaluationDialog,
    CheckoutResult,
    AddComponentDialog
    ExperimentResultDialog,
    AiEditor
    // AddComponentDialog
  },
  data() {
    return {
      showNewDialog: true,
      dialogVisible: false,
      schedulingDialogVisible: false,
      experimentResultDialogVisible: false,
      currentExperimentResult: null,
      isEdit: false,
      currentEditIndex: -1,
      selectedScheduling: null,
      form: {
        recordNo: "",
        testItemName: "",
        testItemNo: "",
        testMethodName: "",
        testMethodNo: "",
        dispatchId: "",
        experimentResult: "",
        id: "",
        resultWorkEvaluates: [],
        status: -1
      },
      rules: {
        recordNo: [
          {
            required: true,
            message: "请输入原始检验记录编号",
            trigger: "blur",
          },
        ],
        testItemName: [
          { required: true, message: "请输入检测项名字", trigger: "blur" },
        ],
        testItemNo: [
          { required: true, message: "请输入检测项编号", trigger: "blur" },
        ],
        testMethodName: [
          { required: true, message: "请输入检测方法名字", trigger: "blur" },
        ],
        testMethodNo: [
          { required: true, message: "请输入检测方法编号", trigger: "blur" },
        dispatchId: [
          { required: true, message: "请选择所属实验调度", trigger: "change" }
        ],
      },
      taskTableData: [],
      experimentResultData: [
        {
          planName: "名称名称名称",
          experimentCode: "3814763",
          experimentName: "名称名称22",
          experimentDate: "2024-05-28",
          experimenter: "刘大大",
          createTime: "2025-1-2 16:27:17",
          creator: "周乐心",
          status: "实验员已提交",
        },
      ],
      inspectionResultData: [
        {
          planName: "名称名称名称",
          experimentCode: "31423764",
          createTime: "",
          creator: "",
          status: "已提交",
        },
        {
          planName: "名称名称名称",
          experimentCode: "31423764",
          createTime: "",
          creator: "",
          status: "已提交",
        },
      ],
      experimentResultData: [],
      inspectionResultData: [],
      // 化验师数据
      labTechnicians: [
        {
          id: 1,
          name: '张三',
          role: '化验师',
          data: null // 评定数据,null 表示未评定
        },
        {
          id: 2,
          name: '李四',
          role: '化验师',
          data: null
        }
      ],
      labTechnicians: [],
      selectedLabTechnician: null,
      // 实验员数据
      experimenters: [
        {
          id: 1,
          name: '王五',
          role: '实验员',
          data: null
        },
        {
          id: 2,
          name: '赵六',
          role: '实验员',
          data: null
        }
      ],
      experimenters: [],
      selectedExperimenter: null,
      // 工艺工程师数据
      processEngineers: [],
      selectedProcessEngineer: null,
      // 弹窗控制
      evaluationDialogVisible: false,
      currentEvaluationType: '',
      checkoutResultVisible: false,
      currentCheckoutResult: null
      currentCheckoutResult: null,
      statusTypeMap: {
        "-1": "info",
        "1": "warning",
        "2": "success",
        "3": "info"
      },
      statusTextMap: {
        "-1": "草稿箱",
        "1": "待确认",
        "2": "已确认",
        "3": "已封存"
      },
      currentEvaluationData: null, // 添加当前评价数据
    };
  },
  watch: {
    selectedLabTechnician: {
      handler(newVal) {
        console.log("selectedLabTechnician", newVal);
      },
    },
  },
@@ -421,26 +301,24 @@
    // 默认选中第一个人员
    this.selectedLabTechnician = this.labTechnicians[0];
    this.selectedExperimenter = this.experimenters[0];
    this.selectedProcessEngineer = this.processEngineers[0];
    // 如果是编辑模式,获取详情数据
    const id = this.$route.query.id;
    if (id) {
      this.getDetailData(id);
    }
  },
  methods: {
    handleSelectScheduling() {
      this.schedulingDialogVisible = true;
    },
    handleSchedulingSelect(selectedData) {
      if (selectedData && selectedData.length > 0) {
        this.selectedScheduling = selectedData[0];
        this.$message.success("选择成功");
      }
    },
    handleAddTask() {
      this.isEdit = false;
      this.currentEditIndex = -1;
      this.dialogVisible = true;
      this.schedulingDialogVisible = true;
    },
    handleEditTask(row) {
      this.isEdit = true;
      this.currentEditIndex = this.taskTableData.findIndex(
        (item) => item === row
        (item) => item == row
      );
      const editData = {
@@ -480,7 +358,7 @@
        type: "warning",
      })
        .then(() => {
          const index = this.taskTableData.findIndex((item) => item === row);
          const index = this.taskTableData.findIndex((item) => item == row);
          if (index > -1) {
            const item = this.taskTableData[index];
            if (item.photos) {
@@ -502,7 +380,7 @@
            this.$message.success("删除成功");
          }
        })
        .catch(() => {});
        .catch(() => { });
    },
    handleTaskSubmit(formData) {
      const photos = formData.photos.map((file) => ({
@@ -532,7 +410,7 @@
          oldData.photos.forEach((photo) => {
            if (
              photo.url.startsWith("blob:") &&
              !photos.find((p) => p.url === photo.url)
              !photos.find((p) => p.url == photo.url)
            ) {
              URL.revokeObjectURL(photo.url);
            }
@@ -542,7 +420,7 @@
          oldData.spectrums.forEach((spectrum) => {
            if (
              spectrum.url.startsWith("blob:") &&
              !spectrums.find((s) => s.url === spectrum.url)
              !spectrums.find((s) => s.url == spectrum.url)
            ) {
              URL.revokeObjectURL(spectrum.url);
            }
@@ -564,11 +442,18 @@
      return photos.map((photo) => photo.url);
    },
    handleViewDetail(row) {
      console.log("查看详情", row);
      // 获取实验结果详情
      this.currentExperimentResult = row;
      this.experimentResultDialogVisible = true;
    },
    handleViewInspectionDetail(row) {
      // 获取检验结果详情
      this.currentCheckoutResult = row;
      this.checkoutResultVisible = true;
    },
    handleCheckoutResultClose() {
      this.currentCheckoutResult = null
      this.checkoutResultVisible = false;
    },
    // 选择化验师
    handleSelectLabTechnician(technician) {
@@ -578,43 +463,528 @@
    handleSelectExperimenter(experimenter) {
      this.selectedExperimenter = experimenter;
    },
    // 选择工艺工程师
    handleSelectProcessEngineer(engineer) {
      this.selectedProcessEngineer = engineer;
    },
    // 去评价
    handleEvaluate(type) {
      if(this.$route.query.type == 'view' && type !='processEngineer'){
        this.$message.warning('当前为查看模式,无法进行评价');
        return;
      }
      this.currentEvaluationType = type;
      // 根据类型获取当前选中人员的评定数据
      if (type == 'labTechnician' && this.selectedLabTechnician) {
        this.currentEvaluationData = this.selectedLabTechnician.data?.resultEvaluateJson;
      } else if (type == 'experimenter' && this.selectedExperimenter) {
        this.currentEvaluationData = this.selectedExperimenter.data?.resultEvaluateJson;
      } else if (type == 'processEngineer' && this.selectedProcessEngineer) {
        this.currentEvaluationData = this.selectedProcessEngineer.data?.resultEvaluateJson;
      }
      this.evaluationDialogVisible = true;
    },
    // 处理评价提交
    handleEvaluationSubmit(evaluationData) {
      const { type, activeIndex } = evaluationData;
      if (type === 'labTechnician') {
      // 将评分数据转换为后端需要的格式
      const evaluateData = {
        evaluateType: type == 'labTechnician' ? 2 : type == 'experimenter' ? 3 : 1, // 1=工艺工程师 2=化验师 3=实验员
        evaluateOne: this.getEvaluateValue(activeIndex[0].score),
        evaluateTwo: this.getEvaluateValue(activeIndex[1].score),
        evaluateThree: this.getEvaluateValue(activeIndex[2].score),
        evaluateFour: this.getEvaluateValue(activeIndex[3].score),
        evaluateFive: this.getEvaluateValue(activeIndex[4].score),
        evaluateSix: this.getEvaluateValue(activeIndex[5].score),
        evaluateTime: moment().format('YYYY-MM-DD HH:mm:ss'),
        resultEvaluateJson: JSON.stringify(activeIndex),
        dispatchId: this.selectedScheduling?.id,
        userId: type == 'labTechnician' ? this.selectedLabTechnician.id :
                type == 'experimenter' ? this.selectedExperimenter.id :
                this.selectedProcessEngineer.id,
        // teamId: this.selectedScheduling?.teamId,
        status: 1
      };
      if (type == 'labTechnician') {
        // 更新化验师列表中的数据
        const labTechnician = this.labTechnicians.find(item => item.id === this.selectedLabTechnician.id);
        const labTechnician = this.labTechnicians.find(item => item.id == this.selectedLabTechnician.id);
        if (labTechnician) {
          labTechnician.data = activeIndex;
          // 更新当前选中的化验师数据
          labTechnician.data = { ...labTechnician.data, ...evaluateData };
          this.selectedLabTechnician = { ...labTechnician };
        }
      } else if (type === 'experimenter') {
      } else if (type == 'experimenter') {
        // 更新实验员列表中的数据
        const experimenter = this.experimenters.find(item => item.id === this.selectedExperimenter.id);
        const experimenter = this.experimenters.find(item => item.id == this.selectedExperimenter.id);
        if (experimenter) {
          experimenter.data = activeIndex;
          // 更新当前选中的实验员数据
          experimenter.data = { ...experimenter.data, ...evaluateData };
          this.selectedExperimenter = { ...experimenter };
        }
      } else if (type == 'processEngineer') {
        // 工艺工程师评定直接调用接口
        console.log('11111111111111111111',{
          ...evaluateData,
          resultReportId: this.form.id // 添加实验报告ID
        })
        evaluateProcess({
          ...evaluateData,
          resultReportId: this.form.id // 添加实验报告ID
        }).then(res => {
          if (res.code == 200) {
            this.$message.success('评定成功');
            // 重新获取详情数据
            this.getDetailData(this.form.id);
          } else {
            this.$message.error(res.msg || '评定失败');
          }
        }).catch(err => {
          this.$message.error('评定失败');
        });
      }
      // 这里可以添加数据持久化的逻辑,比如调用API保存到后端
      // this.saveEvaluationData(type, activeIndex);
      this.$message.success('评价提交成功');
      this.evaluationDialogVisible = false;
      this.currentEvaluationData = null;
    },
    // 将分数转换为评定值
    getEvaluateValue(score) {
      // 2分 = 良好(1), 1分 = 正确(2), 0分 = 失误(3)
      const scoreMap = {
        2: 1, // 良好
        1: 2, // 正确
        0: 3  // 失误
      };
      return scoreMap[score] || 3; // 默认返回失误
    },
    // 收集评分数据
    collectEvaluateData() {
      const evaluates = [];
      // 收集化验师评分
      this.labTechnicians.forEach(tech => {
        if (tech.data) {
          evaluates.push({
            ...tech.data,
            dispatchId: this.selectedScheduling?.id,
            userId: tech.id,
            teamId: this.selectedScheduling?.teamId,
            status: -1,
            id: tech.data.id || undefined
          });
        }
      });
      // 收集实验员评分
      this.experimenters.forEach(exp => {
        if (exp.data) {
          evaluates.push({
            ...exp.data,
            dispatchId: this.selectedScheduling?.id,
            userId: exp.id,
            teamId: this.selectedScheduling?.teamId,
            status: -1,
            id: exp.data.id || undefined
          });
        }
      });
      // 收集工艺工程师评分
      this.processEngineers.forEach(eng => {
        if (eng.data) {
          evaluates.push({
            ...eng.data,
            dispatchId: this.selectedScheduling?.id,
            userId: eng.id,
            teamId: this.selectedScheduling?.teamId,
            status: -1,
            id: eng.data.id || undefined
          });
        }
      });
      return evaluates;
    },
    // 更新弹窗显示状态
    updateEvaluationDialogVisible(value) {
      this.evaluationDialogVisible = value;
      if (!value) {
        this.currentEvaluationData = null; // 关闭弹窗时清空数据
      }
    },
    handleSchedulingClose() {
      this.schedulingDialogVisible = false;
    },
    handleSchedulingSelect(selectedData) {
      if (selectedData && selectedData.length > 0) {
        this.selectedScheduling = selectedData[0];
        this.taskTableData = [selectedData[0]]; // 更新表格数据
        // 调用getOtherInfoByDispatchId接口
        this.getInfomationByDispatchId(selectedData[0]);
        this.$message.success("选择成功");
      }
    },
    getInfomationByDispatchId(selectedData) {
      getOtherInfoByDispatchId({ dispatchId: selectedData.id }).then(res => {
        // 直接使用接口返回的字段,因为字段名完全一致
        let list = res.inspectionReports.map(item => ({
          ...item,
          experimentName: selectedData.experimentName,
          projectName: selectedData.projectName,
          experimentCode: selectedData.experimentCode
        })) || []
        this.experimentResultData = res.experimentSchemeVOS || [];
        this.inspectionResultData = list;
        if (!this.$route.query.id) {
          // 处理实验人员数据
          const participants = res.experimentDispatchParticipants || [];
          // 获取工艺工程师列表
          this.processEngineers = participants
            .filter(p => p.roleType == 3) // 3=工艺工程师
            .map(p => ({
              id: p.userId,
              nickName: p.nickName || '工艺工程师',
              role: '工艺工程师',
              data: null
            }));
          // 获取化验师列表
          this.labTechnicians = participants
            .filter(p => p.roleType == 4) // 4=化验师
            .map(p => ({
              id: p.userId,
              nickName: p.nickName || '化验师',
              role: '化验师',
              data: null
            }));
          // 获取实验员列表
          this.experimenters = participants
            .filter(p => p.roleType == 5) // 5=实验员
            .map(p => ({
              id: p.userId,
              nickName: p.nickName || '实验员',
              role: '实验员',
              data: null
            }));
          // 处理评定数据
          const evaluates = res.resultWorkEvaluates || [];
          evaluates.forEach(evaluate => {
            // 根据评定类型和用户ID匹配对应的评定数据
            if (evaluate.evaluateType == 1) { // 1=工艺工程师
              const engineer = this.processEngineers.find(e => e.id == evaluate.userId);
              if (engineer) {
                engineer.data = {
                  id: evaluate.id, // 保存id
                  evaluateOne: evaluate.evaluateOne,
                  evaluateTwo: evaluate.evaluateTwo,
                  evaluateThree: evaluate.evaluateThree,
                  evaluateFour: evaluate.evaluateFour,
                  evaluateFive: evaluate.evaluateFive,
                  evaluateSix: evaluate.evaluateSix,
                  evaluateTime: evaluate.evaluateTime,
                  resultEvaluateJson: evaluate.resultEvaluateJson
                };
              }
            } else if (evaluate.evaluateType == 2) { // 2=化验师
              const technician = this.labTechnicians.find(t => t.id == evaluate.userId);
              if (technician) {
                technician.data = {
                  id: evaluate.id, // 保存id
                  evaluateOne: evaluate.evaluateOne,
                  evaluateTwo: evaluate.evaluateTwo,
                  evaluateThree: evaluate.evaluateThree,
                  evaluateFour: evaluate.evaluateFour,
                  evaluateFive: evaluate.evaluateFive,
                  evaluateSix: evaluate.evaluateSix,
                  evaluateTime: evaluate.evaluateTime,
                  resultEvaluateJson: evaluate.resultEvaluateJson
                };
              }
            } else if (evaluate.evaluateType == 3) { // 3=实验员
              const experimenter = this.experimenters.find(e => e.id == evaluate.userId);
              if (experimenter) {
                experimenter.data = {
                  id: evaluate.id, // 保存id
                  evaluateOne: evaluate.evaluateOne,
                  evaluateTwo: evaluate.evaluateTwo,
                  evaluateThree: evaluate.evaluateThree,
                  evaluateFour: evaluate.evaluateFour,
                  evaluateFive: evaluate.evaluateFive,
                  evaluateSix: evaluate.evaluateSix,
                  evaluateTime: evaluate.evaluateTime,
                  resultEvaluateJson: evaluate.resultEvaluateJson
                };
              }
            }
          });
          // 默认选中第一个人员
          if (this.processEngineers.length > 0) {
            this.selectedProcessEngineer = this.processEngineers[0];
          }
          if (this.labTechnicians.length > 0) {
            this.selectedLabTechnician = this.labTechnicians[0];
          }
          if (this.experimenters.length > 0) {
            this.selectedExperimenter = this.experimenters[0];
          }
        }
      }).catch(err => {
        this.$message.error('获取其他信息失败');
      });
    },
    getStatusType(status) {
      return this.statusTypeMap[status] || 'info';
    },
    getStatusText(status) {
      return this.statusTextMap[status] || '未知状态';
    },
    getResultStatusType(status) {
      const statusMap = {
        '-1': "info",
        '1': "warning",
        '2': "warning",
        '3': "success",
        '4': "danger",
        '5': "info",
        '6': 'success'
      };
      return statusMap[status] || "info";
    },
    getResultStatusText(status) {
      const statusMap = {
        '-1': "草稿",
        '1': "已发送",
        '2': "申请中止待审核",
        '3': "申请中止已通过",
        '4': "申请中止已驳回",
        '5': "已封存",
        '6': '实验员已提交'
      };
      return statusMap[status] || "未知";
    },
    getCheckoutStatusType(status) {
      const statusMap = {
        '-1': 'info',
        '1': 'warning',
        '2': 'success'
      };
      return statusMap[status] || 'info';
    },
    getCheckoutStatusText(status) {
      const statusMap = {
        '-1': '草稿箱',
        '1': '待提交',
        '2': '已提交'
      };
      return statusMap[status] || '未知';
    },
    // 验证评分数据
    validateEvaluates() {
      // 检查是否所有实验员和化验师都有评分
      const allTechnicians = this.labTechnicians.every(tech => tech.data);
      const allExperimenters = this.experimenters.every(exp => exp.data);
      if (!allTechnicians || !allExperimenters) {
        this.$message.error('请完成所有实验员和化验师的评分');
        return false;
      }
      return true;
    },
    // 提交表单
    async handleSubmit(status) {
      try {
        // 如果是提交状态,进行必填校验
        if (status == 1) {
          // 校验表单
          await this.$refs.form.validate();
          // 获取富文本编辑器内容
          const experimentResult = this.$refs.analysisEditor.getContent();
          // 校验实验数据分析及结论
          if (!experimentResult || experimentResult == '<p></p>' || experimentResult.trim() == '<p></p>') {
            this.$message.error('请输入实验数据分析及结论');
            return;
          }
          // 校验评分数据
          if (!this.validateEvaluates()) {
            return;
          }
        }
        // 收集评分数据
        const evaluates = this.collectEvaluateData();
        // 更新评分数据的状态
        evaluates.forEach(evaluate => {
          evaluate.status = status;
        });
        // 构建提交数据
        const submitData = {
          dispatchId: this.selectedScheduling?.id,
          experimentResult: this.$refs.analysisEditor.getContent(),
          status: status,
          resultWorkEvaluates: evaluates
        };
        console.log('111111111111',submitData)
        // 如果有ID,则是编辑
        if (this.form.id) {
          submitData.id = this.form.id;
          await update(submitData);
        } else {
          await add(submitData);
        }
        this.$message.success(status == 1 ? '提交成功' : '保存草稿成功');
        this.$router.go(-1);
      } catch (error) {
        this.$message.error('提交失败,请重试');
      }
    },
    // 获取详情数据
    async getDetailData(id) {
      try {
        const res = await getDetail({ id });
        if (res) {
          this.form = {
            ...res,
            experimentResult: res.experimentResult || ''
          };
          // 设置选中的实验调度
          if (res.experimentDispatchVO) {
            this.selectedScheduling = {
              ...res.experimentDispatchVO
            };
            this.taskTableData = [res.experimentDispatchVO]
            // 获取其他信息
            await this.getInfomationByDispatchId(res.experimentDispatchVO);
          }
          if (res.experimentDispatchParticipants) {
            // 处理实验人员数据
            const participants = res.experimentDispatchParticipants || [];
            // 获取工艺工程师列表
            this.processEngineers = participants
              .filter(p => p.roleType == 3) // 3=工艺工程师
              .map(p => ({
                id: p.userId,
                nickName: p.nickName || '工艺工程师',
                role: '工艺工程师',
                data: null
              }));
            // 获取化验师列表
            this.labTechnicians = participants
              .filter(p => p.roleType == 4)
              .map(p => ({
                id: p.userId,
                nickName: p.nickName || '化验师',
                role: '化验师',
                data: null
              }));
            // 获取实验员列表
            this.experimenters = participants
              .filter(p => p.roleType == 5)
              .map(p => ({
                id: p.userId,
                nickName: p.nickName || '实验员',
                role: '实验员',
                data: null
              }));
            // 处理评分数据
            if (res.resultWorkEvaluates) {
              res.resultWorkEvaluates.forEach(evaluate => {
                if (evaluate.evaluateType == 1) { // 工艺工程师
                  const engineer = this.processEngineers.find(e => e.id == evaluate.userId);
                  if (engineer) {
                    engineer.data = {
                      id: evaluate.id,
                      evaluateOne: evaluate.evaluateOne,
                      evaluateTwo: evaluate.evaluateTwo,
                      evaluateThree: evaluate.evaluateThree,
                      evaluateFour: evaluate.evaluateFour,
                      evaluateFive: evaluate.evaluateFive,
                      evaluateSix: evaluate.evaluateSix,
                      evaluateTime: evaluate.evaluateTime,
                      resultEvaluateJson: evaluate.resultEvaluateJson
                    };
                  }
                } else if (evaluate.evaluateType == 2) { // 化验师
                  const technician = this.labTechnicians.find(t => t.id == evaluate.userId);
                  if (technician) {
                    technician.data = {
                      id: evaluate.id,
                      evaluateOne: evaluate.evaluateOne,
                      evaluateTwo: evaluate.evaluateTwo,
                      evaluateThree: evaluate.evaluateThree,
                      evaluateFour: evaluate.evaluateFour,
                      evaluateFive: evaluate.evaluateFive,
                      evaluateSix: evaluate.evaluateSix,
                      evaluateTime: evaluate.evaluateTime,
                      resultEvaluateJson: evaluate.resultEvaluateJson
                    };
                  }
                } else if (evaluate.evaluateType == 3) { // 实验员
                  const experimenter = this.experimenters.find(e => e.id == evaluate.userId);
                  if (experimenter) {
                    experimenter.data = {
                      id: evaluate.id,
                      evaluateOne: evaluate.evaluateOne,
                      evaluateTwo: evaluate.evaluateTwo,
                      evaluateThree: evaluate.evaluateThree,
                      evaluateFour: evaluate.evaluateFour,
                      evaluateFive: evaluate.evaluateFive,
                      evaluateSix: evaluate.evaluateSix,
                      evaluateTime: evaluate.evaluateTime,
                      resultEvaluateJson: evaluate.resultEvaluateJson
                    };
                  }
                }
              });
            }
            // 默认选中第一个人员
            if (this.processEngineers.length > 0) {
              this.selectedProcessEngineer = this.processEngineers[0];
            }
            if (this.labTechnicians.length > 0) {
              this.selectedLabTechnician = this.labTechnicians[0];
            }
            if (this.experimenters.length > 0) {
              this.selectedExperimenter = this.experimenters[0];
            }
          }
        }
      } catch (error) {
        this.$message.error('获取详情失败');
      }
    },
    // 判断是否可以评定
    canEvaluate() {
      const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}');
      const isAdmin = userInfo.roleType == 1; // 1是超级管理员
      const isApprover = userInfo.roleType == 2; // 2是审批人
      return (isAdmin || isApprover) && this.form.status == 2; // 2是待评定状态
    }
  },
  computed: {
    isView() {
      return this.$route.query.type == 'view';
    },
  },
};
</script>
@@ -748,11 +1118,13 @@
      color: rgba(4, 156, 154, 1);
    }
  }
  .evaluate-card-cotent {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    .no-data {
      font-family: PingFangSC, PingFang SC;
      font-weight: 500;
@@ -762,6 +1134,7 @@
      margin-top: 58px;
      margin-bottom: 30px;
    }
    .to-evaluate {
      width: 65px;
      background: #049c9a;
@@ -774,10 +1147,26 @@
      text-align: center;
      margin-bottom: 12px;
    }
    .evaluate-table{
    .evaluate-table {
      width: 100%;
      margin-top: 29px;
    }
  }
}
.content-box {
  padding: 0 20px;
  margin: 20px 0;
}
.evaluate-table-wrapper {
  width: 100%;
  cursor: pointer;
  transition: all 0.3s;
  &:hover {
    opacity: 0.8;
  }
}
</style>
laboratory/src/views/dataManagement/testResultReport/list.vue
@@ -1,31 +1,35 @@
<template>
  <div class="list">
    <TableCustom :queryForm="form" :tableData="tableData" :total="total" :height="null">
    <TableCustom :queryForm="form" :tableData="tableData" :total="total" :height="null" @handlePageChange="handlePageChange" @handleSizeChange="handleSizeChange">
      <template #search>
        <el-form :model="form" labelWidth="auto" inline>
          <el-form-item label="所属项目课题方案:">
            <el-input v-model="form.projectPlan" placeholder="请输入"></el-input>
            <el-input v-model="form.projectName" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="实验编号:">
            <el-input v-model="form.experimentNo" placeholder="请输入"></el-input>
            <el-input v-model="form.experimentCode" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="实验名称:">
            <el-input v-model="form.experimentName" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="创建日期:">
            <el-date-picker
              v-model="form.createTime"
              v-model="dateRange"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              value-format="yyyy-MM-dd"
              @change="handleDateChange"
            ></el-date-picker>
          </el-form-item>
          <el-form-item label="状态:">
            <el-select v-model="form.status" placeholder="请选择">
              <el-option label="待提交" value="pending"></el-option>
              <el-option label="已提交" value="submitted"></el-option>
              <el-option label="全部" value=""></el-option>
              <el-option label="待提交" :value="1"></el-option>
              <el-option label="待评定" :value="2"></el-option>
              <el-option label="已评定" :value="3"></el-option>
              <el-option label="已封存" :value="4"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="">
@@ -45,6 +49,7 @@
              实验结果汇报列表
            </div>
            <div
              v-if="isProcessEngineer"
              class="drafts"
              :class="{ active: currentType === 'draft' }"
              @click="handleTypeChange('draft')"
@@ -52,160 +57,137 @@
              草稿箱
            </div>
          </div>
          <el-button @click="handleAddResult" class="el-icon-plus" type="primary">
            新增实验结果
          <el-button v-if="isProcessEngineer" @click="handleAddResult" class="el-icon-plus" type="primary">
            新增实验结果汇报
          </el-button>
        </div>
      </template>
      <template #table>
        <el-table-column prop="projectPlan" label="所属项目课题方案"></el-table-column>
        <el-table-column prop="experimentNo" label="实验编号"></el-table-column>
        <el-table-column prop="projectName" label="所属项目课题方案"></el-table-column>
        <el-table-column prop="experimentCode" label="实验编号"></el-table-column>
        <el-table-column prop="experimentName" label="实验名称"></el-table-column>
        <el-table-column prop="engineer" label="工艺工程师"></el-table-column>
        <el-table-column prop="chemist" label="化验师"></el-table-column>
        <el-table-column prop="engineerApproved" label="是否评定">
        <el-table-column prop="processEngineerName" label="工艺工程师"></el-table-column>
        <el-table-column prop="laboratoryChemistName" label="化验师"></el-table-column>
        <el-table-column prop="laboratoryChemistEvaluate" label="是否评定">
          <template slot-scope="scope">
            <el-tag :type="scope.row.engineerApproved === '是' ? 'success' : 'danger'">
              {{ scope.row.engineerApproved }}
            <el-tag :type="scope.row.laboratoryChemistEvaluate === 1 ? 'success' : 'danger'">
              {{ scope.row.laboratoryChemistEvaluate === 1 ? '是' : '否' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="experimenter" label="实验员"></el-table-column>
        <el-table-column prop="experimenterApproved" label="是否评定">
        <el-table-column prop="experimenterName" label="实验员"></el-table-column>
        <el-table-column prop="experimenterEvaluate" label="是否评定">
          <template slot-scope="scope">
            <el-tag :type="scope.row.experimenterApproved === '是' ? 'success' : 'danger'">
              {{ scope.row.experimenterApproved }}
            <el-tag :type="scope.row.experimenterEvaluate === 1 ? 'success' : 'danger'">
              {{ scope.row.experimenterEvaluate === 1 ? '是' : '否' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建日期"></el-table-column>
        <el-table-column prop="createTime" label="创建日期" width="180"></el-table-column>
        <el-table-column prop="status" label="状态">
          <template slot-scope="scope">
            <el-tag :type="scope.row.status === '已提交' ? 'success' : 'warning'">
              {{ scope.row.status }}
            <el-tag :type="getStatusType(scope.row.status)">
              {{ getStatusText(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="280">
        <el-table-column label="操作" width="180">
          <template slot-scope="scope">
            <template v-if="currentType === 'list'">
              <!-- 待提交状态 -->
              <template v-if="scope.row.status === '待提交'">
                <el-button type="text" @click="handleSubmit(scope.row)">提交</el-button>
                <el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
                <el-button type="text" @click="handleDetail(scope.row.id)">详情</el-button>
                <el-button type="text" @click="handleDelete(scope.row)">删除</el-button>
              <template v-if="isProcessEngineer">
                <template v-if="scope.row.status === 1">
                  <el-button type="text" @click="handleSubmit(scope.row)">提交</el-button>
                  <el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
                  <el-button type="text" @click="handleDetail(scope.row.id)">详情</el-button>
                  <el-button type="text" @click="handleDelete(scope.row)">删除</el-button>
                </template>
                <!-- <template v-else-if="scope.row.status === 2">
                  <el-button type="text" @click="handleDetail(scope.row.id)">详情</el-button>
                </template> -->
                <template v-else>
                  <el-button type="text" @click="handleDetail(scope.row.id)">详情</el-button>
                </template>
              </template>
              <!-- 待评定状态 -->
              <template v-else-if="scope.row.status === '待评定'">
                <el-button type="text" @click="handleEvaluate(scope.row)">评定</el-button>
              <template v-else>
                <el-button type="text" @click="handleDetail(scope.row.id)">详情</el-button>
              </template>
              <!-- 已提交状态 -->
              <template v-else-if="scope.row.status === '已提交'">
                <el-button type="text" @click="handleDetail(scope.row.id)">详情</el-button>
                <el-button
                  v-if="scope.row.status === 2"
                  type="text"
                  @click="handleEvaluate(scope.row)"
                >评定</el-button>
              </template>
            </template>
            <!-- 草稿箱 -->
            <template v-else>
              <el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
              <el-button type="text" @click="handleDetail(scope.row.id)">详情</el-button>
              <el-button type="text" @click="handleDelete(scope.row)">删除</el-button>
            </template>
          </template>
        </el-table-column>
      </template>
    </TableCustom>
    <ShowDelConfirm
      :title="changeStatusTitle"
      :tip="changeStatusTip"
      :show="changeStatus"
      @close="changeStatus = false"
      @confirm="handleChangeStatusConfirm"
    />
    <!-- 评价弹窗 -->
    <evaluation-dialog
      :modelValue="evaluationDialogVisible"
      :type="'processEngineer'"
      :viewJson="currentEvaluationData"
      @update:modelValue="updateEvaluationDialogVisible"
      @submit="handleEvaluationSubmit"
    />
  </div>
</template>
<script>
import { getList,deleteById,commit,evaluateProcess } from './service';
import ShowDelConfirm from "@/components/showDelConfirm/index.vue";
import EvaluationDialog from "./components/evaluation-dialog.vue";
import moment from "moment";
export default {
  name: "TestResultReport",
  components: {
    ShowDelConfirm,
    EvaluationDialog
  },
  data() {
    return {
      currentType: "list", // 当前显示类型:list-列表,draft-草稿箱
      dateRange: [], // 日期范围
      form: {
        projectPlan: "",
        experimentNo: "",
        projectName: "",
        experimentCode: "",
        experimentName: "",
        createTime: [],
        status: ""
        startTime: "",
        endTime: "",
        status: "",
        pageNum: 1,
        pageSize: 10
      },
      tableData: [],
      total: 0,
      // 正式列表数据
      mockListData: [
        {
          id: '1',
          projectPlan: '名称名称名称',
          experimentNo: '31423764',
          experimentName: '名称名称名称',
          engineer: '李治悦',
          chemist: '刘大大',
          engineerApproved: '否',
          experimenter: '周乐心; 张瑞瑞',
          experimenterApproved: '否',
          createTime: '2025-1-2 16:27:17',
          status: '待提交'
        },
        {
          id: '2',
          projectPlan: '高性能材料研究',
          experimentNo: '31423765',
          experimentName: '材料强度测试',
          engineer: '赵雨',
          chemist: '王泽',
          engineerApproved: '是',
          experimenter: '李明; 张华',
          experimenterApproved: '是',
          createTime: '2025-1-2 16:30:17',
          status: '已提交'
        },
        {
          id: '3',
          projectPlan: '新型合金开发',
          experimentNo: '31423766',
          experimentName: '合金性能分析',
          engineer: '杨静',
          chemist: '陈亮',
          engineerApproved: '是',
          experimenter: '王刚',
          experimenterApproved: '否',
          createTime: '2025-1-2 16:35:17',
          status: '待评定'
        }
      ],
      // 草稿箱数据
      mockDraftData: [
        {
          id: '4',
          projectPlan: '环保材料研究',
          experimentNo: '31423767',
          experimentName: '材料降解测试',
          engineer: '张伟',
          chemist: '李强',
          engineerApproved: '否',
          experimenter: '王芳',
          experimenterApproved: '否',
          createTime: '2025-1-2 16:40:17',
          status: '草稿'
        },
        {
          id: '5',
          projectPlan: '纳米材料开发',
          experimentNo: '31423768',
          experimentName: '纳米结构分析',
          engineer: '刘洋',
          chemist: '周杰',
          engineerApproved: '否',
          experimenter: '孙明',
          experimenterApproved: '否',
          createTime: '2025-1-2 16:45:17',
          status: '草稿'
        }
      ]
      // 确认弹窗相关数据
      changeStatus: false,
      changeStatusTitle: "",
      changeStatusTip: "",
      currentOperationRow: null,
      currentOperationType: '',
      // 评价弹窗相关数据
      evaluationDialogVisible: false,
      currentEvaluationData: null,
    };
  },
  computed: {
    isProcessEngineer() {
      const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}');
      return userInfo.roleType === 3; // 3是工艺工程师
    }
  },
  created() {
    this.getTableData();
@@ -213,12 +195,16 @@
  methods: {
    resetForm() {
      this.form = {
        projectPlan: "",
        experimentNo: "",
        projectName: "",
        experimentCode: "",
        experimentName: "",
        createTime: [],
        status: ""
        startTime: "",
        endTime: "",
        status: "",
        pageNum: 1,
        pageSize: 10
      };
      this.dateRange = [];
    },
    handleSearch() {
      this.getTableData();
@@ -227,7 +213,6 @@
      this.$router.push({
        path: "/dataManagement/testResultReport/detail",
        query: { 
          id: 'new',
          type: 'add'
        }
      });
@@ -251,49 +236,161 @@
      });
    },
    handleSubmit(row) {
      this.$confirm('确认提交该实验结果?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // TODO: 调用提交接口
        this.$message.success('提交成功');
        this.getTableData();
      }).catch(() => {});
      this.currentOperationRow = row;
      this.currentOperationType = 'submit';
      this.changeStatusTitle = "确认提交?";
      this.changeStatusTip = "提交之后无法再次编辑";
      this.changeStatus = true;
    },
    handleDelete(row) {
      this.$confirm('确认删除该实验结果?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // TODO: 调用删除接口
        this.$message.success('删除成功');
        this.getTableData();
      }).catch(() => {});
      this.currentOperationRow = row;
      this.currentOperationType = 'delete';
      this.changeStatusTitle = "确认要删除这条信息吗?";
      this.changeStatusTip = "删除后信息无法找回";
      this.changeStatus = true;
    },
    handleEvaluate(row) {
      this.$router.push({
        path: "/dataManagement/testResultReport/detail",
        query: {
          id: row.id,
          type: 'evaluate'
        }
      });
      this.currentOperationRow = row;
      this.evaluationDialogVisible = true;
    },
    handleTypeChange(type) {
      this.currentType = type;
      this.getTableData();
    },
    getTableData() {
      // 根据currentType获取不同的数据
      if (this.currentType === 'list') {
        this.tableData = this.mockListData;
        this.total = this.mockListData.length;
      const params = {
        ...this.form,
        status: this.currentType === 'draft' ? -1 : this.form.status
      };
      getList(params).then(res => {
        if (res.code === 200) {
          this.tableData = res.data.records || [];
          this.total = res.data.total || 0;
        } else {
          this.$message.error(res.msg || '获取数据失败');
        }
      }).catch(err => {
        this.$message.error('获取数据失败');
      });
    },
    handleDateChange(val) {
      if (val) {
        this.form.startTime = val[0];
        this.form.endTime = val[1];
      } else {
        this.tableData = this.mockDraftData;
        this.total = this.mockDraftData.length;
        this.form.startTime = '';
        this.form.endTime = '';
      }
    },
    getStatusType(status) {
      const statusMap = {
        '-1': 'info',
        '1': 'warning',
        '2': 'warning',
        '3': 'success',
        '4': 'info',
        '5': 'warning'
      };
      return statusMap[status] || 'info';
    },
    getStatusText(status) {
      const statusMap = {
        '-1': '草稿箱',
        '1': '待提交',
        '2': '待评定',
        '3': '已评定',
        '4': '已封存',
        '5': '已解封'
      };
      return statusMap[status] || '未知';
    },
    handlePageChange(pageNum) {
      this.form.pageNum = pageNum;
      this.getTableData();
    },
    handleSizeChange(pageSize) {
      this.form.pageSize = pageSize;
      this.getTableData();
    },
    handleChangeStatusConfirm() {
      if (!this.currentOperationRow) return;
      if (this.currentOperationType === 'submit') {
        commit({ id: this.currentOperationRow.id }).then(res => {
          if (res) {
            this.$message.success('提交成功');
            this.changeStatus = false;
            this.getTableData();
          } else {
            this.$message.error(res.msg || '提交失败');
          }
        }).catch(err => {
          this.$message.error('提交失败');
        });
      } else if (this.currentOperationType === 'delete') {
        deleteById({ id: this.currentOperationRow.id }).then(res => {
          if (res) {
            this.$message.success('删除成功');
            this.changeStatus = false;
            this.getTableData();
          } else {
            this.$message.error(res.msg || '删除失败');
          }
        }).catch(err => {
          this.$message.error('删除失败');
        });
      }
    },
    // 更新弹窗显示状态
    updateEvaluationDialogVisible(value) {
      this.evaluationDialogVisible = value;
      if (!value) {
        this.currentEvaluationData = null;
      }
    },
    // 处理评价提交
    handleEvaluationSubmit(evaluationData) {
      const { activeIndex } = evaluationData;
      // 将评分数据转换为后端需要的格式
      const evaluateData = {
        evaluateType: 1, // 1=工艺工程师
        evaluateOne: this.getEvaluateValue(activeIndex[0].score),
        evaluateTwo: this.getEvaluateValue(activeIndex[1].score),
        evaluateThree: this.getEvaluateValue(activeIndex[2].score),
        evaluateFour: this.getEvaluateValue(activeIndex[3].score),
        evaluateFive: this.getEvaluateValue(activeIndex[4].score),
        evaluateSix: this.getEvaluateValue(activeIndex[5].score),
        evaluateTime: moment().format('YYYY-MM-DD HH:mm:ss'),
        resultEvaluateJson: JSON.stringify(activeIndex),
        resultReportId: this.currentOperationRow.id,
        dispatchId: this.currentOperationRow.dispatchId,
        status: 1
      };
      console.log('evaluateData',evaluateData)
      evaluateProcess(evaluateData).then(res => {
        if (res.code == 200) {
          this.$message.success('评定成功');
          this.evaluationDialogVisible = false;
          this.getTableData(); // 重新获取列表数据
        } else {
          this.$message.error(res.msg || '评定失败');
        }
      }).catch(err => {
        this.$message.error('评定失败');
      });
    },
    // 将分数转换为评定值
    getEvaluateValue(score) {
      // 2分 = 良好(1), 1分 = 正确(2), 0分 = 失误(3)
      const scoreMap = {
        2: 1, // 良好
        1: 2, // 正确
        0: 3  // 失误
      };
      return scoreMap[score] || 3; // 默认返回失误
    }
  }
};
@@ -312,33 +409,29 @@
  padding-bottom: 20px;
  justify-content: space-between;
  align-items: center;
  .title {
  .title, .drafts {
    background: #fafafc;
    border-radius: 8px 8px 0px 0px;
    border: 1px solid #dcdfe6;
    padding: 16px 29px;
    font-weight: bold;
    font-size: 18px;
    color: #606266;
    width: unset;
    cursor: pointer;
    font-weight: 400;
  }
  .title {
    padding: 16px 29px;
  }
  .drafts {
    padding: 16px 65px;
    background: #fafafc;
    border-radius: 8px 8px 0px 0px;
    border: 1px solid #dcdfe6;
    font-weight: 400;
    font-size: 18px;
    color: #606266;
    margin-left: 16px;
    cursor: pointer;
  }
  .active {
    color: #049c9a;
    background: #ffffff;
    border-radius: 8px 8px 0px 0px;
    border: 1px solid #049c9a;
    font-weight: bold;
  }
}
</style> 
laboratory/src/views/dataManagement/testResultReport/service.js
New file
@@ -0,0 +1,52 @@
import axios from '@/utils/request';
// 列表
export const getList = (data) => {
  return axios.post('/api/t-experiment-result-report/pageList', { ...data })
}
// 详情
export const getDetail = (data) => {
  return axios.get('/open/t-experiment-result-report/getDetailById', { params:data })
}
//添加
export const add = (data) => {
  return axios.post('/api/t-experiment-result-report/add', { ...data })
}
//修改
export const update = (data) => {
  return axios.post('/api/t-experiment-result-report/update', { ...data })
}
//删除
export const deleteById = (data) => {
  return axios.delete('/open/t-experiment-result-report/deleteById', { params:data })
}//删除
export const commit = (data) => {
  return axios.get('/open/t-experiment-result-report/commit', { params:data })
}
//批量删除
export const deleteByIds = (data) => {
  return axios.delete('/open/t-experiment-result-report/deleteByIds', { params:data })
}
// 获取实验结果汇报评定列表-审批人使用
export const evaluatePageList = (data) => {
  return axios.post('/api/t-experiment-result-report/evaluatePageList', { ...data })
}
// 评定工艺工程师实验
export const evaluateProcess = (data) => {
  return axios.post('/api/t-experiment-result-report/evaluateProcess', { ...data })
}
// 通过实验调度id获取实验结果、检验结果、评价信息、参与人员信息
export const getOtherInfoByDispatchId = (data) => {
  return axios.get('/open/t-experiment-result-report/getOtherInfoByDispatchId', { params:data })
}
// 实验方案详情
export const getExperimentDetail = (data) => {
  return axios.get('/open/t-experiment-scheme/getDetailById', { params:data })
}
// 通过实验调度查询查询组别列表
export const getGroupByDispatchId = (data) => {
  return axios.get('/open/t-experiment-scheme/getGroupByDispatchId', { params:data })
}