保誠-保戶業務員媒合平台
wayne
2022-03-10 e8241decc705f9db3e46aed7b3a3f8b3188cf820
PAMapp/pages/appointment/_appointmentId/close/index.vue
@@ -11,59 +11,61 @@
        </UiField>
      </el-row>
      <template v-if="appointmentCloseInfo.selectCloseOption === 'done'">
      <template v-if="appointmentCloseInfo.selectCloseOption === contactStatus.DONE">
        <el-row
          type="flex"
          class="pam-paragraph" style="flex-direction: column">
          <UiField label="身分證字號/居留證字號" :labelSize="20" class="required">
            <input
              class="appointment-client-detail-close__input mt-10"
              :class="{'is-invalid':!identityIdValid}"
              v-model="appointmentCloseInfo.policyholderIdentityId"
              placeholder="請輸入"
              type="text">
          </UiField>
          <div class="error mt-5 mb-5" v-show="!identityIdValid">
            <span>身分證字號格式有誤</span>
          </div>
        </el-row>
        <el-row
          type="flex"
          class="pam-paragraph">
          <UiField label="商品代碼Plan Code" :labelSize="20">
          <UiField label="商品代碼Plan Code" :labelSize="20" class="required">
            <input
              class="appointment-client-detail-close__input"
              class="appointment-client-detail-close__input mt-10"
              v-model="appointmentCloseInfo.planCode"
              placeholder="請輸入"
              type="text">
              <!-- <el-input
                type="input"
                placeholder="請輸入"
                v-model="appointmentCloseInfo.planCode">
              </el-input> -->
          </UiField>
        </el-row>
        <el-row
          type="flex"
          class="pam-paragraph">
          <UiField label="進件時間" :labelSize="20">
            <input
              class="appointment-client-detail-close__input"
              v-model="appointmentCloseInfo.planCode"
              placeholder="TBD: 日期元件"
              type="text">
          <UiField label="進件時間" :labelSize="20" class="required">
            <DateTimePicker
              :defaultValue="appointmentCloseInfo.policyEntryDate"
              class="mt-10"
              @changeDateTime="appointmentCloseDate = $event"></DateTimePicker>
          </UiField>
        </el-row>
      </template>
      <template v-if="appointmentCloseInfo.selectCloseOption === 'close'">
      <template v-if="appointmentCloseInfo.selectCloseOption === contactStatus.CLOSE">
        <el-row
          class="pam-paragraph">
          <UiField label="未成交原因" :labelSize="20">
          <UiField label="未成交原因" :labelSize="20" class="required">
            <UiSelect :closeReason.sync="appointmentCloseInfo.closedReason"
              :options="appointmentFailReason" class="mt-10"/>
          </UiField>
              <select
                class="appointment-client-detail-close__select"
                name="failReason" id="failReason" v-model="appointmentCloseInfo.failReason">
                <option :value="failReason.value" v-for="(failReason, index) in appointmentFailReason" :key="index">
                  {{ failReason.key }}
                </option>
              </select>
              <div style="display: flex" class="mt-10">
                <input
                  v-if="appointmentCloseInfo.failReason === 'other'"
                  class="appointment-client-detail-close__input"
                  v-model="appointmentCloseInfo.otherFailReason"
                  placeholder="請輸入原因,限50字。"
                  type="text">
              </div>
          <input
            v-if="appointmentCloseInfo.closedReason === 'other'
                || appointmentCloseInfo.closedReason === 'no_suitable_commodity'"
            class="appointment-client-detail-close__input mt-10"
            v-model="appointmentCloseInfo.closedOtherReason"
            placeholder="請輸入原因,限50字。"
            type="text">
        </el-row>
      </template>
@@ -72,22 +74,13 @@
        class="pam-paragraph">
        <UiField label="備註" :labelSize="20">
          <el-input
          class="mt-10"
            type="textarea"
            :rows="3"
            placeholder="請輸入"
            v-model="appointmentCloseInfo.archivedDate"
            v-model="appointmentCloseInfo.remark"
            resize="none">
          </el-input>
          <!-- <textarea
            v-model="appointmentCloseInfo.archivedDate"
            class="appointment-close__remark"
            placeholder="請輸入"
            name="remark"
            id="remark"
            wrap="off"
            rows="3">
          </textarea> -->
        </UiField>
      </el-row>
