| | |
| | | </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> |
| | | |
| | |
| | | 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> |
| | | |
| | |
| | | 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> |