From bdae23a40c461c2c6b6ee614f661eac731c949c8 Mon Sep 17 00:00:00 2001
From: Mila <Mila@pollex.com.tw>
Date: 星期三, 22 十二月 2021 14:12:05 +0800
Subject: [PATCH] Merge branch 'master' of https://192.168.0.10:8443/r/pcalife/PAM

---
 PAMapp/components/QuickFilter/QuickFilterSelector.vue                         |    6 
 PAMapp/components/Ui/UiField.vue                                              |    2 
 PAMapp/pages/consultantLogin/index.vue                                        |    6 
 PAMapp/shared/models/otpInfo.model.ts                                         |    0 
 pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java         |   10 
 PAMapp/pages/accountSetting/index.vue                                         |    9 
 PAMapp/shared/models/loginSuccessToken.model.ts                               |    0 
 PAMapp/shared/models/ConsultantLoginInfo.ts                                   |    0 
 PAMapp/shared/models/loginRequest.model.ts                                    |    0 
 PAMapp/pages/userReviewsRecord/index.vue                                      |   16 
 pamapi/src/doc/sql/20211222_w.sql                                             |    1 
 PAMapp/shared/models/registerInfo.ts                                          |    0 
 PAMapp/pages/faq.vue                                                          |    4 
 pamapi/src/main/java/com/pollex/pam/web/rest/errors/SendSMSFailException.java |    2 
 PAMapp/shared/models/quick-filter.model.ts                                    |   14 
 PAMapp/shared/models/appointment.model.ts                                     |   39 ++
 pamapi/src/main/java/com/pollex/pam/config/ApplicationProperties.java         |   27 ++
 pamapi/src/main/java/com/pollex/pam/service/dto/SendMailResponse.java         |    4 
 pamapi/src/main/resources/templates/mail/appointmentNotifyEmail.html          |   15 +
 PAMapp/shared/models/reviews.model.ts                                         |    4 
 PAMapp/shared/services/my-consultant.service.ts                               |   42 +++
 pamapi/src/main/resources/config/application-dev.yml                          |    3 
 PAMapp/pages/questionnaire/_agentNo.vue                                       |   21 
 PAMapp/shared/storageConsultant.ts                                            |    0 
 pamapi/src/main/java/com/pollex/pam/domain/Consultant.java                    |   16 +
 PAMapp/shared/models/editAppointmentParams.model.ts                           |    0 
 PAMapp/components/AddAndReservedBtns.vue                                      |    4 
 pamapi/src/main/resources/config/application-pollex.yml                       |   11 
 PAMapp/components/NavBar.vue                                                  |    2 
 PAMapp/pages/agentInfo/_agentNo.vue                                           |    8 
 PAMapp/pages/myAppointmentList/appointmentList.vue                            |    2 
 PAMapp/shared/const/faqList.ts                                                |    0 
 PAMapp/components/Client/ClientCard.vue                                       |   11 
 PAMapp/pages/myConsultantList/consultantList.vue                              |    4 
 PAMapp/shared/models/enum/seniority.ts                                        |    0 
 PAMapp/shared/services/query-consultant.service.ts                            |   37 ++
 PAMapp/store/localStorage.ts                                                  |    4 
 pamapi/src/main/java/com/pollex/pam/service/SendMsgService.java               |  136 +++++++++-
 PAMapp/shared/models/strict-query.model.ts                                    |   24 +
 PAMapp/components/Ui/UiPagination.vue                                         |    2 
 PAMapp/shared/const/quickFilter-questionList.ts                               |    3 
 PAMapp/shared/models/enum/otpErrorCode.ts                                     |    0 
 PAMapp/components/Consultant/ConsultantList.vue                               |    2 
 PAMapp/shared/models/enum/Gender.ts                                           |    0 
 PAMapp/pages/login/index.vue                                                  |   16 
 PAMapp/store/index.ts                                                         |   36 +-
 PAMapp/pages/recommendConsultant/result.vue                                   |    4 
 PAMapp/pages/record/index.vue                                                 |   18 
 PAMapp/shared/services/httpClient.ts                                          |    0 
 PAMapp/shared/models/enum/ContactType.ts                                      |    0 
 PAMapp/pages/myConsultantList.vue                                             |    2 
 PAMapp/shared/models/loginVerify.model.ts                                     |    0 
 PAMapp/pages/myConsultantList/contactedList.vue                               |    4 
 PAMapp/components/QuickFilter/QuickFilterConsultantList.vue                   |    6 
 pamapi/src/main/resources/config/application-sit.yml                          |    3 
 PAMapp/shared/services/appointment.service.ts                                 |   18 
 PAMapp/shared/services/account-setting.service.ts                             |   17 +
 PAMapp/components/Consultant/ConsultantSwiper.vue                             |    6 
 PAMapp/pages/index.vue                                                        |    2 
 PAMapp/pages/myAppointmentList/contactedList.vue                              |    2 
 PAMapp/pages/userReviews/index.vue                                            |   16 
 PAMapp/shared/models/client.model.ts                                          |    0 
 PAMapp/shared/errorService.ts                                                 |    0 
 PAMapp/shared/models/account.model.ts                                         |    0 
 PAMapp/shared/const/hide-reviews.ts                                           |    0 
 PAMapp/shared/device.ts                                                       |    0 
 PAMapp/pages/quickFilter/index.vue                                            |   12 
 PAMapp/shared/models/enum/Role.ts                                             |    5 
 PAMapp/components/Client/ClientList.vue                                       |    2 
 PAMapp/shared/storageRequests.ts                                              |    2 
 pamapi/src/main/java/com/pollex/pam/web/rest/TestSendMsgResource.java         |   28 +
 PAMapp/shared/services/login.service.ts                                       |    0 
 PAMapp/pages/myAppointmentList.vue                                            |    2 
 /dev/null                                                                     |   14 -
 PAMapp/components/BackActionBar.vue                                           |    3 
 PAMapp/components/Consultant/ConsultantCard.vue                               |   15 
 PAMapp/shared/models/clientInfo.ts                                            |    0 
 PAMapp/components/popUpFrame.vue                                              |    4 
 pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java           |    4 
 PAMapp/pages/recommendConsultant/index.vue                                    |    2 
 PAMapp/shared/models/consultant.model.ts                                      |    0 
 PAMapp/shared/services/reviews.service.ts                                     |   18 +
 PAMapp/shared/models/agent-info.model.ts                                      |    0 
 pamapi/src/main/resources/config/application-uat.yml                          |    3 
 84 files changed, 571 insertions(+), 184 deletions(-)

