From 6fa4bba623713c396432ba8b863846883d6a1906 Mon Sep 17 00:00:00 2001
From: wayne <wayne8692wayne8692@gmail.com>
Date: 星期三, 26 一月 2022 10:52:23 +0800
Subject: [PATCH] Merge branch 'pollex-dev' into sit

---
 PAMapp/pages/index.vue |  316 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 307 insertions(+), 9 deletions(-)

diff --git a/PAMapp/pages/index.vue b/PAMapp/pages/index.vue
index b267189..e424a82 100644
--- a/PAMapp/pages/index.vue
+++ b/PAMapp/pages/index.vue
@@ -39,14 +39,117 @@
         <ConsultantSwiper :agents="recommendList"></ConsultantSwiper>
       </div>
     </div>
+
+    <Ui-Dialog
+        :isVisible.sync="isShowAppointmentDialog"
+        :width="appointmentDialogWidth"
+        class="pam-myDemand-dialog pam-dialog-reserved"
+      >
+        <div v-if="appointmentDetail">
+            <h5 class="subTitle text--center mb-30">������</h5>
+            <p class="smTxt">{{appointmentDetail.appointmentDate | formatDate}}</p>
+            <div class="reserved-info">
+                <p>憪��{appointmentDetail.name}}</p>
+                <p>�閰梧�{appointmentDetail.phone}}</p>
+                <p>Email嚗{appointmentDetail.email}}</p>
+                <p>�批嚗{gender}}</p>
+                <p>撟湧翩嚗{appointmentDetail.age | toAgeLabel }}</p>
+                <p>�璆哨�{appointmentDetail.job}}</p>
+                <p>��瘙�{appointmentDetail.requirement.split(',').join('��')}}</p>
+                <p
+                    v-for="(item, index) in hopeContactTime"
+                    :key="index"
+                >��蝯⊥�挾{{index + 1 | formatNumber}}嚗{ item | formatHopeContactTime }}</p>
+                <div v-if="appointmentDetail.satisfactionScore">
+                    <div class="mdTxt mt-10 mb-10">皛踵�漲</div>
+                    <el-rate
+                    :value="appointmentDetail.satisfactionScore"
+                    class="pam-myDemand-dialog__rate"
+                    disabled>
+                    </el-rate>
+                </div>
+            </div>
+
+            <div v-if="notScoreAppointmentYet" class="reserved-btn">
+                <el-button type="primary"
+                    @click.native="isShowReviewDialog = true">蝯虫�遛��漲閰��</el-button>
+            </div>
+        </div>
+      </Ui-Dialog>
+
+      <PopUpFrame
+        :isOpen.sync="isShowReAppointmentDialog"
+        @closePopUp="removeUrlQueryParameter('notContactAppointmentIdFromMsg')"
+      >
+          <div class="pam-dialog-review">
+              <div class="mt-30 text--middle" v-if="agentInfo">
+                敺甇������<span class="text--bold">{{ consultantName }}</span>憿批�迤敹�葉嚗������蒂���隞“���
+              </div>
+
+                <el-row
+                  type="flex"
+                  class="mt-50"
+                  justify="center">
+                  <el-button
+                      type="primary"
+                      @click="reAppointment">��������隞“���</el-button>
+                </el-row>
+                <el-row
+                  type="flex"
+                  class="mt-20"
+                  justify="center">
+                  <el-button
+                      class="outline_btn"
+                      @click="cancelAppointment">������</el-button>
+                </el-row>
+          </div>
+      </PopUpFrame>
+
+      <PopUpFrame
+        :isOpen.sync="isShowReviewDialog"
+        @closePopUp="removeUrlQueryParameter('appointmentId')"
+      >
+          <div class="mdTxt pam-dialog-review">
+              靽憿批�遛��漲
+              <span class="hint">������</span>
+              <div class="mt-30 review-content" v-if="agentInfo">
+                  <UiAvatar :size="80" :agentNo="agentInfo.agentNo"></UiAvatar>
+                  <div class="review-text">撠憿批��
+                      <span class="text--primary">{{agentInfo.name}}</span>
+                      ��擃���蝯虫�嗾憿��嚗�
+                  </div>
+              </div>
+
+              <div class="review-score">
+                  <el-rate v-model="inputScore" class="pam-rate mt-30"></el-rate>
+              </div>
+
+              <div class="review-btn">
+                  <el-button
+                      type="primary"
+                      :disabled="!inputScore"
+                      @click="userReviewsConsultants">�</el-button>
+              </div>
+          </div>
+      </PopUpFrame>
   </div>
 </template>
 
 <script lang="ts">
   import { Vue, Component, State, Action, Watch, namespace } from 'nuxt-property-decorator';
