董国庆
2025-05-09 757cc54560ed87962bc36218536aaa769680cc81
项目课题方案审批对接口列表添加
7个文件已修改
961 ■■■■■ 已修改文件
laboratory/src/components/AiEditor/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/components/approvalProcess/index.vue 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/utils/request.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/approvalPlan/addPlan.vue 227 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/approvalPlan/components/approvalDialog.vue 256 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/approvalPlan/list.vue 296 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/dataManagement/approvalPlan/service.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/components/AiEditor/index.vue
@@ -60,10 +60,14 @@
      },
      immediate: true
    },
    readOnly(newVal) {
      if (this.editor) {
        this.editor.setReadOnly(newVal)
      }
    readOnly: {
      handler(newVal) {
        console.log('readOnly', newVal)
        if (this.editor) {
          this.editor.setReadOnly(newVal)
        }
      },
      immediate: true
    }
  },
  mounted() {
laboratory/src/components/approvalProcess/index.vue
@@ -6,32 +6,40 @@
        :key="index"
        :type="activity.type"
      >
        <div v-if="activity.mode && activity.mode == 'card'">
          <div class="member-list-card" v-for="item in 3" :key="item">
        <div v-if="activity.mode === 'card'">
          <div
            class="member-list-card"
            v-for="(group, groupIndex) in activity.groups"
            :key="groupIndex"
          >
            <div class="member-item">
              <div class="member-title">
                {{ ["工艺工程师", "实验员", "化验师"][item - 1] }}
                {{ group.title }}
              </div>
              <div class="flex-over">
                <div class="people-list" v-for="item in 10" :key="item">
                <div
                  class="people-list"
                  v-for="(member, memberIndex) in group.members"
                  :key="memberIndex"
                >
                  <div class="people-item">
                    <img src="" alt="" class="people-img" />
                    <div class="member-name">{{ item }}</div>
                    <img :src="member.avatar" alt="" class="people-img" />
                    <div class="member-name">{{ member.name }}</div>
                  </div>
                  <div class="member-status">
                    <div
                      class="member-status-text"
                      :class="
                        activity.type == 'success' ? 'success' : 'warning'
                        member.status === 'approved' ? 'success' : 'warning'
                      "
                    >
                      {{ activity.type == "success" ? "同意" : "待审批" }}
                      {{ member.status === "approved" ? "同意" : "待审批" }}
                    </div>
                    <div
                      v-if="activity.type == 'success'"
                      v-if="member.status === 'approved'"
                      class="member-status-time"
                    >
                      2025-04-08 12:30
                      {{ member.approveTime }}
                    </div>
                  </div>
                </div>
@@ -42,11 +50,15 @@
        <div
          v-else
          class="approval-process-item"
          :class="activity.type == 'primary' ? '' : 'approval-process-item1'"
          :class="activity.type === 'primary' ? '' : 'approval-process-item1'"
        >
          <div class="approval-process-item-name">提交人:李雷雷</div>
          <div class="approval-process-item-time">
            提交时间:2020-12-01 12:30
          <div
            v-for="(field, idx) in activity.fields"
            :key="idx"
            style="margin-bottom: 6px"
          >
            <span>{{ field.label }}</span>
            <span>{{ field.value }}</span>
          </div>
        </div>
      </el-timeline-item>
@@ -58,58 +70,77 @@
export default {
  name: "ApprovalProcess",
  props: {
    status: {
      type: String,
      default: "approved", // pending-等待审核, approved-已通过
      validator: (value) => ["pending", "approved"].includes(value),
    },
    submitTime: {
      type: String,
      default: "",
    },
    approver: {
      type: String,
      default: "",
    },
    approveTime: {
      type: String,
      default: "",
    },
    mode: {
      type: String,
      default: "",//card-就是卡片模式,其他就是列表模式
    },
  },
  computed: {
    processData() {
      const baseData = [
        {
          content: "提交审批",
          time: this.submitTime,
          type: "primary",
        },
      ];
      if (this.status === "approved") {
        console.log("111111111111111", this.status);
        baseData.push({
          content: `${this.approver}审批通过`,
          time: this.approveTime,
          type: "success",
          mode: this.mode,
        });
      } else {
        console.log("122222222222222221", this.status);
        baseData.push({
          content: "等待审核",
          time: this.submitTime,
          type: "warning",
          mode: this.mode,
        });
      }
      return baseData;
    processData: {
      type: Array,
      required: true,
      // 数据结构示例:
      // [
      //   {
      //     type: 'primary',
      //     content: '提交审批',
      //     time: '2020-12-01 12:30',
      //     mode: 'list'
      //   },
      //   {
      //     type: 'success',
      //     mode: 'card',
      //     groups: [
      //       {
      //         title: '工艺工程师',
      //         members: [
      //           {
      //             name: '张三',
      //             avatar: '',
      //             status: 'approved',
      //             approveTime: '2025-04-08 12:30'
      //           }
      //         ]
      //       }
      //     ]
      //   }
      // ]
      // 数据结构示例:
      //       [
      //   {
      //     type: 'success',
      //     mode: 'card',
      //     groups: [
      //       {
      //         title: '工艺工程师',
      //         members: [
      //           {
      //             fields: [
      //               { label: '姓名', value: '张三' },
      //               { label: '状态', value: '同意' },
      //               { label: '审批时间', value: '2025-04-08 12:30' }
      //             ],
      //             avatar: '' // 头像地址,可选
      //           },
      //           {
      //             fields: [
      //               { label: '姓名', value: '李四' },
      //               { label: '状态', value: '待审批' }
      //             ],
      //             avatar: ''
      //           }
      //         ]
      //       },
      //       {
      //         title: '实验员',
      //         members: [
      //           {
      //             fields: [
      //               { label: '姓名', value: '王五' },
      //               { label: '状态', value: '同意' },
      //               { label: '审批时间', value: '2025-04-08 13:00' }
      //             ],
      //             avatar: ''
      //           }
      //         ]
      //       }
      //     ]
      //   }
      // ]
    },
  },
};
@@ -230,7 +261,7 @@
        text-align: left;
        padding-left: 17px;
      }
      .flex-over{
      .flex-over {
        margin-top: 12px;
        flex: 1;
        overflow: auto;
@@ -242,7 +273,7 @@
        align-items: center;
        padding: 0 20px;
        margin-top: 12px;
        display: flex;
        .people-item {
          display: flex;
laboratory/src/utils/request.js
@@ -57,7 +57,6 @@
    }
    if (res.data.code == 200) {
      console.log('res',res)
      if (!res.data) {
        return Promise.resolve({})
      }
laboratory/src/views/dataManagement/approvalPlan/addPlan.vue
@@ -15,14 +15,18 @@
        label-position="top"
        style="margin-top: 38px"
      >
        <el-form-item prop="name" label="项目课题方案名称">
          <el-input v-model="form.name" placeholder="请输入" />
        <el-form-item prop="projectName" label="项目课题方案名称">
          <el-input v-model="form.projectName" placeholder="请输入" />
        </el-form-item>
        <el-form-item prop="description" label="项目阶段">
          <el-input v-model="form.description" placeholder="请输入" />
        <el-form-item prop="projectStage" label="项目阶段">
          <el-select v-model="form.projectStage" placeholder="请选择">
            <el-option label="实验室开发阶段" :value="1" />
            <el-option label="中式试验阶段" :value="2" />
            <el-option label="生产验证试验阶段" :value="3" />
          </el-select>
        </el-form-item>
        <el-form-item prop="description" label="项目课题方案编号">
          <el-input v-model="form.description" placeholder="请输入" />
        <el-form-item prop="projectCode" label="项目课题方案编号">
          <el-input v-model="form.projectCode" placeholder="请输入" disabled />
        </el-form-item>
      </el-form>
      <div class="header-title">
@@ -33,7 +37,7 @@
      </div>
      <AiEditor
        ref="purposeEditor"
        v-model="editorContents.purpose"
        v-model="editorContents.experimentObjective"
        height="200px"
        placeholder="请输入实验目的..."
      />
@@ -48,7 +52,7 @@
      </div>
      <AiEditor
        ref="materialEditor"
        v-model="editorContents.material"
        v-model="editorContents.experimentMaterial"
        height="200px"
        placeholder="请输入实验材料..."
      />
@@ -57,7 +61,7 @@
      </div>
      <AiEditor
        ref="equipmentEditor"
        v-model="editorContents.equipment"
        v-model="editorContents.experimentDevice"
        height="200px"
        placeholder="请输入实验设备..."
      />
@@ -69,7 +73,7 @@
      </div>
      <AiEditor
        ref="methodEditor"
        v-model="editorContents.method"
        v-model="editorContents.experimentTestMethod"
        height="200px"
        placeholder="请输入检测方法及开发..."
      />
@@ -81,7 +85,7 @@
      </div>
      <AiEditor
        ref="stepsEditor"
        v-model="editorContents.steps"
        v-model="editorContents.experimentProcedure"
        height="200px"
        placeholder="请输入实验步骤..."
      />
@@ -93,7 +97,7 @@
      </div>
      <AiEditor
        ref="dataAnalysisEditor"
        v-model="editorContents.dataAnalysis"
        v-model="editorContents.dataAcquisition"
        height="200px"
        placeholder="请输入数据采集及分析..."
      />
@@ -105,7 +109,7 @@
      </div>
      <AiEditor
        ref="evaluationEditor"
        v-model="editorContents.evaluation"
        v-model="editorContents.resultEvaluation"
        height="200px"
        placeholder="请输入结果评估..."
      />
@@ -117,7 +121,7 @@
      </div>
      <AiEditor
        ref="notesEditor"
        v-model="editorContents.notes"
        v-model="editorContents.precautions"
        height="200px"
        placeholder="请输入注意事项..."
      />
@@ -132,7 +136,7 @@
<script>
import AiEditor from '@/components/AiEditor'
// import { savePlan, saveDraft } from '@/api/approvalPlan'
import { addProposal, updateProposal, getDetailById } from './service'
export default {
  name: "AddProject",
@@ -141,57 +145,60 @@
  },
  data() {
    return {
      id: '', // 用于编辑时存储id
      form: {
        name: '',
        description: '',
        purpose: '',
        material: '',
        equipment: '',
        method: '',
        steps: '',
        dataAnalysis: '',
        evaluation: '',
        notes: ''
        projectName: '',
        projectStage: '',
        projectCode: '',
        experimentObjective: '',
        experimentMaterial: '',
        experimentDevice: '',
        experimentTestMethod: '',
        experimentProcedure: '',
        dataAcquisition: '',
        resultEvaluation: '',
        precautions: '',
        auditStatus: 1, // 默认为审批中
      },
      editorContents: {
        purpose: '',
        material: '',
        equipment: '',
        method: '',
        steps: '',
        dataAnalysis: '',
        evaluation: '',
        notes: ''
        experimentObjective: '',
        experimentMaterial: '',
        experimentDevice: '',
        experimentTestMethod: '',
        experimentProcedure: '',
        dataAcquisition: '',
        resultEvaluation: '',
        precautions: ''
      },
      rules: {
        name: [
          { required: true, message: "请输入项目组名称", trigger: "blur" },
        projectName: [
          { required: true, message: "请输入项目课题方案名称", trigger: "blur" },
        ],
        description: [
          { required: true, message: "请输入项目组描述", trigger: "blur" },
        projectStage: [
          { required: true, message: "请选择项目阶段", trigger: "change" },
        ],
        purpose: [
        experimentObjective: [
          { required: true, message: "请输入实验目的", trigger: "blur" },
        ],
        material: [
        experimentMaterial: [
          { required: true, message: "请输入实验材料", trigger: "blur" },
        ],
        equipment: [
        experimentDevice: [
          { required: true, message: "请输入实验设备", trigger: "blur" },
        ],
        method: [
        experimentTestMethod: [
          { required: true, message: "请输入检测方法及开发", trigger: "blur" },
        ],
        steps: [
        experimentProcedure: [
          { required: true, message: "请输入实验步骤", trigger: "blur" },
        ],
        dataAnalysis: [
        dataAcquisition: [
          { required: true, message: "请输入数据采集及分析", trigger: "blur" },
        ],
        evaluation: [
        resultEvaluation: [
          { required: true, message: "请输入结果评估", trigger: "blur" },
        ],
        notes: [
        precautions: [
          { required: true, message: "请输入注意事项", trigger: "blur" },
        ],
      },
@@ -201,40 +208,130 @@
    // 获取所有编辑器的内容
    getAllEditorContent() {
      return {
        purpose: this.$refs.purposeEditor.getContent(),
        material: this.$refs.materialEditor.getContent(),
        equipment: this.$refs.equipmentEditor.getContent(),
        method: this.$refs.methodEditor.getContent(),
        steps: this.$refs.stepsEditor.getContent(),
        dataAnalysis: this.$refs.dataAnalysisEditor.getContent(),
        evaluation: this.$refs.evaluationEditor.getContent(),
        notes: this.$refs.notesEditor.getContent()
        experimentObjective: this.$refs.purposeEditor.getContent(),
        experimentMaterial: this.$refs.materialEditor.getContent(),
        experimentDevice: this.$refs.equipmentEditor.getContent(),
        experimentTestMethod: this.$refs.methodEditor.getContent(),
        experimentProcedure: this.$refs.stepsEditor.getContent(),
        dataAcquisition: this.$refs.dataAnalysisEditor.getContent(),
        resultEvaluation: this.$refs.evaluationEditor.getContent(),
        precautions: this.$refs.notesEditor.getContent()
      }
    },
    // 保存
    handleSave() {
    // 统一处理方法
    handleSubmit(type) {
      this.$refs.form.validate((valid) => {
        if (valid) {
          // 获取所有编辑器内容
          const editorContents = this.getAllEditorContent()
          // 检查编辑器内容是否为空
          const emptyFields = []
          console.log('editorContents', editorContents)
          // 判断内容是否为空(排除<p></p>)
          const isEmptyContent = (content) => {
            return !content || content === '<p></p>' || content.trim() === '<p></p>'
          }
          if (isEmptyContent(editorContents.experimentObjective)) emptyFields.push('实验目的')
          if (isEmptyContent(editorContents.experimentMaterial)) emptyFields.push('实验材料')
          if (isEmptyContent(editorContents.experimentDevice)) emptyFields.push('实验设备')
          if (isEmptyContent(editorContents.experimentTestMethod)) emptyFields.push('检测方法及开发')
          if (isEmptyContent(editorContents.experimentProcedure)) emptyFields.push('实验步骤')
          if (isEmptyContent(editorContents.dataAcquisition)) emptyFields.push('数据采集及分析')
          if (isEmptyContent(editorContents.resultEvaluation)) emptyFields.push('结果评估')
          if (isEmptyContent(editorContents.precautions)) emptyFields.push('注意事项')
          if (emptyFields.length > 0) {
            this.$message.warning(`请填写${emptyFields.join('、')}`)
            return false
          }
          const formData = {
            ...this.form,
            ...this.getAllEditorContent()
            ...editorContents,
            auditStatus: type === 'draft' ? -1 : 1 // 草稿箱:-1, 审批中:1
          }
          console.log('保存数据:', formData)
          this.$message.success('保存成功')
          const request = this.id ? updateProposal : addProposal
          if (this.id) {
            formData.id = this.id
          }
          console.log('请求参数:', {
            formData
          })
          request(formData).then(res => {
            console.log('接口返回:', res)
            if (res.code === 200) {
              const successMsg = type === 'draft' ? '草稿保存成功' : (this.id ? '更新成功' : '保存成功')
              this.$message.success(successMsg)
              this.$router.back()
            } else {
              const errorMsg = type === 'draft' ? '草稿保存失败' : (this.id ? '更新失败' : '保存失败')
              this.$message.error(res.msg || errorMsg)
            }
          }).catch(err => {
            console.error('接口错误:', err)
            const errorMsg = type === 'draft' ? '草稿保存失败' : (this.id ? '更新失败' : '保存失败')
            this.$message.error(errorMsg)
          })
        } else {
          this.$message.warning('请填写必填项')
          return false
        }
      })
    },
    // 保存
    handleSave() {
      this.handleSubmit('save')
    },
    // 保存草稿
    handleSaveDraft() {
      const formData = {
        ...this.form,
        ...this.getAllEditorContent(),
        status: 'draft'
      }
      console.log('草稿数据:', formData)
      this.$message.success('草稿保存成功')
      this.handleSubmit('draft')
    },
    // 获取详情
    getDetail() {
      if (this.id) {
        console.log('获取详情参数:', { id: this.id })
        getDetailById({ id: this.id }).then(res => {
          console.log('详情接口返回:', res)
          if (res.code === 200 && res.data) {
            const data = res.data
            // 设置表单数据
            this.form = {
              projectName: data.projectName,
              projectStage: data.projectStage,
              projectCode: data.projectCode,
              auditStatus: data.auditStatus
            }
            // 设置编辑器内容
            this.editorContents = {
              experimentObjective: data.experimentObjective,
              experimentMaterial: data.experimentMaterial,
              experimentDevice: data.experimentDevice,
              experimentTestMethod: data.experimentTestMethod,
              experimentProcedure: data.experimentProcedure,
              dataAcquisition: data.dataAcquisition,
              resultEvaluation: data.resultEvaluation,
              precautions: data.precautions
            }
          }
        }).catch(err => {
          console.error('获取详情失败:', err)
        })
      }
    }
  },
  created() {
    // 从路由参数中获取id
    this.id = this.$route.query.id
    if (this.id) {
      this.getDetail()
    }
  }
};
</script>
laboratory/src/views/dataManagement/approvalPlan/components/approvalDialog.vue
@@ -25,14 +25,30 @@
              label-position="top"
              style="margin-top: 38px"
            >
              <el-form-item prop="name" label="项目课题方案名称">
                <el-input v-model="form.name" placeholder="请输入" />
              <el-form-item prop="projectName" label="项目课题方案名称">
                <el-input
                  v-model="form.projectName"
                  placeholder="请输入"
                  disabled
                />
              </el-form-item>
              <el-form-item prop="description" label="项目阶段">
                <el-input v-model="form.description" placeholder="请输入" />
              <el-form-item prop="projectStage" label="项目阶段">
                <el-select
                  v-model="form.projectStage"
                  placeholder="请选择"
                  disabled
                >
                  <el-option label="实验室开发阶段" :value="1" />
                  <el-option label="中式试验阶段" :value="2" />
                  <el-option label="生产验证试验阶段" :value="3" />
                </el-select>
              </el-form-item>
              <el-form-item prop="description" label="项目课题方案编号">
                <el-input v-model="form.description" placeholder="请输入" />
              <el-form-item prop="projectCode" label="项目课题方案编号">
                <el-input
                  v-model="form.projectCode"
                  placeholder="请输入"
                  disabled
                />
              </el-form-item>
            </el-form>
            <div class="header-title">
@@ -41,6 +57,12 @@
                <div>一 、实验目的</div>
              </div>
            </div>
            <AiEditor
              ref="purposeEditor"
              :value="form.experimentObjective"
              height="200px"
              :readOnly="true"
            />
            <div class="header-title">
              <div class="header-title-left">
                <img src="@/assets/public/headercard.png" />
@@ -50,53 +72,88 @@
            <div class="item-title">
              <span>1.实验材料</span>
            </div>
            <AiEditor
              ref="materialEditor"
              :value="form.experimentMaterial"
              height="200px"
              :readOnly="true"
            />
            <div class="item-title">
              <span>2.实验设备</span>
            </div>
            <AiEditor
              ref="equipmentEditor"
              :value="form.experimentDevice"
              height="200px"
              :readOnly="true"
            />
            <div class="header-title">
              <div class="header-title-left">
                <img src="@/assets/public/headercard.png" />
                <div>三 、检测方法及开发</div>
              </div>
            </div>
            <AiEditor
              ref="methodEditor"
              :value="form.experimentTestMethod"
              height="200px"
              :readOnly="true"
            />
            <div class="header-title">
              <div class="header-title-left">
                <img src="@/assets/public/headercard.png" />
                <div>四 、实验步骤</div>
              </div>
            </div>
            <AiEditor
              ref="stepsEditor"
              :value="form.experimentProcedure"
              height="200px"
              :readOnly="true"
            />
            <div class="header-title">
              <div class="header-title-left">
                <img src="@/assets/public/headercard.png" />
                <div>五 、数据采集及分析</div>
              </div>
            </div>
            <AiEditor
              ref="dataAnalysisEditor"
              :value="form.dataAcquisition"
              height="200px"
              :readOnly="true"
            />
            <div class="header-title">
              <div class="header-title-left">
                <img src="@/assets/public/headercard.png" />
                <div>六 、结果评估</div>
              </div>
            </div>
            <AiEditor
              ref="evaluationEditor"
              :value="form.resultEvaluation"
              height="200px"
              :readOnly="true"
            />
            <div class="header-title">
              <div class="header-title-left">
                <img src="@/assets/public/headercard.png" />
                <span>注意事项</span>
              </div>
            </div>
            <AiEditor
              ref="notesEditor"
              :value="form.precautions"
              height="200px"
              :readOnly="true"
            />
          </template>
          <SelectMember ref="selectMember" />
        </Card>
      </div>
      <!-- 右侧审批流程 -->
      <div class="approval-flow">
        <div class="flow-content">
          <approval-process
            :status="form.status"
            :submit-time="form.createTime"
            :approver="form.approver"
            :approve-time="form.approveTime"
          />
          <approval-process :processData="form.processData" />
        </div>
      </div>
    </div>
@@ -122,12 +179,20 @@
      </div>
      <div class="remark">
        <div class="remark-title">审批意见</div>
        <el-input type="textarea" v-model="remark" placeholder="请输入审批意见"   />
        <el-input
          type="textarea"
          v-model="remark"
          placeholder="请输入审批意见"
        />
      </div>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleClose">取 消</el-button>
      <el-button type="primary" @click="handleApprove" v-if="type === 'approve'"
      <el-button
        type="primary"
        style="margin-left: 20px"
        @click="handleApprove"
        v-if="type === 'approve'"
        >通过</el-button
      >
    </div>
@@ -135,12 +200,15 @@
</template>
<script>
import ApprovalProcess from '@/components/approvalProcess'
import ApprovalProcess from "@/components/approvalProcess";
import { getDetailById, audit } from "../service";
import AiEditor from "@/components/AiEditor";
export default {
  name: "ApprovalDialog",
  components: {
    ApprovalProcess
    ApprovalProcess,
    AiEditor,
  },
  props: {
    visible: {
@@ -159,17 +227,22 @@
  data() {
    return {
      form: {
        planName: "",
        planCode: "",
        stage: "",
        creator: "",
        projectName: "",
        projectCode: "",
        projectStage: "",
        experimentObjective: "",
        experimentMaterial: "",
        experimentDevice: "",
        experimentTestMethod: "",
        experimentProcedure: "",
        dataAcquisition: "",
        resultEvaluation: "",
        precautions: "",
        auditStatus: "",
        createTime: "",
        approvalComment: "",
        status: "pending",
        approver: "",
        approveTime: ""
        approveTime: "",
      },
      radio1: 1,
      rules: {},
      status: "1",
      remark: "",
@@ -181,39 +254,108 @@
    },
  },
  watch: {
    data: {
    visible: {
      handler(val) {
        if (val) {
          this.form = { ...val };
        console.log("visible", val, "22", this.data);
        if (val && this.data && this.data.id) {
          this.getDetail(this.data.id);
        }
      },
      immediate: true,
    },
  },
  methods: {
    // 获取详情
    getDetail(id) {
      console.log("获取详情参数:", { id });
      getDetailById({ id })
        .then((res) => {
          console.log("获取详情:", res);
          if (res) {
            this.form = { ...res };
            // 组装流程数据
            const processData = [];
            // 提交节点
            processData.push({
              type: "primary",
              mode: "list",
              fields: [
                { label: "提交人:", value: res.updateBy || "" },
                { label: "提交时间:", value: res.createTime || "" },
              ],
            });
            if (res.auditStatus == 2 || res.auditStatus == 3) {
              processData.push({
                type:
                  audit.status === 2
                    ? "success"
                    : audit.status === 3
                    ? "danger"
                    : "warning",
                mode: "list",
                fields: [
                  {
                    label: "审核结果",
                    value:
                      audit.status === 2
                        ? "通过"
                        : audit.status === 3
                        ? "驳回"
                        : "待审批",
                  },
                  { label: "审批意见:", value: audit.auditRemark || "" },
                  { label: "审核人:", value: audit.auditPersonName || "" },
                  { label: "审核时间:", value: audit.auditTime || "" },
                ],
              });
            }else{
              processData.push({
              type: "primary",
              mode: "list",
              fields: [
                { label: "等待审核"},
              ],
            });
            }
            // 如有卡片模式,按前述结构 push
            this.form.processData = processData;
          }
        })
        .catch((err) => {
          console.error("获取详情失败:", err);
          this.$message.error("获取详情失败");
        });
    },
    handleClose() {
      this.$emit("update:visible", false);
      this.form.approvalComment = "";
      this.remark = "";
      this.status = "1";
    },
    handleApprove() {
      if (!this.form.approvalComment) {
      if (!this.remark) {
        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",
      });
      const params = {
        id: this.form.id,
        auditStatus: this.status === "1" ? 2 : 3, // 2-通过,3-驳回
        auditComment: this.remark,
      };
      audit(params)
        .then((res) => {
          if (res.code === 200) {
            this.$message.success("审批成功");
            this.$emit("update:visible", false);
            this.$emit("success");
          } else {
            this.$message.error(res.msg || "审批失败");
          }
        })
        .catch((err) => {
          console.error("审批失败:", err);
          this.$message.error("审批失败");
        });
    },
  },
};
@@ -391,12 +533,20 @@
  }
}
.dialog-footer{
    align-items: center;
    display: flex;
    justify-content: center;
    button{
        width: 150px;
    }
.dialog-footer {
  align-items: center;
  display: flex;
  justify-content: center;
  button {
    width: 150px;
  }
}
</style>
.content-display {
  padding: 10px 20px;
  min-height: 100px;
  background: #f5f7fa;
  border-radius: 4px;
  margin: 10px 0;
}
</style>
laboratory/src/views/dataManagement/approvalPlan/list.vue
@@ -13,54 +13,42 @@
            <el-input v-model="form.createBy" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="创建时间:">
            <el-date-picker
              v-model="form.createTime"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              value-format="yyyy-MM-dd"
            ></el-date-picker>
            <el-date-picker v-model="form.createTime" type="daterange" range-separator="至" start-placeholder="开始日期"
              end-placeholder="结束日期" value-format="yyyy-MM-dd"></el-date-picker>
          </el-form-item>
          <el-form-item label="审批人:">
            <el-input v-model="form.auditPersonName" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="">
            <el-button type="default" @click="resetForm">重置</el-button>
            <el-button type="primary" @click="handleSearch" style="margin-left: 20px;">查询</el-button>
            <el-button type="primary" @click="handleSearch" style="margin-left: 20px">查询</el-button>
          </el-form-item>
        </el-form>
      </template>
      <template #setting>
        <div class="tableTitle">
          <div class="flex a-center">
            <div
            class="title"
              :class="{active:currentType === 'list'}"
              @click="handleTypeChange('list')"
            >项目课题方案列表</div>
            <div
            class="drafts"
              :class="{active:currentType === 'draft'}"
              @click="handleTypeChange('draft')"
            >草稿箱</div>
            <div class="title" :class="{ active: currentType === 'list' }" @click="handleTypeChange('list')">
              项目课题方案列表
            </div>
            <div v-if="isProcessEngineer" class="drafts" :class="{ active: currentType === 'draft' }"
              @click="handleTypeChange('draft')">
              草稿箱
            </div>
          </div>
          <el-button @click="handleAddPlan" class="el-icon-plus" type="primary">
            新增项目课题方案</el-button
          >
          <el-button v-if="isProcessEngineer" @click="handleAddPlan" class="el-icon-plus" type="primary">
            新增项目课题方案</el-button>
        </div>
      </template>
      <template #table>
        <el-table-column
          prop="projectCode"
          label="项目课题方案编号"
        ></el-table-column>
        <el-table-column
          prop="projectName"
          label="项目课题方案名称"
        ></el-table-column>
        <el-table-column prop="stage" label="项目阶段"></el-table-column>
        <el-table-column prop="createBy" label="创建人"></el-table-column>
        <el-table-column prop="projectCode" label="项目课题方案编号"></el-table-column>
        <el-table-column prop="projectName" label="项目课题方案名称"></el-table-column>
        <el-table-column prop="projectStage" label="项目阶段">
          <template slot-scope="scope">
            {{ getProjectStageText(scope.row.projectStage) }}
          </template>
        </el-table-column>
        <el-table-column prop="updateBy" label="创建人"></el-table-column>
        <el-table-column prop="createTime" label="创建日期"></el-table-column>
        <el-table-column prop="auditStatus" label="审批状态">
          <template slot-scope="scope">
@@ -73,60 +61,45 @@
        <el-table-column prop="auditTime" label="审批时间"></el-table-column>
        <el-table-column label="操作" width="250">
          <template slot-scope="scope">
            <el-button
              v-if="scope.row.auditStatus === 1"
              type="text"
              @click="handleApprove(scope.row)"
              >审批</el-button
            >
            <el-button
              v-if="scope.row.auditStatus === 2"
              type="text"
              @click="handleRevokeApprove(scope.row)"
              >撤销审批</el-button
            >
            <el-button
              v-if="scope.row.auditStatus === 3"
              type="text"
              @click="handleEdit(scope.row)"
              >编辑</el-button
            >
            <el-button
              v-if="scope.row.auditStatus === 3"
              type="text"
              @click="handleDelete(scope.row)"
              >删除</el-button
            >
            <el-button type="text" @click="handleDetail(scope.row)"
              >详情</el-button
            >
            <!-- 工艺工程师的按钮 -->
            <template v-if="isProcessEngineer">
              <el-button v-if="scope.row.auditStatus === 1" type="text"
                @click="handleRevokeApprove(scope.row)">撤销审批</el-button>
              <el-button v-if="scope.row.auditStatus === 3" type="text" @click="handleEdit(scope.row)">编辑</el-button>
              <el-button v-if="scope.row.auditStatus === 3" type="text" @click="handleDelete(scope.row)">删除</el-button>
              <el-button v-if="scope.row.auditStatus !== 1" type="text" @click="handleDetail(scope.row)">详情</el-button>
            </template>
            <!-- 审批人和超级管理员的按钮 -->
            <template v-else>
              <el-button v-if="scope.row.auditStatus === 1" type="text" @click="handleApprove(scope.row)">审批</el-button>
              <el-button v-if="scope.row.auditStatus !== 1" type="text" @click="handleDetail(scope.row)">详情</el-button>
            </template>
          </template>
        </el-table-column>
      </template>
    </TableCustom>
    <!-- 审批弹窗 -->
    <approval-dialog
      :visible.sync="approvalDialogVisible"
      :type="approvalDialogType"
      :data="currentApprovalData"
      @approve="handleApproveSubmit"
      @reject="handleRejectSubmit"
    />
    <approval-dialog :visible.sync="approvalDialogVisible" :type="approvalDialogType" :data="currentApprovalData"
      @approve="handleApproveSubmit" @reject="handleRejectSubmit" />
    <ShowDelConfirm :title="changeStatusTitle" :tip="changeStatusTip" :show="changeStatus"
      @close="changeStatus = false" @confirm="handleChangeStatusConfirm" />
  </div>
</template>
<script>
import ApprovalDialog from './components/approvalDialog.vue'
import { getProposalList } from './service'
import ShowDelConfirm from "@/components/showDelConfirm/index.vue";
import ApprovalDialog from "./components/approvalDialog.vue";
import { getProposalList } from "./service";
export default {
  name: "ProjectList",
  components: {
    ApprovalDialog
    ApprovalDialog,
    ShowDelConfirm
  },
  data() {
    return {
      currentType: 'list', // 当前显示类型:list-列表,draft-草稿箱
      currentType: "list", // 当前显示类型:list-列表,draft-草稿箱
      form: {
        projectName: "",
        projectCode: "",
@@ -137,69 +110,82 @@
        pageNum: 1,
        pageSize: 10,
        startTime: "",
        endTime: ""
        endTime: "",
      },
      tableData: [],
      total: 0,
      // 模拟数据
      mockListData: [
        {
          planCode: 'PLAN-2024-001',
          planName: '2024年度实验室设备升级方案',
          stage: '规划阶段',
          creator: '张三',
          createTime: '2024-03-15',
          status: 'pending',
          approver: '李四',
          approveTime: '2024-03-16'
          planCode: "PLAN-2024-001",
          planName: "2024年度实验室设备升级方案",
          stage: "规划阶段",
          creator: "张三",
          createTime: "2024-03-15",
          status: "pending",
          approver: "李四",
          approveTime: "2024-03-16",
        },
        {
          planCode: 'PLAN-2024-002',
          planName: '实验室安全管理制度更新方案',
          stage: '实施阶段',
          creator: '王五',
          createTime: '2024-03-14',
          status: 'approved',
          approver: '赵六',
          approveTime: '2024-03-15'
          planCode: "PLAN-2024-002",
          planName: "实验室安全管理制度更新方案",
          stage: "实施阶段",
          creator: "王五",
          createTime: "2024-03-14",
          status: "approved",
          approver: "赵六",
          approveTime: "2024-03-15",
        },
        {
          planCode: 'PLAN-2024-003',
          planName: '实验室人员培训计划',
          stage: '准备阶段',
          creator: '孙七',
          createTime: '2024-03-13',
          status: 'rejected',
          approver: '周八',
          approveTime: '2024-03-14'
        }
          planCode: "PLAN-2024-003",
          planName: "实验室人员培训计划",
          stage: "准备阶段",
          creator: "孙七",
          createTime: "2024-03-13",
          status: "rejected",
          approver: "周八",
          approveTime: "2024-03-14",
        },
      ],
      mockDraftData: [
        {
          planCode: 'DRAFT-2024-001',
          planName: '实验室设备采购计划(草稿)',
          stage: '规划阶段',
          creator: '张三',
          createTime: '2024-03-16',
          status: 'draft',
          approver: '',
          approveTime: ''
          planCode: "DRAFT-2024-001",
          planName: "实验室设备采购计划(草稿)",
          stage: "规划阶段",
          creator: "张三",
          createTime: "2024-03-16",
          status: "draft",
          approver: "",
          approveTime: "",
        },
        {
          planCode: 'DRAFT-2024-002',
          planName: '实验室改造方案(草稿)',
          stage: '准备阶段',
          creator: '李四',
          createTime: '2024-03-15',
          status: 'draft',
          approver: '',
          approveTime: ''
        }
          planCode: "DRAFT-2024-002",
          planName: "实验室改造方案(草稿)",
          stage: "准备阶段",
          creator: "李四",
          createTime: "2024-03-15",
          status: "draft",
          approver: "",
          approveTime: "",
        },
      ],
      approvalDialogVisible: false,
      approvalDialogType: 'approve',
      approvalDialogType: "approve",
      currentApprovalData: null,
      // 确认弹窗相关数据
      changeStatus: false,
      changeStatusTitle: "",
      changeStatusTip: "",
      currentOperationType: "", // 当前操作类型:revoke-撤销审批,delete-删除
      currentOperationRow: null, // 当前操作的行数据
    };
  },
  computed: {
    isProcessEngineer() {
      return false;
      // 这里需要根据实际的用户角色判断逻辑来修改
      return this.$store.state.user.role === 'processEngineer';
    }
  },
  created() {
    this.getTableData();
@@ -212,11 +198,11 @@
        createBy: "",
        createTime: [],
        auditPersonName: "",
        auditStatus: this.currentType === 'draft' ? -1 : 1,
        auditStatus: this.currentType === "draft" ? -1 : 1,
        pageNum: 1,
        pageSize: 10,
        startTime: "",
        endTime: ""
        endTime: "",
      };
    },
    handleSearch() {
@@ -231,12 +217,12 @@
    },
    getStatusType(status) {
      const statusMap = {
        1: "warning",   // 审批中
        2: "success",   // 已通过
        3: "danger",    // 已驳回
        4: "info",      // 已撤销
        5: "info",      // 已封存
        "-1": "info",   // 草稿
        1: "warning", // 审批中
        2: "success", // 已通过
        3: "danger", // 已驳回
        4: "info", // 已撤销
        5: "info", // 已封存
        "-1": "info", // 草稿
      };
      return statusMap[status] || "info";
    },
@@ -251,6 +237,14 @@
      };
      return statusMap[status] || "未知";
    },
    getProjectStageText(stage) {
      const stageMap = {
        1: "实验室开发阶段",
        2: "中式试验阶段",
        3: "生产验证试验阶段"
      };
      return stageMap[stage] || "未知阶段";
    },
    handleAddPlan() {
      this.$router.push({
        path: "/dataManagement/addPlan",
@@ -258,43 +252,49 @@
    },
    handleApprove(row) {
      this.currentApprovalData = row;
      this.approvalDialogType = 'approve';
      this.approvalDialogType = "approve";
      this.approvalDialogVisible = true;
    },
    handleApproveSubmit(data) {
      // 处理审批通过
      console.log('审批通过:', data);
      console.log("审批通过:", data);
      this.approvalDialogVisible = false;
      this.$message.success('审批通过成功');
      this.$message.success("审批通过成功");
      this.getTableData();
    },
    handleRejectSubmit(data) {
      // 处理审批驳回
      console.log('审批驳回:', data);
      console.log("审批驳回:", data);
      this.approvalDialogVisible = false;
      this.$message.success('审批驳回成功');
      this.$message.success("审批驳回成功");
      this.getTableData();
    },
    handleRevokeApprove(row) {
      // 实现撤销审批逻辑
      console.log("撤销审批数据:", row);
      this.currentOperationType = "revoke";
      this.currentOperationRow = row;
      this.changeStatusTitle = "确认要撤销这条审批吗?";
      this.changeStatusTip = "撤销后,审批人将无法收到此条审批信息"; // 这里可以根据实际需求修改提示文案
      this.changeStatus = true;
    },
    handleEdit(row) {
      // 实现编辑逻辑
      console.log("编辑数据:", row);
    },
    handleDelete(row) {
      // 实现删除逻辑
      console.log("删除数据:", row);
      this.currentOperationType = "delete";
      this.currentOperationRow = row;
      this.changeStatusTitle = "确认要删除这条信息吗?";
      this.changeStatusTip = "删除后信息无法找回"; // 这里可以根据实际需求修改提示文案
      this.changeStatus = true;
    },
    handleDetail(row) {
      this.currentApprovalData = row;
      this.approvalDialogType = 'view';
      this.approvalDialogType = "view";
      this.approvalDialogVisible = true;
    },
    handleTypeChange(type) {
      this.currentType = type;
      this.form.auditStatus = type === 'draft' ? -1 : '';
      this.form.auditStatus = type === "draft" ? -1 : "";
      this.getTableData();
    },
    getTableData() {
@@ -305,15 +305,30 @@
        this.form.startTime = "";
        this.form.endTime = "";
      }
      // 创建新的请求参数对象,排除createTime
      const { createTime, ...requestParams } = this.form;
      console.log(requestParams,'requestParams')
      getProposalList(requestParams).then(res => {
      console.log(requestParams, "requestParams");
      getProposalList(requestParams).then((res) => {
        console.log(res, "请求回来的数据");
        this.tableData = res.data.records;
        this.total = res.data.total;
      });
    },
    handleChangeStatusConfirm() {
      if (this.currentOperationType === "revoke") {
        // 处理撤销审批逻辑
        console.log("撤销审批数据:", this.currentOperationRow);
        // TODO: 调用撤销审批接口
        this.$message.success("撤销审批成功");
      } else if (this.currentOperationType === "delete") {
        // 处理删除逻辑
        console.log("删除数据:", this.currentOperationRow);
        // TODO: 调用删除接口
        this.$message.success("删除成功");
      }
      this.changeStatus = false;
      this.getTableData();
    },
  },
};
@@ -323,15 +338,18 @@
.list {
  height: 100%;
}
.flex {
  display: flex;
  align-items: center;
}
.tableTitle {
  display: flex;
  padding-bottom: 20px;
  justify-content: space-between;
  align-items: center;
  .title {
    background: #fafafc;
    border-radius: 8px 8px 0px 0px;
@@ -343,6 +361,7 @@
    width: unset;
    cursor: pointer;
  }
  .drafts {
    padding: 16px 65px;
    background: #fafafc;
@@ -354,7 +373,8 @@
    margin-left: 16px;
    cursor: pointer;
  }
  .active{
  .active {
    color: #049c9a;
    background: #ffffff;
    border-radius: 8px 8px 0px 0px;
laboratory/src/views/dataManagement/approvalPlan/service.js
@@ -32,5 +32,5 @@
}
//根据id查询方案详情
export function getDetailById(data) {
  return axios.get('/open/t-project-proposal/getDetailById', { ...data })
  return axios.get('/open/t-project-proposal/getDetailById', {params:data })
}