<template>
|
<el-dialog :title="dialogTitle" :visible.sync="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">
|
<div class="header-title">
|
<div class="header-title-left">
|
<img src="@/assets/public/headercard.png" />
|
<div>所属实验调度</div>
|
</div>
|
</div>
|
<Table :data="groupTableData" :total="0" :height="null" class="groupTable">
|
<el-table-column type="index" label="序号" width="80"></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="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">
|
<div class="header-title-left">
|
<img src="@/assets/public/headercard.png" />
|
<div>中止原因说明</div>
|
</div>
|
</div>
|
<AiEditor ref="purposeEditor" :readOnly="true" :value="form.stopReason" height="200px" placeholder="请输入文字" />
|
|
</template>
|
</Card>
|
</div>
|
<!-- 右侧审批流程 -->
|
<div class="approval-flow">
|
<div class="flow-content">
|
<approval-process :processData="approvalProcessData" />
|
</div>
|
</div>
|
</div>
|
<div class="approval-dialog-approve" v-if="type === 'approve'">
|
<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>
|
<div class="remark" style="flex:1">
|
<div class="remark-title">审批意见</div>
|
<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'"
|
style="margin-left: 20px;">通过</el-button>
|
</div>
|
</el-dialog>
|
</template>
|
|
<script>
|
import ApprovalProcess from '@/components/approvalProcess'
|
import AiEditor from '@/components/AiEditor'
|
import { audit, getDetail } from '../service'
|
export default {
|
name: "ApprovalDialog",
|
components: {
|
ApprovalProcess, AiEditor
|
},
|
props: {
|
visible: {
|
type: Boolean,
|
default: false,
|
},
|
type: {
|
type: String,
|
default: "approve", // approve-审批,view-查看
|
},
|
data: {
|
type: Object,
|
default: () => ({}),
|
},
|
},
|
computed: {
|
dialogVisible: {
|
get() {
|
return this.visible;
|
},
|
set(val) {
|
this.$emit('update:visible', val);
|
}
|
},
|
dialogTitle() {
|
return this.type === "approve" ? "审批实验中止申请" : "实验中止申请审批详情";
|
},
|
},
|
watch: {
|
visible: {
|
handler(val) {
|
if (val && this.data && this.data.id) {
|
// this.form = { ...val };
|
this.getDialogDetail(this.data.id)
|
}
|
},
|
immediate: true,
|
},
|
},
|
data() {
|
return {
|
form: {
|
planName: "",
|
planCode: "",
|
stage: "",
|
creator: "",
|
createTime: "",
|
approvalComment: "",
|
status: "pending",
|
approver: "",
|
approveTime: ""
|
},
|
groupTableData: [],
|
approvalProcessData: [],
|
radio1: 1,
|
rules: {},
|
status: "1",
|
remark: "",
|
};
|
},
|
methods: {
|
async getDialogDetail(id) {
|
try {
|
const res = await getDetail({ 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,
|
stopReason: res.stopReason,
|
};
|
|
// 构建实验调度数据
|
if (res.experimentDispatch) {
|
this.groupTableData = [res.experimentDispatch];
|
}
|
|
} catch (error) {
|
console.error("获取方案详情失败:", error);
|
this.$message.error("获取方案详情失败");
|
this.handleClose();
|
}
|
},
|
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);
|
this.remark = "";
|
},
|
handleApprove() {
|
if (!this.remark) {
|
this.$message.warning("请输入审批意见");
|
return;
|
}
|
this.handleSubmit();
|
},
|
async handleSubmit() {
|
try {
|
const params = {
|
id: this.data.id,
|
auditRemark: this.remark,
|
status: this.status === '1' ? 3 : 4 // 1表示通过(status=3),2表示拒绝(status=4)
|
};
|
console.log('params params',params)
|
const res = await audit(params);
|
console.log('res res',res)
|
if (res) {
|
this.$message.success('审批成功');
|
this.handleClose();
|
}
|
} catch (error) {
|
console.error('审批失败:', error);
|
this.$message.error('审批失败');
|
}
|
},
|
},
|
};
|
</script>
|
|
<style scoped lang="less">
|
::v-deep .el-dialog__header {
|
border-bottom: 1px solid #e4e7ed;
|
}
|
|
.approval-dialog {
|
display: flex;
|
height: 300px;
|
|
.approval-content {
|
flex: 1;
|
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;
|
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;
|
|
.el-form--inline .el-form-item {
|
margin-right: 83px;
|
}
|
}
|
}
|
}
|
|
.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-bottom: 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";
|
}
|
}
|
|
.header-title-left :first-child {
|
margin-top: 0;
|
}
|
}
|
|
.header-title:first-child {
|
.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 {
|
padding: 38px 20px;
|
display: flex;
|
align-content: center;
|
|
.status {
|
margin-right: 40px;
|
}
|
|
// align-items: center;
|
.status-title {
|
color: #222222;
|
font-family: "SourceHanSansCN-Medium";
|
line-height: 14px;
|
margin-bottom: 16px;
|
}
|
|
.status-content {
|
display: flex;
|
align-items: center;
|
gap: 16px;
|
background: #ffffff;
|
border-radius: 10px;
|
border: 1px solid rgba(4, 156, 154, 0.5);
|
|
.resolve {
|
border-radius: 10px;
|
font-size: 16px;
|
padding: 5px 55px;
|
font-weight: 400;
|
color: #333333;
|
cursor: pointer;
|
}
|
|
.reject {
|
border-radius: 10px;
|
font-size: 16px;
|
padding: 5px 55px;
|
font-weight: 400;
|
color: #333333;
|
cursor: pointer;
|
}
|
|
.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;
|
}
|
}
|
|
.dialog-footer {
|
align-items: center;
|
display: flex;
|
justify-content: center;
|
|
button {
|
width: 150px;
|
}
|
}
|
</style>
|