保誠-保戶業務員媒合平台
Mila
2022-01-19 e471f81737e1e113f913ac615a0a368ab3ca2cd1
update TODO#134465 約訪紀錄(查看更多)
修改6個檔案
新增2個檔案
438 ■■■■ 已變更過的檔案
PAMapp/components/Appointment/AppointmentInterviewList.vue 141 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/Appointment/AppointmentRecordList.vue 2 ●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/BackActionBar.vue 12 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/Interview/InterviewAdd.vue 66 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/Interview/InterviewCard.vue 145 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/appointment/_appointmentId/index.vue 3 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/appointment/_appointmentId/interviewList/index.vue 38 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/store/index.ts 31 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/Appointment/AppointmentInterviewList.vue
@@ -1,82 +1,20 @@
<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
@@ -84,13 +22,8 @@
  @Prop()
  interviewList!: InterviewRecord[];
  @Mutation
  updateInterviewRecord!: (data: InterviewRecord) => void;
  appointmentId!: string;
  futureList: InterviewRecord[] = [];
  pastList: InterviewRecord[] = [];
  displayList: InterviewRecord[] = [];
  //////////////////////////////////////////////////////////////////////
@@ -103,10 +36,9 @@
  @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);
      }
  }
@@ -116,9 +48,8 @@
    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`);
  }
}
@@ -129,49 +60,5 @@
  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>
PAMapp/components/Appointment/AppointmentRecordList.vue
@@ -4,7 +4,7 @@
            <InterviewRecordCard :noticeLogsList="displayLogs.slice(0, 3)"></InterviewRecordCard>
            <section class="text--right mt-30">
            <section class="text--right mt-30" v-if="displayLogs.length > 3">
                <div class="pam-link-button--lg"
                @click="readMoreBtn"
                >展開看更多</div>
PAMapp/components/BackActionBar.vue
@@ -89,8 +89,16 @@
                                                            : 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;
          }
PAMapp/components/Interview/InterviewAdd.vue
@@ -1,6 +1,6 @@
<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>
@@ -85,25 +85,26 @@
      <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 = '';
@@ -121,38 +122,29 @@
    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;
                }
        }
    }
@@ -173,6 +165,7 @@
            }
            this.updateRecord(updateInterviewRecord);
        }
        this.updateAppointmentDetail(+this.appointmentId);
    }
    private createdRecord(interviewRecordInfo) {
@@ -197,14 +190,11 @@
        }
    }
    closePopup() {
        this.$router.push(`/appointment/${this.appointmentId}`);
    }
    deleteInterviewRecord() {
        appointmentService.deleteInterviewRecord(this.interviewId).then(res => {
            this.confirmTxt = '刪除成功';
            this.showConfirmPopup = true;
            this.updateAppointmentDetail(+this.appointmentId);
        });
    }
@@ -214,10 +204,14 @@
           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() {
PAMapp/components/Interview/InterviewCard.vue
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,145 @@
<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>
PAMapp/pages/appointment/_appointmentId/index.vue
@@ -91,12 +91,9 @@
</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';
PAMapp/pages/appointment/_appointmentId/interviewList/index.vue
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,38 @@
<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>
PAMapp/store/index.ts
@@ -5,7 +5,7 @@
import reviewsService from '~/shared/services/reviews.service';
import { Consultant } from '~/shared/models/consultant.model';
import { getFavoriteFromStorage, setFavoriteToStorage } from '~/shared/storageConsultant';
import { AppointmentLog, InterviewRecord } from '~/shared/models/appointment.model';
import { AppointmentLog } from '~/shared/models/appointment.model';
import { AgentOfStrictQuery, StrictQueryParams } from '~/shared/models/strict-query.model';
@Module
@@ -15,16 +15,6 @@
    myConsultantList: Consultant[] = [];
    myAppointmentReviewLogList: AppointmentLog[] = [];
    interviewRecord: InterviewRecord = {
        appointmentId   : 0,
        content         : '',
        createdBy       : '',
        createdDate     : '',
        id              : 0,
        interviewDate   : '',
        lastModifiedBy  : '',
        lastModifiedDate: ''
    }
    get isUserLogin() {
        return this.context.getters['localStorage/isUserLogin'];
@@ -48,25 +38,6 @@
    @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