diff --git a/PAMapp/assets/ts/api/appointment.ts b/PAMapp/assets/ts/api/appointment.ts
deleted file mode 100644
index 81a90ca..0000000
--- a/PAMapp/assets/ts/api/appointment.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { http } from '~/assets/ts/services/httpClient';
-
-import { AppointmentLog } from '../models/appointment.model';
-
-// 璅�撌脰蝯�
-export function markAsContact(appointmentId: number) {
-    const headers = {
-        Authorization: 'Bearer ' + localStorage.getItem('id_token')
-    }
-    // TODO: 頝�垢蝣箄���ㄐ��� API 銝�府���� void, ���府���敺���� - Ben 2021/11/16
-    return http.post('/appointment/markAsContacted/'+appointmentId, undefined, {headers})
-            .then(res => res.data)
-}
-
-export function getMyReviewLog(): Promise<AppointmentLog[]> {
-    const headers = {
-        Authorization: 'Bearer ' + localStorage.getItem('id_token')
-    }
-    return http.get('/satisfaction/getMySatisfaction', { headers }).then(res => res.data);
-}
-
-
-// 憿批��憿舐內����蝑敺孛�
-export function allAppointmentsView() {
-    const headers = {
-        Authorization: 'Bearer ' + localStorage.getItem('id_token')
-    }
-    return http.post('/consultant/record/allAppointmentsView', undefined, {headers})
-}
diff --git a/PAMapp/assets/ts/api/consultant.ts b/PAMapp/assets/ts/api/consultant.ts
deleted file mode 100644
index 120188d..0000000
--- a/PAMapp/assets/ts/api/consultant.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-import { AxiosResponse } from 'axios';
-import { ConsultantLoginInfo } from '../models/ConsultantLoginInfo';
-import _ from 'lodash';
-import { UserSetting } from '../models/account.model';
-import { Consultant } from '~/assets/ts/models/consultant.model';
-import { http } from '../services/httpClient';
-import { FastQueryParams } from '../models/quickFilter.model';
-
-
-// ��靽憿批��
-export function recommend() {
-    return http.get<Consultant[]>('/consultant/recommend')
-            .then(res => res.data);
-}
-
-// 敹恍�祟�
-export function fastQuery(data: FastQueryParams) {
-    return http.post<Consultant[]>('/consultant/fastQuery', data).then(res => res.data);
-}
-
-// ������
-export function strictQuery(data:StrictQueryParams):Promise<AxiosResponse<AgentOfStrictQuery[]>>{
-    return http.post('/consultant/strictQuery', data)
-}
-
-// ��憿批��
-export function addFavoriteConsultant(agentNoList: string[]) {
-    const headers = {
-        Authorization: 'Bearer ' + localStorage.getItem('id_token')
-    }
-    return http.post('/consultant/favorite', {agentNoList}, {headers})
-}
-
-// ����岷���
-export function appointmentDemand(data: AppointmentParams) {
-    const headers = {
-        Authorization: 'Bearer ' + localStorage.getItem('id_token')
-    }
-    return http.post('/appointment/customer/create', data, {headers})
-}
-
-//憿批�底蝝啗���
-export function getConsultantDetail(agentNo:string){
-    return http.get('/consultant/detail', {params:{agentNo:agentNo}})
-}
-
-// 蝘駁憿批��
-export function deleteConsultant(agentId: string) {
-    const headers = {
-        Authorization: 'Bearer ' + localStorage.getItem('id_token')
-    }
-    return http.delete('/consultant/favorite/'+agentId, {headers})
-}
-
-//���蝙��董�����
-export function getUserAccountSetting() : Promise<UserSetting> {
-    const headers = {
-        Authorization: 'Bearer ' + localStorage.getItem('id_token')
-    }
-    return http.get<UserSetting>('/customer/info', {headers}).then(res => res.data);
-}
-
-//��雿輻�董�����
-export function updateAccountSetting(params: any) : any {
-    const headers = {
-        Authorization: 'Bearer ' + localStorage.getItem('id_token')
-    }
-    return http.put('/customer/info', params ,{headers}).then(res => res.data);
-}
-
-//摰X�脰�遛��漲閰��
-
-export function userReviewsConsultants(data: UserReviewsConsultantsParams) {
-    const headers = {
-        Authorization: 'Bearer ' + localStorage.getItem('id_token')
-    }
-    return http.post('/satisfaction/create', data ,{headers});
-}
-
-// ������
-// export function cancelAppointment(appointment: number) {
-//     const headers = {
-//         Authorization: 'Bearer ' + localStorage.getItem('id_token')
-//     }
-//     return http.delete('/appointment/'+appointment ,{headers});
-// }
-
-// 蝺刻摩����
-export function editAppointment(editAppointmentParams: editAppointmentParams) {
-    const headers = {
-        Authorization: 'Bearer ' + localStorage.getItem('id_token')
-    }
-    return http.put('/appointment', editAppointmentParams, {headers});
-}
-
-export interface AppointmentRequests {
-    phone          : string,
-    email          : string,
-    contactType    : string,
-    gender         : string,
-    age            : string,
-    job            : string,
-    requirement    : string[],
-    hopeContactTime: ContactTime[],
-    agentNo        : string,
-}
-export interface ContactTime {
-  selectWeekOptions : string[],
-  selectTimesOptions: string[]
-}
-export interface AppointmentParams {
-    phone          : string,
-    email          : string,
-    contactType    : string,
-    gender         : string,
-    age            : string,
-    job            : string,
-    requirement    : string,
-    hopeContactTime: string,
-    agentNo        : string
-}
-export interface StrictQueryParams{
-    gender          : string;
-    avgScore        : number;
-    status          : string;    //phase 1 disable
-    area            : string;
-    requirements    : string[];
-    otherRequirement: string;
-    seniority       : string;
-    popularTags     : string[];
-    otherPopularTags: string;
-}
-export interface AgentOfStrictQuery {
-    agentNo      : string;
-    name         : string;
-    img          : string;
-    expertise    : string[];
-    avgScore     : number;
-    contactStatus: null;
-    updateTime   : null;
-    seniority    : string;
-    new          : boolean;
-}
-export interface RequestOfLoginSuccess{
-  id_token: string;
-}
-
-export interface UserReviewsConsultantsParams{
-    appointmentId: number,
-    score        : number,
-}
-
-export interface editAppointmentParams {
-    id              : number,
-    phone           : string,
-    email           : string,
-    contactType     : string,
-    gender          : string,
-    age             : string,
-    job             : string,
-    requirement     : string,
-    hopeContactTime : string,
-    otherRequirement: null
-}
diff --git a/PAMapp/assets/ts/api/share.ts b/PAMapp/assets/ts/api/share.ts
deleted file mode 100644
index 835376c..0000000
--- a/PAMapp/assets/ts/api/share.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { AxiosRequestConfig, AxiosError, AxiosResponse} from 'axios';
-import ErrorMessageBox from '../errorService';
-import axios from 'axios';
-import _ from 'lodash';
-
-const notRequireInterceptorErrorUrl = [
-  '/otp/verify',
-  '/eService/authenticate',
-  '/login/validate/get_img_code',
-  '/login/validate/verify_img_code',
-];
-
-export const service = axios.create({
-  baseURL: process.env.BASE_URL,
-  withCredentials: true
-});
-
-service.interceptors.request.use(
-  (config: AxiosRequestConfig) => {
-    loadingStart();
-    addHttpHeader(config);
-    return config;
-  }
-);
-
-service.interceptors.response.use(
-  (response: AxiosResponse) => {
-    loadingFinish();
-    return response;
-  },
-  (error: AxiosError) => {
-    loadingFinish();
-    showErrorMessageBox(error)
-    return Promise.reject(error);
-  }
-);
-
-function addHttpHeader(config: AxiosRequestConfig): void {
-  config.headers = {
-    Authorization: 'Bearer ' + localStorage.getItem('id_token')
-  }
-}
-
-function loadingStart(): void {
-  window.$nuxt.$loading.start();
-};
-
-function loadingFinish(): void {
-  window.$nuxt.$loading.finish();
-};
-
-function showErrorMessageBox(error: any): void {
-  // console.log('error', error, error.response);
-  if (!_.includes(notRequireInterceptorErrorUrl, error.config.url)) {
-    switch (error.response.status) {
-      case 401:
-        Promise.all([ErrorMessageBox('���暹��'),window.$nuxt.$store.dispatch('localStorage.service/clearStorage')]).then(()=>{
-          _.isEqual(window.$nuxt.$route.name, 'index') ? location.reload() : window.$nuxt.$router.push('/');
-        });
-        break;
-
-      default:
-        ErrorMessageBox('', error);
-        break;
-    }
-  }
-};
diff --git a/PAMapp/assets/ts/models/UserReviewsConsultantsParams.ts b/PAMapp/assets/ts/models/UserReviewsConsultantsParams.ts
deleted file mode 100644
index 93ece16..0000000
--- a/PAMapp/assets/ts/models/UserReviewsConsultantsParams.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export interface UserReviewsConsultantsParams{
-  appointmentId:number,
-  score:number,
-}
diff --git a/PAMapp/assets/ts/models/agentOfStrictQuery.ts b/PAMapp/assets/ts/models/agentOfStrictQuery.ts
deleted file mode 100644
index 16d6627..0000000
--- a/PAMapp/assets/ts/models/agentOfStrictQuery.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-
-export interface AgentOfStrictQuery {
-  agentNo: string;
-  name: string;
-  img: string;
-  expertise: string[];
-  avgScore: number;
-  contactStatus: null;
-  updateTime: null;
-  seniority: string;
-  new: boolean;
-}
diff --git a/PAMapp/assets/ts/models/appointmentParams.ts b/PAMapp/assets/ts/models/appointmentParams.ts
deleted file mode 100644
index e3eead8..0000000
--- a/PAMapp/assets/ts/models/appointmentParams.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-
-export interface AppointmentParams {
-  phone: string;
-  email: string;
-  contactType: string;
-  gender: string;
-  age: string;
-  job: string;
-  requirement: string;
-  hopeContactTime: string;
-  agentNo: string;
-}
diff --git a/PAMapp/assets/ts/models/enum/Role.ts b/PAMapp/assets/ts/models/enum/Role.ts
deleted file mode 100644
index acae4db..0000000
--- a/PAMapp/assets/ts/models/enum/Role.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export enum Role{
-    ADMIN = 'admin',
-    USER = 'user',
-    NOT_LOGIN = ''
-}
\ No newline at end of file
diff --git a/PAMapp/assets/ts/models/fastQueryParams.model.ts b/PAMapp/assets/ts/models/fastQueryParams.model.ts
deleted file mode 100644
index c24376d..0000000
--- a/PAMapp/assets/ts/models/fastQueryParams.model.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-
-export interface FastQueryParams {
-  gender: string;
-  communicationStyles: string[];
-  avgScore: number;
-  status: string;
-}
diff --git a/PAMapp/assets/ts/models/strictQueryParams.ts b/PAMapp/assets/ts/models/strictQueryParams.ts
deleted file mode 100644
index ba69baf..0000000
--- a/PAMapp/assets/ts/models/strictQueryParams.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-
-export interface StrictQueryParams {
-  gender: string;
-  avgScore: number;
-  status: string; //phase 1 disable
-  area: string;
-  requirements: string[];
-  otherRequirement: string;
-  seniority: string;
-  popularTags: string[];
-  otherPopularTags: string;
-}
diff --git a/PAMapp/assets/ts/services/my-consultant.service.ts b/PAMapp/assets/ts/services/my-consultant.service.ts
deleted file mode 100644
index c27a41d..0000000
--- a/PAMapp/assets/ts/services/my-consultant.service.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { http } from "./httpClient";
-
-import { AgentInfo } from '~/assets/ts/models/agent-info.model';
-import { Consultant } from "../models/consultant.model";
-
-class MyConsultantService {
-
-  async getFavoriteConsultantList(): Promise<Consultant[]> {
-    return http.get<Consultant[]>('/consultant/favorite').then((res) => {
-      const hasNewConsultant = res.data.find((consultant) => !consultant.customerViewTime);
-      if (hasNewConsultant) {
-        this.viewMyConsultantList();
-      };
-      return res.data;
-    });
-  }
-
-  private viewMyConsultantList(): void {
-    http.post('/consultant/favorite/view');
-  }
-
-  //憿批�底蝝啗���
-  async getConsultantDetail(agentNo:string): Promise<AgentInfo> {
-    return http.get('/consultant/detail', {params:{agentNo:agentNo}}).then((res) => res.data);
-  }
-
-}
-
-export default new MyConsultantService();
diff --git a/PAMapp/assets/ts/services/pamService.service.ts b/PAMapp/assets/ts/services/pamService.service.ts
deleted file mode 100644
index e89d07e..0000000
--- a/PAMapp/assets/ts/services/pamService.service.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import { AxiosResponse } from 'axios';
-import { http } from "./httpClient";
-import { editAppointmentParams } from '../models/editAppointmentParams.model';
-import { AppointmentDetail } from '../models/AppointmentDetail';
-import { UserSetting } from '../models/account.model';
-import { FastQueryParams } from '../models/quickFilter.model';
-import { Consultant } from '../models/consultant.model';
-import { StrictQueryParams } from '../models/strictQueryParams';
-import { AppointmentParams } from '../models/appointmentParams';
-import { UserReviewsConsultantsParams } from '../models/UserReviewsConsultantsParams';
-import { AgentOfStrictQuery } from '../models/agentOfStrictQuery';
-import _ from "lodash";
-
-
-
-
-class PamService {
-  constructor() {}
-
-  /** ��靽憿批�� **/
-  recommend():Promise<AxiosResponse<Consultant[]>>{
-    return http.get('/consultant/recommend');
-  }
-
-  /** 敹恍�祟� **/
-  fastQuery(data: FastQueryParams):Promise<AxiosResponse<Consultant[]>>{
-    return http.post('/consultant/fastQuery', data)
-  }
-
-  /** ������ **/
-  strictQuery(data:StrictQueryParams):Promise<AxiosResponse<AgentOfStrictQuery[]>>{
-    return http.post('/consultant/strictQuery', data)
-  }
-
-  /** ��憿批�� **/
-  addFavoriteConsultant(agentNoList: string[]):Promise<AxiosResponse<any>>{
-    return http.post('/consultant/favorite', {agentNoList})
-  }
-
-  /** ����岷��� **/
-  appointmentDemand(data: AppointmentParams):Promise<AxiosResponse<any>> {
-    return http.post('/appointment/customer/create', data)
-  }
-
-  /** 憿批�底蝝啗��� **/
-  getConsultantDetail(agentNo:string):Promise<AxiosResponse<any>>{
-    return http.get('/consultant/detail', {params:{agentNo:agentNo}})
-  }
-
-  /** 蝘駁憿批�� **/
-  deleteConsultant(agentId: string):Promise<AxiosResponse<any>>{
-    return http.delete('/consultant/favorite/'+agentId);
-  }
-
-
-
-  /** �����蝝啁� **/
-  getAppointmentDetail(apointmentId: number):Promise<AxiosResponse<AppointmentDetail>> {
-    return http.get('/appointment/getDetail/'+apointmentId)
-  }
-
-  /** ���蝙��董����� **/
-  getUserAccountSetting():Promise<AxiosResponse<UserSetting>>{
-    return http.get<UserSetting>('/customer/info');
-  }
-
-  /** ��雿輻�董����� **/
-  updateAccountSetting(params: any):Promise<AxiosResponse<any>> {
-    return http.put('/customer/info', params);
-  }
-
-  //摰X�脰�遛��漲閰��
-  userReviewsConsultants(data: UserReviewsConsultantsParams):Promise<AxiosResponse<any>> {
-    return http.post('/satisfaction/create', data);
-  }
-
-  // ������
-  cancelAppointment(appointment: number):Promise<AxiosResponse<any>>{
-    return http.delete('/appointment/'+appointment);
-  }
-
-  // 蝺刻摩����
-  editAppointment(editAppointmentParams:editAppointmentParams):Promise<AxiosResponse<any>>{
-    return http.put('/appointment', editAppointmentParams);
-  }
-}
-
-export default new PamService();
-
-
diff --git a/PAMapp/assets/ts/services/query-consultant.service.ts b/PAMapp/assets/ts/services/query-consultant.service.ts
deleted file mode 100644
index 1236fdc..0000000
--- a/PAMapp/assets/ts/services/query-consultant.service.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { http } from "./httpClient";
-
-import { Consultant } from "../models/consultant.model";
-
-class QueryConsultantService {
-
-    // ��靽憿批��
-    async getRecommendConsultantList(): Promise<Consultant[]> {
-      return http.get<Consultant[]>('/consultant/recommend').then((res) => res.data);
-    }
-
-}
-
-export default new QueryConsultantService();
diff --git a/PAMapp/components/AddAndReservedBtns.vue b/PAMapp/components/AddAndReservedBtns.vue
index d88a444..fa37c72 100644
--- a/PAMapp/components/AddAndReservedBtns.vue
+++ b/PAMapp/components/AddAndReservedBtns.vue
@@ -12,7 +12,7 @@
 
 <script lang="ts">
 import { Vue, Component, Prop, Emit, Action, State, namespace } from 'nuxt-property-decorator';
-import { Consultant } from '~/assets/ts/models/consultant.model';
+import { Consultant } from '~/shared/models/consultant.model';
 
 const localStorage = namespace('localStorage');
 @Component
@@ -41,4 +41,4 @@
                 ? true : false
     }
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/PAMapp/components/BackActionBar.vue b/PAMapp/components/BackActionBar.vue
index bf0c489..dc671d9 100644
--- a/PAMapp/components/BackActionBar.vue
+++ b/PAMapp/components/BackActionBar.vue
@@ -11,13 +11,14 @@
 import { namespace } from 'nuxt-property-decorator';
 import { Vue, Component,} from 'vue-property-decorator';
 import * as _ from 'lodash';
