| | |
| | | |
| | | confirmSignature() { |
| | | const canvas = this.$refs.signatureCanvas |
| | | const imageData = canvas.toDataURL('image/png') |
| | | this.$emit('confirm', imageData) |
| | | const ctx = this.context |
| | | |
| | | // 保存当前画布内容 |
| | | const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height) |
| | | |
| | | // 先填充背景色 |
| | | ctx.fillStyle = 'rgba(239, 248, 250, 1)' |
| | | ctx.fillRect(0, 0, canvas.width, canvas.height) |
| | | |
| | | // 创建一个临时画布来保存签名内容 |
| | | const tempCanvas = document.createElement('canvas') |
| | | tempCanvas.width = canvas.width |
| | | tempCanvas.height = canvas.height |
| | | const tempCtx = tempCanvas.getContext('2d') |
| | | tempCtx.putImageData(imageData, 0, 0) |
| | | |
| | | // 将签名内容绘制到主画布上 |
| | | ctx.drawImage(tempCanvas, 0, 0) |
| | | |
| | | // 导出图片 |
| | | const signatureImage = canvas.toDataURL('image/png') |
| | | this.$emit('confirm', signatureImage) |
| | | } |
| | | }, |
| | | beforeDestroy() { |
| | |
| | | <template> |
| | | <div class="approval-process"> |
| | | <el-timeline> |
| | | <el-timeline-item v-for="(activity, index) in processData" :key="index" :type="activity.type" |
| | | :timestamp="activity.time"> |
| | | <div class="approval-process-item" :class="activity.type == 'primary' ? '' : 'approval-process-item1'"> |
| | | <div class="approval-process-item-name"> |
| | | 提交人:李雷雷 |
| | | <el-timeline-item |
| | | v-for="(activity, index) in processData" |
| | | :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 class="member-item"> |
| | | <div class="member-title"> |
| | | {{ ["工艺工程师", "实验员", "化验师"][item - 1] }} |
| | | </div> |
| | | <div class="flex-over"> |
| | | <div class="people-list" v-for="item in 10" :key="item"> |
| | | <div class="people-item"> |
| | | <img src="" alt="" class="people-img" /> |
| | | <div class="member-name">{{ item }}</div> |
| | | </div> |
| | | <div class="member-status"> |
| | | <div |
| | | class="member-status-text" |
| | | :class=" |
| | | activity.type == 'success' ? 'success' : 'warning' |
| | | " |
| | | > |
| | | {{ activity.type == "success" ? "同意" : "待审批" }} |
| | | </div> |
| | | <div |
| | | v-if="activity.type == 'success'" |
| | | class="member-status-time" |
| | | > |
| | | 2025-04-08 12:30 |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | <div |
| | | v-else |
| | | class="approval-process-item" |
| | | :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> |
| | | |
| | | |
| | | </div> |
| | | </el-timeline-item> |
| | | </el-timeline> |
| | |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'ApprovalProcess', |
| | | name: "ApprovalProcess", |
| | | props: { |
| | | status: { |
| | | type: String, |
| | | default: 'pending', // pending-等待审核, approved-已通过 |
| | | validator: value => ['pending', 'approved'].includes(value) |
| | | default: "approved", // pending-等待审核, approved-已通过 |
| | | validator: (value) => ["pending", "approved"].includes(value), |
| | | }, |
| | | submitTime: { |
| | | type: String, |
| | | default: '' |
| | | default: "", |
| | | }, |
| | | approver: { |
| | | type: String, |
| | | default: '' |
| | | default: "", |
| | | }, |
| | | approveTime: { |
| | | type: String, |
| | | default: '' |
| | | } |
| | | default: "", |
| | | }, |
| | | mode: { |
| | | type: String, |
| | | default: "",//card-就是卡片模式,其他就是列表模式 |
| | | }, |
| | | }, |
| | | computed: { |
| | | processData() { |
| | | const baseData = [ |
| | | { |
| | | content: '提交审批', |
| | | content: "提交审批", |
| | | time: this.submitTime, |
| | | type: 'primary' |
| | | } |
| | | ] |
| | | type: "primary", |
| | | }, |
| | | ]; |
| | | |
| | | if (this.status === 'approved') { |
| | | if (this.status === "approved") { |
| | | console.log("111111111111111", this.status); |
| | | |
| | | baseData.push({ |
| | | content: `${this.approver}审批通过`, |
| | | time: this.approveTime, |
| | | type: 'success' |
| | | }) |
| | | type: "success", |
| | | mode: this.mode, |
| | | }); |
| | | } else { |
| | | console.log("122222222222222221", this.status); |
| | | baseData.push({ |
| | | content: '等待审核', |
| | | content: "等待审核", |
| | | time: this.submitTime, |
| | | type: 'warning' |
| | | }) |
| | | type: "warning", |
| | | mode: this.mode, |
| | | }); |
| | | } |
| | | |
| | | return baseData |
| | | } |
| | | } |
| | | } |
| | | return baseData; |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | |
| | | .el-timeline-item__node { |
| | | width: 20px !important; |
| | | height: 20px !important; |
| | | background: #FFFFFF; |
| | | background: #ffffff; |
| | | box-shadow: 0px 2px 6px 0px rgba(4, 156, 154, 0.36) !important; |
| | | border: 4px solid rgba(144, 147, 153, 0.40) !important; |
| | | border: 4px solid rgba(144, 147, 153, 0.4) !important; |
| | | left: -10px; |
| | | top: -8px; |
| | | } |
| | |
| | | .el-timeline-item__node--primary { |
| | | width: 20px !important; |
| | | height: 20px !important; |
| | | background: #FFFFFF; |
| | | background: #ffffff; |
| | | box-shadow: 0px 2px 6px 0px rgba(4, 156, 154, 0.36) !important; |
| | | border: 4px solid rgba(10, 203, 202, 1) !important; |
| | | left: -10px !important; |
| | | top: -8px !important; |
| | | // border-image: linear-gradient(180deg, rgba(10, 203, 202, 1), rgba(4, 156, 154, 1)) 4 4 !important; |
| | | } |
| | | |
| | | .member-list-card { |
| | | width: 280px; |
| | | height: 300px; |
| | | border-radius: 8px; |
| | | border: 1px solid #dcdfe6; |
| | | margin-top: 10px; |
| | | |
| | | &:nth-child(1) { |
| | | background: linear-gradient( |
| | | to bottom, |
| | | rgba(4, 156, 154, 0.2) 0%, |
| | | rgba(5, 242, 194, 0) 70% |
| | | ); |
| | | } |
| | | |
| | | &:nth-child(2) { |
| | | background: linear-gradient( |
| | | to bottom, |
| | | rgba(5, 160, 193, 0.2) 0%, |
| | | rgba(5, 242, 194, 0) 70% |
| | | ); |
| | | } |
| | | |
| | | &:nth-child(3) { |
| | | background: linear-gradient( |
| | | to bottom, |
| | | rgba(255, 77, 79, 0.2) 0%, |
| | | rgba(255, 242, 194, 0) 70% |
| | | ); |
| | | } |
| | | |
| | | &:nth-child(4) { |
| | | background: linear-gradient( |
| | | to bottom, |
| | | rgba(250, 199, 20, 0.21) 0%, |
| | | rgba(255, 242, 194, 0) 70% |
| | | ); |
| | | } |
| | | |
| | | .member-item { |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .member-title { |
| | | margin-top: 20px; |
| | | width: 100%; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | font-weight: bold; |
| | | font-size: 16px; |
| | | color: rgba(0, 0, 0, 0.8); |
| | | line-height: 16px; |
| | | text-align: left; |
| | | padding-left: 17px; |
| | | } |
| | | .flex-over{ |
| | | margin-top: 12px; |
| | | flex: 1; |
| | | overflow: auto; |
| | | height: 100%; |
| | | } |
| | | .people-list { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 0 20px; |
| | | margin-top: 12px; |
| | | |
| | | display: flex; |
| | | .people-item { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .people-img { |
| | | width: 44px; |
| | | height: 44px; |
| | | border-radius: 50%; |
| | | margin-right: 10px; |
| | | } |
| | | .member-status { |
| | | align-items: flex-end; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-between; |
| | | } |
| | | .member-status-text { |
| | | width: 52px; |
| | | height: 22px; |
| | | line-height: 22px; |
| | | border-radius: 4px; |
| | | text-align: center; |
| | | border: 1px solid rgba(0, 0, 0, 0.15); |
| | | } |
| | | .warning { |
| | | background: #fffbe6; |
| | | border-radius: 4px; |
| | | border: 1px solid #fff1b8; |
| | | font-family: PingFangSC, PingFang SC; |
| | | font-weight: 400; |
| | | font-size: 12px; |
| | | color: #faad14; |
| | | } |
| | | .success { |
| | | font-family: PingFangSC, PingFang SC; |
| | | font-weight: 400; |
| | | font-size: 12px; |
| | | color: rgba(0, 0, 0, 0.88); |
| | | } |
| | | .member-status-time { |
| | | font-family: PingFang-SC, PingFang-SC; |
| | | font-weight: 500; |
| | | font-size: 12px; |
| | | color: rgba(0, 0, 0, 0.4); |
| | | line-height: 17px; |
| | | margin-top: 5px; |
| | | } |
| | | } |
| | | |
| | | .member-name { |
| | | font-family: SourceHanSansCN, SourceHanSansCN; |
| | | font-weight: 500; |
| | | font-size: 14px; |
| | | color: rgba(0, 0, 0, 0.8); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div> |
| | | <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"> |
| | | <el-form |
| | | ref="form" |
| | | :model="form" |
| | | :rules="rules" |
| | | inline |
| | | label-position="top" |
| | | :disabled="type === 'view'" |
| | | > |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>一、项目课题方案信息</span> |
| | | </div> |
| | | </div> |
| | | <div style="padding-left: 25px"> |
| | | <el-form-item prop="planName" label="项目课题方案名称"> |
| | | <el-input v-model="form.planName" placeholder="请输入" /> |
| | | </el-form-item> |
| | | <el-form-item prop="planCode" label="项目课题方案编号"> |
| | | <el-input v-model="form.planCode" placeholder="请输入" /> |
| | | </el-form-item> |
| | | <el-form-item prop="stage" label="项目阶段"> |
| | | <el-input v-model="form.stage" placeholder="请输入" /> |
| | | </el-form-item> |
| | | </div> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>二 、实验信息</span> |
| | | </div> |
| | | </div> |
| | | <div style="padding-left: 25px"> |
| | | <el-form-item prop="testDate" label="试验日期"> |
| | | <el-date-picker |
| | | v-model="form.testDate" |
| | | type="date" |
| | | placeholder="选择日期" |
| | | value-format="yyyy-MM-dd" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item prop="testName" label="实验名称"> |
| | | <el-input v-model="form.testName" placeholder="请输入" /> |
| | | </el-form-item> |
| | | <el-form-item prop="testCode" label="实验编号"> |
| | | <el-input v-model="form.testCode" placeholder="请输入" /> |
| | | </el-form-item> |
| | | </div> |
| | | |
| | | <div class="add-group"> |
| | | <span>实验分组</span> |
| | | </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="remark" label="备注"></el-table-column> |
| | | </Table> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>三 、计划时间及人员</span> |
| | | </div> |
| | | </div> |
| | | <div style="padding-left: 25px"> |
| | | <el-form-item prop="testTime" label="试验时间"> |
| | | <el-date-picker |
| | | v-model="form.testTime" |
| | | type="datetime" |
| | | placeholder="选择日期时间" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | /> |
| | | </el-form-item> |
| | | </div> |
| | | <div class="add-group"> |
| | | <div>*</div> |
| | | <span>参加人员</span> |
| | | </div> |
| | | <div class="member-list"> |
| | | <div v-for="item in 3" :key="item" class="member-list-card"> |
| | | <div class="member-item"> |
| | | <div class="member-title"> |
| | | {{ ["工艺工程师", "实验员", "化验师"][item - 1] }} |
| | | </div> |
| | | <div |
| | | :class=" |
| | | item == 1 || item == 2 || item == 3 |
| | | ? 'member-name-box' |
| | | : 'flex1' |
| | | " |
| | | > |
| | | <div |
| | | :class=" |
| | | item == 1 || item == 2 || item == 3 |
| | | ? 'member-name-box' |
| | | : 'member-name-box-2' |
| | | " |
| | | > |
| | | <div |
| | | v-for="i in memberList(item)" |
| | | :key="i" |
| | | class="member-name" |
| | | > |
| | | 张三 |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="member-change" v-if="type !== 'view'"> |
| | | <div class="member-change-btn">修改</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>四 、任务分解</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <Table |
| | | :data="taskTableData" |
| | | :total="0" |
| | | :height="null" |
| | | class="rwuTable" |
| | | > |
| | | <el-table-column |
| | | type="index" |
| | | label="序号" |
| | | width="80" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="taskName" |
| | | label="任务名称" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="leader" |
| | | label="负责人" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="startTime" |
| | | label="开始时间" |
| | | ></el-table-column> |
| | | </Table> |
| | | |
| | | <div class="header-title"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>五 、关键节点</span> |
| | | </div> |
| | | </div> |
| | | </el-form> |
| | | </template> |
| | | </Card> |
| | | </div> |
| | | <!-- 右侧审批流程 --> |
| | | <div class="approval-flow" v-if="type === 'view'"> |
| | | <div class="flow-content"> |
| | | <approval-process |
| | | mode="card" |
| | | :status="form.status" |
| | | :submit-time="form.createTime" |
| | | :approver="form.approver" |
| | | :approve-time="form.approveTime" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="approval-dialog-approve" v-if="type === 'approve'"> |
| | | <div class="add-group"> |
| | | <div>*</div> |
| | | <span>签字确认</span> |
| | | <el-button |
| | | v-if="type !== 'view'" |
| | | type="primary" |
| | | class="el-icon-plus" |
| | | @click="openSignature" |
| | | >签名</el-button |
| | | > |
| | | </div> |
| | | <img |
| | | v-if="imgSrc" |
| | | style="width: 200px; height: 100px; margin-left: 25px" |
| | | :src="imgSrc" |
| | | fit="fit" |
| | | /> |
| | | </div> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="handleClose" v-if="type === 'view'">取 消</el-button> |
| | | <el-button |
| | | type="primary" |
| | | @click="handleApprove" |
| | | v-if="type === 'approve'" |
| | | >确认</el-button |
| | | > |
| | | </div> |
| | | </el-dialog> |
| | | <SignatureCanvas |
| | | :visible="signatureDialogVisible" |
| | | @confirm="handleSignatureConfirm" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import ApprovalProcess from "@/components/approvalProcess"; |
| | | import SignatureCanvas from "@/components/SignatureCanvas.vue"; |
| | | |
| | | export default { |
| | | name: "ApprovalDialog", |
| | | components: { |
| | | ApprovalProcess, |
| | | SignatureCanvas, |
| | | }, |
| | | props: { |
| | | visible: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | type: { |
| | | type: String, |
| | | default: "approve", // approve-审批,view-查看 |
| | | }, |
| | | data: { |
| | | type: Object, |
| | | default: () => ({}), |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | form: { |
| | | planName: "", |
| | | planCode: "", |
| | | stage: "", |
| | | testDate: "", |
| | | testName: "", |
| | | testCode: "", |
| | | testTime: "", |
| | | creator: "", |
| | | createTime: "", |
| | | approvalComment: "", |
| | | status: "approved", |
| | | approver: "", |
| | | approveTime: "", |
| | | }, |
| | | rules: { |
| | | planName: [ |
| | | { |
| | | required: true, |
| | | message: "请输入项目课题方案名称", |
| | | trigger: "blur", |
| | | }, |
| | | ], |
| | | planCode: [ |
| | | { |
| | | required: true, |
| | | message: "请输入项目课题方案编号", |
| | | trigger: "blur", |
| | | }, |
| | | ], |
| | | stage: [{ required: true, message: "请输入项目阶段", trigger: "blur" }], |
| | | testDate: [ |
| | | { required: true, message: "请选择试验日期", trigger: "change" }, |
| | | ], |
| | | testName: [ |
| | | { required: true, message: "请输入实验名称", trigger: "blur" }, |
| | | ], |
| | | testCode: [ |
| | | { required: true, message: "请输入实验编号", trigger: "blur" }, |
| | | ], |
| | | testTime: [ |
| | | { required: true, message: "请选择试验时间", trigger: "change" }, |
| | | ], |
| | | }, |
| | | imgSrc: "", |
| | | signatureDialogVisible: false, |
| | | status: "1", |
| | | remark: "", |
| | | groupTableData: [], |
| | | taskTableData: [], |
| | | }; |
| | | }, |
| | | computed: { |
| | | dialogTitle() { |
| | | return this.type === "approve" ? "确认实验调度" : "实验调度详情"; |
| | | }, |
| | | }, |
| | | watch: { |
| | | data: { |
| | | handler(val) { |
| | | if (val) { |
| | | this.form = { ...val }; |
| | | } |
| | | }, |
| | | immediate: true, |
| | | }, |
| | | }, |
| | | methods: { |
| | | memberList(i) { |
| | | switch (i) { |
| | | case 1: |
| | | return [1]; |
| | | case 2: |
| | | return [1]; |
| | | case 3: |
| | | return [1, 2, 3, 4, 5, 6, 7, 8]; |
| | | case 4: |
| | | return [1, 2, 3, 4, 5, 6, 7, 8]; |
| | | default: |
| | | break; |
| | | } |
| | | }, |
| | | 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", |
| | | }); |
| | | }, |
| | | memberList(item) { |
| | | return item === 1 ? 2 : item === 2 ? 3 : 1; |
| | | }, |
| | | openSignature() { |
| | | this.signatureDialogVisible = true; |
| | | }, |
| | | handleSignatureConfirm(imageData) { |
| | | console.log("imageData imageData", imageData); |
| | | this.signatureDialogVisible = false; |
| | | this.imgSrc = imageData; |
| | | |
| | | // 这里处理签名确认后的逻辑 |
| | | // this.$confirm('确认该实验调度吗?', '提示', { |
| | | // confirmButtonText: '确定', |
| | | // cancelButtonText: '取消', |
| | | // type: 'warning' |
| | | // }).then(() => { |
| | | // // 这里可以将签名图片数据(imageData)连同其他数据一起提交到后端 |
| | | // this.$message.success('确认成功'); |
| | | // this.signatureDialogVisible = false; |
| | | // this.getTableData(); |
| | | // }).catch(() => { |
| | | // this.signatureDialogVisible = false; |
| | | // }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | ::v-deep .el-dialog__header { |
| | | border-bottom: 1px solid #e4e7ed; |
| | | } |
| | | |
| | | .approval-dialog { |
| | | display: flex; |
| | | height: 60vh; |
| | | |
| | | .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-dialog-approve { |
| | | margin-top: 26px; |
| | | } |
| | | |
| | | .approval-content-card { |
| | | height: calc(100% - 100px) !important; |
| | | box-shadow: none !important; |
| | | } |
| | | |
| | | .header-title { |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | gap: 13px; |
| | | margin-top: 38px; |
| | | |
| | | .header-title-left { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 13px; |
| | | |
| | | img { |
| | | width: 12px; |
| | | height: 19px; |
| | | } |
| | | |
| | | div { |
| | | flex-shrink: 0; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #222222; |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | |
| | | &:before { |
| | | content: "*"; |
| | | color: #f56c6c; |
| | | margin-right: 4px; |
| | | } |
| | | } |
| | | |
| | | span { |
| | | flex-shrink: 0; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #222222; |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | } |
| | | } |
| | | |
| | | .header-title-left :first-child { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | |
| | | .header-title:first-child { |
| | | .header-title-left { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | |
| | | .item-title { |
| | | padding-left: 25px; |
| | | |
| | | span { |
| | | flex-shrink: 0; |
| | | font-weight: bold; |
| | | font-size: 14px; |
| | | color: #222222; |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | margin: 18px 0; |
| | | |
| | | &:before { |
| | | content: "*"; |
| | | color: #f56c6c; |
| | | margin-right: 4px; |
| | | } |
| | | } |
| | | } |
| | | .approval-dialog-approve { |
| | | img { |
| | | border: 2px dashed #049c9a; |
| | | } |
| | | } |
| | | |
| | | .add-group { |
| | | padding-left: 25px; |
| | | margin-top: 14px; |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 19px; |
| | | |
| | | div { |
| | | color: #f56c6c; |
| | | } |
| | | |
| | | span { |
| | | font-weight: 500; |
| | | font-size: 14px; |
| | | color: #222222; |
| | | line-height: 21px; |
| | | margin: 0 32px 0 8px; |
| | | } |
| | | } |
| | | |
| | | .groupTable { |
| | | width: 65%; |
| | | padding-left: 40px; |
| | | } |
| | | .rwuTable { |
| | | width: 85%; |
| | | padding-left: 40px; |
| | | } |
| | | |
| | | .member-list { |
| | | margin-top: 18px; |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 28px; |
| | | margin-left: 38px; |
| | | |
| | | .member-list-card { |
| | | width: 280px; |
| | | height: 300px; |
| | | border-radius: 8px; |
| | | border: 1px solid #dcdfe6; |
| | | |
| | | &:nth-child(1) { |
| | | background: linear-gradient( |
| | | to bottom, |
| | | rgba(4, 156, 154, 0.2) 0%, |
| | | rgba(5, 242, 194, 0) 70% |
| | | ); |
| | | } |
| | | |
| | | &:nth-child(2) { |
| | | background: linear-gradient( |
| | | to bottom, |
| | | rgba(5, 160, 193, 0.2) 0%, |
| | | rgba(5, 242, 194, 0) 70% |
| | | ); |
| | | } |
| | | |
| | | &:nth-child(3) { |
| | | background: linear-gradient( |
| | | to bottom, |
| | | rgba(255, 77, 79, 0.2) 0%, |
| | | rgba(255, 242, 194, 0) 70% |
| | | ); |
| | | } |
| | | |
| | | &:nth-child(4) { |
| | | background: linear-gradient( |
| | | to bottom, |
| | | rgba(250, 199, 20, 0.21) 0%, |
| | | rgba(255, 242, 194, 0) 70% |
| | | ); |
| | | } |
| | | |
| | | .member-item { |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .member-title { |
| | | margin-top: 20px; |
| | | width: 100%; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | font-weight: bold; |
| | | font-size: 16px; |
| | | color: rgba(0, 0, 0, 0.8); |
| | | line-height: 16px; |
| | | text-align: center; |
| | | } |
| | | .flex1 { |
| | | flex: 1; |
| | | } |
| | | |
| | | .member-name-box { |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .member-name-box-2 { |
| | | flex: 1; |
| | | padding: 0 20px; |
| | | padding-top: 40px; |
| | | display: grid; |
| | | grid-template-columns: repeat(4, 1fr); |
| | | gap: 20px; |
| | | justify-items: center; |
| | | align-items: start; |
| | | } |
| | | |
| | | .member-name { |
| | | width: 60px; |
| | | height: 60px; |
| | | background: #7d8b79; |
| | | border-radius: 50%; |
| | | text-align: center; |
| | | line-height: 60px; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | | color: #ffffff; |
| | | margin: 0; |
| | | } |
| | | |
| | | .member-change { |
| | | display: flex; |
| | | justify-content: center; |
| | | padding: 10px 0; |
| | | margin-top: auto; |
| | | cursor: pointer; |
| | | .member-change-btn { |
| | | background: #fff1f0; |
| | | border-radius: 4px; |
| | | border: 1px solid #ffccc7; |
| | | padding: 1px 8px; |
| | | font-weight: 400; |
| | | font-size: 12px; |
| | | color: #ff4d4f; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .dialog-footer { |
| | | align-items: center; |
| | | display: flex; |
| | | justify-content: center; |
| | | button { |
| | | width: 150px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | :visible="signatureDialogVisible" |
| | | @confirm="handleSignatureConfirm" |
| | | /> |
| | | <edit-dispatch |
| | | :visible.sync="approvalDialogVisible" |
| | | :type="approvalDialogType" |
| | | :data="currentApprovalData" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import SignatureCanvas from "@/components/SignatureCanvas.vue"; |
| | | import EditDispatch from "./editDispatch.vue"; |
| | | |
| | | export default { |
| | | name: "dispatchingList", |
| | | components: { |
| | | SignatureCanvas, |
| | | EditDispatch, |
| | | }, |
| | | data() { |
| | | return { |
| | |
| | | participants: "张三、李四、王五", |
| | | createTime: "2024-03-15", |
| | | status: "pending", |
| | | planName: "新材料研发项目", |
| | | planCode: "PLAN-2024-001", |
| | | stage: "实验阶段", |
| | | testDate: "2024-03-20", |
| | | testName: "材料力学性能测试", |
| | | testCode: "TEST-2024-001", |
| | | testTime: "2024-03-20 09:00", |
| | | groupTableData: [ |
| | | { |
| | | groupName: "对照组", |
| | | remark: "标准材料组" |
| | | }, |
| | | { |
| | | groupName: "实验组", |
| | | remark: "新材料组" |
| | | } |
| | | ], |
| | | taskTableData: [ |
| | | { |
| | | taskName: "材料准备", |
| | | leader: "张三", |
| | | startTime: "2024-03-20 09:00" |
| | | }, |
| | | { |
| | | taskName: "性能测试", |
| | | leader: "李四", |
| | | startTime: "2024-03-20 10:00" |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | experimentCode: "EXP-2024-002", |
| | |
| | | ], |
| | | signatureDialogVisible: false, |
| | | currentRow: null, |
| | | approvalDialogVisible: false, |
| | | approvalDialogType: "view", |
| | | currentApprovalData: null, |
| | | }; |
| | | }, |
| | | created() { |
| | |
| | | }); |
| | | }, |
| | | handleConfirm(row) { |
| | | this.currentRow = row; |
| | | this.signatureDialogVisible = true; |
| | | // this.currentRow = row; |
| | | // this.signatureDialogVisible = true; |
| | | |
| | | this.currentApprovalData = row; |
| | | this.approvalDialogType = "approve"; |
| | | this.approvalDialogVisible = true; |
| | | }, |
| | | handleSignatureConfirm(imageData) { |
| | | console.log("imageData imageData", imageData); |