<template>
  <div>
    <!-- menu -->
    <div
      v-if="checkPrivilege('button', 'SelectTikuPaper', 'TaskApplyManage')"
      class="mb-4 tab-btns"
    >
      <el-button
        v-for="tab in tabs"
        :key="tab.val"
        size="medium"
        :type="curTab == tab.val ? 'primary' : 'default'"
        @click="selectMenu(tab.val)"
        >{{ tab.name }}
      </el-button>
    </div>
    <!-- table -->
    <table class="table mb-2">
      <colgroup>
        <col width="100" />
        <col width="240" />
        <col />
        <col v-if="taskStatus.IS_APPLY && !taskStatus.IS_REBUILD" width="80" />
      </colgroup>
      <tr>
        <th>试卷类型</th>
        <th>试卷文件</th>
        <th>答题卡</th>
        <th v-if="taskStatus.IS_APPLY && !taskStatus.IS_REBUILD">操作</th>
      </tr>
      <tr v-for="(attachment, index) in paperAttachments" :key="index">
        <td>
          <span>{{ attachment.name }}卷</span>
          <span class="color-gray-2" v-if="attachment.isExposed">(已曝光)</span>
        </td>
        <template v-if="IS_TIKU_TAB">
          <!-- 试卷文件 -->
          <td>
            <template v-if="!attachment.isExposed && taskStatus.IS_APPLY">
              <div class="box-justify">
                <el-button
                  type="text"
                  class="btn-primary box-grow"
                  @click="toSelect(attachment)"
                >
                  <i
                    :class="[
                      'icon',
                      attachment.attachmentId ? 'icon-files-act' : 'icon-files',
                    ]"
                  ></i
                  >{{ attachment.filename || "选择试卷" }}
                </el-button>
                <el-button
                  type="text"
                  class="btn-primary box-static"
                  :disabled="!attachment.paperUrl"
                  @click="toViewPaper(attachment)"
                  >预览</el-button
                >
              </div>
            </template>
            <el-button
              v-else
              type="text"
              class="btn-primary"
              @click="downloadPaper(attachment)"
            >
              <div
                :class="{
                  'color-primary': auditLogCache.paper[attachment.attachmentId],
                }"
              >
                <i
                  class="icon icon-download mr-1"
                  v-if="attachment.attachmentId"
                ></i>
                {{ attachment.filename }}
              </div>
            </el-button>
          </td>
          <!-- 答题卡 -->
          <td>
            <template v-if="taskStatus.IS_APPLY">
              <el-select
                v-model="attachment.cardId"
                placeholder="请选择"
                style="width: 260px; margin-right: 10px"
                @change="(val) => tkCardChange(val, attachment)"
              >
                <el-option
                  v-for="item in attachment.cards"
                  :key="item.id"
                  :value="item.id"
                  :label="item.title"
                >
                  <div class="box-justify">
                    <div class="box-grow">{{ item.title }}</div>
                    <el-button
                      class="btn-danger btn-icon box-static"
                      type="text"
                      icon="el-icon-remove"
                      @click="toDeleteCard(item, attachment)"
                    ></el-button>
                  </div>
                </el-option>
              </el-select>
              <el-button
                class="btn-primary"
                type="text"
                :disabled="!attachment.cardId"
                @click="toViewCard(attachment)"
                >预览</el-button
              >
              <el-button
                v-if="!taskStatus.IS_REBUILD"
                class="btn-primary"
                type="text"
                :disabled="!attachment.cardId"
                @click="toEditCard(attachment)"
                >编辑</el-button
              >
            </template>
            <el-button
              v-else
              type="text"
              class="btn-primary"
              @click="toViewCard(attachment)"
              ><i
                :class="{
                  'color-primary': auditLogCache.card[attachment.cardId],
                }"
                >{{ attachment.cardTitle || "预览" }}</i
              ></el-button
            >
          </td>
        </template>
        <template v-else>
          <!-- 试卷文件 -->
          <td>
            <el-button
              v-if="!attachment.isExposed && taskStatus.IS_APPLY"
              type="text"
              class="btn-primary"
              @click="toUpload(attachment)"
            >
              <i
                :class="[
                  'icon',
                  attachment.attachmentId ? 'icon-files-act' : 'icon-files',
                ]"
              ></i
              >{{
                attachment.attachmentId
                  ? attachment.filename
                  : "点击上传试卷文件"
              }}
            </el-button>
            <el-button
              v-else
              type="text"
              class="btn-primary"
              @click="downloadPaper(attachment)"
            >
              <div
                :class="{
                  'color-primary': auditLogCache.paper[attachment.attachmentId],
                }"
              >
                <i
                  class="icon icon-download mr-1"
                  v-if="attachment.attachmentId"
                ></i>
                {{ attachment.filename }}
              </div>
            </el-button>
          </td>
          <!-- 答题卡 -->
          <td>
            <template v-if="taskStatus.IS_APPLY">
              <el-select
                class="mr-2"
                v-model="attachment.cardId"
                placeholder="请选择"
                style="width: 200px"
                filterable
                @change="cardChange(attachment)"
              >
                <el-option
                  v-for="item in cards"
                  :key="item.id"
                  :value="item.id"
                  :label="item.title"
                  :disabled="item.disabled"
                >
                  <span
                    :class="[
                      item.type === 'GENERIC'
                        ? 'color-success'
                        : 'color-primary',
                      'mr-1',
                      {
                        'color-danger': item.used,
                      },
                    ]"
                    >[{{ item.type === "GENERIC" ? "通" : "专" }}]</span
                  >
                  {{ item.title }}
                </el-option>
              </el-select>
              <span
                v-if="attachment.cardId"
                :class="[
                  attachment.cardType === 'GENERIC'
                    ? 'color-success'
                    : 'color-primary',
                  'mr-1',
                  {
                    'color-danger': attachment.used,
                  },
                ]"
                >[{{ attachment.cardType === "GENERIC" ? "通" : "专" }}]</span
              >
              <el-button
                class="btn-primary"
                type="text"
                :disabled="!attachment.cardId"
                @click="toViewCard(attachment)"
                >预览</el-button
              >
              <template v-if="!taskStatus.IS_REBUILD">
                <el-button
                  class="btn-primary"
                  type="text"
                  :disabled="
                    !attachment.cardId ||
                    (attachment.cardType === 'GENERIC' &&
                      attachment.createMethod !== 'STANDARD')
                  "
                  @click="toCopyCard(attachment)"
                  >复制</el-button
                >
                <el-button
                  class="btn-primary"
                  type="text"
                  :disabled="
                    !attachment.cardId ||
                    attachment.cardType === 'GENERIC' ||
                    !(!attachment.used && attachment.createId === user.id)
                  "
                  @click="toEditCard(attachment)"
                  >编辑</el-button
                >
                <el-button
                  class="btn-primary"
                  type="text"
                  :disabled="!taskStatus.CAN_CREATE_CARD"
                  @click="toCreateCard(attachment)"
                  >新建</el-button
                >
              </template>
            </template>
            <el-button
              v-else
              type="text"
              class="btn-primary"
              @click="toViewCard(attachment)"
            >
              <i
                :class="{
                  'color-primary': auditLogCache.card[attachment.cardId],
                }"
              >
                {{ attachment.cardTitle || "预览" }}
              </i>
            </el-button>
          </td>
        </template>
        <!-- 操作 -->
        <td
          v-if="taskStatus.IS_APPLY && !taskStatus.IS_REBUILD"
          class="text-right"
        >
          <el-button
            v-if="index === paperAttachments.length - 1"
            class="btn-primary btn-icon"
            type="text"
            icon="el-icon-circle-plus"
            @click="addAtachment"
          ></el-button>
          <el-button
            v-if="attachment.canDelete"
            class="btn-danger btn-icon"
            type="text"
            icon="el-icon-remove"
            @click="deleteAttachment(index)"
          ></el-button>
        </td>
      </tr>
      <tr v-if="!paperAttachments.length">
        <td colspan="5">
          <p class="tips-info text-center">暂无数据</p>
        </td>
      </tr>
    </table>

    <el-form v-if="!taskStatus.IS_REBUILD">
      <el-form-item label="单次抽卷卷型数量：" label-width="150">
        <el-input-number
          v-model="curTaskApply.drawCount"
          :min="1"
          :max="maxFetchCount"
          :step="1"
          :controls="false"
          step-strictly
          :disabled="!taskStatus.IS_APPLY || taskStatus.IS_EXPOSED_MODE"
        ></el-input-number>
        <!-- :disabled="!taskStatus.IS_APPLY || taskStatus.IS_EXPOSED_MODE" -->
      </el-form-item>
    </el-form>

    <!-- 附件 -->
    <h4 class="mb-2">
      附件<span v-if="taskStatus.IS_APPLY">（最多4张）</span>：
    </h4>
    <div class="image-list">
      <div
        class="image-item"
        v-for="(img, index) in paperConfirmAttachments"
        :key="index"
      >
        <img
          :src="img.url"
          :alt="img.filename"
          title="点击查看大图"
          @click="toPreview(index)"
        />
        <div v-if="taskStatus.IS_APPLY" class="image-delete">
          <i
            class="el-icon-delete-solid"
            @click="deletePaperConfirmAttachment(index)"
          ></i>
        </div>
      </div>
      <div
        v-if="paperConfirmAttachments.length < 4 && taskStatus.IS_APPLY"
        class="image-item image-add"
        title="上传附件"
        @click="toUploadPaperConfirm"
      >
        <i class="el-icon-plus"></i>
      </div>
    </div>
    <div
      v-if="!taskStatus.IS_APPLY && !paperConfirmAttachments.length"
      class="image-list-none"
    >
      暂无数据
    </div>

    <!-- 附件说明 -->
    <h4 class="mb-2">附件说明：</h4>
    <el-input
      v-if="taskStatus.IS_APPLY"
      class="mb-2"
      v-model="curTaskApply.remark"
      type="textarea"
      resize="none"
      :rows="2"
      :maxlength="100"
      clearable
      show-word-limit
      placeholder="建议不超过100个字"
    ></el-input>
    <div class="color-gray-2" v-else>
      <p v-if="curTaskApply.remark">{{ curTaskApply.remark }}</p>
      <p v-else>暂无</p>
    </div>

    <!-- upload-paper-dialog -->
    <upload-paper-dialog
      :paper-attachment="curAttachment"
      :upload-type="curUploadType"
      @confirm="uploadConfirm"
      ref="UploadPaperDialog"
    ></upload-paper-dialog>
    <!-- image-preview -->
    <simple-image-preview
      :cur-image="curImage"
      @on-prev="toPrevImage"
      @on-next="toNextImage"
      ref="SimpleImagePreview"
    ></simple-image-preview>
    <!-- ModifyCard -->
    <modify-card ref="ModifyCard" @modified="cardModified"></modify-card>

    <!-- SelectTikuPaperDialog -->
    <select-tiku-paper-dialog
      ref="SelectTikuPaperDialog"
      :row="curAttachment"
      @confirm="tikuPaperSelected"
    ></select-tiku-paper-dialog>
    <!-- CardBuildDialog -->
    <card-build-dialog
      ref="CardBuildDialog"
      :presetData="cardBuildPresetData"
      @confirm="cardBuildConfirm"
    ></card-build-dialog>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions } from "vuex";

