董国庆
2025-06-26 97ee8ffcb333367ec8407deb8b2186609c4d4739
laboratory/src/views/reportLibrary/feasibilityStudy/components/approval/index.vue
@@ -1,402 +1,536 @@
<template>
    <el-dialog :title="dialogTitle"  :visible.sync="visible" width="80%" po :close-on-click-modal="false"
        @close="handleClose">
        <div class="approval-dialog">
            <!-- 左侧审批内容 -->
            <div class="approval-content">
                <Card class="approval-content-card">
                    <template style="position: relative">
                        <div class="header-title" style="width: 100%;">
                            <div class="header-title-left">
                                <img src="@/assets/public/headercard.png" />
                                <div>所属项目组</div>
                            </div>
                        </div>
                        <Table :height="null" :total="0" @handleCurrentChange="handleCurrentChange"
                            @handleSizeChange="handleSizeChange">
                            <template>
                                <el-table-column prop="name" label="项目组名称" />
                                <el-table-column prop="age" label="项目负责人" />
                                <el-table-column prop="age" label="项目组成员" />
                                <el-table-column prop="age" label="创建时间" />
                            </template>
                        </Table>
                        <el-form ref="form" :model="form" :rules="rules" inline label-position="top"
                            style="margin-top: 38px">
                            <div class="header-title" style="width: 100%;">
                                <div class="header-title-left">
                                    <img src="@/assets/public/headercard.png" />
                                    <div>报告编号</div>
                                </div>
                            </div>
                            <form-item prop="name" style="margin-top: 38px">
                                <el-input v-model="form.name" style="width: 100%;" placeholder="请输入报告编号" />
                            </form-item>
                            <div class="header-title" style="width: 100%;">
                                <div class="header-title-left">
                                    <img src="@/assets/public/headercard.png" />
                                    <div>报告名称</div>
                                </div>
                            </div>
                            <form-item prop="name" style="margin-top: 38px">
                                <el-input v-model="form.name" style="width: 100%;" placeholder="请输入报告编号" />
                            </form-item>
                            <div class="header-title" style="width: 100%;">
                                <div class="header-title-left">
                                    <img src="@/assets/public/headercard.png" />
                                    <div>报告正文</div>
                                </div>
                            </div>
                            <form-item prop="name" style="margin-top: 38px">
                                <ai-editor v-model="form.name" style="width: 100%;" placeholder="请输入报告编号" />
                            </form-item>
                        </el-form>
                    </template>
                    <!-- <SelectMember ref="selectMember" /> -->
                </Card>
  <el-dialog
    :title="dialogTitle"
    :visible.sync="visible"
    width="80%"
    @open="open"
    po
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div
      class="approval-dialog"
      :style="{ height: obj.isDetail ? '50vh' : '40vh' }"
    >
      <!-- 左侧审批内容 -->
      <div class="approval-content">
        <Card class="approval-content-card">
          <template style="position: relative">
            <div class="header-title" style="width: 100%">
              <div class="header-title-left">
                <img src="@/assets/public/headercard.png" />
                <div>所属项目组</div>
              </div>
            </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" />
            <Table :height="null" :total="0" :data="tableData">
              <template>
                <el-table-column prop="teamName" label="项目组名称" />
                <el-table-column prop="personCharge" label="项目负责人" />
                <el-table-column prop="staffName" label="项目组成员" />
                <el-table-column prop="createTime" label="创建时间" />
              </template>
            </Table>
            <el-form
              ref="form"
              :model="form"
              :rules="rules"
              inline
              label-position="top"
              style="margin-top: 38px"
            >
              <div class="header-title" style="width: 100%">
                <div class="header-title-left">
                  <img src="@/assets/public/headercard.png" />
                  <div>报告编号</div>
                </div>
              </div>
              <el-form-item prop="reportCode" style="margin-top: 38px">
                <el-input
                  disabled
                  v-model="form.reportCode"
                  style="width: 100%"
                  placeholder="请输入报告编号"
                />
              </el-form-item>
              <div class="header-title" style="width: 100%">
                <div class="header-title-left">
                  <img src="@/assets/public/headercard.png" />
                  <div>报告名称</div>
                </div>
              </div>
              <el-form-item prop="reportName" style="margin-top: 38px">
                <el-input
                  disabled
                  v-model="form.reportName"
                  style="width: 100%"
                  placeholder="请输入报告名称"
                />
              </el-form-item>
              <div class="header-title" style="width: 100%">
                <div class="header-title-left">
                  <img src="@/assets/public/headercard.png" />
                  <div>报告正文</div>
                </div>
              </div>
              <el-form-item prop="reportText" style="margin-top: 38px">
                <ai-editor
                  :readOnly="true"
                  :value="form.reportText"
                  style="width: 100%"
                  placeholder="请输入报告正文"
                />
              </el-form-item>
              <div class="header-title" style="width: 100%">
                <div class="header-title-left">
                  <img src="@/assets/public/headercard.png" />
                  <div>附件</div>
                </div>
              </div>
              <el-form-item prop="name" style="margin-top: -18px">
                <el-upload action="#" :file-list="fileList" disabled>
                </el-upload>
              </el-form-item>
            </el-form>
          </template>
          <!-- <SelectMember ref="selectMember" /> -->
        </Card>
      </div>
      <!-- 右侧审批流程 -->
      <div class="approval-flow">
        <div class="flow-content">
          <approval-process :processData="form.processData" />
        </div>
      </div>
    </div>
    <div class="approval-dialog-approve" v-if="!obj.isDetail">
      <el-row :span="24">
        <el-col :span="12">
          <div class="status">
            <div class="status-title">审批结果</div>
            <div class="status-content">
              <div
                class="resolve"
                :class="status == '2' && 'activeStatus'"
                @click.stop="status = 2"
              >
                通过
              </div>
              <div
                class="reject"
                :class="status == '4' && 'activeStatus'"
                @click.stop="status = 4"
              >
                驳回
              </div>
            </div>
        </div>
        <div class="approval-dialog-approve">
            <el-row :span="24">
                <el-col :span="12">
                    <div class="status">
                        <div class="status-title">审批结果</div>
                        <div class="status-content">
                            <div class="resolve" :class="status == '1' && 'activeStatus'" @click.stop="status = 1">
                                通过
                            </div>
                            <div class="reject" :class="status == '2' && 'activeStatus'" @click.stop="status = 2">
                                驳回
                            </div>
                        </div>
                    </div>
                </el-col>
                <el-col :span="12">
                    <div class="remark">
                        <div class="remark-title">审批意见</div>
                        <el-input type="textarea" v-model="remark" placeholder="请输入审批意见" />
                    </div>
                </el-col>
            </el-row>
        </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>
        </div>
    </el-dialog>
          </div>
        </el-col>
        <el-col :span="12">
          <div class="remark">
            <div class="remark-title">审批意见</div>
            <el-input
              type="textarea"
              v-model="remark"
              placeholder="请输入审批意见"
            />
          </div>
        </el-col>
      </el-row>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleClose">{{
        obj.isDetail ? "关闭" : "取 消"
      }}</el-button>
      <el-button type="primary" @click="handleApprove" v-if="!obj.isDetail"
        >确认</el-button
      >
    </div>
  </el-dialog>
