From 5730601f103ea285d129bf3d89acd649e86c114a Mon Sep 17 00:00:00 2001 From: Tomas <tomasysh@gmail.com> Date: 星期三, 08 十二月 2021 10:17:44 +0800 Subject: [PATCH] separate vue files --- PAMapp/components/QuickFilter/QuickFilterSelector.vue | 11 PAMapp/pages/consultantLogin/index.vue | 202 -- PAMapp/pages/myAppointmentList/my-appointment.component.ts | 63 PAMapp/pages/quickFilter/quick-filter.component.ts | 144 + PAMapp/pages/myConsultantList/my-consultant-list.component.ts | 28 PAMapp/pages/accountSetting/index.vue | 255 -- PAMapp/assets/ts/models/fast-query-params.model.ts | 6 PAMapp/pages/myAppointmentList/appointmentList/appointment-list.component.ts | 26 PAMapp/pages/myAppointmentList/my-appointment.component.scss | 26 PAMapp/pages/record/record.component.scss | 44 PAMapp/pages/recommendConsultant/result/index.vue | 88 PAMapp/pages/accountSetting/account-setting.component.scss | 118 + PAMapp/pages/myAppointmentList/appointmentList/index.vue | 29 PAMapp/pages/myConsultantList/my-consultant-list.component.scss | 0 PAMapp/pages/myConsultantList/consultantList/consultant-list.component.ts | 16 PAMapp/assets/ts/models/agentInfo.model.ts | 19 PAMapp/pages/questionnaire/_agentNo.vue | 395 ---- PAMapp/pages/login/login.component.ts | 373 ++++ PAMapp/assets/ts/models/enum/role.enum.ts | 0 PAMapp/components/NavBar.vue | 9 PAMapp/pages/agentInfo/_agentNo.vue | 124 - PAMapp/pages/quickFilter/quick-filter.component.scss | 52 PAMapp/pages/record/record.component.ts | 23 PAMapp/assets/ts/models/selected.model.ts | 4 PAMapp/pages/accountSetting/account-setting.component.ts | 98 + PAMapp/pages/myConsultantList/contactedList/contacted-list.component.ts | 13 PAMapp/pages/recommendConsultant/recommend-consultant.component.ts | 183 + PAMapp/store/localStorage.ts | 2 PAMapp/pages/consultantLogin/consultant-login.component.scss | 77 PAMapp/pages/recommendConsultant/recommend-consultant.component.scss | 291 +++ PAMapp/pages/login/login.component.scss | 97 + PAMapp/pages/login/index.vue | 474 ----- PAMapp/pages/myAppointmentList/index.vue | 45 PAMapp/pages/recommendConsultant/result/recommend-consultant-result.component.ts | 32 PAMapp/pages/userReviews/user-reviews.component.scss | 103 + PAMapp/pages/myAppointmentList/contactedList/index.vue | 33 PAMapp/pages/myConsultantList/contactedList/contacted-list.component.scss | 0 PAMapp/pages/myAppointmentList/contactedList/contacted-list.component.scss | 0 PAMapp/pages/record/index.vue | 83 PAMapp/assets/ts/models/strict-query-dto.model.ts | 11 PAMapp/pages/myAppointmentList/appointmentList/appointment-list.component.scss | 0 PAMapp/assets/scss/utilities/_utilities.scss | 12 PAMapp/assets/ts/models/enum/gender.enum.ts | 2 PAMapp/pages/agentInfo/agent-info.component.ts | 54 PAMapp/pages/userReviews/user-reviews.component.ts | 43 PAMapp/pages/userReviews/index.vue | 171 - PAMapp/pages/recommendConsultant/result/recommend-consultant-result.component.scss | 114 + PAMapp/assets/ts/api/consultant.ts | 8 PAMapp/assets/ts/models/question-option.model.ts | 12 PAMapp/pages/questionnaire/questionnaire.component.scss | 159 + PAMapp/pages/quickFilter/index.vue | 213 -- PAMapp/pages/consultantLogin/consultant-login.component.ts | 103 + PAMapp/pages/myConsultantList/consultantList/index.vue | 18 PAMapp/pages/questionnaire/questionnaire.component.ts | 228 ++ PAMapp/pages/myAppointmentList/contactedList/contacted-list.component.ts | 34 PAMapp/pages/myConsultantList/consultantList/consultant-list.component.scss | 0 PAMapp/components/BackActionBar.vue | 2 /dev/null | 113 - PAMapp/pages/agentInfo/agent-info.component.scss | 48 PAMapp/pages/recommendConsultant/index.vue | 493 ----- PAMapp/assets/ts/models/reviews-item.model.ts | 5 PAMapp/pages/myConsultantList/contactedList/contactedList.vue | 18 PAMapp/pages/myConsultantList/index.vue | 41 63 files changed, 2,942 insertions(+), 2,546 deletions(-) diff --git a/PAMapp/assets/scss/utilities/_utilities.scss b/PAMapp/assets/scss/utilities/_utilities.scss index 877b5dc..aaa7494 100644 --- a/PAMapp/assets/scss/utilities/_utilities.scss +++ b/PAMapp/assets/scss/utilities/_utilities.scss @@ -13,6 +13,10 @@ margin-top: 20px; } +.mt-25 { + margin-top: 25px; +} + .mb-30 { margin-bottom: 30px; } @@ -89,8 +93,16 @@ padding: 20px 30px 40px 30px; } +.w-55 { + width: 55% !important; +} + @for $fontSize from 12 through 45 { .fs-#{$fontSize} { font-size: #{$fontSize} + 'px'; } } + +.position-r { + position: relative; +} diff --git a/PAMapp/assets/ts/api/consultant.ts b/PAMapp/assets/ts/api/consultant.ts index a797075..768e0b7 100644 --- a/PAMapp/assets/ts/api/consultant.ts +++ b/PAMapp/assets/ts/api/consultant.ts @@ -5,6 +5,7 @@ import _ from 'lodash'; import { UserSetting } from '../models/account.model'; import { Consultant } from '~/assets/ts/models/consultant.model'; +import { FastQueryParams } from '../models/fast-query-params.model'; // 憿批恥��(TODO: OTP隤����� ���蝙�) export function login(user: any) { @@ -131,13 +132,6 @@ Authorization: 'Bearer ' + localStorage.getItem('id_token') } return service.post('/satisfaction/create', data ,{headers}); -} - -export interface FastQueryParams { - gender : string, - communicationStyles: string[], - avgScore : number, - status : string } export interface AppointmentRequests { diff --git a/PAMapp/assets/ts/models/agentInfo.model.ts b/PAMapp/assets/ts/models/agentInfo.model.ts new file mode 100644 index 0000000..1db440e --- /dev/null +++ b/PAMapp/assets/ts/models/agentInfo.model.ts @@ -0,0 +1,19 @@ +export interface AgentInfo { + name : string; + agentNo : string; + role : string; + image : string; + avgScore : number; + title : string; + phoneNumber : string; + serveArea : string; + companyAddress : string; + latestLoginTime: Date | null; + seniority : string; + suitability : number; + evaluation : number; + expertiseList : string[]; + concept : string; + experiences : string[]; + awards : string; +} diff --git a/PAMapp/assets/ts/models/enum/Gender.ts b/PAMapp/assets/ts/models/enum/gender.enum.ts similarity index 97% rename from PAMapp/assets/ts/models/enum/Gender.ts rename to PAMapp/assets/ts/models/enum/gender.enum.ts index b9f84ed..126da1e 100644 --- a/PAMapp/assets/ts/models/enum/Gender.ts +++ b/PAMapp/assets/ts/models/enum/gender.enum.ts @@ -1,4 +1,4 @@ export enum Gender{ MALE="male", FEMALE="female", -} \ No newline at end of file +} diff --git a/PAMapp/assets/ts/models/enum/Role.ts b/PAMapp/assets/ts/models/enum/role.enum.ts similarity index 100% rename from PAMapp/assets/ts/models/enum/Role.ts rename to PAMapp/assets/ts/models/enum/role.enum.ts diff --git a/PAMapp/assets/ts/models/fast-query-params.model.ts b/PAMapp/assets/ts/models/fast-query-params.model.ts new file mode 100644 index 0000000..01f8030 --- /dev/null +++ b/PAMapp/assets/ts/models/fast-query-params.model.ts @@ -0,0 +1,6 @@ +export interface FastQueryParams { + gender : string, + communicationStyles: string[], + avgScore : number, + status : string +} diff --git a/PAMapp/assets/ts/models/question-option.model.ts b/PAMapp/assets/ts/models/question-option.model.ts new file mode 100644 index 0000000..356674d --- /dev/null +++ b/PAMapp/assets/ts/models/question-option.model.ts @@ -0,0 +1,12 @@ +export interface QuestionOption { + title: string; + detail: Detail[]; + type: string; + name: string; +} + +interface Detail { + value: string; + name?: string; + className: string; +} diff --git a/PAMapp/assets/ts/models/reviews-item.model.ts b/PAMapp/assets/ts/models/reviews-item.model.ts new file mode 100644 index 0000000..db0bafe --- /dev/null +++ b/PAMapp/assets/ts/models/reviews-item.model.ts @@ -0,0 +1,5 @@ +export interface ReviewsItem { + avatar : any; + name : string; + avgScore: number; +} diff --git a/PAMapp/assets/ts/models/selected.model.ts b/PAMapp/assets/ts/models/selected.model.ts new file mode 100644 index 0000000..ee3bf1a --- /dev/null +++ b/PAMapp/assets/ts/models/selected.model.ts @@ -0,0 +1,4 @@ +export interface Selected { + option: string; + value: any; +} diff --git a/PAMapp/assets/ts/models/strict-query-dto.model.ts b/PAMapp/assets/ts/models/strict-query-dto.model.ts new file mode 100644 index 0000000..102e2af --- /dev/null +++ b/PAMapp/assets/ts/models/strict-query-dto.model.ts @@ -0,0 +1,11 @@ +export interface StrictQueryDto { + gender : string, + area : string, + status : string, + requirements : string[], + otherRequirement: string, + seniority : string, + avgScore : number, + popularTags : string[], + otherPopularTags: string +} diff --git a/PAMapp/components/BackActionBar.vue b/PAMapp/components/BackActionBar.vue index ea00720..a26b20f 100644 --- a/PAMapp/components/BackActionBar.vue +++ b/PAMapp/components/BackActionBar.vue @@ -9,7 +9,7 @@ <script lang="ts"> import { namespace, Watch } from 'nuxt-property-decorator'; import { Vue, Component,} from 'vue-property-decorator'; -import { Role } from '~/assets/ts/models/enum/Role'; +import { Role } from '~/assets/ts/models/enum/role.enum'; import * as _ from 'lodash'; import { isLogin } from '~/assets/ts/auth'; diff --git a/PAMapp/components/NavBar.vue b/PAMapp/components/NavBar.vue index c3fc5b3..111e909 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 '~/assets/ts/models/enum/role.enum'; import * as _ from 'lodash'; const roleStorage = namespace('localStorage'); @@ -63,13 +63,8 @@ title: '���董�����', }, { - authorityOfRoleList:[Role.ADMIN], + authorityOfRoleList:[Role.ADMIN, Role.USER], routeUrl: '/record', - title: '�������', - }, - { - authorityOfRoleList: [Role.USER], - routeUrl: '/userReviewsRecord', title: '�������', }, { diff --git a/PAMapp/components/QuickFilter/QuickFilterSelector.vue b/PAMapp/components/QuickFilter/QuickFilterSelector.vue index 915eca1..977d802 100644 --- a/PAMapp/components/QuickFilter/QuickFilterSelector.vue +++ b/PAMapp/components/QuickFilter/QuickFilterSelector.vue @@ -65,8 +65,9 @@ <script lang="ts"> import { Vue, Component, Prop, Watch, Emit } from 'nuxt-property-decorator'; -import { FastQueryParams } from '~/assets/ts/api/consultant'; -import { QuestionOption } from '~/pages/quickFilter/index.vue'; +import { FastQueryParams } from '~/assets/ts/models/fast-query-params.model'; +import { Selected } from '~/assets/ts/models/selected.model'; +import { QuestionOption } from '~/assets/ts/models/question-option.model'; @Component export default class QuickFilterDrawer extends Vue { @@ -131,10 +132,6 @@ } -export interface Selected { - option: string; - value: any; -} </script> <style lang="scss" scoped> @@ -146,4 +143,4 @@ flex-wrap: wrap; } -</style> \ No newline at end of file +</style> diff --git a/PAMapp/pages/accountSetting/account-setting.component.scss b/PAMapp/pages/accountSetting/account-setting.component.scss new file mode 100644 index 0000000..e32f0e0 --- /dev/null +++ b/PAMapp/pages/accountSetting/account-setting.component.scss @@ -0,0 +1,118 @@ +.account-page{ + .block{ + display: flex; + } + .account-page-title{ + font-size: 20px; + margin-bottom: 34px; + } + .account-card{ + display: flex; + flex-direction: column; + border-bottom: 1px solid gray; + margin-bottom: 33px; + .contact-type{ + width: 184px; + margin-right: 16px; + font-size: 20px; + display: flex; + flex-direction: column; + align-items: flex-start; + } + &.edit { + input { + border: 1px solid lightgray; + background-color: #fff; + } + } + } + .account-setting-btn{ + display: flex; + justify-content: center; + } +} +.error-txt{ + padding-bottom: 10px; + .error { + @extend .smTxt_bold; + @extend .text--primary; + height: 16px; + } +} +.name-input{ + width: 184px; + height:27px; + margin-bottom: 20px; + font-size: 20px; + margin-top: -3px; + } +.setting-title{ + margin-left: 28px; + margin-bottom:10px; + width: 58px; + font-size: 20px; + } +.header{ + display: flex; + align-items: baseline; +} +.contact-input{ + font-size: 20px; + margin-bottom: 10px; + text-overflow: ellipsis; + margin-top: 10px; + width: 184px; +} +.input{ + border: 0; + background-color: rgba(0,0,0,0) ; + outline-color: gainsboro; +} +.input:focus{ + background-color: #fff; +} +.icon-color-change{ + color:$PRIMARY_RED; + font-size: 20px; +} +.icon{ + font-size:20px; + // color:#1B365D; +} +@include desktop{ + + .header{ + display: flex; + align-items: baseline; + justify-content: space-between; + } + .setting-title{ + margin-bottom:10px; + width: 58px; + font-size: 18px; + font-weight: bold; + } + .account-page{ + .account-page-title{ + font-size: 20px; + margin-bottom: 34px; + font-weight: bold; + } + } + .account-card{ + display: flex; + flex-direction: column; + border-bottom: 1px solid gray; + margin-bottom: 33px; + .contact-type{ + margin-left: 10px; + font-size: 20px; + } + } + .name-input{ + width: 550px; + } + .contact-input{ + width:550px + } + } diff --git a/PAMapp/pages/accountSetting/account-setting.component.ts b/PAMapp/pages/accountSetting/account-setting.component.ts new file mode 100644 index 0000000..79dad96 --- /dev/null +++ b/PAMapp/pages/accountSetting/account-setting.component.ts @@ -0,0 +1,98 @@ + +import { Vue,Component } from 'vue-property-decorator' +import { getUserAccountSetting, updateAccountSetting } from '~/assets/ts/api/consultant'; +import { UserSetting } from '~/assets/ts/models/account.model'; + +@Component +export default class AccountSetting extends Vue { + _userSetting!: UserSetting; + userNameDisabled = true; + userPhoneDisabled = true; + userEmailDisabled = true ; + userNameValue = ''; + phoneValue = '' ; + emailValue = '' ; + + onEditMode = false; + formValidStatus = { + name: true, + phone: true, + email: true, + }; + + get nameValid(): boolean { + this.formValidStatus.name = this.userNameValue ? true : false; + return this.formValidStatus.name; + } + + get phoneValid(): boolean { + const rule = /^09[0-9]{8}$/; + this.formValidStatus.phone = this.phoneValue ? rule.test(this.phoneValue) : true; + return this.formValidStatus.phone; + } + + get emailValid(): boolean { + const rule = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; + this.formValidStatus.email = this.emailValue ? rule.test(this.emailValue) : true;; + return this.formValidStatus.email; + } + + editField(fieldName: string): void { + this.onEditMode = true; + const enablePromise = new Promise((resolve, reject) => { // 甇斤promise隤�� + resolve((this as any)[`${fieldName}Disabled`] = false); + }); + const targetInput = this.$refs[fieldName] as any; + enablePromise.then((_) => { + targetInput.focus(); + }); + } + + get isSubmitBtnDisabled(): boolean { + const isFormValid = this.formValidStatus.name && this.formValidStatus.phone && this.formValidStatus.email; + return !isFormValid || !this.onEditMode + || (!this.phoneValue && !this.emailValue); + } + + updateAccountSetting(): void { + // const dataChanged = (): boolean => { + // return this._userSetting.name !== this.userNameValue + // || this._userSetting.phone !== this.phoneValue + // || this._userSetting.email !== this.emailValue; + // }; + // if (dataChanged) { + + // } + if (!this.onEditMode) return; + const editSettingInfo: UserSetting = { + name: this.userNameValue, + phone: this.phoneValue, + email: this.emailValue + } + updateAccountSetting(editSettingInfo).then((res: any) => { + this.resetSettingForm(); + }); + } + + private resetSettingForm(): void { + this.onEditMode = false; + this.userNameDisabled = true; + this.userPhoneDisabled = true; + this.userEmailDisabled = true ; + } + + mounted(){ + getUserAccountSetting().then((userInfo: UserSetting)=>{ + this._userSetting = { + name: userInfo.name || '', + phone: userInfo.phone || '', + email: userInfo.email || '', + }; + + this.phoneValue = this._userSetting.phone!; + this.userNameValue = this._userSetting.name!; + this.emailValue = this._userSetting.email!; + }) + } + +} diff --git a/PAMapp/pages/accountSetting/index.vue b/PAMapp/pages/accountSetting/index.vue index fb21f19..8c4a31e 100644 --- a/PAMapp/pages/accountSetting/index.vue +++ b/PAMapp/pages/accountSetting/index.vue @@ -1,14 +1,14 @@ <template> <div class="account-page"> <div class="account-page-title">�犖撣唾�身摰�</div> - <section class="account-card" :class="{'edit': !userNameDisabled }"> + <section class="account-card" :class="{'edit': !userNameDisabled }"> <div class="header"> <div class="block"> <div class="setting-title">憪��</div> <div class="contact-type"> <input :disabled="userNameDisabled" - v-model="userNameValue" + v-model="userNameValue" ref="userName" class="input name-input" > @@ -16,22 +16,22 @@ <span v-show="!nameValid" class="error">甇斗���‵</span> </div> </div> - + </div> <i class="icon-edit icon" @click="editField('userName')" :class="{'icon-color-change': !userNameDisabled}"></i> </div> - + </section> - <section class="account-card" :class="{'edit': !userPhoneDisabled }" v-if="phoneValue"> + <section class="account-card" :class="{'edit': !userPhoneDisabled }" v-if="phoneValue"> <div class="header"> - <div class="block"> + <div class="block"> <div class="setting-title">蝬��</div> <div class="contact-type"> ����Ⅳ <input :disabled="userPhoneDisabled" - v-model="phoneValue" + v-model="phoneValue" :class="{ 'is-invalid': !phoneValid }" @@ -44,19 +44,19 @@ </div> </div> </div> - <!-- <i class="icon-edit icon" + <!-- <i class="icon-edit icon" @click="editField('userPhone')" :class="{'icon-color-change': !userPhoneDisabled}"></i> --> </div> - + </section> - <section class="account-card" :class="{'edit': !userEmailDisabled }" v-if="emailValue"> + <section class="account-card" :class="{'edit': !userEmailDisabled }" v-if="emailValue"> <div class="header"> <div class="block"> <div class="setting-title">蝬��</div> <div class="contact-type">Email - <input + <input :disabled="userEmailDisabled" v-model="emailValue" :class="{ @@ -71,15 +71,15 @@ </div> </div> </div> - - <!-- <i class="icon-edit icon" @click="editField('userEmail')" + + <!-- <i class="icon-edit icon" @click="editField('userEmail')" :class="{'icon-color-change': !userEmailDisabled}"></i> --> </div> - + </section> <div class="account-setting-btn mb-30"> - <el-button + <el-button :disabled="isSubmitBtnDisabled" @click.native="updateAccountSetting">�</el-button> </div> @@ -87,227 +87,8 @@ </div> </template> -<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'; - -@Component -export default class AccountSetting extends Vue { - _userSetting!: UserSetting; - userNameDisabled = true; - userPhoneDisabled = true; - userEmailDisabled = true ; - userNameValue = ''; - phoneValue = '' ; - emailValue = '' ; - - onEditMode = false; - formValidStatus = { - name: true, - phone: true, - email: true, - }; - - get nameValid(): boolean { - this.formValidStatus.name = this.userNameValue ? true : false; - return this.formValidStatus.name; - } - - get phoneValid(): boolean { - const rule = /^09[0-9]{8}$/; - this.formValidStatus.phone = this.phoneValue ? rule.test(this.phoneValue) : true; - return this.formValidStatus.phone; - } - - get emailValid(): boolean { - const rule = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; - this.formValidStatus.email = this.emailValue ? rule.test(this.emailValue) : true;; - return this.formValidStatus.email; - } - - editField(fieldName: string): void { - this.onEditMode = true; - const enablePromise = new Promise((resolve, reject) => { // 甇斤promise隤�� - resolve((this as any)[`${fieldName}Disabled`] = false); - }); - const targetInput = this.$refs[fieldName] as any; - enablePromise.then((_) => { - targetInput.focus(); - }); - } - - get isSubmitBtnDisabled(): boolean { - const isFormValid = this.formValidStatus.name && this.formValidStatus.phone && this.formValidStatus.email; - return !isFormValid || !this.onEditMode - || (!this.phoneValue && !this.emailValue); - } - - updateAccountSetting(): void { - // const dataChanged = (): boolean => { - // return this._userSetting.name !== this.userNameValue - // || this._userSetting.phone !== this.phoneValue - // || this._userSetting.email !== this.emailValue; - // }; - // if (dataChanged) { - - // } - if (!this.onEditMode) return; - const editSettingInfo: UserSetting = { - name: this.userNameValue, - phone: this.phoneValue, - email: this.emailValue - } - updateAccountSetting(editSettingInfo).then((res: any) => { - console.log('updateRes:', res); - this.resetSettingForm(); - }); - } - - private resetSettingForm(): void { - this.onEditMode = false; - this.userNameDisabled = true; - this.userPhoneDisabled = true; - this.userEmailDisabled = true ; - } - - mounted(){ - getUserAccountSetting().then((userInfo: UserSetting)=>{ - this._userSetting = { - name: userInfo.name || '', - phone: userInfo.phone || '', - email: userInfo.email || '', - }; - - this.phoneValue = this._userSetting.phone!; - this.userNameValue = this._userSetting.name!; - this.emailValue = this._userSetting.email!; - }) - } - -} - - -</script> +<script src="./account-setting.component.ts"></script> <style lang="scss" scoped> -.account-page{ - .block{ - display: flex; - } - .account-page-title{ - font-size: 20px; - margin-bottom: 34px; - } - .account-card{ - display: flex; - flex-direction: column; - border-bottom: 1px solid gray; - margin-bottom: 33px; - .contact-type{ - width: 184px; - margin-right: 16px; - font-size: 20px; - display: flex; - flex-direction: column; - align-items: flex-start; - } - &.edit { - input { - border: 1px solid lightgray; - background-color: #fff; - } - } - } - .account-setting-btn{ - display: flex; - justify-content: center; - } -} -.error-txt{ - padding-bottom: 10px; - .error { - @extend .smTxt_bold; - @extend .text--primary; - height: 16px; - } -} -.name-input{ - width: 184px; - height:27px; - margin-bottom: 20px; - font-size: 20px; - margin-top: -3px; - } -.setting-title{ - margin-left: 28px; - margin-bottom:10px; - width: 58px; - font-size: 20px; - } -.header{ - display: flex; - align-items: baseline; -} -.contact-input{ - font-size: 20px; - margin-bottom: 10px; - text-overflow: ellipsis; - margin-top: 10px; - width: 184px; -} -.input{ - border: 0; - background-color: rgba(0,0,0,0) ; - outline-color: gainsboro; -} -.input:focus{ - background-color: #fff; -} -.icon-color-change{ - color:$PRIMARY_RED; - font-size: 20px; -} -.icon{ - font-size:20px; - // color:#1B365D; -} -@include desktop{ - - .header{ - display: flex; - align-items: baseline; - justify-content: space-between; - } - .setting-title{ - margin-bottom:10px; - width: 58px; - font-size: 18px; - font-weight: bold; - } - .account-page{ - .account-page-title{ - font-size: 20px; - margin-bottom: 34px; - font-weight: bold; - } - } - .account-card{ - display: flex; - flex-direction: column; - border-bottom: 1px solid gray; - margin-bottom: 33px; - .contact-type{ - margin-left: 10px; - font-size: 20px; - } - } - .name-input{ - width: 550px; - } - .contact-input{ - width:550px - } - } - -</style> \ No newline at end of file + @import "./account-setting.component.scss"; +</style> diff --git a/PAMapp/pages/agentInfo/_agentNo.vue b/PAMapp/pages/agentInfo/_agentNo.vue index 03478ed..a3b562f 100644 --- a/PAMapp/pages/agentInfo/_agentNo.vue +++ b/PAMapp/pages/agentInfo/_agentNo.vue @@ -130,8 +130,8 @@ type="flex" class="pam-paragraph"> <UiField icon="school" label="�犖��"> - <span v-for="(experience, index) in agentInfo.experiences" :key="index"> - {{ experience }}<span v-if="index !== agentInfo.experiences.length - 1">, </span> + <span v-for="(experience, index) in agentInfo.expertiseList" :key="index"> + {{ experience }}<span v-if="index !== agentInfo.expertiseList.length - 1">, </span> </span> </UiField> </el-row> @@ -182,124 +182,8 @@ </div> </template> -<script lang="ts"> -import { Context } from '@nuxt/types'; -import { namespace } from 'nuxt-property-decorator'; -import { Vue, Component } from 'vue-property-decorator'; -import { getConsultantDetail } from '~/assets/ts/api/consultant'; -import { Role } from '~/assets/ts//models/enum/Role'; -const roleStorage = namespace('localStorage'); -@Component -export default class AgentInfoComponent extends Vue { - @roleStorage.Getter currentRole!:string|null; - role = Role; - agentInfo!: AgentInfo; - isAlertAddSuccess = false; - isAlertFieldInfo = false; - fieldInfoTitle = ''; - fieldInfoDesc = ''; - - async asyncData(context: Context) { - const agentNo = context.route.params.agentNo; - let agentInfo = {}; - await getConsultantDetail(agentNo).then((res) => agentInfo = res.data ) - return { - agentInfo - } - } - - get agentName(): string { - return `${this.agentInfo.name}(${this.agentInfo.role})`; - } - - alertAddSuccess() { - this.isAlertAddSuccess = true; - } - - alertFieldInfo(field: string): void { - this.isAlertFieldInfo = true; - switch(field) { - case 'suitability': - this.fieldInfoTitle = '���漲'; - this.fieldInfoDesc = '���漲��������翰�祟�敺����雿�憿批����脰�������蝯行�����潘��隞乩������“������潦��'; - break; - case 'evaluation': - this.fieldInfoTitle = '隢株岷摨西”�'; - this.fieldInfoDesc = '隢株岷摨西”��撠��雿�憿批�������垣閰X���脰�������蝯行�����潦��'; - break; - } - } -} - -interface AgentInfo { - name : string; - agentNo : string; - role : string; - image : string; - avgScore : number; - title : string; - phoneNumber : string; - serveArea : string; - companyAddress : string; - lastestLoginTime: Date | null; - seniority : string; - suitability : number; - evaluation : number; - expertises : string[]; - concept : string; - experiences : string[]; - awards : string; -} -</script> +<script src="./agent-info.component.ts"></script> <style lang="scss"> -.pam-icon { - font-size: 15px; - padding-right: 8px; - color: $PRUDENTIAL_GREY; - &.icon--primary { - color: $PRIMARY_RED; - } -} -.pam-field { - display: flex; - flex-direction: column; - .pam-field__label { - display: flex; - align-items: center; - .pam-icon { - font-size: 12px; - } - .pam-field__title { - font-size: 16px; - font-weight: bold; - display: flex; - align-items: center; - } - } -} - -.pam-field-suitability { - .el-progress-bar__inner { - background-color: $LIGHT_BLUE !important; - } -} - -.pam-field-evaluation { - .el-progress-bar__inner { - background-color: $TEAL_GREEN!important; - } -} - -.pam-field-experts { - display: flex; - flex-wrap: wrap; -} - -.pam-progress__label { - justify-content: space-between; - flex-wrap: wrap; - line-height: 24px; -} - + @import "./agent-info.component.scss"; </style> diff --git a/PAMapp/pages/agentInfo/agent-info.component.scss b/PAMapp/pages/agentInfo/agent-info.component.scss new file mode 100644 index 0000000..37f0e48 --- /dev/null +++ b/PAMapp/pages/agentInfo/agent-info.component.scss @@ -0,0 +1,48 @@ +.pam-icon { + font-size: 15px; + padding-right: 8px; + color: $PRUDENTIAL_GREY; + &.icon--primary { + color: $PRIMARY_RED; + } +} +.pam-field { + display: flex; + flex-direction: column; + .pam-field__label { + display: flex; + align-items: center; + .pam-icon { + font-size: 12px; + } + .pam-field__title { + font-size: 16px; + font-weight: bold; + display: flex; + align-items: center; + } + } +} + +.pam-field-suitability { + .el-progress-bar__inner { + background-color: $LIGHT_BLUE !important; + } +} + +.pam-field-evaluation { + .el-progress-bar__inner { + background-color: $TEAL_GREEN!important; + } +} + +.pam-field-experts { + display: flex; + flex-wrap: wrap; +} + +.pam-progress__label { + justify-content: space-between; + flex-wrap: wrap; + line-height: 24px; +} diff --git a/PAMapp/pages/agentInfo/agent-info.component.ts b/PAMapp/pages/agentInfo/agent-info.component.ts new file mode 100644 index 0000000..8a80074 --- /dev/null +++ b/PAMapp/pages/agentInfo/agent-info.component.ts @@ -0,0 +1,54 @@ +import { Context } from '@nuxt/types'; +import { namespace } from 'nuxt-property-decorator'; +import { Vue, Component } from 'vue-property-decorator'; + +import { getConsultantDetail } from '~/assets/ts/api/consultant'; + +import { Role } from '~/assets/ts/models/enum/role.enum'; +import { AgentInfo } from '~/assets/ts/models/agentInfo.model'; + +const roleStorage = namespace('localStorage'); + +@Component +export default class AgentInfoComponent extends Vue { + + @roleStorage.Getter currentRole!:string|null; + + role = Role; + agentInfo!: AgentInfo; + isAlertAddSuccess = false; + isAlertFieldInfo = false; + fieldInfoTitle = ''; + fieldInfoDesc = ''; + + async asyncData(context: Context) { + const agentNo = context.route.params.agentNo; + let agentInfo = {}; + await getConsultantDetail(agentNo).then((res) => agentInfo = res.data ) + return { + agentInfo + } + } + + get agentName(): string { + return `${this.agentInfo.name}(${this.agentInfo.role})`; + } + + alertAddSuccess() { + this.isAlertAddSuccess = true; + } + + alertFieldInfo(field: string): void { + this.isAlertFieldInfo = true; + switch(field) { + case 'suitability': + this.fieldInfoTitle = '���漲'; + this.fieldInfoDesc = '���漲��������翰�祟�敺����雿�憿批����脰�������蝯行�����潘��隞乩������“������潦��'; + break; + case 'evaluation': + this.fieldInfoTitle = '隢株岷摨西”�'; + this.fieldInfoDesc = '隢株岷摨西”��撠��雿�憿批�������垣閰X���脰�������蝯行�����潦��'; + break; + } + } +} diff --git a/PAMapp/pages/consultantLogin/consultant-login.component.scss b/PAMapp/pages/consultantLogin/consultant-login.component.scss new file mode 100644 index 0000000..756aacc --- /dev/null +++ b/PAMapp/pages/consultantLogin/consultant-login.component.scss @@ -0,0 +1,77 @@ +.pam-consultant-login { + margin: auto; + width: 336px; + font-size: 20px; + color: $PRIMARY_BLACK; + + &__header { + text-align: center; + font-size: 24px; + font-weight: bold; + letter-spacing: 1.2; + color: $PRIMARY_BLACK; + } + + &__title { + display: flex; + justify-content: space-between; + align-items: center; + } + + &__input { + width: 100%; + outline: 0; + border: 1px solid #CCCCCC; + border-radius: 10px; + font-size: 20px; + height: 50px; + padding: 10px 90px 10px 15px; + overflow: auto; + box-sizing: border-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + + &Icon { + position: absolute; + display: flex; + align-items: center; + top: 15px; + right: 15px; + } + } + + &__forgot-password { + color: $PRIMARY_RED; + text-decoration: none; + font-size: 16px; + } + + &__verifyBlock { + display: flex; + justify-content: space-between; + } + + &__verifyImg { + width: 126px; + height: 50px; + border:1px #cccccc solid; + img { + width: 100%; + height: 100%; + } + } + + &__confirmBlock { + display: flex; + justify-content: center; + } + + &__confirm { + color: $PRIMARY_WHITE; + width: 80px; + height: 50px; + border-radius: 30px; + border: 1px solid $LIGHT_GREY; + background-color: $PRIMARY_RED; + } +} diff --git a/PAMapp/pages/consultantLogin/consultant-login.component.ts b/PAMapp/pages/consultantLogin/consultant-login.component.ts new file mode 100644 index 0000000..cbd2696 --- /dev/null +++ b/PAMapp/pages/consultantLogin/consultant-login.component.ts @@ -0,0 +1,103 @@ +import { Vue, Component , namespace } from 'nuxt-property-decorator'; +import { AxiosError } from 'axios'; +import { getImgOfVerification, logInToConsultant, getVerificationStatus } from '~/assets/ts/api/consultant'; +import { Role } from '~/assets/ts/models/enum/role.enum'; +import ErrorMessageBox from '~/assets/ts/errorService'; + +const roleStorage = namespace('localStorage'); +@Component({ + layout: 'home' +}) +export default class ConsultantLogin extends Vue { + @roleStorage.Mutation storageIdToken!: (token: string) => void; + @roleStorage.Mutation storageRole!: (role: string) => void; + @roleStorage.Mutation storageConsultantId!:(id:string) => void; + isRememberUserName = false; + isShowPassword = false; + imgSrc = ''; + verificationCode=''; + consultantDto = { + username: '', + password: '', + } + + get isAlreadyDone():boolean{ + return !!(this.verificationCode && this.consultantDto.username && this.consultantDto.password); + } + + mounted() { + this.getInitUserName(); + this.regenerateImgOfVerification(); + }; + + private getInitUserName(): void { + const username = localStorage.getItem('consultantUserName') + if (username) { + this.consultantDto.username = username; + this.isRememberUserName = true; + } + } + + public regenerateImgOfVerification(): void { + getImgOfVerification().then( imgOfBase64 => + this.imgSrc = imgOfBase64 + ); + }; + + public isRememberChange():void{ + this.isRememberUserName = !this.isRememberUserName; + this.storeUserName(); + } + + public sendInfo():void{ + this.isAlreadyDone ? this.verify() : ErrorMessageBox('隢Ⅱ隤董����Ⅳ隞亙���Ⅳ��憛怠神摰'); + } + + private verify():void{ + getVerificationStatus(this.verificationCode).then( verifySuccess => { + if(verifySuccess.data){ + this.loginWithConsultant() + }else{ + this.clearValue(); + this.regenerateImgOfVerification(); + ErrorMessageBox('撽�Ⅳ頛詨�隤�'); + } + }); + } + + private loginWithConsultant(): void { + logInToConsultant(this.consultantDto).then(res => { + this.storageIdToken(res.data.id_token); + this.storageRole(Role.ADMIN); + this.storageConsultantId(this.consultantDto.username) + this.storeUserName(); + this.$router.push('/myAppointmentList/appointmentList'); + }).catch((error:AxiosError)=>{ + this.checkHttpErrorStatus(error); + }); + } + private checkHttpErrorStatus(error:any):void{ + this.clearValue(); + this.regenerateImgOfVerification(); + switch (error.response.status) { + case 401: + const errorMsg = error.response.data.detail; + ErrorMessageBox(errorMsg); + break; + + default: + ErrorMessageBox('',error); + break; + } + } + + private storeUserName(): void { + localStorage.setItem('consultantUserName', this.isRememberUserName ? this.consultantDto.username : ''); + }; + + private clearValue():void{ + if (!this.isRememberUserName) this.consultantDto.username=''; + this.consultantDto.password = ''; + this.verificationCode = ''; + } +}; diff --git a/PAMapp/pages/consultantLogin/index.vue b/PAMapp/pages/consultantLogin/index.vue index 283f867..e59a9ca 100644 --- a/PAMapp/pages/consultantLogin/index.vue +++ b/PAMapp/pages/consultantLogin/index.vue @@ -55,206 +55,8 @@ </div> </template> -<script lang="ts"> - import { Vue, Component , namespace } from 'nuxt-property-decorator'; - import { AxiosError } from 'axios'; - import { getImgOfVerification, logInToConsultant, getVerificationStatus } from '~/assets/ts/api/consultant'; - import { Role } from '~/assets/ts/models/enum/Role'; - import ErrorMessageBox from '~/assets/ts/errorService'; - - const roleStorage = namespace('localStorage'); - @Component({ - layout: 'home' - }) - export default class ConsultantLogin extends Vue { - @roleStorage.Mutation storageIdToken!: (token: string) => void; - @roleStorage.Mutation storageRole!: (role: string) => void; - @roleStorage.Mutation storageConsultantId!:(id:string) => void; - isRememberUserName = false; - isShowPassword = false; - imgSrc = ''; - verificationCode=''; - consultantDto = { - username: '', - password: '', - } - - get isAlreadyDone():boolean{ - return !!(this.verificationCode && this.consultantDto.username && this.consultantDto.password); - } - - mounted() { - this.getInitUserName(); - this.regenerateImgOfVerification(); - }; - - private getInitUserName(): void { - const username = localStorage.getItem('consultantUserName') - if (username) { - this.consultantDto.username = username; - this.isRememberUserName = true; - } - } - - public regenerateImgOfVerification(): void { - getImgOfVerification().then( imgOfBase64 => - this.imgSrc = imgOfBase64 - ); - }; - - public isRememberChange():void{ - this.isRememberUserName = !this.isRememberUserName; - this.storeUserName(); - } - - public sendInfo():void{ - this.isAlreadyDone ? this.verify() : ErrorMessageBox('隢Ⅱ隤董����Ⅳ隞亙���Ⅳ��憛怠神摰'); - } - - private verify():void{ - getVerificationStatus(this.verificationCode).then( verifySuccess => { - if(verifySuccess.data){ - this.loginWithConsultant() - }else{ - this.clearValue(); - this.regenerateImgOfVerification(); - ErrorMessageBox('撽�Ⅳ頛詨�隤�'); - } - }); - } - - private loginWithConsultant(): void { - logInToConsultant(this.consultantDto).then(res => { - this.storageIdToken(res.data.id_token); - this.storageRole(Role.ADMIN); - this.storageConsultantId(this.consultantDto.username) - this.storeUserName(); - this.$router.push('/myAppointmentList/appointmentList'); - }).catch((error:AxiosError)=>{ - this.checkHttpErrorStatus(error); - }); - } - private checkHttpErrorStatus(error:any):void{ - this.clearValue(); - this.regenerateImgOfVerification(); - switch (error.response.status) { - case 401: - const errorMsg = error.response.data.detail; - ErrorMessageBox(errorMsg); - break; - - default: - ErrorMessageBox('',error); - break; - } - } - - private storeUserName(): void { - localStorage.setItem('consultantUserName', this.isRememberUserName ? this.consultantDto.username : ''); - }; - - private clearValue():void{ - if (!this.isRememberUserName) this.consultantDto.username=''; - this.consultantDto.password = ''; - this.verificationCode = ''; - } - }; - -</script> +<script src="./consultant-login.component.ts"></script> <style lang="scss" scoped> - .mt-20 { - margin-top: 20px; - } - - .mt-25 { - margin-top: 25px; - } - - .w-55 { - width: 55% !important; - } - - .position-r { - position: relative; - } - - .pam-consultant-login { - margin: auto; - width: 336px; - font-size: 20px; - color: $PRIMARY_BLACK; - - &__header { - text-align: center; - font-size: 24px; - font-weight: bold; - letter-spacing: 1.2; - color: $PRIMARY_BLACK; - } - - &__title { - display: flex; - justify-content: space-between; - align-items: center; - } - - &__input { - width: 100%; - outline: 0; - border: 1px solid #CCCCCC; - border-radius: 10px; - font-size: 20px; - height: 50px; - padding: 10px 90px 10px 15px; - overflow: auto; - box-sizing: border-box; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - - &Icon { - position: absolute; - display: flex; - align-items: center; - top: 15px; - right: 15px; - } - } - - &__forgot-password { - color: $PRIMARY_RED; - text-decoration: none; - font-size: 16px; - } - - &__verifyBlock { - display: flex; - justify-content: space-between; - } - - &__verifyImg { - width: 126px; - height: 50px; - border:1px #cccccc solid; - img { - width: 100%; - height: 100%; - } - } - - &__confirmBlock { - display: flex; - justify-content: center; - } - - &__confirm { - color: $PRIMARY_WHITE; - width: 80px; - height: 50px; - border-radius: 30px; - border: 1px solid $LIGHT_GREY; - background-color: $PRIMARY_RED; - } - } - + @import "./consultant-login.component.scss"; </style> diff --git a/PAMapp/pages/login/index.vue b/PAMapp/pages/login/index.vue index 6f02559..cc5c228 100644 --- a/PAMapp/pages/login/index.vue +++ b/PAMapp/pages/login/index.vue @@ -339,476 +339,8 @@ </div> </template> -<script lang="ts"> -import { namespace } from 'nuxt-property-decorator'; -import { Vue, Component, Ref } from 'vue-property-decorator'; -import { LoginRequest, LoginVerify, loginVerify, OtpInfo, register, RegisterInfo, sendOtp } from '~/assets/ts/api/consultant'; -import ErrorMessageBox from '~/assets/ts/errorService'; -import { OtpErrorCode } from '~/assets/ts/models/enum/otpErrorCode'; -import { Role } from '~/assets/ts/models/enum/Role'; +<script src="./login.component.ts"></script> -const roleStorage = namespace('localStorage'); - -@Component -export default class Login extends Vue { - @roleStorage.Mutation storageIdToken!: (token:string) => void; - @roleStorage.Mutation storageRole!: (role:string) => void; - @Ref('contract') readonly contract!: any; - - connectDevice: 'MOBILE' | 'EMAIL' = 'MOBILE'; - - phoneNumber = ''; - otpCode = ''; - onPhoneVerifyStep: 'APPLY_OTP' | 'INPUT_OTP' | 'SUBMIT_OTP' = 'APPLY_OTP'; - otpCounterSec = 900; - otpResendCounter = 30; - otpInterval: any; - phoneOtpInfo!: OtpInfo; - - email = ''; - onEmailVerifyResendStatus: 'APPLY_OTP' | 'CAN_RESEND' = 'APPLY_OTP'; - emailCounterSec = 900; - emailResendCounter = 30; - emailOtpCode = ''; - emailResendInterval: any; - emailOtpInfo!: OtpInfo; - - autoRedirectCounter = 3; - autoRedirectInterval: any; - - name = ''; - agreeContract = false; - isReadContract = false; - - phoneSuccessConfirmVisable = false; - emailOtpConfirmVisable = false; - - registerDialogVisible = false; - registerSuccessConfirmVisable = false; - - applyAccount_onAction = false; - - previousPath = ''; - mounted() { - const phoneOtpTime = localStorage.getItem('phoneOtpTime'); - const emailOtpTime = localStorage.getItem('emailOtpTime'); - const parsePhoneOtpTime = phoneOtpTime ? JSON.parse(phoneOtpTime) : ''; - const parseEmailOtpTime = emailOtpTime ? JSON.parse(emailOtpTime) : ''; - if (parsePhoneOtpTime && parsePhoneOtpTime.contactType === 'SMS') { - this.phoneDiffTime(parsePhoneOtpTime); - } - if (parseEmailOtpTime && parseEmailOtpTime.contactType === 'EMAIL') { - this.emailDiffTime(parseEmailOtpTime); - } - } - - detectContractReadStatus(event: any): void { - const scrollTop = Math.round(event.target.scrollTop); - const height = event.target.scrollHeight - event.target.clientHeight; - if (Math.floor(scrollTop/10) === (Math.floor(height/10))) { - this.isReadContract = true; - } - }; - - get isSubmitBtnDisabled(): boolean { - return this.connectDevice === 'MOBILE' - ? (!this.otpCode || !this.phoneNumber || !this.phoneValid || !this.otpCounterSec) - : (!this.emailOtpCode || !this.email || !this.emailValid || !this.emailCounterSec) - } - - get phoneCounter() { - let min = Math.floor(this.otpCounterSec / 60); - let sec = Math.floor(this.otpCounterSec % 60); - return `${min < 10 ? '0' + min : min}:${sec < 10 ? '0' + sec : sec}`; - } - - get emailOtpCounter() { - let min = Math.floor(this.emailCounterSec / 60); - let sec = Math.floor(this.emailCounterSec % 60); - return `${min < 10 ? '0' + min : min}:${sec < 10 ? '0' + sec : sec}`; - } - - get showPhoneOtpCodeField(): boolean { - return this.connectDevice === 'MOBILE' && this.onPhoneVerifyStep === 'INPUT_OTP'; - }; - - get showEmailVerifyField(): boolean { - return this.connectDevice === 'EMAIL' && this.onEmailVerifyResendStatus === 'CAN_RESEND'; - }; - - get phoneValid() { - const rule = /^09[0-9]{8}$/; - return this.phoneNumber ? rule.test(this.phoneNumber) : true; - } - - get emailValid() { - const rule = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; - return this.email ? rule.test(this.email) : true; - } - - applyOtpVerification(type: string): void { - const isMobile = this.connectDevice === 'MOBILE'; - const loginInfo: LoginRequest = { - loginType: isMobile ? 'SMS' : 'EMAIL', - account: isMobile ? this.phoneNumber : this.email, - } - sendOtp(loginInfo).then(otpInfo => { - if (otpInfo.success) { - this.storageOtpTime(type, otpInfo); - this.startOtpSetting(type); - this.startOtpCount(type); - } else { - const errorMsg = OtpErrorCode[otpInfo.failCode] ? OtpErrorCode[otpInfo.failCode]:'OTP蝟餌絞�隤�'; - ErrorMessageBox(errorMsg); - } - }); - }; - - resentOtp(type: string) { - this.resetOtpSetting(type); - this.applyOtpVerification(type); - } - - deleteOtpInfo(type: string) { - this.resetOtpSetting(type); - if (type === 'MOBILE') { - this.onPhoneVerifyStep = 'APPLY_OTP'; - this.phoneNumber = ''; - this.otpCode = ''; - } else { - this.onEmailVerifyResendStatus = 'APPLY_OTP'; - this.email = ''; - this.emailOtpCode = ''; - } - this.removeOtpTime(); - } - - applyAccount(): void { - if (this.applyAccount_onAction) { - return ; - } - - this.applyAccount_onAction = true; - const registerInfo = this.setRegisterInfo(); - - register(registerInfo).then(res => { - this.storageIdToken(res.data.id_token); - this.storageRole(Role.USER); - this.storagePhoneOrEmail(registerInfo); - this.autoRedirect(); - this.registerSuccessConfirmVisable = true; - }).catch(() => { - this.applyAccount_onAction = false; - }); - }; - - confirmApplySuccess(): void { - this.phoneSuccessConfirmVisable = false; - this.registerSuccessConfirmVisable = false; - this.redirect(); - } - - private autoRedirect() { - this.autoRedirectInterval = setInterval(() => { - this.autoRedirectCounter -= 1; - - if (this.autoRedirectCounter === 0) { - clearInterval(this.autoRedirectInterval); - this.redirect(); - } - }, 1000) - } - - private redirect() { - const backToPrevious = ['questionnaire', 'myConsultantList']; - const find = backToPrevious.findIndex(item => this.previousPath.includes(item)); - console.log(this.previousPath, find, 'redirect'); - find > -1 ? this.$router.go(-1) : this.$router.push('/'); - } - - beforeRouteEnter (to, from, next) { - next(vm => { - console.log(from.path, 'beforeRouteEnter'); - vm.previousPath = from.path; - }) - } - - login() { - const login: LoginVerify = this.setLoginInfo(); - this.removeOtpTime(); - loginVerify(login).then(res => { - this.storageIdToken(res.data.id_token); - this.storageRole(Role.USER); - this.phoneSuccessConfirmVisable = true; - this.autoRedirect(); - this.storagePhoneOrEmail(this.setRegisterInfo()); - }).catch(error => { - this.checkHttpErrorStatus(error); - }); - } - private checkHttpErrorStatus(error:any):void{ - switch (error.response.status) { - case 401: - const errorMsg = OtpErrorCode[error.response?.data?.detail] ? OtpErrorCode[error.response?.data?.detail]:'OTP蝟餌絞�隤�'; - ErrorMessageBox(errorMsg); - break; - case 403: - this.registerDialogVisible = true; - setTimeout(() => { - const isScrollBarNeedless = this.contract.scrollHeight <= this.contract.clientHeight; - if (isScrollBarNeedless) { - this.isReadContract = true; - } - }, 1000); - break; - default: - ErrorMessageBox('',error); - break; - } - } - - destroyed() { - this.removeOtpTime(); - clearInterval(this.otpInterval); - clearInterval(this.emailResendInterval); - clearInterval(this.autoRedirectInterval); - } - - private phoneDiffTime(parseOtpTime: any) { - const diffSecs = this.calcDiffSecs(parseOtpTime.time); - - if (diffSecs < this.otpCounterSec) { - this.otpResendCounter = diffSecs < 30 ? 30 - diffSecs : 0; - this.otpCounterSec -= diffSecs; - this.phoneNumber = parseOtpTime.phone; - this.onPhoneVerifyStep = 'INPUT_OTP'; - this.phoneOtpInfo = this.setOtpInfo(parseOtpTime); - this.startOtpCount('MOBILE'); - } else { - localStorage.removeItem('phoneOtpTime'); - } - } - - private emailDiffTime(parseOtpTime: any) { - const diffSecs = this.calcDiffSecs(parseOtpTime.time); - - if (diffSecs < this.emailCounterSec) { - this.emailResendCounter = diffSecs < 30 ? 30 - diffSecs : 0; - this.emailCounterSec -= diffSecs; - this.email = parseOtpTime.email; - this.onEmailVerifyResendStatus = 'CAN_RESEND'; - this.emailOtpInfo = this.setOtpInfo(parseOtpTime); - this.startOtpCount('EMAIL'); - } else { - localStorage.removeItem('emailOtpTime'); - } - } - - private calcDiffSecs(parseOtpTime) { - const currentTime = new Date().getTime(); - const storageTime = new Date(parseOtpTime).getTime(); - return Math.floor((currentTime - storageTime) / 1000); - } - - private resetOtpSetting(type: string) { - if (type === 'MOBILE') { - clearInterval(this.otpInterval); - this.otpResendCounter = 30; - this.otpCounterSec = 900; - } else { - clearInterval(this.emailResendInterval); - this.emailResendCounter = 30; - this.emailCounterSec = 900; - } - } - - private setOtpInfo(parseOtpTime) { - return { - indexKey: parseOtpTime.indexKey, - success: true, - failCode: '', - failReason: '', - } - } - - private storageOtpTime(type: string, otpInfo: OtpInfo) { - type === 'MOBILE' ? this.phoneOtpInfo = otpInfo : this.emailOtpInfo = otpInfo; - const info = {...this.setRegisterInfo(), time: new Date()} - type === 'MOBILE' ? localStorage.setItem('phoneOtpTime',JSON.stringify(info)) - : localStorage.setItem('emailOtpTime',JSON.stringify(info)); - } - - private startOtpSetting(type: string) { - if (type === 'MOBILE') { - this.onPhoneVerifyStep = 'INPUT_OTP'; - } else { - this.onEmailVerifyResendStatus = 'CAN_RESEND'; - this.emailOtpConfirmVisable = true; - } - } - - private startOtpCount(type: string) { - type === 'MOBILE' ? this.startPhoneCounter() : this.startEmailCounter();; - } - - private startEmailCounter() { - this.emailResendInterval = setInterval(() => { - this.emailCounterSec -= 1; - if (this.emailResendCounter !== 0) { - this.emailResendCounter -= 1; - } - if (this.emailCounterSec === 0) { - clearInterval(this.emailResendInterval); - } - }, 1000) - } - - private startPhoneCounter() { - this.otpInterval = setInterval(() => { - this.otpCounterSec -= 1; - if (this.otpResendCounter !== 0) { - this.otpResendCounter -= 1; - } - if (this.otpCounterSec === 0) { - clearInterval(this.otpInterval) - } - }, 1000) - } - - private setRegisterInfo(): RegisterInfo { - return this.connectDevice === 'MOBILE' - ? { - phone: this.phoneNumber, - indexKey: this.phoneOtpInfo.indexKey, - otpCode: this.otpCode, - name: this.name, - contactType: 'SMS' - } - : { - email: this.email, - indexKey: this.emailOtpInfo.indexKey, - otpCode: this.otpCode, - name: this.name, - contactType: 'EMAIL' - } - } - - private storagePhoneOrEmail(registerInfo:RegisterInfo):void{ - const info = {...registerInfo, time: new Date()} - localStorage.setItem('userInfo',JSON.stringify(info)); - } - - private removeOtpTime() { - localStorage.removeItem('emailOtpTime'); - localStorage.removeItem('phoneOtpTime'); - } - - private setLoginInfo() { - const isMobile = this.connectDevice === 'MOBILE' - return { - account: isMobile ? this.phoneNumber : this.email, - indexKey: isMobile ? this.phoneOtpInfo.indexKey : this.emailOtpInfo.indexKey, - otpCode: isMobile ? this.otpCode : this.emailOtpCode - } - } -} -</script> - -<style lang="scss"> -.pam-login-page { - font-size: 20px !important; - display: flex; - flex-direction: column; - .pam-login-page__action-bar { - display: flex; - flex: 1; - align-items: flex-end; - @include desktop { - margin-bottom: 30px; - } - } - } - - .pam-input { - height: 26px; - width: calc(100% - 36px); - border-radius: 10px !important; - padding: 12px 18px !important; - border:1px solid #CCCCCC; - outline: 0; - @extend .text--middle; - &::placeholder { - color: $PRUDENTIAL_GREY; - } - &.is-invalid { - border: 1px solid $PRIMARY_RED !important; - border-radius: 20px; - } - } - -.pam-register-dialog__contract { - $DEVICE_EXTRA_HEIGHT: 42px; - $ALIGN_PADDING: 60px; - $TOP_CONTENT_HEIGHT: 186px; - $BOTTOM_CONTENT_HEIGHT: 131px; - max-height: calc(100vh - $DEVICE_EXTRA_HEIGHT - $ALIGN_PADDING - $TOP_CONTENT_HEIGHT - $BOTTOM_CONTENT_HEIGHT); - overflow-y: scroll; - border-radius: 6px; - border: 1px solid #707070; - padding: 20px; - @include desktop { - height: 335px; - } -} - - .pam-radio { - color: $PRIMARY_RED; - align-items: center; - display: flex; - font-size: 20px; - font-weight: bold; - input { - display: none; - } - i { - font-size: 27px; - padding-right: 5px; - } - } - - .pam-field-title__hint { - @extend .smTxt_bold; - color: #68737A; - } - - .error { - @extend .smTxt_bold; - @extend .text--primary; - height: 16px; - } - - .pam-popUp-title { - font-size: 20px; - line-height: 27px; - } - - .pam-popUp-txt { - font-size: 18px; - color: $MID_GREY; - } - - .disabled { - color: #A7A8AA; - } - - .pam-input-position { - position: relative; - .icon-close { - cursor: pointer; - position: absolute; - right: 15px; - top: 28px; - font-size: 16px; - } - } +<style lang="scss" scoped> + @import "./login.component.scss"; </style> diff --git a/PAMapp/pages/login/login.component.scss b/PAMapp/pages/login/login.component.scss new file mode 100644 index 0000000..ff9f53f --- /dev/null +++ b/PAMapp/pages/login/login.component.scss @@ -0,0 +1,97 @@ + +.pam-login-page { + font-size: 20px !important; + display: flex; + flex-direction: column; + .pam-login-page__action-bar { + display: flex; + flex: 1; + align-items: flex-end; + @include desktop { + margin-bottom: 30px; + } + } + } + + .pam-input { + height: 26px; + width: calc(100% - 36px); + border-radius: 10px !important; + padding: 12px 18px !important; + border:1px solid #CCCCCC; + outline: 0; + @extend .text--middle; + &::placeholder { + color: $PRUDENTIAL_GREY; + } + &.is-invalid { + border: 1px solid $PRIMARY_RED !important; + border-radius: 20px; + } + } + +.pam-register-dialog__contract { + $DEVICE_EXTRA_HEIGHT: 42px; + $ALIGN_PADDING: 60px; + $TOP_CONTENT_HEIGHT: 186px; + $BOTTOM_CONTENT_HEIGHT: 131px; + max-height: calc(100vh - $DEVICE_EXTRA_HEIGHT - $ALIGN_PADDING - $TOP_CONTENT_HEIGHT - $BOTTOM_CONTENT_HEIGHT); + overflow-y: scroll; + border-radius: 6px; + border: 1px solid #707070; + padding: 20px; + @include desktop { + height: 335px; + } +} + + .pam-radio { + color: $PRIMARY_RED; + align-items: center; + display: flex; + font-size: 20px; + font-weight: bold; + input { + display: none; + } + i { + font-size: 27px; + padding-right: 5px; + } + } + + .pam-field-title__hint { + @extend .smTxt_bold; + color: #68737A; + } + + .error { + @extend .smTxt_bold; + @extend .text--primary; + height: 16px; + } + + .pam-popUp-title { + font-size: 20px; + line-height: 27px; + } + + .pam-popUp-txt { + font-size: 18px; + color: $MID_GREY; + } + + .disabled { + color: #A7A8AA; + } + + .pam-input-position { + position: relative; + .icon-close { + cursor: pointer; + position: absolute; + right: 15px; + top: 28px; + font-size: 16px; + } + } diff --git a/PAMapp/pages/login/login.component.ts b/PAMapp/pages/login/login.component.ts new file mode 100644 index 0000000..3bde506 --- /dev/null +++ b/PAMapp/pages/login/login.component.ts @@ -0,0 +1,373 @@ + +import { namespace } from 'nuxt-property-decorator'; +import { Vue, Component, Ref } from 'vue-property-decorator'; +import { LoginRequest, LoginVerify, loginVerify, OtpInfo, register, RegisterInfo, sendOtp } from '~/assets/ts/api/consultant'; +import ErrorMessageBox from '~/assets/ts/errorService'; +import { OtpErrorCode } from '~/assets/ts/models/enum/otpErrorCode'; +import { Role } from '~/assets/ts/models/enum/role.enum'; + +const roleStorage = namespace('localStorage'); + +@Component +export default class Login extends Vue { + @roleStorage.Mutation storageIdToken!: (token:string) => void; + @roleStorage.Mutation storageRole!: (role:string) => void; + @Ref('contract') readonly contract!: any; + + connectDevice: 'MOBILE' | 'EMAIL' = 'MOBILE'; + + phoneNumber = ''; + otpCode = ''; + onPhoneVerifyStep: 'APPLY_OTP' | 'INPUT_OTP' | 'SUBMIT_OTP' = 'APPLY_OTP'; + otpCounterSec = 900; + otpResendCounter = 30; + otpInterval: any; + phoneOtpInfo!: OtpInfo; + + email = ''; + onEmailVerifyResendStatus: 'APPLY_OTP' | 'CAN_RESEND' = 'APPLY_OTP'; + emailCounterSec = 900; + emailResendCounter = 30; + emailOtpCode = ''; + emailResendInterval: any; + emailOtpInfo!: OtpInfo; + + autoRedirectCounter = 3; + autoRedirectInterval: any; + + name = ''; + agreeContract = false; + isReadContract = false; + + phoneSuccessConfirmVisable = false; + emailOtpConfirmVisable = false; + + registerDialogVisible = false; + registerSuccessConfirmVisable = false; + + applyAccount_onAction = false; + + previousPath = ''; + mounted() { + const phoneOtpTime = localStorage.getItem('phoneOtpTime'); + const emailOtpTime = localStorage.getItem('emailOtpTime'); + const parsePhoneOtpTime = phoneOtpTime ? JSON.parse(phoneOtpTime) : ''; + const parseEmailOtpTime = emailOtpTime ? JSON.parse(emailOtpTime) : ''; + if (parsePhoneOtpTime && parsePhoneOtpTime.contactType === 'SMS') { + this.phoneDiffTime(parsePhoneOtpTime); + } + if (parseEmailOtpTime && parseEmailOtpTime.contactType === 'EMAIL') { + this.emailDiffTime(parseEmailOtpTime); + } + } + + detectContractReadStatus(event: any): void { + const scrollTop = Math.round(event.target.scrollTop); + const height = event.target.scrollHeight - event.target.clientHeight; + if (Math.floor(scrollTop/10) === (Math.floor(height/10))) { + this.isReadContract = true; + } + }; + + get isSubmitBtnDisabled(): boolean { + return this.connectDevice === 'MOBILE' + ? (!this.otpCode || !this.phoneNumber || !this.phoneValid || !this.otpCounterSec) + : (!this.emailOtpCode || !this.email || !this.emailValid || !this.emailCounterSec) + } + + get phoneCounter() { + let min = Math.floor(this.otpCounterSec / 60); + let sec = Math.floor(this.otpCounterSec % 60); + return `${min < 10 ? '0' + min : min}:${sec < 10 ? '0' + sec : sec}`; + } + + get emailOtpCounter() { + let min = Math.floor(this.emailCounterSec / 60); + let sec = Math.floor(this.emailCounterSec % 60); + return `${min < 10 ? '0' + min : min}:${sec < 10 ? '0' + sec : sec}`; + } + + get showPhoneOtpCodeField(): boolean { + return this.connectDevice === 'MOBILE' && this.onPhoneVerifyStep === 'INPUT_OTP'; + }; + + get showEmailVerifyField(): boolean { + return this.connectDevice === 'EMAIL' && this.onEmailVerifyResendStatus === 'CAN_RESEND'; + }; + + get phoneValid() { + const rule = /^09[0-9]{8}$/; + return this.phoneNumber ? rule.test(this.phoneNumber) : true; + } + + get emailValid() { + const rule = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; + return this.email ? rule.test(this.email) : true; + } + + applyOtpVerification(type: string): void { + const isMobile = this.connectDevice === 'MOBILE'; + const loginInfo: LoginRequest = { + loginType: isMobile ? 'SMS' : 'EMAIL', + account: isMobile ? this.phoneNumber : this.email, + } + sendOtp(loginInfo).then(otpInfo => { + if (otpInfo.success) { + this.storageOtpTime(type, otpInfo); + this.startOtpSetting(type); + this.startOtpCount(type); + } else { + const errorMsg = OtpErrorCode[otpInfo.failCode] ? OtpErrorCode[otpInfo.failCode]:'OTP蝟餌絞�隤�'; + ErrorMessageBox(errorMsg); + } + }); + }; + + resentOtp(type: string) { + this.resetOtpSetting(type); + this.applyOtpVerification(type); + } + + deleteOtpInfo(type: string) { + this.resetOtpSetting(type); + if (type === 'MOBILE') { + this.onPhoneVerifyStep = 'APPLY_OTP'; + this.phoneNumber = ''; + this.otpCode = ''; + } else { + this.onEmailVerifyResendStatus = 'APPLY_OTP'; + this.email = ''; + this.emailOtpCode = ''; + } + this.removeOtpTime(); + } + + applyAccount(): void { + if (this.applyAccount_onAction) { + return ; + } + + this.applyAccount_onAction = true; + const registerInfo = this.setRegisterInfo(); + + register(registerInfo).then(res => { + this.storageIdToken(res.data.id_token); + this.storageRole(Role.USER); + this.storagePhoneOrEmail(registerInfo); + this.autoRedirect(); + this.registerSuccessConfirmVisable = true; + }).catch(() => { + this.applyAccount_onAction = false; + }); + }; + + confirmApplySuccess(): void { + this.phoneSuccessConfirmVisable = false; + this.registerSuccessConfirmVisable = false; + this.redirect(); + } + + private autoRedirect() { + this.autoRedirectInterval = setInterval(() => { + this.autoRedirectCounter -= 1; + + if (this.autoRedirectCounter === 0) { + clearInterval(this.autoRedirectInterval); + this.redirect(); + } + }, 1000) + } + + private redirect() { + const backToPrevious = ['questionnaire', 'myConsultantList']; + const find = backToPrevious.findIndex(item => this.previousPath.includes(item)); + console.log(this.previousPath, find, 'redirect'); + find > -1 ? this.$router.go(-1) : this.$router.push('/'); + } + + beforeRouteEnter (to, from, next) { + next(vm => { + console.log(from.path, 'beforeRouteEnter'); + vm.previousPath = from.path; + }) + } + + login() { + const login: LoginVerify = this.setLoginInfo(); + this.removeOtpTime(); + loginVerify(login).then(res => { + this.storageIdToken(res.data.id_token); + this.storageRole(Role.USER); + this.phoneSuccessConfirmVisable = true; + this.autoRedirect(); + this.storagePhoneOrEmail(this.setRegisterInfo()); + }).catch(error => { + this.checkHttpErrorStatus(error); + }); + } + private checkHttpErrorStatus(error:any):void{ + switch (error.response.status) { + case 401: + const errorMsg = OtpErrorCode[error.response?.data?.detail] ? OtpErrorCode[error.response?.data?.detail]:'OTP蝟餌絞�隤�'; + ErrorMessageBox(errorMsg); + break; + case 403: + this.registerDialogVisible = true; + setTimeout(() => { + const isScrollBarNeedless = this.contract.scrollHeight <= this.contract.clientHeight; + if (isScrollBarNeedless) { + this.isReadContract = true; + } + }, 1000); + break; + default: + ErrorMessageBox('',error); + break; + } + } + + destroyed() { + this.removeOtpTime(); + clearInterval(this.otpInterval); + clearInterval(this.emailResendInterval); + clearInterval(this.autoRedirectInterval); + } + + private phoneDiffTime(parseOtpTime: any) { + const diffSecs = this.calcDiffSecs(parseOtpTime.time); + + if (diffSecs < this.otpCounterSec) { + this.otpResendCounter = diffSecs < 30 ? 30 - diffSecs : 0; + this.otpCounterSec -= diffSecs; + this.phoneNumber = parseOtpTime.phone; + this.onPhoneVerifyStep = 'INPUT_OTP'; + this.phoneOtpInfo = this.setOtpInfo(parseOtpTime); + this.startOtpCount('MOBILE'); + } else { + localStorage.removeItem('phoneOtpTime'); + } + } + + private emailDiffTime(parseOtpTime: any) { + const diffSecs = this.calcDiffSecs(parseOtpTime.time); + + if (diffSecs < this.emailCounterSec) { + this.emailResendCounter = diffSecs < 30 ? 30 - diffSecs : 0; + this.emailCounterSec -= diffSecs; + this.email = parseOtpTime.email; + this.onEmailVerifyResendStatus = 'CAN_RESEND'; + this.emailOtpInfo = this.setOtpInfo(parseOtpTime); + this.startOtpCount('EMAIL'); + } else { + localStorage.removeItem('emailOtpTime'); + } + } + + private calcDiffSecs(parseOtpTime) { + const currentTime = new Date().getTime(); + const storageTime = new Date(parseOtpTime).getTime(); + return Math.floor((currentTime - storageTime) / 1000); + } + + private resetOtpSetting(type: string) { + if (type === 'MOBILE') { + clearInterval(this.otpInterval); + this.otpResendCounter = 30; + this.otpCounterSec = 900; + } else { + clearInterval(this.emailResendInterval); + this.emailResendCounter = 30; + this.emailCounterSec = 900; + } + } + + private setOtpInfo(parseOtpTime) { + return { + indexKey: parseOtpTime.indexKey, + success: true, + failCode: '', + failReason: '', + } + } + + private storageOtpTime(type: string, otpInfo: OtpInfo) { + type === 'MOBILE' ? this.phoneOtpInfo = otpInfo : this.emailOtpInfo = otpInfo; + const info = {...this.setRegisterInfo(), time: new Date()} + type === 'MOBILE' ? localStorage.setItem('phoneOtpTime',JSON.stringify(info)) + : localStorage.setItem('emailOtpTime',JSON.stringify(info)); + } + + private startOtpSetting(type: string) { + if (type === 'MOBILE') { + this.onPhoneVerifyStep = 'INPUT_OTP'; + } else { + this.onEmailVerifyResendStatus = 'CAN_RESEND'; + this.emailOtpConfirmVisable = true; + } + } + + private startOtpCount(type: string) { + type === 'MOBILE' ? this.startPhoneCounter() : this.startEmailCounter();; + } + + private startEmailCounter() { + this.emailResendInterval = setInterval(() => { + this.emailCounterSec -= 1; + if (this.emailResendCounter !== 0) { + this.emailResendCounter -= 1; + } + if (this.emailCounterSec === 0) { + clearInterval(this.emailResendInterval); + } + }, 1000) + } + + private startPhoneCounter() { + this.otpInterval = setInterval(() => { + this.otpCounterSec -= 1; + if (this.otpResendCounter !== 0) { + this.otpResendCounter -= 1; + } + if (this.otpCounterSec === 0) { + clearInterval(this.otpInterval) + } + }, 1000) + } + + private setRegisterInfo(): RegisterInfo { + return this.connectDevice === 'MOBILE' + ? { + phone: this.phoneNumber, + indexKey: this.phoneOtpInfo.indexKey, + otpCode: this.otpCode, + name: this.name, + contactType: 'SMS' + } + : { + email: this.email, + indexKey: this.emailOtpInfo.indexKey, + otpCode: this.otpCode, + name: this.name, + contactType: 'EMAIL' + } + } + + private storagePhoneOrEmail(registerInfo:RegisterInfo):void{ + const info = {...registerInfo, time: new Date()} + localStorage.setItem('userInfo',JSON.stringify(info)); + } + + private removeOtpTime() { + localStorage.removeItem('emailOtpTime'); + localStorage.removeItem('phoneOtpTime'); + } + + private setLoginInfo() { + const isMobile = this.connectDevice === 'MOBILE' + return { + account: isMobile ? this.phoneNumber : this.email, + indexKey: isMobile ? this.phoneOtpInfo.indexKey : this.emailOtpInfo.indexKey, + otpCode: isMobile ? this.otpCode : this.emailOtpCode + } + } +} diff --git a/PAMapp/pages/myAppointmentList.vue b/PAMapp/pages/myAppointmentList.vue deleted file mode 100644 index 85a57da..0000000 --- a/PAMapp/pages/myAppointmentList.vue +++ /dev/null @@ -1,133 +0,0 @@ -<template> - <div> - <div class="pam-myAppointment-banner"></div> - <div class="pam-container"> - <div class="pam-cus-tabs mb-30"> - <div - class="cus-tab-item" - :class="{'is-active': activeTabName === 'appointmentList'}" - @click="tabClick('appointmentList')" - >摰X���� - <span class="p">({{appointmentList.length}})</span> - </div> - <div - class="cus-tab-item" - :class="{'is-active': activeTabName === 'contactedList'}" - @click="tabClick('contactedList')" - >撌脰蝯� - <span class="p">({{contactedList.length}})</span> - </div> - </div> - - <NuxtChild></NuxtChild> - </div> - - <PopUpFrame - :isOpen.sync="showNewAppointmentNumber" - > - <div class="text--center mdTxt"> - <p class="mb-50">雿�� <span class="text--primary">{{newAppointmentNumber}}</span> �������</p> - <div class="text--center"> - <el-button - type="primary" - @click="showNewAppointmentNumber = false" - >������</el-button> - </div> - </div> - </PopUpFrame> - </div> -</template> - -<script lang="ts"> -import { Vue, Component, State, Action, Watch } from 'nuxt-property-decorator'; -import { allAppointmentsView, ClientInfo } from '~/assets/ts/api/appointment'; -import * as _ from 'lodash'; - -@Component({ - layout: 'home' -}) -export default class ClientReservedList extends Vue { - activeTabName = 'appointmentList'; - appointmentList: ClientInfo[] = []; - contactedList: ClientInfo[] = []; - clients: ClientInfo[] = []; - newAppointmentNumber: number = 0; - showNewAppointmentNumber = false; - - @State('myAppointmentList') myAppointmentList!: ClientInfo[]; - @Action storeMyAppointmentList!: () => Promise<number>; - - mounted() { - this.storeMyAppointmentList().then(newDataLength => { - this.newAppointmentNumber = newDataLength; - if (this.newAppointmentNumber > 0) { - this.showNewAppointmentNumber = true; - allAppointmentsView().then(res => res); - } - }); - - if (this.$route.name) { - this.activeTabName = this.$route.name.split('-')[1] - } - } - - @Watch('myAppointmentList') - onMyAppointmentListChange() { - this.contactedList = this.myAppointmentList - .filter(item => item.communicateStatus === 'contacted'); - - this.appointmentList = this.myAppointmentList - .filter(item => item.communicateStatus !== 'contacted'); - } - - tabClick(path: string) { - this.activeTabName = path; - this.$router.push('/myAppointmentList/' + this.activeTabName) - } - - get route(): string{ - const routeName = this.$route.name; - return routeName ? routeName:''; - }; - - get bannerClassName() { - return this.routeFormatBannerClass(this.route); - }; - - // format to {page}-banner or pam-no-banner tag - private routeFormatBannerClass(route: string): string { - const needBannerTags = ['myAppointmentList-appointmentList', 'myAppointmentList-contactedList']; - return _.includes(needBannerTags, route) ? route + '-banner' : 'pam-no-banner'; - }; - -} -</script> - -<style lang="scss" scoped> - .pam-myAppointment-banner { - width: 100%; - height: 120px; - background-size: cover; - background-repeat: no-repeat; - background-position: center; - position: relative; - background-image: url('~/assets/images/myAppointmentList/agent_banner_mob.svg'); - } - - @media (min-width: 768px) { - .pam-myAppointment-banner { - background-image: url('~/assets/images/myAppointmentList/agent_banner_web.svg'); - } - } - - .pam-container { - margin: 30px 20px; - } - - @include desktop { - .pam-container { - width: 700px; - margin: 30px auto; - } - } -</style> \ No newline at end of file diff --git a/PAMapp/pages/myAppointmentList/appointmentList/appointment-list.component.scss b/PAMapp/pages/myAppointmentList/appointmentList/appointment-list.component.scss new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/PAMapp/pages/myAppointmentList/appointmentList/appointment-list.component.scss diff --git a/PAMapp/pages/myAppointmentList/appointmentList.vue b/PAMapp/pages/myAppointmentList/appointmentList/appointment-list.component.ts similarity index 67% rename from PAMapp/pages/myAppointmentList/appointmentList.vue rename to PAMapp/pages/myAppointmentList/appointmentList/appointment-list.component.ts index 8cee481..03e33bc 100644 --- a/PAMapp/pages/myAppointmentList/appointmentList.vue +++ b/PAMapp/pages/myAppointmentList/appointmentList/appointment-list.component.ts @@ -1,28 +1,3 @@ -<template> - <div> - <el-input - type="text" - placeholder="隢撓���摮�" - class="mb-30 pam-clientReserved-input" - v-model="keyWord" - @keyup.enter.native="search" - > - <i slot="suffix" class="icon-search search cursor--pointer" @click="search"></i> - </el-input> - - <ClientList - :clients="pageList" - :title="'reservedList'" - ></ClientList> - - <UiPagination - :totalList="filterList" - @changePage="changePage" - ></UiPagination> - </div> -</template> - -<script lang="ts"> import { Vue, Component, State, Watch } from 'nuxt-property-decorator'; import { ClientInfo } from '~/assets/ts/api/appointment'; @@ -64,4 +39,3 @@ } } -</script> \ No newline at end of file diff --git a/PAMapp/pages/myAppointmentList/appointmentList/index.vue b/PAMapp/pages/myAppointmentList/appointmentList/index.vue new file mode 100644 index 0000000..e9212ad --- /dev/null +++ b/PAMapp/pages/myAppointmentList/appointmentList/index.vue @@ -0,0 +1,29 @@ +<template> + <div> + <el-input + type="text" + placeholder="隢撓���摮�" + class="mb-30 pam-clientReserved-input" + v-model="keyWord" + @keyup.enter.native="search" + > + <i slot="suffix" class="icon-search search cursor--pointer" @click="search"></i> + </el-input> + + <ClientList + :clients="pageList" + :title="'reservedList'" + ></ClientList> + + <UiPagination + :totalList="filterList" + @changePage="changePage" + ></UiPagination> + </div> +</template> + +<script src="./appointment-list.component.ts"></script> + +<style lang="scss" scoped> + @import "./appointment-list.component.scss"; +</style> diff --git a/PAMapp/pages/myAppointmentList/contactedList.vue b/PAMapp/pages/myAppointmentList/contactedList.vue deleted file mode 100644 index 15954b7..0000000 --- a/PAMapp/pages/myAppointmentList/contactedList.vue +++ /dev/null @@ -1,64 +0,0 @@ -<template> - <div> - <el-input - type="text" - placeholder="隢撓���摮�" - class="mb-30 pam-clientReserved-input" - v-model="keyWord" - @keyup.enter.native="search" - > - <i - slot="suffix" - class="icon-search search cursor--pointer" - @click="search" - ></i> - </el-input> - - <ClientList - :clients="pageList" - :title="'contactedList'" - ></ClientList> - - <UiPagination - :totalList="filterList" - @changePage="changePage" - ></UiPagination> - </div> -</template> - -<script lang="ts"> -import { Vue, Component, Watch, State } from 'nuxt-property-decorator'; -import { ClientInfo } from '~/assets/ts/api/appointment'; - -@Component -export default class ClientContactedList extends Vue { - @State('myAppointmentList') myAppointmentList!: ClientInfo[]; - - contactedList: ClientInfo[] = []; - pageList: ClientInfo[] = []; - keyWord: string = ''; - filterList: ClientInfo[] = []; - - @Watch('myAppointmentList') - onMyAppointmentListChange() { - this.contactedList = (this.myAppointmentList || []) - .filter(item => item.communicateStatus === 'contacted') - .sort((a, b) => a.contactTime > b.contactTime ? -1 : 1); - this.filterList = this.contactedList; - } - - mounted() { - this.onMyAppointmentListChange(); - } - - changePage(pageList: ClientInfo[]) { - this.pageList = pageList; - } - - search() { - this.filterList = this.contactedList.filter(item => { - return item.name.match(this.keyWord) || item.requirement.match(this.keyWord) - }) - } -} -</script> \ No newline at end of file diff --git a/PAMapp/pages/myAppointmentList/contactedList/contacted-list.component.scss b/PAMapp/pages/myAppointmentList/contactedList/contacted-list.component.scss new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/PAMapp/pages/myAppointmentList/contactedList/contacted-list.component.scss diff --git a/PAMapp/pages/myAppointmentList/contactedList/contacted-list.component.ts b/PAMapp/pages/myAppointmentList/contactedList/contacted-list.component.ts new file mode 100644 index 0000000..7c2aeb2 --- /dev/null +++ b/PAMapp/pages/myAppointmentList/contactedList/contacted-list.component.ts @@ -0,0 +1,34 @@ +import { Vue, Component, Watch, State } from 'nuxt-property-decorator'; +import { ClientInfo } from '~/assets/ts/api/appointment'; + +@Component +export default class ClientContactedList extends Vue { + @State('myAppointmentList') myAppointmentList!: ClientInfo[]; + + contactedList: ClientInfo[] = []; + pageList: ClientInfo[] = []; + keyWord: string = ''; + filterList: ClientInfo[] = []; + + @Watch('myAppointmentList') + onMyAppointmentListChange() { + this.contactedList = (this.myAppointmentList || []) + .filter(item => item.communicateStatus === 'contacted') + .sort((a, b) => a.contactTime > b.contactTime ? -1 : 1); + this.filterList = this.contactedList; + } + + mounted() { + this.onMyAppointmentListChange(); + } + + changePage(pageList: ClientInfo[]) { + this.pageList = pageList; + } + + search() { + this.filterList = this.contactedList.filter(item => { + return item.name.match(this.keyWord) || item.requirement.match(this.keyWord) + }) + } +} diff --git a/PAMapp/pages/myAppointmentList/contactedList/index.vue b/PAMapp/pages/myAppointmentList/contactedList/index.vue new file mode 100644 index 0000000..6c3d427 --- /dev/null +++ b/PAMapp/pages/myAppointmentList/contactedList/index.vue @@ -0,0 +1,33 @@ +<template> + <div> + <el-input + type="text" + placeholder="隢撓���摮�" + class="mb-30 pam-clientReserved-input" + v-model="keyWord" + @keyup.enter.native="search" + > + <i + slot="suffix" + class="icon-search search cursor--pointer" + @click="search" + ></i> + </el-input> + + <ClientList + :clients="pageList" + :title="'contactedList'" + ></ClientList> + + <UiPagination + :totalList="filterList" + @changePage="changePage" + ></UiPagination> + </div> +</template> + +<script src="./contacted-list.component.ts"></script> + +<style lang="scss" scoped> + @import "./contacted-list.component.scss"; +</style> diff --git a/PAMapp/pages/myAppointmentList/index.vue b/PAMapp/pages/myAppointmentList/index.vue new file mode 100644 index 0000000..de9a850 --- /dev/null +++ b/PAMapp/pages/myAppointmentList/index.vue @@ -0,0 +1,45 @@ +<template> + <div> + <div class="pam-myAppointment-banner"></div> + <div class="pam-container"> + <div class="pam-cus-tabs mb-30"> + <div + class="cus-tab-item" + :class="{'is-active': activeTabName === 'appointmentList'}" + @click="tabClick('appointmentList')" + >摰X���� + <span class="p">({{appointmentList.length}})</span> + </div> + <div + class="cus-tab-item" + :class="{'is-active': activeTabName === 'contactedList'}" + @click="tabClick('contactedList')" + >撌脰蝯� + <span class="p">({{contactedList.length}})</span> + </div> + </div> + + <NuxtChild></NuxtChild> + </div> + + <PopUpFrame + :isOpen.sync="showNewAppointmentNumber" + > + <div class="text--center mdTxt"> + <p class="mb-50">雿�� <span class="text--primary">{{newAppointmentNumber}}</span> �������</p> + <div class="text--center"> + <el-button + type="primary" + @click="showNewAppointmentNumber = false" + >������</el-button> + </div> + </div> + </PopUpFrame> + </div> +</template> + +<script src="./my-appointment.component.ts"></script> + +<style lang="scss" scoped> + @import "./my-appointment.component.scss"; +</style> diff --git a/PAMapp/pages/myAppointmentList/my-appointment.component.scss b/PAMapp/pages/myAppointmentList/my-appointment.component.scss new file mode 100644 index 0000000..46456ad --- /dev/null +++ b/PAMapp/pages/myAppointmentList/my-appointment.component.scss @@ -0,0 +1,26 @@ +.pam-myAppointment-banner { + width: 100%; + height: 120px; + background-size: cover; + background-repeat: no-repeat; + background-position: center; + position: relative; + background-image: url('~/assets/images/myAppointmentList/agent_banner_mob.svg'); +} + +@media (min-width: 768px) { + .pam-myAppointment-banner { + background-image: url('~/assets/images/myAppointmentList/agent_banner_web.svg'); + } +} + +.pam-container { + margin: 30px 20px; +} + +@include desktop { + .pam-container { + width: 700px; + margin: 30px auto; + } +} diff --git a/PAMapp/pages/myAppointmentList/my-appointment.component.ts b/PAMapp/pages/myAppointmentList/my-appointment.component.ts new file mode 100644 index 0000000..032d362 --- /dev/null +++ b/PAMapp/pages/myAppointmentList/my-appointment.component.ts @@ -0,0 +1,63 @@ + +import { Vue, Component, State, Action, Watch } from 'nuxt-property-decorator'; +import { allAppointmentsView, ClientInfo } from '~/assets/ts/api/appointment'; +import * as _ from 'lodash'; + +@Component({ + layout: 'home' +}) +export default class ClientReservedList extends Vue { + activeTabName = 'appointmentList'; + appointmentList: ClientInfo[] = []; + contactedList: ClientInfo[] = []; + clients: ClientInfo[] = []; + newAppointmentNumber: number = 0; + showNewAppointmentNumber = false; + + @State('myAppointmentList') myAppointmentList!: ClientInfo[]; + @Action storeMyAppointmentList!: () => Promise<number>; + + mounted() { + this.storeMyAppointmentList().then(newDataLength => { + this.newAppointmentNumber = newDataLength; + if (this.newAppointmentNumber > 0) { + this.showNewAppointmentNumber = true; + allAppointmentsView().then(res => res); + } + }); + + if (this.$route.name) { + this.activeTabName = this.$route.name.split('-')[1] + } + } + + @Watch('myAppointmentList') + onMyAppointmentListChange() { + this.contactedList = this.myAppointmentList + .filter(item => item.communicateStatus === 'contacted'); + + this.appointmentList = this.myAppointmentList + .filter(item => item.communicateStatus !== 'contacted'); + } + + tabClick(path: string) { + this.activeTabName = path; + this.$router.push('/myAppointmentList/' + this.activeTabName) + } + + get route(): string{ + const routeName = this.$route.name; + return routeName ? routeName:''; + }; + + get bannerClassName() { + return this.routeFormatBannerClass(this.route); + }; + + // format to {page}-banner or pam-no-banner tag + private routeFormatBannerClass(route: string): string { + const needBannerTags = ['myAppointmentList-appointmentList', 'myAppointmentList-contactedList']; + return _.includes(needBannerTags, route) ? route + '-banner' : 'pam-no-banner'; + }; + +} diff --git a/PAMapp/pages/myConsultantList/consultantList.vue b/PAMapp/pages/myConsultantList/consultantList.vue deleted file mode 100644 index b1b0a5c..0000000 --- a/PAMapp/pages/myConsultantList/consultantList.vue +++ /dev/null @@ -1,30 +0,0 @@ -<template> - <div> - <ConsultantList - :agents="pageList" - ></ConsultantList> - - <UiPagination - :totalList="consultantList" - @changePage="changePage" - ></UiPagination> - </div> -</template> - -<script lang="ts"> -import { Vue, Component, Prop, Getter } from 'nuxt-property-decorator'; -import { Consultant } from '~/assets/ts/models/consultant.model'; - - -@Component -export default class ConsultantPage extends Vue { - @Prop() consultantList!: Consultant[]; - @Getter isLogin!: boolean; - pageList: Consultant[] = []; - - changePage(pageList: Consultant[]) { - this.pageList = pageList; - } - -} -</script> \ No newline at end of file diff --git a/PAMapp/pages/myConsultantList/consultantList/consultant-list.component.scss b/PAMapp/pages/myConsultantList/consultantList/consultant-list.component.scss new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/PAMapp/pages/myConsultantList/consultantList/consultant-list.component.scss diff --git a/PAMapp/pages/myConsultantList/consultantList/consultant-list.component.ts b/PAMapp/pages/myConsultantList/consultantList/consultant-list.component.ts new file mode 100644 index 0000000..21a9b04 --- /dev/null +++ b/PAMapp/pages/myConsultantList/consultantList/consultant-list.component.ts @@ -0,0 +1,16 @@ + +import { Vue, Component, Prop, Getter } from 'nuxt-property-decorator'; +import { Consultant } from '~/assets/ts/models/consultant.model'; + + +@Component +export default class ConsultantPage extends Vue { + @Prop() consultantList!: Consultant[]; + @Getter isLogin!: boolean; + pageList: Consultant[] = []; + + changePage(pageList: Consultant[]) { + this.pageList = pageList; + } + +} diff --git a/PAMapp/pages/myConsultantList/consultantList/index.vue b/PAMapp/pages/myConsultantList/consultantList/index.vue new file mode 100644 index 0000000..881a7f1 --- /dev/null +++ b/PAMapp/pages/myConsultantList/consultantList/index.vue @@ -0,0 +1,18 @@ +<template> + <div> + <ConsultantList + :agents="pageList" + ></ConsultantList> + + <UiPagination + :totalList="consultantList" + @changePage="changePage" + ></UiPagination> + </div> +</template> + +<script src="./consultant-list.component.ts"></script> + +<style lang="scss" scoped> + @import "./consultant-list.component.scss"; +</style> diff --git a/PAMapp/pages/myConsultantList/contactedList.vue b/PAMapp/pages/myConsultantList/contactedList.vue deleted file mode 100644 index a9d3d72..0000000 --- a/PAMapp/pages/myConsultantList/contactedList.vue +++ /dev/null @@ -1,28 +0,0 @@ -<template> - <div> - <ConsultantList - :agents="pageList" - ></ConsultantList> - - <UiPagination - :totalList="contactedList" - @changePage="changePage" - ></UiPagination> - </div> -</template> - -<script lang="ts"> -import { Vue, Component, Prop } from 'nuxt-property-decorator' ; -import { Consultant } from '~/assets/ts/models/consultant.model'; - - -@Component -export default class ContactedList extends Vue { - @Prop() contactedList!: Consultant[]; - pageList: Consultant[] = []; - - changePage(pageList: Consultant[]) { - this.pageList = pageList; - } -} -</script> \ No newline at end of file diff --git a/PAMapp/pages/myConsultantList/contactedList/contacted-list.component.scss b/PAMapp/pages/myConsultantList/contactedList/contacted-list.component.scss new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/PAMapp/pages/myConsultantList/contactedList/contacted-list.component.scss diff --git a/PAMapp/pages/myConsultantList/contactedList/contacted-list.component.ts b/PAMapp/pages/myConsultantList/contactedList/contacted-list.component.ts new file mode 100644 index 0000000..53a6a6a --- /dev/null +++ b/PAMapp/pages/myConsultantList/contactedList/contacted-list.component.ts @@ -0,0 +1,13 @@ +import { Vue, Component, Prop } from 'nuxt-property-decorator' ; +import { Consultant } from '~/assets/ts/models/consultant.model'; + + +@Component +export default class ContactedList extends Vue { + @Prop() contactedList!: Consultant[]; + pageList: Consultant[] = []; + + changePage(pageList: Consultant[]) { + this.pageList = pageList; + } +} diff --git a/PAMapp/pages/myConsultantList/contactedList/contactedList.vue b/PAMapp/pages/myConsultantList/contactedList/contactedList.vue new file mode 100644 index 0000000..42663cf --- /dev/null +++ b/PAMapp/pages/myConsultantList/contactedList/contactedList.vue @@ -0,0 +1,18 @@ +<template> + <div> + <ConsultantList + :agents="pageList" + ></ConsultantList> + + <UiPagination + :totalList="contactedList" + @changePage="changePage" + ></UiPagination> + </div> +</template> + +<script src="./contacted-list.component.ts"></script> + +<style lang="scss" scoped> + @import "./contacted-list.component.scss"; +</style> diff --git a/PAMapp/pages/myConsultantList/index.vue b/PAMapp/pages/myConsultantList/index.vue new file mode 100644 index 0000000..bb67df2 --- /dev/null +++ b/PAMapp/pages/myConsultantList/index.vue @@ -0,0 +1,41 @@ +<template> + <div> + <div class="pam-cus-tabs mb-30"> + <div + class="cus-tab-item" + :class="{'is-active': activeTabName === 'consultantList'}" + @click="tabClick('consultantList')" + >憿批�� + <span class="p">({{consultantList.length}})</span> + </div> + <div + class="cus-tab-item" + :class="{'is-active': activeTabName === 'contactedList'}" + @click="tabClick('contactedList')" + >撌脰蝯� + <span class="p">({{contactedList.length}})</span> + </div> + </div> + + <NuxtChild + :contactedList="contactedList" + :consultantList="consultantList" + ></NuxtChild> + + <!-- <ConsultantList + :agents="pageList" + ></ConsultantList> + + <UiPagination + :totalList="consultantList" + @changePage="changePage" + ></UiPagination> --> + + </div> +</template> + +<script src="./my-consultant-list.component.ts"></script> + +<style lang="scss" scoped> + @import "./my-consultant-list.component.scss"; +</style> diff --git a/PAMapp/pages/myConsultantList/my-consultant-list.component.scss b/PAMapp/pages/myConsultantList/my-consultant-list.component.scss new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/PAMapp/pages/myConsultantList/my-consultant-list.component.scss diff --git a/PAMapp/pages/myConsultantList.vue b/PAMapp/pages/myConsultantList/my-consultant-list.component.ts similarity index 60% rename from PAMapp/pages/myConsultantList.vue rename to PAMapp/pages/myConsultantList/my-consultant-list.component.ts index 490d23c..2a4c907 100644 --- a/PAMapp/pages/myConsultantList.vue +++ b/PAMapp/pages/myConsultantList/my-consultant-list.component.ts @@ -1,30 +1,3 @@ -<template> - <div> - <div class="pam-cus-tabs mb-30"> - <div - class="cus-tab-item" - :class="{'is-active': activeTabName === 'consultantList'}" - @click="tabClick('consultantList')" - >憿批�� - <span class="p">({{consultantList.length}})</span> - </div> - <div - class="cus-tab-item" - :class="{'is-active': activeTabName === 'contactedList'}" - @click="tabClick('contactedList')" - >撌脰蝯� - <span class="p">({{contactedList.length}})</span> - </div> - </div> - - <NuxtChild - :contactedList="contactedList" - :consultantList="consultantList" - ></NuxtChild> - </div> -</template> - -<script lang='ts'> import { Vue, Component, Watch, State, Action } from 'nuxt-property-decorator'; import { Consultant } from '~/assets/ts/models/consultant.model'; @@ -66,4 +39,3 @@ } } -</script> \ No newline at end of file diff --git a/PAMapp/pages/questionnaire/_agentNo.vue b/PAMapp/pages/questionnaire/_agentNo.vue index 547af0a..9e60e96 100644 --- a/PAMapp/pages/questionnaire/_agentNo.vue +++ b/PAMapp/pages/questionnaire/_agentNo.vue @@ -127,397 +127,8 @@ </div> </template> -<script lang="ts"> - import { Vue, Component } from 'nuxt-property-decorator'; - import { addFavoriteConsultant, appointmentDemand, AppointmentParams, AppointmentRequests ,RegisterInfo } from '~/assets/ts/api/consultant'; - import { getRequestsFromStorage, setRequestsToStorage, getRequestQuestionFromStorage, removeRequestQuestionFromStorage } from '~/assets/ts/storageRequests'; - import { Gender } from '~/assets/ts/models/enum/Gender'; - import { ContactType } from '~/assets/ts/models/enum/ContactType'; - import _ from 'lodash'; - import { isLogin } from '~/assets/ts/auth'; +<script src="./questionnaire.component.ts"></script> - @Component - export default class Questionnaire extends Vue { - genderOptions=[ - { - title:'���', - label:Gender.MALE, - }, - { - title:'憟單��', - label:Gender.FEMALE, - } - ]; - - requirementOptions=[ - { - title:'�摨瑁����', - label:'�摨瑁����', - }, - { - title:'摮戊��', - label:'摮戊��', - }, - { - title:'鞈閬��', - label:'鞈閬��', - }, - { - title:'璅暑��隡�', - label:'璅暑��隡�', - }, - { - title:'靽�瑼�/閬��', - label:'靽�瑼�/閬��', - }, - { - title:'����', - label:'����', - }, - ]; - - ageRangeOptions=[ - { - title:'20甇脖誑銝�', - label:'under_20', - }, - { - title:'21-30 甇�', - label:'21-30' - }, - { - title:'31-40 甇�', - label:'31-40' - }, - { - title:'41-50 甇�', - label:'41-50' - }, - { - title:'46-55 甇�', - label:'46-55', - }, - { - title:'51-60 甇�', - label:'51-60', - }, - { - title:'61-70 甇�', - label:'61-70', - }, - { - title:'71 甇脖誑銝�', - label:'over_71', - } - ]; - - quesAboutList = [ - { - title:'�摨瑁����', - content:'����澈擃憿批末嚗�靽�兢蝳�嚗��������嚗��飩������摮拙��粥銝��頝荔�犖����迤閬����' - }, - { - title:'摮戊��', - content:'摮拙���������葦銋摮貊��撠靘�蒂�雿嚗飛���������������瓷嚗��楝銝���韏瑕飛��' - }, - { - title:'鞈閬��', - content:'��迤��瓷撖��雓寡�����嚗鈭箇�����蝳西瓷��◢�����Ⅱ靽�蝛拙��嚗�摰嗆��靘�末��皞���' - }, - { - title:'璅暑��隡�', - content:'�銝�頛拙����隡��摮���翰瘣鳴�停敺�����������隡瓷����撌勗�帘摰�嚗蝎曉蔗���僑鈭箇�������' - }, - { - title:'靽�瑼�/閬��', - content:'��瑼Z�撌梁������蝚血����靘�◢�蝘餉��瘙��' - }, - { - title:'����', - content:'���� ���������憸券�����鈭怒�����嚗���摰帘摰漲嚗��隞亙��澈��ˊ�靽���嚗�' - } - ]; - - myRequest: AppointmentRequests = { - phone : this.userInfo?.phone ? this.userInfo.phone : '', - email : this.userInfo?.email ? this.userInfo.email : '', - contactType : _.isEqual(this.userInfo?.contactType,ContactType.SMS) ? ContactType.PHONE: ContactType.EMAIL, - gender : '', - age : '', - job : '', - requirement : [], - hopeContactTime: [{ - selectWeekOptions : [], - selectTimesOptions: [], - }], - agentNo: '', - }; - - showDrawer= false; - sendReserve = false; - - beforeRouteEnter(to: any, from: any, next: any) { - next(vm => { - if (from.name === 'login' && !isLogin()) { - vm.$router.go(-1); - return; - } - - if (!isLogin()) { - vm.$router.push('/login'); - } - }) - } - - mounted(): void { - this.setMyRequest(); - } - - private setMyRequest(): void { - const storageMyRequest = getRequestsFromStorage(); - const storageMyQuestion = getRequestQuestionFromStorage(); - - if (storageMyRequest) { - this.myRequest = { - ...storageMyRequest, - hopeContactTime: storageMyRequest.hopeContactTime?.length - ? storageMyRequest.hopeContactTime - : [{ - selectWeekOptions: [], - selectTimesOptions: [], - }], - }; - } - - if (storageMyQuestion) { - this.myRequest = { - ...this.myRequest, - requirement: storageMyQuestion - } - removeRequestQuestionFromStorage(); - } - } - - get phoneValid(): boolean { - const rule = /^09[0-9]{8}$/; - return this.myRequest.phone - ? rule.test(this.myRequest.phone) && _.isEqual(this.myRequest.phone.length,10) - : true; - } - - get userInfo(): RegisterInfo { - const initUserInfo = JSON.parse(localStorage.getItem('userInfo')!); - return initUserInfo; - } - - get isDisabledSubmitBtn(): boolean { - return _.includes(this.myRequest.contactType,ContactType.PHONE) - ? !this.isHopeContactTimeDone() - : !this.phoneValid; - } - - get isLogin() { - return isLogin(); - } - - private isHopeContactTimeDone():boolean{ - return this.myRequest.hopeContactTime[0]?.selectWeekOptions.length >0 && this.myRequest.hopeContactTime[0]?.selectTimesOptions.length >0; - } - - sentDemand() { - addFavoriteConsultant([this.$route.params.agentNo]).then(res => this.sentAppointmentDemand()); - } - - private sentAppointmentDemand() { - const data: AppointmentParams = { - ...this.myRequest, - requirement: _.map(this.myRequest.requirement,o=>o).toString(), - hopeContactTime: this.myRequest.phone && this.phoneValid ? this.getHopeContactTime() :'', - agentNo: this.$route.params.agentNo - }; - - appointmentDemand(data).then(res => { - this.sendReserve = true; - this.myRequest.hopeContactTime = []; - setRequestsToStorage(this.myRequest); - }); - } - - getHopeContactTime() { - const selectedHopeContactTime = this.myRequest.hopeContactTime.filter((i) => i.selectWeekOptions?.length && i.selectTimesOptions?.length); - return selectedHopeContactTime.map(i => { - return `'${i.selectWeekOptions}��${i.selectTimesOptions}'`} - ).toString(); - } - - closeReservePopUp() { - this.sendReserve = false; - this.$router.push('/') - } - - } -</script> - -<style lang="scss" scoped> -.sendReserve-txt{ - display: flex; - justify-content: center; - margin-top: 10px; - margin-bottom: 26px; -} - -//drawer��摨���見撘� -.qa-dialog-footer{ - display: flex; - justify-content: center; - margin-bottom: 81px; - color: #ED1B2E; - cursor: pointer; -} - -//����見撘���� -.ques-footer{ - justify-content: center; - margin: 30px 0; - display: flex; - flex-direction: column; - align-items: center; - .el-button { - width: 120px; - height:50px; - background-color: #ED1B2E; - color:#FFFFFF; - font-weight: normal; - @extend .text--middle ; - &.el-button--default { - color: $PRIMARY_RED; - background-color: #FFFFFF; - border-color: $PRIMARY_RED; - } - &.el-button--primary { - background-color: $PRIMARY_RED; - border-color: $PRIMARY_RED; - } - &.is-disabled { - color: $PRIMARY_WHITE; - background-color: $MID_GREY; - border-color: $MID_GREY; - border-style: solid; - pointer-events: none; - } - } -} - -//閰喟敦���rawer銝剝�摰寧征��之撠身蝵� -.qa-dialog{ - overflow-y:auto; - height: 500px; - margin-top: 20px; -} - -//閰喟敦���rawer銝餉���� -.qaTextTitle{ - margin-top:30px; - display: flex; - justify-content: center; -} - -.el-button+.el-button{ - margin-left: 0; -} - -.datepicker{ - display: flex; - flex-direction: column; -} - -.required { - position: relative; - &::before { - content: '*'; - position: absolute; - color: #FF0000; - transform: translate(-12px, 0); - } -} - -.ques-page--reset.pam-page-container { - margin: 0px auto; -} - -.ques-header { - position: relative; -} - -.ques-header__mob-banner { - width: 100%; - min-height: 80px; - background-color: #F8F9FA; - background-image: url('~/assets/images/questionnaire/reserve_bg_mob.svg'); - background-repeat: no-repeat; - background-size: cover; - background-position: center; -} - -.ques-header__info { - position: relative; - padding:30px 20px; - margin: 0px 20px; - background-color: #B3E7E3; - border-radius: 10px; -} - -.ques-header__input-block { - display: flex; - align-items: center; - @extend .text--middle,.mt-10 ; - .ques-header__input{ - &.is-invalid{ - border: 2px solid $PRIMARY_RED !important; - } - flex: 1; - height: 50px; - border-radius: 10px; - border: 1px #CCCCCC solid; - background-color: $PRIMARY_WHITE; - padding: 15px 10px; - box-sizing: border-box; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - } -} - -.ques-container { - position: relative; - margin: 0px 20px; -} - - -@include desktop{ - .ques-header{ - display: flex; - justify-content: flex-end; - min-height: 460px; - background-image: url('~/assets/images/questionnaire/reserve_bg_web.svg'); - background-repeat: no-repeat; - background-size: contain; - background-position: bottom; - } - .ques-header__mob-banner{ - display: none; - } - .ques-header__info{ - margin: 30px 20px; - width:500px; - min-height: 400px; - -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; /* Firefox, other Gecko */ - box-sizing: border-box; - } - .ques-container{ - margin: 0px; - } -} - +<style lang="scss"> + @import "./questionnaire.component.scss"; </style> - diff --git a/PAMapp/pages/questionnaire/questionnaire.component.scss b/PAMapp/pages/questionnaire/questionnaire.component.scss new file mode 100644 index 0000000..ee03a39 --- /dev/null +++ b/PAMapp/pages/questionnaire/questionnaire.component.scss @@ -0,0 +1,159 @@ +.sendReserve-txt{ + display: flex; + justify-content: center; + margin-top: 10px; + margin-bottom: 26px; +} + +//drawer��摨���見撘� +.qa-dialog-footer{ + display: flex; + justify-content: center; + margin-bottom: 81px; + color: #ED1B2E; + cursor: pointer; +} + +//����見撘���� +.ques-footer{ + justify-content: center; + margin: 30px 0; + display: flex; + flex-direction: column; + align-items: center; + .el-button { + width: 120px; + height:50px; + background-color: #ED1B2E; + color:#FFFFFF; + font-weight: normal; + @extend .text--middle ; + &.el-button--default { + color: $PRIMARY_RED; + background-color: #FFFFFF; + border-color: $PRIMARY_RED; + } + &.el-button--primary { + background-color: $PRIMARY_RED; + border-color: $PRIMARY_RED; + } + &.is-disabled { + color: $PRIMARY_WHITE; + background-color: $MID_GREY; + border-color: $MID_GREY; + border-style: solid; + pointer-events: none; + } + } +} + +//閰喟敦���rawer銝剝�摰寧征��之撠身蝵� +.qa-dialog{ + overflow-y:auto; + height: 500px; + margin-top: 20px; +} + +//閰喟敦���rawer銝餉���� +.qaTextTitle{ + margin-top:30px; + display: flex; + justify-content: center; +} + +.el-button+.el-button{ + margin-left: 0; +} + +.datepicker{ + display: flex; + flex-direction: column; +} + +.required { + position: relative; + &::before { + content: '*'; + position: absolute; + color: #FF0000; + transform: translate(-12px, 0); + } +} + +.ques-page--reset.pam-page-container { + margin: 0px auto; +} + +.ques-header { + position: relative; +} + +.ques-header__mob-banner { + width: 100%; + min-height: 80px; + background-color: #F8F9FA; + background-image: url('~/assets/images/questionnaire/reserve_bg_mob.svg'); + background-repeat: no-repeat; + background-size: cover; + background-position: center; +} + +.ques-header__info { + position: relative; + padding:30px 20px; + margin: 0px 20px; + background-color: #B3E7E3; + border-radius: 10px; +} + +.ques-header__input-block { + display: flex; + align-items: center; + @extend .text--middle,.mt-10 ; + .ques-header__input{ + &.is-invalid{ + border: 2px solid $PRIMARY_RED !important; + } + flex: 1; + height: 50px; + border-radius: 10px; + border: 1px #CCCCCC solid; + background-color: $PRIMARY_WHITE; + padding: 15px 10px; + box-sizing: border-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + } +} + +.ques-container { + position: relative; + margin: 0px 20px; +} + + +@include desktop{ + .ques-header{ + display: flex; + justify-content: flex-end; + min-height: 460px; + background-image: url('~/assets/images/questionnaire/reserve_bg_web.svg'); + background-repeat: no-repeat; + background-size: contain; + background-position: bottom; + } + .ques-header__mob-banner{ + display: none; + } + .ques-header__info{ + margin: 30px 20px; + width:500px; + min-height: 400px; + -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ + -moz-box-sizing: border-box; /* Firefox, other Gecko */ + box-sizing: border-box; + } + .ques-container{ + margin: 0px; + } +} diff --git a/PAMapp/pages/questionnaire/questionnaire.component.ts b/PAMapp/pages/questionnaire/questionnaire.component.ts new file mode 100644 index 0000000..a5dddc4 --- /dev/null +++ b/PAMapp/pages/questionnaire/questionnaire.component.ts @@ -0,0 +1,228 @@ +import { Vue, Component } from 'nuxt-property-decorator'; +import { addFavoriteConsultant, appointmentDemand, AppointmentParams, AppointmentRequests ,RegisterInfo } from '~/assets/ts/api/consultant'; +import { getRequestsFromStorage, setRequestsToStorage, getRequestQuestionFromStorage, removeRequestQuestionFromStorage } from '~/assets/ts/storageRequests'; +import { Gender } from '~/assets/ts/models/enum/gender.enum'; +import { ContactType } from '~/assets/ts/models/enum/ContactType'; +import _ from 'lodash'; +import { isLogin } from '~/assets/ts/auth'; + +@Component +export default class Questionnaire extends Vue { + genderOptions=[ + { + title:'���', + label:Gender.MALE, + }, + { + title:'憟單��', + label:Gender.FEMALE, + } + ]; + + requirementOptions=[ + { + title:'�摨瑁����', + label:'�摨瑁����', + }, + { + title:'摮戊��', + label:'摮戊��', + }, + { + title:'鞈閬��', + label:'鞈閬��', + }, + { + title:'璅暑��隡�', + label:'璅暑��隡�', + }, + { + title:'靽�瑼�/閬��', + label:'靽�瑼�/閬��', + }, + { + title:'����', + label:'����', + }, + ]; + + ageRangeOptions=[ + { + title:'20甇脖誑銝�', + label:'under_20', + }, + { + title:'21-30 甇�', + label:'21-30' + }, + { + title:'31-40 甇�', + label:'31-40' + }, + { + title:'41-50 甇�', + label:'41-50' + }, + { + title:'46-55 甇�', + label:'46-55', + }, + { + title:'51-60 甇�', + label:'51-60', + }, + { + title:'61-70 甇�', + label:'61-70', + }, + { + title:'71 甇脖誑銝�', + label:'over_71', + } + ]; + + quesAboutList = [ + { + title:'�摨瑁����', + content:'����澈擃憿批末嚗�靽�兢蝳�嚗��������嚗��飩������摮拙��粥銝��頝荔�犖����迤閬����' + }, + { + title:'摮戊��', + content:'摮拙���������葦銋摮貊��撠靘�蒂�雿嚗飛���������������瓷嚗��楝銝���韏瑕飛��' + }, + { + title:'鞈閬��', + content:'��迤��瓷撖��雓寡�����嚗鈭箇�����蝳西瓷��◢�����Ⅱ靽�蝛拙��嚗�摰嗆��靘�末��皞���' + }, + { + title:'璅暑��隡�', + content:'�銝�頛拙����隡��摮���翰瘣鳴�停敺�����������隡瓷����撌勗�帘摰�嚗蝎曉蔗���僑鈭箇�������' + }, + { + title:'靽�瑼�/閬��', + content:'��瑼Z�撌梁������蝚血����靘�◢�蝘餉��瘙��' + }, + { + title:'����', + content:'���� ���������憸券�����鈭怒�����嚗���摰帘摰漲嚗��隞亙��澈��ˊ�靽���嚗�' + } + ]; + + myRequest: AppointmentRequests = { + phone : this.userInfo?.phone ? this.userInfo.phone : '', + email : this.userInfo?.email ? this.userInfo.email : '', + contactType : _.isEqual(this.userInfo?.contactType,ContactType.SMS) ? ContactType.PHONE: ContactType.EMAIL, + gender : '', + age : '', + job : '', + requirement : [], + hopeContactTime: [{ + selectWeekOptions : [], + selectTimesOptions: [], + }], + agentNo: '', + }; + + showDrawer= false; + sendReserve = false; + + beforeRouteEnter(to: any, from: any, next: any) { + next(vm => { + if (from.name === 'login' && !isLogin()) { + vm.$router.go(-1); + return; + } + + if (!isLogin()) { + vm.$router.push('/login'); + } + }) + } + + mounted(): void { + this.setMyRequest(); + } + + private setMyRequest(): void { + const storageMyRequest = getRequestsFromStorage(); + const storageMyQuestion = getRequestQuestionFromStorage(); + + if (storageMyRequest) { + this.myRequest = { + ...storageMyRequest, + hopeContactTime: storageMyRequest.hopeContactTime?.length + ? storageMyRequest.hopeContactTime + : [{ + selectWeekOptions: [], + selectTimesOptions: [], + }], + }; + } + + if (storageMyQuestion) { + this.myRequest = { + ...this.myRequest, + requirement: storageMyQuestion + } + removeRequestQuestionFromStorage(); + } + } + + get phoneValid(): boolean { + const rule = /^09[0-9]{8}$/; + return this.myRequest.phone + ? rule.test(this.myRequest.phone) && _.isEqual(this.myRequest.phone.length,10) + : true; + } + + get userInfo(): RegisterInfo { + const initUserInfo = JSON.parse(localStorage.getItem('userInfo')!); + return initUserInfo; + } + + get isDisabledSubmitBtn(): boolean { + return _.includes(this.myRequest.contactType,ContactType.PHONE) + ? !this.isHopeContactTimeDone() + : !this.phoneValid; + } + + get isLogin() { + return isLogin(); + } + + private isHopeContactTimeDone():boolean{ + return this.myRequest.hopeContactTime[0]?.selectWeekOptions.length >0 && this.myRequest.hopeContactTime[0]?.selectTimesOptions.length >0; + } + + sentDemand() { + addFavoriteConsultant([this.$route.params.agentNo]).then(res => this.sentAppointmentDemand()); + } + + private sentAppointmentDemand() { + const data: AppointmentParams = { + ...this.myRequest, + requirement: _.map(this.myRequest.requirement,o=>o).toString(), + hopeContactTime: this.myRequest.phone && this.phoneValid ? this.getHopeContactTime() :'', + agentNo: this.$route.params.agentNo + }; + + appointmentDemand(data).then(res => { + this.sendReserve = true; + this.myRequest.hopeContactTime = []; + setRequestsToStorage(this.myRequest); + }); + } + + getHopeContactTime() { + const selectedHopeContactTime = this.myRequest.hopeContactTime.filter((i) => i.selectWeekOptions?.length && i.selectTimesOptions?.length); + return selectedHopeContactTime.map(i => { + return `'${i.selectWeekOptions}��${i.selectTimesOptions}'`} + ).toString(); + } + + closeReservePopUp() { + this.sendReserve = false; + this.$router.push('/') + } + +} diff --git a/PAMapp/pages/quickFilter/index.vue b/PAMapp/pages/quickFilter/index.vue index c6ef025..cb9f95a 100644 --- a/PAMapp/pages/quickFilter/index.vue +++ b/PAMapp/pages/quickFilter/index.vue @@ -64,213 +64,8 @@ </div> </template> -<script lang="ts"> -import { Vue, Component, namespace } from 'nuxt-property-decorator'; -import { FastQueryParams } from '~/assets/ts/api/consultant'; -import { Consultant } from '~/assets/ts/models/consultant.model'; -import { Selected } from '~/components/QuickFilter/QuickFilterSelector.vue'; -import { fastQuery } from '~/assets/ts/api/consultant'; +<script src="./quick-filter.component.ts"></script> -const localStorage = namespace('localStorage'); -@Component -export default class QuickFilter extends Vue { - @localStorage.Mutation storageQuickFilter!: (token: string) => void; - @localStorage.Getter quickFilterSelectedData!: Selected[]; - - isOpenQuestionPopUp = false; - consultantList: Consultant[] = []; - questionOption = {}; - confirmItem: Selected[] = []; - questionList: QuestionOption[] = [ - { - name: 'gender', - title: '憿批��批', - detail: [ - { name: '���', value: 'male', className: 'btn_man'}, - { name: '憟單��', value: 'female', className: 'btn_woman'} - ], - type: 'radio' - }, - { - name: 'avgScore', - title: '憿批�遛��漲', - detail: [], - type: '' - }, - { - name: 'communicationStyles', - title: '皞�◢�', - detail: [ - { value: '雓寞��祕', className: 'btn_owl'}, - { value: '��翰銝餃��', className: 'btn_tiger'}, - { value: '���', className: 'btn_koala'}, - { value: '�隢◢頞�', className: 'btn_peacock'} - ], - type: 'checkbox' - }, - // { - // name: 'status', - // title: '銝�����', - // detail: [], - // type: 'radio' - // } - ]; - - mounted() { - if (this.quickFilterSelectedData && this.quickFilterSelectedData.length > 0) { - this.confirmItem = this.quickFilterSelectedData; - this.getRecommendList(); - } - } - - gender(): string { - const filter = this.confirmItem.filter(item => item.option === 'gender').map(i => i.value); - return filter.length === 0 ? '' : filter[0]; - } - - avgScore(): number { - const filter = this.confirmItem.filter(item => item.option === 'avgScore').map(i => i.value); - return filter.length === 0 ? '' : filter[0]; - } - - communicationStyles(): string[] { - return this.confirmItem.filter(item => item.option === 'communicationStyles').map(i => i.value); - } - - isActive(name: string) { - return name === 'gender' && !!this.gender() - || name === 'avgScore' && !!this.avgScore() - || name === 'communicationStyles' && !!this.communicationStyles().length - } - - openPopUp(question: QuestionOption) { - this.questionOption = question; - this.isOpenQuestionPopUp =true; - } - - removeTag(value: string) { - this.confirmItem = this.confirmItem.filter(item => item.value !== value); - this.confirmItem.length > 0 ? this.getRecommendList() : this.consultantList = []; - } - - confirm(event: Selected) { - this.setConfirmData(event); - this.confirmItem.length > 0 ? this.getRecommendList() : this.consultantList = []; - this.isOpenQuestionPopUp = false; - } - - setConfirmData(event: Selected) { - if (event.option === 'communicationStyles') { - this.filterCommunicationStyles(event); - } else { - const findIndex = this.confirmItem.findIndex(item => item.option === event.option); - findIndex === -1 ? this.confirmItem.push(event) : this.confirmItem[findIndex] = event; - } - } - - filterCommunicationStyles(event: Selected) { - const confirmValue = this.confirmItem - .filter(item => item.option === 'communicationStyles') - .map(i => i.value); - const pickerValue = event.value; - - this.confirmItem = this.confirmItem - .filter(item => pickerValue.includes(item.value) || item.option !== 'communicationStyles'); - - const addValue = pickerValue.filter(item => !confirmValue.includes(item)).map(i => { - return { - option: 'communicationStyles', - value: i - } - }) - if (addValue.length > 0) { - this.confirmItem.push(...addValue); - } - } - - getRecommendList() { - const data: FastQueryParams = { - gender: this.gender(), - communicationStyles: this.communicationStyles(), - avgScore: this.avgScore(), - status: '' - } - - fastQuery(data).then((res) => { - this.consultantList = res.data; - this.storageQuickFilter(JSON.stringify(this.confirmItem)) - }) - } - -} - -export interface QuestionOption { - title: string; - detail: Detail[]; - type: string; - name: string; -} - -interface Detail { - value: string; - name?: string; - className: string; -} - -</script> - -<style lang="scss" scoped> - .emptyBox { - width: 100%; - height: 100px; - border: solid 1px $LIGHT_GREY; - text-align: center; - border-radius: 10px; - - .smTxt { - line-height: 100px; - } - } - - .recommendStyle { - box-shadow: 0 0 6px #00000029; - background-color: $PRIMARY_WHITE; - } - - .quickBtnBlock { - display: flex; - width: 100%; - height: 132px; - flex-wrap: wrap; - justify-content: space-between; - - .quickBtn { - width: 48%; - height: 56px; - text-align: center; - box-shadow: 0 0 6px #22222229; - border-radius: 10px; - border-color: $CORAL; - - &.isActive { - background-color: $CORAL; - color: $PRIMARY_WHITE; - } - } - .quickBtn+.quickBtn { - margin-left: 0; - } - - } - - .recommend { - position: relative; - - .img { - position: absolute; - top: -50px; - right: 10px; - } - } - -</style> \ No newline at end of file +<style lang="scss"> + @import "./quick-filter.component.scss"; +</style> diff --git a/PAMapp/pages/quickFilter/quick-filter.component.scss b/PAMapp/pages/quickFilter/quick-filter.component.scss new file mode 100644 index 0000000..d03cdfa --- /dev/null +++ b/PAMapp/pages/quickFilter/quick-filter.component.scss @@ -0,0 +1,52 @@ +.emptyBox { + width: 100%; + height: 100px; + border: solid 1px $LIGHT_GREY; + text-align: center; + border-radius: 10px; + + .smTxt { + line-height: 100px; + } +} + +.recommendStyle { + box-shadow: 0 0 6px #00000029; + background-color: $PRIMARY_WHITE; +} + +.quickBtnBlock { + display: flex; + width: 100%; + height: 132px; + flex-wrap: wrap; + justify-content: space-between; + + .quickBtn { + width: 48%; + height: 56px; + text-align: center; + box-shadow: 0 0 6px #22222229; + border-radius: 10px; + border-color: $CORAL; + + &.isActive { + background-color: $CORAL; + color: $PRIMARY_WHITE; + } + } + .quickBtn+.quickBtn { + margin-left: 0; + } + +} + +.recommend { + position: relative; + + .img { + position: absolute; + top: -50px; + right: 10px; + } +} diff --git a/PAMapp/pages/quickFilter/quick-filter.component.ts b/PAMapp/pages/quickFilter/quick-filter.component.ts new file mode 100644 index 0000000..4cfdd1c --- /dev/null +++ b/PAMapp/pages/quickFilter/quick-filter.component.ts @@ -0,0 +1,144 @@ + +import { Vue, Component, namespace } from 'nuxt-property-decorator'; + + +import { fastQuery } from '~/assets/ts/api/consultant'; +import { QuestionOption } from '~/assets/ts/models/question-option.model'; +import { Consultant } from '~/assets/ts/models/consultant.model'; +import { Selected } from '~/assets/ts/models/selected.model'; +import { FastQueryParams } from '~/assets/ts/models/fast-query-params.model'; + +const localStorage = namespace('localStorage'); +@Component +export default class QuickFilter extends Vue { + @localStorage.Mutation storageQuickFilter!: (token: string) => void; + @localStorage.Getter quickFilterSelectedData!: Selected[]; + + isOpenQuestionPopUp = false; + consultantList: Consultant[] = []; + questionOption = {}; + confirmItem: Selected[] = []; + questionList: QuestionOption[] = [ + { + name: 'gender', + title: '憿批��批', + detail: [ + { name: '���', value: 'male', className: 'btn_man'}, + { name: '憟單��', value: 'female', className: 'btn_woman'} + ], + type: 'radio' + }, + { + name: 'avgScore', + title: '憿批�遛��漲', + detail: [], + type: '' + }, + { + name: 'communicationStyles', + title: '皞�◢�', + detail: [ + { value: '雓寞��祕', className: 'btn_owl'}, + { value: '��翰銝餃��', className: 'btn_tiger'}, + { value: '���', className: 'btn_koala'}, + { value: '�隢◢頞�', className: 'btn_peacock'} + ], + type: 'checkbox' + }, + // { + // name: 'status', + // title: '銝�����', + // detail: [], + // type: 'radio' + // } + ]; + + mounted() { + if (this.quickFilterSelectedData && this.quickFilterSelectedData.length > 0) { + this.confirmItem = this.quickFilterSelectedData; + this.getRecommendList(); + } + } + + gender(): string { + const filter = this.confirmItem.filter(item => item.option === 'gender').map(i => i.value); + return filter.length === 0 ? '' : filter[0]; + } + + avgScore(): number { + const filter = this.confirmItem.filter(item => item.option === 'avgScore').map(i => i.value); + return filter.length === 0 ? '' : filter[0]; + } + + communicationStyles(): string[] { + return this.confirmItem.filter(item => item.option === 'communicationStyles').map(i => i.value); + } + + isActive(name: string) { + return name === 'gender' && !!this.gender() + || name === 'avgScore' && !!this.avgScore() + || name === 'communicationStyles' && !!this.communicationStyles().length + } + + openPopUp(question: QuestionOption) { + this.questionOption = question; + this.isOpenQuestionPopUp =true; + } + + removeTag(value: string) { + this.confirmItem = this.confirmItem.filter(item => item.value !== value); + this.confirmItem.length > 0 ? this.getRecommendList() : this.consultantList = []; + } + + confirm(event: Selected) { + this.setConfirmData(event); + this.confirmItem.length > 0 ? this.getRecommendList() : this.consultantList = []; + this.isOpenQuestionPopUp = false; + } + + setConfirmData(event: Selected) { + if (event.option === 'communicationStyles') { + this.filterCommunicationStyles(event); + } else { + const findIndex = this.confirmItem.findIndex(item => item.option === event.option); + findIndex === -1 ? this.confirmItem.push(event) : this.confirmItem[findIndex] = event; + } + } + + filterCommunicationStyles(event: Selected) { + const confirmValue = this.confirmItem + .filter(item => item.option === 'communicationStyles') + .map(i => i.value); + const pickerValue = event.value; + + this.confirmItem = this.confirmItem + .filter(item => pickerValue.includes(item.value) || item.option !== 'communicationStyles'); + + const addValue = pickerValue.filter(item => !confirmValue.includes(item)).map(i => { + return { + option: 'communicationStyles', + value: i + } + }) + if (addValue.length > 0) { + this.confirmItem.push(...addValue); + } + } + + getRecommendList() { + const data: FastQueryParams = { + gender: this.gender(), + communicationStyles: this.communicationStyles(), + avgScore: this.avgScore(), + status: '' + } + + fastQuery(data).then((res) => { + this.consultantList = res.data; + this.storageQuickFilter(JSON.stringify(this.confirmItem)) + }) + } + +} + + diff --git a/PAMapp/pages/recommendConsultant/criteria.vue b/PAMapp/pages/recommendConsultant/criteria.vue deleted file mode 100644 index 039388e..0000000 --- a/PAMapp/pages/recommendConsultant/criteria.vue +++ /dev/null @@ -1,3 +0,0 @@ -<template> - <div>������(����)</div> -</template> \ No newline at end of file diff --git a/PAMapp/pages/recommendConsultant/index.vue b/PAMapp/pages/recommendConsultant/index.vue index 37598dc..305c56d 100644 --- a/PAMapp/pages/recommendConsultant/index.vue +++ b/PAMapp/pages/recommendConsultant/index.vue @@ -1,5 +1,5 @@ <template> - <div class="pam-rec-cosultant-page"> + <div class="pam-rec-consultant-page"> <div class="pb-10 mdTxt">憿批��批</div> <SingleSelectBtn :singleSelected.sync="strictQueryDto.gender" :options="genderOptions"/> <div class="pam-paragraph"> @@ -83,495 +83,8 @@ </div> </template> -<script lang="ts"> - import { - Vue, - Component, - Mutation, - namespace, - Action, - State - } from 'nuxt-property-decorator'; - import * as _ from 'lodash'; - import { Seniority } from '~/assets/ts/models/enum/seniority'; - import { setRequestQuestionToStorage } from '~/assets/ts/storageRequests'; - - const localStorage = namespace('localStorage'); - - @Component - export default class RecommendConsultant extends Vue { - isVisiblePopUp = false; - strictQueryDto: StrictQueryDto ={ - gender:'', - area:'', - status:'', - requirements: [], - otherRequirement:'', - seniority:'', - avgScore:0, - popularTags: [], - otherPopularTags:'', - }; - genderOptions=[ - { - title:'���', - label:Gender.MALE, - }, - { - title:'憟單��', - label:Gender.FEMALE, - } - ]; - requirementOptions=[ - { - title:'�摨瑁����', - label:'�摨瑁����', - }, - { - title:'摮戊��', - label:'摮戊��', - }, - { - title:'鞈閬��', - label:'鞈閬��', - }, - { - title:'璅暑��隡�', - label:'璅暑��隡�', - }, - { - title:'靽�瑼�/閬��', - label:'靽�瑼�/閬��', - }, - { - title:'����', - label:'����', - }, - ]; - seniorityOptions=[ - { - title:'銝��', - subTitle:'撟湧翩銝����', - label:Seniority.UNLIMITED, - }, - { - title:'撟渲��', - subTitle:'蝯血僑頛犖銝�����', - label:Seniority.YOUNG, - }, - { - title:'鞈楛', - subTitle:'����麾', - label:Seniority.SENIOR, - } - ]; - popularOptions=[ - { - title: '#��', - label:'��' - }, - { - title: '#憭梯', - label:'憭梯' - }, - { - title: '#����', - label:'����' - }, - { - title: '#����', - label:'����' - }, - { - title: '#憯賡', - label: '憯賡' - }, - { - title: '#����', - label:'����' - }, - { - title: '#����', - label:'����' - }, - { - title: '#����', - label:'����' - } - ]; - queaAboutList = [ - { - title: '�摨瑁����', - content: '����澈擃憿批末嚗�靽�兢蝳�嚗��������嚗��飩������摮拙��粥銝��頝荔�犖����迤閬����' - }, - { - title: '摮戊��', - content: '摮拙���������葦銋摮貊��撠靘�蒂�雿嚗飛���������������瓷嚗��楝銝���韏瑕飛��' - }, - { - title: '鞈閬��', - content: '��迤��瓷撖��雓寡�����嚗鈭箇�����蝳西瓷��◢�����Ⅱ靽�蝛拙��嚗�摰嗆��靘�末��皞���' - }, - { - title: '璅暑��隡�', - content: '�銝�頛拙����隡��摮���翰瘣鳴�停敺�����������隡瓷����撌勗�帘摰�嚗蝎曉蔗���僑鈭箇�������' - }, - { - title: '靽�瑼�/閬��', - content: '��瑼Z�撌梁������蝚血����靘�◢�蝘餉��瘙��' - }, - { - title: '����', - content: '���� ���������憸券�����鈭怒�����嚗���摰帘摰漲嚗��隞亙��澈��ˊ�靽���嚗�' - } - ]; - showDialog = false; - showAddress = false; - - @Mutation updateStrictQueryList!: (data: any) => void; - @Action storeStrictQueryList!: (data: any) => Promise<number>; - @State strictQueryList!: any; - @localStorage.State recommendConsultantItem!: string; - - mounted() { - if (!!this.recommendConsultantItem) { - this.strictQueryDto = JSON.parse(this.recommendConsultantItem); - } - } - async makePair() { - await this.storeStrictQueryList(this.strictQueryDto).then(dataLength => { - const questions = this.strictQueryDto.requirements.length ? this.strictQueryDto.requirements : []; - setRequestQuestionToStorage(questions); - if (dataLength === 0) { - this.isVisiblePopUp = true; - return; - } - this.$router.push('/recommendConsultant/result'); - }); - } - get notFinishByRequireRules():boolean{ - const area = this.strictQueryDto.area; - const requirementLength = this.strictQueryDto.requirements - ? this.strictQueryDto.requirements.length - : 0; - return !(area && requirementLength >0) - } - - confirmAddress(area: string) { - this.strictQueryDto.area = area; - this.showAddress = false; - } - - } - enum Gender{ - MALE="male", - FEMALE="female", - } - - export interface StrictQueryDto { - gender: string, - area: string, - status: string, - requirements: string[], - otherRequirement: string, - seniority: string, - avgScore: number, - popularTags: string[], - otherPopularTags: string - } -</script> +<script src="./recommend-consultant.component.ts"></script> <style lang="scss"> - -.pam-rec-cosultant-page { - .rec-pop-container{ - width:310px; - .rec-pop-options{ - .el-checkbox-group{ - display: flex; - flex-wrap: wrap; - flex-direction: row; - .el-checkbox{ - width:90px; - height: 50px; - padding:0; - .el-checkbox__label{ - justify-content: center; - align-items: center; - display: flex; - padding:15px 20px; - text-align: center; - } - } - .pam-selectAll-btn{ - margin-top: 60px; - margin-left:-203px; - height: 50px; - width: 90px; - padding: 10px; - } - - } - } - - } - .rec-multi-select{ - .el-checkbox-group { - display: flex; - flex-direction: column; - align-items: flex-start; - } - } - - input:focus, - textarea:focus { - outline: none; - } - - .input { - border: none; - width: 90%; - border-radius: 10px; - } - - .job-pick { - height: 50px; - border-radius: 10px; - border: 1px solid #D0D0CE; - display: flex; - justify-content: space-between; - background-color: #FFFFFF; - } - - .down-icon { - color: #ED1B2E; - font-size: 25px; - align-self: center; - margin-right: 15px; - } - - .popOtherBtn { - margin-left: -190px; - margin-top: 45px; - } - - .genderBtn { - width: 80px; - height: 47px; - display: contents; - } - - .qa-dialog { - overflow-y: auto; - height: 500px; - margin-top: 20px; - text-align: justify; - } - - .qaTextTitle { - margin-top: 30px - } - - .qa-dialog-footer { - display: flex; - justify-content: center; - margin-bottom: 81px; - color: #ED1B2E; - cursor: pointer; - } - - .el-drawer__container ::-webkit-scrollbar { - display: none; - } - .el-button+.el-button { - margin-left: 0; - } - - .seniority-choice { - display: flex; - flex-wrap: wrap; - } - - .area-choice { - height: 50px; - border-radius: 10px; - border: 1px solid #D0D0CE; - display: flex; - justify-content: space-between; - background-color: #FFFFFF; - } - - .area-icon { - color: #ED1B2E; - font-size: 25px; - display: flex; - justify-content: flex-end; - padding-right: 16px; - padding-top: 11px; - } - - input::-webkit-input-placeholder { - font-size: 20px; - padding-left: 10px; - } - - .el-button.is-disabled { - font-size: 20px; - border-radius: 20px; - color: #FFFFFF; - background-color: #A7A8AA; - border: 1px solid #A7A8AA; - } - - .rec-footer { - height: 70px; - display: flex; - justify-content: center; - align-items: center; - } - - .other-PopBtn { - width: 90px; - height: 47px; - margin-top: 10px; - } - - - - .rec-ques-location { - display: flex; - align-items: center; - } - - .pop-tag { - display: flex; - flex-wrap: wrap; - margin: -10px; - - } - - .rec-popular { - display: flex; - align-items: baseline; - padding-top: 10px; - margin-bottom: 10px; - } - - .rec-btn-type { - padding-bottom: 10px; - } - - .rec-question { - display: flex; - flex-direction: column; - - } - - .rec-banner { - height: 120px; - background-color: #D0D0CE; - - } - - .rec-btn { - font-size: 20px; - border-radius: 20px; - color: black; - border: 1px solid #D0D0CE; - } - - .rec-pop-btn { - font-size: 20px; - border-radius: 20px; - color: black; - margin: 0px 0px 10px 10px; - border: 1px solid #D0D0CE; - width: 90px; - height: 47px; - } - - .el-progress__text { - display: none; - } - - .el-progress-bar { - padding-right: 0; - } - - .el-progress-bar__inner { - background-color: #ED1B2E; - } - - .required { - position: relative; - - &::before { - content: '*'; - position: absolute; - color: #FF0000; - transform: translate(-12px, 0); - z-index: 5; - } - } - - .area-txt { - display: flex; - align-items: center; - margin-left: 18px; - } - - @include desktop { - - .desktopBtn { - margin-right: 10px; - height: 47px - } - - .popOtherBtn { - margin-left: 10px; - margin-top: -10px; - } - - .rec-pop-container{ - width:auto; - .rec-pop-options{ - .el-checkbox-group{ - display: flex; - flex-wrap:wrap; - flex-direction: none; - .el-checkbox{ - width:90px; - height: 50px; - padding:0; - .el-checkbox__label{ - justify-content: center; - align-items: center; - display: flex; - padding:15px 20px; - text-align: center; - } - } - .pam-selectAll-btn{ - margin-top:0px; - margin-left:0px; - height: 50px; - width: 90px; - padding: 10px; - } - } - } - - } - - .rec-multi-select{ - .el-checkbox-group { - display: flex; - flex-direction: row; - align-items: flex-start; - flex-wrap: wrap; - } - } - } -} - + @import "./recommend-consultant.component.scss"; </style> diff --git a/PAMapp/pages/recommendConsultant/recommend-consultant.component.scss b/PAMapp/pages/recommendConsultant/recommend-consultant.component.scss new file mode 100644 index 0000000..3278a8f --- /dev/null +++ b/PAMapp/pages/recommendConsultant/recommend-consultant.component.scss @@ -0,0 +1,291 @@ + +.pam-rec-consultant-page { + .rec-pop-container{ + width:310px; + .rec-pop-options{ + .el-checkbox-group{ + display: flex; + flex-wrap: wrap; + flex-direction: row; + .el-checkbox{ + width:90px; + height: 50px; + padding:0; + .el-checkbox__label{ + justify-content: center; + align-items: center; + display: flex; + padding:15px 20px; + text-align: center; + } + } + .pam-selectAll-btn{ + margin-top: 60px; + margin-left:-203px; + height: 50px; + width: 90px; + padding: 10px; + } + + } + } + + } + .rec-multi-select{ + .el-checkbox-group { + display: flex; + flex-direction: column; + align-items: flex-start; + } + } + + input:focus, + textarea:focus { + outline: none; + } + + .input { + border: none; + width: 90%; + border-radius: 10px; + } + + .job-pick { + height: 50px; + border-radius: 10px; + border: 1px solid #D0D0CE; + display: flex; + justify-content: space-between; + background-color: #FFFFFF; + } + + .down-icon { + color: #ED1B2E; + font-size: 25px; + align-self: center; + margin-right: 15px; + } + + .popOtherBtn { + margin-left: -190px; + margin-top: 45px; + } + + .genderBtn { + width: 80px; + height: 47px; + display: contents; + } + + .qa-dialog { + overflow-y: auto; + height: 500px; + margin-top: 20px; + text-align: justify; + } + + .qaTextTitle { + margin-top: 30px + } + + .qa-dialog-footer { + display: flex; + justify-content: center; + margin-bottom: 81px; + color: #ED1B2E; + cursor: pointer; + } + + .el-drawer__container ::-webkit-scrollbar { + display: none; + } + .el-button+.el-button { + margin-left: 0; + } + + .seniority-choice { + display: flex; + flex-wrap: wrap; + } + + .area-choice { + height: 50px; + border-radius: 10px; + border: 1px solid #D0D0CE; + display: flex; + justify-content: space-between; + background-color: #FFFFFF; + } + + .area-icon { + color: #ED1B2E; + font-size: 25px; + display: flex; + justify-content: flex-end; + padding-right: 16px; + padding-top: 11px; + } + + input::-webkit-input-placeholder { + font-size: 20px; + padding-left: 10px; + } + + .el-button.is-disabled { + font-size: 20px; + border-radius: 20px; + color: #FFFFFF; + background-color: #A7A8AA; + border: 1px solid #A7A8AA; + } + + .rec-footer { + height: 70px; + display: flex; + justify-content: center; + align-items: center; + } + + .other-PopBtn { + width: 90px; + height: 47px; + margin-top: 10px; + } + + + + .rec-ques-location { + display: flex; + align-items: center; + } + + .pop-tag { + display: flex; + flex-wrap: wrap; + margin: -10px; + + } + + .rec-popular { + display: flex; + align-items: baseline; + padding-top: 10px; + margin-bottom: 10px; + } + + .rec-btn-type { + padding-bottom: 10px; + } + + .rec-question { + display: flex; + flex-direction: column; + + } + + .rec-banner { + height: 120px; + background-color: #D0D0CE; + + } + + .rec-btn { + font-size: 20px; + border-radius: 20px; + color: black; + border: 1px solid #D0D0CE; + } + + .rec-pop-btn { + font-size: 20px; + border-radius: 20px; + color: black; + margin: 0px 0px 10px 10px; + border: 1px solid #D0D0CE; + width: 90px; + height: 47px; + } + + .el-progress__text { + display: none; + } + + .el-progress-bar { + padding-right: 0; + } + + .el-progress-bar__inner { + background-color: #ED1B2E; + } + + .required { + position: relative; + + &::before { + content: '*'; + position: absolute; + color: #FF0000; + transform: translate(-12px, 0); + z-index: 5; + } + } + + .area-txt { + display: flex; + align-items: center; + margin-left: 18px; + } + + @include desktop { + + .desktopBtn { + margin-right: 10px; + height: 47px + } + + .popOtherBtn { + margin-left: 10px; + margin-top: -10px; + } + + .rec-pop-container{ + width:auto; + .rec-pop-options{ + .el-checkbox-group{ + display: flex; + flex-wrap:wrap; + flex-direction: none; + .el-checkbox{ + width:90px; + height: 50px; + padding:0; + .el-checkbox__label{ + justify-content: center; + align-items: center; + display: flex; + padding:15px 20px; + text-align: center; + } + } + .pam-selectAll-btn{ + margin-top:0px; + margin-left:0px; + height: 50px; + width: 90px; + padding: 10px; + } + } + } + + } + + .rec-multi-select{ + .el-checkbox-group { + display: flex; + flex-direction: row; + align-items: flex-start; + flex-wrap: wrap; + } + } + } +} diff --git a/PAMapp/pages/recommendConsultant/recommend-consultant.component.ts b/PAMapp/pages/recommendConsultant/recommend-consultant.component.ts new file mode 100644 index 0000000..7b12d6e --- /dev/null +++ b/PAMapp/pages/recommendConsultant/recommend-consultant.component.ts @@ -0,0 +1,183 @@ +import { + Vue, + Component, + Mutation, + namespace, + Action, + State +} from 'nuxt-property-decorator'; +import * as _ from 'lodash'; + +import { Seniority } from '~/assets/ts/models/enum/seniority'; +import { setRequestQuestionToStorage } from '~/assets/ts/storageRequests'; +import { Gender } from '~/assets/ts/models/enum/gender.enum'; +import { StrictQueryDto } from '~/assets/ts/models/strict-query-dto.model'; + +const localStorage = namespace('localStorage'); + +@Component +export default class RecommendConsultant extends Vue { + isVisiblePopUp = false; + strictQueryDto: StrictQueryDto ={ + gender:'', + area:'', + status:'', + requirements: [], + otherRequirement:'', + seniority:'', + avgScore:0, + popularTags: [], + otherPopularTags:'', + }; + genderOptions=[ + { + title:'���', + label:Gender.MALE, + }, + { + title:'憟單��', + label:Gender.FEMALE, + } + ]; + requirementOptions=[ + { + title:'�摨瑁����', + label:'�摨瑁����', + }, + { + title:'摮戊��', + label:'摮戊��', + }, + { + title:'鞈閬��', + label:'鞈閬��', + }, + { + title:'璅暑��隡�', + label:'璅暑��隡�', + }, + { + title:'靽�瑼�/閬��', + label:'靽�瑼�/閬��', + }, + { + title:'����', + label:'����', + }, + ]; + seniorityOptions=[ + { + title:'銝��', + subTitle:'撟湧翩銝����', + label:Seniority.UNLIMITED, + }, + { + title:'撟渲��', + subTitle:'蝯血僑頛犖銝�����', + label:Seniority.YOUNG, + }, + { + title:'鞈楛', + subTitle:'����麾', + label:Seniority.SENIOR, + } + ]; + popularOptions=[ + { + title: '#��', + label:'��' + }, + { + title: '#憭梯', + label:'憭梯' + }, + { + title: '#����', + label:'����' + }, + { + title: '#����', + label:'����' + }, + { + title: '#憯賡', + label: '憯賡' + }, + { + title: '#����', + label:'����' + }, + { + title: '#����', + label:'����' + }, + { + title: '#����', + label:'����' + } + ]; + queaAboutList = [ + { + title: '�摨瑁����', + content: '����澈擃憿批末嚗�靽�兢蝳�嚗��������嚗��飩������摮拙��粥銝��頝荔�犖����迤閬����' + }, + { + title: '摮戊��', + content: '摮拙���������葦銋摮貊��撠靘�蒂�雿嚗飛���������������瓷嚗��楝銝���韏瑕飛��' + }, + { + title: '鞈閬��', + content: '��迤��瓷撖��雓寡�����嚗鈭箇�����蝳西瓷��◢�����Ⅱ靽�蝛拙��嚗�摰嗆��靘�末��皞���' + }, + { + title: '璅暑��隡�', + content: '�銝�頛拙����隡��摮���翰瘣鳴�停敺�����������隡瓷����撌勗�帘摰�嚗蝎曉蔗���僑鈭箇�������' + }, + { + title: '靽�瑼�/閬��', + content: '��瑼Z�撌梁������蝚血����靘�◢�蝘餉��瘙��' + }, + { + title: '����', + content: '���� ���������憸券�����鈭怒�����嚗���摰帘摰漲嚗��隞亙��澈��ˊ�靽���嚗�' + } + ]; + showDialog = false; + showAddress = false; + + @Mutation updateStrictQueryList!: (data: any) => void; + @Action storeStrictQueryList!: (data: any) => Promise<number>; + @State strictQueryList!: any; + @localStorage.State recommendConsultantItem!: string; + + mounted() { + if (!!this.recommendConsultantItem) { + this.strictQueryDto = JSON.parse(this.recommendConsultantItem); + } + } + async makePair() { + await this.storeStrictQueryList(this.strictQueryDto).then(dataLength => { + const questions = this.strictQueryDto.requirements.length ? this.strictQueryDto.requirements : []; + setRequestQuestionToStorage(questions); + if (dataLength === 0) { + this.isVisiblePopUp = true; + return; + } + this.$router.push('/recommendConsultant/result'); + }); + } + get notFinishByRequireRules():boolean{ + const area = this.strictQueryDto.area; + const requirementLength = this.strictQueryDto.requirements + ? this.strictQueryDto.requirements.length + : 0; + return !(area && requirementLength >0) + } + + confirmAddress(area: string) { + this.strictQueryDto.area = area; + this.showAddress = false; + } + +} + diff --git a/PAMapp/pages/recommendConsultant/result.vue b/PAMapp/pages/recommendConsultant/result.vue deleted file mode 100644 index 0c06be1..0000000 --- a/PAMapp/pages/recommendConsultant/result.vue +++ /dev/null @@ -1,233 +0,0 @@ -<template> -<div> - <div class="mdTxt pb-10">��憿批��</div> - <ul class="pam-rec-agent__list"> - <li class="pam-rec-agent-card" v-for="(info,index) in pageList" :key="index"> - <div class="pam-rec-agent-card__content"> - <div class="pam-rec-agent-card__content-header"> - <div class="pam-rec-agent-card__avatar"> - <UiAvatar :fileName="info.img" ></UiAvatar> - </div> - <div class="pam-rec-agent-card__main-info"> - <div class="text--middle pt-10 rec-desktop-name">{{ info.name }}</div> - <div class="rec-role">{{ info.role }}</div> - <span class="rec-detail fix-chrome-click--issue" @click="showAgentDetail(info.agentNo)">閰喟敦鞈��</span> - </div> - </div> - <div class="pam-rec-agent-card__content-body"> - <el-row type="flex" class="pam-paragraph"> - <div class="field"> - <div class="field__label">撠����</div> - <div class="field__content expertieses-container"> - <div class="pr-10 pb-10" v-for="(expert, index) in info.expertise" :key="index"> - #{{ expert }} - </div> - </div> - </div> - </el-row> - - <el-row type="flex" class="pam-paragraph"> - <el-col :span="12"> - <div class="field__label"> - ����風 - </div> - <div class="field__content"> - {{ info.seniority }} - </div> - </el-col> - <el-col :span="12"> - <div class="field__label"> - 摰X皛踵�漲 - </div> - <div class="field__content"> - <i class="icon-star" style="color:#F2C75C"></i> - {{ info.avgScore }} - </div> - </el-col> - </el-row> - - </div> - <div class="pam-rec-agent-card__content-footer"> - <AddAndReservedBtns - :cusClass="'pam-rec-btns'" - :agentInfo="info" - @openPopUp="openPopUp" - ></AddAndReservedBtns> - </div> - </div> - </li> - </ul> - - <UiPagination - class="mb-30" - :totalList="strictQueryList" - @changePage="changePage" - :pageSize = 6 - ></UiPagination> - - <PopUpFrame :isOpen.sync="isVisiblePopUp" - > - <div class="text--center mdTxt"> - <p class="mb-50">{{popUpTxt}}</p> - <div class="text--center"> - <el-button - type="primary" - @click="isVisiblePopUp = false" - >������</el-button> - </div> - </div> - </PopUpFrame> - -</div> -</template> -<script lang="ts"> -import {Vue,Component, State, namespace, Action} from 'nuxt-property-decorator'; -import { AgentOfStrictQuery } from '~/assets/ts/api/consultant'; - -const localStorage = namespace('localStorage'); - -@Component -export default class Reslut extends Vue{ - @State('strictQueryList') strictQueryList!: AgentOfStrictQuery[]; - @Action storeStrictQueryList!: (data: any) => Promise<number>; - @localStorage.State recommendConsultantItem!: string; - - pageList: any[] = []; - isVisiblePopUp = false; - popUpTxt = ''; - mounted() { - if (this.recommendConsultantItem && this.strictQueryList.length === 0) { - const strictQueryDto = JSON.parse(this.recommendConsultantItem); - this.storeStrictQueryList(strictQueryDto); - } - } - - changePage(pageList: any[]) { - this.pageList = pageList; - } - showAgentDetail(agentNo: string): void { - this.$router.push(`/agentInfo/${agentNo}`); - } - openPopUp(txt: string) { - this.popUpTxt = txt; - this.isVisiblePopUp = true; - } -} -</script> - -<style lang="scss" scoped> -.pam-rec-agent-card { - margin-bottom: 10px; - border-radius: 10px; - border: 1px solid $LIGHT_GREY; - padding: 20px 33px; - - .pam-rec-agent-card__content { - .pam-rec-agent-card__content-header { - display: flex; - .pam-rec-agent-card__avatar { - display: flex; - flex-direction: row; - margin-right: 20px; - } - .pam-rec-agent-card__main-info { - display: flex; - flex-direction: column; - justify-content: flex-end; - .rec-role { - font-size: 16px; - color: $PRUDENTIAL_GREY; - font-weight: bold; - margin-top: 4px; - } - .rec-detail{ - font-size: 20px; - color:$PRIMARY_RED; - font-weight: bold; - padding-top: 30px; - cursor: pointer; - } - } - } - .pam-rec-agent-card__content-body { - height: 200px; - } - } -} - -.field__label { - font-size: 16px; - color: $PRUDENTIAL_GREY; - font-weight:bold; - margin-bottom: 7px; -} -.field__content{ - font-size: 18px; -} -.expertieses-container { - display: flex; - flex-wrap: wrap; -} - -@include desktop{ - .pam-rec-agent__list{ - display: flex; - flex-wrap: wrap; - flex-direction:row; - width: 100%; - } - .pam-paragraph{ - margin-top: 10px; - } - .pam-rec-agent-card { - border-radius: 10px; - border: 1px solid $LIGHT_GREY; - padding: 15px 20px 15px 20px; - width: 170px; - margin: 0 10px 10px 10px; - - .pam-rec-agent-card__content { - .pam-rec-agent-card__content-header { - display: flex; - .pam-rec-agent-card__avatar { - display: flex; - flex-direction: row; - margin-right: 20px; - } - .pam-rec-agent-card__main-info { - display: flex; - flex-direction: column; - justify-content: center; - .rec-desktop-name{ - font-size: 12px; - font-weight: bold; - } - .rec-role { - font-size: 12px; - color:$PRUDENTIAL_GREY; - } - .rec-detail{ - font-size: 12px; - color:$PRIMARY_RED; - font-weight: bold; - padding-top: 10px; - } - } - } - } - } - .field__label { - font-size: 12px; - color: $PRUDENTIAL_GREY; - font-weight:bold; - margin-bottom: 7px; - } - .field__content{ - font-size: 12px; - } - .expertieses-container { - display: flex; - flex-wrap: wrap; - } -} -</style> diff --git a/PAMapp/pages/recommendConsultant/result/index.vue b/PAMapp/pages/recommendConsultant/result/index.vue new file mode 100644 index 0000000..00ce1b1 --- /dev/null +++ b/PAMapp/pages/recommendConsultant/result/index.vue @@ -0,0 +1,88 @@ +<template> +<div> + <div class="mdTxt pb-10">��憿批��</div> + <ul class="pam-rec-agent__list"> + <li class="pam-rec-agent-card" v-for="(info,index) in pageList" :key="index"> + <div class="pam-rec-agent-card__content"> + <div class="pam-rec-agent-card__content-header"> + <div class="pam-rec-agent-card__avatar"> + <UiAvatar :fileName="info.img" ></UiAvatar> + </div> + <div class="pam-rec-agent-card__main-info"> + <div class="text--middle pt-10 rec-desktop-name">{{ info.name }}</div> + <div class="rec-role">{{ info.role }}</div> + <span class="rec-detail fix-chrome-click--issue" @click="showAgentDetail(info.agentNo)">閰喟敦鞈��</span> + </div> + </div> + <div class="pam-rec-agent-card__content-body"> + <el-row type="flex" class="pam-paragraph"> + <div class="field"> + <div class="field__label">撠����</div> + <div class="field__content expertieses-container"> + <div class="pr-10 pb-10" v-for="(expert, index) in info.expertise" :key="index"> + #{{ expert }} + </div> + </div> + </div> + </el-row> + + <el-row type="flex" class="pam-paragraph"> + <el-col :span="12"> + <div class="field__label"> + ����風 + </div> + <div class="field__content"> + {{ info.seniority }} + </div> + </el-col> + <el-col :span="12"> + <div class="field__label"> + 摰X皛踵�漲 + </div> + <div class="field__content"> + <i class="icon-star" style="color:#F2C75C"></i> + {{ info.avgScore }} + </div> + </el-col> + </el-row> + + </div> + <div class="pam-rec-agent-card__content-footer"> + <AddAndReservedBtns + :cusClass="'pam-rec-btns'" + :agentInfo="info" + @openPopUp="openPopUp" + ></AddAndReservedBtns> + </div> + </div> + </li> + </ul> + + <UiPagination + class="mb-30" + :totalList="strictQueryList" + @changePage="changePage" + :pageSize = 6 + ></UiPagination> + + <PopUpFrame :isOpen.sync="isVisiblePopUp" + > + <div class="text--center mdTxt"> + <p class="mb-50">{{popUpTxt}}</p> + <div class="text--center"> + <el-button + type="primary" + @click="isVisiblePopUp = false" + >������</el-button> + </div> + </div> + </PopUpFrame> + +</div> +</template> + +<script src="./recommend-consultant-result.component.ts"></script> + +<style lang="scss" scoped> + @import "./recommend-consultant-result.component.scss"; +</style> diff --git a/PAMapp/pages/recommendConsultant/result/recommend-consultant-result.component.scss b/PAMapp/pages/recommendConsultant/result/recommend-consultant-result.component.scss new file mode 100644 index 0000000..fc88fdd --- /dev/null +++ b/PAMapp/pages/recommendConsultant/result/recommend-consultant-result.component.scss @@ -0,0 +1,114 @@ +.pam-rec-agent-card { + margin-bottom: 10px; + border-radius: 10px; + border: 1px solid $LIGHT_GREY; + padding: 20px 33px; + + .pam-rec-agent-card__content { + .pam-rec-agent-card__content-header { + display: flex; + .pam-rec-agent-card__avatar { + display: flex; + flex-direction: row; + margin-right: 20px; + } + .pam-rec-agent-card__main-info { + display: flex; + flex-direction: column; + justify-content: flex-end; + .rec-role { + font-size: 16px; + color: $PRUDENTIAL_GREY; + font-weight: bold; + margin-top: 4px; + } + .rec-detail{ + font-size: 20px; + color:$PRIMARY_RED; + font-weight: bold; + padding-top: 30px; + cursor: pointer; + } + } + } + .pam-rec-agent-card__content-body { + height: 200px; + } + } +} + +.field__label { + font-size: 16px; + color: $PRUDENTIAL_GREY; + font-weight:bold; + margin-bottom: 7px; +} +.field__content{ + font-size: 18px; +} +.expertieses-container { + display: flex; + flex-wrap: wrap; +} + +@include desktop{ + .pam-rec-agent__list{ + display: flex; + flex-wrap: wrap; + flex-direction:row; + width: 100%; + } + .pam-paragraph{ + margin-top: 10px; + } + .pam-rec-agent-card { + border-radius: 10px; + border: 1px solid $LIGHT_GREY; + padding: 15px 20px 15px 20px; + width: 170px; + margin: 0 10px 10px 10px; + + .pam-rec-agent-card__content { + .pam-rec-agent-card__content-header { + display: flex; + .pam-rec-agent-card__avatar { + display: flex; + flex-direction: row; + margin-right: 20px; + } + .pam-rec-agent-card__main-info { + display: flex; + flex-direction: column; + justify-content: center; + .rec-desktop-name{ + font-size: 12px; + font-weight: bold; + } + .rec-role { + font-size: 12px; + color:$PRUDENTIAL_GREY; + } + .rec-detail{ + font-size: 12px; + color:$PRIMARY_RED; + font-weight: bold; + padding-top: 10px; + } + } + } + } + } + .field__label { + font-size: 12px; + color: $PRUDENTIAL_GREY; + font-weight:bold; + margin-bottom: 7px; + } + .field__content{ + font-size: 12px; + } + .expertieses-container { + display: flex; + flex-wrap: wrap; + } +} diff --git a/PAMapp/pages/recommendConsultant/result/recommend-consultant-result.component.ts b/PAMapp/pages/recommendConsultant/result/recommend-consultant-result.component.ts new file mode 100644 index 0000000..fa7b3d5 --- /dev/null +++ b/PAMapp/pages/recommendConsultant/result/recommend-consultant-result.component.ts @@ -0,0 +1,32 @@ +import {Vue,Component, State, namespace, Action} from 'nuxt-property-decorator'; +import { AgentOfStrictQuery } from '~/assets/ts/api/consultant'; + +const localStorage = namespace('localStorage'); + +@Component +export default class RecommendConsultantResult extends Vue{ + @State('strictQueryList') strictQueryList!: AgentOfStrictQuery[]; + @Action storeStrictQueryList!: (data: any) => Promise<number>; + @localStorage.State recommendConsultantItem!: string; + + pageList: any[] = []; + isVisiblePopUp = false; + popUpTxt = ''; + mounted() { + if (this.recommendConsultantItem && this.strictQueryList.length === 0) { + const strictQueryDto = JSON.parse(this.recommendConsultantItem); + this.storeStrictQueryList(strictQueryDto); + } + } + + changePage(pageList: any[]) { + this.pageList = pageList; + } + showAgentDetail(agentNo: string): void { + this.$router.push(`/agentInfo/${agentNo}`); + } + openPopUp(txt: string) { + this.popUpTxt = txt; + this.isVisiblePopUp = true; + } +} diff --git a/PAMapp/pages/record.vue b/PAMapp/pages/record.vue deleted file mode 100644 index bf002b7..0000000 --- a/PAMapp/pages/record.vue +++ /dev/null @@ -1,45 +0,0 @@ -<template> - <!-- <div>record-������� - <el-tabs - v-model="activeTabName" - @tab-click="tabClick" - > - <el-tab-pane - label="�������" - name="contactRecord" - > - </el-tab-pane> - <el-tab-pane - label="皛踵�漲蝝����" - name="reviews" - ></el-tab-pane> - </el-tabs> --> - - <NuxtChild></NuxtChild> - <!-- </div> --> -</template> - -<script lang="ts"> -import { Vue, Component, Watch } from 'vue-property-decorator'; -import { Route } from 'vue-router/types/router.d'; - -@Component -export default class Record extends Vue { - activeTabName = 'contactRecord'; - - tabClick() { - this.$router.push('/record/' + this.activeTabName); - } - - @Watch('$route') watchRouter(currentRoute: Route) { - const pathArray = currentRoute.fullPath.split('/'); - this.activeTabName = pathArray[pathArray.length - 1]; - } -} -</script> - -<style lang="scss" scoped> - .el-tabs__item:hover { - color: #303133; - } -</style> \ No newline at end of file diff --git a/PAMapp/pages/record/contactRecord.vue b/PAMapp/pages/record/contactRecord.vue deleted file mode 100644 index eebe275..0000000 --- a/PAMapp/pages/record/contactRecord.vue +++ /dev/null @@ -1,3 +0,0 @@ -<template> - <div>�������(�������)</div> -</template> \ No newline at end of file diff --git a/PAMapp/pages/record/index.vue b/PAMapp/pages/record/index.vue index 692841f..0dfac99 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,92 +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'; -const roleStorage = namespace('localStorage'); +<script src="./record.component.ts"></script> -@Component -export default class Reviews extends Vue{ - - today = new Date(); - - @roleStorage.Getter currentRole!:string; - - @State('myAppointmentReviewLogList') myAppointmentReviewLogList!: AppointmentLog[]; - - @Action storeMyAppointmentReviewLog!: any; - - appointmentLogList: AppointmentLog[] = []; - - mounted() { - this.storeMyAppointmentReviewLog(); - } - - - -} -</script> -<style lang="scss" scoped> -.user-reviews-page{ - margin-bottom:155px; - .user-reviews-header{ - height: 43px; - margin-top: 28px; - display: flex; - justify-content: center; - border-bottom: 2px solid black; - } - .user-reviews-content{ - .user-reviews-card{ - display: flex; - justify-content: space-between; - margin-top: 26px; - border-bottom: 1px solid #707070; - height: 54px; - padding-bottom: 15px; - .user-reviews-card-content{ - width: 242px; - padding-right:50px; - line-height: 1.2; - font-size: 20px; - margin-left: 15px; - } - .user-reviews-card-date{ - font-size: 12px; - display: flex; - flex-direction: column; - align-items: flex-end; - margin-right: 15px; - width:52px; - .date{ - margin-bottom: 2px; - - } - } - } - } -} -@include desktop{ - .user-reviews-card-content{ - flex: 1; - } -} -</style> \ No newline at end of file +<style lang="scss"> + @import "./record.component.scss"; +</style> diff --git a/PAMapp/pages/record/record.component.scss b/PAMapp/pages/record/record.component.scss new file mode 100644 index 0000000..be1a4c6 --- /dev/null +++ b/PAMapp/pages/record/record.component.scss @@ -0,0 +1,44 @@ +.user-reviews-page{ + margin-bottom:155px; + .user-reviews-header{ + height: 43px; + margin-top: 28px; + display: flex; + justify-content: center; + border-bottom: 2px solid black; + } + .user-reviews-content{ + .user-reviews-card{ + display: flex; + justify-content: space-between; + margin-top: 26px; + border-bottom: 1px solid #707070; + height: 54px; + padding-bottom: 15px; + .user-reviews-card-content{ + width: 242px; + padding-right:50px; + line-height: 1.2; + font-size: 20px; + margin-left: 15px; + } + .user-reviews-card-date{ + font-size: 12px; + display: flex; + flex-direction: column; + align-items: flex-end; + margin-right: 15px; + width:52px; + .date{ + margin-bottom: 2px; + + } + } + } + } +} +@include desktop{ + .user-reviews-card-content{ + flex: 1; + } +} diff --git a/PAMapp/pages/record/record.component.ts b/PAMapp/pages/record/record.component.ts new file mode 100644 index 0000000..4e66245 --- /dev/null +++ b/PAMapp/pages/record/record.component.ts @@ -0,0 +1,23 @@ +import { Vue, Component, Action, State, namespace } from 'nuxt-property-decorator'; +import { AppointmentLog } from '~/assets/ts/models/appointment.model'; + +const roleStorage = namespace('localStorage'); + +@Component +export default class Reviews extends Vue{ + + today = new Date(); + + @roleStorage.Getter currentRole!:string; + + @State('myAppointmentReviewLogList') myAppointmentReviewLogList!: AppointmentLog[]; + + @Action storeMyAppointmentReviewLog!: any; + + appointmentLogList: AppointmentLog[] = []; + + mounted() { + this.storeMyAppointmentReviewLog(); + } + +} diff --git a/PAMapp/pages/record/reviews.vue b/PAMapp/pages/record/reviews.vue deleted file mode 100644 index 792609c..0000000 --- a/PAMapp/pages/record/reviews.vue +++ /dev/null @@ -1,3 +0,0 @@ -<template> - <div>�������(皛踵�漲蝝����)</div> -</template> \ No newline at end of file diff --git a/PAMapp/pages/userReviews/index.vue b/PAMapp/pages/userReviews/index.vue index 96b0cd9..92b8406 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,164 +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'; +<script src="./user-reviews.component.ts"></script> -@Component({ - layout: 'home' -}) -export default class UserReviews extends Vue{ - - isMobileDevice = true; - - showReviews = false; - - reviewsList:ReviewsList[] = [ - { - avatar:'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png', - name:'�蝢��', - avgScore: 0 - }, - { - avatar:'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png', - name:'鞈�', - avgScore: 0 - }, - { - avatar:'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png', - name:'������', - avgScore: 0 - } - ]; - - reviewsDialogCheck(): void { - this.reviewsList = this.reviewsList.filter((reviewItem) => !reviewItem.avgScore); - this.showReviews = false; - }; - - mounted() { - this.isMobileDevice = isMobileDevice(); - }; - - sendReviews() { - this.showReviews = true; - }; -} -export interface ReviewsList{ - avatar:any; - name:string; - avgScore:number; -} -</script> -<style lang="scss" scoped> -.reviews-page{ - background-color: #F8F9FA; - .reviews-banner{ - background-image: url('~/assets/images/satisfaction/banner_mob.svg'); - height: 120px; - margin-bottom: 10px; - } - .reviews-container{ - padding-right: 10px; - padding-left: 10px; - padding-bottom: 10px; - .reviews-header{ - margin-top: 10px; - .reviews-header-container{ - display: flex; - margin-bottom:38px; - align-items: baseline; - .reviews-header-title{ - margin-right: 17.5px; - font-size: 20px; - } - .reviews-header-subTitle{ - font-size: 16px; - color: #68737A; - } - } - } - .reviews-content{ - .reviews-content-card{ - .card-body{ - display: flex; - .card-avatar{ - .img{ - height: 80px; - width: 80px; - } - } - .card-txt{ - font-size: 20px; - padding-top: 20px; - .p{ - font-size: 23px; - color:#ED1B2E; - font-weight: bold; - } - } - } - .card-score{ - margin-top: 10px; - margin-bottom: 30px; - display: flex; - justify-content: center; - } - } - } - } - .reviews-footer{ - height: 70px; - display: flex; - justify-content: center; - margin-top: 45px; - background-color: #fff; - .reviews-footer-btn{ - width: 120px; - height: 50px; - margin-top: 10px; - } - } - .reviews-dialog{ - display: flex; - justify-content: center; - margin-bottom: 56px; - .reviews-dialog-title{ - font-size: 18px; - } - } - .reviews-btn-block{ - display: flex; - justify-content: center; - } -} - -@include desktop{ - .reviews-page{ - .reviews-banner{ - height: 147px; - background-image: url('~/assets/images/satisfaction/banner_web.svg'); - } - .reviews-container{ - width: 700px; - margin: 30px auto 0px auto; - .reviews-content{ - display: flex; - flex-direction: column; - align-items: flex-start; - } - } - .reviews-footer{ - background-color:#F8F9FA; - } - } - -} - -</style> \ No newline at end of file +<style lang="scss"> + @import "./user-reviews.component.scss"; +</style> diff --git a/PAMapp/pages/userReviews/user-reviews.component.scss b/PAMapp/pages/userReviews/user-reviews.component.scss new file mode 100644 index 0000000..969cf5c --- /dev/null +++ b/PAMapp/pages/userReviews/user-reviews.component.scss @@ -0,0 +1,103 @@ +.reviews-page{ + background-color: #F8F9FA; + .reviews-banner{ + background-image: url('~/assets/images/satisfaction/banner_mob.svg'); + height: 120px; + margin-bottom: 10px; + } + .reviews-container{ + padding-right: 10px; + padding-left: 10px; + padding-bottom: 10px; + .reviews-header{ + margin-top: 10px; + .reviews-header-container{ + display: flex; + margin-bottom:38px; + align-items: baseline; + .reviews-header-title{ + margin-right: 17.5px; + font-size: 20px; + } + .reviews-header-subTitle{ + font-size: 16px; + color: #68737A; + } + } + } + .reviews-content{ + .reviews-content-card{ + .card-body{ + display: flex; + .card-avatar{ + .img{ + height: 80px; + width: 80px; + } + } + .card-txt{ + font-size: 20px; + padding-top: 20px; + .p{ + font-size: 23px; + color:#ED1B2E; + font-weight: bold; + } + } + } + .card-score{ + margin-top: 10px; + margin-bottom: 30px; + display: flex; + justify-content: center; + } + } + } + } + .reviews-footer{ + height: 70px; + display: flex; + justify-content: center; + margin-top: 45px; + background-color: #fff; + .reviews-footer-btn{ + width: 120px; + height: 50px; + margin-top: 10px; + } + } + .reviews-dialog{ + display: flex; + justify-content: center; + margin-bottom: 56px; + .reviews-dialog-title{ + font-size: 18px; + } + } + .reviews-btn-block{ + display: flex; + justify-content: center; + } +} + +@include desktop{ + .reviews-page{ + .reviews-banner{ + height: 147px; + background-image: url('~/assets/images/satisfaction/banner_web.svg'); + } + .reviews-container{ + width: 700px; + margin: 30px auto 0px auto; + .reviews-content{ + display: flex; + flex-direction: column; + align-items: flex-start; + } + } + .reviews-footer{ + background-color:#F8F9FA; + } + } + +} diff --git a/PAMapp/pages/userReviews/user-reviews.component.ts b/PAMapp/pages/userReviews/user-reviews.component.ts new file mode 100644 index 0000000..061f640 --- /dev/null +++ b/PAMapp/pages/userReviews/user-reviews.component.ts @@ -0,0 +1,43 @@ +import { Vue,Component } from 'vue-property-decorator' +import { isMobileDevice } from '~/assets/ts/device'; +import { ReviewsItem } from '~/assets/ts/models/reviews-item.model'; + +@Component({ + layout: 'home' +}) +export default class UserReviews extends Vue { + + isMobileDevice = true; + showReviews = false; + + reviewsList: ReviewsItem[] = [ + { + avatar:'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png', + name:'�蝢��', + avgScore: 0 + }, + { + avatar:'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png', + name:'鞈�', + avgScore: 0 + }, + { + avatar:'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png', + name:'������', + avgScore: 0 + } + ]; + + reviewsDialogCheck(): void { + this.reviewsList = this.reviewsList.filter((reviewItem) => !reviewItem.avgScore); + this.showReviews = false; + }; + + mounted() { + this.isMobileDevice = isMobileDevice(); + }; + + sendReviews() { + this.showReviews = true; + }; +} diff --git a/PAMapp/pages/userReviewsRecord/index.vue b/PAMapp/pages/userReviewsRecord/index.vue deleted file mode 100644 index a0665d9..0000000 --- a/PAMapp/pages/userReviewsRecord/index.vue +++ /dev/null @@ -1,113 +0,0 @@ -<template> - -<div class="user-reviews-page"> - <section class="mdTxt"> - ������� - </section> - - <section class="user-reviews-header"> - <div class="header-title mdTxt"> - 皛踵�漲蝝���� - </div> - </section> - - <section class="user-reviews-content"> - <div - class="user-reviews-card" - v-for="(appointmentLog, index) in myAppointmentReviewLogList" - :key="index"> - <div class="user-reviews-card-content" v-if="currentRole === 'user'"> - �撠�<span class="mdTxt">{{ ` ${appointmentLog.agentName} ` }}</span>���� <UiReviewScore :score="appointmentLog.score" /> 閰嚗� - </div> - <div class="user-reviews-card-content" v-else> - {{ `${appointmentLog.clientName} `}} 撠���� <UiReviewScore :score="appointmentLog.score" /> 閰嚗� - </div> - <div class="user-reviews-card-date"> - <div class="date"> - <UiDateFormat - :date="appointmentLog.lastModifiedDate" - onlyShowSection="DAY" /> - </div> - <div class="time"> - <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'; - -const roleStorage = namespace('localStorage'); - -@Component -export default class UserReviewsRecord extends Vue{ - - today = new Date(); - - @roleStorage.Getter currentRole!:string; - - @State('myAppointmentReviewLogList') myAppointmentReviewLogList!: AppointmentLog[]; - - @Action storeMyAppointmentReviewLog!: any; - - appointmentLogList: AppointmentLog[] = []; - - mounted() { - this.storeMyAppointmentReviewLog(); - } - -} -</script> -<style lang="scss" scoped> -.user-reviews-page{ - margin-bottom:155px; - .user-reviews-header{ - height: 43px; - margin-top: 28px; - display: flex; - justify-content: center; - border-bottom: 2px solid black; - } - .user-reviews-content{ - .user-reviews-card{ - display: flex; - justify-content: space-between; - margin-top: 26px; - border-bottom: 1px solid #707070; - height: 54px; - padding-bottom: 15px; - .user-reviews-card-content{ - width: 242px; - padding-right:50px; - line-height: 1.2; - font-size: 20px; - margin-left: 15px; - } - .user-reviews-card-date{ - font-size: 12px; - display: flex; - flex-direction: column; - align-items: flex-end; - margin-right: 15px; - width:52px; - .date{ - margin-bottom: 2px; - - } - } - } - } -} -@include desktop{ - .user-reviews-card-content{ - flex: 1; - } -} -</style> \ No newline at end of file diff --git a/PAMapp/store/localStorage.ts b/PAMapp/store/localStorage.ts index d93aa2c..96bc774 100644 --- a/PAMapp/store/localStorage.ts +++ b/PAMapp/store/localStorage.ts @@ -1,5 +1,5 @@ -import { Selected } from '~/components/QuickFilter/QuickFilterSelector.vue'; import { Module, Mutation, VuexModule ,Action } from 'vuex-module-decorators'; +import { Selected } from '~/assets/ts/models/selected.model'; @Module export default class LocalStorage extends VuexModule { id_token = localStorage.getItem('id_token'); -- Gitblit v1.8.0