<template>
|
<div class="appointment-client-detail-close-page">
|
|
<el-row
|
type="flex"
|
class="pam-paragraph">
|
<UiField label="歸檔方式" :labelSize="20">
|
<SingleSelectBtn class="mt-10"
|
:singleSelected.sync="appointmentCloseInfo.selectCloseOption"
|
:options="closeOptions" />
|
</UiField>
|
</el-row>
|
|
<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" class="required">
|
<input
|
class="appointment-client-detail-close__input mt-10"
|
v-model="appointmentCloseInfo.planCode"
|
placeholder="請輸入"
|
type="text">
|
</UiField>
|
</el-row>
|
|
<el-row
|
type="flex"
|
class="pam-paragraph">
|
<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 === contactStatus.CLOSE">
|
<el-row
|
class="pam-paragraph">
|
<UiField label="未成交原因" :labelSize="20" class="required">
|
<UiSelect :closeReason.sync="appointmentCloseInfo.closedReason"
|
:options="appointmentFailReason" class="mt-10"/>
|
</UiField>
|
<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>
|
|
<el-row
|
type="flex"
|
class="pam-paragraph">
|
<UiField label="備註" :labelSize="20">
|
<el-input
|
class="mt-10"
|
type="textarea"
|
:rows="3"
|
placeholder="請輸入"
|
v-model="appointmentCloseInfo.remark"
|
resize="none">
|
</el-input>
|
</UiField>
|
</el-row>
|
|
<el-row
|
type="flex"
|
justify="center"
|
class="pam-paragraph">
|
<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 = {
|
closedOtherReason : '',
|
closedReason : 'other',
|
planCode : '',
|
policyEntryDate : '',
|
policyholderIdentityId: '',
|
remark : '',
|
selectCloseOption : this.contactStatus.DONE,
|
};
|
|
closeOptions = [
|
{
|
title:'成交',
|
label: this.contactStatus.DONE,
|
},
|
{
|
title:'未成交',
|
label: this.contactStatus.CLOSE,
|
}
|
];
|
|
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 {
|
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>
|