+  import { Appointment, AppointmentClosedInfo } from '~/shared/models/appointment.model';
   import { Consultant } from '~/shared/models/consultant.model';
+  import { ContactStatus } from '~/shared/models/enum/contact-status';
+  import { UserReviewsConsultantsParams } from '~/shared/models/reviews.model';
+  import { StrictQueryParams } from '~/shared/models/strict-query.model';
+  import appointmentService from '~/shared/services/appointment.service';
+  import reviewsService from '~/shared/services/reviews.service';
+  import UtilsService from '~/shared/services/utils.service';
+  import myConsultantService from '~/shared/services/my-consultant.service';
+import { AgentInfo } from '~/shared/models/agent-info.model';
 
   const localStorage = namespace('localStorage');
+  const roleStorage = namespace('localStorage');
 
   @Component({
     layout: 'home'
@@ -59,10 +162,14 @@
     @State('myConsultantList')
     myConsultantList!: Consultant[];
 
+    @roleStorage.Getter
+    isAdminLogin!: boolean;
+
     @Action
     storeRecommendList!: any;
 
-    @Action storeConsultantList!: any;
+    @Action
+    storeConsultantList!: any;
 
     @localStorage.Mutation
     storageClearQuickFilter!: () => void;
@@ -70,18 +177,92 @@
     @localStorage.Mutation
     storageClearRecommendConsultant!: () => void;
 
+    @localStorage.Getter
+    currentSatisfactionIdFromMsg!: string;
+
+    @localStorage.Getter
+    currentNotContactAppointmentIdFromMsg!: string;
+
+    @localStorage.Mutation
+    storageClearSatisfactionIdFromMsg!: () => void;
+
+    @localStorage.Mutation
+    storageClearNotContactAppointmentIdFromMsg!: () => void;
+
+    @localStorage.Mutation
+    storageStrickQueryItem!: (strictQueryDto: StrictQueryParams) => void;
+
     consultantList: Consultant[] = [];
+
+    appointmentDialogWidth    = '';
+    inputScore                = 0;
+    isShowAppointmentDialog   = false;
+    isShowReAppointmentDialog = false;
+    isShowReviewDialog        = false;
+    consultantName = '';
+    contactStatus = ContactStatus;
+
+    appointmentDetail: Appointment = {
+      age               : '',
+      agentNo           : '',
+      appointmentClosedInfo: {} as AppointmentClosedInfo,
+      appointmentDate   : '',
+      appointmentMemoList: [],
+      appointmentNoticeLogs: [],
+      communicateStatus : this.contactStatus.PICKED,
+      consultantReadTime: '',
+      consultantViewTime: '',
+      contactTime       : '',
+      contactType       : '',
+      customerId        : 0,
+      email             : '',
+      gender            : '',
+      hopeContactTime   : '',
+      interviewRecordDTOs: [],
+      id                : 0,
+      job               : '',
+      lastModifiedDate  : '',
+      name              : '',
+      otherRequirement  : '',
+      phone             : '',
+      requirement       : '',
+      satisfactionScore : 0,
+    };
+
+    agentInfo: Consultant = {
+      agentNo            : '',
+      name               : '',
+      img                : '',
+      expertise          : [],
+      avgScore           : 0,
+      contactStatus      : '',
+      createTime         : '',
+      updateTime         : '',
+      customerViewTime   : '',
+      role               : '',
+      seniority          : '',
+      appointments       : []
+    };
 
     //////////////////////////////////////////////////////////////////////
 
     mounted() {
-      if (!this.recommendList?.length) {
-        this.storeRecommendList();
+      if (this.isAdminLogin) {
+        this.$router.push('/myAppointmentList/appointmentList');
+      } else {
+        if (!this.recommendList?.length) {
+          this.storeRecommendList();
+        }
+
+        this.storeConsultantList();
+        this.storageClearQuickFilter();
+        this.storageClearRecommendConsultant();
       }
 
-      this.storeConsultantList();
-      this.storageClearQuickFilter();
-      this.storageClearRecommendConsultant();
+    }
+
+    destroyed() {
+      this.removeUrlQueryParameter();
     }
 
     //////////////////////////////////////////////////////////////////////
@@ -89,15 +270,133 @@
     @Watch('myConsultantList')
     onMyConsultantListChange() {
       this.consultantList = (this.myConsultantList || [])
-        .filter(item => item.contactStatus !== 'contacted')
         .map((item) => ({ ...item, formatDate: new Date(item.updateTime || item.createTime)}))
-        .sort((preItem, nextItem) => +nextItem.formatDate - +preItem.formatDate)
+        .sort((preItem, nextItem) => +nextItem.formatDate - +preItem.formatDate);
+
+      if (this.currentNotContactAppointmentIdFromMsg) {
+        this.autoOpenAppointmentBy('askReAppointment', +this.currentNotContactAppointmentIdFromMsg);
+        return;
+      }
+
+      if (this.currentSatisfactionIdFromMsg) {
+        this.autoOpenAppointmentBy('inviteReviewConsultant',+this.currentSatisfactionIdFromMsg);
+        this.storageClearSatisfactionIdFromMsg();
+        return;
+      }
+    }
+
+    private autoOpenAppointmentBy(reason: string, targetAppointmentId: number): void {
+        const setAgentInfo = new Promise((resolve, reject) => {
+          this.agentInfo = this.myConsultantList.filter(item => {
+            const appointmentIndex = item.appointments?.findIndex(i => i.id === targetAppointmentId);
+            return appointmentIndex !== undefined && appointmentIndex > -1;
+          })[0];
+          if (this.agentInfo) {
+            myConsultantService.getConsultantDetail(this.agentInfo.agentNo).then((res) => resolve(res));
+          }
+        });
+
+        const setAppointment = new Promise((resolve, reject) => {
+           appointmentService.getAppointmentDetail(targetAppointmentId).then((res) => resolve(res));
+        });
+
+        Promise.all([setAgentInfo, setAppointment]).then((values) => {
+          const agentInfo = values[0] as AgentInfo;
+          const appointmentInfo = values[1] as Appointment;
+          this.consultantName = agentInfo.name;
+          this.appointmentDetail = appointmentInfo;
+          this.appointmentDialogWidth = UtilsService.isMobileDevice() ? '80%' : '';
+          this.isShowAppointmentDialog = true;
+          switch (reason) {
+            case 'inviteReviewConsultant':
+              if (this.notScoreAppointmentYet) {
+                setTimeout(() => {
+                  this.isShowReviewDialog = true;
+                }, 500);
+              }
+              break;
+            case 'askReAppointment':
+              setTimeout(() => {
+                this.isShowReAppointmentDialog = true;
+              }, 500);
+              break;
+          }
+        });
+
     }
 
     //////////////////////////////////////////////////////////////////////
 
     navigateToRoute(path: string): void {
       this.$router.push(path);
+    }
+
+    reAppointment(): void {
+      appointmentService.cancelAppointment(this.appointmentDetail.id).then(() => {
+        const requirements = this.appointmentDetail.requirement.split(',');
+        this.storeConsultantList();
+        this.storageStrickQueryItem({ requirements: requirements });
+        this.storageClearNotContactAppointmentIdFromMsg();
+        this.removeUrlQueryParameter('notContactAppointmentIdFromMsg');
+        this.$router.push('/recommendConsultant');
+      });
+    }
+
+    cancelAppointment(): void {
+      appointmentService.cancelAppointment(this.appointmentDetail.id).then(() => {
+        this.storeConsultantList();
+        this.storageClearNotContactAppointmentIdFromMsg();
+        this.removeUrlQueryParameter('notContactAppointmentIdFromMsg');
+        this.$router.push('');
+      });
+    }
+
+    userReviewsConsultants() {
+      const reviewParams: UserReviewsConsultantsParams = {
+            appointmentId: this.appointmentDetail.id,
+            score: this.inputScore,
+        }
+        this.appointmentDetail.satisfactionScore = this.inputScore;
+
+        reviewsService.userReviewsConsultants(reviewParams).then((res) => {
+            this.isShowReviewDialog = false;
+        });
+    }
+
+    removeUrlQueryParameter(targetKey?: string): void {
+        // NOTE: ���摰�� query parameter [Tomas, 2022/1/24 11:36]
+        // [REF] How to remove a parameter from this.$router.query Nuxt.js? https://reurl.cc/X45aMD
+        let newRouteQuery = {};
+        if (targetKey) {
+          Object.keys(this.$route.query).forEach((key) => {
+            if (key !== targetKey) {
+              newRouteQuery[key] = this.$route.query[key]
+            }
+          })
+        }
+        this.$router.push(newRouteQuery);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////
+
+    get gender() {
+        if (this.appointmentDetail.gender) {
+            return this.appointmentDetail.gender === 'male' ? '���' : '憟單��';
+        }
+        return ''
+    }
+
+    get hopeContactTime() {
+        const contactList = this.appointmentDetail.hopeContactTime
+            .split("'").map((item: any) => item.slice(0, item.length));
+        return contactList.filter((item: any) => !!item && item !== ",")
+    }
+
+    get notScoreAppointmentYet(): boolean {
+      if (this.appointmentDetail.communicateStatus === 'closed' || this.appointmentDetail.communicateStatus === 'done') {
+        return !this.appointmentDetail.satisfactionScore;
+      };
+      return false;
     }
 
   }
@@ -182,5 +481,4 @@
       max-width: 335px;
     }
   }
-
 </style>

--
Gitblit v1.8.0