import { cardForSelectList } from "../../api";
import { attachmentPreview } from "../../../login/api";
import { deleteCard } from "../../../base/api";
import { copyCard } from "../../../card/api";

import UploadPaperDialog from "../UploadPaperDialog.vue";
import SelectTikuPaperDialog from "../createExamAndPrintTask/SelectTikuPaperDialog.vue";
import CardBuildDialog from "../../../card/components/CardBuildDialog.vue";
import SimpleImagePreview from "../../../../components/SimpleImagePreview.vue";
import ModifyCard from "../../../card/components/ModifyCard.vue";

export default {
  name: "task-paper",
  components: {
    UploadPaperDialog,
    SimpleImagePreview,
    ModifyCard,
    CardBuildDialog,
    SelectTikuPaperDialog,
  },
  data() {
    return {
      tabs: [
        {
          name: "上传本地试卷",
          val: "upload",
        },
        {
          name: "从题库选择试卷",
          val: "tiku",
        },
      ],
      curTab: "upload",
      uuid: "",
      user: {},
      paperConfirmAttachmentId: { attachmentId: "", filename: "", url: "" },
      paperAttachments: [],
      paperConfirmAttachments: [],
      curAttachment: {},
      curUploadType: "paper",
      attachmentLimitCount: 26,
      abc: "abcdefghijklmnopqrstuvwxyz".toUpperCase(),
      cards: [],
      // card-build
      cardBuildPresetData: {},
      // image-preview
      curImage: {},
      curImageIndex: 0,
    };
  },
  computed: {
    ...mapState("exam", [
      "editType",
      "examTask",
      "curTaskApply",
      "taskStatus",
      "auditLogCache",
    ]),
    IS_TIKU_TAB() {
      return this.curTab === "tiku";
    },
    maxFetchCount() {
      return this.paperAttachments.length < 1
        ? 1
        : this.paperAttachments.length;
    },
  },
  mounted() {
    this.initData();
  },
  methods: {
    ...mapMutations("exam", ["setEditType", "setExamTask", "setCurTaskApply"]),
    ...mapActions("exam", ["addPreviewLog"]),
    initData() {
      this.paperAttachments = this.curTaskApply.paperAttachmentIds
        ? JSON.parse(this.curTaskApply.paperAttachmentIds)
        : [];

      if (!this.paperAttachments.length) {
        this.addAtachment();
      }

      const pAttachment = this.paperAttachments.some((item) => !!item.paperId);
      if (pAttachment) {
        this.curTab = "tiku";
        this.uuid = pAttachment.uuid || this.$randomCode(32);
      } else {
        this.curTab = "upload";
        this.uuid = this.$randomCode(32);
      }

      const exposedPaperType = this.curTaskApply.exposedPaperType || "";
      let exposedPaperTypes = exposedPaperType.split(",");
      exposedPaperTypes.sort((a, b) => (a > b ? -1 : 1));
      const maxExposedPaperType = exposedPaperTypes[0];
      this.paperAttachments.forEach((paper) => {
        paper.canDelete = maxExposedPaperType
          ? paper.name > maxExposedPaperType
          : true;
        paper.isExposed = exposedPaperTypes.includes(paper.name);
      });

      this.paperConfirmAttachments = this.curTaskApply.paperConfirmAttachmentIds
        ? JSON.parse(this.curTaskApply.paperConfirmAttachmentIds)
        : [];

      if (this.taskStatus.IS_APPLY) this.getCardList();
    },
    async selectMenu(tab) {
      if (!this.taskStatus.IS_APPLY) return;

      const attachment = this.paperAttachments[0];
      if (attachment.cardId || attachment.attachmentId) {
        const result = await this.$confirm(
          "更改类型会清空已设置数据，确定要更改类型？",
          "提示",
          {
            type: "warning",
          }
        ).catch(() => {});
        if (result !== "confirm") return;

        this.paperAttachments = [];
        this.addAtachment();
      }

      this.curTab = tab;
    },
    async getCardList() {
      if (!this.curTaskApply.courseId || !this.curTaskApply.examId) return;
      const data = await cardForSelectList({
        courseId: this.curTaskApply.courseId,
        examId: this.curTaskApply.examId,
        paperNumber: this.curTaskApply.paperNumber,
      });
      this.cards = data || [];
      if (this.taskStatus.IS_REBUILD) {
        this.cards = this.cards.filter((item) => item.type === "GENERIC");
      }
    },
    async getTkCardList(attachment) {
      if (
        !this.curTaskApply.courseId ||
        !this.curTaskApply.examId ||
        !attachment.paperId
      )
        return;
      const data = await cardForSelectList({
        courseId: this.curTaskApply.courseId,
        examId: this.curTaskApply.examId,
        paperId: attachment.paperId,
      });
      attachment.cards = data || [];
    },
    addAtachment() {
      if (this.paperAttachments.length >= this.attachmentLimitCount) return;

      const name = this.abc[this.paperAttachments.length];
      const newAttachment = {
        name,
        attachmentId: "",
        filename: "",
        paperId: null,
        paperUrl: null,
        uuid: null,
        cardId: "",
        cardType: "",
        createMethod: "",
        cardTitle: "",
        pages: 0,
        canDelete: true,
        isExposed: false,
        used: false,
        createId: null,
        cards: [],
      };
      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];
      });

      if (
        this.curTaskApply.drawCount &&
        this.curTaskApply.drawCount > this.paperAttachments.length
      ) {
        this.curTaskApply.drawCount = this.paperAttachments.length;
      }
    },
    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);
    },
    toViewCard(attachment) {
      this.addPreviewLog({ attachment, type: "card" });
      window.open(
        this.getRouterPath({
          name: "CardPreview",
          params: {
            cardId: attachment.cardId,
          },
        })
      );
    },
    async toCopyCard(attachment) {
      this.curAttachment = { ...attachment };
      const newCardId = await copyCard(
        attachment.cardId,
        this.curTaskApply.courseId
      );
      this.cardModified({ id: newCardId });
    },
    toEditCard(attachment) {
      this.curAttachment = { ...attachment };
      this.$ls.set("prepareTcPCard", {
        id: attachment.cardId,
        examTaskId: this.curTaskApply.examTaskId,
        courseId: this.curTaskApply.courseId,
        courseName: this.curTaskApply.courseName,
        makeMethod: this.curTaskApply.makeMethod,
        cardRuleId: this.curTaskApply.cardRuleId,
        type: attachment.cardType,
        createMethod: attachment.createMethod,
      });
      this.$refs.ModifyCard.open();
    },
    async cardModified(data) {
      // data: {id,title}
      if (!data.id) return;

      if (this.IS_TIKU_TAB) {
        const aind = this.paperAttachments.findIndex(
          (item) => item.name === this.curAttachment.name
        );
        this.paperAttachments[aind].cardTitle = data.title;
        await this.getTkCardList(this.curAttachment);

        return;
      }

      await this.getCardList();
      let card = this.cards.find((item) => item.id === data.id);

      const aind = this.paperAttachments.findIndex(
        (item) => item.name === this.curAttachment.name
      );
      if (aind !== -1 && card) {
        this.paperAttachments[aind].cardId = card.id;
        this.paperAttachments[aind].cardType = card.type;
        this.paperAttachments[aind].createMethod = card.createMethod;
        this.paperAttachments[aind].cardTitle = card.title;
        this.paperAttachments[aind].used = card.used;
        this.paperAttachments[aind].createId = card.createId;
      }
    },
    cardChange(attachment) {
      const card = this.cards.find((item) => item.id === attachment.cardId);
      if (card) {
        attachment.cardType = card.type;
        attachment.createMethod = card.createMethod;
        attachment.cardTitle = card.title;
        attachment.used = card.used;
        attachment.createId = card.createId;
      }
    },
    tkCardChange(card, attachment) {
      attachment.cardTitle = card.title;
    },
    async toDeleteCard(card, attachment) {
      const confirm = await this.$confirm(
        `确定要删除题卡【${card.title}】吗?`,
        "提示",
        {
          type: "warning",
        }
      ).catch(() => {});
      if (confirm !== "confirm") return;

      await deleteCard(card.id);
      this.$message.success("删除成功！");
      attachment.cards = attachment.cards.filter((item) => item.id !== card.id);
      if (attachment.cardId === card.id) {
        attachment.cardId = null;
        attachment.cardTitle = "";
      }
    },
    async toCreateCard(attachment) {
      if (!this.examTask.cardRuleId) {
        this.$message.error("题卡规则缺失！");
        return;
      }
      const res = await this.$prompt("确定要提交当前题卡吗?", "提示", {
        type: "warning",
        showInput: true,
        inputPlaceholder: "请输入题卡名称",
        inputValidator: (val) => {
          if (!val) return "请输入题卡名称！";
          if (val.length > 50) return "题卡名称不得超过50个字符！";
          return true;
        },
      }).catch(() => {});
      if (!res || res.action !== "confirm") return;

      this.curAttachment = { ...attachment };
      // 这里只允许新建标准专卡
      this.$ls.set("prepareTcPCard", {
        courseId: this.examTask.courseId,
        courseName: this.examTask.courseName,
        schoolName: this.$ls.get("schoolName"),
        makeMethod: "SELF",
        cardName: res.value,
        cardRuleId: this.examTask.cardRuleId,
        type: "CUSTOM",
        createMethod: "STANDARD",
      });
      this.$refs.ModifyCard.open();
    },
    async downloadPaper(attachment) {
      if (!attachment.attachmentId) return;
      this.addPreviewLog({ attachment, type: "paper" });
      const data = await attachmentPreview(attachment.attachmentId);
      window.open(data.url);
    },
    // select-paper
    toSelect(attachment) {
      this.curAttachment = {
        ...attachment,
        courseId: this.examTask.courseId,
      };
      this.$refs.SelectTikuPaperDialog.open();
    },
    async tikuPaperSelected(data) {
      this.cardBuildPresetData = {
        examId: this.examTask.examId,
        courseId: this.examTask.courseId,
        courseName: this.examTask.courseName,
        schoolName: this.$ls.get("schoolName"),
        makeMethod: "SELF",
        cardName: "",
        cardRuleId: this.examTask.cardRuleId,
        type: "CUSTOM",
        createMethod: "STANDARD",
        paperId: data.id,
        paperName: data.name,
        uuid: this.uuid,
      };
      this.$refs.CardBuildDialog.open();
    },
    cardBuildConfirm(data) {
      if (!data.success) {
        this.$message.error(data.message);
        return;
      }
      const ind = this.paperAttachments.findIndex(
        (item) => item.name === this.curAttachment.name
      );
      if (ind === -1) return;

      const info = data.data;
      this.curAttachment = { ...this.paperAttachments[ind] };
      this.paperAttachments[ind] = Object.assign(this.paperAttachments[ind], {
        paperId: this.cardBuildPresetData.paperId,
        cardType: this.cardBuildPresetData.type,
        createMethod: this.cardBuildPresetData.createMethod,
        filename: this.cardBuildPresetData.paperName,
        cardId: info.id,
        cardTitle: info.title,
        uuid: info.uuid,
        attachmentId: info.attachmentId,
        paperUrl: info.paperUrl,
      });
      this.getTkCardList(this.paperAttachments[ind]);
    },
    toViewPaper(attachment) {
      if (!attachment.paperUrl) return;
      window.open(attachment.paperUrl);
    },
    // image-preview
    toPreview(index) {
      this.curImageIndex = index;
      this.selectImage(index);
      this.$refs.SimpleImagePreview.open();
    },
    selectImage(index) {
      this.curImage = this.paperConfirmAttachments[index];
    },
    toPrevImage() {
      if (this.curImageIndex === 0) {
        this.curImageIndex = this.paperConfirmAttachments.length - 1;
      } else {
        this.curImageIndex--;
      }

      this.selectImage(this.curImageIndex);
    },
    toNextImage() {
      if (this.curImageIndex === this.paperConfirmAttachments.length - 1) {
        this.curImageIndex = 0;
      } else {
        this.curImageIndex++;
      }

      this.selectImage(this.curImageIndex);
    },
    // action
    getData() {
      let data = { ...this.curTaskApply };
      data.paperType = this.paperAttachments.map((item) => item.name).join(",");
      data.paperAttachmentIds = JSON.stringify(this.paperAttachments, (k, v) =>
        k === "url" ? undefined : v
      );
      data.paperConfirmAttachmentIds = JSON.stringify(
        this.paperConfirmAttachments
      );
      return data;
    },
    checkData() {
      if (this.IS_TIKU_TAB) {
        const paperValid = !this.paperAttachments.some((item) => !item.paperId);
        if (!paperValid) {
          this.$message.error("请完成试卷选择！");
          return;
        }

        const cardValid = !this.paperAttachments.some((item) => !item.cardId);
        if (!cardValid) {
          this.$message.error("有试卷类型未选择题卡！");
          return;
        }
      } else {
        // 设置了入库强制包含试卷时，校验试卷是否上传。
        // 未设置入库强制包含试卷时，若有试卷上传，则需要上传全部。若无试卷上传，则通过。
        if (this.curTaskApply.includePaper) {
          const attachmentValid = !this.paperAttachments.some(
            (item) => !item.attachmentId
          );
          if (!attachmentValid) {
            this.$message.error("请完成试卷文件上传！");
            return;
          }
        } else {
          const hasUploadPaperAttachments = this.paperAttachments.filter(
            (item) => item.attachmentId
          );
          if (
            hasUploadPaperAttachments.length > 0 &&
            hasUploadPaperAttachments.length !== this.paperAttachments.length
          ) {
            this.$message.error("有试卷文件未完成上传！");
            return;
          }
        }

        const cardValid = !this.paperAttachments.some((item) => !item.cardId);
        if (!cardValid) {
          this.$message.error("有试卷类型未选择题卡！");
          return;
        }
      }

      return true;
    },
  },
};
</script>
