<template>
  <div class="app-container tech-resource-page">
    <el-tabs v-model="activeTab" type="border-card" @tab-click="handleTabClick">
      <el-tab-pane :label="tsT('tabExpert')" name="expert" />
      <el-tab-pane :label="tsT('tabAchievement')" name="achievement" />
      <el-tab-pane :label="tsT('tabInstrument')" name="instrument" />
      <el-tab-pane :label="tsT('tabVideo')" name="video" />
    </el-tabs>

    <br />

    <el-card shadow="never">
      <el-form ref="queryForm" :model="queryParams" size="small" :inline="true">
        <el-form-item prop="resourceType">
          <template slot="label">{{ tsT("queryResourceType") }}</template>
          <el-select v-model="queryParams.resourceType" :placeholder="tsCommon('pleaseSelect')" style="width: 150px" @change="handleQueryTypeChange">
            <el-option v-for="item in resourceTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item prop="resourceName">
          <template slot="label">{{ tsT("queryResourceName") }}</template>
          <el-input
            v-model="queryParams.resourceName"
            :placeholder="tsT('queryResourceNamePh')"
            clearable
            style="width: 200px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item prop="publishStatus">
          <template slot="label">{{ tsT("queryPublishStatus") }}</template>
          <el-select v-model="queryParams.publishStatus" :placeholder="tsCommon('pleaseSelect')" clearable style="width: 130px">
            <el-option :label="$t('techService.status.unpublished')" :value="0" />
            <el-option :label="$t('techService.status.published')" :value="1" />
            <el-option :label="$t('techService.status.offline')" :value="2" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">{{ tsCommon("search") }}</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">{{ tsCommon("reset") }}</el-button>
          <el-button
            v-hasPermi="['techService:techResource:add']"
            type="primary"
            plain
            icon="el-icon-plus"
            size="mini"
            @click="handleAdd"
          >{{ tsCommon("add") }}</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <br />

    <el-card shadow="never">
      <el-table v-loading="loading" :data="tableList" border>
        <el-table-column :label="tsT('colResourceName')" prop="resourceName" align="center" min-width="110" :show-overflow-tooltip="true" />
        <el-table-column :label="tsT('colIntro')" align="center" min-width="140" :show-overflow-tooltip="true">
          <template slot-scope="scope">
            <span>{{ listIntroText(scope.row) }}</span>
          </template>
        </el-table-column>
        <el-table-column v-if="showColContact" :label="tsT('colContact')" prop="contactPhone" align="center" width="120" />
        <el-table-column v-if="showColAffiliated" :label="tsT('colAffiliatedUnit')" prop="affiliatedUnit" align="center" min-width="110" :show-overflow-tooltip="true" />
        <el-table-column v-if="showColAddress" :label="tsT('colDetailAddress')" prop="detailAddress" align="center" min-width="120" :show-overflow-tooltip="true" />
        <el-table-column v-if="activeTab === 'achievement'" :label="tsT('colResearchDirection')" prop="researchDirection" align="center" min-width="100" :show-overflow-tooltip="true" />
        <el-table-column v-if="activeTab === 'instrument'" :label="tsT('colInstrumentModel')" prop="instrumentModel" align="center" width="100" :show-overflow-tooltip="true" />
        <el-table-column v-if="activeTab === 'video'" :label="tsT('colCourseTopic')" align="center" min-width="100" :show-overflow-tooltip="true">
          <template slot-scope="scope">
            <span>{{ courseTopicLabel(scope.row.courseTopic) }}</span>
          </template>
        </el-table-column>
        <el-table-column v-if="showColAccount" :label="tsT('colAccount')" align="center" width="100">
          <template slot-scope="scope">
            <span>{{ Number(scope.row.accountAssigned) === 1 ? $t('techService.status.yes') : $t('techService.status.no') }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="tsCommon('colShelf')" align="center" width="92">
          <template slot-scope="scope">
            <span>{{ displayPublishStatusText(scope.row.displayPublishStatus) }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="tsCommon('colCreate')" align="center" width="160">
          <template slot-scope="scope">
            <span>{{ scope.row.createTime ? parseTime(scope.row.createTime) : $t('techService.status.dash') }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="tsCommon('colOp')" align="center" class-name="small-padding fixed-width" width="300" fixed="right">
          <template slot-scope="scope">
            <el-button v-hasPermi="['techService:techResource:query']" type="text" size="mini" @click="handleView(scope.row)">{{ tsCommon("view") }}</el-button>
            <el-button
              v-hasPermi="['techService:techResource:edit']"
              v-if="scope.row.canEdit"
              type="text"
              size="mini"
              @click="handleEdit(scope.row)"
            >{{ tsCommon("edit") }}</el-button>
            <el-button
              v-hasPermi="['techService:techResource:remove']"
              v-if="scope.row.canDelete"
              type="text"
              size="mini"
              @click="handleDelete(scope.row)"
            >{{ tsCommon("delete") }}</el-button>
            <el-button
              v-hasPermi="['techService:techResource:publish']"
              v-if="scope.row.canPublish"
              type="text"
              size="mini"
              @click="handlePublish(scope.row)"
            >{{ tsCommon("publish") }}</el-button>
            <el-button
              v-hasPermi="['techService:techResource:offline']"
              v-if="scope.row.canOffline"
              type="text"
              size="mini"
              @click="handleOffline(scope.row)"
            >{{ tsCommon("offline") }}</el-button>
            <el-button
              v-hasPermi="['techService:techResource:assignAccount']"
              v-if="scope.row.canAssignAccount"
              type="text"
              size="mini"
              @click="handleAssignAccount(scope.row)"
            >{{ tsCommon("assignAccount") }}</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination
        v-show="total > 0"
        :total="total"
        :page.sync="queryParams.pageNum"
        :limit.sync="queryParams.pageSize"
        @pagination="getList"
      />
    </el-card>

    <el-dialog :title="dialogTitle" :visible.sync="open" width="720px" append-to-body @close="cancel">
      <el-form :key="formKey" ref="form" :model="form" label-width="140px">
        <el-form-item prop="resourceType" :rules="formRules.resourceType">
          <template slot="label">{{ tsT("formResourceType") }}</template>
          <el-select v-model="form.resourceType" :placeholder="tsCommon('pleaseSelect')" :disabled="dialogEdit" style="width: 100%" @change="handleFormTypeChange">
            <el-option v-for="item in resourceTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
          <div v-if="dialogEdit" class="el-form-item__tip">{{ tsT("resourceTypeLocked") }}</div>
        </el-form-item>
        <el-form-item prop="resourceName" :rules="formRules.resourceName">
          <template slot="label">{{ tsT("formResourceName") }}</template>
          <el-input v-model="form.resourceName" :placeholder="tsT('phResourceName')" :maxlength="nameMaxLen" show-word-limit />
        </el-form-item>
        <el-form-item v-if="needPhoto" prop="photoFilePath" :rules="formRules.photoFilePath">
          <template slot="label">{{ tsT("formPhoto") }}</template>
          <el-upload
            list-type="picture-card"
            :class="{ hide: hidePhotoUpload }"
            :action="uploadAction"
            :headers="uploadHeaders"
            :before-upload="beforePhotoUpload"
            :on-success="handlePhotoUploadSuccess"
            :on-error="handleUploadHttpError"
            :on-remove="handlePhotoRemove"
            :limit="1"
            :file-list="photoFileList"
          >
            <i class="el-icon-plus" />
          </el-upload>
          <div class="el-upload__tip">{{ tsCommon("tipPhoto") }}</div>
        </el-form-item>
        <el-form-item v-if="needCover" prop="coverFilePath" :rules="formRules.coverFilePath">
          <template slot="label">{{ tsT("formCover") }}</template>
          <el-upload
            list-type="picture-card"
            :class="{ hide: hideCoverUpload }"
            :action="uploadAction"
            :headers="uploadHeaders"
            :before-upload="beforeCoverUpload"
            :on-success="handleCoverUploadSuccess"
            :on-error="handleUploadHttpError"
            :on-remove="handleCoverRemove"
            :limit="1"
            :file-list="coverFileList"
          >
            <i class="el-icon-plus" />
          </el-upload>
          <div class="el-upload__tip">{{ tsCommon("tipCover") }}</div>
        </el-form-item>
        <el-form-item v-if="needVideo" prop="videoFilePath" :rules="formRules.videoFilePath">
          <template slot="label">{{ tsT("formVideo") }}</template>
          <el-upload
            class="upload-file-uploader"
            :action="uploadAction"
            :headers="uploadHeaders"
            :before-upload="beforeVideoUpload"
            :on-success="handleVideoUploadSuccess"
            :on-error="handleUploadHttpError"
            :show-file-list="false"
          >
            <el-button size="mini" type="primary">{{ tsCommon("pickFile") }}</el-button>
          </el-upload>
          <div class="el-upload__tip">{{ tsCommon("tipVideo") }}</div>
          <ul v-if="form.videoFilePath" class="upload-file-list el-upload-list el-upload-list--text">
            <li class="el-upload-list__item ele-upload-list__item-content">
              <el-link :href="form.videoFileUrl || '#'" :underline="false" target="_blank">
                <span class="el-icon-video-camera"> {{ videoDisplayName }} </span>
              </el-link>
              <div class="ele-upload-list__item-content-action">
                <el-link type="danger" :underline="false" @click="clearVideo">{{ tsCommon("del") }}</el-link>
              </div>
            </li>
          </ul>
        </el-form-item>

        <template v-if="isAchievementType(form.resourceType)">
          <el-form-item prop="researchDirection" :rules="formRules.researchDirection">
            <template slot="label">{{ tsT("formResearchDirection") }}</template>
            <el-select v-model="form.researchDirection" filterable allow-create default-first-option :placeholder="tsT('phResearchDirection')" style="width: 100%">
              <el-option v-for="item in researchDirOptions" :key="item" :label="item" :value="item" />
            </el-select>
          </el-form-item>
          <el-form-item prop="achievementSummary" :rules="formRules.achievementSummary">
            <template slot="label">{{ tsT("formAchievementSummary") }}</template>
            <el-input v-model="form.achievementSummary" type="textarea" :rows="3" :placeholder="tsT('phAchievementSummary')" maxlength="500" show-word-limit />
          </el-form-item>
          <el-form-item prop="keyTechPrinciple" :rules="formRules.keyTechPrinciple">
            <template slot="label">{{ tsT("formKeyTechPrinciple") }}</template>
            <el-input v-model="form.keyTechPrinciple" type="textarea" :rows="3" maxlength="500" show-word-limit />
          </el-form-item>
          <el-form-item prop="techAdvantage" :rules="formRules.techAdvantage">
            <template slot="label">{{ tsT("formTechAdvantage") }}</template>
            <el-input v-model="form.techAdvantage" type="textarea" :rows="3" maxlength="500" show-word-limit />
          </el-form-item>
          <el-form-item prop="completionUnit" :rules="formRules.completionUnit">
            <template slot="label">{{ tsT("formCompletionUnit") }}</template>
            <el-input v-model="form.completionUnit" maxlength="20" show-word-limit />
          </el-form-item>
        </template>

        <el-form-item v-if="showIntroductionField" prop="introduction" :rules="formRules.introduction">
          <template slot="label">{{ tsT("formIntroduction") }}</template>
          <el-input v-model="form.introduction" type="textarea" :rows="3" :placeholder="tsT('phIntroduction')" maxlength="500" show-word-limit />
        </el-form-item>

        <template v-if="isExpertType(form.resourceType)">
          <el-form-item prop="contactPhone" :rules="formRules.contactPhone">
            <template slot="label">{{ tsT("formContactPhone") }}</template>
            <el-input v-model="form.contactPhone" :placeholder="tsT('phContactPhone')" maxlength="11" />
          </el-form-item>
          <el-form-item prop="affiliatedUnit" :rules="formRules.affiliatedUnit">
            <template slot="label">{{ tsT("formAffiliatedUnit") }}</template>
            <el-input v-model="form.affiliatedUnit" :placeholder="tsT('phAffiliatedUnit')" maxlength="20" show-word-limit />
          </el-form-item>
          <el-form-item prop="detailAddress" :rules="formRules.detailAddress">
            <template slot="label">{{ tsT("formDetailAddress") }}</template>
            <el-input v-model="form.detailAddress" :placeholder="tsT('phDetailAddress')" maxlength="100" show-word-limit />
          </el-form-item>
          <el-form-item prop="serviceArea" :rules="formRules.serviceArea">
            <template slot="label">{{ tsT("formServiceArea") }}</template>
            <el-input v-model="form.serviceArea" :placeholder="tsT('phServiceArea')" maxlength="100" show-word-limit />
          </el-form-item>
          <el-form-item prop="feeStandard" :rules="formRules.feeStandard">
            <template slot="label">{{ tsT("formFeeStandard") }}</template>
            <div class="form-unit-wrap">
              <el-input-number v-model="form.feeStandard" :min="0.01" :precision="2" :step="10" controls-position="right" class="form-unit-input" />
              <span class="form-unit">{{ tsCommon("unitYuanHour") }}</span>
            </div>
          </el-form-item>
          <el-form-item prop="serviceStartTime" :rules="formRules.serviceStartTime">
            <template slot="label">{{ tsT("formServiceTime") }}</template>
            <el-time-select
              v-model="form.serviceStartTime"
              :placeholder="tsT('formServiceStart')"
              :picker-options="timePickerOptions"
              style="width: 160px"
              @change="handleServiceStartTimeChange"
            />
            <span class="time-sep">{{ tsCommon("timeSeparator") }}</span>
            <el-time-select
              v-model="form.serviceEndTime"
              :placeholder="tsT('formServiceEnd')"
              :picker-options="timePickerOptionsEnd"
              style="width: 160px"
              @change="handleServiceEndTimeChange"
            />
          </el-form-item>
          <el-form-item prop="serviceWeekdaysList" :rules="formRules.serviceWeekdaysList">
            <template slot="label">{{ tsT("formServiceWeekdays") }}</template>
            <el-checkbox-group v-model="form.serviceWeekdaysList" @change="validateFormField('serviceWeekdaysList')">
              <el-checkbox v-for="item in weekdayOptions" :key="item.value" :label="item.value">{{ item.label }}</el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </template>

        <template v-if="isInstrumentType(form.resourceType)">
          <el-form-item prop="instrumentModel" :rules="formRules.instrumentModel">
            <template slot="label">{{ tsT("formInstrumentModel") }}</template>
            <el-input v-model="form.instrumentModel" maxlength="10" show-word-limit />
          </el-form-item>
          <el-form-item prop="affiliatedUnit" :rules="formRules.affiliatedUnit">
            <template slot="label">{{ tsT("formAffiliatedUnit") }}</template>
            <el-input v-model="form.affiliatedUnit" :placeholder="tsT('phAffiliatedUnit')" maxlength="20" show-word-limit />
          </el-form-item>
          <el-form-item prop="storageLocation" :rules="formRules.storageLocation">
            <template slot="label">{{ tsT("formStorageLocation") }}</template>
            <el-input v-model="form.storageLocation" :placeholder="tsT('phStorageLocation')" maxlength="100" show-word-limit />
          </el-form-item>
          <el-form-item prop="reservationProcess" :rules="formRules.reservationProcess">
            <template slot="label">{{ tsT("formReservationProcess") }}</template>
            <el-input v-model="form.reservationProcess" type="textarea" :rows="3" :placeholder="tsT('phReservationProcess')" maxlength="500" show-word-limit />
          </el-form-item>
          <el-form-item prop="personInCharge" :rules="formRules.personInCharge">
            <template slot="label">{{ tsT("formPersonInCharge") }}</template>
            <el-input v-model="form.personInCharge" maxlength="10" show-word-limit />
          </el-form-item>
          <el-form-item prop="contactPhone" :rules="formRules.contactPhone">
            <template slot="label">{{ tsT("formContactPhone") }}</template>
            <el-input v-model="form.contactPhone" :placeholder="tsT('phContactPhone')" maxlength="11" />
          </el-form-item>
          <el-form-item prop="borrowFee" :rules="formRules.borrowFee">
            <template slot="label">{{ tsT("formBorrowFee") }}</template>
            <div class="form-unit-wrap">
              <el-input-number v-model="form.borrowFee" :min="0.01" :precision="2" :step="10" controls-position="right" class="form-unit-input" />
              <span class="form-unit">{{ tsCommon("unitYuanHour") }}</span>
            </div>
          </el-form-item>
          <el-form-item prop="serviceStartTime" :rules="formRules.serviceStartTime">
            <template slot="label">{{ tsT("formServiceTime") }}</template>
            <el-time-select
              v-model="form.serviceStartTime"
              :placeholder="tsT('formServiceStart')"
              :picker-options="timePickerOptions"
              style="width: 160px"
              @change="handleServiceStartTimeChange"
            />
            <span class="time-sep">{{ tsCommon("timeSeparator") }}</span>
            <el-time-select
              v-model="form.serviceEndTime"
              :placeholder="tsT('formServiceEnd')"
              :picker-options="timePickerOptionsEnd"
              style="width: 160px"
              @change="handleServiceEndTimeChange"
            />
          </el-form-item>
          <el-form-item prop="serviceWeekdaysList" :rules="formRules.serviceWeekdaysList">
            <template slot="label">{{ tsT("formServiceWeekdays") }}</template>
            <el-checkbox-group v-model="form.serviceWeekdaysList" @change="validateFormField('serviceWeekdaysList')">
              <el-checkbox v-for="item in weekdayOptions" :key="item.value" :label="item.value">{{ item.label }}</el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </template>

        <template v-if="isVideoType(form.resourceType)">
          <el-form-item prop="courseTopic" :rules="formRules.courseTopic">
            <template slot="label">{{ tsT("formCourseTopic") }}</template>
            <el-select v-model="form.courseTopic" :placeholder="tsT('phCourseTopic')" style="width: 100%">
              <el-option v-for="item in courseTopicOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
        </template>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">{{ tsCommon("ok") }}</el-button>
        <el-button @click="cancel">{{ tsCommon("cancel") }}</el-button>
      </div>
    </el-dialog>

    <el-dialog :title="tsCommon('viewTitle')" :visible.sync="viewOpen" width="720px" append-to-body>
      <el-form label-width="140px" size="small">
        <el-form-item :label="tsT('formResourceType')">
          <span>{{ resourceTypeText(viewRow.resourceType) }}</span>
        </el-form-item>
        <el-form-item :label="tsT('formResourceName')">
          <span>{{ viewRow.resourceName || $t('techService.status.dash') }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.photoFileUrl" :label="tsT('formPhoto')">
          <image-preview :src="viewRow.photoFileUrl" :width="120" :height="120" />
        </el-form-item>
        <el-form-item v-if="viewRow.coverFileUrl" :label="tsT('formCover')">
          <image-preview :src="viewRow.coverFileUrl" :width="120" :height="120" />
        </el-form-item>
        <el-form-item v-if="viewRow.videoFileUrl" :label="tsT('formVideo')">
          <el-link :href="viewRow.videoFileUrl" target="_blank" type="primary">{{ viewRow.videoFileUrl }}</el-link>
        </el-form-item>
        <el-form-item v-if="isAchievementType(viewRow.resourceType) && viewRow.researchDirection" :label="tsT('formResearchDirection')">
          <span>{{ viewRow.researchDirection }}</span>
        </el-form-item>
        <el-form-item v-if="isAchievementType(viewRow.resourceType) && viewRow.achievementSummary" :label="tsT('formAchievementSummary')">
          <span class="view-text">{{ viewRow.achievementSummary }}</span>
        </el-form-item>
        <el-form-item v-if="isAchievementType(viewRow.resourceType) && viewRow.keyTechPrinciple" :label="tsT('formKeyTechPrinciple')">
          <span class="view-text">{{ viewRow.keyTechPrinciple }}</span>
        </el-form-item>
        <el-form-item v-if="isAchievementType(viewRow.resourceType) && viewRow.techAdvantage" :label="tsT('formTechAdvantage')">
          <span class="view-text">{{ viewRow.techAdvantage }}</span>
        </el-form-item>
        <el-form-item v-if="isAchievementType(viewRow.resourceType) && viewRow.completionUnit" :label="tsT('formCompletionUnit')">
          <span>{{ viewRow.completionUnit }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.introduction" :label="tsT('formIntroduction')">
          <span class="view-text">{{ viewRow.introduction }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.contactPhone" :label="tsT('formContactPhone')">
          <span>{{ viewRow.contactPhone }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.affiliatedUnit" :label="tsT('formAffiliatedUnit')">
          <span>{{ viewRow.affiliatedUnit }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.detailAddress" :label="tsT('formDetailAddress')">
          <span>{{ viewRow.detailAddress }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.serviceArea" :label="tsT('formServiceArea')">
          <span>{{ viewRow.serviceArea }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.feeStandard != null" :label="tsT('formFeeStandard')">
          <span>{{ viewRow.feeStandard }} {{ tsCommon('unitYuanHour') }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.borrowFee != null" :label="tsT('formBorrowFee')">
          <span>{{ viewRow.borrowFee }} {{ tsCommon('unitYuanHour') }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.serviceStartTime" :label="tsT('formServiceTime')">
          <span>{{ viewRow.serviceStartTime }} {{ tsCommon('timeSeparator') }} {{ viewRow.serviceEndTime }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.serviceWeekdaysList && viewRow.serviceWeekdaysList.length" :label="tsT('formServiceWeekdays')">
          <span>{{ weekdaysLabel(viewRow.serviceWeekdaysList) }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.instrumentModel" :label="tsT('formInstrumentModel')">
          <span>{{ viewRow.instrumentModel }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.storageLocation" :label="tsT('formStorageLocation')">
          <span>{{ viewRow.storageLocation }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.reservationProcess" :label="tsT('formReservationProcess')">
          <span class="view-text">{{ viewRow.reservationProcess }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.personInCharge" :label="tsT('formPersonInCharge')">
          <span>{{ viewRow.personInCharge }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.courseTopic" :label="tsT('formCourseTopic')">
          <span>{{ courseTopicLabel(viewRow.courseTopic) }}</span>
        </el-form-item>
        <el-form-item v-if="isExpertType(viewRow.resourceType)" :label="tsT('viewAccountAssigned')">
          <span>{{ Number(viewRow.accountAssigned) === 1 ? $t('techService.status.yes') : $t('techService.status.no') }}</span>
        </el-form-item>
        <el-form-item v-if="viewRow.assignedLoginName" :label="tsT('viewAssignedLogin')">
          <span>{{ viewRow.assignedLoginName }}</span>
        </el-form-item>
        <el-form-item :label="tsCommon('colShelf')">
          <span>{{ displayPublishStatusText(viewRow.displayPublishStatus) }}</span>
        </el-form-item>
        <el-form-item :label="tsT('viewPublishTime')">
          <span>{{ viewRow.publishTime ? parseTime(viewRow.publishTime) : $t('techService.status.dash') }}</span>
        </el-form-item>
        <el-form-item :label="tsT('viewOfflineTime')">
          <span>{{ viewRow.offlineTime ? parseTime(viewRow.offlineTime) : $t('techService.status.dash') }}</span>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button v-if="viewRow.canEdit" v-hasPermi="['techService:techResource:edit']" type="primary" @click="handleEditFromView">{{ tsCommon("edit") }}</el-button>
        <el-button @click="viewOpen = false">{{ tsCommon("close") }}</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getToken } from "@/utils/auth"
import techServiceLocaleMixin from "@/mixins/techServiceLocaleMixin"
import {
  listTechResource,
  getTechResource,
  addTechResource,
  updateTechResource,
  delTechResource,
  publishTechResource,
  offlineTechResource,
  assignAccountTechResource
} from "@/api/techService/techResource"
import { listInformationCategoryChildren } from "@/api/category/informationCategory"

const PHONE_REG = /^1[3-9]\d{9}$/
const RESOURCE_TYPE_CODE = {
  EXPERT: "004005",
  ACHIEVEMENT: "004006",
  INSTRUMENT: "004007",
  VIDEO: "004008"
}
const TAB_TYPE_MAP = {
  expert: RESOURCE_TYPE_CODE.EXPERT,
  achievement: RESOURCE_TYPE_CODE.ACHIEVEMENT,
  instrument: RESOURCE_TYPE_CODE.INSTRUMENT,
  video: RESOURCE_TYPE_CODE.VIDEO
}
const TYPE_TAB_MAP = {
  [RESOURCE_TYPE_CODE.EXPERT]: "expert",
  [RESOURCE_TYPE_CODE.ACHIEVEMENT]: "achievement",
  [RESOURCE_TYPE_CODE.INSTRUMENT]: "instrument",
  [RESOURCE_TYPE_CODE.VIDEO]: "video"
}
/** 存量 tinyint 迁移前 */
const LEGACY_RESOURCE_TYPE = { 1: "004005", 2: "004006", 3: "004007", 4: "004008" }
const LEGACY_COURSE_TOPIC = { 1: "005001", 2: "005002", 3: "005003", 4: "005004" }
const RESOURCE_TYPE_PARENT_CODE = "004"
const RESOURCE_TYPE_CATEGORY_TYPE = "7"
const COURSE_TOPIC_PARENT_CODE = "005"
const COURSE_TOPIC_CATEGORY_TYPE = "8"

export default {
  name: "TechServiceTechResource",
  mixins: [techServiceLocaleMixin],
  data() {
    return {
      tsNs: "techResource",
      activeTab: "expert",
      loading: false,
      open: false,
      viewOpen: false,
      viewRow: {},
      dialogEdit: false,
      formKey: 0,
      total: 0,
      tableList: [],
      queryParams: {
        pageNum: 1,
        pageSize: 20,
        resourceType: RESOURCE_TYPE_CODE.EXPERT,
        resourceName: undefined,
        publishStatus: undefined
      },
      form: {},
      resourceTypeOptions: [],
      courseTopicOptions: [],
      imageFileExts: ["jpg", "jpeg", "png"],
      videoFileExts: ["mp4"],
      videoDisplayName: "video.mp4",
      timePickerOptions: { start: "00:00", step: "00:15", end: "23:45" }
    }
  },
  computed: {
    dialogTitle() {
      return this.dialogEdit ? this.tsT("dialogEdit") : this.tsT("dialogAdd")
    },
    weekdayOptions() {
      return [1, 2, 3, 4, 5, 6, 7].map((value) => ({ label: this.tsT("weekday" + value), value }))
    },
    researchDirOptions() {
      return [1, 2, 3, 4].map((i) => this.tsT("researchDir" + i))
    },
    nameMaxLen() {
      const t = this.form.resourceType
      return this.isAchievementType(t) || this.isVideoType(t) ? 20 : 10
    },
    needPhoto() {
      const t = this.form.resourceType
      return this.isExpertType(t) || this.isInstrumentType(t)
    },
    needCover() {
      const t = this.form.resourceType
      return this.isAchievementType(t) || this.isVideoType(t)
    },
    needVideo() {
      return this.isVideoType(this.form.resourceType)
    },
    showIntroductionField() {
      const t = this.form.resourceType
      return this.isExpertType(t) || this.isInstrumentType(t) || this.isVideoType(t)
    },
    showColContact() {
      return this.activeTab === "expert" || this.activeTab === "instrument"
    },
    showColAffiliated() {
      return this.activeTab === "expert" || this.activeTab === "instrument"
    },
    showColAddress() {
      return this.activeTab === "expert"
    },
    showColAccount() {
      return this.activeTab === "expert"
    },
    uploadAction() {
      return process.env.VUE_APP_BASE_API + "/common/upload"
    },
    uploadHeaders() {
      return { Authorization: "Bearer " + getToken() }
    },
    photoFileList() {
      if (!this.form.photoFileUrl) {
        return []
      }
      return [{ name: "photo", url: this.form.photoFileUrl }]
    },
    coverFileList() {
      if (!this.form.coverFileUrl) {
        return []
      }
      return [{ name: "cover", url: this.form.coverFileUrl }]
    },
    hidePhotoUpload() {
      return !!(this.form.photoFilePath || this.form.photoFileUrl)
    },
    hideCoverUpload() {
      return !!(this.form.coverFilePath || this.form.coverFileUrl)
    },
    timePickerOptionsEnd() {
      return {
        start: "00:00",
        step: "00:15",
        end: "23:45",
        minTime: this.form.serviceStartTime || "00:00"
      }
    },
    formRules() {
      const phoneRuleOptional = [{ validator: this.validatePhoneOptional, trigger: "blur" }]
      const rules = {
        resourceType: [{ required: true, message: this.tsT("ruleResourceType"), trigger: "change" }],
        resourceName: [{ required: true, validator: this.validateResourceName, trigger: "blur" }]
      }
      const t = this.form.resourceType
      if (this.isExpertType(t) || this.isInstrumentType(t)) {
        rules.photoFilePath = []
      }
      if (this.isVideoType(t)) {
        rules.videoFilePath = [{ required: true, message: this.tsT("ruleVideo"), trigger: "change" }]
        rules.coverFilePath = []
      }
      if (this.isExpertType(t) || this.isInstrumentType(t) || this.isVideoType(t)) {
        rules.introduction = [{ max: 500, message: this.tsT("ruleLen1500"), trigger: "blur" }]
      }
      if (this.isExpertType(t)) {
        rules.contactPhone = phoneRuleOptional
        rules.affiliatedUnit = [{ max: 20, message: this.tsT("ruleLen120"), trigger: "blur" }]
        rules.detailAddress = [{ max: 100, message: this.tsT("ruleLen1100"), trigger: "blur" }]
        rules.serviceArea = [{ max: 100, message: this.tsT("ruleLen1100"), trigger: "blur" }]
        rules.feeStandard = []
        rules.serviceStartTime = [{ validator: this.validateServiceTimeOptional, trigger: "change" }]
        rules.serviceWeekdaysList = []
      } else if (this.isAchievementType(t)) {
        rules.researchDirection = [
          { required: true, message: this.tsT("ruleResearchDirection"), trigger: "change" },
          { min: 1, max: 20, message: this.tsT("ruleLen120"), trigger: "blur" }
        ]
        rules.achievementSummary = [{ max: 500, message: this.tsT("ruleLen1500"), trigger: "blur" }]
        rules.keyTechPrinciple = [{ max: 500, message: this.tsT("ruleLen1500"), trigger: "blur" }]
        rules.techAdvantage = [{ max: 500, message: this.tsT("ruleLen1500"), trigger: "blur" }]
        rules.completionUnit = [{ max: 20, message: this.tsT("ruleLen120"), trigger: "blur" }]
      } else if (this.isInstrumentType(t)) {
        rules.instrumentModel = [{ max: 10, message: this.tsT("ruleLen110"), trigger: "blur" }]
        rules.affiliatedUnit = [{ max: 20, message: this.tsT("ruleLen120"), trigger: "blur" }]
        rules.storageLocation = [{ max: 100, message: this.tsT("ruleLen1100"), trigger: "blur" }]
        rules.reservationProcess = [{ max: 500, message: this.tsT("ruleLen1500"), trigger: "blur" }]
        rules.personInCharge = [{ max: 10, message: this.tsT("ruleLen110"), trigger: "blur" }]
        rules.contactPhone = phoneRuleOptional
        rules.borrowFee = []
        rules.serviceStartTime = [{ validator: this.validateServiceTimeOptional, trigger: "change" }]
        rules.serviceWeekdaysList = []
      } else if (this.isVideoType(t)) {
        rules.courseTopic = [{ required: true, message: this.tsT("ruleCourseTopic"), trigger: "change" }]
      }
      return rules
    }
  },
  created() {
    this.loadResourceTypeOptions()
    this.loadCourseTopicOptions()
    this.getList()
  },
  methods: {
    mapCategoryItem(item) {
      if (!item) {
        return { value: "", label: "" }
      }
      return {
        value: item["code"] != null ? item["code"] : item.code,
        label: item["name"] != null ? item["name"] : item.name
      }
    },
    loadResourceTypeOptions() {
      return listInformationCategoryChildren(RESOURCE_TYPE_PARENT_CODE, RESOURCE_TYPE_CATEGORY_TYPE).then((res) => {
        const list = res.data || []
        this.resourceTypeOptions = list.map((item) => this.mapCategoryItem(item)).filter((o) => o.value)
      })
    },
    loadCourseTopicOptions() {
      return listInformationCategoryChildren(COURSE_TOPIC_PARENT_CODE, COURSE_TOPIC_CATEGORY_TYPE).then((res) => {
        const list = res.data || []
        this.courseTopicOptions = list.map((item) => this.mapCategoryItem(item)).filter((o) => o.value)
      })
    },
    normalizeResourceType(val) {
      if (val == null || val === "") {
        return ""
      }
      const num = Number(val)
      if (!Number.isNaN(num) && LEGACY_RESOURCE_TYPE[num]) {
        return LEGACY_RESOURCE_TYPE[num]
      }
      return String(val)
    },
    normalizeCourseTopic(val) {
      if (val == null || val === "") {
        return ""
      }
      const num = Number(val)
      if (!Number.isNaN(num) && LEGACY_COURSE_TOPIC[num]) {
        return LEGACY_COURSE_TOPIC[num]
      }
      return String(val)
    },
    isExpertType(val) {
      return this.normalizeResourceType(val) === RESOURCE_TYPE_CODE.EXPERT
    },
    isAchievementType(val) {
      return this.normalizeResourceType(val) === RESOURCE_TYPE_CODE.ACHIEVEMENT
    },
    isInstrumentType(val) {
      return this.normalizeResourceType(val) === RESOURCE_TYPE_CODE.INSTRUMENT
    },
    isVideoType(val) {
      return this.normalizeResourceType(val) === RESOURCE_TYPE_CODE.VIDEO
    },
    courseTopicLabel(val) {
      if (val == null || val === "") {
        return ""
      }
      const key = this.normalizeCourseTopic(val)
      const item = this.courseTopicOptions.find((o) => String(o.value) === key)
      if (item) {
        return item.label
      }
      for (let i = 1; i <= 4; i += 1) {
        if (this.tsT("courseTopic" + i) === val) {
          return val
        }
      }
      return key || String(val)
    },
    enrichRowFlags(row) {
      const publishStatus = Number(row.publishStatus)
      const canModify = publishStatus === 0 && String(row.delFlag || "0") === "0"
      const isPublished = publishStatus === 1
      return {
        ...row,
        canEdit: row.canEdit != null ? row.canEdit : canModify,
        canDelete: row.canDelete != null ? row.canDelete : canModify,
        canPublish: row.canPublish != null ? row.canPublish : canModify,
        canOffline: row.canOffline != null ? row.canOffline : isPublished,
        canAssignAccount:
          row.canAssignAccount != null
            ? row.canAssignAccount
            : this.isExpertType(row.resourceType) && Number(row.accountAssigned) === 0 && canModify
      }
    },
    listIntroText(row) {
      if (this.isAchievementType(row.resourceType)) {
        return row.achievementSummary || this.$t("techService.status.dash")
      }
      return row.introduction || this.$t("techService.status.dash")
    },
    weekdaysLabel(list) {
      return (list || [])
        .map((v) => {
          const item = this.weekdayOptions.find((o) => o.value === v)
          return item ? item.label : ""
        })
        .filter(Boolean)
        .join("、")
    },
    validateResourceName(rule, value, callback) {
      const t = this.form.resourceType
      const max = this.isAchievementType(t) || this.isVideoType(t) ? 20 : 10
      const v = (value || "").trim()
      if (!v) {
        callback(new Error(this.tsT("ruleResourceName")))
        return
      }
      if (v.length < 1 || v.length > max) {
        callback(new Error(this.tsT(max === 20 ? "ruleLen120" : "ruleLen110")))
        return
      }
      callback()
    },
    validatePhone(rule, value, callback) {
      if (!value || !PHONE_REG.test(String(value).trim())) {
        callback(new Error(this.tsT("rulePhone")))
        return
      }
      callback()
    },
    validatePhoneOptional(rule, value, callback) {
      if (!value || !String(value).trim()) {
        callback()
        return
      }
      if (!PHONE_REG.test(String(value).trim())) {
        callback(new Error(this.tsT("rulePhone")))
        return
      }
      callback()
    },
    validateFormField(field) {
      this.$nextTick(() => {
        this.$refs.form && this.$refs.form.validateField(field)
      })
    },
    validateWeekdays(rule, value, callback) {
      if (!value || !value.length) {
        callback(new Error(this.tsT("ruleWeekdayOne")))
        return
      }
      callback()
    },
    validateServiceTime(rule, value, callback) {
      const start = this.form.serviceStartTime
      const end = this.form.serviceEndTime
      if (!start || !end) {
        callback(new Error(this.tsT("ruleServiceTime")))
        return
      }
      if (start > end) {
        callback(new Error(this.tsT("ruleServiceEnd")))
        return
      }
      callback()
    },
    validateServiceTimeOptional(rule, value, callback) {
      const start = this.form.serviceStartTime
      const end = this.form.serviceEndTime
      if (!start && !end) {
        callback()
        return
      }
      if (!start || !end) {
        callback(new Error(this.tsT("ruleServiceTime")))
        return
      }
      if (start > end) {
        callback(new Error(this.tsT("ruleServiceEnd")))
        return
      }
      callback()
    },
    handleTabClick() {
      this.queryParams.resourceType = TAB_TYPE_MAP[this.activeTab]
      this.queryParams.pageNum = 1
      this.getList()
    },
    handleQueryTypeChange(val) {
      const tab = TYPE_TAB_MAP[this.normalizeResourceType(val)]
      if (tab) {
        this.activeTab = tab
      }
      this.handleQuery()
    },
    getList() {
      this.loading = true
      listTechResource(this.queryParams)
        .then((res) => {
          this.tableList = (res.rows || []).map((row) => this.enrichRowFlags(row))
          this.total = res.total != null ? res.total : 0
        })
        .finally(() => {
          this.loading = false
        })
    },
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    resetQuery() {
      this.queryParams.resourceName = undefined
      this.queryParams.publishStatus = undefined
      this.queryParams.resourceType = TAB_TYPE_MAP[this.activeTab]
      this.resetForm("queryForm")
      this.handleQuery()
    },
    resetFormModel() {
      const resourceType = TAB_TYPE_MAP[this.activeTab]
      const hasServiceSchedule = this.hasServiceScheduleType(resourceType)
      this.form = {
        id: undefined,
        resourceType,
        resourceName: undefined,
        photoFileUrl: undefined,
        photoFilePath: undefined,
        coverFileUrl: undefined,
        coverFilePath: undefined,
        videoFileUrl: undefined,
        videoFilePath: undefined,
        introduction: undefined,
        achievementSummary: undefined,
        keyTechPrinciple: undefined,
        techAdvantage: undefined,
        researchDirection: undefined,
        completionUnit: undefined,
        contactPhone: undefined,
        affiliatedUnit: undefined,
        detailAddress: undefined,
        serviceArea: undefined,
        feeStandard: undefined,
        borrowFee: undefined,
        serviceStartTime: hasServiceSchedule ? this.defaultServiceStartTime() : undefined,
        serviceEndTime: hasServiceSchedule ? this.defaultServiceEndTime() : undefined,
        serviceWeekdaysList: hasServiceSchedule ? this.defaultServiceWeekdaysList() : [],
        instrumentModel: undefined,
        storageLocation: undefined,
        reservationProcess: undefined,
        personInCharge: undefined,
        courseTopic: undefined
      }
      this.videoDisplayName = "video.mp4"
    },
    handleAdd() {
      this.formKey += 1
      this.resetFormModel()
      this.dialogEdit = false
      this.open = true
      this.$nextTick(() => {
        if (this.hasServiceScheduleType(this.form.resourceType)) {
          this.form.serviceEndTime = this.defaultServiceEndTime()
        }
        if (this.$refs.form) {
          this.$refs.form.clearValidate()
        }
      })
    },
    fillFormFromApi(data) {
      this.form = {
        id: data.id,
        resourceType: data.resourceType,
        resourceName: data.resourceName,
        photoFileUrl: data.photoFileUrl,
        photoFilePath: data.photoFilePath,
        coverFileUrl: data.coverFileUrl,
        coverFilePath: data.coverFilePath,
        videoFileUrl: data.videoFileUrl,
        videoFilePath: data.videoFilePath,
        introduction: data.introduction,
        achievementSummary: data.achievementSummary,
        keyTechPrinciple: data.keyTechPrinciple,
        techAdvantage: data.techAdvantage,
        researchDirection: data.researchDirection,
        completionUnit: data.completionUnit,
        contactPhone: data.contactPhone,
        affiliatedUnit: data.affiliatedUnit,
        detailAddress: data.detailAddress,
        serviceArea: data.serviceArea,
        feeStandard: data.feeStandard,
        borrowFee: data.borrowFee,
        serviceStartTime: data.serviceStartTime,
        serviceEndTime: data.serviceEndTime,
        serviceWeekdaysList: data.serviceWeekdaysList ? [...data.serviceWeekdaysList] : [],
        instrumentModel: data.instrumentModel,
        storageLocation: data.storageLocation,
        reservationProcess: data.reservationProcess,
        personInCharge: data.personInCharge,
        courseTopic: data.courseTopic
      }
      this.videoDisplayName = data.videoFilePath ? data.videoFilePath.split("/").pop() : "video.mp4"
    },
    handleEdit(row) {
      if (!row.canEdit) {
        this.$modal.msgWarning(this.tsT("msgPublishedCannotEdit"))
        return
      }
      getTechResource(row.id).then((res) => {
        const data = res.data || {}
        if (Number(data.publishStatus) === 1) {
          this.$modal.msgWarning(this.tsT("msgPublishedCannotEdit"))
          return
        }
        this.formKey += 1
        this.dialogEdit = true
        this.fillFormFromApi(data)
        this.open = true
        this.$nextTick(() => {
          if (this.$refs.form) {
            this.$refs.form.clearValidate()
          }
        })
      })
    },
    handleEditFromView() {
      this.viewOpen = false
      this.handleEdit(this.viewRow)
    },
    handleView(row) {
      getTechResource(row.id).then((res) => {
        this.viewRow = this.enrichRowFlags(res.data || {})
        this.viewOpen = true
      })
    },
    handleDelete(row) {
      if (!row.canDelete) {
        this.$modal.msgWarning(this.tsT("msgPublishedCannotDelete"))
        return
      }
      this.$modal
        .confirm(this.tsT("confirmDelete", { name: row.resourceName }))
        .then(() => delTechResource(row.id))
        .then(() => {
          this.$modal.msgSuccess(this.tsCommon("msgDelOk"))
          this.getList()
        })
        .catch(() => {})
    },
    handlePublish(row) {
      this.$modal
        .confirm(this.tsT("confirmPublish"))
        .then(() => publishTechResource(row.id))
        .then(() => {
          this.$modal.msgSuccess(this.tsCommon("msgPubOk"))
          this.getList()
        })
        .catch(() => {})
    },
    handleOffline(row) {
      this.$modal
        .confirm(this.tsT("confirmOffline"))
        .then(() => offlineTechResource(row.id))
        .then(() => {
          this.$modal.msgSuccess(this.tsCommon("msgOffOk"))
          this.getList()
        })
        .catch(() => {})
    },
    handleAssignAccount(row) {
      this.$modal
        .confirm(this.tsT("confirmAssign"))
        .then(() => assignAccountTechResource(row.id))
        .then(() => {
          this.$modal.msgSuccess(this.tsCommon("msgAssignOk"))
          this.getList()
        })
        .catch(() => {})
    },
    handleFormTypeChange() {
      const t = this.normalizeResourceType(this.form.resourceType)
      if (this.hasServiceScheduleType(t)) {
        this.applyDefaultServiceSchedule(t)
      } else {
        this.form.serviceStartTime = undefined
        this.form.serviceEndTime = undefined
        this.form.serviceWeekdaysList = []
      }
      this.$nextTick(() => {
        if (this.$refs.form) {
          this.$refs.form.clearValidate()
        }
      })
    },
    hasServiceScheduleType(resourceType) {
      const t = this.normalizeResourceType(resourceType)
      return this.isExpertType(t) || this.isInstrumentType(t)
    },
    defaultServiceStartTime() {
      return "08:00"
    },
    defaultServiceEndTime() {
      return "18:00"
    },
    defaultServiceWeekdaysList() {
      return [1, 2, 3, 4, 5]
    },
    applyDefaultServiceSchedule(resourceType) {
      if (!this.hasServiceScheduleType(resourceType)) {
        return
      }
      this.form.serviceStartTime = this.defaultServiceStartTime()
      this.form.serviceWeekdaysList = this.defaultServiceWeekdaysList()
      this.$nextTick(() => {
        this.form.serviceEndTime = this.defaultServiceEndTime()
      })
    },
    handleServiceStartTimeChange() {
      const start = this.form.serviceStartTime
      const end = this.form.serviceEndTime
      if (start && (!end || end <= start)) {
        this.$nextTick(() => {
          this.form.serviceEndTime = this.defaultServiceEndTime()
          this.validateFormField("serviceStartTime")
        })
        return
      }
      this.validateFormField("serviceStartTime")
    },
    handleServiceEndTimeChange() {
      this.validateFormField("serviceStartTime")
    },
    extOf(fileName) {
      if (!fileName || fileName.lastIndexOf(".") < 0) {
        return ""
      }
      return fileName.slice(fileName.lastIndexOf(".") + 1).toLowerCase()
    },
    beforePhotoUpload(file) {
      const ext = this.extOf(file.name)
      if (!this.imageFileExts.includes(ext)) {
        this.$modal.msgError(this.tsCommon("errPhotoFmt"))
        return false
      }
      if (file.name.includes(",")) {
        this.$modal.msgError(this.tsCommon("errComma"))
        return false
      }
      if (file.size / 1024 / 1024 >= 10) {
        this.$modal.msgError(this.tsCommon("errPhotoMb"))
        return false
      }
      this.$modal.loading(this.tsCommon("uploadingImg"))
      return true
    },
    handlePhotoUploadSuccess(res) {
      this.$modal.closeLoading()
      if (res.code === 200) {
        this.form.photoFileUrl = res.url
        this.form.photoFilePath = res.fileName
        this.$refs.form && this.$refs.form.validateField("photoFilePath")
      } else {
        this.$modal.msgError(res.msg || this.tsCommon("errUploadFail"))
      }
    },
    handlePhotoRemove() {
      this.form.photoFileUrl = undefined
      this.form.photoFilePath = undefined
    },
    beforeCoverUpload(file) {
      const ext = this.extOf(file.name)
      if (!this.imageFileExts.includes(ext)) {
        this.$modal.msgError(this.tsCommon("errCoverFmt"))
        return false
      }
      if (file.name.includes(",")) {
        this.$modal.msgError(this.tsCommon("errComma"))
        return false
      }
      if (file.size / 1024 / 1024 >= 10) {
        this.$modal.msgError(this.tsCommon("errCoverMb"))
        return false
      }
      this.$modal.loading(this.tsCommon("uploadingImg"))
      return true
    },
    handleCoverUploadSuccess(res) {
      this.$modal.closeLoading()
      if (res.code === 200) {
        this.form.coverFileUrl = res.url
        this.form.coverFilePath = res.fileName
      } else {
        this.$modal.msgError(res.msg || this.tsCommon("errUploadFail"))
      }
    },
    handleCoverRemove() {
      this.form.coverFileUrl = undefined
      this.form.coverFilePath = undefined
    },
    beforeVideoUpload(file) {
      const ext = this.extOf(file.name)
      if (!this.videoFileExts.includes(ext)) {
        this.$modal.msgError(this.tsCommon("errVideoFmt"))
        return false
      }
      if (file.name.includes(",")) {
        this.$modal.msgError(this.tsCommon("errComma"))
        return false
      }
      if (file.size / 1024 / 1024 >= 30) {
        this.$modal.msgError(this.tsCommon("errVideoMb"))
        return false
      }
      this.$modal.loading(this.tsCommon("uploadingFile"))
      return true
    },
    handleVideoUploadSuccess(res, file) {
      this.$modal.closeLoading()
      if (res.code === 200) {
        this.form.videoFileUrl = res.url
        this.form.videoFilePath = res.fileName
        this.videoDisplayName = res.originalFilename || file.name
        this.$refs.form && this.$refs.form.validateField("videoFilePath")
      } else {
        this.$modal.msgError(res.msg || this.tsCommon("errUploadFail"))
      }
    },
    clearVideo() {
      this.form.videoFileUrl = undefined
      this.form.videoFilePath = undefined
      this.videoDisplayName = "video.mp4"
    },
    handleUploadHttpError() {
      this.$modal.closeLoading()
      this.$modal.msgError(this.tsCommon("errUploadRetry"))
    },
    buildSubmitPayload() {
      const payload = {
        resourceType: this.form.resourceType,
        resourceName: (this.form.resourceName || "").trim()
      }
      const t = this.form.resourceType
      if (this.isExpertType(t) || this.isInstrumentType(t)) {
        payload.photoFileUrl = this.form.photoFileUrl
        payload.photoFilePath = this.form.photoFilePath
      }
      if (this.isAchievementType(t) || this.isVideoType(t)) {
        if (this.form.coverFilePath) {
          payload.coverFileUrl = this.form.coverFileUrl
          payload.coverFilePath = this.form.coverFilePath
        }
      }
      if (this.isVideoType(t)) {
        payload.videoFileUrl = this.form.videoFileUrl
        payload.videoFilePath = this.form.videoFilePath
      }
      if (this.isExpertType(t) || this.isInstrumentType(t) || this.isVideoType(t)) {
        payload.introduction = (this.form.introduction || "").trim()
      }
      if (this.isExpertType(t)) {
        Object.assign(payload, {
          contactPhone: this.form.contactPhone,
          affiliatedUnit: (this.form.affiliatedUnit || "").trim(),
          detailAddress: (this.form.detailAddress || "").trim(),
          serviceArea: (this.form.serviceArea || "").trim(),
          feeStandard: this.form.feeStandard,
          serviceStartTime: this.form.serviceStartTime,
          serviceEndTime: this.form.serviceEndTime,
          serviceWeekdaysList: this.form.serviceWeekdaysList
        })
      } else if (this.isAchievementType(t)) {
        Object.assign(payload, {
          researchDirection: (this.form.researchDirection || "").trim(),
          achievementSummary: (this.form.achievementSummary || "").trim(),
          keyTechPrinciple: (this.form.keyTechPrinciple || "").trim(),
          techAdvantage: (this.form.techAdvantage || "").trim(),
          completionUnit: (this.form.completionUnit || "").trim()
        })
      } else if (this.isInstrumentType(t)) {
        Object.assign(payload, {
          instrumentModel: (this.form.instrumentModel || "").trim(),
          affiliatedUnit: (this.form.affiliatedUnit || "").trim(),
          storageLocation: (this.form.storageLocation || "").trim(),
          reservationProcess: (this.form.reservationProcess || "").trim(),
          personInCharge: (this.form.personInCharge || "").trim(),
          contactPhone: this.form.contactPhone,
          borrowFee: this.form.borrowFee,
          serviceStartTime: this.form.serviceStartTime,
          serviceEndTime: this.form.serviceEndTime,
          serviceWeekdaysList: this.form.serviceWeekdaysList
        })
      } else if (this.isVideoType(t)) {
        Object.assign(payload, {
          courseTopic: this.form.courseTopic
        })
      }
      return payload
    },
    submitForm() {
      this.$refs.form.validate((valid) => {
        if (!valid) {
          return
        }
        const payload = this.buildSubmitPayload()
        if (this.dialogEdit) {
          payload.id = this.form.id
          updateTechResource(payload).then(() => {
            this.$modal.msgSuccess(this.tsCommon("msgModOk"))
            this.open = false
            this.getList()
          })
        } else {
          addTechResource(payload).then(() => {
            this.$modal.msgSuccess(this.tsCommon("msgAddOk"))
            this.open = false
            this.getList()
          })
        }
      })
    },
    cancel() {
      this.open = false
      this.resetFormModel()
    }
  }
}
</script>

<style scoped>
.tech-resource-page ::v-deep .el-tabs__content {
  display: none;
}
.form-unit-wrap {
  display: flex;
  align-items: center;
  width: 100%;
}
.form-unit-wrap .form-unit-input {
  flex: 1;
  width: auto;
}
.form-unit-wrap ::v-deep .el-input-number {
  width: 100%;
}
.form-unit {
  flex-shrink: 0;
  margin-left: 8px;
  color: #909399;
  font-size: 12px;
  white-space: nowrap;
}
.time-sep {
  margin: 0 8px;
  color: #909399;
}
.hide ::v-deep .el-upload--picture-card {
  display: none;
}
.view-text {
  white-space: pre-wrap;
  word-break: break-word;
}
.upload-file-list {
  margin-top: 8px;
}
</style>