-import { Role } from '~/assets/ts/models/enum/role';
+import { Role } from '~/shared/models/enum/role';
 
 const roleStorage = namespace('localStorage');
 @Component
 export default class UiCarousel extends Vue {
   @roleStorage.Getter currentRole!:string;
   get label(): string {
+
     if (this.$route.name) {
       const routeName = this.$route.name.split('-')[0];
       let featureLabel = '';
diff --git a/PAMapp/components/Client/ClientCard.vue b/PAMapp/components/Client/ClientCard.vue
index 4fca204..b600629 100644
--- a/PAMapp/components/Client/ClientCard.vue
+++ b/PAMapp/components/Client/ClientCard.vue
@@ -96,10 +96,11 @@
 <script lang="ts">
 import { Vue, Component, Prop, Action } from 'nuxt-property-decorator';
 
-import appointmentService from '~/assets/ts/services/appointment.service';
-import { isMobileDevice } from '~/assets/ts/device';
-import { hideReviews } from '~/assets/ts/const/hide-reviews';
-import { ClientInfo } from '~/assets/ts/models/client.model';
+import appointmentService from '~/shared/services/appointment.service';
+import { isMobileDevice } from '~/shared/device';
+import { hideReviews } from '~/shared/const/hide-reviews';
+import { ClientInfo } from '~/shared/models/client.model';
+import myConsultantService from '~/shared/services/my-consultant.service';
 
 
 @Component({
@@ -198,7 +199,7 @@
     }
 
     markAppointment() {
-        appointmentService.markAsContact(this.client.id).then(data => {
+        myConsultantService.markAsContact(this.client.id).then(data => {
             // TODO: 閬敺����� updated client 鞈�� - Ben 2021/11/16
             const updatedClient = {...this.client};
             updatedClient.communicateStatus = 'contacted';
diff --git a/PAMapp/components/Client/ClientList.vue b/PAMapp/components/Client/ClientList.vue
index afdcdfc..31c4095 100644
--- a/PAMapp/components/Client/ClientList.vue
+++ b/PAMapp/components/Client/ClientList.vue
@@ -18,7 +18,7 @@
 <script lang='ts'>
 import { Vue, Component, Prop } from 'nuxt-property-decorator';
 
-import { ClientInfo } from '~/assets/ts/models/client.model';
+import { ClientInfo } from '~/shared/models/client.model';
 
 @Component
 export default class ClientList extends Vue {
diff --git a/PAMapp/components/Consultant/ConsultantCard.vue b/PAMapp/components/Consultant/ConsultantCard.vue
index f774135..6d2c5ae 100644
--- a/PAMapp/components/Consultant/ConsultantCard.vue
+++ b/PAMapp/components/Consultant/ConsultantCard.vue
@@ -129,12 +129,13 @@
 <script lang="ts">
 import { Vue, Component, Prop, Action, namespace } from 'nuxt-property-decorator';
 
-import appointmentService from '~/assets/ts/services/appointment.service';
-import { isMobileDevice } from '~/assets/ts/device';
-import { hideReviews } from '~/assets/ts/const/hide-reviews';
-import { UserReviewsConsultantsParams, userReviewsConsultants } from '~/assets/ts/api/consultant';
-import { Consultant, ConsultantWithAppointmentId } from '~/assets/ts/models/consultant.model';
-import { Appointment } from '~/assets/ts/models/appointment.model';
+import appointmentService from '~/shared/services/appointment.service';
+import reviewsService from '~/shared/services/reviews.service';
+import { isMobileDevice } from '~/shared/device';
+import { hideReviews } from '~/shared/const/hide-reviews';
+import { Consultant, ConsultantWithAppointmentId } from '~/shared/models/consultant.model';
+import { Appointment } from '~/shared/models/appointment.model';
+import { UserReviewsConsultantsParams } from '~/shared/models/reviews.model';
 
 const localStorage = namespace('localStorage');
 @Component({
@@ -354,7 +355,7 @@
         }
         this.appointmentDetail.satisfactionScore = this.inputScore;
 
-        userReviewsConsultants(reviewParams).then((res) => {
+        reviewsService.userReviewsConsultants(reviewParams).then((res) => {
             this.reviewsBtn = false;
             this.storeConsultantList();
         });
diff --git a/PAMapp/components/Consultant/ConsultantList.vue b/PAMapp/components/Consultant/ConsultantList.vue
index 33b9929..ce11a46 100644
--- a/PAMapp/components/Consultant/ConsultantList.vue
+++ b/PAMapp/components/Consultant/ConsultantList.vue
@@ -24,7 +24,7 @@
 
 <script lang="ts">
 import { Vue, Component, Prop, namespace } from 'nuxt-property-decorator';
-import { Consultant } from '~/assets/ts/models/consultant.model';
+import { Consultant } from '~/shared/models/consultant.model';
 
 const roleStorage = namespace('localStorage');
 
diff --git a/PAMapp/components/Consultant/ConsultantSwiper.vue b/PAMapp/components/Consultant/ConsultantSwiper.vue
index 7f8d13b..8adfc60 100644
--- a/PAMapp/components/Consultant/ConsultantSwiper.vue
+++ b/PAMapp/components/Consultant/ConsultantSwiper.vue
@@ -29,8 +29,8 @@
 <script lang="ts">
 import { Vue, Component, Prop } from 'vue-property-decorator';
 import { SwiperOptions } from 'swiper';
-import { Consultant } from '~/assets/ts/models/consultant.model';
-import { hideReviews } from '~/assets/ts/const/hide-reviews';
+import { Consultant } from '~/shared/models/consultant.model';
+import { hideReviews } from '~/shared/const/hide-reviews';
 
 @Component
 export default class UiSwiper extends Vue {
@@ -38,7 +38,7 @@
     @Prop() agents!: Consultant[];
 
     hideReviews = hideReviews ;
-    
+
     swiperOptions: SwiperOptions = {
       loop: false,
         slideToClickedSlide: false,
diff --git a/PAMapp/components/NavBar.vue b/PAMapp/components/NavBar.vue
index 6681eca..ca0cc1e 100644
--- a/PAMapp/components/NavBar.vue
+++ b/PAMapp/components/NavBar.vue
@@ -34,7 +34,7 @@
 <script lang="ts">
   import { Vue, Component } from 'vue-property-decorator';
   import { namespace } from 'nuxt-property-decorator';
-  import { Role } from '~/assets/ts/models/enum/role';
+  import { Role } from '~/shared/models/enum/role';
   import * as _ from 'lodash';
 
   const roleStorage = namespace('localStorage');
diff --git a/PAMapp/components/QuickFilter/QuickFilterConsultantList.vue b/PAMapp/components/QuickFilter/QuickFilterConsultantList.vue
index 4e722f1..de08434 100644
--- a/PAMapp/components/QuickFilter/QuickFilterConsultantList.vue
+++ b/PAMapp/components/QuickFilter/QuickFilterConsultantList.vue
@@ -82,8 +82,8 @@
 <script lang="ts">
 import { ElCarousel } from 'element-ui/types/carousel';
 import { Vue, Component, Prop } from 'vue-property-decorator';
-import { Consultant } from '~/assets/ts/models/consultant.model';
-import { hideReviews } from '~/assets/ts/const/hide-reviews';
+import { Consultant } from '~/shared/models/consultant.model';
+import { hideReviews } from '~/shared/const/hide-reviews';
 
 @Component
 export default class QuickFilterConsultantList extends Vue {
@@ -219,4 +219,4 @@
         }
     }
 
-</style>
\ No newline at end of file
+</style>
diff --git a/PAMapp/components/QuickFilter/QuickFilterSelector.vue b/PAMapp/components/QuickFilter/QuickFilterSelector.vue
index b286ecf..5d3cf8d 100644
--- a/PAMapp/components/QuickFilter/QuickFilterSelector.vue
+++ b/PAMapp/components/QuickFilter/QuickFilterSelector.vue
@@ -98,8 +98,8 @@
 
 <script lang="ts">
 import { Vue, Component, Prop, Watch, Emit } from 'nuxt-property-decorator';
-import { hideReviews } from '~/assets/ts/const/hide-reviews';
-import { FastQueryParams, QuestionOption, Selected } from '~/assets/ts/models/quickFilter.model';
+import { hideReviews } from '~/shared/const/hide-reviews';
+import { FastQueryParams, QuestionOption, Selected } from '~/shared/models/quick-filter.model';
 @Component
 export default class QuickFilterDrawer extends Vue {
     pickedItem: FastQueryParams = {
@@ -227,4 +227,4 @@
         }
     }
 
-</style>
\ No newline at end of file
+</style>
diff --git a/PAMapp/components/Ui/UiField.vue b/PAMapp/components/Ui/UiField.vue
index 5d5ee7b..df98f3c 100644
--- a/PAMapp/components/Ui/UiField.vue
+++ b/PAMapp/components/Ui/UiField.vue
@@ -13,7 +13,7 @@
 
 <script lang="ts">
 import { Vue, Component, Prop } from 'vue-property-decorator';
-import { isMobileDevice } from '~/assets/ts/device';
+import { isMobileDevice } from '~/shared/device';
 
 @Component
 export default class UiField extends Vue {
diff --git a/PAMapp/components/Ui/UiPagination.vue b/PAMapp/components/Ui/UiPagination.vue
index 40f2709..abb27a9 100644
--- a/PAMapp/components/Ui/UiPagination.vue
+++ b/PAMapp/components/Ui/UiPagination.vue
@@ -12,7 +12,7 @@
 
 <script lang="ts">
 import { Vue, Component, Prop, Emit, Watch } from 'nuxt-property-decorator';
-import { Consultant } from '~/assets/ts/models/consultant.model';
+import { Consultant } from '~/shared/models/consultant.model';
 
 @Component
 export default class UiPagination extends Vue {
diff --git a/PAMapp/components/popUpFrame.vue b/PAMapp/components/popUpFrame.vue
index f08993c..cfff207 100644
--- a/PAMapp/components/popUpFrame.vue
+++ b/PAMapp/components/popUpFrame.vue
@@ -15,7 +15,7 @@
 
 <script lang="ts">
   import { Vue, Component, Prop,Emit, Watch, PropSync} from 'vue-property-decorator';
-  import { isMobileDevice } from '../assets/ts/device';
+  import { isMobileDevice } from '~/shared/device';
   @Component
   export default class PopUpFrame extends Vue {
     @PropSync('isOpen',{type:Boolean,default:false}) syncIsOpen!:boolean;
@@ -32,7 +32,7 @@
     private get isUseDialog() : boolean {
       return this.syncIsOpen && !isMobileDevice();
     }
-    
+
     private set isUseDialog(value: boolean) {
       this.$emit('update:isOpen',value);
     }
diff --git a/PAMapp/pages/accountSetting/index.vue b/PAMapp/pages/accountSetting/index.vue
index 4a1275c..33ecd55 100644
--- a/PAMapp/pages/accountSetting/index.vue
+++ b/PAMapp/pages/accountSetting/index.vue
@@ -70,8 +70,9 @@
 
 <script lang="ts">
 import { Vue,Component } from 'vue-property-decorator'
-import { getUserAccountSetting, updateAccountSetting } from '~/assets/ts/api/consultant';
-import { UserSetting } from '~/assets/ts/models/account.model';
+import { UserSetting } from '~/shared/models/account.model';
+
+import accountSettingService from '~/shared/services/account-setting.service';
 
 @Component
 export default class AccountSetting extends Vue {
@@ -139,7 +140,7 @@
                 phone: this.phoneValue,
                 email: this.emailValue
             }
-            updateAccountSetting(editSettingInfo).then((res: any) => {
+            accountSettingService.updateAccountSetting(editSettingInfo).then((res: any) => {
                 console.log('updateRes:', res);
                 this.resetSettingForm();
             });
@@ -153,7 +154,7 @@
         }
 
         mounted(){
-            getUserAccountSetting().then((userInfo: UserSetting)=>{
+            accountSettingService.getUserAccountSetting().then((userInfo: UserSetting)=>{
                 this._userSetting = {
                     name: userInfo.name || '',
                     phone: userInfo.phone || '',
diff --git a/PAMapp/pages/agentInfo/_agentNo.vue b/PAMapp/pages/agentInfo/_agentNo.vue
index fb434b4..de479db 100644
--- a/PAMapp/pages/agentInfo/_agentNo.vue
+++ b/PAMapp/pages/agentInfo/_agentNo.vue
@@ -190,10 +190,10 @@
 import { namespace } from 'nuxt-property-decorator';
 import { Vue, Component } from 'vue-property-decorator';
 
-import myConsultantService from '~/assets/ts/services/my-consultant.service';
-import { AgentInfo } from '~/assets/ts/models/agent-info.model';
-import { hideReviews } from '~/assets/ts/const/hide-reviews';
-import { Role } from '~/assets/ts/models/enum/role';
+import myConsultantService from '~/shared/services/my-consultant.service';
+import { AgentInfo } from '~/shared/models/agent-info.model';
+import { hideReviews } from '~/shared/const/hide-reviews';
+import { Role } from '~/shared/models/enum/role';
 
 const roleStorage = namespace('localStorage');
 
diff --git a/PAMapp/pages/consultantLogin/index.vue b/PAMapp/pages/consultantLogin/index.vue
index 8ad62c8..3a90f3f 100644
--- a/PAMapp/pages/consultantLogin/index.vue
+++ b/PAMapp/pages/consultantLogin/index.vue
@@ -58,9 +58,9 @@
 <script lang="ts">
   import { Vue, Component , namespace } from 'nuxt-property-decorator';
   import { AxiosError } from 'axios';
-  import { Role } from '~/assets/ts/models/enum/role';
-  import ErrorMessageBox from '~/assets/ts/errorService';
-  import loginService from '~/assets/ts/services/login.service'
+  import { Role } from '~/shared/models/enum/role';
+  import ErrorMessageBox from '~/shared/errorService';
+  import loginService from '~/shared/services/login.service'
 
   const roleStorage = namespace('localStorage');
   @Component({
diff --git a/PAMapp/pages/faq.vue b/PAMapp/pages/faq.vue
index 3b629c5..d01440f 100644
--- a/PAMapp/pages/faq.vue
+++ b/PAMapp/pages/faq.vue
@@ -9,7 +9,7 @@
 
 <script lang="ts">
 import { Vue, Component } from 'nuxt-property-decorator';
-import { faqList } from '~/assets/ts/const/faqList';
+import { faqList } from '~/shared/const/faqList';
 
 @Component
 export default class Faq extends Vue {
@@ -22,4 +22,4 @@
 }
 </script>
 
-<style lang="scss" scoped></style>
\ No newline at end of file
+<style lang="scss" scoped></style>
diff --git a/PAMapp/pages/index.vue b/PAMapp/pages/index.vue
index 55baff7..5e21e53 100644
--- a/PAMapp/pages/index.vue
+++ b/PAMapp/pages/index.vue
@@ -44,7 +44,7 @@
 
 <script lang="ts">
   import { Vue, Component, State, Action, Watch, namespace } from 'nuxt-property-decorator';
-  import { Consultant } from '~/assets/ts/models/consultant.model';
+  import { Consultant } from '~/shared/models/consultant.model';
 
   const localStorage = namespace('localStorage');
   @Component({
diff --git a/PAMapp/pages/login/index.vue b/PAMapp/pages/login/index.vue
index 1167d6f..8e60407 100644
--- a/PAMapp/pages/login/index.vue
+++ b/PAMapp/pages/login/index.vue
@@ -335,14 +335,14 @@
 <script lang="ts">
 import { namespace } from 'nuxt-property-decorator';
 import { Vue, Component, Ref } from 'vue-property-decorator';
-import ErrorMessageBox from '~/assets/ts/errorService';
-import { OtpErrorCode } from '~/assets/ts/models/enum/otpErrorCode';
-import { Role } from '~/assets/ts/models/enum/role';
-import { LoginRequest } from '~/assets/ts/models/loginRequest.model';
-import { LoginVerify } from '~/assets/ts/models/loginVerify.model';
-import { OtpInfo } from '~/assets/ts/models/otpInfo.model';
-import { RegisterInfo } from '~/assets/ts/models/registerInfo';
-import loginService from '~/assets/ts/services/login.service';
+import ErrorMessageBox from '~/shared/errorService';
+import { OtpErrorCode } from '~/shared/models/enum/otpErrorCode';
+import { Role } from '~/shared/models/enum/role';
+import { LoginRequest } from '~/shared/models/loginRequest.model';
+import { LoginVerify } from '~/shared/models/loginVerify.model';
+import { OtpInfo } from '~/shared/models/otpInfo.model';
+import { RegisterInfo } from '~/shared/models/registerInfo';
+import loginService from '~/shared/services/login.service';
 
 const roleStorage = namespace('localStorage');
 
diff --git a/PAMapp/pages/myAppointmentList.vue b/PAMapp/pages/myAppointmentList.vue
index 6578ae8..f5198db 100644
--- a/PAMapp/pages/myAppointmentList.vue
+++ b/PAMapp/pages/myAppointmentList.vue
@@ -45,7 +45,7 @@
 
 import * as _ from 'lodash';
 
-import { ClientInfo } from '~/assets/ts/models/client.model';
+import { ClientInfo } from '~/shared/models/client.model';
 
 @Component({
     layout: 'home',
diff --git a/PAMapp/pages/myAppointmentList/appointmentList.vue b/PAMapp/pages/myAppointmentList/appointmentList.vue
index 791b947..617b4fb 100644
--- a/PAMapp/pages/myAppointmentList/appointmentList.vue
+++ b/PAMapp/pages/myAppointmentList/appointmentList.vue
@@ -25,7 +25,7 @@
 <script lang="ts">
 import { Vue, Component, State, Watch } from 'nuxt-property-decorator';
 
-import { ClientInfo } from '~/assets/ts/models/client.model';
+import { ClientInfo } from '~/shared/models/client.model';
 
 @Component
 export default class ClientReservedList extends Vue {
diff --git a/PAMapp/pages/myAppointmentList/contactedList.vue b/PAMapp/pages/myAppointmentList/contactedList.vue
index dbd8232..92ecd84 100644
--- a/PAMapp/pages/myAppointmentList/contactedList.vue
+++ b/PAMapp/pages/myAppointmentList/contactedList.vue
@@ -29,7 +29,7 @@
 <script lang="ts">
 import { Vue, Component, Watch, State } from 'nuxt-property-decorator';
 
-import { ClientInfo } from '~/assets/ts/models/client.model';
+import { ClientInfo } from '~/shared/models/client.model';
 
 @Component
 export default class ClientContactedList extends Vue {
diff --git a/PAMapp/pages/myConsultantList.vue b/PAMapp/pages/myConsultantList.vue
index d0b0ae0..687547c 100644
--- a/PAMapp/pages/myConsultantList.vue
+++ b/PAMapp/pages/myConsultantList.vue
@@ -26,7 +26,7 @@
 
 <script lang='ts'>
 import { Vue, Component, Watch, State, Action } from 'nuxt-property-decorator';
-import { Consultant, ConsultantWithAppointmentId } from '~/assets/ts/models/consultant.model';
+import { Consultant, ConsultantWithAppointmentId } from '~/shared/models/consultant.model';
 
 @Component
 export default class myConsultantList extends Vue {
diff --git a/PAMapp/pages/myConsultantList/consultantList.vue b/PAMapp/pages/myConsultantList/consultantList.vue
index 0ea42af..0b1d3b6 100644
--- a/PAMapp/pages/myConsultantList/consultantList.vue
+++ b/PAMapp/pages/myConsultantList/consultantList.vue
@@ -14,7 +14,7 @@
 
 <script lang="ts">
 import { Vue, Component, Prop } from 'nuxt-property-decorator';
-import { Consultant } from '~/assets/ts/models/consultant.model';
+import { Consultant } from '~/shared/models/consultant.model';
 
 
 @Component
@@ -27,4 +27,4 @@
     }
 
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/PAMapp/pages/myConsultantList/contactedList.vue b/PAMapp/pages/myConsultantList/contactedList.vue
index af53d84..1977f6b 100644
--- a/PAMapp/pages/myConsultantList/contactedList.vue
+++ b/PAMapp/pages/myConsultantList/contactedList.vue
@@ -14,7 +14,7 @@
 
 <script lang="ts">
 import { Vue, Component, Prop } from 'nuxt-property-decorator' ;
-import { Consultant } from '~/assets/ts/models/consultant.model';
+import { Consultant } from '~/shared/models/consultant.model';
 
 
 @Component
@@ -26,4 +26,4 @@
         this.pageList = pageList;
     }
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/PAMapp/pages/questionnaire/_agentNo.vue b/PAMapp/pages/questionnaire/_agentNo.vue
index 9b8b5c1..83f35e9 100644
--- a/PAMapp/pages/questionnaire/_agentNo.vue
+++ b/PAMapp/pages/questionnaire/_agentNo.vue
@@ -140,13 +140,16 @@
 
 <script lang="ts">
 import { Vue, Component, State, Action, Watch, namespace } from 'nuxt-property-decorator';
-import { addFavoriteConsultant, appointmentDemand, AppointmentParams, AppointmentRequests ,editAppointment } from '~/assets/ts/api/consultant';
-import { getRequestQuestionFromStorage, getRequestsFromStorage, removeRequestQuestionFromStorage, setRequestsToStorage } from '~/assets/ts/storageRequests';
+import { getRequestsFromStorage, removeRequestQuestionFromStorage, setRequestsToStorage } from '~/shared/storageRequests';
 import _ from 'lodash';
-import { Consultant } from '~/assets/ts/models/consultant.model';
-import { ContactType } from '~/assets/ts/models/enum/ContactType';
-import { Gender } from '~/assets/ts/models/enum/Gender';
-import { RegisterInfo } from '~/assets/ts/models/registerInfo';
+
+import queryConsultantService from '~/shared/services/query-consultant.service';
+import appointmentService from '~/shared/services/appointment.service';
+import { Consultant } from '~/shared/models/consultant.model';
+import { ContactType } from '~/shared/models/enum/ContactType';
+import { Gender } from '~/shared/models/enum/Gender';
+import { RegisterInfo } from '~/shared/models/registerInfo';
+import { AppointmentParams, AppointmentRequests } from '~/shared/models/appointment.model';
 
   const roleStorage = namespace('localStorage');
   @Component
@@ -350,7 +353,7 @@
       if (this.isEditBtn) {
         this.sentEditAppointmentDemand();
       } else {
-        addFavoriteConsultant([this.$route.params.agentNo]).then(res => this.sentAppointmentDemand());
+        queryConsultantService.addFavoriteConsultant([this.$route.params.agentNo]).then(res => this.sentAppointmentDemand());
       }
 
     }
@@ -363,7 +366,7 @@
           agentNo: this.$route.params.agentNo
         };
 
-        appointmentDemand(data).then(res => {
+        queryConsultantService.appointmentDemand(data).then(res => {
             this.sendReserve = true;
             this.myRequest.hopeContactTime = [];
             setRequestsToStorage(this.myRequest);
@@ -378,7 +381,7 @@
           id: this.appointmentId,
           otherRequirement: null
         }
-        editAppointment(info).then(res => {
+        appointmentService.editAppointment(info).then(res => {
           this.sendReserve = true;
           this.myRequest.hopeContactTime = [];
           setRequestsToStorage(this.myRequest);
diff --git a/PAMapp/pages/quickFilter/index.vue b/PAMapp/pages/quickFilter/index.vue
index d978446..6e6444e 100644
--- a/PAMapp/pages/quickFilter/index.vue
+++ b/PAMapp/pages/quickFilter/index.vue
@@ -70,10 +70,10 @@
 
 <script lang="ts">
 import { Vue, Component, namespace } from 'nuxt-property-decorator';
-import { Consultant } from '~/assets/ts/models/consultant.model';
-import { questionList } from '~/assets/ts/const/quickFilter-questionList';
-import { FastQueryParams, QuestionOption, Selected } from '~/assets/ts/models/quickFilter.model';
-import { fastQuery } from '~/assets/ts/api/consultant';
+import { Consultant } from '~/shared/models/consultant.model';
+import { FastQueryParams, QuestionOption, Selected } from '~/shared/models/quick-filter.model';
+import queryConsultantService from '~/shared/services/query-consultant.service';
+import { questionList } from '~/shared/const/quickFilter-questionList';
 
 const localStorage = namespace('localStorage');
 @Component({
@@ -196,7 +196,7 @@
             seniority: this.getSeniority()
         }
 
-        fastQuery(data).then((consultantList) => {
+        queryConsultantService.fastQuery(data).then((consultantList) => {
             this.consultantList = consultantList;
             this.storageQuickFilter(JSON.stringify(this.confirmItem))
         })
@@ -260,4 +260,4 @@
         }
     }
 
-</style>
\ No newline at end of file
+</style>
diff --git a/PAMapp/pages/recommendConsultant/index.vue b/PAMapp/pages/recommendConsultant/index.vue
index f4135c6..0d0eb55 100644
--- a/PAMapp/pages/recommendConsultant/index.vue
+++ b/PAMapp/pages/recommendConsultant/index.vue
@@ -95,7 +95,7 @@
     State
   } from 'nuxt-property-decorator';
   import * as _ from 'lodash';
-  import { Seniority } from '~/assets/ts/models/enum/seniority';
+  import { Seniority } from '~/shared/models/enum/seniority';
 
   const localStorage = namespace('localStorage');
 
diff --git a/PAMapp/pages/recommendConsultant/result.vue b/PAMapp/pages/recommendConsultant/result.vue
index 9f04e1e..3695bfc 100644
--- a/PAMapp/pages/recommendConsultant/result.vue
+++ b/PAMapp/pages/recommendConsultant/result.vue
@@ -83,8 +83,8 @@
 </template>
 <script lang="ts">
 import {Vue,Component, State, namespace, Action} from 'nuxt-property-decorator';
-import { AgentOfStrictQuery } from '~/assets/ts/api/consultant';
-import { hideReviews } from '~/assets/ts/const/hide-reviews';
+import { hideReviews } from '~/shared/const/hide-reviews';
+import { AgentOfStrictQuery } from '~/shared/models/strict-query.model';
 
 const localStorage = namespace('localStorage');
 
diff --git a/PAMapp/pages/record/index.vue b/PAMapp/pages/record/index.vue
index 692841f..db7ac04 100644
--- a/PAMapp/pages/record/index.vue
+++ b/PAMapp/pages/record/index.vue
@@ -12,7 +12,7 @@
     </section>
 
     <section class="user-reviews-content">
-        <div 
+        <div
             class="user-reviews-card"
             v-for="(appointmentLog, index) in myAppointmentReviewLogList"
             :key="index">
@@ -24,25 +24,25 @@
             </div>
             <div class="user-reviews-card-date">
                 <div class="date">
-                    <UiDateFormat 
+                    <UiDateFormat
                         :date="appointmentLog.lastModifiedDate"
                         onlyShowSection="DAY" />
                 </div>
                 <div class="time">
-                    <UiDateFormat 
+                    <UiDateFormat
                         :date="appointmentLog.lastModifiedDate"
                         onlyShowSection="TIME" />
                 </div>
             </div>
         </div>
     </section>
-  
+
 </div>
 
 </template>
 <script lang="ts">
 import { Vue, Component, Action, State, namespace } from 'nuxt-property-decorator';
-import { AppointmentLog } from '~/assets/ts/models/appointment.model';
+import { AppointmentLog } from '~/shared/models/appointment.model';
 
 const roleStorage = namespace('localStorage');
 
@@ -63,8 +63,8 @@
         this.storeMyAppointmentReviewLog();
     }
 
-    
-    
+
+
 }
 </script>
 <style lang="scss" scoped>
@@ -101,7 +101,7 @@
                 width:52px;
                 .date{
                     margin-bottom: 2px;
-                    
+
                 }
             }
         }
@@ -112,4 +112,4 @@
         flex: 1;
     }
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/PAMapp/pages/userReviews/index.vue b/PAMapp/pages/userReviews/index.vue
index 96b0cd9..6152aad 100644
--- a/PAMapp/pages/userReviews/index.vue
+++ b/PAMapp/pages/userReviews/index.vue
@@ -1,9 +1,9 @@
-<template> 
+<template>
 <div class="reviews-page">
     <!-- 憿批恥��遛��漲蝯阡“��� -->
     <div class="reviews-banner"></div>
 
-    <section class="reviews-container"> 
+    <section class="reviews-container">
         <section class="reviews-header">
             <div class="reviews-header-container">
                 <div class="reviews-header-title">皛踵�漲隤踵</div>
@@ -20,17 +20,17 @@
                     <div class="card-txt">
                         撠憿批��
                         <span class="p">{{item.name}}</span>��擃���,�蝯虫�嗾憿���?
-                        <div 
+                        <div
                             class="card-score"
                             v-if="!isMobileDevice">
                             <el-rate class="user-reviews-rate" v-model="item.avgScore"></el-rate>
                         </div>
                     </div>
                 </div>
-                <div 
+                <div
                     class="card-score"
                     v-if="isMobileDevice">
-                    <el-rate 
+                    <el-rate
                         class="user-reviews-rate"
                         v-model="item.avgScore"></el-rate>
                 </div>
@@ -49,13 +49,13 @@
             <el-button type="primary" class="reviews-dialog-btn" @click.native="reviewsDialogCheck">������</el-button>
         </div>
     </PopUpFrame>
-    
+
 
 </div>
 </template>
 <script lang="ts">
 import { Vue,Component } from 'vue-property-decorator'
-import { isMobileDevice } from '~/assets/ts/device';
+import { isMobileDevice } from '~/shared/device';
 
 
 @Component({
@@ -209,4 +209,4 @@
 
 }
 
-</style>
\ No newline at end of file
+</style>
diff --git a/PAMapp/pages/userReviewsRecord/index.vue b/PAMapp/pages/userReviewsRecord/index.vue
index a0665d9..2f5471e 100644
--- a/PAMapp/pages/userReviewsRecord/index.vue
+++ b/PAMapp/pages/userReviewsRecord/index.vue
@@ -12,7 +12,7 @@
     </section>
 
     <section class="user-reviews-content">
-        <div 
+        <div
             class="user-reviews-card"
             v-for="(appointmentLog, index) in myAppointmentReviewLogList"
             :key="index">
@@ -24,25 +24,25 @@
             </div>
             <div class="user-reviews-card-date">
                 <div class="date">
-                    <UiDateFormat 
+                    <UiDateFormat
                         :date="appointmentLog.lastModifiedDate"
                         onlyShowSection="DAY" />
                 </div>
                 <div class="time">
-                    <UiDateFormat 
+                    <UiDateFormat
                         :date="appointmentLog.lastModifiedDate"
                         onlyShowSection="TIME" />
                 </div>
             </div>
         </div>
     </section>
-  
+
 </div>
 
 </template>
 <script lang="ts">
 import { Vue, Component, Action, State, namespace } from 'nuxt-property-decorator';
-import { AppointmentLog } from '~/assets/ts/models/appointment.model';
+import { AppointmentLog } from '~/shared/models/appointment.model';
 
 const roleStorage = namespace('localStorage');
 
@@ -62,7 +62,7 @@
     mounted() {
         this.storeMyAppointmentReviewLog();
     }
-    
+
 }
 </script>
 <style lang="scss" scoped>
@@ -99,7 +99,7 @@
                 width:52px;
                 .date{
                     margin-bottom: 2px;
-                    
+
                 }
             }
         }
@@ -110,4 +110,4 @@
         flex: 1;
     }
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/PAMapp/assets/ts/const/faqList.ts b/PAMapp/shared/const/faqList.ts
similarity index 100%
rename from PAMapp/assets/ts/const/faqList.ts
rename to PAMapp/shared/const/faqList.ts
diff --git a/PAMapp/assets/ts/const/hide-reviews.ts b/PAMapp/shared/const/hide-reviews.ts
similarity index 100%
rename from PAMapp/assets/ts/const/hide-reviews.ts
rename to PAMapp/shared/const/hide-reviews.ts
diff --git a/PAMapp/assets/ts/const/quickFilter-questionList.ts b/PAMapp/shared/const/quickFilter-questionList.ts
similarity index 95%
rename from PAMapp/assets/ts/const/quickFilter-questionList.ts
rename to PAMapp/shared/const/quickFilter-questionList.ts
index a31bc0a..34cdcda 100644
--- a/PAMapp/assets/ts/const/quickFilter-questionList.ts
+++ b/PAMapp/shared/const/quickFilter-questionList.ts
@@ -1,5 +1,6 @@
 import { Seniority } from "../models/enum/seniority";
-import { QuestionOption } from "../models/quickFilter.model";
+import { QuestionOption } from "../models/quick-filter.model";
+
 
 export const questionList: QuestionOption[] = [
     {
diff --git a/PAMapp/assets/ts/device.ts b/PAMapp/shared/device.ts
similarity index 100%
rename from PAMapp/assets/ts/device.ts
rename to PAMapp/shared/device.ts
diff --git a/PAMapp/assets/ts/errorService.ts b/PAMapp/shared/errorService.ts
similarity index 100%
rename from PAMapp/assets/ts/errorService.ts
rename to PAMapp/shared/errorService.ts
diff --git a/PAMapp/assets/ts/models/ConsultantLoginInfo.ts b/PAMapp/shared/models/ConsultantLoginInfo.ts
similarity index 100%
rename from PAMapp/assets/ts/models/ConsultantLoginInfo.ts
rename to PAMapp/shared/models/ConsultantLoginInfo.ts
diff --git a/PAMapp/assets/ts/models/account.model.ts b/PAMapp/shared/models/account.model.ts
similarity index 100%
rename from PAMapp/assets/ts/models/account.model.ts
rename to PAMapp/shared/models/account.model.ts
diff --git a/PAMapp/assets/ts/models/agent-info.model.ts b/PAMapp/shared/models/agent-info.model.ts
similarity index 100%
rename from PAMapp/assets/ts/models/agent-info.model.ts
rename to PAMapp/shared/models/agent-info.model.ts
diff --git a/PAMapp/assets/ts/models/appointment.model.ts b/PAMapp/shared/models/appointment.model.ts
similarity index 62%
rename from PAMapp/assets/ts/models/appointment.model.ts
rename to PAMapp/shared/models/appointment.model.ts
index f411b7a..1774dd6 100644
--- a/PAMapp/assets/ts/models/appointment.model.ts
+++ b/PAMapp/shared/models/appointment.model.ts
@@ -55,4 +55,41 @@
   customerId       : number;
   name             : string;
 }
-
+export interface AppointmentParams {
+  phone          : string;
+  email          : string;
+  contactType    : string;
+  gender         : string;
+  age            : string;
+  job            : string;
+  requirement    : string;
+  hopeContactTime: string;
+  agentNo        : string;
+}
+export interface EditAppointmentParams {
+  id              : number,
+  phone           : string,
+  email           : string,
+  contactType     : string,
+  gender          : string,
+  age             : string,
+  job             : string,
+  requirement     : string,
+  hopeContactTime : string,
+  otherRequirement: null
+}
+export interface AppointmentRequests {
+  phone          : string,
+  email          : string,
+  contactType    : string,
+  gender         : string,
+  age            : string,
+  job            : string,
+  requirement    : string[],
+  hopeContactTime: ContactTime[],
+  agentNo        : string,
+}
+export interface ContactTime {
+selectWeekOptions : string[],
+selectTimesOptions: string[]
+}
diff --git a/PAMapp/assets/ts/models/client.model.ts b/PAMapp/shared/models/client.model.ts
similarity index 100%
rename from PAMapp/assets/ts/models/client.model.ts
rename to PAMapp/shared/models/client.model.ts
diff --git a/PAMapp/assets/ts/models/clientInfo.ts b/PAMapp/shared/models/clientInfo.ts
similarity index 100%
rename from PAMapp/assets/ts/models/clientInfo.ts
rename to PAMapp/shared/models/clientInfo.ts
diff --git a/PAMapp/assets/ts/models/consultant.model.ts b/PAMapp/shared/models/consultant.model.ts
similarity index 100%
rename from PAMapp/assets/ts/models/consultant.model.ts
rename to PAMapp/shared/models/consultant.model.ts
diff --git a/PAMapp/assets/ts/models/editAppointmentParams.model.ts b/PAMapp/shared/models/editAppointmentParams.model.ts
similarity index 100%
rename from PAMapp/assets/ts/models/editAppointmentParams.model.ts
rename to PAMapp/shared/models/editAppointmentParams.model.ts
diff --git a/PAMapp/assets/ts/models/enum/ContactType.ts b/PAMapp/shared/models/enum/ContactType.ts
similarity index 100%
rename from PAMapp/assets/ts/models/enum/ContactType.ts
rename to PAMapp/shared/models/enum/ContactType.ts
diff --git a/PAMapp/assets/ts/models/enum/Gender.ts b/PAMapp/shared/models/enum/Gender.ts
similarity index 100%
rename from PAMapp/assets/ts/models/enum/Gender.ts
rename to PAMapp/shared/models/enum/Gender.ts
diff --git a/PAMapp/shared/models/enum/Role.ts b/PAMapp/shared/models/enum/Role.ts
new file mode 100644
index 0000000..1b2823c
--- /dev/null
+++ b/PAMapp/shared/models/enum/Role.ts
@@ -0,0 +1,5 @@
+export enum Role{
+    ADMIN     = 'admin',
+    USER      = 'user',
+    NOT_LOGIN = ''
+}
diff --git a/PAMapp/assets/ts/models/enum/otpErrorCode.ts b/PAMapp/shared/models/enum/otpErrorCode.ts
similarity index 100%
rename from PAMapp/assets/ts/models/enum/otpErrorCode.ts
rename to PAMapp/shared/models/enum/otpErrorCode.ts
diff --git a/PAMapp/assets/ts/models/enum/seniority.ts b/PAMapp/shared/models/enum/seniority.ts
similarity index 100%
rename from PAMapp/assets/ts/models/enum/seniority.ts
rename to PAMapp/shared/models/enum/seniority.ts
diff --git a/PAMapp/assets/ts/models/loginRequest.model.ts b/PAMapp/shared/models/loginRequest.model.ts
similarity index 100%
rename from PAMapp/assets/ts/models/loginRequest.model.ts
rename to PAMapp/shared/models/loginRequest.model.ts
diff --git a/PAMapp/assets/ts/models/loginSuccessToken.model.ts b/PAMapp/shared/models/loginSuccessToken.model.ts
similarity index 100%
rename from PAMapp/assets/ts/models/loginSuccessToken.model.ts
rename to PAMapp/shared/models/loginSuccessToken.model.ts
diff --git a/PAMapp/assets/ts/models/loginVerify.model.ts b/PAMapp/shared/models/loginVerify.model.ts
similarity index 100%
rename from PAMapp/assets/ts/models/loginVerify.model.ts
rename to PAMapp/shared/models/loginVerify.model.ts
diff --git a/PAMapp/assets/ts/models/otpInfo.model.ts b/PAMapp/shared/models/otpInfo.model.ts
similarity index 100%
rename from PAMapp/assets/ts/models/otpInfo.model.ts
rename to PAMapp/shared/models/otpInfo.model.ts
diff --git a/PAMapp/assets/ts/models/quickFilter.model.ts b/PAMapp/shared/models/quick-filter.model.ts
similarity index 78%
rename from PAMapp/assets/ts/models/quickFilter.model.ts
rename to PAMapp/shared/models/quick-filter.model.ts
index 2db9ea3..0516095 100644
--- a/PAMapp/assets/ts/models/quickFilter.model.ts
+++ b/PAMapp/shared/models/quick-filter.model.ts
@@ -1,13 +1,13 @@
 export interface QuestionOption {
-    title: string;
+    title : string;
     detail: Detail[];
-    type: string;
-    name: string;
+    type  : string;
+    name  : string;
 }
 
 interface Detail {
-    value: string;
-    name?: string;
+    value    : string;
+    name?    : string;
     className: string;
     subTitle?: string
 }
@@ -23,5 +23,5 @@
 
 export interface Selected {
     option: string;
-    value: any;
-}
\ No newline at end of file
+    value : any;
+}
diff --git a/PAMapp/assets/ts/models/registerInfo.ts b/PAMapp/shared/models/registerInfo.ts
similarity index 100%
rename from PAMapp/assets/ts/models/registerInfo.ts
rename to PAMapp/shared/models/registerInfo.ts
diff --git a/PAMapp/shared/models/reviews.model.ts b/PAMapp/shared/models/reviews.model.ts
new file mode 100644
index 0000000..438cdd3
--- /dev/null
+++ b/PAMapp/shared/models/reviews.model.ts
@@ -0,0 +1,4 @@
+export interface UserReviewsConsultantsParams{
+  appointmentId: number,
+  score        : number,
+}
diff --git a/PAMapp/shared/models/strict-query.model.ts b/PAMapp/shared/models/strict-query.model.ts
new file mode 100644
index 0000000..59892c1
--- /dev/null
+++ b/PAMapp/shared/models/strict-query.model.ts
@@ -0,0 +1,24 @@
+
+export interface StrictQueryParams {
+  gender          : string;
+  avgScore        : number;
+  status          : string;    //phase 1 disable
+  area            : string;
+  requirements    : string[];
+  otherRequirement: string;
+  seniority       : string;
+  popularTags     : string[];
+  otherPopularTags: string;
+}
+
+export interface AgentOfStrictQuery {
+  agentNo      : string;
+  name         : string;
+  img          : string;
+  expertise    : string[];
+  avgScore     : number;
+  contactStatus: null;
+  updateTime   : null;
+  seniority    : string;
+  new          : boolean;
+}
diff --git a/PAMapp/shared/services/account-setting.service.ts b/PAMapp/shared/services/account-setting.service.ts
new file mode 100644
index 0000000..ab560f5
--- /dev/null
+++ b/PAMapp/shared/services/account-setting.service.ts
@@ -0,0 +1,17 @@
+import { http } from "./httpClient";
+
+import { UserSetting } from "~/shared/models/account.model";
+
+class AccountSettingService{
+
+  //���蝙��董�����
+  async getUserAccountSetting() : Promise<UserSetting> {
+    return http.get<UserSetting>('/customer/info').then(res => res.data);
+  }
+  //��雿輻�董�����
+  async updateAccountSetting(params: any) : Promise<any> {
+    return http.put('/customer/info', params ).then(res => res.data);
+  }
+
+}
+export default new AccountSettingService();
diff --git a/PAMapp/assets/ts/services/appointment.service.ts b/PAMapp/shared/services/appointment.service.ts
similarity index 68%
rename from PAMapp/assets/ts/services/appointment.service.ts
rename to PAMapp/shared/services/appointment.service.ts
index 33f33b2..c8c6f9d 100644
--- a/PAMapp/assets/ts/services/appointment.service.ts
+++ b/PAMapp/shared/services/appointment.service.ts
@@ -1,7 +1,7 @@
 import { http } from "./httpClient";
 
-import { ClientInfo } from "../models/client.model";
-import { AppointmentDetail } from "../models/appointment.model";
+import { ClientInfo } from "~/shared/models/client.model";
+import { AppointmentDetail, EditAppointmentParams } from "~/shared/models/appointment.model";
 
 class AppointmentService {
 
@@ -16,16 +16,9 @@
     });
   }
 
+  // 憿批��憿舐內����蝑敺孛�
   private viewAllAppointment(): void {
     http.post('/consultant/record/allAppointmentsView').then();
-  }
-
-  // 璅�撌脰蝯�
-  markAsContact(appointmentId: number): Promise<void> {
-      // TODO: 頝�垢蝣箄���ㄐ��� API 銝�府���� void, ���府���敺���� - Ben 2021/11/16
-      // return http.post('/appointment/markAsContacted/'+appointmentId, undefined, {headers})
-      //         .then(res => res.data)
-      return http.post(`/appointment/markAsContacted/${appointmentId}`);
   }
 
   // 霈�������孛�嚗������������
@@ -43,6 +36,11 @@
     return http.delete(`/appointment/${appointmentId}`);
   }
 
+  // 蝺刻摩����
+  editAppointment(editAppointmentParams: EditAppointmentParams) {
+    return http.put('/appointment', editAppointmentParams);
+  }
+
 }
 
 export default new AppointmentService();
diff --git a/PAMapp/assets/ts/services/httpClient.ts b/PAMapp/shared/services/httpClient.ts
similarity index 100%
rename from PAMapp/assets/ts/services/httpClient.ts
rename to PAMapp/shared/services/httpClient.ts
diff --git a/PAMapp/assets/ts/services/login.service.ts b/PAMapp/shared/services/login.service.ts
similarity index 100%
rename from PAMapp/assets/ts/services/login.service.ts
rename to PAMapp/shared/services/login.service.ts
diff --git a/PAMapp/shared/services/my-consultant.service.ts b/PAMapp/shared/services/my-consultant.service.ts
new file mode 100644
index 0000000..ed06483
--- /dev/null
+++ b/PAMapp/shared/services/my-consultant.service.ts
@@ -0,0 +1,42 @@
+import { http } from "./httpClient";
+
+import { AgentInfo } from '~/shared/models/agent-info.model';
+import { Consultant } from "../models/consultant.model";
+
+class MyConsultantService {
+
+  async getFavoriteConsultantList(): Promise<Consultant[]> {
+    return http.get<Consultant[]>('/consultant/favorite').then((res) => {
+      const hasNewConsultant = res.data.find((consultant) => !consultant.customerViewTime);
+      if (hasNewConsultant) {
+        this.viewMyConsultantList();
+      };
+      return res.data;
+    });
+  }
+
+  private viewMyConsultantList(): void {
+    http.post('/consultant/favorite/view');
+  }
+
+  //憿批�底蝝啗���
+  async getConsultantDetail(agentNo:string): Promise<AgentInfo> {
+    return http.get('/consultant/detail', {params:{agentNo:agentNo}}).then((res) => res.data);
+  }
+
+  // 蝘駁憿批��
+  async deleteConsultant(agentId: string) {
+    return http.delete(`/consultant/favorite/${agentId}`);
+  }
+
+  // 璅�撌脰蝯�
+  markAsContact(appointmentId: number): Promise<void> {
+    // TODO: 頝�垢蝣箄���ㄐ��� API 銝�府���� void, ���府���敺���� - Ben 2021/11/16
+    // return http.post('/appointment/markAsContacted/'+appointmentId, undefined, {headers})
+    //         .then(res => res.data)
+    return http.post(`/appointment/markAsContacted/${appointmentId}`);
+  }
+
+}
+
+export default new MyConsultantService();
diff --git a/PAMapp/shared/services/query-consultant.service.ts b/PAMapp/shared/services/query-consultant.service.ts
new file mode 100644
index 0000000..a11cd13
--- /dev/null
+++ b/PAMapp/shared/services/query-consultant.service.ts
@@ -0,0 +1,37 @@
+import { http } from "./httpClient";
+
+import { Consultant } from "~/shared/models/consultant.model";
+import { FastQueryParams } from "~/shared/models/quick-filter.model";
+import { AgentOfStrictQuery, StrictQueryParams } from "~/shared/models/strict-query.model";
+import { AppointmentParams } from "~/shared/models/appointment.model";
+
+class QueryConsultantService {
+
+  // ��靽憿批��
+  async getRecommendConsultantList(): Promise<Consultant[]> {
+    return http.get<Consultant[]>('/consultant/recommend').then((res) => res.data);
+  }
+
+  // 敹恍�祟�
+  async fastQuery(data: FastQueryParams): Promise<Consultant[]> {
+    return http.post<Consultant[]>('/consultant/fastQuery', data).then(res => res.data);
+  }
+
+  // ������
+  async strictQuery(data:StrictQueryParams): Promise<AgentOfStrictQuery[]>{
+    return http.post('/consultant/strictQuery', data).then((res) => res.data);
+  }
+
+  // ��憿批��
+  async addFavoriteConsultant(agentNoList: string[]) {
+    return http.post('/consultant/favorite', { agentNoList });
+  }
+
+  // ����岷���
+  async appointmentDemand(data: AppointmentParams) {
+    return http.post('/appointment/customer/create', data);
+  }
+
+}
+
+export default new QueryConsultantService();
diff --git a/PAMapp/shared/services/reviews.service.ts b/PAMapp/shared/services/reviews.service.ts
new file mode 100644
index 0000000..0580c8b
--- /dev/null
+++ b/PAMapp/shared/services/reviews.service.ts
@@ -0,0 +1,18 @@
+import { http } from "./httpClient";
+
+import { UserReviewsConsultantsParams } from "../models/reviews.model";
+import { AppointmentLog } from "../models/appointment.model";
+
+class ReviewsService {
+
+  //摰X�脰�遛��漲閰��
+  userReviewsConsultants(data: UserReviewsConsultantsParams) {
+    return http.post('/satisfaction/create', data );
+  }
+  //������������
+  async getMyReviewLog(): Promise<AppointmentLog[]> {
+    return http.get('/satisfaction/getMySatisfaction').then(res => res.data);
+  }
+}
+
+export default new ReviewsService();
diff --git a/PAMapp/assets/ts/storageConsultant.ts b/PAMapp/shared/storageConsultant.ts
similarity index 100%
rename from PAMapp/assets/ts/storageConsultant.ts
rename to PAMapp/shared/storageConsultant.ts
diff --git a/PAMapp/assets/ts/storageRequests.ts b/PAMapp/shared/storageRequests.ts
similarity index 91%
rename from PAMapp/assets/ts/storageRequests.ts
rename to PAMapp/shared/storageRequests.ts
index 4b499a5..a50917f 100644
--- a/PAMapp/assets/ts/storageRequests.ts
+++ b/PAMapp/shared/storageRequests.ts
@@ -1,4 +1,4 @@
-import { AppointmentRequests } from "./api/consultant";
+import { AppointmentRequests } from "./models/appointment.model";
 
 export function getRequestsFromStorage(): AppointmentRequests {
   const requests = localStorage.getItem('myRequests');
diff --git a/PAMapp/store/index.ts b/PAMapp/store/index.ts
index 74ff925..25d55a2 100644
--- a/PAMapp/store/index.ts
+++ b/PAMapp/store/index.ts
@@ -1,15 +1,17 @@
+import { StrictQueryParams } from '~/shared/models/strict-query.model';
 import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators'
 
-import { getMyReviewLog } from '~/assets/ts/api/appointment';
-import { recommend, AgentOfStrictQuery, addFavoriteConsultant, deleteConsultant, strictQuery } from '~/assets/ts/api/consultant';
-import { getFavoriteFromStorage, setFavoriteToStorage } from '~/assets/ts/storageConsultant';
+import { getFavoriteFromStorage, setFavoriteToStorage } from '~/shared/storageConsultant';
 
-import myConsultantService from '~/assets/ts/services/my-consultant.service';
-import appointmentService from '~/assets/ts/services/appointment.service';
+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 '~/assets/ts/models/consultant.model';
-import { AppointmentLog } from '~/assets/ts/models/appointment.model';
-import { ClientInfo } from '~/assets/ts/models/client.model';
+import { Consultant } from '~/shared/models/consultant.model';
+import { AppointmentLog } from '~/shared/models/appointment.model';
+import { ClientInfo } from '~/shared/models/client.model';
+import { AgentOfStrictQuery } from '~/shared/models/strict-query.model';
 @Module
 export default class Store extends VuexModule {
     recommendList: Consultant[] = [];
@@ -57,7 +59,7 @@
 
     @Action
     storeRecommendList() {
-        recommend().then(data => {
+        queryConsultantService.getRecommendConsultantList().then(data => {
             this.context.commit('updateRecommend', data)
         })
     }
@@ -74,7 +76,7 @@
 
         if (localData?.length) {
             const agentNoList = localData.map(i => i.agentNo)
-            await addFavoriteConsultant(agentNoList).then(res => {
+            await queryConsultantService.addFavoriteConsultant(agentNoList).then(res => {
                 localStorage.removeItem('favoriteConsultant')
             })
         }
@@ -94,7 +96,7 @@
         if (!this.isUserLogin) {
             setFavoriteToStorage(left);
         } else {
-            await deleteConsultant(agentNo)
+            await myConsultantService.deleteConsultant(agentNo)
         }
 
         this.context.commit('updateConsultantList', left)
@@ -109,7 +111,7 @@
             if (!found) {
                 const newData = [consultantToAdd].concat(this.myConsultantList);
                 if (this.isUserLogin) {
-                    await addFavoriteConsultant([consultantToAdd.agentNo])
+                    await queryConsultantService.addFavoriteConsultant([consultantToAdd.agentNo])
                 } else {
                     setFavoriteToStorage(newData);
                 }
@@ -134,7 +136,7 @@
 
     @Action
     storeMyAppointmentReviewLog() {
-        getMyReviewLog().then((data) => {
+        reviewsService.getMyReviewLog().then((data) => {
             const dataWithLatestDate = data.map((item) => {
                 return {
                     ...item,
@@ -154,11 +156,11 @@
     }
 
     @Action
-    async storeStrictQueryList(strictQueryDto) {
-        return await strictQuery(strictQueryDto).then(res=>{
+    async storeStrictQueryList(strictQueryDto: StrictQueryParams) {
+        return await queryConsultantService.strictQuery(strictQueryDto).then(res=>{
             this.context.commit('localStorage/storageRecommendConsultant', JSON.stringify(strictQueryDto));
-            this.context.commit('updateStrictQueryList', res.data)
-            return res.data.length;
+            this.context.commit('updateStrictQueryList', res)
+            return res.length;
         });
     }
 
diff --git a/PAMapp/store/localStorage.ts b/PAMapp/store/localStorage.ts
index e31bf7c..aefef14 100644
--- a/PAMapp/store/localStorage.ts
+++ b/PAMapp/store/localStorage.ts
@@ -1,6 +1,6 @@
 import { Module, Mutation, VuexModule ,Action } from 'vuex-module-decorators';
-import { Role } from '~/assets/ts/models/enum/Role';
-import { Selected } from '~/assets/ts/models/quickFilter.model';
+import { Role } from '~/shared/models/enum/role';
+import { Selected } from '~/shared/models/quick-filter.model';
 @Module
 export default class LocalStorage extends VuexModule {
   id_token = localStorage.getItem('id_token');
diff --git a/pamapi/src/doc/sql/20211222_w.sql b/pamapi/src/doc/sql/20211222_w.sql
new file mode 100644
index 0000000..a6bdd67
--- /dev/null
+++ b/pamapi/src/doc/sql/20211222_w.sql
@@ -0,0 +1 @@
+ALTER TABLE omo.consultant ADD email varchar NULL;
diff --git a/pamapi/src/main/java/com/pollex/pam/config/ApplicationProperties.java b/pamapi/src/main/java/com/pollex/pam/config/ApplicationProperties.java
index 3841d13..fc204ce 100644
--- a/pamapi/src/main/java/com/pollex/pam/config/ApplicationProperties.java
+++ b/pamapi/src/main/java/com/pollex/pam/config/ApplicationProperties.java
@@ -18,6 +18,8 @@
     private String eServiceLoginUrl;
     private String eServiceLoginFunc;
     private String eServiceLoginSys;
+    private String frontEndDomain;
+    private boolean sendNotifyMsg;
     private SMS sms;
     private Email email;
 
@@ -75,6 +77,22 @@
 
     public void seteServiceLoginSys(String eServiceLoginSys) {
         this.eServiceLoginSys = eServiceLoginSys;
+    }
+
+    public String getFrontEndDomain() {
+        return frontEndDomain;
+    }
+
+    public void setFrontEndDomain(String frontEndDomain) {
+        this.frontEndDomain = frontEndDomain;
+    }
+
+    public boolean isSendNotifyMsg() {
+        return sendNotifyMsg;
+    }
+
+    public void setSendNotifyMsg(boolean sendNotifyMsg) {
+        this.sendNotifyMsg = sendNotifyMsg;
     }
 
     public SMS getSms() {
@@ -135,6 +153,7 @@
     public static class Email {
         private String url;
         private String functionId;
+        private String senderEmail;
 
         public String getUrl() {
             return url;
@@ -151,5 +170,13 @@
         public void setFunctionId(String functionId) {
             this.functionId = functionId;
         }
+
+        public String getSenderEmail() {
+            return senderEmail;
+        }
+
+        public void setSenderEmail(String senderEmail) {
+            this.senderEmail = senderEmail;
+        }
     }
 }
diff --git a/pamapi/src/main/java/com/pollex/pam/domain/Consultant.java b/pamapi/src/main/java/com/pollex/pam/domain/Consultant.java
index 60fcbf9..5071ff6 100644
--- a/pamapi/src/main/java/com/pollex/pam/domain/Consultant.java
+++ b/pamapi/src/main/java/com/pollex/pam/domain/Consultant.java
@@ -71,6 +71,9 @@
     @Column(name = "communication_style")
     private String communicationStyle;
 
+    @Column(name = "email")
+    private String email;
+
     public Long getId() {
         return id;
     }
@@ -230,6 +233,14 @@
         this.communicationStyle = communicationStyle;
     }
 
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
     @Override
     public String toString() {
         return "Consultant{" +
@@ -245,13 +256,14 @@
             ", gender=" + gender +
             ", phoneNumber='" + phoneNumber + '\'' +
             ", companyAddress='" + companyAddress + '\'' +
-            ", seniorityYear='" + seniorityYear + '\'' +
-            ", seniorityMonth='" + seniorityMonth + '\'' +
+            ", seniorityYear=" + seniorityYear +
+            ", seniorityMonth=" + seniorityMonth +
             ", concept='" + concept + '\'' +
             ", experience='" + experience + '\'' +
             ", award='" + award + '\'' +
             ", recommend=" + recommend +
             ", communicationStyle='" + communicationStyle + '\'' +
+            ", email='" + email + '\'' +
             '}';
     }
 }
diff --git a/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java b/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java
index 5b5cb33..ec045e3 100644
--- a/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java
+++ b/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java
@@ -53,12 +53,12 @@
 	@Autowired
 	SatisfactionService satisfactionService;
 
-	public void customerCreateAppointment(AppointmentCreateDTO appointmentCreateDTO) {
+	public Appointment customerCreateAppointment(AppointmentCreateDTO appointmentCreateDTO) {
 		Appointment appointment = appointmentDTOMapper.toAppointment(appointmentCreateDTO);
         appointment.setStatus(AVAILABLE);
 		appointment.setCustomerId(SecurityUtils.getCustomerDBId());
 		appointment.setCommunicateStatus(ContactStatusEnum.RESERVED);
-		appointmentRepository.save(appointment);
+		return appointmentRepository.save(appointment);
 	}
 
     public void updateAppointment(AppointmentUpdateDTO updateAppointmentDTO) {
diff --git a/pamapi/src/main/java/com/pollex/pam/service/SendMsgService.java b/pamapi/src/main/java/com/pollex/pam/service/SendMsgService.java
index 650fbac..eb758f6 100644
--- a/pamapi/src/main/java/com/pollex/pam/service/SendMsgService.java
+++ b/pamapi/src/main/java/com/pollex/pam/service/SendMsgService.java
@@ -1,16 +1,23 @@
 package com.pollex.pam.service;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.pollex.pam.config.ApplicationProperties;
 import com.pollex.pam.config.ApplicationProperties.SMS;
+import com.pollex.pam.domain.Appointment;
+import com.pollex.pam.repository.ConsultantRepository;
 import com.pollex.pam.service.dto.*;
 import com.pollex.pam.service.util.HttpRequestUtil;
 import com.pollex.pam.web.rest.errors.SendEmailFailException;
 import com.pollex.pam.web.rest.errors.SendSMSFailException;
+import io.jsonwebtoken.lang.Assert;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+import org.thymeleaf.context.Context;
+import org.thymeleaf.spring5.SpringTemplateEngine;
 
 import java.nio.charset.StandardCharsets;
 import java.time.LocalDateTime;
@@ -27,10 +34,95 @@
     private static final Logger log = LoggerFactory.getLogger(SendMsgService.class);
     private final Encoder encoder = Base64.getEncoder();
 
+    private static final String EMAIL_SUBJECT = "靽���像�蝟餌絞�嚗���";
+
     @Autowired
     ApplicationProperties applicationProperties;
 
-    public void sendMsgBySMS(String toMobile, String content) throws SendSMSFailException{
+    @Autowired
+    ConsultantRepository consultantRepository;
+
+    @Autowired
+    SpringTemplateEngine springTemplateEngine;
+
+    public void sendAppointmentNotify(Appointment appointment) {
+        Assert.notNull(appointment);
+
+        log.debug("is need sending notify msg = {}", applicationProperties.isSendNotifyMsg());
+        if(applicationProperties.isSendNotifyMsg()) {
+            log.debug("sending appointment notify, appointmentId = {}", appointment.getId());
+            sendAppointmentNotifyBySMS(appointment);
+            sendAppointmentNotifyByEmail(appointment);
+
+            // todo ��蝣箄�������瘙蝙�html mail
+            // sendAppointmentNotifyByHtmlEmail(appointment);
+        }
+    }
+
+    private void sendAppointmentNotifyBySMS(Appointment appointment) throws SendSMSFailException {
+        String msg = getAppointmentNotifyWording(appointment);
+        String consultantMobile = consultantRepository.findOneByAgentNo(appointment.getAgentNo()).get().getPhoneNumber();
+
+        try {
+            sendMsgBySMS(consultantMobile, msg);
+        } catch (SendSMSFailException e) {
+            log.debug("send sms failed, appointment Id = {}", appointment.getId(), e);
+        }
+    }
+
+    private void sendAppointmentNotifyByEmail(Appointment appointment) {
+        // todo ��敺靽�頂蝯勗�辣靽∠拳 (銝行�閮剖��葉)
+        String senderEmail = applicationProperties.getEmail().getSenderEmail();
+        String consultantEmail = consultantRepository.findOneByAgentNo(appointment.getAgentNo()).get().getEmail();
+        String content = getAppointmentNotifyWording(appointment);
+
+        try {
+            sendMsgByEmail(senderEmail, consultantEmail, EMAIL_SUBJECT, content, false);
+        } catch (SendEmailFailException e) {
+            log.debug("send email failed, appointment Id = {}", appointment.getId(), e);
+        }
+    }
+
+    private void sendAppointmentNotifyByHtmlEmail(Appointment appointment) {
+        // todo ��敺靽�頂蝯勗�辣靽∠拳 (銝行�閮剖��葉)
+        String senderEmail = applicationProperties.getEmail().getSenderEmail();
+        String consultantEmail = consultantRepository.findOneByAgentNo(appointment.getAgentNo()).get().getEmail();
+        String customerMobile = appointment.getPhone();
+        String normalContent;
+
+        if(StringUtils.hasText(customerMobile)) {
+            normalContent = "閬芣��“��憟踝����蝑�靽���像������嚗府摰X����Ⅳ�" + customerMobile + "\n";
+        }
+        else {
+            normalContent = "閬芣��“��憟踝����蝑�靽���像������\n";
+        }
+
+        Context context = new Context();
+        context.setVariable("content", normalContent);
+        context.setVariable("urlHint", getAppointmentDetailUrl(appointment.getId()));
+        String content = springTemplateEngine.process("mail/appointmentNotifyEmail", context);
+
+        try {
+            sendMsgByEmail(senderEmail, consultantEmail, EMAIL_SUBJECT, content, true);
+        } catch (SendEmailFailException e) {
+            log.debug("send email failed, appointment Id = {}", appointment.getId(), e);
+        }
+    }
+
+    private String getAppointmentNotifyWording(Appointment appointment) {
+        String normalContent;
+        if(StringUtils.hasText(appointment.getPhone())) {
+            normalContent = "閬芣��“��憟踝����蝑�靽���像������嚗府摰X����Ⅳ�" + appointment.getPhone() + "\n";
+        }
+        else {
+            normalContent = "閬芣��“��憟踝����蝑�靽���像������\n";
+        }
+
+        String urlContent = "暺�雯��嚗�" + getAppointmentDetailUrl(appointment.getId()) + " �����像������";
+        return normalContent + urlContent;
+    }
+
+    public SendSMSResponse sendMsgBySMS(String toMobile, String content) throws SendSMSFailException {
         SMS smsProperties = applicationProperties.getSms();
 
         SendSMSRequest sendSMSRequest = new SendSMSRequest();
@@ -54,6 +146,7 @@
             log.debug("response status code = {}", responseEntity.getStatusCode());
             log.debug("smsResponse = {}", responseEntity.getBody());
 
+            return responseEntity.getBody();
             // todo ����閬�����隤方������葫��
         }
         catch (Exception e) {
@@ -62,11 +155,20 @@
         }
     }
 
-    public void sendMsgByEmail(String from, String to, String subject, String content, boolean htmlFormat) throws SendEmailFailException{
-        sendMsgByEmail(from, to, subject, content, htmlFormat, Collections.emptyList(), Collections.emptyList());
+    public String sendMsgByHtmlTestTemplateEmail(String from, String to) {
+        Context context = new Context();
+        context.setVariable("content", "閬芣��“��憟踝����蝑�靽���像������\n");
+        context.setVariable("urlHint", getAppointmentDetailUrl(0L));
+
+        String content = springTemplateEngine.process("mail/appointmentNotifyEmail", context);
+        return sendMsgByEmail(from, to, EMAIL_SUBJECT, content, true);
     }
 
-    public void sendMsgByEmail(
+    public String sendMsgByEmail(String from, String to, String subject, String content, boolean htmlFormat) throws SendEmailFailException{
+        return sendMsgByEmail(from, to, subject, content, htmlFormat, Collections.emptyList(), Collections.emptyList());
+    }
+
+    public String sendMsgByEmail(
         String fromAddress, String toAddress, String subject, String content, boolean htmlFormat, List<String> toCCAddress,
         List<String> attachments) throws SendEmailFailException
     {
@@ -80,21 +182,23 @@
         sendMailRequest.setHtmlFormat(htmlFormat);
         sendMailRequest.setFunctionId(applicationProperties.getEmail().getFunctionId());
 
-        sendMsgByEmail(sendMailRequest);
+        return sendMsgByEmail(sendMailRequest);
     }
 
-    public void sendMsgByEmail(SendMailRequest sendMailRequest) throws SendEmailFailException{
+    private String sendMsgByEmail(SendMailRequest sendMailRequest) throws SendEmailFailException{
         try {
-            ResponseEntity<SendMailResponse> responseEntity =
-                HttpRequestUtil.postWithJson( applicationProperties.getEmail().getUrl(), sendMailRequest, SendMailResponse.class);
+            ResponseEntity<String> responseEntity =
+                HttpRequestUtil.postWithJson( applicationProperties.getEmail().getUrl(), sendMailRequest, String.class);
+            log.debug("responseEntity = {}", responseEntity);
 
-            SendMailResponse sendMailResponse = responseEntity.getBody();
-            log.debug("response status code = {}", responseEntity.getStatusCode());
-            log.debug("emailResponse = {}", responseEntity.getBody());
+            SendMailResponse sendMailResponse = new ObjectMapper().readValue(responseEntity.getBody(), SendMailResponse.class);
+            log.debug("sendMailResponse = {}", sendMailResponse);
 
-            if(sendMailResponse == null || sendMailResponse.getData() == null || "ADDED".equalsIgnoreCase(sendMailResponse.getData().getMessageStatus())) {
-                throw new SendEmailFailException();
-            }
+//            if(sendMailResponse == null || sendMailResponse.getData() == null || "ADDED".equalsIgnoreCase(sendMailResponse.getData().getMessageStatus())) {
+//                throw new SendEmailFailException();
+//            }
+
+            return responseEntity.getBody();
         }
         catch (SendEmailFailException e) {
             throw e;
@@ -104,4 +208,8 @@
             throw new SendEmailFailException();
         }
     }
+
+    private String getAppointmentDetailUrl(Long appointmentId) {
+        return applicationProperties.getFrontEndDomain() + "/myAppointmentList/contactedList?appointmentId=" + appointmentId;
+    }
 }
diff --git a/pamapi/src/main/java/com/pollex/pam/service/dto/SendMailResponse.java b/pamapi/src/main/java/com/pollex/pam/service/dto/SendMailResponse.java
index 808dcf6..aee72f7 100644
--- a/pamapi/src/main/java/com/pollex/pam/service/dto/SendMailResponse.java
+++ b/pamapi/src/main/java/com/pollex/pam/service/dto/SendMailResponse.java
@@ -1,5 +1,8 @@
 package com.pollex.pam.service.dto;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class SendMailResponse {
     private Data data;
 
@@ -11,6 +14,7 @@
         this.data = data;
     }
 
+    @JsonIgnoreProperties(ignoreUnknown = true)
     public static class Data {
         private String messageStatus;
 
diff --git a/pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java b/pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java
index 1704d11..38592f3 100644
--- a/pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java
+++ b/pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java
@@ -1,5 +1,7 @@
 package com.pollex.pam.web.rest;
 
+import com.pollex.pam.domain.Appointment;
+import com.pollex.pam.service.SendMsgService;
 import com.pollex.pam.service.dto.AppointmentUpdateDTO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
@@ -20,6 +22,9 @@
 	@Autowired
 	SatisfactionService satisfactionService;
 
+    @Autowired
+    SendMsgService sendMsgService;
+
     @PutMapping("")
     public ResponseEntity<Void> updateAppointment(@RequestBody AppointmentUpdateDTO appointment) {
         appointmentService.updateAppointment(appointment);
@@ -34,8 +39,9 @@
 
 	@PostMapping("/customer/create")
 	public void clientCreateAppointment(@RequestBody AppointmentCreateDTO appointmentCreateDTO) {
-		appointmentService.customerCreateAppointment(appointmentCreateDTO);
-	}
+        Appointment appointment = appointmentService.customerCreateAppointment(appointmentCreateDTO);
+        sendMsgService.sendAppointmentNotify(appointment);
+    }
 
 	@PostMapping("/markAsContacted/{appointmentId}")
 	public void markAsContacted(@PathVariable Long appointmentId) {
diff --git a/pamapi/src/main/java/com/pollex/pam/web/rest/TestSendMsgResource.java b/pamapi/src/main/java/com/pollex/pam/web/rest/TestSendMsgResource.java
index c9ff370..461ea06 100644
--- a/pamapi/src/main/java/com/pollex/pam/web/rest/TestSendMsgResource.java
+++ b/pamapi/src/main/java/com/pollex/pam/web/rest/TestSendMsgResource.java
@@ -1,6 +1,8 @@
 package com.pollex.pam.web.rest;
 
+import com.pollex.pam.repository.AppointmentRepository;
 import com.pollex.pam.service.SendMsgService;
+import com.pollex.pam.service.dto.SendSMSResponse;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
@@ -13,21 +15,35 @@
     @Autowired
     SendMsgService sendMsgService;
 
+    @Autowired
+    AppointmentRepository appointmentRepository;
+
     @GetMapping("/bySMS")
-    public ResponseEntity<Void> bySMS(@RequestParam String toMobile, @RequestParam String content) {
-        sendMsgService.sendMsgBySMS(toMobile, content);
-        return ResponseEntity.noContent().build();
+    public ResponseEntity<SendSMSResponse> bySMS(@RequestParam String toMobile, @RequestParam String content) {
+        return ResponseEntity.ok(sendMsgService.sendMsgBySMS(toMobile, content));
     }
 
     @GetMapping("/byEmail")
-    public ResponseEntity<Void> byEmail(
+    public ResponseEntity<String> byEmail(
         @RequestParam String from,
         @RequestParam String to,
         @RequestParam String subject,
         @RequestParam String content,
         @RequestParam boolean htmlFormat
     ) {
-        sendMsgService.sendMsgByEmail(from, to, subject, content, htmlFormat);
-        return ResponseEntity.noContent().build();
+        return ResponseEntity.ok(sendMsgService.sendMsgByEmail(from, to, subject, content, htmlFormat));
+    }
+
+    @GetMapping("/byHtmlEmail")
+    public ResponseEntity<String> byHtmlEmail(
+        @RequestParam String from,
+        @RequestParam String to
+    ) {
+        return ResponseEntity.ok(sendMsgService.sendMsgByHtmlTestTemplateEmail(from, to));
+    }
+
+    @GetMapping("/appointment/{appointmentId}")
+    public void sendAppointmentNotify(@PathVariable Long appointmentId) {
+        sendMsgService.sendAppointmentNotify(appointmentRepository.findById(appointmentId).get());
     }
 }
diff --git a/pamapi/src/main/java/com/pollex/pam/web/rest/errors/SendSMSFailException.java b/pamapi/src/main/java/com/pollex/pam/web/rest/errors/SendSMSFailException.java
index acfeda4..0b721ab 100644
--- a/pamapi/src/main/java/com/pollex/pam/web/rest/errors/SendSMSFailException.java
+++ b/pamapi/src/main/java/com/pollex/pam/web/rest/errors/SendSMSFailException.java
@@ -3,7 +3,7 @@
 import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.ResponseStatus;
 
-@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR, reason = "send email failed")
+@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR, reason = "send sms failed")
 public class SendSMSFailException extends RuntimeException{
     public SendSMSFailException(){}
     public SendSMSFailException(String message) {
diff --git a/pamapi/src/main/resources/config/application-dev.yml b/pamapi/src/main/resources/config/application-dev.yml
index ddf5c77..66b939b 100644
--- a/pamapi/src/main/resources/config/application-dev.yml
+++ b/pamapi/src/main/resources/config/application-dev.yml
@@ -119,6 +119,8 @@
   e-service-login-url: https://eserviceuat.pcalife.com.tw/sso/chatbotValidate
   e-service-login-func: ValidateUsrLogin
   e-service-login-sys: epos
+  front-end-domain: http://localhost:3000
+  send-notify-msg: false
   sms:
     url: https://localhost:8081/testSMS
     source-code: ePos
@@ -127,3 +129,4 @@
   email:
     url: https://localhost:8081/testEmail
     function-id: epos
+    sender-email: test@pollex.com.tw
diff --git a/pamapi/src/main/resources/config/application-pollex.yml b/pamapi/src/main/resources/config/application-pollex.yml
index 005cba7..800d738 100644
--- a/pamapi/src/main/resources/config/application-pollex.yml
+++ b/pamapi/src/main/resources/config/application-pollex.yml
@@ -117,3 +117,14 @@
   e-service-login-url: https://eserviceuat.pcalife.com.tw/sso/chatbotValidate
   e-service-login-func: ValidateUsrLogin
   e-service-login-sys: epos
+  front-end-domain: http://dev.pollex.com.tw:5566/pam
+  send-notify-msg: false
+  sms:
+    url: https://localhost:8081/testSMS
+    source-code: ePos
+    sender: POS
+    sms-type: '0017'
+  email:
+    url: https://localhost:8081/testEmail
+    function-id: epos
+    sender-email: test@pollex.com.tw
diff --git a/pamapi/src/main/resources/config/application-sit.yml b/pamapi/src/main/resources/config/application-sit.yml
index 26a2198..908d753 100644
--- a/pamapi/src/main/resources/config/application-sit.yml
+++ b/pamapi/src/main/resources/config/application-sit.yml
@@ -117,6 +117,8 @@
   e-service-login-url: https://eserviceuat.pcalife.com.tw/sso/chatbotValidate
   e-service-login-func: ValidateUsrLogin
   e-service-login-sys: epos
+  front-end-domain: https://vtwlifeopensyssit.pru.intranet.asia/pam
+  send-notify-msg: true
   sms:
     url: https://vtwlifewinbo66.pru.intranet.asia/MesgQueueMgmnt/rest/smsSendMsgResource
     source-code: ePos
@@ -125,3 +127,4 @@
   email:
     url: https://vtwlifeopensysuat.pru.intranet.asia/tsgw/mq/mqSendMail
     function-id: epos
+    sender-email: test@pollex.com.tw
diff --git a/pamapi/src/main/resources/config/application-uat.yml b/pamapi/src/main/resources/config/application-uat.yml
index e23f9ac..a6b85d7 100644
--- a/pamapi/src/main/resources/config/application-uat.yml
+++ b/pamapi/src/main/resources/config/application-uat.yml
@@ -117,6 +117,8 @@
   e-service-login-url: https://eserviceuat.pcalife.com.tw/sso/chatbotValidate
   e-service-login-func: ValidateUsrLogin
   e-service-login-sys: epos
+  front-end-domain: https://vtwlifeopensysuat.pru.intranet.asia/pam
+  send-notify-msg: true
   sms:
     url: https://vtwlifewinbo66.pru.intranet.asia/MesgQueueMgmnt/rest/smsSendMsgResource
     source-code: ePos
@@ -125,3 +127,4 @@
   email:
     url: https://vtwlifeopensysuat.pru.intranet.asia/tsgw/mq/mqSendMail
     function-id: epos
+    sender-email: test@pollex.com.tw
diff --git a/pamapi/src/main/resources/templates/mail/appointmentNotifyEmail.html b/pamapi/src/main/resources/templates/mail/appointmentNotifyEmail.html
new file mode 100644
index 0000000..644a43a
--- /dev/null
+++ b/pamapi/src/main/resources/templates/mail/appointmentNotifyEmail.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org" lang="zh">
+  <head>
+    <title>������</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  </head>
+  <body>
+    <p th:text="${content}">閬芣��“��憟踝����蝑�靽���像������</p>
+    <p>
+      暺�雯��嚗�
+      <a th:href="${urlHint}" th:text="${urlHint}">Url Position</a>
+      �����像�����
+    </p>
+  </body>
+</html>

--
Gitblit v1.8.0