|
@@ -0,0 +1,455 @@
|
|
|
+<template>
|
|
|
+ <div class="apply-content task-detail">
|
|
|
+ <p class="tips-info tips-dark mb-2">
|
|
|
+ 提示:多卷型试卷由于会绑定一个答题卡模板,因此试卷结构必须相同。多卷型试卷之间客观题要求试题内容相同,可允许大题内的小题题序不同。
|
|
|
+ </p>
|
|
|
+ <div class="task-body">
|
|
|
+ <div v-if="IS_APPLY" class="mb-2 text-right">
|
|
|
+ <el-button @click="addAtachment" icon="icon icon-plus-act"
|
|
|
+ >增加卷型</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ <table class="table">
|
|
|
+ <tr>
|
|
|
+ <th>试卷类型</th>
|
|
|
+ <th>试卷文件</th>
|
|
|
+ <th>答题卡</th>
|
|
|
+ <th v-if="IS_APPLY">操作</th>
|
|
|
+ </tr>
|
|
|
+ <tr v-for="(attachment, index) in paperAttachments" :key="index">
|
|
|
+ <td>{{ attachment.name }}卷</td>
|
|
|
+ <td class="td-link">
|
|
|
+ <span
|
|
|
+ v-if="IS_APPLY"
|
|
|
+ @click="toUpload(attachment)"
|
|
|
+ title="点击上传试卷"
|
|
|
+ >
|
|
|
+ <i
|
|
|
+ :class="[
|
|
|
+ 'icon',
|
|
|
+ attachment.attachmentId ? 'icon-files-act' : 'icon-files'
|
|
|
+ ]"
|
|
|
+ ></i
|
|
|
+ >{{
|
|
|
+ attachment.attachmentId
|
|
|
+ ? attachment.filename
|
|
|
+ : "点击上传试卷文件"
|
|
|
+ }}
|
|
|
+ </span>
|
|
|
+ <span
|
|
|
+ v-else
|
|
|
+ @click="downloadPaper(attachment)"
|
|
|
+ title="点击下载试卷"
|
|
|
+ >
|
|
|
+ <i class="icon icon-download-act"></i>{{ attachment.filename }}
|
|
|
+ </span>
|
|
|
+ </td>
|
|
|
+ <td
|
|
|
+ class="td-link"
|
|
|
+ :rowspan="paperAttachments.length"
|
|
|
+ v-if="index === 0"
|
|
|
+ >
|
|
|
+ <span @click="toCreateCard"
|
|
|
+ ><i class="icon icon-plus-act"></i>{{ cardTodoName }}</span
|
|
|
+ >
|
|
|
+ </td>
|
|
|
+ <td v-if="IS_APPLY">
|
|
|
+ <el-button
|
|
|
+ class="btn-table-icon"
|
|
|
+ type="text"
|
|
|
+ icon="icon icon-delete"
|
|
|
+ title="删除"
|
|
|
+ @click="deleteAttachment(index)"
|
|
|
+ ></el-button>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </table>
|
|
|
+
|
|
|
+ <h4 class="mb-2">备注说明:</h4>
|
|
|
+ <el-input
|
|
|
+ class="mb-2"
|
|
|
+ v-model.trim="curTaskApply.remark"
|
|
|
+ type="textarea"
|
|
|
+ resize="none"
|
|
|
+ :rows="2"
|
|
|
+ :maxlength="100"
|
|
|
+ clearable
|
|
|
+ show-word-limit
|
|
|
+ placeholder="建议不超过100个字"
|
|
|
+ :disabled="!IS_APPLY"
|
|
|
+ ></el-input>
|
|
|
+
|
|
|
+ <h4 class="mb-2">上传入库审核表(最多4张)</h4>
|
|
|
+ <div class="image-list">
|
|
|
+ <div
|
|
|
+ class="image-item"
|
|
|
+ v-for="(img, index) in paperConfirmAttachments"
|
|
|
+ :key="index"
|
|
|
+ >
|
|
|
+ <img :src="img.path" :alt="img.filename" />
|
|
|
+ <div v-if="IS_APPLY" class="image-delete">
|
|
|
+ <i
|
|
|
+ class="el-icon-delete-solid"
|
|
|
+ @click="deletePaperConfirmAttachment(index)"
|
|
|
+ ></i>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="paperConfirmAttachments.length < 4 && IS_APPLY"
|
|
|
+ class="image-item image-add"
|
|
|
+ title="上传入库审核表"
|
|
|
+ @click="toUploadPaperConfirm"
|
|
|
+ >
|
|
|
+ <i class="el-icon-plus"></i>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- audit -->
|
|
|
+ <h4 v-if="IS_AUDIT" class="mb-2">审核意见:</h4>
|
|
|
+ <el-input
|
|
|
+ v-if="IS_AUDIT"
|
|
|
+ class="mb-2"
|
|
|
+ v-model.trim="reason"
|
|
|
+ type="textarea"
|
|
|
+ resize="none"
|
|
|
+ :rows="5"
|
|
|
+ :maxlength="1000"
|
|
|
+ clearable
|
|
|
+ show-word-limit
|
|
|
+ placeholder="建议不超过1000个字"
|
|
|
+ ></el-input>
|
|
|
+ </div>
|
|
|
+ <div class="task-action">
|
|
|
+ <el-button
|
|
|
+ v-if="IS_APPLY"
|
|
|
+ type="primary"
|
|
|
+ :disabled="isSubmit"
|
|
|
+ @click="submit"
|
|
|
+ >确认提交</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ v-if="IS_APPLY"
|
|
|
+ type="primary"
|
|
|
+ :disabled="isSubmit"
|
|
|
+ style="width:88px;"
|
|
|
+ @click="toSave"
|
|
|
+ >暂存</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ v-if="IS_AUDIT"
|
|
|
+ type="primary"
|
|
|
+ :disabled="isSubmit"
|
|
|
+ @click="toAuditApply('PASS')"
|
|
|
+ >通过</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ v-if="IS_AUDIT"
|
|
|
+ type="danger"
|
|
|
+ plain
|
|
|
+ @click="toAuditApply('NOT_PASS')"
|
|
|
+ >不通过</el-button
|
|
|
+ >
|
|
|
+ <el-button type="danger" @click="cancel" plain>取消</el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- upload-paper-dialog -->
|
|
|
+ <upload-paper-dialog
|
|
|
+ :paper-attachment="curAttachment"
|
|
|
+ :upload-type="curUploadType"
|
|
|
+ @confirm="uploadConfirm"
|
|
|
+ ref="UploadPaperDialog"
|
|
|
+ ></upload-paper-dialog>
|
|
|
+ <!-- card-option-dialog -->
|
|
|
+ <card-option-dialog
|
|
|
+ :data="task"
|
|
|
+ ref="CardOptionDialog"
|
|
|
+ @upload-sample-over="initData"
|
|
|
+ @draft-task="silentSave"
|
|
|
+ @confirm="cardConfirm"
|
|
|
+ ></card-option-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import UploadPaperDialog from "./UploadPaperDialog";
|
|
|
+import CardOptionDialog from "./CardOptionDialog";
|
|
|
+import { taskApplyDetail, updateTaskApply, updateTaskReview } from "../api";
|
|
|
+
|
|
|
+const initTaskApply = {
|
|
|
+ id: "",
|
|
|
+ examTaskId: "",
|
|
|
+ paperType: "A",
|
|
|
+ paperAttachmentIds: "",
|
|
|
+ paperConfirmAttachmentIds: "",
|
|
|
+ cardId: "",
|
|
|
+ cardSource: "",
|
|
|
+ refCardId: "",
|
|
|
+ remark: ""
|
|
|
+};
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "apply-content",
|
|
|
+ components: { UploadPaperDialog, CardOptionDialog },
|
|
|
+ props: {
|
|
|
+ examTask: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ },
|
|
|
+ viewType: {
|
|
|
+ type: String,
|
|
|
+ default: "APPLY",
|
|
|
+ validator: val => ["APPLY", "VIEW", "AUDIT"].includes(val)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ isSubmit: false,
|
|
|
+ curTaskApply: { ...initTaskApply },
|
|
|
+ paperConfirmAttachmentId: { attachmentId: "", filename: "", path: "" },
|
|
|
+ paperAttachments: [],
|
|
|
+ paperConfirmAttachments: [],
|
|
|
+ curAttachment: {},
|
|
|
+ curUploadType: "paper",
|
|
|
+ attachmentLimitCount: 26,
|
|
|
+ abc: "abcdefghijklmnopqrstuvwxyz".toUpperCase(),
|
|
|
+ task: {},
|
|
|
+ reason: ""
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ IS_APPLY() {
|
|
|
+ return this.viewType === "APPLY";
|
|
|
+ },
|
|
|
+ IS_VIEW() {
|
|
|
+ return this.viewType === "VIEW";
|
|
|
+ },
|
|
|
+ IS_AUDIT() {
|
|
|
+ return this.viewType === "AUDIT";
|
|
|
+ },
|
|
|
+ cardTodoName() {
|
|
|
+ let name = "创建答题卡";
|
|
|
+ if (this.curTaskApply.cardId) {
|
|
|
+ if (this.curTaskApply.cardSource === 0) {
|
|
|
+ name = "选择题卡";
|
|
|
+ } else if (this.curTaskApply.cardSource === 1) {
|
|
|
+ name = "编辑题卡";
|
|
|
+ } else {
|
|
|
+ // 已经审核的题卡可以自行编辑,未审核的题卡只能查看
|
|
|
+ // name = this.curTaskApply.auditingStatus ? "编辑题卡" : "查看题卡";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return name;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.initData();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async initData() {
|
|
|
+ const data = await taskApplyDetail(this.examTask.id);
|
|
|
+ this.curTaskApply = this.$objAssign(initTaskApply, data);
|
|
|
+ this.paperAttachments = data.paperAttachmentIds
|
|
|
+ ? JSON.parse(data.paperAttachmentIds)
|
|
|
+ : [];
|
|
|
+ this.paperConfirmAttachments = data.paperConfirmAttachmentIds
|
|
|
+ ? JSON.parse(data.paperConfirmAttachmentIds)
|
|
|
+ : [];
|
|
|
+ },
|
|
|
+ addAtachment() {
|
|
|
+ if (this.paperAttachments.length >= this.attachmentLimitCount) return;
|
|
|
+
|
|
|
+ const newAttachment = {
|
|
|
+ name: this.abc[this.paperAttachments.length],
|
|
|
+ attachmentId: "",
|
|
|
+ filename: "",
|
|
|
+ pages: 0
|
|
|
+ };
|
|
|
+ this.paperAttachments.push(newAttachment);
|
|
|
+ },
|
|
|
+ deleteAttachment(index) {
|
|
|
+ if (this.paperAttachments.length <= 1) {
|
|
|
+ this.$message.error("试卷类型数量不得少于1");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.paperAttachments.splice(index, 1);
|
|
|
+ this.paperAttachments.forEach((item, itemIndex) => {
|
|
|
+ item.name = this.abc[itemIndex];
|
|
|
+ });
|
|
|
+ },
|
|
|
+ toUpload(attachment) {
|
|
|
+ this.curUploadType = "paper";
|
|
|
+ this.curAttachment = {
|
|
|
+ ...attachment
|
|
|
+ };
|
|
|
+ this.$refs.UploadPaperDialog.open();
|
|
|
+ },
|
|
|
+ toUploadPaperConfirm() {
|
|
|
+ if (this.paperConfirmAttachments.length >= 4) return;
|
|
|
+ this.curUploadType = "paperConfirm";
|
|
|
+ this.curAttachment = {
|
|
|
+ ...this.paperConfirmAttachmentId
|
|
|
+ };
|
|
|
+ this.$refs.UploadPaperDialog.open();
|
|
|
+ },
|
|
|
+ uploadConfirm(attachment, uploadType) {
|
|
|
+ if (uploadType === "paper") {
|
|
|
+ const index = this.paperAttachments.findIndex(
|
|
|
+ item => item.name === attachment.name
|
|
|
+ );
|
|
|
+ this.paperAttachments.splice(index, 1, { ...attachment });
|
|
|
+ } else {
|
|
|
+ this.paperConfirmAttachments.push(attachment);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ deletePaperConfirmAttachment(index) {
|
|
|
+ this.paperConfirmAttachments.splice(index, 1);
|
|
|
+ },
|
|
|
+ toCreateCard() {
|
|
|
+ this.task = {
|
|
|
+ ...this.getTaskData(),
|
|
|
+ auditStatus: this.examTask.auditStatus,
|
|
|
+ examTaskId: this.examTask.id,
|
|
|
+ cardRuleId: this.examTask.cardRuleId
|
|
|
+ };
|
|
|
+ if (this.curTaskApply.cardId) {
|
|
|
+ if (this.curTaskApply.cardSource === 0) {
|
|
|
+ this.$refs.CardOptionDialog.open();
|
|
|
+ } else if (this.curTaskApply.cardSource === 1) {
|
|
|
+ this.$router.push({
|
|
|
+ name: "CardDesign",
|
|
|
+ params: {
|
|
|
+ cardId: this.curTaskApply.cardId
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ if (this.curTaskApply.auditingStatus) {
|
|
|
+ this.$router.push({
|
|
|
+ name: "CardDesign",
|
|
|
+ params: {
|
|
|
+ cardId: this.curTaskApply.cardId
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ window.open(
|
|
|
+ this.getRouterPath({
|
|
|
+ name: "CardPreview",
|
|
|
+ params: {
|
|
|
+ cardId: this.curTaskApply.cardId,
|
|
|
+ viewType: "view"
|
|
|
+ }
|
|
|
+ })
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.$refs.CardOptionDialog.open();
|
|
|
+ },
|
|
|
+ cancel() {
|
|
|
+ this.$emit("cancel");
|
|
|
+ },
|
|
|
+ downloadPaper(attachment) {
|
|
|
+ window.open(attachment.path);
|
|
|
+ },
|
|
|
+ cardConfirm(data) {
|
|
|
+ this.curTaskApply = this.$objAssign(this.curTaskApply, data);
|
|
|
+ },
|
|
|
+ getTaskData() {
|
|
|
+ let data = { ...this.curTaskApply };
|
|
|
+ data.paperType = this.paperAttachments.map(item => item.name).join();
|
|
|
+ data.paperAttachmentIds = JSON.stringify(this.paperAttachments);
|
|
|
+ data.paperConfirmAttachmentIds = JSON.stringify(
|
|
|
+ this.paperConfirmAttachments
|
|
|
+ );
|
|
|
+ console.log(data);
|
|
|
+ return data;
|
|
|
+ },
|
|
|
+ checkDataValid() {
|
|
|
+ const attachmentValid = !this.paperAttachments.some(
|
|
|
+ item => !item.attachmentId
|
|
|
+ );
|
|
|
+ if (!attachmentValid) {
|
|
|
+ this.$message.error("请完成试卷文件上传!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!this.paperConfirmAttachments.length) {
|
|
|
+ this.$message.error("请上传入库审核表!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.task.cardId && !this.task.refCardId) {
|
|
|
+ this.$message.error("请选择题卡创建方式!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+ async toSave() {
|
|
|
+ if (this.isSubmit) return;
|
|
|
+ this.isSubmit = true;
|
|
|
+ const datas = this.getTaskData();
|
|
|
+ datas.operateType = "STAGE";
|
|
|
+ const data = await updateTaskApply(datas).catch(() => {});
|
|
|
+ this.isSubmit = false;
|
|
|
+ if (!data) return;
|
|
|
+
|
|
|
+ this.$message.success("保存成功!");
|
|
|
+ },
|
|
|
+ async silentSave() {
|
|
|
+ const datas = this.getTaskData();
|
|
|
+ datas.operateType = "STAGE";
|
|
|
+ await updateTaskApply(datas).catch(() => {});
|
|
|
+ },
|
|
|
+ async submit() {
|
|
|
+ if (!this.checkDataValid()) return;
|
|
|
+
|
|
|
+ this.$confirm(
|
|
|
+ "任务确定提交后,则不可更改试卷及答题卡内容,确定提交该任务?",
|
|
|
+ "提示",
|
|
|
+ {
|
|
|
+ cancelButtonClass: "el-button--danger is-plain",
|
|
|
+ confirmButtonClass: "el-button--primary",
|
|
|
+ type: "warning"
|
|
|
+ }
|
|
|
+ ).then(async () => {
|
|
|
+ const datas = this.getTaskData();
|
|
|
+ datas.operateType = "SUBMIT";
|
|
|
+ const data = await updateTaskApply(datas).catch(() => {});
|
|
|
+ if (!data) return;
|
|
|
+ this.$message.success("提交成功!");
|
|
|
+ this.goback();
|
|
|
+ this.$emit("modified");
|
|
|
+ });
|
|
|
+ },
|
|
|
+ toAuditApply(type) {
|
|
|
+ if (type === "PASS") {
|
|
|
+ this.auditApply(type);
|
|
|
+ } else {
|
|
|
+ if (!this.reason) {
|
|
|
+ this.$message.error("请输入审核意见!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.$confirm("确定不通过该申请吗?", "提示", {
|
|
|
+ cancelButtonClass: "el-button--danger is-plain",
|
|
|
+ confirmButtonClass: "el-button--primary",
|
|
|
+ type: "warning"
|
|
|
+ }).then(() => {
|
|
|
+ this.auditApply(type);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async auditApply(type) {
|
|
|
+ const data = await updateTaskReview({
|
|
|
+ reviewStatus: type,
|
|
|
+ examTaskId: this.examTask.id,
|
|
|
+ reason: this.reason
|
|
|
+ }).catch(() => {});
|
|
|
+ if (!data) return;
|
|
|
+ this.$message.success("审核成功!");
|
|
|
+ this.$emit("modified");
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|