<template>
  <div class="apply-content task-detail">
    <div class="task-body">
      <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 class="table mb-2">
        <colgroup>
          <col width="100" />
          <col width="240" />
          <col />
          <col v-if="IS_APPLY && !IS_REBUILD" width="80" />
        </colgroup>
        <tr>
          <th>试卷类型</th>
          <th>试卷文件</th>
          <th>答题卡</th>
          <th v-if="IS_APPLY && !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>
              <el-button
                v-if="!attachment.isExposed && IS_APPLY"
                type="text"
                class="btn-primary"
                @click="toSelect(attachment)"
              >
                <i
                  :class="[
                    'icon',
                    attachment.attachmentId ? 'icon-files-act' : 'icon-files',
                  ]"
                ></i
                >{{ 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="IS_APPLY">
                <el-select
                  v-model="attachment.cardId"
                  placeholder="请选择"
                  style="width: 260px; margin-right: 10px"
                >
                  <el-option
                    v-if="attachment.cardId"
                    :value="attachment.cardId"
                    :label="attachment.cardTitle"
                  >
                  </el-option>
                </el-select>
                <el-button
                  class="btn-primary"
                  type="text"
                  :disabled="!attachment.cardId"
                  @click="toViewCard(attachment)"
                  >预览</el-button
                >
                <el-button
                  v-if="!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 && 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="IS_APPLY">
                <el-select
                  class="mr-2"
                  v-model="attachment.cardId"
                  placeholder="请选择"
                  style="width: 200px"
                  filterable
                  @visible-change="
                    (visible) => cardOptionOpened(visible, attachment)
                  "
                  @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="!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="!canCreateCard"
                    @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="IS_APPLY && !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="!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="!IS_APPLY || exposedMode"
          ></el-input-number>
          <!-- :disabled="!IS_APPLY || exposedMode" -->
        </el-form-item>
      </el-form>

      <h4 class="mb-2">附件<span v-if="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="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>
      <div
        v-if="!IS_APPLY && !paperConfirmAttachments.length"
        class="image-list-none"
      >
        暂无数据
      </div>

      <h4 class="mb-2">附件说明：</h4>
      <el-input
        v-if="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>
      <!-- 作废 -->
      <el-alert
        v-if="curTaskApply.taskStatus === 'CANCEL'"
        class="mt-1"
        :title="`已作废，原因：${curTaskApply.cancelRemark || ''}`"
        type="error"
        :closable="false"
      >
      </el-alert>

      <!-- 入库申请-审核阶段 -->
      <!-- audit history -->
      <div
        v-if="flowHistoryList.length && curTaskApply.flowStatus !== 'START'"
        class="task-audit-history flow-timeline"
      >
        <h4 class="mb-4">审核记录：</h4>
        <el-timeline>
          <el-timeline-item
            v-for="flow in flowHistoryList"
            :key="flow.stepKey"
            :type="flow.type"
            hide-timestamp
            size="large"
            placement="top"
            :class="{ 'timeline-item-stop': flow.nextIsNewFlow }"
          >
            <div class="flow-item">
              <div class="flow-item-content">
                <p v-if="flow.createTime" class="flow-item-time">
                  {{ flow.createTime | timestampFilter }}
                </p>
                <h4 class="flow-item-title">{{ flow.approveUserName }}</h4>
                <p class="flow-item-desc">
                  <span
                    v-if="flow.approveOperation"
                    :class="{
                      'color-danger': flow.approveOperation === 'REJECT',
                    }"
                    >{{
                      flow.approveOperation | flowApproveOperationTypeFilter
                    }}</span
                  >
                  <span>{{ flow.approveRemark }}</span>
                </p>
                <div
                  v-if="flow.attachments.length"
                  class="flow-item-attachment"
                >
                  <span>附件：</span>
                  <more-btn
                    v-for="item in flow.attachments"
                    :key="item.name"
                    type="text"
                    class="btn-primary"
                    :data="`${item.name}卷:${item.filename}`"
                    :show-count="20"
                    @click="downloadPaper(item)"
                  ></more-btn>
                </div>
                <div
                  v-if="flow.isApproveSetFlowNextNode && approveUsers.length"
                  class="flow-item-users"
                >
                  <span>审批人：</span>
                  <el-tag
                    v-for="user in approveUsers"
                    :key="user.id"
                    size="small"
                    :disable-transitions="false"
                  >
                    {{ user.name }}
                  </el-tag>
                </div>
              </div>
              <div
                v-if="
                  flow.isApproveSetFlowNextNode &&
                  ((IS_AUDIT && auditModal.approvePass === 'PASS') ||
                    curTaskApply.flowStatus === 'REJECT' ||
                    curTaskApply.flowStatus === 'CANCEL')
                "
                class="flow-item-action"
              >
                <el-button
                  class="user-select"
                  icon="el-icon-plus"
                  @click="toSelectNextFlowUser"
                ></el-button>
                <p v-if="!approveUsers.length" class="tips-info tips-error">
                  请选择审核人
                </p>
              </div>
            </div>
          </el-timeline-item>
        </el-timeline>
      </div>
      <!-- 入库申请-申请阶段 -->
      <div
        v-if="flowList.length && curTaskApply.flowStatus === 'START'"
        class="task-audit-history flow-timeline"
      >
        <h4 class="mb-4">流程：</h4>
        <el-timeline>
          <el-timeline-item
            v-for="flow in flowList"
            :key="flow.taskKey"
            :type="flow.type"
          >
            <div class="flow-item">
              <div class="flow-item-content">
                <h4 class="flow-item-title">{{ flow.taskName }}</h4>
                <p v-if="flow.approveUserNames" class="flow-item-desc">
                  {{ flow.approveUserNames }}
                </p>
                <div
                  v-if="flow.isApproveSetFlowNextNode && approveUsers.length"
                  class="flow-item-users"
                >
                  <span>审批人：</span>
                  <el-tag
                    v-for="user in approveUsers"
                    :key="user.id"
                    size="small"
                    :disable-transitions="false"
                  >
                    {{ user.name }}
                  </el-tag>
                </div>
              </div>
              <div
                v-if="flow.isApproveSetFlowNextNode"
                class="flow-item-action"
              >
                <el-button
                  class="user-select"
                  icon="el-icon-plus"
                  @click="toSelectNextFlowUser"
                ></el-button>
                <p v-if="!approveUsers.length" class="tips-info tips-error">
                  请选择审核人
                </p>
              </div>
            </div>
          </el-timeline-item>
        </el-timeline>
      </div>

      <!-- audit -->
      <div v-if="IS_AUDIT" class="task-audit">
        <el-form
          ref="auditModalComp"
          :model="auditModal"
          :rules="auditRules"
          label-width="90px"
        >
          <el-form-item prop="approvePass" label="审批操作：">
            <el-radio-group
              v-model="auditModal.approvePass"
              @change="approvePassChange"
            >
              <el-radio
                v-for="(val, key) in TASK_AUDIT_RESULT"
                :key="key"
                :label="key"
                >{{ val }}</el-radio
              >
            </el-radio-group>
          </el-form-item>
          <el-form-item
            v-if="auditModal.approvePass === 'REJECT'"
            prop="setup"
            label="驳回节点："
          >
            <el-select
              v-model="auditModal.setup"
              placeholder="请选择"
              style="width: 100%"
            >
              <el-option
                v-for="item in rejectSetupList"
                :key="item.taskKey"
                :value="item.setup"
                :label="item.name"
              >
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="auditModal.approvePass !== 'EXCHANGE'"
            :key="auditModal.approvePass"
            prop="remark"
            label="审批意见："
          >
            <el-input
              class="mb-2"
              v-model="auditModal.remark"
              type="textarea"
              resize="none"
              :rows="5"
              :maxlength="100"
              clearable
              show-word-limit
              placeholder="建议不超过100个字"
              ref="ReasonInput"
            ></el-input>
          </el-form-item>
          <el-form-item
            v-if="auditModal.approvePass === 'EXCHANGE'"
            prop="userId"
            label="审批人："
          >
            <el-tag
              v-for="user in exchangeUsers"
              :key="user.id"
              :disable-transitions="false"
              size="medium"
            >
              {{ user.name }}
            </el-tag>
            <el-button
              class="ml-2"
              size="mini"
              type="primary"
              @click="toSelectExchangeUser"
              >选择用户</el-button
            >
          </el-form-item>
        </el-form>
      </div>
    </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"
        @click="toSave"
        >暂存</el-button
      > -->
      <el-button
        v-if="IS_AUDIT"
        type="primary"
        :disabled="isSubmit"
        @click="toAuditSubmit"
        >确定</el-button
      >
      <!-- <el-button
        v-if="IS_AUDIT_APPLY"
        type="primary"
        :disabled="isSubmit"
        @click="toAuditApply"
        >提交</el-button
      > -->
      <el-button @click="cancel">取消</el-button>
    </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>
    <!-- select-user-dialog -->
    <select-user-dialog
      v-if="IS_AUDIT || IS_NEED_SELECT_APPROVE_USER"
      ref="SelectUserDialog"
      :user-limit-count="userLimitCount"
      :filter-roles="userFilterRoles"
      :users="curSelectedUsers"
      @modified="userSelected"
    ></select-user-dialog>
    <!-- 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 UploadPaperDialog from "./UploadPaperDialog";
import SelectTikuPaperDialog from "./createExamAndPrintTask/SelectTikuPaperDialog.vue";
import CardBuildDialog from "../../card/components/CardBuildDialog.vue";

import {
  taskApplyDetail,
  updateTaskApply,
  taskAuditApply,
  cardForSelectList,
  savePreviewLog,
} from "../api";
import { attachmentPreview } from "../../login/api";
import SimpleImagePreview from "@/components/SimpleImagePreview";
import SelectUserDialog from "../../base/components/SelectUserDialog";
import ModifyCard from "../../card/components/ModifyCard";
import { TASK_AUDIT_RESULT, COMMON_CARD_RULE_ID } from "@/constants/enumerate";
import {
  taskFlowDetail,
  taskFlowApproverExchange,
  taskFlowNodeInfo,
  taskFlowApprover,
  flowDetailByFlowId,
} from "../../base/api";
import { copyCard } from "../../card/api";

const initTaskApply = {
  examId: "",
  examTaskId: "",
  category: "",
  paperNumber: "",
  paperType: "A",
  paperAttachmentIds: "",
  paperConfirmAttachmentIds: "",
  cardId: "",
  cardRuleId: "",
  makeMethod: "",
  remark: "",
  courseId: "",
  courseCode: "",
  courseName: "",
  drawCount: 1,
  exposedPaperType: "",
  auditContent: [],
  // 流程
  flowId: "",
  flowStatus: "",
  setup: null,
  // 工作台任务id
  flowTaskId: "",
  // 题卡状态
  status: "",
  // 考务规则
  review: false,
  includePaper: false,
  customCard: false,
  // 作废
  taskStatus: "",
  cancelRemark: "",
};

export default {
  name: "apply-content",
  components: {
    UploadPaperDialog,
    SimpleImagePreview,
    SelectUserDialog,
    ModifyCard,
    CardBuildDialog,
    SelectTikuPaperDialog,
  },
  props: {
    examTask: {
      type: Object,
      default() {
        return {};
      },
    },
    editType: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      isSubmit: false,
      tabs: [
        {
          name: "上传本地试卷",
          val: "upload",
        },
        {
          name: "从题库选择试卷",
          val: "tiku",
        },
      ],
      curTab: "upload",
      user: {},
      curTaskApply: { ...initTaskApply },
      paperConfirmAttachmentId: { attachmentId: "", filename: "", url: "" },
      paperAttachments: [],
      paperConfirmAttachments: [],
      curAttachment: {},
      curUploadType: "paper",
      attachmentLimitCount: 26,
      abc: "abcdefghijklmnopqrstuvwxyz".toUpperCase(),
      cards: [],
      task: {},
      reason: "",
      TASK_AUDIT_RESULT: { ...TASK_AUDIT_RESULT, EXCHANGE: "转他人审批" },
      // audit
      flowList: [],
      flowInfo: {},
      auditModal: {
        approvePass: "PASS",
        setup: "",
        remark: "",
        userId: "",
      },
      auditRules: {
        approvePass: [
          {
            required: true,
          },
        ],
        setup: [
          {
            required: true,
            validator: (rule, value, callback) => {
              if (this.auditModal.approvePass === "REJECT" && !value) {
                callback(new Error(`请选择要驳回到的节点`));
              } else {
                callback();
              }
            },
            trigger: "change",
          },
        ],
        remark: [
          {
            required: false,
            validator: (rule, value, callback) => {
              if (this.auditModal.approvePass === "REJECT" && !value) {
                callback(new Error(`请输入审批意见`));
              } else {
                callback();
              }
            },
            trigger: "change",
          },
        ],
        userId: [
          {
            required: true,
            message: "请选择审批人",
            trigger: "change",
          },
        ],
      },
      flowHistoryList: [],
      rejectSetupList: [], // 可以驳回的节点
      exchangeUsers: [],
      selectUserType: "exchange", // exchange:转审，approve:下一节点审核
      curSelectedUsers: [],
      auditLogCache: { paper: {}, card: {} },
      // card-build
      cardBuildPresetData: {},
      // 选择下一节点审批人
      IS_NEED_SELECT_APPROVE_USER: false,
      nextFlowTaskResult: {}, //下一节点信息
      approveUsers: [],
      userLimitCount: 1,
      userFilterRoles: [],
      // image-preview
      curImage: {},
      curImageIndex: 0,
    };
  },
  computed: {
    IS_APPLY() {
      return this.editType
        ? this.editType === "APPLY"
        : this.curTaskApply.setup === 1 || this.curTaskApply.setup === null;
    },
    IS_PREVIEW() {
      return this.editType
        ? this.editType === "PREVIEW"
        : this.curTaskApply.setup !== null && this.curTaskApply.setup <= 0;
    },
    IS_AUDIT() {
      const IS_COMMON_AUDIT = this.editType
        ? this.editType === "AUDIT"
        : this.curTaskApply.setup > 1;
      return IS_COMMON_AUDIT;
    },
    FLOW_IS_OVER() {
      return ["END", "FINISH"].includes(this.curTaskApply.flowStatus);
    },
    IS_TIKU_TAB() {
      return this.curTab === "tiku";
    },
    maxFetchCount() {
      return this.paperAttachments.length < 1
        ? 1
        : this.paperAttachments.length;
    },
    canCreateCard() {
      return (
        this.curTaskApply.courseId &&
        this.curTaskApply.examId &&
        this.curTaskApply.cardRuleId !== COMMON_CARD_RULE_ID
      );
    },
    exposedMode() {
      return !!this.curTaskApply.exposedPaperType;
    },
    IS_REBUILD() {
      return this.curTaskApply.category === "REBUILD";
    },
  },
  mounted() {
    this.user = this.$ls.get("user", {});
    this.initData();
  },
  methods: {
    async initData() {
      const data = await taskApplyDetail(
        this.examTask.id,
        this.examTask.source
      );
      this.$emit("info-update", {
        setup: data.setup,
        semesterName: data.semesterName,
        examId: data.examId,
        examName: data.examName,
        examModel: data.examModel,
      });
      this.curTaskApply = this.$objAssign(initTaskApply, data || {});
      this.curTaskApply.examId =
        this.curTaskApply.examId || this.examTask.examId;
      this.curTaskApply.examTaskId = this.examTask.id;
      this.curTaskApply.courseId = this.examTask.courseId;
      this.curTaskApply.courseName = this.examTask.courseName;
      this.curTaskApply.cardRuleId = this.examTask.cardRuleId;
      this.curTaskApply.customCard = this.examTask.customCard;
      this.curTaskApply.paperNumber = this.examTask.paperNumber;
      this.curTaskApply.auditContent = JSON.parse(
        this.curTaskApply.auditContent || "[]"
      );
      this.curTaskApply.includePaper =
        data.printContent.indexOf("PAPER") !== -1;
      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.curTaskApply.uuid = pAttachment.uuid || this.$randomCode(32);
      } else {
        this.curTab = "upload";
        this.curTaskApply.uuid = this.$randomCode(32);
      }

      const exposedPaperType = data.exposedPaperType || "";
      let exposedPaperTypes = exposedPaperType.split(",");
      exposedPaperTypes.sort((a, b) => (a > b ? -1 : 1));
      const maxExposedPaperType = exposedPaperTypes[0];
      let auditLogCache = { paper: {}, card: {} };
      this.paperAttachments.forEach((paper) => {
        paper.canDelete = maxExposedPaperType
          ? paper.name > maxExposedPaperType
          : true;
        paper.isExposed = exposedPaperTypes.includes(paper.name);
        if (
          paper.attachmentId &&
          this.curTaskApply.auditContent.includes("PAPER")
        )
          auditLogCache.paper[paper.attachmentId] = false;
        if (paper.cardId && this.curTaskApply.auditContent.includes("CARD"))
          auditLogCache.card[paper.cardId] = false;
      });
      this.auditLogCache = auditLogCache;

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

      if (this.IS_APPLY) this.getCardList();

      // flow
      if (this.curTaskApply.flowStatus === "START") {
        await this.getFlowList();
      } else {
        await this.getFlowHistory();
        if (!this.IS_PREVIEW && this.curTaskApply.review)
          this.getCurFlowNodeInfo();
      }

      // if (this.IS_AUDIT) this.getCurFlowNodeInfo();
    },
    async selectMenu(tab) {
      if (!this.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.IS_REBUILD) {
        this.cards = this.cards.filter((item) => item.type === "GENERIC");
      }
    },
    async getFlowHistory() {
      if (!this.curTaskApply.flowId) return;

      const data = await taskFlowDetail(this.curTaskApply.flowId).catch(
        () => {}
      );
      if (!data) return;

      const FLOW_STATUS = {
        SUBMIT: "success",
        APPROVE: "success",
        EXCHANGE: "success",
        REJECT: "danger",
        END: "success",
      };
      let nextFlowId = "";
      this.flowHistoryList = data.tfFlowViewLogResultList.map((item, index) => {
        const nextItem = data.tfFlowViewLogResultList[index + 1];
        nextFlowId = nextItem ? nextItem.flowId : item.flowId;
        item.nextIsNewFlow = nextFlowId !== item.flowId;
        item.type = FLOW_STATUS[item.approveOperation];
        item.attachments = item.paperAttachmentId
          ? JSON.parse(item.paperAttachmentId)
          : [];
        item.isApproveSetFlowNextNode = false;
        return item;
      });
      const flowIsEnd = data.currFlowTaskResult.taskKey === "end";
      this.flowHistoryList.push({
        type: flowIsEnd ? "success" : "current",
        stepKey: this.$randomCode(),
        approveSetup: data.currFlowTaskResult.setup, //审批人节点
        approveRemark: data.currFlowTaskResult.taskName, //审批信息
        approveOperation: flowIsEnd ? "END" : "",
        approveUserName: data.currFlowTaskResult.approveUserNames, //审批人
        createTime: null,
        nextIsNewFlow: false,
        isApproveSetFlowNextNode: false,
        attachments: [],
      });
    },
    async getFlowList() {
      if (!this.curTaskApply.flowId) return;
      const data = await flowDetailByFlowId(this.curTaskApply.flowId);
      if (!data) return;

      const modelType =
        data.flowTaskResultList[0] && data.flowTaskResultList[0].modelType;
      this.flowInfo = {
        customFlowId: data.id,
        version: data.version,
      };
      const nextFlowNodeIndex = 1;
      this.IS_NEED_SELECT_APPROVE_USER = modelType === "APPROVE_SET";
      const flowList = data.flowTaskResultList || [];
      this.flowList = flowList.map((flow, index) => {
        flow.isApproveSetFlowNextNode =
          this.IS_NEED_SELECT_APPROVE_USER && index === nextFlowNodeIndex;
        return flow;
      });

      if (this.flowList.length) {
        this.flowList[0].type = "success";
      }

      this.nextFlowTaskResult = this.flowList[nextFlowNodeIndex];
    },
    async getCurFlowNodeInfo() {
      const data = await taskFlowNodeInfo(this.curTaskApply.flowTaskId);
      this.rejectSetupList = (data && data.rejectSetupList) || [];
      this.rejectSetupList.forEach((item) => {
        item.name = `【${item.taskName}】${item.approveUserNames}`;
      });
      this.nextFlowTaskResult = data.nextFlowTaskResult;
      // 被打回给命题老师之后，命题老师只能通过。
      if (data.setup === 1 && !this.rejectSetupList.length) {
        this.TASK_AUDIT_RESULT = { PASS: "通过" };
        this.auditModal.approvePass = "PASS";
      }
      // 判断发起人自选，不管approveUserNames有没有值，都可以选择下个审核人员
      const { modelType, taskKey } = this.nextFlowTaskResult;
      this.IS_NEED_SELECT_APPROVE_USER =
        modelType === "APPROVE_SET" && taskKey.toLowerCase() !== "end";
      this.flowHistoryList[
        this.flowHistoryList.length - 1
      ].isApproveSetFlowNextNode = this.IS_NEED_SELECT_APPROVE_USER;
    },
    approvePassChange() {
      this.auditRules.remark[0].required =
        this.auditModal.approvePass === "REJECT";
    },
    addAtachment() {
      if (this.paperAttachments.length >= this.attachmentLimitCount) return;

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

      //   const selectedCardIds = this.paperAttachments.map((item) => item.cardId);
      //   this.cards = this.cards.map((card) => {
      //     card.disabled =
      //       card.id !== attachment.cardId &&
      //       selectedCardIds.includes(card.id) &&
      //       card.type !== "GENERIC";
      //     return card;
      //   });
    },
    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();
    },
    cancel() {
      this.$emit("cancel");
    },
    async downloadPaper(attachment) {
      if (!attachment.attachmentId) return;
      this.addPreviewLog(attachment, "paper");
      const data = await attachmentPreview(attachment.attachmentId);
      window.open(data.url);
    },
    toSelectNextFlowUser() {
      if (!this.IS_NEED_SELECT_APPROVE_USER) return;

      this.userLimitCount =
        this.nextFlowTaskResult.approveUserCountType === "ONE" ? 1 : 0;
      this.userFilterRoles =
        this.nextFlowTaskResult.approveUserSelectRange === "ROLE"
          ? this.nextFlowTaskResult.approveUserSelectRoles.map(
              (item) => item.id
            )
          : [];
      this.selectUserType = "approve";
      this.curSelectedUsers = this.approveUsers;
      this.$refs.SelectUserDialog.open();
    },
    toSelectExchangeUser() {
      this.userLimitCount = 1;
      this.userFilterRoles = [];
      this.curSelectedUsers = this.exchangeUsers;
      this.selectUserType = "exchange";
      this.$refs.SelectUserDialog.open();
    },
    userSelected(users) {
      if (this.selectUserType === "exchange") {
        this.exchangeUsers = users;
        this.auditModal.userId = users[0].id;
      } else {
        this.approveUsers = users;
      }
    },
    getTaskData() {
      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
      );
      if (this.IS_NEED_SELECT_APPROVE_USER)
        data.approveUserIds = this.approveUsers.map((item) => item.id);
      return data;
    },
    checkDataValid() {
      if (this.IS_TIKU_TAB) {
        const attachmentValid = !this.paperAttachments.some(
          (item) => !item.cardId
        );
        if (!attachmentValid) {
          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;
        }
      }

      if (this.IS_NEED_SELECT_APPROVE_USER && !this.approveUsers.length) {
        this.$message.error("请设置审核人员！");
        return;
      }

      return true;
    },
    // 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.curTaskApply.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,
      });
    },
    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;

      const result = await this.$confirm(
        "任务确定提交后，则不可更改试卷及答题卡内容，确定提交该任务？",
        "提示",
        {
          type: "warning",
        }
      ).catch(() => {});
      if (result !== "confirm") return;

      const datas = this.getTaskData();
      datas.operateType = "SUBMIT";
      const data = await updateTaskApply(datas).catch(() => {});
      if (!data) return;
      this.$message.success("提交成功！");
      this.$emit("modified");
    },
    async toAuditSubmit() {
      if (this.IS_AUDIT && !this.checkAllFilePreview()) {
        this.$message.error(
          "还有未被查看过的题卡或试卷，请点击试卷及题卡进行查看审核"
        );
        return;
      }

      const valid = await this.$refs.auditModalComp.validate().catch(() => {});
      if (!valid) return;

      if (
        this.auditModal.approvePass === "PASS" &&
        this.IS_NEED_SELECT_APPROVE_USER &&
        !this.approveUsers.length
      ) {
        this.$message.error("请设置审核人员！");
        return;
      }

      const actionName = this.TASK_AUDIT_RESULT[this.auditModal.approvePass];
      const result = await this.$confirm(
        `确定${actionName}该申请吗？`,
        "提示",
        {
          type: "warning",
        }
      ).catch(() => {});
      if (result !== "confirm") return;

      if (this.auditModal.approvePass === "EXCHANGE") {
        let datas = {
          taskId: this.curTaskApply.flowTaskId,
          userId: this.auditModal.userId,
        };
        const data = await taskFlowApproverExchange(datas).catch(() => {});
        if (!data) return;
      } else {
        let datas = { ...this.auditModal };
        datas.taskId = this.curTaskApply.flowTaskId;

        if (
          this.auditModal.approvePass === "PASS" &&
          this.IS_NEED_SELECT_APPROVE_USER
        )
          datas.approveUserIds = this.approveUsers.map((item) => item.id);

        const data = await taskFlowApprover(datas).catch(() => {});
        if (!data) return;
      }

      this.$message.success("审批成功！");
      this.$emit("modified");
    },
    async toAuditApply() {
      const result = await this.$confirm("确定提交该任务吗？", "提示", {
        type: "warning",
      }).catch(() => {});
      if (result !== "confirm") return;

      const datas = {
        examTaskDetail: this.getTaskData(),
        flowTaskId: this.curTaskApply.flowTaskId,
        approvePass: "PASS",
      };
      const data = await taskAuditApply(datas).catch(() => {});
      if (!data) return;

      this.$message.success("审批成功！");
      this.$emit("modified");
    },
    // audit preview log
    async addPreviewLog(attachment, type) {
      if (!this.IS_AUDIT) return;
      const id = type === "paper" ? attachment.attachmentId : attachment.cardId;
      if (!Object.prototype.hasOwnProperty.call(this.auditLogCache[type], id))
        return;

      this.auditLogCache[type][id] = true;
      await savePreviewLog({
        examTaskId: this.curTaskApply.examTaskId,
        paperType: attachment.name,
        type,
      });
    },
    checkAllFilePreview() {
      return (
        !Object.values(this.auditLogCache.paper).some((item) => !item) &&
        !Object.values(this.auditLogCache.card).some((item) => !item)
      );
    },
    // 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);
    },
  },
};
</script>