@@ -96,60 +89,227 @@
        justify="center"
        class="pam-paragraph">
        <el-button @click="$router.go(-1)">取消</el-button>
        <el-button @click="$router.go(-1)">確認</el-button>
        <el-button @click="closeAppointment" :disabled="isSubmitBtnDisabled">確認</el-button>
      </el-row>
      <PopUpFrame :isOpen.sync="isShowSuccessAlert">
        <div class="text--middle invite-review">
          <div  class="mb-30 mt-10">結案成功</div>
          <el-button type="primary" @click="closeAlert">確定</el-button>
        </div>
      </PopUpFrame>
  </div>
</template>
<script lang="ts">
import { namespace } from 'nuxt-property-decorator';
import { Vue, Component } from 'vue-property-decorator';
import { Appointment, ToCloseAppointment, ToDoneAppointment } from '~/shared/models/appointment.model';
import appointmentService from '~/shared/services/appointment.service';
import { appointmentFailReasonList } from '~/shared/const/appointment-fail-reason-list';
import { ContactStatus } from '~/shared/models/enum/contact-status';
const appointmentStore = namespace('appointment.store');
@Component
export default class AppointmentDetailCloseComponent extends Vue {
  @appointmentStore.Action
  updateAppointmentDetail!: (appointmentId: number) => Appointment;
  @appointmentStore.State('appointmentDetail')
  appointmentDetail!: Appointment;
  contactStatus = ContactStatus;
  appointmentCloseDate = '';
  isShowSuccessAlert = false;
  appointmentCloseInfo = {
    archivedDate     : '',
    failReason       : 'other',
    otherFailReason  : '',
    planCode         : '',
    remark           : '',
    selectCloseOption: 'done',
    closedOtherReason     : '',
    closedReason          : 'other',
    planCode              : '',
    policyEntryDate       : '',
    policyholderIdentityId: '',
    remark                : '',
    selectCloseOption     : this.contactStatus.DONE,
  };
  closeOptions = [
    {
      title:'成交',
      label: 'done',
      label: this.contactStatus.DONE,
    },
    {
      title:'未成交',
      label: 'close',
      label: this.contactStatus.CLOSE,
    }
  ];
  appointmentFailReason = [
    {
      key: '其他',
      value: 'other'
  appointmentFailReason = appointmentFailReasonList;
  //////////////////////////////////////////////////////////////////////
  mounted() {
    const appointmentId = +this.$route.params.appointmentId;
    const closedInfo = this.appointmentDetail.appointmentClosedInfo;
    if (this.appointmentDetail.id === appointmentId
        && (this.appointmentDetail.communicateStatus === this.contactStatus.DONE
        || this.appointmentDetail.communicateStatus === this.contactStatus.CLOSE
        || this.appointmentDetail.communicateStatus === this.contactStatus.CANCEL)
        ) {
        this.appointmentCloseInfo = {
        closedOtherReason     : closedInfo?.closedOtherReason,
        closedReason          : closedInfo?.closedReason,
        planCode              : closedInfo?.planCode,
        policyEntryDate       : closedInfo?.policyEntryDate,
        policyholderIdentityId: closedInfo?.policyholderIdentityId,
        remark                : closedInfo?.remark,
        selectCloseOption     : this.appointmentDetail.communicateStatus === this.contactStatus.DONE
                                ? this.contactStatus.DONE
                                : this.contactStatus.CLOSE
      };
      this.appointmentCloseDate = closedInfo?.policyEntryDate;
    }
  ];
  }
  //////////////////////////////////////////////////////////////////////
  closeAppointment(): void {
    const appointmentId = +this.$route.params.appointmentId;
    if (this.appointmentCloseInfo.selectCloseOption === this.contactStatus.DONE) {
      const toDoneAppointment: ToDoneAppointment = {
        appointmentId         : appointmentId,
        contactStatus         : this.contactStatus.DONE,
        planCode              : this.appointmentCloseInfo.planCode,
        policyEntryDate       : this.appointmentCloseDate,
        policyholderIdentityId: this.appointmentCloseInfo.policyholderIdentityId,
        remark                : this.appointmentCloseInfo.remark,
      }
      appointmentService.closeAppointment(toDoneAppointment).then((_) => this.updateAppointmentDetail(appointmentId));
      this.isShowSuccessAlert = true;
    } else {
      const toCloseAppointment: ToCloseAppointment = {
        appointmentId    : appointmentId,
        closedOtherReason: this.appointmentCloseInfo.closedOtherReason,
        closedReason     : this.appointmentCloseInfo.closedReason,
        contactStatus    : this.contactStatus.CLOSE,
        remark           : this.appointmentCloseInfo.remark,
      }
      appointmentService.closeAppointment(toCloseAppointment).then((_) => {
        this.updateAppointmentDetail(appointmentId);
        this.isShowSuccessAlert = true;
      });
    }
  }
  closeAlert(){
    this.isShowSuccessAlert = false ;
    this.$router.push(`/myAppointmentList/contactedList`);
  }
  checkIdentityId(id) {
    const tab = 'ABCDEFGHJKLMNPQRSTUVXYWZIO';
    const weight = [9, 8, 7, 6, 5, 4, 3, 2, 1, 1];
    if (id.length !== 10) return false;
    let i = tab.indexOf(id.charAt(0)) + 10;
    if (i === 9) return false;
    let sum = Math.floor((i % 100) / 10) + (i % 10) * 9;
    for (i = 1; i < 10; i += 1) {
      let v = parseInt(id.charAt(i), 10);
      if (i === 1 && Number.isNaN(v)) {
        switch (id.charAt(i)) {
          case 'A':
            v = 0;
            break;
          case 'B':
            v = 1;
            break;
          case 'C':
            v = 2;
            break;
          case 'D':
            v = 3;
            break;
          default:
            return false;
        }
      } else if (i === 1 && ([1, 2, 8, 9].indexOf(v) === -1)) {
        return false;
      }
      if (i > 1 && Number.isNaN(v)) return false;
      sum += v * weight[i];
    }
    if (sum % 10 !== 0) return false;
    return true;
  }
  get isSubmitBtnDisabled() {
    const {
      selectCloseOption,
      policyholderIdentityId,
      planCode,
      closedReason,
      closedOtherReason,
      remark
    } = this.appointmentCloseInfo;
    if (selectCloseOption === this.contactStatus.DONE) {
      return !policyholderIdentityId || !this.identityIdValid || !planCode || !this.appointmentCloseDate
    } else if (closedReason === 'other' || closedReason === 'no_suitable_commodity') {
      return !closedOtherReason
    }
    return false
  }
  get identityIdValid() {
    const identityId = this.appointmentCloseInfo.policyholderIdentityId;
    return identityId ? this.checkIdentityId(identityId) : true;
  }
}
</script>
<style lang="scss" scoped>
.appointment-close__remark,
.appointment-client-detail-close__input,
.appointment-client-detail-close__select {
.appointment-client-detail-close__input {
  border-radius: 5px;
  border   : 1px solid #707070;
  font-size: 20px;
  padding  : 10px 20px;
  width    : 100%;
  box-sizing: border-box;
  &::placeholder {
    color: $MID_GREY;
  }
  &.is-invalid {
    border-color: $PRIMARY_RED !important;
  }
}
.invite-review{
  display: flex;
  flex-direction: column;
  align-items: center;
}
 .error {
    @extend .smTxt_bold;
    @extend .text--primary;
    height: 16px;
  }
  .required {
    position: relative;
    &::before {
      content: '*';
      font-size: 15px;
      font-weight: bold;
      position: absolute;
      color: #FF0000;
      transform: translateX(-2px);
      z-index: 5;
    }
  }
</style>