| | |
| | | <div class="header-title"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>所属实验调度</span> |
| | | <div>所属实验调度</div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="table-container"> |
| | | <el-table :data="experimentData" border style="width: 100%"> |
| | | <el-table-column prop="name" label="所属项目课题方案" /> |
| | | <el-table-column prop="code" label="实验编号" /> |
| | | <el-table-column prop="title" label="实验主题" /> |
| | | <el-table-column prop="startTime" label="实验开始时间" /> |
| | | <el-table-column prop="endTime" label="实验结束时间" /> |
| | | <el-table-column prop="participants" label="参加人员" /> |
| | | <el-table-column prop="status" label="状态" /> |
| | | <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> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <div class="header-title"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>申请说明</span> |
| | | <div>中止原因说明</div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="content-box"> |
| | | <AiEditor |
| | | ref="reasonEditor" |
| | | v-model="editorContent" |
| | | :value="editorContent" |
| | | height="200px" |
| | | placeholder="请输入申请说明..." |
| | | /> |
| | |
| | | :auto-upload="false" |
| | | :on-change="handleFileChange" |
| | | :file-list="fileList" |
| | | :on-remove="handleFileRemove" |
| | | multiple |
| | | :limit="5" |
| | | > |
| | | <el-button size="small" type="primary">选择文件</el-button> |
| | | <div slot="tip" class="el-upload__tip">支持格式:.rar .zip .doc .docx .pdf .jpg...</div> |
| | |
| | | |
| | | <div class="footer-section"> |
| | | <div class="footer-content"> |
| | | <el-button type="primary" @click="openSignatureDialog" :disabled="!agreement">提交</el-button> |
| | | <el-button type="primary" @click="openSignatureDialog" >提交</el-button> |
| | | <el-checkbox v-model="agreement">我确认,已仔细实验说明,准确描述本次实验中止全部情况及原因,特此申请中止本次实验。</el-checkbox> |
| | | </div> |
| | | </div> |
| | |
| | | |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="handleDialogClose">取 消</el-button> |
| | | <el-button type="primary" @click="handleConfirm" :disabled="!imgSrc">确 认</el-button> |
| | | <el-button type="primary" @click="handleConfirm">确 认</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | |
| | | <script> |
| | | import AiEditor from '@/components/AiEditor' |
| | | import SignatureCanvas from "@/components/SignatureCanvas.vue" |
| | | import { getDetail, applicationTermination } from './service' |
| | | |
| | | export default { |
| | | name: 'StopExperiment', |
| | |
| | | }, |
| | | data() { |
| | | return { |
| | | experimentData: [{ |
| | | name: '金标准研究项', |
| | | code: 'DD-EX001', |
| | | title: '金标准研究项', |
| | | startTime: '2025-1-2 14:50:19', |
| | | endTime: '2025-02-27', |
| | | participants: '范兵, 李天霸, 张三, 李四', |
| | | status: '已确认' |
| | | }], |
| | | id: null, |
| | | experimentData: [], |
| | | editorContent: '', |
| | | fileList: [], |
| | | agreement: false, |
| | | signatureDialogVisible: false, |
| | | signatureCanvasVisible: false, |
| | | imgSrc: "", |
| | | loading: false |
| | | } |
| | | }, |
| | | created() { |
| | | this.id = this.$route.query.id |
| | | if (this.id) { |
| | | this.getExperimentDetail() |
| | | } else { |
| | | this.$message.error('参数错误,缺少实验ID') |
| | | } |
| | | }, |
| | | methods: { |
| | | // 获取实验详情 |
| | | async getExperimentDetail() { |
| | | try { |
| | | this.loading = true |
| | | const res = await getDetail({ id: this.id }) |
| | | if (res) { |
| | | const data = res |
| | | this.experimentData = [{...data.experimentDispatch}] |
| | | } else { |
| | | this.$message.warning('未获取到实验详情') |
| | | } |
| | | } catch (error) { |
| | | console.error('获取实验详情失败:', error) |
| | | this.$message.error('获取实验详情失败') |
| | | } finally { |
| | | this.loading = false |
| | | } |
| | | }, |
| | | handleFileChange(file, fileList) { |
| | | // this.fileList = fileList |
| | | this.fileList = [{uid: Date.now(), |
| | | name: '实验中止申请表.txt', |
| | | raw: file, |
| | | size: file.size, |
| | | url:'https://example.com/files/default-stop-application.pdf', |
| | | status: 'success'}] |
| | | }, |
| | | handleFileRemove(file, fileList) { |
| | | this.fileList = fileList |
| | | }, |
| | | getEditorContent() { |
| | |
| | | }, |
| | | validateForm() { |
| | | const content = this.getEditorContent() |
| | | if (!content) { |
| | | this.$message.error('请填写申请说明') |
| | | if (!content || content === '<p></p>' || content.trim() === '<p></p>') { |
| | | this.$message.error('请填写中止原因说明') |
| | | return false |
| | | } |
| | | if (!this.agreement) { |
| | | this.$message.error('请确认申请说明') |
| | | this.$message.error('请先勾选确认申请说明') |
| | | return false |
| | | } |
| | | return true |
| | | }, |
| | | openSignatureDialog() { |
| | | if (!this.validateForm()) return |
| | | this.signatureDialogVisible = true |
| | | }, |
| | | handleDialogClose() { |
| | |
| | | }, |
| | | handleSignatureConfirm(imageData) { |
| | | this.signatureCanvasVisible = false |
| | | this.imgSrc = imageData |
| | | // this.imgSrc = imageData |
| | | this.imgSrc = 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg' |
| | | }, |
| | | handleConfirm() { |
| | | async handleConfirm() { |
| | | if (!this.imgSrc) { |
| | | this.$message.warning("请先完成签名确认") |
| | | return |
| | | } |
| | | if (this.validateForm()) { |
| | | const formData = { |
| | | reason: this.getEditorContent(), |
| | | files: this.fileList, |
| | | experimentInfo: this.experimentData[0], |
| | | signature: this.imgSrc |
| | | try { |
| | | this.loading = true |
| | | |
| | | // 处理多个文件,将文件路径和名称通过逗号拼接 |
| | | let filePaths = ''; |
| | | let fileNames = ''; |
| | | |
| | | if (this.fileList.length > 0) { |
| | | // 模拟文件路径 |
| | | filePaths = this.fileList.map(file => file.url).join(',') |
| | | |
| | | // 文件名称通过逗号拼接 |
| | | fileNames = this.fileList.map(file => file.name).join(',') |
| | | } |
| | | |
| | | const formData = { |
| | | id: this.id, // 实验方案id |
| | | stopReason: this.getEditorContent(), // 中止原因 |
| | | commitSign: this.imgSrc, // 提交签字 |
| | | stopFile: filePaths, // 中止文件路径,多个文件路径通过逗号拼接 |
| | | stopFileName: fileNames // 中止文件名称,多个文件名称通过逗号拼接 |
| | | } |
| | | |
| | | console.log('提交的数据:', formData) |
| | | |
| | | await applicationTermination(formData) |
| | | this.$message.success('提交成功') |
| | | this.handleDialogClose() |
| | | // 提交成功后返回列表页 |
| | | this.$router.go(-1) |
| | | } catch (error) { |
| | | console.error('提交失败:', error) |
| | | this.$message.error('提交失败') |
| | | } finally { |
| | | this.loading = false |
| | | } |
| | | console.log('提交的数据:', formData) |
| | | this.$message.success('提交成功') |
| | | this.handleDialogClose() |
| | | } |
| | | }, |
| | | 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] || "未知"; |
| | | } |
| | | } |
| | | } |
| | |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | } |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .header-title:first-child { |
| | |
| | | span { |
| | | font-size: 14px; |
| | | color: #222222; |
| | | &::before { |
| | | content: "*"; |
| | | color: #f56c6c; |
| | | margin-right: 4px; |
| | | } |
| | | // &::before { |
| | | // content: "*"; |
| | | // color: #f56c6c; |
| | | // margin-right: 4px; |
| | | // } |
| | | } |
| | | } |
| | | |