</template>
<script>
import ApprovalProcess from '@/components/approvalProcess'
import AiEditor from '@/components/AiEditor'
import ApprovalProcess from "@/components/approvalProcess";
import AiEditor from "@/components/AiEditor";
import { getDetail } from "../../service";
import { customUploadRequest, getFullUrl } from "@/utils/utils";
export default {
    name: "ApprovalDialog",
    components: {
        ApprovalProcess,
        AiEditor
  name: "ApprovalDialog",
  components: {
    ApprovalProcess,
    AiEditor,
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    props: {
        visible: {
            type: Boolean,
            default: false,
        },
        type: {
            type: String,
            default: "approve", // approve-审批,view-查看
        },
        data: {
            type: Object,
            default: () => ({}),
        },
    type: {
      type: String,
      default: "approve", // approve-审批,view-查看
    },
    data() {
        return {
            form: {
                planName: "",
                planCode: "",
                stage: "",
                creator: "",
                createTime: "",
                approvalComment: "",
                status: "pending",
                approver: "",
                approveTime: ""
            },
            radio1: 1,
            rules: {},
            status: "1",
            remark: "",
        };
    obj: {
      type: Object,
      default: () => {},
    },
    computed: {
        dialogTitle() {
            return this.type === "approve" ? "审批" : "审批详情";
        },
  },
  data() {
    return {
      form: {
        reportCode: "",
        reportName: "",
        reportText: "",
        teamName: "",
        createBy: "",
        createTime: "",
        status: "",
        approvalComment: "",
        approver: "",
        approveTime: "",
        processData: [],
        updateBy: "",
        auditRemark: "",
        auditPersonName: "",
        auditTime: "",
        feasibilityReportFiles: [],
      },
      fileList: [],
      tableData: [],
      rules: {},
      status: "2",
      remark: "",
    };
  },
  computed: {
    dialogTitle() {
      return this.type === "approve" ? "审批" : "审批详情";
    },
    watch: {
        data: {
            handler(val) {
                if (val) {
                    this.form = { ...val };
                }
            },
            immediate: true,
        },
    },
    methods: {
        handleClose() {
            this.$emit("close");
            this.form.approvalComment = "";
        },
        handleApprove() {
            if (!this.form.approvalComment) {
                this.$message.warning("请输入审批意见");
                return;
            }
            this.$emit("approve", {
                ...this.form,
                status: "approved",
  },
  methods: {
    getFullUrl,
    open() {
      if (!this.obj.id) {
        this.$message.error("缺少必要参数");
        return;
      }
      getDetail(this.obj.id)
        .then((res) => {
          const data = res.data || res;
          this.form = {
            ...this.form,
            ...data,
            processData: [],
          };
          if (
            data.feasibilityReportFiles &&
            data.feasibilityReportFiles.length > 0
          ) {
            this.fileList =
              data.feasibilityReportFiles.map((file) => {
                return {
                  name: file.fileName,
                  url: getFullUrl(file.fileUrl),
                  uid: file.id,
                };
              });
            this.form.feasibilityReportFiles =data.feasibilityReportFiles;
          } else {
            this.fileList = [];
            this.form.feasibilityReportFiles = [];
          }
          this.tableData = data.projectTeam
            ? [{ ...data.projectTeam, staffName: data.staffNames || "" }]
            : [];
          let processData = [];
          // 提交节点
          processData.push({
            type: "primary",
            mode: "list",
            fields: [
              { label: "提交人:", value: data.updateBy || "" },
              { label: "提交时间:", value: data.createTime || "" },
            ],
          });
          if (data.status == 2 || data.status == 4) {
            processData.push({
              type: "primary",
              mode: "list",
              fields: [
                {
                  label: "审核结果:",
                  value: data.status == 4 ? "驳回" : "通过" || "",
                },
                { label: "审批意见:", value: data.auditRemark || "" },
                { label: "审核人:", value: data.auditPersonName || "" },
                { label: "审核时间:", value: data.auditTime || "" },
              ],
            });
        },
        handleReject() {
            if (!this.form.approvalComment) {
                this.$message.warning("请输入审批意见");
                return;
            }
            this.$emit("reject", {
                ...this.form,
                status: "rejected",
          } else {
            processData.push({
              type: "warning",
              mode: "list",
              fields: [{ label: "等待审核" }],
            });
        },
        handleCurrentChange(page) {
            this.form.pageNum = page
            this.getList()
        },
        handleSizeChange(size) {
            this.form.pageSize = size
            this.getList()
        },
          }
          if (data.status == 2) {
            processData.push({
              type: "warning",
              mode: "list",
              fields: [{ label: "等待评定" }],
            });
          }
          if (data.status == 3) {
            processData.push({
              type: "success",
              mode: "list",
              fields: [
                { label: "评定状态:已评定" },
                { label: "评定人:", value: data.evaluatePersonName || "" },
                { label: "评定时间:", value: data.evaluateTime || "" },
              ],
            });
          }
          this.form.processData = processData;
        })
        .catch((err) => {
          this.$message.error("获取详情失败");
        });
    },
    handleClose() {
      this.$emit("close");
      this.form.approvalComment = "";
    },
    handleApprove() {
      this.$emit("approve", {
        ...this.form,
        statuss: this.status,
        remark: this.remark,
      });
    },
    handleCurrentChange(page) {
      this.form.pageNum = page;
      this.getList();
    },
    handleSizeChange(size) {
      this.form.pageSize = size;
      this.getList();
    },
  },
};
</script>
<style scoped lang="less">
::v-deep .el-dialog__header {
    border-bottom: 1px solid #e4e7ed;
  border-bottom: 1px solid #e4e7ed;
}
.approval-dialog {
    display: flex;
    height: 40vh;
  display: flex;
  height: 40vh;
    .approval-content {
        flex: 3;
        margin-right: 20px;
        background: #ffffff;
        box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08);
        border-radius: 10px;
  .approval-content {
    flex: 3;
    margin-right: 20px;
    background: #ffffff;
    box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08);
    border-radius: 10px;
  }
  .approval-flow {
    padding: 40px 20px;
    // width: 405px;
    flex: 2;
    background: #ffffff;
    box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08);
    border-radius: 10px;
    .flow-title {
      font-size: 16px;
      font-weight: bold;
      margin-bottom: 20px;
      color: #303133;
    }
    .approval-flow {
        padding: 40px 20px;
        // width: 405px;
        flex: 2;
        background: #ffffff;
        box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08);
        border-radius: 10px;
        .flow-title {
            font-size: 16px;
            font-weight: bold;
            margin-bottom: 20px;
            color: #303133;
        }
    .flow-content {
      height: calc(100% - 40px);
      overflow-y: auto;
        .flow-content {
            height: calc(100% - 40px);
            overflow-y: auto;
            .el-form--inline .el-form-item {
                margin-right: 83px;
            }
        }
      .el-form--inline .el-form-item {
        margin-right: 83px;
      }
    }
  }
}
.approval-content-card {
    height: calc(100% - 100px) !important;
    box-shadow: none !important;
  height: calc(100% - 100px) !important;
  box-shadow: none !important;
}
.header-title {
    // display: flex;
  // display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 20px;
  gap: 13px;
  .header-title-left {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 20px;
    gap: 13px;
    margin-top: 38px;
    .header-title-left {
        display: flex;
        align-items: center;
        gap: 13px;
        margin-top: 38px;
        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";
        }
    img {
      width: 12px;
      height: 19px;
    }
    .header-title-left :first-child {
        margin-top: 0;
    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 {
    .header-title-left {
        margin-top: 0;
    }
  .header-title-left {
    margin-top: 0;
  }
}
.item-title {
    padding-left: 25px;
  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;
  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;
        }
    &:before {
      content: "*";
      color: #f56c6c;
      margin-right: 4px;
    }
  }
}
.approval-dialog-approve {
    padding: 38px 20px;
    // display: flex;
    align-content: center;
  padding: 38px 20px;
  // display: flex;
  align-content: center;
    .status {
        margin-right: 40px;
        max-width: 60%;
  .status {
    margin-right: 40px;
    max-width: 60%;
  }
  //   align-items: center;
  .status-title {
    color: #222222;
    font-family: "SourceHanSansCN-Medium";
    line-height: 14px;
    margin-bottom: 16px;
  }
  .status-content {
    display: flex;
    align-items: center;
    width: 100%;
    gap: 16px;
    background: #ffffff;
    border-radius: 10px;
    border: 1px solid rgba(4, 156, 154, 0.5);
    .resolve {
      border-radius: 10px;
      flex: 1;
      font-size: 16px;
      // padding: 5px 55px;
      font-weight: 400;
      color: #333333;
      cursor: pointer;
      line-height: 32px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    //   align-items: center;
    .status-title {
        color: #222222;
        font-family: "SourceHanSansCN-Medium";
        line-height: 14px;
        margin-bottom: 16px;
    .reject {
      flex: 1;
      border-radius: 10px;
      font-size: 16px;
      line-height: 32px;
      // padding: 5px 55px;
      font-weight: 400;
      color: #333333;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .status-content {
        display: flex;
        align-items: center;
        width: 100%;
        gap: 16px;
        background: #ffffff;
        border-radius: 10px;
        border: 1px solid rgba(4, 156, 154, 0.5);
        .resolve {
            border-radius: 10px;
            flex: 1;
            font-size: 16px;
            // padding: 5px 55px;
            font-weight: 400;
            color: #333333;
            cursor: pointer;
            line-height: 32px;
            display: flex;
            align-items: center;
            justify-content: center
        }
        .reject {
            flex: 1;
            border-radius: 10px;
            font-size: 16px;
            line-height: 32px;
            // padding: 5px 55px;
            font-weight: 400;
            color: #333333;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center
        }
        .activeStatus {
            background: #ebfefd;
            color: #049c9a;
            box-shadow: 0px 0px 6px 0px rgba(10, 109, 108, 0.25);
            border-radius: 10px;
        }
    .activeStatus {
      background: #ebfefd;
      color: #049c9a;
      box-shadow: 0px 0px 6px 0px rgba(10, 109, 108, 0.25);
      border-radius: 10px;
    }
  }
    .remark-title {
        color: #222222;
        font-family: "SourceHanSansCN-Medium";
        line-height: 14px;
        margin-bottom: 16px;
    }
  .remark-title {
    color: #222222;
    font-family: "SourceHanSansCN-Medium";
    line-height: 14px;
    margin-bottom: 16px;
  }
}
.dialog-footer {
    align-items: center;
    display: flex;
    justify-content: center;
    gap: 20px;
  align-items: center;
  display: flex;
  justify-content: center;
  gap: 20px;
    button {
        width: 150px;
    }
  button {
    width: 150px;
  }
}
</style>