| | |
| | | </div> |
| | | </div> |
| | | <div style="padding-left: 25px"> |
| | | <el-form-item prop="planName" label="项目课题方案名称"> |
| | | <el-input v-model="form.planName" placeholder="请输入" /> |
| | | <el-form-item prop="projectName" label="项目课题方案名称"> |
| | | <el-input |
| | | v-model="form.projectName" |
| | | placeholder="请输入" |
| | | :disabled="true" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item prop="planCode" label="项目课题方案编号"> |
| | | <el-input v-model="form.planCode" placeholder="请输入" /> |
| | | <el-form-item prop="projectCode" label="项目课题方案编号"> |
| | | <el-input |
| | | v-model="form.projectCode" |
| | | placeholder="请输入" |
| | | :disabled="true" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item prop="stage" label="项目阶段"> |
| | | <el-input v-model="form.stage" placeholder="请输入" /> |
| | | <el-form-item prop="projectStage" label="项目阶段"> |
| | | <el-select |
| | | v-model="form.projectStage" |
| | | disabled |
| | | placeholder="请选择" |
| | | > |
| | | <el-option label="实验室开发阶段" :value="1" /> |
| | | <el-option label="中式试验阶段" :value="2" /> |
| | | <el-option label="生产验证试验阶段" :value="3" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </div> |
| | | |
| | |
| | | </div> |
| | | </div> |
| | | <div style="padding-left: 25px"> |
| | | <el-form-item prop="testDate" label="试验日期"> |
| | | <el-form-item prop="experimentDate" label="实验日期"> |
| | | <el-date-picker |
| | | v-model="form.testDate" |
| | | name="data-test" |
| | | style="width: 100%" |
| | | v-model="form.experimentDate" |
| | | type="date" |
| | | placeholder="选择日期" |
| | | value-format="yyyy-MM-dd" |
| | | :disabled="true" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item prop="experimentName" label="实验名称"> |
| | | <el-input |
| | | v-model="form.experimentName" |
| | | placeholder="请输入" |
| | | :disabled="true" |
| | | /> |
| | | </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 prop="experimentCode" label="实验编号"> |
| | | <el-input |
| | | v-model="form.experimentCode" |
| | | placeholder="请输入" |
| | | :disabled="true" |
| | | /> |
| | | </el-form-item> |
| | | </div> |
| | | |
| | |
| | | </div> |
| | | </div> |
| | | <div style="padding-left: 25px"> |
| | | <el-form-item prop="testTime" label="试验时间"> |
| | | <el-form-item prop="experimentTime" label="试验时间"> |
| | | <el-date-picker |
| | | v-model="form.testTime" |
| | | type="datetime" |
| | | placeholder="选择日期时间" |
| | | style="width: 100%" |
| | | v-model="form.experimentTime" |
| | | type="datetimerange" |
| | | range-separator="至" |
| | | start-placeholder="开始时间" |
| | | end-placeholder="结束时间" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | /> |
| | | :default-time="['00:00:00', '23:59:59']" |
| | | :disabled="true" |
| | | ></el-date-picker> |
| | | </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 |
| | | v-for="item in [3, 4, 5]" |
| | | :key="item" |
| | | class="member-list-card" |
| | | > |
| | | <div class="member-item"> |
| | | <div class="member-title"> |
| | | {{ ["工艺工程师", "实验员", "化验师"][item - 1] }} |
| | | {{ ["工艺工程师", "化验师", "实验员"][item - 3] }} |
| | | </div> |
| | | <div |
| | | :class=" |
| | | item == 1 || item == 2 || item == 3 |
| | | ? 'member-name-box' |
| | | : 'flex1' |
| | | " |
| | | > |
| | | <div :class="item == 3 ? 'member-name-box' : 'flex1'"> |
| | | <div |
| | | :class=" |
| | | item == 1 || item == 2 || item == 3 |
| | | ? 'member-name-box' |
| | | : 'member-name-box-2' |
| | | item == 3 ? 'member-name-box' : 'member-name-box-2' |
| | | " |
| | | > |
| | | <div |
| | | v-for="i in memberList(item)" |
| | | :key="i" |
| | | :key="i.userId" |
| | | class="member-name" |
| | | > |
| | | 张三 |
| | | {{ i.nickName }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="member-change" v-if="type !== 'view'"> |
| | | <div class="member-change-btn">修改</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | label="任务名称" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="leader" |
| | | prop="personCharge" |
| | | label="负责人" |
| | | ></el-table-column> |
| | | <el-table-column |
| | |
| | | <span>五 、关键节点</span> |
| | | </div> |
| | | </div> |
| | | <div style="padding-left: 25px"> |
| | | <AIEditor |
| | | ref="keyNodesEditor" |
| | | :readOnly="true" |
| | | :value="form.keyNodes" |
| | | height="200" |
| | | /> |
| | | </div> |
| | | </el-form> |
| | | </template> |
| | | </Card> |
| | |
| | | <!-- 右侧审批流程 --> |
| | | <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" |
| | | /> |
| | | <approval-process :processData="form.processData" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | <SignatureCanvas |
| | | :visible="signatureDialogVisible" |
| | | @confirm="handleSignatureConfirm" |
| | | @close="signatureDialogVisible = false" |
| | | /> |
| | | </div> |
| | | </template> |
| | |
| | | <script> |
| | | import ApprovalProcess from "@/components/approvalProcess"; |
| | | import SignatureCanvas from "@/components/SignatureCanvas.vue"; |
| | | import AIEditor from "@/components/AiEditor"; |
| | | import { getDetailById, sign } from "./service"; |
| | | |
| | | export default { |
| | | name: "ApprovalDialog", |
| | | components: { |
| | | ApprovalProcess, |
| | | SignatureCanvas, |
| | | AIEditor, |
| | | }, |
| | | props: { |
| | | visible: { |
| | |
| | | data() { |
| | | return { |
| | | form: { |
| | | planName: "", |
| | | planCode: "", |
| | | stage: "", |
| | | testDate: "", |
| | | testName: "", |
| | | testCode: "", |
| | | testTime: "", |
| | | creator: "", |
| | | createTime: "", |
| | | approvalComment: "", |
| | | status: "approved", |
| | | approver: "", |
| | | approveTime: "", |
| | | projectName: "", |
| | | projectCode: "", |
| | | projectStage: "", |
| | | experimentName: "", |
| | | experimentCode: "", |
| | | experimentDate: "", |
| | | experimentTime: [], |
| | | status: "", |
| | | experimentDispatchGroups: [], |
| | | experimentDispatchParticipants: [], |
| | | experimentDispatchTasks: [], |
| | | keyNodes: "", |
| | | processData: [], |
| | | }, |
| | | rules: { |
| | | planName: [ |
| | | projectName: [ |
| | | { |
| | | required: true, |
| | | message: "请输入项目课题方案名称", |
| | | trigger: "blur", |
| | | }, |
| | | ], |
| | | planCode: [ |
| | | projectCode: [ |
| | | { |
| | | required: true, |
| | | message: "请输入项目课题方案编号", |
| | | trigger: "blur", |
| | | }, |
| | | ], |
| | | stage: [{ required: true, message: "请输入项目阶段", trigger: "blur" }], |
| | | testDate: [ |
| | | { required: true, message: "请选择试验日期", trigger: "change" }, |
| | | ], |
| | | testName: [ |
| | | experimentName: [ |
| | | { required: true, message: "请输入实验名称", trigger: "blur" }, |
| | | ], |
| | | testCode: [ |
| | | experimentCode: [ |
| | | { required: true, message: "请输入实验编号", trigger: "blur" }, |
| | | ], |
| | | testTime: [ |
| | | { required: true, message: "请选择试验时间", trigger: "change" }, |
| | | experimentDate: [ |
| | | { required: true, message: "请选择实验日期", trigger: "change" }, |
| | | ], |
| | | experimentTime: [ |
| | | { required: true, message: "请选择实验时间范围", trigger: "change" }, |
| | | ], |
| | | }, |
| | | imgSrc: "", |
| | | signatureDialogVisible: false, |
| | | status: "1", |
| | | remark: "", |
| | | groupTableData: [], |
| | | taskTableData: [], |
| | | members: { |
| | | processEngineer: [], // 工艺工程师 |
| | | experimenter: [], // 实验员 |
| | | analyst: [], // 化验师 |
| | | }, |
| | | }; |
| | | }, |
| | | computed: { |
| | |
| | | data: { |
| | | handler(val) { |
| | | if (val) { |
| | | this.form = { ...val }; |
| | | this.getDetail(val.id); |
| | | } |
| | | }, |
| | | 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]; |
| | | // 获取详情 |
| | | getDetail(id) { |
| | | getDetailById({ id }) |
| | | .then((res) => { |
| | | if (res) { |
| | | const data = res; |
| | | // 设置表单数据 |
| | | this.form = { |
| | | projectName: data.projectName, |
| | | projectCode: data.projectCode, |
| | | projectStage: data.projectStage, |
| | | experimentName: data.experimentName, |
| | | experimentCode: data.experimentCode, |
| | | experimentDate: data.experimentDate, |
| | | experimentTime: [ |
| | | data.experimentStartTime, |
| | | data.experimentEndTime, |
| | | ], |
| | | status: data.status, |
| | | experimentDispatchGroups: data.experimentDispatchGroups || [], |
| | | experimentDispatchParticipants: |
| | | data.experimentDispatchParticipants || [], |
| | | experimentDispatchTasks: data.experimentDispatchTasks || [], |
| | | keyNodes: data.keyNodes, |
| | | processData: [], |
| | | }; |
| | | |
| | | // 设置表格数据 |
| | | this.groupTableData = data.experimentDispatchGroups || []; |
| | | this.taskTableData = data.experimentDispatchTasks || []; |
| | | |
| | | // 处理参与人员数据 |
| | | this.members = { |
| | | processEngineer: |
| | | data.experimentDispatchParticipants.filter( |
| | | (p) => p.roleType === 3 |
| | | ) || [], |
| | | experimenter: |
| | | data.experimentDispatchParticipants.filter( |
| | | (p) => p.roleType === 5 |
| | | ) || [], |
| | | analyst: |
| | | data.experimentDispatchParticipants.filter( |
| | | (p) => p.roleType === 4 |
| | | ) || [], |
| | | }; |
| | | |
| | | // 组装流程数据 |
| | | let processData = []; |
| | | // 提交节点 |
| | | processData.push({ |
| | | type: "primary", |
| | | mode: "list", |
| | | fields: [ |
| | | { label: "提交人:", value: data.createBy || "" }, |
| | | { label: "提交时间:", value: data.createTime || "" }, |
| | | ], |
| | | }); |
| | | |
| | | // 处理参与人员数据,按角色分类 |
| | | const participants = data.experimentDispatchParticipants || []; |
| | | const analyst = participants.filter((p) => p.roleType === 4); // 化验师 |
| | | const experimenter = participants.filter((p) => p.roleType === 5); // 实验员 |
| | | |
| | | // 添加确认节点 |
| | | processData.push({ |
| | | type: "success", |
| | | mode: "card", |
| | | groups: [ |
| | | { |
| | | title: "化验师", |
| | | members: analyst.map((item) => ({ |
| | | name: item.nickName || "", |
| | | status: item.status === 2 ? "已确认" : "待确认", |
| | | approveTime: item.status === 2 ? item.signTime : "", |
| | | avatar: item.avatar || "", |
| | | })), |
| | | }, |
| | | { |
| | | title: "实验员", |
| | | members: experimenter.map((item) => ({ |
| | | name: item.nickName || "", |
| | | status: item.status === 2 ? "已确认" : "待确认", |
| | | approveTime: item.status === 2 ? item.signTime : "", |
| | | avatar: item.avatar || "", |
| | | })), |
| | | }, |
| | | ], |
| | | }); |
| | | |
| | | this.form.processData = processData; |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.error("获取详情失败:", err); |
| | | this.$message.error("获取详情失败"); |
| | | }); |
| | | }, |
| | | memberList(type) { |
| | | switch (type) { |
| | | case 3: // 工艺工程师 |
| | | return this.members.processEngineer; |
| | | case 5: // 实验员 |
| | | return this.members.experimenter; |
| | | case 4: // 化验师 |
| | | return this.members.analyst; |
| | | default: |
| | | break; |
| | | return []; |
| | | } |
| | | }, |
| | | handleClose() { |
| | | this.$emit("update:visible", false); |
| | | this.form.approvalComment = ""; |
| | | this.$emit("close", false); |
| | | this.signatureDialogVisible = false; |
| | | this.imgSrc = ''; |
| | | }, |
| | | handleApprove() { |
| | | if (!this.form.approvalComment) { |
| | | this.$message.warning("请输入审批意见"); |
| | | return; |
| | | } |
| | | this.$emit("approve", { |
| | | ...this.form, |
| | | status: "approved", |
| | | // 组装签名数据 |
| | | const params = { |
| | | id: this.data.id, // 传递当前调度id |
| | | signImg: this.imgSrc, // 签名图片 |
| | | }; |
| | | sign(params).then(res => { |
| | | if (res && res.code === 200) { |
| | | this.$message.success('签字成功'); |
| | | this.handleClose(); |
| | | } else { |
| | | this.$message.error(res.msg || '签字失败'); |
| | | } |
| | | }).catch(() => { |
| | | this.$message.error('签字失败'); |
| | | }); |
| | | }, |
| | | 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; |
| | | // }); |
| | | // 模拟上传签名图片,实际应调用上传接口,成功后回显图片链接 |
| | | // TODO: 替换为实际上传接口 |
| | | // uploadSignature(imageData).then(url => { this.imgSrc = url }) |
| | | this.imgSrc = 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'; // 默认图片链接 |
| | | }, |
| | | }, |
| | | }; |
| | |
| | | } |
| | | |
| | | .header-title:first-child { |
| | | margin-top: 0; |
| | | .header-title-left { |
| | | margin-top: 0; |
| | | } |