| | |
| | | }, |
| | | component: () => import("../views/dataManagement/testResultReport/detail.vue"), |
| | | }, |
| | | { |
| | | path: "suspendExperiment", |
| | | meta: { |
| | | title: "实验中止审批", |
| | | keepAlive: true, |
| | | }, |
| | | component: () => import("../views/dataManagement/suspendExperiment/list.vue"), |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | |
| | | <template> |
| | | <Card> |
| | | <template style="position: relative"> |
| | | <el-form |
| | | ref="form" |
| | | :model="form" |
| | | :rules="rules" |
| | | inline |
| | | label-position="top" |
| | | > |
| | | <div class="header-title" style="margin-bottom: 38px;justify-content: space-between;"> |
| | | <div style="display: flex;align-items: center;gap: 13px;"> |
| | | <el-form ref="form" :model="form" :rules="rules" inline label-position="top"> |
| | | <div class="header-title" style="margin-bottom: 38px; justify-content: space-between"> |
| | | <div style="display: flex; align-items: center; gap: 13px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>所属实验调度</div> |
| | | </div> |
| | | <el-button |
| | | @click="showScheduling = true" |
| | | class="el-icon-plus" |
| | | type="primary" |
| | | > |
| | | 选择实验调度</el-button |
| | | > |
| | | <el-button @click="showScheduling = true" class="el-icon-plus" type="primary"> |
| | | 选择实验调度</el-button> |
| | | </div> |
| | | <el-button |
| | | @click="handleStopExperiment" |
| | | type="danger" |
| | | > |
| | | 申请终止实验</el-button |
| | | > |
| | | <el-button @click="handleStopExperiment" type="danger"> |
| | | 申请终止实验</el-button> |
| | | </div> |
| | | <Table |
| | | :data="groupTableData" |
| | | :total="0" |
| | | :height="null" |
| | | class="groupTable" |
| | | > |
| | | <el-table-column |
| | | type="index" |
| | | label="序号" |
| | | width="80" |
| | | ></el-table-column> |
| | | <Table :data="groupTableData" :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> |
| | | <el-table-column label="操作" width="200"> |
| | | <template slot-scope="scope"> |
| | | <el-button type="text" @click="handleEditGroup(scope.row)" |
| | | >编辑</el-button |
| | | > |
| | | <el-button type="text" @click="handleDeleteGroup(scope.row)" |
| | | >移除</el-button |
| | | > |
| | | <el-button type="text" @click="handleEditGroup(scope.row)">编辑</el-button> |
| | | <el-button type="text" @click="handleDeleteGroup(scope.row)">移除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </Table> |
| | |
| | | <!-- <el-button type="primary" class="el-icon-plus" @click="handleAddGroup">添加组别</el-button> --> |
| | | </div> |
| | | |
| | | <Table |
| | | :data="groupTableData" |
| | | :total="0" |
| | | :height="null" |
| | | class="groupTable" |
| | | > |
| | | <el-table-column |
| | | type="index" |
| | | label="序号" |
| | | width="80" |
| | | ></el-table-column> |
| | | <Table :data="groupTableData" :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> |
| | |
| | | <div class="add-group"> |
| | | <div>*</div> |
| | | <span>参加人员</span> |
| | | <el-button type="primary" class="el-icon-plus" @click="addMember" |
| | | >选择参加人员</el-button |
| | | > |
| | | <el-button type="primary" class="el-icon-plus" @click="addMember">选择参加人员</el-button> |
| | | </div> |
| | | <div class="member-list"> |
| | | <div v-for="item in 3" :key="item" class="member-list-card"> |
| | |
| | | <div class="member-title"> |
| | | {{ ["工艺工程师", "实验员", "化验师"][item - 1] }} |
| | | </div> |
| | | <div |
| | | :class="item == 1 || item == 2 ? 'member-name-box' : 'flex1'" |
| | | > |
| | | <div |
| | | :class=" |
| | | item == 1 || item == 2 |
| | | ? 'member-name-box' |
| | | : 'member-name-box-2' |
| | | " |
| | | > |
| | | <div |
| | | v-for="i in memberList(item)" |
| | | :key="i" |
| | | class="member-name" |
| | | > |
| | | <div :class="item == 1 || item == 2 ? 'member-name-box' : 'flex1'"> |
| | | <div :class="item == 1 || item == 2 ? 'member-name-box': 'member-name-box-2'"> |
| | | <div v-for="i in memberList(item)" :key="i" class="member-name"> |
| | | 张三 |
| | | </div> |
| | | </div> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="content-box"> |
| | | <AiEditor |
| | | ref="purposeEditor" |
| | | v-model="editorContents.purpose" |
| | | height="200px" |
| | | placeholder="请输入实验目的..." |
| | | /> |
| | | <AiEditor ref="purposeEditor" v-model="editorContents.purpose" height="200px" placeholder="请输入实验目的..." /> |
| | | </div> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="content-box"> |
| | | <AiEditor |
| | | ref="processEditor" |
| | | v-model="editorContents.process" |
| | | height="200px" |
| | | placeholder="请输入工艺参数及路线..." |
| | | /> |
| | | <AiEditor ref="processEditor" v-model="editorContents.process" height="200px" placeholder="请输入工艺参数及路线..." /> |
| | | </div> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | |
| | | <div>三、实验材料及设备</div> |
| | | </div> |
| | | </div> |
| | | <DynamicComponent |
| | | ref="materialComponent" |
| | | title="实验材料" |
| | | @submit="handleMaterialSubmit" |
| | | /> |
| | | <DynamicComponent |
| | | ref="equipmentComponent" |
| | | title="实验所用设备" |
| | | @submit="handleEquipmentSubmit" |
| | | /> |
| | | <DynamicComponent ref="materialComponent" title="实验材料" @submit="handleMaterialSubmit" /> |
| | | <DynamicComponent ref="equipmentComponent" title="实验所用设备" @submit="handleEquipmentSubmit" /> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | |
| | | <div>四、实验操作步骤记录</div> |
| | | </div> |
| | | <el-button @click="handleAddStep" class="el-icon-plus" type="primary"> |
| | | 添加步骤</el-button |
| | | > |
| | | 添加步骤</el-button> |
| | | </div> |
| | | |
| | | <div class="step-list" v-for="(item, idx) in stepList" :key="idx"> |
| | |
| | | </div> |
| | | <div class="step-list-item-control"> |
| | | <div class="controlBtn edit" @click="handleEditStep(idx)"> |
| | | <img |
| | | src="@/assets/public/edit.png" |
| | | alt="编辑" |
| | | class="edit-icon" |
| | | /> |
| | | <img src="@/assets/public/edit.png" alt="编辑" class="edit-icon" /> |
| | | 编辑 |
| | | </div> |
| | | <div class="controlBtn delete" @click="handleDeleteStep(idx)"> |
| | | <img |
| | | src="@/assets/public/delete.png" |
| | | alt="删除" |
| | | class="delete-icon" |
| | | /> |
| | | <img src="@/assets/public/delete.png" alt="删除" class="delete-icon" /> |
| | | 删除 |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <DynamicComponent |
| | | :ref="'stepContent' + idx" |
| | | @submit="(content) => handleStepContentSubmit(idx, content)" |
| | | /> |
| | | <DynamicComponent :ref="'stepContent' + idx" @submit="(content) => handleStepContentSubmit(idx, content)" /> |
| | | </div> |
| | | |
| | | <div class="add-project-footer"> |
| | | <el-button type="primary" class="save-btn" @click="handleSave" |
| | | >发送</el-button |
| | | > |
| | | <el-button type="primary" class="save-btn" @click="handleSave">发送</el-button> |
| | | <el-button @click="handleSaveDraft">存草稿</el-button> |
| | | </div> |
| | | </el-form> |
| | |
| | | this.$message.success("删除成功"); |
| | | } |
| | | }) |
| | | .catch(() => {}); |
| | | .catch(() => { }); |
| | | }, |
| | | handleGroupSubmit(form) { |
| | | const index = this.groupTableData.findIndex( |
| | |
| | | this.$message.success("删除成功"); |
| | | } |
| | | }) |
| | | .catch(() => {}); |
| | | .catch(() => { }); |
| | | }, |
| | | handleTaskSubmit(form) { |
| | | const index = this.taskTableData.findIndex( |
| | |
| | | this.stepList.splice(index, 1); |
| | | this.$message.success("删除成功"); |
| | | }) |
| | | .catch(() => {}); |
| | | .catch(() => { }); |
| | | }, |
| | | handleEditStep(index) { |
| | | this.editingStepIndex = index; |
| | |
| | | return true; |
| | | }, |
| | | handleStopExperiment() { |
| | | this.$router.push('/dataManagement/scheme-management/stop-experiment') |
| | | this.$router.push("/dataManagement/scheme-management/stop-experiment"); |
| | | }, |
| | | }, |
| | | }; |
| | |
| | | flex-wrap: wrap; |
| | | gap: 13px; |
| | | margin-top: 38px; |
| | | |
| | | .header-title-left { |
| | | display: flex; |
| | | align-items: center; |
| | |
| | | |
| | | .header-title:first-child { |
| | | margin-top: 0px; |
| | | |
| | | .header-title-left { |
| | | margin-top: 0; |
| | | } |
| | |
| | | width: 65%; |
| | | padding-left: 40px; |
| | | } |
| | | |
| | | .rwuTable { |
| | | width: 85%; |
| | | padding-left: 40px; |
| | |
| | | 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% |
| | | ); |
| | | 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% |
| | | ); |
| | | 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% |
| | | ); |
| | | 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% |
| | | ); |
| | | background: linear-gradient(to bottom, |
| | | rgba(250, 199, 20, 0.21) 0%, |
| | | rgba(255, 242, 194, 0) 70%); |
| | | } |
| | | |
| | | .member-item { |
| | |
| | | line-height: 16px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .flex1 { |
| | | flex: 1; |
| | | } |
| | |
| | | padding: 10px 0; |
| | | margin-top: auto; |
| | | cursor: pointer; |
| | | |
| | | .member-change-btn { |
| | | background: #fff1f0; |
| | | border-radius: 4px; |
| | |
| | | padding: 20px; |
| | | margin-top: 37px; |
| | | } |
| | | |
| | | .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; |
| | |
| | | flex-wrap: wrap; |
| | | flex: 1; |
| | | } |
| | | |
| | | .step-list-item-control { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .controlBtn { |
| | | height: 24px; |
| | | background: #ffffff; |
| | |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .edit { |
| | | border: 1px solid #44be09; |
| | | font-family: PingFangSC, PingFang SC; |
| | |
| | | line-height: 24px; |
| | | margin-right: 50px; |
| | | } |
| | | |
| | | .delete { |
| | | border: 1px solid #ff4d4f; |
| | | font-family: PingFangSC, PingFang SC; |
| | |
| | | color: #ff4d4f; |
| | | line-height: 24px; |
| | | } |
| | | |
| | | .edit-icon { |
| | | width: 14px; |
| | | height: 14px; |
| | | margin-right: 8px; |
| | | } |
| | | |
| | | .delete-icon { |
| | | width: 13px; |
| | | height: 13px; |
New file |
| | |
| | | <template> |
| | | <el-dialog :title="dialogTitle" :visible.sync="visible" 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="groupName" label="实验编号"></el-table-column> |
| | | <el-table-column prop="stage" label="实验名称"></el-table-column> |
| | | <el-table-column prop="creator" label="通知时间"></el-table-column> |
| | | <el-table-column prop="createTime" label="实验开始时间"></el-table-column> |
| | | <el-table-column prop="approver" label="实验结束时间"></el-table-column> |
| | | <el-table-column prop="approveTime" label="参加人员"></el-table-column> |
| | | <el-table-column prop="status" label="状态"> |
| | | </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" v-model="form.purpose" height="200px" placeholder="请输入文字" /> |
| | | |
| | | </template> |
| | | </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" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="approval-dialog-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"> |
| | | <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' |
| | | export default { |
| | | name: "ApprovalDialog", |
| | | components: { |
| | | ApprovalProcess, AiEditor |
| | | }, |
| | | props: { |
| | | visible: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | type: { |
| | | type: String, |
| | | default: "approve", // approve-审批,view-查看 |
| | | }, |
| | | data: { |
| | | type: Object, |
| | | default: () => ({}), |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | form: { |
| | | planName: "", |
| | | planCode: "", |
| | | stage: "", |
| | | creator: "", |
| | | createTime: "", |
| | | approvalComment: "", |
| | | status: "pending", |
| | | approver: "", |
| | | approveTime: "" |
| | | }, |
| | | radio1: 1, |
| | | rules: {}, |
| | | status: "1", |
| | | remark: "", |
| | | }; |
| | | }, |
| | | computed: { |
| | | dialogTitle() { |
| | | return this.type === "approve" ? "审批实验中止申请" : "实验中止申请审批详情"; |
| | | }, |
| | | }, |
| | | watch: { |
| | | data: { |
| | | handler(val) { |
| | | if (val) { |
| | | this.form = { ...val }; |
| | | } |
| | | }, |
| | | immediate: true, |
| | | }, |
| | | }, |
| | | methods: { |
| | | handleClose() { |
| | | this.$emit("update:visible", false); |
| | | this.form.approvalComment = ""; |
| | | }, |
| | | 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", |
| | | }); |
| | | }, |
| | | }, |
| | | }; |
| | | </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> |
New file |
| | |
| | | <template> |
| | | <div class="list"> |
| | | <TableCustom :queryForm="form" :tableData="tableData" :total="total"> |
| | | <template #search> |
| | | <el-form :model="form" labelWidth="auto" inline> |
| | | <el-form-item label="所属项目课题方案:"> |
| | | <el-input v-model="form.planName" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="实验编号:"> |
| | | <el-input v-model="form.planCode" 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-form-item> |
| | | <el-form-item label="状态"> |
| | | <el-input v-model="form.approver" 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-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> |
| | | </div> |
| | | </template> |
| | | <template #table> |
| | | <el-table-column prop="planCode" label="所属项目课题方案"></el-table-column> |
| | | <el-table-column prop="planName" label="实验编号"></el-table-column> |
| | | <el-table-column prop="stage" label="实验名称"></el-table-column> |
| | | <el-table-column prop="creator" label="试验日期"></el-table-column> |
| | | <el-table-column prop="createTime" label="实验员"></el-table-column> |
| | | <el-table-column prop="approver" label="提交时间"></el-table-column> |
| | | <el-table-column prop="approveTime" 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> |
| | | |
| | | <el-table-column label="操作" width="250"> |
| | | <template slot-scope="scope"> |
| | | <el-button v-if="scope.row.status === 'pending'" type="text" |
| | | @click="handleApprove(scope.row)">审批</el-button> |
| | | |
| | | <el-button type="text" @click="handleDetail(scope.row)">详情</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </template> |
| | | </TableCustom> |
| | | <!-- 审批弹窗 --> |
| | | <approval-dialog :visible.sync="approvalDialogVisible" :type="approvalDialogType" :data="currentApprovalData" |
| | | @approve="handleApproveSubmit" @reject="handleRejectSubmit" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import ApprovalDialog from './components/approvalDialog.vue' |
| | | |
| | | export default { |
| | | name: "ProjectList", |
| | | components: { |
| | | ApprovalDialog |
| | | }, |
| | | data() { |
| | | return { |
| | | currentType: 'list', // 当前显示类型:list-列表,draft-草稿箱 |
| | | form: { |
| | | planName: "", |
| | | planCode: "", |
| | | creator: "", |
| | | createTime: [], |
| | | approver: "", |
| | | status: "", |
| | | }, |
| | | 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-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' |
| | | } |
| | | ], |
| | | mockDraftData: [ |
| | | { |
| | | 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: '' |
| | | } |
| | | ], |
| | | approvalDialogVisible: false, |
| | | approvalDialogType: 'approve', |
| | | currentApprovalData: null, |
| | | }; |
| | | }, |
| | | created() { |
| | | this.getTableData(); |
| | | }, |
| | | methods: { |
| | | resetForm() { |
| | | this.form = { |
| | | planName: "", |
| | | planCode: "", |
| | | creator: "", |
| | | createTime: [], |
| | | approver: "", |
| | | status: "", |
| | | }; |
| | | }, |
| | | handleSearch() { |
| | | // 实现查询逻辑 |
| | | console.log("查询条件:", this.form); |
| | | }, |
| | | getStatusType(status) { |
| | | const statusMap = { |
| | | pending: "warning", |
| | | rejected: "danger", |
| | | approved: "success", |
| | | archived: "info", |
| | | draft: "info" |
| | | }; |
| | | return statusMap[status] || "info"; |
| | | }, |
| | | getStatusText(status) { |
| | | const statusMap = { |
| | | pending: "待审批", |
| | | rejected: "已驳回", |
| | | approved: "已通过", |
| | | archived: "已封存", |
| | | draft: "草稿" |
| | | }; |
| | | return statusMap[status] || "未知"; |
| | | }, |
| | | handleAddPlan() { |
| | | this.$router.push({ |
| | | path: "/dataManagement/addPlan", |
| | | }); |
| | | }, |
| | | handleApprove(row) { |
| | | this.currentApprovalData = row; |
| | | this.approvalDialogType = 'approve'; |
| | | this.approvalDialogVisible = true; |
| | | }, |
| | | handleApproveSubmit(data) { |
| | | // 处理审批通过 |
| | | console.log('审批通过:', data); |
| | | this.approvalDialogVisible = false; |
| | | this.$message.success('审批通过成功'); |
| | | this.getTableData(); |
| | | }, |
| | | handleRejectSubmit(data) { |
| | | // 处理审批驳回 |
| | | console.log('审批驳回:', data); |
| | | this.approvalDialogVisible = false; |
| | | this.$message.success('审批驳回成功'); |
| | | this.getTableData(); |
| | | }, |
| | | handleRevokeApprove(row) { |
| | | // 实现撤销审批逻辑 |
| | | console.log("撤销审批数据:", row); |
| | | }, |
| | | handleEdit(row) { |
| | | // 实现编辑逻辑 |
| | | console.log("编辑数据:", row); |
| | | }, |
| | | handleDelete(row) { |
| | | // 实现删除逻辑 |
| | | console.log("删除数据:", row); |
| | | }, |
| | | handleDetail(row) { |
| | | this.currentApprovalData = row; |
| | | this.approvalDialogType = 'view'; |
| | | this.approvalDialogVisible = true; |
| | | }, |
| | | handleTypeChange(type) { |
| | | this.currentType = type; |
| | | this.getTableData(); |
| | | }, |
| | | getTableData() { |
| | | // 根据currentType请求不同的数据 |
| | | if (this.currentType === 'list') { |
| | | this.tableData = this.mockListData; |
| | | this.total = this.mockListData.length; |
| | | } else { |
| | | this.tableData = this.mockDraftData; |
| | | this.total = this.mockDraftData.length; |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .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; |
| | | border: 1px solid #dcdfe6; |
| | | padding: 16px 29px; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #606266; |
| | | width: unset; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .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; |
| | | } |
| | | } |
| | | </style> |