Merge branch 'Phase3' of ssh://192.168.0.10:29418/pcalife/PAM into Phase3
| | |
| | | <template> |
| | | <div> |
| | | <div class="interview__header"> |
| | | <div class="mdTxt">ç´è¨ªç´é</div> |
| | | <div class="pam-link-button--lg" |
| | | @click="addInterview">+æ°å¢</div> |
| | | </div> |
| | | |
| | | <template v-if="!interviewList.length"> |
| | | <div class="record-card record-card--empty"> |
| | | ç¡ç´è¨ªç´é |
| | | </div> |
| | | </template> |
| | | |
| | | <template v-if="interviewList.length"> |
| | | <div |
| | | v-for="(item, index) in futureList" |
| | | :key="index + 'feature'" |
| | | class="interview--future" |
| | | @click="editInterview(item)" |
| | | > |
| | | |
| | | <div class="record-card"> |
| | | <div class="record-card-date"> |
| | | <div> |
| | | <UiDateFormat |
| | | class="date bold" |
| | | :date="item.interviewDate" |
| | | onlyShowSection="DAY" /> |
| | | </div> |
| | | <div> |
| | | <UiDateFormat |
| | | class="time mt-5 line-space" |
| | | :date="item.interviewDate" |
| | | onlyShowSection="TIME" /> |
| | | </div> |
| | | </div> |
| | | <div class="record-card-content"> |
| | | <span>{{item.content}}</span> |
| | | </div> |
| | | </div> |
| | | <div class="interview__header"> |
| | | <div class="mdTxt">ç´è¨ªç´é</div> |
| | | <div class="pam-link-button--lg" |
| | | @click="addInterview">+æ°å¢</div> |
| | | </div> |
| | | <InterviewCard :interviewList="displayList.slice(0, 3)"></InterviewCard> |
| | | |
| | | <section |
| | | class="interview--past" |
| | | v-for="(item, index) in pastList" |
| | | :key="index + 'past'" |
| | | @click="editInterview(item)" |
| | | > |
| | | <div class="record-card"> |
| | | <div class="record-card-date"> |
| | | <div> |
| | | <UiDateFormat |
| | | class="date bold" |
| | | :date="item.interviewDate" |
| | | onlyShowSection="DAY" /> |
| | | </div> |
| | | <div> |
| | | <UiDateFormat |
| | | class="time mt-5 line-space" |
| | | :date="item.interviewDate" |
| | | onlyShowSection="TIME" /> |
| | | </div> |
| | | </div> |
| | | <div class="record-card-content"> |
| | | <span>{{item.content}}</span> |
| | | </div> |
| | | </div> |
| | | <section class="text--right mt-30" v-if="interviewList.length > 3"> |
| | | <div class="pam-link-button--lg" @click="readMoreBtn">å±éçæ´å¤</div> |
| | | </section> |
| | | |
| | | <section class="more-log-action"> |
| | | <div class="pam-link-button--lg">å±éçæ´å¤</div> |
| | | </section> |
| | | </template> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop, Watch, Mutation } from 'nuxt-property-decorator'; |
| | | import { Vue, Component, Prop, Watch } from 'nuxt-property-decorator'; |
| | | import { InterviewRecord } from '~/shared/models/appointment.model'; |
| | | |
| | | @Component |
| | |
| | | @Prop() |
| | | interviewList!: InterviewRecord[]; |
| | | |
| | | @Mutation |
| | | updateInterviewRecord!: (data: InterviewRecord) => void; |
| | | |
| | | appointmentId!: string; |
| | | |
| | | futureList: InterviewRecord[] = []; |
| | | pastList: InterviewRecord[] = []; |
| | | displayList: InterviewRecord[] = []; |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | |
| | | @Watch('interviewList', {immediate: true}) |
| | | updateInterviewList() { |
| | | if (this.interviewList && this.interviewList.length > 0) { |
| | | this.futureList = this.interviewList |
| | | .filter(item => new Date(item.interviewDate).getTime() >= new Date().getTime()) |
| | | this.pastList = this.interviewList |
| | | .filter(item => new Date(item.interviewDate).getTime() < new Date().getTime()); |
| | | this.displayList = this.interviewList |
| | | .map((i) => ({ ...i, sortDate: new Date(i.interviewDate)})) |
| | | .sort((preItem, nextItem) => +nextItem.sortDate - +preItem.sortDate); |
| | | } |
| | | } |
| | | |
| | |
| | | this.$router.push(`/appointment/${this.appointmentId}/interview/new`); |
| | | } |
| | | |
| | | editInterview(interviewRecord) { |
| | | this.updateInterviewRecord(interviewRecord); |
| | | this.$router.push(`/appointment/${this.appointmentId}/interview/${interviewRecord.id}`); |
| | | readMoreBtn() { |
| | | this.$router.push(`/appointment/${this.appointmentId}/interviewList`); |
| | | } |
| | | |
| | | } |
| | |
| | | display : flex; |
| | | justify-content: space-between; |
| | | margin-bottom : 10px; |
| | | } |
| | | .interview--future{ |
| | | border-bottom: 1px solid #CCCCCC; |
| | | padding-bottom: 17px; |
| | | margin-bottom: 17px; |
| | | .record{ |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | .record-card { |
| | | height: 62px; |
| | | border: 1px solid #707070; |
| | | border-radius: 5px; |
| | | display: flex; |
| | | border-bottom: 1px solid #000; |
| | | .record-card-date{ |
| | | display: flex; |
| | | flex-direction: column; |
| | | margin-left: 10px; |
| | | margin-right: 10px; |
| | | margin-top: 10px; |
| | | } |
| | | .record-card-content{ |
| | | height: 42px; |
| | | margin-top: 10px; |
| | | margin-right: 10px; |
| | | line-height: 1.2; |
| | | } |
| | | &.record-card--empty { |
| | | align-items : center; |
| | | background-color: #fff; |
| | | color : $MID_GREY; |
| | | justify-content : center; |
| | | } |
| | | } |
| | | .line-space{ |
| | | letter-spacing: 1px; |
| | | } |
| | | .more-log-action{ |
| | | margin-top: 30px; |
| | | display: flex; |
| | | justify-content:flex-end; |
| | | } |
| | | </style> |
| | |
| | | <div class="record-log-component"> |
| | | <div class="mdTxt mt-30 mb-10">系統éç¥ç´é</div> |
| | | |
| | | <div v-for="(item, index) in displayLogs" |
| | | :key="index"> |
| | | <section |
| | | class="record-log-card" |
| | | > |
| | | <div class="record-log-card-date-container"> |
| | | <div class="record-log-card-date-container-circle"> |
| | | <div class="xxsTxt bold line-height">{{item.createdDate | formatYear}}</div> |
| | | <div> |
| | | <UiDateFormat |
| | | class="xxsTxt bold line-height" |
| | | :date="item.createdDate" |
| | | onlyShowSection="DAY" /> |
| | | </div> |
| | | <div> |
| | | <UiDateFormat |
| | | class="xxsTxt mt-4 line-space" |
| | | :date="item.createdDate" |
| | | onlyShowSection="TIME" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="record-log-msg"> |
| | | <div>ç¼éç´è¨ªéç¥ |
| | | <span v-if="item.email && item.phone">(ææ©ç°¡è¨ãEmail)</span> |
| | | <span v-else-if="item.email">(Email)</span> |
| | | <span v-else>(ææ©ç°¡è¨)</span> |
| | | </div> |
| | | <div class="mt-10">é ç´{{item.interviewDate | formatDate}}</div> |
| | | </div> |
| | | </section> |
| | | <div class="time-line"></div> |
| | | </div> |
| | | <InterviewRecordCard :noticeLogsList="displayLogs.slice(0, 3)"></InterviewRecordCard> |
| | | |
| | | <section class="more-log-action"> |
| | | <section class="text--right mt-30" v-if="displayLogs.length > 3"> |
| | | <div class="pam-link-button--lg" |
| | | @click="readMoreBtn" |
| | | >å±éçæ´å¤</div> |
| | | </section> |
| | | </div> |
| | |
| | | import { Vue, Component, Prop, Watch } from 'nuxt-property-decorator'; |
| | | import { NoticeLogs } from '~/shared/models/appointment.model'; |
| | | |
| | | @Component({ |
| | | filters: { |
| | | formatYear(value) { |
| | | if (value) { |
| | | return new Date(value).getFullYear(); |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | @Component |
| | | export default class AppointmentRecordList extends Vue { |
| | | |
| | | @Prop() |
| | |
| | | |
| | | appointmentId: string = ''; |
| | | displayLogs : NoticeLogs[] = []; |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | mounted() { |
| | | this.appointmentId = this.$route.params.appointmentId; |
| | |
| | | } |
| | | } |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | readMoreBtn() { |
| | | this.$router.push(`/appointment/${this.appointmentId}/recordList`); |
| | | } |
| | | |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .record-log-component{ |
| | | display: flex; |
| | | flex-direction: column; |
| | | .record-log-card{ |
| | | display: flex; |
| | | .record-log-card-date-container{ |
| | | position:relative; |
| | | .record-log-card-date-container-circle{ |
| | | display: flex; |
| | | flex-direction: column; |
| | | width: 56px; |
| | | height: 56px; |
| | | border-radius: 50%; |
| | | border:1px solid $PRIMARY_BLACK; |
| | | justify-content: center; |
| | | align-items: center; |
| | | align-content: center; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .mt-4{ |
| | | margin-top: 4px; |
| | | } |
| | | .line-space{ |
| | | letter-spacing: 1px; |
| | | } |
| | | .line-height{ |
| | | line-height:1.2; |
| | | } |
| | | .time-line{ |
| | | border-left: 1px solid black; |
| | | height: 30px; |
| | | margin-left: 28px; |
| | | |
| | | } |
| | | .record-log-msg{ |
| | | margin-left: 13px; |
| | | margin-top: 10px; |
| | | } |
| | | .more-log-action{ |
| | | display: flex; |
| | | justify-content:flex-end; |
| | | } |
| | | |
| | | </style> |
| | |
| | | import * as _ from 'lodash'; |
| | | import { Role } from '~/shared/models/enum/Role'; |
| | | |
| | | const roleStorage = namespace('localStorage'); |
| | | const appointmentStore = namespace('appointment.store'); |
| | | const roleStorage = namespace('localStorage'); |
| | | |
| | | @Component |
| | | export default class UiCarousel extends Vue { |
| | |
| | | @roleStorage.Getter |
| | | currentRole!:string; |
| | | |
| | | @appointmentStore.Getter |
| | | isCloseAppointment!: boolean; |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | goBack(): void { |
| | | const pathName = this.$route.name; |
| | | pathName?.includes('myConsultantList') ? this.$router.push('/') : this.$router.go(-1); |
| | | pathName?.includes('myConsultantList') |
| | | ? this.$router.push('/') |
| | | : this.$router.go(-1); |
| | | } |
| | | |
| | | get label(): string { |
| | |
| | | featureLabel = 'F&Q 常è¦åé¡'; |
| | | break; |
| | | case 'appointment': |
| | | const appointmentFeatureLabel = this.$route.name.includes('close') ? 'çµæ¡' : 'é ç´è³è¨'; |
| | | const appointmentFeatureLabel = this.$route.name.includes('close') |
| | | ? 'çµæ¡' |
| | | : this.isCloseAppointment ? 'çµæ¡æç´°' : 'é ç´è³è¨'; |
| | | const inInterview = this.$route.name.includes('interview'); |
| | | const addNewInterview = this.$route.name.includes('new'); |
| | | if (inInterview) { |
| | | featureLabel = addNewInterview ? 'æ°å¢ç´è¨ªç´é' : '編輯ç´è¨ªç´é'; |
| | | const interviewList = this.$route.name.includes('interviewList'); |
| | | const recordList = this.$route.name.includes('recordList'); |
| | | if (interviewList) { |
| | | featureLabel = 'ç´è¨ªç´é'; |
| | | } else if (recordList) { |
| | | featureLabel = '系統éç¥ç´é'; |
| | | } else if (inInterview) { |
| | | featureLabel = addNewInterview |
| | | ? 'æ°å¢ç´è¨ªç´é' |
| | | : '編輯ç´è¨ªç´é'; |
| | | } else { |
| | | featureLabel = appointmentFeatureLabel; |
| | | } |
| | |
| | | updateMyAppointmentList!: (data: Appointment) => void; |
| | | |
| | | @appointmentStore.Action |
| | | setAppointmentDetail!: (appointmentId: number) => Promise<Appointment>; |
| | | getAppointmentDetail!: (appointmentId: number) => Promise<Appointment>; |
| | | |
| | | @appointmentStore.Getter |
| | | appointmentProgress!: ContactStatus; |
| | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | viewAppointmentDetail(): void { |
| | | this.setAppointmentDetail(this.client.id).then((_) => { |
| | | this.getAppointmentDetail(this.client.id).then((_) => { |
| | | this.$router.push(`/appointment/${this.client.id}`); |
| | | }); |
| | | } |
| | |
| | | <template> |
| | | <div class="edit-appointment-record"> |
| | | <div class="edit-appointment-record-date" v-if="interviewId"> |
| | | <div class="edit-appointment-record-date" v-if="interviewId && interviewRecord"> |
| | | <span>{{interviewRecord.createdDate | formatDate}} 建ç«</span> |
| | | <span>{{interviewRecord.lastModifiedDate | formatDate}} æ´æ°</span> |
| | | </div> |
| | |
| | | |
| | | <InterviewMsg |
| | | :isVisible.sync="showInterviewMsgPopup" |
| | | :client="appointmentDetail" |
| | | @closeDialog="closePopup" |
| | | ></InterviewMsg> |
| | | </div> |
| | | </template> |
| | | <script lang="ts"> |
| | | import { InterviewRecord, InterviewRecordInfo } from '~/shared/models/appointment.model'; |
| | | import { Vue, Component, Prop, State, Mutation, Watch, Action } from 'nuxt-property-decorator'; |
| | | import { Appointment, InterviewRecord, InterviewRecordInfo } from '~/shared/models/appointment.model'; |
| | | import { Vue, Component, Watch, namespace } from 'nuxt-property-decorator'; |
| | | import appointmentService from '~/shared/services/appointment.service'; |
| | | |
| | | const appointmentStore = namespace('appointment.store'); |
| | | |
| | | @Component |
| | | export default class InterviewAdd extends Vue { |
| | | @State |
| | | interviewRecord!: InterviewRecord; |
| | | |
| | | @Mutation |
| | | updateInterviewRecord!: (data: InterviewRecord) => void; |
| | | @appointmentStore.State |
| | | appointmentDetail!: Appointment; |
| | | |
| | | @Mutation |
| | | clearInterviewRecord!: () => void; |
| | | @appointmentStore.Action |
| | | updateAppointmentDetail!: (id: number) => Appointment; |
| | | |
| | | interviewTime = ''; |
| | | content = ''; |
| | |
| | | |
| | | defaultValue = ''; |
| | | |
| | | interviewRecord!: InterviewRecord; |
| | | |
| | | //////////////////////////////////////////////////////////////////// |
| | | |
| | | mounted() { |
| | | this.interviewId = this.$route.params.interviewId; |
| | | this.appointmentId = this.$route.params.appointmentId; |
| | | const isEditPage = this.interviewId && this.interviewRecord; |
| | | if (isEditPage) { |
| | | this.checkInterviewRecord(); |
| | | } |
| | | } |
| | | |
| | | private checkInterviewRecord() { |
| | | if (this.interviewRecord.appointmentId !== +this.appointmentId |
| | | || this.interviewRecord.id !== +this.interviewId) { |
| | | appointmentService.getAppointmentDetail(+this.appointmentId).then((data) => { |
| | | const currentInterviewRecord = data.interviewRecordDTOs.filter(item => item.id === +this.interviewId)[0]; |
| | | this.updateInterviewRecord(currentInterviewRecord); |
| | | }) |
| | | } |
| | | } |
| | | |
| | | destroyed() { |
| | | this.clearInterviewRecord(); |
| | | this.onAppointmentDetailChange(); |
| | | } |
| | | |
| | | //////////////////////////////////////////////////////////////////// |
| | | |
| | | @Watch('interviewRecord', {immediate: true}) |
| | | watchInterviewRecord() { |
| | | if (this.interviewRecord && this.interviewRecord.content) { |
| | | this.content = this.interviewRecord.content; |
| | | this.defaultValue = this.interviewRecord.interviewDate; |
| | | @Watch('appointmentDetail', {immediate: true}) |
| | | onAppointmentDetailChange() { |
| | | if (this.appointmentDetail && this.appointmentDetail.id === +this.appointmentId) { |
| | | this.interviewRecord = this.appointmentDetail.interviewRecordDTOs |
| | | .filter(item => item.id === +this.interviewId)[0]; |
| | | |
| | | if (this.interviewRecord && this.interviewId) { |
| | | this.content = this.interviewRecord.content; |
| | | this.defaultValue = this.interviewRecord.interviewDate; |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | this.updateRecord(updateInterviewRecord); |
| | | } |
| | | this.updateAppointmentDetail(+this.appointmentId); |
| | | } |
| | | |
| | | private createdRecord(interviewRecordInfo) { |
| | |
| | | } |
| | | } |
| | | |
| | | closePopup() { |
| | | this.$router.push(`/appointment/${this.appointmentId}`); |
| | | } |
| | | |
| | | deleteInterviewRecord() { |
| | | appointmentService.deleteInterviewRecord(this.interviewId).then(res => { |
| | | this.confirmTxt = 'åªé¤æå'; |
| | | this.showConfirmPopup = true; |
| | | this.updateAppointmentDetail(+this.appointmentId); |
| | | }); |
| | | } |
| | | |
| | |
| | | this.defaultValue = this.interviewRecord.interviewDate; |
| | | this.isEdit = false; |
| | | } else { |
| | | this.$router.push(`/appointment/${this.appointmentId}`); |
| | | this.$router.go(-1); |
| | | } |
| | | } |
| | | |
| | | closePopup() { |
| | | this.$router.go(-1); |
| | | } |
| | | |
| | | //////////////////////////////////////////////////////////////////// |
| | | |
| | | get formatInterviewDate() { |
¤ñ¹ï·sÀÉ®× |
| | |
| | | <template> |
| | | <div> |
| | | <template v-if="!interviewList.length"> |
| | | <div class="record-card record-card--empty"> |
| | | ç¡ç´è¨ªç´é |
| | | </div> |
| | | </template> |
| | | |
| | | <template v-else> |
| | | <div class="interview--future"> |
| | | <div class="record-card mb-10" |
| | | v-for="(item, index) in futureList" |
| | | :key="index + 'feature'" |
| | | @click="editInterview(item)" |
| | | > |
| | | <div class="record-card-date"> |
| | | <div> |
| | | <UiDateFormat |
| | | class="date bold" |
| | | :date="item.interviewDate" |
| | | onlyShowSection="DAY" /> |
| | | </div> |
| | | <div> |
| | | <UiDateFormat |
| | | class="time mt-5 line-space" |
| | | :date="item.interviewDate" |
| | | onlyShowSection="TIME" /> |
| | | </div> |
| | | </div> |
| | | <div class="record-card-content"> |
| | | <span>{{item.content}}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <section class="interview--past" v-if="pastList.length"> |
| | | <div class="record-card mb-10" |
| | | v-for="(item, index) in pastList" |
| | | :key="index + 'past'" |
| | | @click="editInterview(item)" |
| | | > |
| | | <div class="record-card-date"> |
| | | <div> |
| | | <UiDateFormat |
| | | class="date bold" |
| | | :date="item.interviewDate" |
| | | onlyShowSection="DAY" /> |
| | | </div> |
| | | <div> |
| | | <UiDateFormat |
| | | class="time mt-5 line-space" |
| | | :date="item.interviewDate" |
| | | onlyShowSection="TIME" /> |
| | | </div> |
| | | </div> |
| | | <div class="record-card-content"> |
| | | <span>{{item.content}}</span> |
| | | </div> |
| | | </div> |
| | | </section> |
| | | </template> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Component, Prop, Vue, Watch } from "nuxt-property-decorator"; |
| | | import { InterviewRecord } from "~/shared/models/appointment.model"; |
| | | |
| | | @Component |
| | | export default class InterviewCard extends Vue { |
| | | |
| | | @Prop() |
| | | interviewList!: InterviewRecord[]; |
| | | |
| | | futureList: InterviewRecord[] = []; |
| | | pastList: InterviewRecord[] = []; |
| | | |
| | | appointmentId!: number; |
| | | |
| | | mounted() { |
| | | this.appointmentId = +this.$route.params.appointmentId; |
| | | } |
| | | |
| | | @Watch('interviewList', {immediate: true}) |
| | | onInterviewListChange() { |
| | | if (this.interviewList.length > 0) { |
| | | this.futureList = this.interviewList |
| | | .filter(item => new Date(item.interviewDate).getTime() >= new Date().getTime()) |
| | | .sort((preItem, nextItem) => +new Date(nextItem.interviewDate) - +new Date(preItem.interviewDate)); |
| | | this.pastList = this.interviewList |
| | | .filter(item => new Date(item.interviewDate).getTime() < new Date().getTime()) |
| | | .sort((preItem, nextItem) => +new Date(nextItem.interviewDate) - +new Date(preItem.interviewDate)); |
| | | } |
| | | |
| | | } |
| | | |
| | | editInterview(interviewRecord) { |
| | | this.$router.push(`/appointment/${this.appointmentId}/interview/${interviewRecord.id}`); |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .interview--future{ |
| | | .record{ |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | .interview--past { |
| | | border-top: 1px solid #CCCCCC; |
| | | padding-top: 17px; |
| | | margin-top: 17px; |
| | | } |
| | | .record-card { |
| | | height: 62px; |
| | | border: 1px solid #707070; |
| | | border-radius: 5px; |
| | | display: flex; |
| | | border-bottom: 1px solid #000; |
| | | .record-card-date{ |
| | | display: flex; |
| | | flex-direction: column; |
| | | margin-left: 10px; |
| | | margin-right: 10px; |
| | | margin-top: 10px; |
| | | } |
| | | .record-card-content{ |
| | | height: 42px; |
| | | margin-top: 10px; |
| | | margin-right: 10px; |
| | | line-height: 1.2; |
| | | } |
| | | &.record-card--empty { |
| | | align-items : center; |
| | | background-color: #fff; |
| | | color : $MID_GREY; |
| | | justify-content : center; |
| | | } |
| | | } |
| | | .line-space{ |
| | | letter-spacing: 1px; |
| | | } |
| | | </style> |
| | |
| | | |
| | | <el-input |
| | | type="textarea" |
| | | autosize="true" |
| | | :autosize="true" |
| | | placeholder="ç´è¨ªéç¥" |
| | | resize="none" |
| | | v-model="isInterviewTxt"> |
| | |
| | | </div> |
| | | </template> |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop, PropSync, Emit, Action } from 'nuxt-property-decorator'; |
| | | import { Vue, Component, Prop, PropSync, Emit, Action, namespace } from 'nuxt-property-decorator'; |
| | | |
| | | import appointmentService from '~/shared/services/appointment.service'; |
| | | import { Appointment, ToInformAppointment } from '~/shared/models/appointment.model'; |
| | | import { AgentInfo } from '~/shared/models/agent-info.model'; |
| | | |
| | | const loginStore = namespace('login.store'); |
| | | const appointmentStore = namespace('appointment.store'); |
| | | |
| | | @Component |
| | | export default class InterviewMsg extends Vue { |
| | | |
| | | @Action |
| | | storeMyAppointmentList!: () => Promise<number>; |
| | | |
| | | @appointmentStore.Action |
| | | updateAppointmentDetail!: (id: number) => Appointment; |
| | | |
| | | @PropSync('isVisible') |
| | | dialogVisible!: boolean; |
| | |
| | | closeDialog() { |
| | | return; |
| | | } |
| | | |
| | | @loginStore.State |
| | | loginConsultant!: AgentInfo; |
| | | |
| | | isShowSuccessAlert = false; |
| | | |
| | |
| | | }; |
| | | appointmentService.informAppointment(appointmentInformation).then((_) => { |
| | | this.isShowSuccessAlert = true ; |
| | | this.updateAppointmentDetail(this.client.id); |
| | | }); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | get isInterviewTxt() : string{ |
| | | return this.interviewTxt = "æ¨å¥½ï¼ææ¯ä¿èª åªåå¹³å°çä¿éªé¡§å" + "agentName"+"ï¼æè¬æ¨çé ç´ï¼æé è¨æå¨ä¸è¿°çæéèæ¨è¯ç¹«"+"\n"+"以䏿¯æçé»è©±è碼/Emailï¼"+"\n"+"agentPhone"+"\n"+"agentEmail"+"\n"+"è¥æ¤æé䏿¹ä¾¿ï¼è«èæè¯ç¹«ï¼è¬è¬ï¼" |
| | | return this.interviewTxt = "æ¨å¥½ï¼ææ¯ä¿èª åªåå¹³å°çä¿éªé¡§å" + this.loginConsultant?.name + "ï¼æè¬æ¨çé ç´ï¼æé è¨æå¨ä¸è¿°çæéèæ¨è¯ç¹«"+"\n"+"以䏿¯æçé»è©±è碼/Emailï¼"+"\n" + this.loginConsultant?.phoneNumber + "\n" + this.loginConsultant?.email + "\n"+"è¥æ¤æé䏿¹ä¾¿ï¼è«èæè¯ç¹«ï¼è¬è¬ï¼" |
| | | } |
| | | |
| | | } |
¤ñ¹ï·sÀÉ®× |
| | |
| | | <template> |
| | | <div class="record-log-component"> |
| | | <div v-for="(item, index) in noticeLogsList" |
| | | :key="index"> |
| | | <section |
| | | class="record-log-card" |
| | | > |
| | | <div class="record-log-card-date-container"> |
| | | <div class="record-log-card-date-container-circle"> |
| | | <div class="xxsTxt bold line-height">{{item.createdDate | formatYear}}</div> |
| | | <div> |
| | | <UiDateFormat |
| | | class="xxsTxt bold line-height" |
| | | :date="item.createdDate" |
| | | onlyShowSection="DAY" /> |
| | | </div> |
| | | <div> |
| | | <UiDateFormat |
| | | class="xxsTxt mt-4 line-space" |
| | | :date="item.createdDate" |
| | | onlyShowSection="TIME" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="record-log-msg"> |
| | | <div>ç¼éç´è¨ªéç¥ |
| | | <span v-if="item.email && item.phone">(ææ©ç°¡è¨ãEmail)</span> |
| | | <span v-else-if="item.email">(Email)</span> |
| | | <span v-else>(ææ©ç°¡è¨)</span> |
| | | </div> |
| | | <div class="mt-10">é ç´{{item.interviewDate | formatDate}}</div> |
| | | </div> |
| | | </section> |
| | | <div class="time-line"></div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Component, Prop, Vue } from "nuxt-property-decorator"; |
| | | import { NoticeLogs } from "~/shared/models/appointment.model"; |
| | | |
| | | @Component({ |
| | | filters: { |
| | | formatYear(value) { |
| | | if (value) { |
| | | return new Date(value).getFullYear(); |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | export default class RecordCard extends Vue { |
| | | @Prop() |
| | | noticeLogsList!: NoticeLogs[]; |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .record-log-component{ |
| | | display: flex; |
| | | flex-direction: column; |
| | | .record-log-card{ |
| | | display: flex; |
| | | .record-log-card-date-container{ |
| | | position:relative; |
| | | .record-log-card-date-container-circle{ |
| | | display: flex; |
| | | flex-direction: column; |
| | | width: 56px; |
| | | height: 56px; |
| | | border-radius: 50%; |
| | | border:1px solid $PRIMARY_BLACK; |
| | | justify-content: center; |
| | | align-items: center; |
| | | align-content: center; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .mt-4{ |
| | | margin-top: 4px; |
| | | } |
| | | .line-space{ |
| | | letter-spacing: 1px; |
| | | } |
| | | .line-height{ |
| | | line-height:1.2; |
| | | } |
| | | .time-line{ |
| | | border-left: 1px solid black; |
| | | height: 30px; |
| | | margin-left: 28px; |
| | | |
| | | } |
| | | .record-log-msg{ |
| | | margin-left: 13px; |
| | | margin-top: 10px; |
| | | } |
| | | </style> |
| | |
| | | </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'; |
| | | |
¤ñ¹ï·sÀÉ®× |
| | |
| | | |
| | | <template> |
| | | <div> |
| | | <div class="text--right mb-30"> |
| | | <div class="pam-link-button--lg" |
| | | @click="addInterview">+æ°å¢</div> |
| | | </div> |
| | | <InterviewCard :interviewList="appointmentDetail.interviewRecordDTOs"></InterviewCard> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Component, namespace, Vue } from "nuxt-property-decorator"; |
| | | import { Appointment } from "~/shared/models/appointment.model"; |
| | | |
| | | const appointmentStore = namespace('appointment.store'); |
| | | |
| | | @Component |
| | | export default class InterviewList extends Vue { |
| | | @appointmentStore.State |
| | | appointmentDetail!: Appointment; |
| | | |
| | | appointmentId!: number; |
| | | |
| | | //////////////////////////////////////////////////////// |
| | | |
| | | mounted() { |
| | | this.appointmentId = +this.$route.params.appointmentId; |
| | | } |
| | | |
| | | //////////////////////////////////////////////////////// |
| | | |
| | | addInterview(): void { |
| | | this.$router.push(`/appointment/${this.appointmentId}/interview/new`); |
| | | } |
| | | |
| | | } |
| | | </script> |
¤ñ¹ï·sÀÉ®× |
| | |
| | | |
| | | |
| | | <template> |
| | | <InterviewRecordCard :noticeLogsList="displayLogs"></InterviewRecordCard> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Component, namespace, Vue, Watch } from "nuxt-property-decorator"; |
| | | import { Appointment, NoticeLogs } from "~/shared/models/appointment.model"; |
| | | |
| | | const appointmentStore = namespace('appointment.store'); |
| | | |
| | | @Component |
| | | export default class RecordList extends Vue { |
| | | @appointmentStore.State |
| | | appointmentDetail!: Appointment; |
| | | |
| | | displayLogs: NoticeLogs[] = []; |
| | | |
| | | //////////////////////////////////////////////////////// |
| | | |
| | | @Watch('appointmentDetail', {immediate: true}) |
| | | onAppointmentDetailChange() { |
| | | if (this.appointmentDetail?.appointmentNoticeLogs.length) { |
| | | this.displayLogs = this.appointmentDetail?.appointmentNoticeLogs |
| | | .map((i) => ({ ...i, sortDate: new Date(i.createdDate)})) |
| | | .sort((preItem, nextItem) => +nextItem.sortDate - +preItem.sortDate); |
| | | } |
| | | } |
| | | |
| | | } |
| | | </script> |
| | |
| | | import { Role } from '~/shared/models/enum/Role'; |
| | | import messageBoxService from '~/shared/services/message-box.service'; |
| | | import loginService from '~/shared/services/login.service' |
| | | import { AgentInfo } from '~/shared/models/agent-info.model'; |
| | | |
| | | const loginStore = namespace('login.store'); |
| | | const roleStorage = namespace('localStorage'); |
| | | |
| | | @Component({ |
| | | layout: 'home' |
| | | }) |
| | |
| | | |
| | | @roleStorage.Mutation |
| | | storageConsultantId!:(id:string) => void; |
| | | |
| | | @loginStore.Action |
| | | getLoginConsultantDetail!: (agentNo: string) => Promise<AgentInfo>; |
| | | |
| | | consultantDto = { |
| | | password: '', |
| | |
| | | private verify():void{ |
| | | loginService.getVerificationStatus(this.verificationCode).then( verifySuccess => { |
| | | if(verifySuccess.data){ |
| | | this.loginWithConsultant() |
| | | this.loginWithConsultant(); |
| | | }else{ |
| | | this.clearValue(); |
| | | this.regenerateImgOfVerification(); |
| | |
| | | |
| | | private loginWithConsultant(): void { |
| | | loginService.logInToConsultant(this.consultantDto).then(res => { |
| | | this.getLoginConsultantDetail(this.consultantDto.username); |
| | | this.storageIdToken(res.data.id_token); |
| | | this.storageRole(Role.ADMIN); |
| | | this.storageConsultantId(this.consultantDto.username) |
| | |
| | | export interface AgentInfo { |
| | | name : string; |
| | | agentNo : string; |
| | | role : string; |
| | | img : string; |
| | | avgScore : number; |
| | | title : string; |
| | | phoneNumber : string; |
| | | serveArea : string; |
| | | companyAddress : string; |
| | | latestLoginTime : Date ; |
| | | seniority : string; |
| | | suitability : number; |
| | | evaluation : number; |
| | | expertise : string[]; |
| | | concept : string; |
| | | experiences : string; |
| | | awards : string; |
| | | gender : string, |
| | | agentNo : string; |
| | | avgScore : number; |
| | | awards : string; |
| | | communicationStyle: string; |
| | | companyAddress : string; |
| | | concept : string; |
| | | email? : string; |
| | | evaluation : number; |
| | | experiences : string; |
| | | expertise : string[]; |
| | | gender : string, |
| | | img : string; |
| | | latestLoginTime : Date ; |
| | | name : string; |
| | | phoneNumber : string; |
| | | role : string; |
| | | seniority : string; |
| | | serveArea : string; |
| | | suitability : number; |
| | | title : string; |
| | | } |
| | |
| | | .filter(item => item.communicateStatus === this.contactStatus.DONE || item.communicateStatus === this.contactStatus.CLOSE ).length; |
| | | } |
| | | |
| | | get isCloseAppointment(): boolean { |
| | | const closedStatusList = [this.contactStatus.DONE, this.contactStatus.CLOSE, this.contactStatus.CANCEL]; |
| | | return closedStatusList.includes(this.appointmentDetail!.communicateStatus); |
| | | } |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | @Mutation |
| | |
| | | } |
| | | |
| | | @Action({ commit: 'SET_APPOINTMENT'}) |
| | | async setAppointmentDetail(appointmentId: number): Promise<Appointment> { |
| | | async getAppointmentDetail(appointmentId: number): Promise<Appointment> { |
| | | if (this.appointmentDetail && this.appointmentDetail.id === appointmentId) { |
| | | return this.appointmentDetail; |
| | | } else { |
| | |
| | | import { StrictQueryParams } from '~/shared/models/strict-query.model'; |
| | | import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators' |
| | | |
| | | import { getFavoriteFromStorage, setFavoriteToStorage } from '~/shared/storageConsultant'; |
| | | |
| | | import myConsultantService from '~/shared/services/my-consultant.service'; |
| | | import queryConsultantService from '~/shared/services/query-consultant.service'; |
| | | import appointmentService from '~/shared/services/appointment.service'; |
| | | import reviewsService from '~/shared/services/reviews.service'; |
| | | |
| | | import { Consultant } from '~/shared/models/consultant.model'; |
| | | import { Appointment, AppointmentLog, InterviewRecord } from '~/shared/models/appointment.model'; |
| | | import { AgentOfStrictQuery } from '~/shared/models/strict-query.model'; |
| | | import { AgentInfo } from '~/shared/models/agent-info.model'; |
| | | import { agentCommunicationStyleList } from '~/shared/const/agent-communication-style-list'; |
| | | import { getFavoriteFromStorage, setFavoriteToStorage } from '~/shared/storageConsultant'; |
| | | import { AppointmentLog } from '~/shared/models/appointment.model'; |
| | | import { AgentOfStrictQuery, StrictQueryParams } from '~/shared/models/strict-query.model'; |
| | | |
| | | @Module |
| | | export default class Store extends VuexModule { |
| | | recommendList: Consultant[] = []; |
| | |
| | | myConsultantList: Consultant[] = []; |
| | | |
| | | myAppointmentReviewLogList: AppointmentLog[] = []; |
| | | interviewRecord: InterviewRecord = { |
| | | appointmentId : 0, |
| | | content : '', |
| | | createdBy : '', |
| | | createdDate : '', |
| | | id : 0, |
| | | interviewDate : '', |
| | | lastModifiedBy : '', |
| | | lastModifiedDate: '' |
| | | } |
| | | |
| | | get isUserLogin() { |
| | | return this.context.getters['localStorage/isUserLogin']; |
| | |
| | | @Mutation |
| | | updateMyAppointmentReviewLog(data: AppointmentLog[]) { |
| | | this.myAppointmentReviewLogList = data; |
| | | } |
| | | |
| | | @Mutation |
| | | updateInterviewRecord(data: InterviewRecord) { |
| | | this.interviewRecord = data; |
| | | } |
| | | |
| | | @Mutation |
| | | clearInterviewRecord() { |
| | | this.interviewRecord = { |
| | | appointmentId : 0, |
| | | content : '', |
| | | createdBy : '', |
| | | createdDate : '', |
| | | id : 0, |
| | | interviewDate : '', |
| | | lastModifiedBy : '', |
| | | lastModifiedDate: '' |
| | | } |
| | | } |
| | | |
| | | @Action |
| | |
| | | localStorage.removeItem('current_role'); |
| | | localStorage.removeItem('consultant_id'); |
| | | localStorage.removeItem('appointment'); |
| | | localStorage.removeItem('login_consultant'); |
| | | this.id_token = localStorage.getItem('id_token'); |
| | | this.current_role = localStorage.getItem('current_role'); |
| | | this.consultant_id = localStorage.getItem('consultant_id'); |
¤ñ¹ï·sÀÉ®× |
| | |
| | | import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators' |
| | | |
| | | import myConsultantService from '~/shared/services/my-consultant.service'; |
| | | import { AgentInfo } from '~/shared/models/agent-info.model'; |
| | | |
| | | @Module |
| | | export default class AppointmentStore extends VuexModule { |
| | | |
| | | loginConsultant?: AgentInfo = JSON.parse(localStorage.getItem('login_consultant')!); |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | @Mutation |
| | | SET_LOGIN_CONSULTANT(agentInfo: AgentInfo): void { |
| | | this.loginConsultant = agentInfo; |
| | | localStorage.setItem('login_consultant', JSON.stringify(agentInfo)); |
| | | } |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | @Action({ commit: 'SET_LOGIN_CONSULTANT' }) |
| | | async getLoginConsultantDetail(agentNo: string): Promise<AgentInfo> { |
| | | return await myConsultantService.getConsultantDetail(agentNo).then((res) => res); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | |
| | | appointmentNoticeLogs: é ç´å®ç¼ééç¥çæ·ç¨ |
| | | appointmentClosedInfo: é ç´å®çµæ¡è³æ |
| | | |
| | | |
| | | response body: |
| | | [ { |
| | | "id" : 385, |
| | | "phone" : "0911223344", |
| | | "email" : "SDD", |
| | | "contactType" : "phone", |
| | | "gender" : "female", |
| | | "age" : "21-30", |
| | | "job" : "å
§å¤", |
| | | "requirement" : "å¥åº·èä¿é", |
| | | "communicateStatus" : "contacted", |
| | | "hopeContactTime" : "'ææä¸,ææäº,ææä¸,ææå,ææäº,ææå
,æææ¥ã9:00~12:00,12:00~14:00,14:00~18:00,18:00~21:00'", |
| | | "otherRequirement" : null, |
| | | "appointmentDate" : "2021-12-16T07:11:05.400Z", |
| | | "lastModifiedDate" : "2021-12-28T07:16:37.004Z", |
| | | "agentNo" : "A568420", |
| | | "customerId" : 139, |
| | | "name" : "Angula-test", |
| | | "consultantViewTime" : "2021-12-27T02:02:18.711Z", |
| | | "consultantReadTime" : "2021-12-28T07:16:01.295Z", |
| | | "contactTime" : "2021-12-28T07:16:37.004Z", |
| | | "satisfactionScore" : null, |
| | | "appointmentMemoList" : [ ], |
| | | "interviewRecordDTOs" : [ ], |
| | | "appointmentNoticeLogs" : [ { |
| | | "id" : 1, |
| | | "phone" : "0912345678", |
| | | "email" : "pollex@gmail.com", |
| | | "appointmentId" : 385, |
| | | "content" : "notice customer invterview time", |
| | | "createdDate" : "2022-01-11T08:54:35.651Z" |
| | | }, { |
| | | "id" : 2, |
| | | "phone" : "0912345678", |
| | | "email" : "pollex@gmail.com", |
| | | "appointmentId" : 385, |
| | | "content" : "notice customer invterview time", |
| | | "createdDate" : "2022-01-11T08:57:23.133Z" |
| | | } ] |
| | | } ] |
| | | { |
| | | "id": 385, |
| | | "phone": "0911223344", |
| | | "email": "SDD", |
| | | "contactType": "phone", |
| | | "gender": "female", |
| | | "age": "21-30", |
| | | "job": "å
§å¤", |
| | | "requirement": "å¥åº·èä¿é", |
| | | "communicateStatus": "done", |
| | | "hopeContactTime": "'ææä¸,ææäº,ææä¸,ææå,ææäº,ææå
,æææ¥ã9:00~12:00,12:00~14:00,14:00~18:00,18:00~21:00'", |
| | | "otherRequirement": null, |
| | | "appointmentDate": "2021-12-16T07:11:05.400Z", |
| | | "lastModifiedDate": "2022-01-19T10:57:51.380Z", |
| | | "agentNo": "A568420", |
| | | "customerId": 139, |
| | | "name": "Angula-test", |
| | | "consultantViewTime": "2021-12-27T02:02:18.711Z", |
| | | "consultantReadTime": "2021-12-28T07:16:01.295Z", |
| | | "contactTime": "2021-12-28T07:16:37.004Z", |
| | | "satisfactionScore": null, |
| | | "appointmentMemoList": [], |
| | | "interviewRecordDTOs": [], |
| | | "appointmentNoticeLogs": [ |
| | | { |
| | | "id": 4, |
| | | "phone": "0912345678", |
| | | "email": "pollex@gmail.com", |
| | | "appointmentId": 385, |
| | | "content": "notice customer invterview time", |
| | | "createdDate": "2022-01-11T09:33:57.754Z", |
| | | "interviewDate": null |
| | | }, |
| | | { |
| | | "id": 6, |
| | | "phone": "0912345678", |
| | | "email": "pollex@gmail.com", |
| | | "appointmentId": 385, |
| | | "content": "notice customer invterview time", |
| | | "createdDate": "2022-01-19T10:38:42.187Z", |
| | | "interviewDate": "2022-11-01T08:00:00.000+00:00" |
| | | } |
| | | ], |
| | | "appointmentClosedInfo": { |
| | | "id": 9, |
| | | "policyholderIdentityId": "A123456789", |
| | | "planCode": "ATMdd", |
| | | "policyEntryDate": "2022-01-12T00:00:00.000+00:00", |
| | | "remark": "test remark", |
| | | "closedReason": "other2", |
| | | "closedOtherReason": "å¿æ
ä¸å¥½ä¸æ³è²·2", |
| | | "appointmentId": 385 |
| | | } |
| | | } |
| | |
| | | package com.pollex.pam.appointment.process; |
| | | |
| | | import java.time.Instant; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | |
| | |
| | | |
| | | import com.pollex.pam.domain.Appointment; |
| | | import com.pollex.pam.domain.AppointmentClosedInfo; |
| | | import com.pollex.pam.enums.ContactStatusEnum; |
| | | import com.pollex.pam.repository.AppointmentClosedInfoRepository; |
| | | import com.pollex.pam.repository.AppointmentRepository; |
| | | import com.pollex.pam.service.AppointmentClosedInfoService; |
| | |
| | | process.createProcess(dto); |
| | | } |
| | | }); |
| | | Appointment appointment = appointmentService.findById(dto.getAppointmentId()); |
| | | appointment.setCommunicateStatus(dto.getContactStatus()); |
| | | |
| | | changeAppointmentCommunicateStatus(dto.getAppointmentId(), dto.getContactStatus()); |
| | | |
| | | } |
| | | |
| | | private void changeAppointmentCommunicateStatus(Long appointmentId, ContactStatusEnum contactStatus) { |
| | | Appointment appointment = appointmentService.findById(appointmentId); |
| | | appointment.setCommunicateStatus(contactStatus); |
| | | appointmentRepository.save(appointment); |
| | | } |
| | | |
| | |
| | | import javax.persistence.Table; |
| | | |
| | | import org.springframework.data.annotation.CreatedDate; |
| | | import org.springframework.data.annotation.LastModifiedDate; |
| | | import org.springframework.data.jpa.domain.support.AuditingEntityListener; |
| | | |
| | | import com.pollex.pam.enums.AppointmentStatusEnum; |
| | |
| | | private Instant appointmentDate = Instant.now(); |
| | | |
| | | @Column(name = "last_modified_date") |
| | | @LastModifiedDate |
| | | private Instant lastModifiedDate = Instant.now(); |
| | | |
| | | @Column(name = "agent_no") |
| | |
| | | import java.time.Instant; |
| | | import java.util.List; |
| | | |
| | | import com.pollex.pam.domain.AppointmentClosedInfo; |
| | | import com.pollex.pam.domain.AppointmentMemo; |
| | | import com.pollex.pam.domain.AppointmentNoticeLog; |
| | | import com.pollex.pam.domain.InterviewRecord; |
| | |
| | | private List<AppointmentMemo> appointmentMemoList; |
| | | private List<InterviewRecordDTO> interviewRecordDTOs; |
| | | private List<AppointmentNoticeLog> appointmentNoticeLogs; |
| | | private AppointmentClosedInfo appointmentClosedInfo; |
| | | |
| | | public Long getId() { |
| | | return id; |
| | |
| | | public void setAppointmentNoticeLogs(List<AppointmentNoticeLog> appointmentNoticeLogs) { |
| | | this.appointmentNoticeLogs = appointmentNoticeLogs; |
| | | } |
| | | public AppointmentClosedInfo getAppointmentClosedInfo() { |
| | | return appointmentClosedInfo; |
| | | } |
| | | public void setAppointmentClosedInfo(AppointmentClosedInfo appointmentClosedInfo) { |
| | | this.appointmentClosedInfo = appointmentClosedInfo; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | import static java.util.stream.Collectors.toList; |
| | | |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import com.pollex.pam.domain.AppointmentClosedInfo; |
| | | import com.pollex.pam.domain.AppointmentCustomerView; |
| | | import com.pollex.pam.domain.AppointmentNoticeLog; |
| | | import com.pollex.pam.repository.AppointmentClosedInfoRepository; |
| | | import com.pollex.pam.service.AppointmentClosedInfoService; |
| | | import com.pollex.pam.service.AppointmentNoticeLogService; |
| | | import com.pollex.pam.service.AppointmentService; |
| | | import com.pollex.pam.service.dto.AppointmentCustomerViewDTO; |
| | |
| | | @Autowired |
| | | AppointmentNoticeLogService appointmentNoticeLogService; |
| | | |
| | | @Autowired |
| | | AppointmentClosedInfoRepository appointmentClosedInfoRepository; |
| | | |
| | | @Transactional |
| | | public AppointmentCustomerViewDTO toAppointmentCustomerViewDTO(AppointmentCustomerView source) { |
| | | AppointmentCustomerViewDTO target = new AppointmentCustomerViewDTO(); |
| | |
| | | appointmentService.setInterviewRecordDTO(target); |
| | | List<AppointmentNoticeLog> noticeLogs = appointmentNoticeLogService.findByAppointmentId(source.getId()); |
| | | target.setAppointmentNoticeLogs(noticeLogs); |
| | | Optional<AppointmentClosedInfo> appointmentClosedInfoOP = appointmentClosedInfoRepository |
| | | .findByAppointmentId(source.getId()); |
| | | if(appointmentClosedInfoOP.isPresent()) { |
| | | target.setAppointmentClosedInfo(appointmentClosedInfoOP.get()); |
| | | } |
| | | |
| | | return target; |
| | | } |
| | | |
| | |
| | | package com.pollex.pam.service.mapper; |
| | | |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import com.pollex.pam.domain.AppointmentNoticeLog; |
| | |
| | | |
| | | public AppointmentNoticeLog toAppointmentNoticeLog(AppointmentNoticeSendDTO source) { |
| | | AppointmentNoticeLog target = new AppointmentNoticeLog(); |
| | | target.setAppointmentId(source.getAppointmentId()); |
| | | BeanUtils.copyProperties(source, target); |
| | | // target.setAppointmentId(source.getAppointmentId()); |
| | | target.setContent(source.getMessage()); |
| | | target.setEmail(source.getEmail()); |
| | | target.setPhone(source.getPhone()); |
| | | // target.setEmail(source.getEmail()); |
| | | // target.setPhone(source.getPhone()); |
| | | return target; |
| | | } |
| | | } |