| | |
| | | <template> |
| | | <div class="appointment-client-detail-page"> |
| | | <div class="appointment-client-detail-page" v-if="!!appointmentDetail"> |
| | | <div class="date-detail"> |
| | | <div>{{ appointmentDetail.appointmentDate | formatDate }}</div> |
| | | <div>{{ appointmentDetail.consultantReadTime | formatDate }}</div> |
| | | <div>{{ appointmentDetail.appointmentDate | formatDate }}預約</div> |
| | | <div>{{ appointmentDetail.consultantReadTime | formatDate }} |
| | | <span v-if="appointmentDetail.consultantReadTime">已讀</span> |
| | | </div> |
| | | </div> |
| | | <!-- TODO: re-send api to update progress [Tomas, 2022/1/17 17:02] --> |
| | | |
| | | <AppointmentProgress |
| | | class="mt-10" |
| | | :currentStep="appointmentDetail.communicateStatus" |
| | | :currentStep="appointmentProgress" |
| | | ></AppointmentProgress> |
| | | |
| | | <section class="client-detail"> |
| | | |
| | | <div class="client-detail-info"> |
| | | <div class="client-detail-info mb-30"> |
| | | <div class="client-detail-info__avatar"> |
| | | <div class="circle"> |
| | | {{ appointmentDetail.name || 'NO NAME' }} |
| | | <div class="sm-circle"> |
| | | {{ appointmentDetail.gender === 'male' ? '男' : '女'}} |
| | | <div class="sm-circle sm-circle-male" v-if="appointmentDetail.gender === 'male'"> |
| | | <i class="icon-sex-male sex-icon"></i> |
| | | </div> |
| | | <div class="sm-circle sm-circle-female" v-if="appointmentDetail.gender === 'female'"> |
| | | <i class="icon-sex-female sex-icon"></i> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="client-detail-info__information"> |
| | | <div>{{ appointmentDetail.age | toAgeLabel }}</div> |
| | | <div>{{ appointmentDetail.phone }}</div> |
| | | <div class="text--underline"> |
| | | <div class=" text--break-all"> |
| | | {{ appointmentDetail.email }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="client-detail-demand mt-10"> |
| | | <div class="client-detail-demand__demand-list"> |
| | | |
| | | <div class="client-detail-demand__demand-list mb-10"> |
| | | <div class="client-detail-demand__demand-list-label">需求</div> |
| | | <div>{{ appointmentDetail.requirement }}</div> |
| | | <div class="client-detail-demand__demand-list-content">{{ appointmentDetail.requirement }}</div> |
| | | </div> |
| | | <div class="client-detail-demand__hope-contact-time"> |
| | | |
| | | <div class="client-detail-demand__demand-list"> |
| | | <div class="client-detail-demand__demand-list-label">聯絡<br />時段</div> |
| | | <div>星期一 17:00 ~ 19:00</div> |
| | | <!-- TODO: 多筆聯絡時段如何呈現 && 跑版問題 [Tomas. 2021/1/12] --> |
| | | <!-- <div>{{ appointmentDetail.hopeContactTime }}</div> --> |
| | | <div class="client-detail-demand__demand-list-content"> |
| | | <div v-for="(hopeContactTime, index) in hopeContactTimeList" :key="index" |
| | | :class="{'mt-10': index > 0, 'pb-10': true, 'hope-contact-time__line': index + 1 < hopeContactTimeList.length }"> |
| | | <div v-for="(item, index) in getHopeContactTimeContent(hopeContactTime)" :key="index" :class="{'mt-10': index < 0 }"> |
| | | {{ item }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="client-detail-action" v-if="showWhenAppointmentHasClosed"> |
| | | <el-button >發送滿意度</el-button> |
| | | <!-- <div class=" btn-center" v-if="showWhenAppointmentHasClosed"> |
| | | <el-button @click="inviteReview">發送滿意度</el-button> |
| | | </div> --> |
| | | |
| | | <div class="client-detail-action" v-if="showWhenAppointmentHasContacted"> |
| | | <el-button @click="closeAppointment" class="desktop-client-detail-action-btn" >結案</el-button> |
| | | <el-button @click="sendMsg" style="margin-left: 0px">通知約訪</el-button> |
| | | </div> |
| | | |
| | | <div class="client-detail-action" v-else> |
| | | <el-button @click="closeAppointment" >結案</el-button> |
| | | <el-button @click="sendMsg" style="margin-left: 0px">通知/約訪</el-button> |
| | | <div class=" btn-center" v-if="showWhenAppointmentHasCreate"> |
| | | <el-button @click="sendMsg">傳送約訪通知</el-button> |
| | | </div> |
| | | |
| | | </section> |
| | | |
| | | <section class="close-appointment-detail" v-if="showWhenAppointmentHasClosed"> |
| | | |
| | | <div class="close-appointment-detail-nav"> |
| | | <div class="mdTxt">結案方式</div> |
| | | <div class="mdTxt text--primary text--underline cursor--pointer" @click="editAppointmentHasClosed">編輯</div> |
| | | </div> |
| | | <span class="mt-10 mb-30">成交</span> |
| | | |
| | | <div class="mdTxt mb-10">保戶身份證字號</div> |
| | | <div class="mb-30">A123456789</div> |
| | | <div class="mdTxt mb-10">商品代碼Plan Code</div> |
| | | <div class="mb-30">8888888</div> |
| | | <div class="mdTxt mb-10">進件時間</div> |
| | | <div class="mb-30">2021/12/2</div> |
| | | <div class="mdTxt mb-10">備註</div> |
| | | <div class="">約訪4次,客戶很喜歡聊寶可夢。</div> |
| | | |
| | | </section> |
| | | <template v-if="showWhenAppointmentHasClosed"> |
| | | <AppointmentClosedInfo :appointmentDetail="appointmentDetail" /> |
| | | </template> |
| | | |
| | | <InterviewMsg |
| | | :isVisible.sync="isVisibleDialog" |
| | |
| | | </InterviewMsg> |
| | | |
| | | |
| | | <section class="mt-30"> |
| | | <section class="mt-30" v-if="!showWhenAppointmentHasCreate"> |
| | | <AppointmentInterviewList :interviewList="appointmentDetail.interviewRecordDTOs" /> |
| | | </section> |
| | | |
| | | <section class="mt-30"> |
| | | <section class="mt-30" v-if="!showWhenAppointmentHasCreate"> |
| | | <AppointmentRecordList :noticeLogs="appointmentDetail.appointmentNoticeLogs" /> |
| | | </section> |
| | | |
| | | <PopUpFrame :isOpen.sync="isShowInviteReviewDialog"> |
| | | <div class="text--middle invite-review"> |
| | | <div class="mb-30 mt-10">已發送滿意度</div> |
| | | <div class="text--primary text--middle cursor--pointer text--underline" @click="isShowInviteReviewDialog = false" :size="'250px'">我知道了</div> |
| | | </div> |
| | | </PopUpFrame> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Context } from '@nuxt/types'; |
| | | |
| | | import { Vue, Component } from 'vue-property-decorator'; |
| | | import { namespace } from 'nuxt-property-decorator'; |
| | | |
| | | import appointmentService from '~/shared/services/appointment.service'; |
| | | import { Appointment } from '~/shared/models/appointment.model'; |
| | | import { ContactStatus } from '~/shared/models/enum/contact-status'; |
| | | |
| | | import reviewsService from '~/shared/services/reviews.service'; |
| | | |
| | | |
| | | const appointmentStore = namespace('appointment.store'); |
| | | |
| | | @Component |
| | | export default class AppointmentDetailComponent extends Vue { |
| | | |
| | | @appointmentStore.State('appointmentDetail') |
| | | appointmentDetail!: Appointment; |
| | | |
| | | @appointmentStore.Getter('appointmentProgress') |
| | | appointmentProgress!: ContactStatus; |
| | | |
| | | isVisibleDialog = false; |
| | | isShowInviteReviewDialog = false ; |
| | | interviewTxt = ""; |
| | | contactStatus = ContactStatus; |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | async asyncData(context: Context) { |
| | | const appointmentId = +context.route.params.appointmentId; |
| | | return { |
| | | appointmentDetail: await appointmentService.getAppointmentDetail(appointmentId).then((res) => res) |
| | | } |
| | | } |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | |
| | | return this.appointmentDetail.communicateStatus === this.contactStatus.DONE |
| | | || this.appointmentDetail.communicateStatus === this.contactStatus.CLOSE |
| | | || this.appointmentDetail.communicateStatus === this.contactStatus.CANCEL; |
| | | } |
| | | |
| | | get showWhenAppointmentHasCreate(): boolean { |
| | | return this.appointmentDetail.communicateStatus === this.contactStatus.PICKED |
| | | || this.appointmentDetail.communicateStatus === this.contactStatus.RESERVED; |
| | | } |
| | | |
| | | get showWhenAppointmentHasContacted() :boolean { |
| | | return this.appointmentDetail.communicateStatus === this.contactStatus.CONTACTED; |
| | | } |
| | | |
| | | get hopeContactTimeList(): any[] { |
| | | return this.appointmentDetail.hopeContactTime.split("','") |
| | | } |
| | | |
| | | getHopeContactTimeContent(hopeContactTimeString: string): string[] { |
| | | const result = hopeContactTimeString.replaceAll("'", '').split('、'); |
| | | return result; |
| | | } |
| | | |
| | | inviteReview(): void { |
| | | reviewsService.sendSatisfactionToClient(this.appointmentDetail.id).then(res => { |
| | | this.isShowInviteReviewDialog = true; |
| | | }); |
| | | } |
| | | } |
| | | </script> |
| | |
| | | height: 100px; |
| | | width: 100px; |
| | | border-radius: 50%; |
| | | background-color: #fff; |
| | | border: 1px solid $PRIMARY_BLACK; |
| | | background-image: url('~/assets/images/appointment/avatar_bg.svg'); |
| | | position: relative; |
| | | display: flex; |
| | | justify-content: center; |
| | |
| | | width: 30px; |
| | | border-radius: 50%; |
| | | background-color: #fff; |
| | | border: 1px solid $PRIMARY_BLACK; |
| | | bottom: 0; |
| | | right: 0; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | .sex-icon { |
| | | font-size: 20px; |
| | | &.icon-sex-male{ |
| | | color: $SKY_BLUE; |
| | | } |
| | | &.icon-sex-female{ |
| | | color: $CORAL; |
| | | } |
| | | } |
| | | &-male { |
| | | border: 1px solid $SKY_BLUE; |
| | | } |
| | | &-female { |
| | | border: 1px solid $LIGHT_RED; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | display: flex; |
| | | } |
| | | .client-detail-demand__demand-list-label { |
| | | @extend .mr-10; |
| | | @extend .mdTxt; |
| | | @extend .mb-10; |
| | | @extend .mdTxt; |
| | | @extend .mr-10; |
| | | line-height: 1.3; |
| | | color : $DARK_BLUE; |
| | | flex-basis: auto; |
| | | min-width : 40px; |
| | | } |
| | | .client-detail-demand__demand-list-content { |
| | | text-align: justify; |
| | | line-height: 1.3; |
| | | text-justify: auto; |
| | | word-break: break-all; |
| | | } |
| | | } |
| | | .client-detail-action { |
| | |
| | | } |
| | | } |
| | | } |
| | | .invite-review{ |
| | | align-items : center; |
| | | display : flex; |
| | | flex-direction: column; |
| | | } |
| | | .close-appointment-detail{ |
| | | background-color: #fff; |
| | | display: flex; |
| | |
| | | justify-content: space-between; |
| | | flex: 1; |
| | | } |
| | | .hope-contact-time__line { |
| | | border-bottom: 1px solid #CCCCCC; |
| | | } |
| | | .btn-center{ |
| | | display: flex; |
| | | justify-content: center; |
| | | } |
| | | |
| | | @include desktop { |
| | | .client-detail-action { |
| | | display: flex; |
| | | justify-content: center; |
| | | } |
| | | .desktop-client-detail-action-btn{ |
| | | margin-right: 10px; |
| | | } |
| | | } |
| | | |
| | | </style> |