保誠-保戶業務員媒合平台
Mila
2021-12-29 cc663139f6abd63f7deac4739b63db754baf595c
update: TODO#132858 顧問經由簡訊或mail 點擊 url 查看客戶預約清單
刪除1個檔案
修改7個檔案
新增1個檔案
212 ■■■■ 已變更過的檔案
PAMapp/components/Client/ClientCard.vue 45 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/Ui/UiPagination.vue 10 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/middleware/myAppointment.ts 19 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/middleware/myAppointmentMiddleware.ts 14 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/myAppointmentList.vue 49 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/myAppointmentList/appointmentList.vue 20 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/myAppointmentList/contactedList.vue 38 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/shared/models/client.model.ts 2 ●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/store/localStorage.ts 15 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/Client/ClientCard.vue
@@ -2,6 +2,7 @@
    <div>
        <el-row
            type="flex"
            ref="clientCardRef"
            class="rowStyle cursor--pointer"
            justify="space-between"
            :class="{'new': newAppointment }"
@@ -94,15 +95,16 @@
</template>
<script lang="ts">
import { Vue, Component, Prop, Action } from 'nuxt-property-decorator';
import { Vue, Component, Prop, Action, namespace, Watch } from 'nuxt-property-decorator';
import appointmentService from '~/shared/services/appointment.service';
import UtilsService from '~/shared/services/utils.service';
import { hideReviews } from '~/shared/const/hide-reviews';
import { ClientInfo } from '~/shared/models/client.model';
import myConsultantService from '~/shared/services/my-consultant.service';
import { ElRow } from 'element-ui/types/row';
const localStorage = namespace('localStorage');
@Component({
    filters: {
        formatNumber(index: number) {
@@ -124,17 +126,27 @@
})
export default class ClientList extends Vue {
    @Action
    updateMyAppointment!: (data: ClientInfo) => void
    @Action
    storeConsultantList!: () => void;
    updateMyAppointment!: (data: ClientInfo) => void;
    @Prop()
    client!: ClientInfo;
    @localStorage.Mutation
    storageClearAppointmentIdFromMsg!: () => void;
    isVisibleDialog = false;
    dialogWidth = '';
    hideReviews = hideReviews;
    //////////////////////////////////////////////////////////////////////
    @Watch('$route', {immediate: true})
    onRouteChange() {
        const appointmentIdFromMsg = this.$route.query.appointmentId;
        if (appointmentIdFromMsg && +appointmentIdFromMsg === this.client.id) {
            this.openDetail();
        }
    }
    //////////////////////////////////////////////////////////////////////
@@ -194,6 +206,10 @@
    }
    openDetail() {
        setTimeout(() => {
            (this.$refs.clientCardRef as any).$el.classList.add('currentShowStyle');
        }, 0)
        this.dialogWidth = UtilsService.isMobileDevice() ? '80%' : '';
        this.isVisibleDialog = true;
    }
@@ -218,7 +234,16 @@
                updatedClient.consultantReadTime = new Date().toString();
                this.updateMyAppointment(updatedClient);
            });
        }
        };
        this.clearAppointmentIdFromMsg();
    }
    private clearAppointmentIdFromMsg() {
        this.storageClearAppointmentIdFromMsg();
        this.$router.push({query: {}});
        setTimeout(() => {
            (this.$refs.clientCardRef as ElRow).$el.classList.remove('currentShowStyle')
        },1000)
    }
}
@@ -231,11 +256,17 @@
        margin-bottom: 10px;
        display: flex;
        justify-content: space-between;
        transition: background-color 0.5s;
        &.new {
            border-left: solid 4px $YELLOW;
        }
        &.currentShowStyle {
            background-color: rgba(236, 195, 178, 0.5);
            transition: background-color 0.5s;
        }
        .unread {
            align-self: center;
PAMapp/components/Ui/UiPagination.vue
@@ -1,6 +1,6 @@
<template>
    <el-pagination
        :current-page.sync="currentPage"
        :current-page.sync="syncCurrentPage"
        layout="prev, pager, next"
        :total="totalList.length"
        :page-size="pageSize"
@@ -11,7 +11,7 @@
</template>
<script lang="ts">
import { Vue, Component, Prop, Emit, Watch } from 'nuxt-property-decorator';
import { Vue, Component, Prop, Emit, Watch, PropSync } from 'nuxt-property-decorator';
import { Consultant } from '~/shared/models/consultant.model';
@Component
@@ -20,7 +20,7 @@
    totalList!: Consultant[];
    @Prop({default: 5}) pageSize!: number;
    currentPage = 1;
    @PropSync('currentPage', {default: 1}) syncCurrentPage!: number;
    pageList: Consultant[] = [];
@@ -34,14 +34,14 @@
    @Watch('totalList')
    watchTotalList(newValue: Consultant[]) {
        if (newValue) {
            this.handleCurrentChange(this.currentPage);
            this.handleCurrentChange(this.syncCurrentPage);
        }
    }
    //////////////////////////////////////////////////////////////////
    mounted() {
        this.handleCurrentChange(this.currentPage);
        this.handleCurrentChange(this.syncCurrentPage);
    }
    //////////////////////////////////////////////////////////////////
PAMapp/middleware/myAppointment.ts
比對新檔案
@@ -0,0 +1,19 @@
import { Middleware } from '@nuxt/types';
const myAppointment: Middleware = (context) => {
  const appointmentIdFromMsg = context.route.query.appointmentId;
  if (appointmentIdFromMsg) {
    context.store.commit('localStorage/storageAppointmentIdFromMsg', appointmentIdFromMsg);
  };
  const isAdminLogin = context.store.getters['localStorage/isAdminLogin'];
  if (isAdminLogin) {
    if (context.route.name === 'myAppointmentList') {
      context.redirect('/myAppointmentList/appointmentList')
    }
  } else {
    context.redirect('/consultantLogin');
  }
}
export default myAppointment
PAMapp/middleware/myAppointmentMiddleware.ts
檔案已刪除
PAMapp/pages/myAppointmentList.vue
@@ -19,7 +19,7 @@
                </div>
            </div>
            <NuxtChild></NuxtChild>
            <NuxtChild keep-alive></NuxtChild>
        </div>
@@ -41,15 +41,17 @@
</template>
<script lang="ts">
import { Vue, Component, State, Action, Watch } from 'nuxt-property-decorator';
import { Vue, Component, State, Action, Watch, namespace } from 'nuxt-property-decorator';
import * as _ from 'lodash';
import { ClientInfo } from '~/shared/models/client.model';
const localStorage = namespace('localStorage');
@Component({
    layout: 'home',
    middleware: 'myAppointmentMiddleware'
    middleware: 'myAppointment'
})
export default class ClientReservedList extends Vue {
@@ -62,6 +64,12 @@
    @Action
    storeMyAppointmentList!: () => Promise<number>;
    @localStorage.Mutation
    storageClearAppointmentIdFromMsg!: () => void;
    @localStorage.Getter
    currentAppointmentIdFromMsg!: string;
    activeTabName         : string       = 'appointmentList';
    appointmentList       : ClientInfo[] = [];
    clients               : ClientInfo[] = [];
@@ -71,15 +79,11 @@
    //////////////////////////////////////////////////////////////////////
    mounted() {
      this.setActivatedTab();
      this.storeMyAppointmentList();
    }
    private setActivatedTab(): void {
      const routeFullName = this.$route.name;
      if (routeFullName) {
        this.activeTabName = routeFullName.split('-')[1];
      }
    destroyed() {
        this.storageClearAppointmentIdFromMsg();
    }
    //////////////////////////////////////////////////////////////////////
@@ -91,13 +95,40 @@
        this.appointmentList = this.myAppointmentList
            .filter(item => item.communicateStatus !== 'contacted');
        if (this.currentAppointmentIdFromMsg) {
            this.redirectAppointmentStatus();
        }
    }
    private redirectAppointmentStatus() {
        const currentAppointmentIndex = this.myAppointmentList
            .findIndex(item => item.id === +this.currentAppointmentIdFromMsg);
        if (currentAppointmentIndex > -1) {
            const communicateStatus = this.myAppointmentList[currentAppointmentIndex].communicateStatus;
            const pathName = communicateStatus === 'reserved' ? 'appointmentList' : 'contactedList';
            this.$router.push(
                {
                    path: '/myAppointmentList/' + pathName,
                    query: {appointmentId: this.currentAppointmentIdFromMsg}
                }
            );
        }
    };
    @Watch('newAppointmentSum')
    newAppointmentSumChange(): void {
      this.showNewAppointmentHint = this.newAppointmentSum > 0;
    }
    @Watch('$route')
    onRouteChange() {
        const routeFullName = this.$route.name;
        if (routeFullName) {
            this.activeTabName = routeFullName.split('-')[1];
        }
    }
    //////////////////////////////////////////////////////////////////////
    clickTab(path: string): void {
PAMapp/pages/myAppointmentList/appointmentList.vue
@@ -17,26 +17,32 @@
        <UiPagination
            :totalList="filterList"
            :currentPage="currentPage"
            @changePage="changePage"
        ></UiPagination>
    </div>
</template>
<script lang="ts">
import { Vue, Component, State, Watch } from 'nuxt-property-decorator';
import { Vue, Component, State, Watch, namespace } from 'nuxt-property-decorator';
import { ClientInfo } from '~/shared/models/client.model';
const localStorage = namespace('localStorage');
@Component
export default class ClientReservedList extends Vue {
    @State('myAppointmentList')
    myAppointmentList!: ClientInfo[];
    @localStorage.Getter
    currentAppointmentIdFromMsg!: string;
    appointmentList: ClientInfo[] = [];
    filterList     : ClientInfo[] = [];
    keyWord        : string       = '';
    pageList       : ClientInfo[] = [];
    currentPage    : number = 1;
    //////////////////////////////////////////////////////////////////////
@@ -66,8 +72,20 @@
      this.appointmentList = [...unViewList, ...unreadList, ...readList];
      this.filterList = this.appointmentList;
      this.getCurrentPage();
    }
    private getCurrentPage() {
        const currentIndex = this.filterList
            .findIndex(item => item.id === +this.currentAppointmentIdFromMsg);
        const pageSize = 5;
        if (currentIndex > -1) {
            this.currentPage = Math.ceil((currentIndex + 1) / pageSize);
        }
    }
    //////////////////////////////////////////////////////////////////////
    search(): void {
        this.filterList = this.appointmentList.filter(item => {
            return item.name.match(this.keyWord) || item.requirement.match(this.keyWord)
PAMapp/pages/myAppointmentList/contactedList.vue
@@ -21,21 +21,40 @@
        <UiPagination
            :totalList="filterList"
            :currentPage="currentPage"
            @changePage="changePage"
        ></UiPagination>
    </div>
</template>
<script lang="ts">
import { Vue, Component, Watch, State } from 'nuxt-property-decorator';
import { Vue, Component, Watch, State, namespace } from 'nuxt-property-decorator';
import { ClientInfo } from '~/shared/models/client.model';
const localStorage = namespace('localStorage');
@Component
export default class ClientContactedList extends Vue {
    @State('myAppointmentList')
    myAppointmentList!: ClientInfo[];
    @localStorage.Getter
    currentAppointmentIdFromMsg!: string;
    contactedList: ClientInfo[] = [];
    filterList   : ClientInfo[] = [];
    keyWord      : string       = '';
    pageList     : ClientInfo[] = [];
    currentPage  : number = 1;
    //////////////////////////////////////////////////////////////////////
    mounted() {
        this.onMyAppointmentListChange();
    }
    //////////////////////////////////////////////////////////////////////
    @Watch('myAppointmentList')
    onMyAppointmentListChange() {
@@ -44,17 +63,16 @@
            .map((item) => ({...item, sortTime: new Date(item.contactTime)}))
            .sort((prevItem, nextItem) => +nextItem.sortTime - +prevItem.sortTime);
        this.filterList = this.contactedList;
        this.getCurrentPage();
    }
    contactedList: ClientInfo[] = [];
    filterList   : ClientInfo[] = [];
    keyWord      : string       = '';
    pageList     : ClientInfo[] = [];
    //////////////////////////////////////////////////////////////////////
    mounted() {
        this.onMyAppointmentListChange();
    private getCurrentPage() {
        const currentIndex = this.filterList.findIndex(item => item.id === +this.currentAppointmentIdFromMsg);
        const pageSize = 5;
        if (currentIndex > -1) {
            this.currentPage = Math.ceil((currentIndex + 1) / pageSize);
        }
    }
    //////////////////////////////////////////////////////////////////////
PAMapp/shared/models/client.model.ts
@@ -18,5 +18,5 @@
  otherRequirement  : string,
  phone             : string,
  requirement       : string,
  satisfactionScore : number,
  satisfactionScore : number
}
PAMapp/store/localStorage.ts
@@ -8,6 +8,7 @@
  consultant_id = localStorage.getItem('consultant_id');
  quickFilterSelectedItem = localStorage.getItem('quickFilter');
  recommendConsultantItem = localStorage.getItem('recommendConsultantItem');
  appointmentIdFromMsg = localStorage.getItem('appointmentIdFromMsg');
  get idToken(): string|null {
    return this.id_token;
@@ -33,7 +34,9 @@
    return this.currentRole === Role.USER;
  }
  get currentAppointmentIdFromMsg(): string|null {
    return this.appointmentIdFromMsg;
  }
  @Mutation storageIdToken(token: string): void {
    localStorage.setItem('id_token', token);
@@ -60,6 +63,11 @@
    this.recommendConsultantItem = localStorage.getItem('recommendConsultantItem');
  }
  @Mutation storageAppointmentIdFromMsg(id: string) {
    localStorage.setItem('appointmentIdFromMsg', id);
    this.appointmentIdFromMsg = localStorage.getItem('appointmentIdFromMsg');
  }
  @Mutation storageClear(): void {
    localStorage.removeItem('myRequests');
    localStorage.removeItem('userInfo');
@@ -82,6 +90,11 @@
    this.recommendConsultantItem = localStorage.getItem('recommendConsultantItem');
  }
  @Mutation storageClearAppointmentIdFromMsg() {
    localStorage.removeItem('appointmentIdFromMsg');
    this.appointmentIdFromMsg = localStorage.getItem('appointmentIdFromMsg');
  }
  @Action actionStorageClear(): void {
    this.context.commit("storageClear");
  }