Merge remote-tracking branch 'origin/master'
| | |
| | | margin: 0; |
| | | color: $PRIMARY_BLACK; |
| | | font-family: Segoe UI; |
| | | overflow-x: hidden; |
| | | scroll-behavior: smooth; |
| | | } |
| | | |
| | | html { |
| | | overflow: hidden; |
| | | height: 100%; |
| | | } |
| | | |
| | | body { |
| | | overflow-y: auto; |
| | | height: 100%; |
| | | overflow-x: hidden; |
| | | } |
| | | |
| | | // btn |
| | |
| | | @mixin desktop() { |
| | | @media (min-width: 1024px) { |
| | | @media (min-width: $DESKTOP_BREAKPOINT) { |
| | | @content; |
| | | } |
| | | } |
| | |
| | | $LIGHT_GREY: #D0D0CE; |
| | | $MID_GREY: #A7A8AA; |
| | | $GREEN: #06A633; |
| | | |
| | | // DEVICE BREAKPOINT |
| | | $DESKTOP_BREAKPOINT: 768px; |
| | |
| | | padding-left: 0; |
| | | text-align: center; |
| | | line-height: 110px; |
| | | background-size: cover; |
| | | background-position: center; |
| | | background-repeat: no-repeat; |
| | | } |
| | | |
| | | &.is-checked { |
| | | background-color: #22222229; |
| | | } |
| | | } |
| | | |
| | | .btn_koala { |
| | | .el-checkbox__label { |
| | | background-image: url('~/assets/images/quickFilter/btn_koala.svg'); |
| | | } |
| | | } |
| | | |
| | | .btn_owl { |
| | | .el-checkbox__label { |
| | | background-image: url('~/assets/images/quickFilter/btn_owl.svg'); |
| | | } |
| | | } |
| | | |
| | | .btn_peacock { |
| | | .el-checkbox__label { |
| | | background-image: url('~/assets/images/quickFilter/btn_peacock.svg'); |
| | | } |
| | | } |
| | | |
| | | .btn_tiger { |
| | | .el-checkbox__label { |
| | | background-image: url('~/assets/images/quickFilter/btn_tiger.svg'); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | .pam-multi-select-btn.el-checkbox-group{ |
| | |
| | | display: block; |
| | | line-height: 110px; |
| | | padding-left: 0; |
| | | |
| | | background-size: cover; |
| | | background-position: center; |
| | | background-repeat: no-repeat; |
| | | } |
| | | |
| | | &.is-checked { |
| | |
| | | } |
| | | } |
| | | |
| | | .btn_woman { |
| | | .el-radio__label { |
| | | background-image: url('~/assets/images/quickFilter/btn_woman.svg'); |
| | | } |
| | | } |
| | | |
| | | .btn_man { |
| | | .el-radio__label { |
| | | background-image: url('~/assets/images/quickFilter/btn_man.svg'); |
| | | } |
| | | } |
| | | .pam-single-btn.el-radio-group{ |
| | | .el-radio { |
| | | padding: 10px 20px; |
| | | border: 1px $LIGHT_GREY solid; |
| | | background-color: $PRIMARY_WHITE; |
| | | border-radius: 50px; |
| | | font-size: 20px; |
| | | margin-right: 10px; |
| | | margin-bottom: 10px; |
| | | |
| | |
| | | |
| | | .el-radio__label { |
| | | text-align: center; |
| | | font-size: 18px; |
| | | color: $PRIMARY_BLACK; |
| | | font-weight: normal; |
| | | display: block; |
| | | padding-left: 0px; |
| | | .radio-sub-title{ |
| | | color: $PRUDENTIAL_GREY; |
| | | } |
| | | } |
| | | |
| | | &.is-checked { |
| | |
| | | color: $PRIMARY_WHITE; |
| | | .el-radio__label{ |
| | | color: $PRIMARY_WHITE; |
| | | .radio-sub-title{ |
| | | color: $PRIMARY_WHITE; |
| | | } |
| | | } |
| | | } |
| | | } |
¤ñ¹ï·sÀÉ®× |
| | |
| | | import axios from 'axios'; |
| | | import { AxiosRequestConfig, AxiosError, AxiosResponse } from 'axios'; |
| | | import { MessageBox } from 'element-ui'; |
| | | import { functionsIn } from 'lodash'; |
| | | import Router from 'vue-router'; |
| | | |
| | | export const service = axios.create({ |
| | | baseURL: 'http://localhost:8080/api', |
| | | headers: { |
| | | Authorization: 'Bearer ' + localStorage.getItem('id_token') |
| | | } |
| | | }) |
| | | |
| | | service.interceptors.request.use(function (config: AxiosRequestConfig) { |
| | | return config; |
| | | }, function (error: AxiosError) { |
| | | return Promise.reject(error); |
| | | }); |
| | | |
| | | service.interceptors.response.use(function (response: AxiosResponse) { |
| | | return response; |
| | | }, function (error: AxiosError) { |
| | | return Promise.reject(error); |
| | | }); |
| | | |
| | | // 顧客ç»å
¥(TODO: OTPèªèéç¼å æ«æä½¿ç¨) |
| | | export function login(user: any) { |
| | | return service.post('/authenticate', user) |
| | | } |
| | | |
| | | // æ¨è¦ä¿éªé¡§å |
| | | export function recommend() { |
| | | return service.get('/consultant/recommend') |
| | | } |
| | | |
| | | // æç顧忏
å® |
| | | export function getFavoriteConsultant() { |
| | | return service.get('/consultant/favorite'); |
| | | } |
| | | |
| | | // å¿«éç¯©é¸ |
| | | export function fastQuery(data: FastQueryParams) { |
| | | return service.post('/consultant/fastQuery', data) |
| | | } |
| | | |
| | | // å´é¸é
å° |
| | | export function strictQuery(data:StrictQueryParams):Promise<AxiosResponse<AgentOfStrictQuery>>{ |
| | | return service.post('/consultant/strictQuery', data) |
| | | } |
| | | |
| | | // å å
¥é¡§å |
| | | export function addFavoriteConsultant(agentNoList: string[]) { |
| | | return service.post('/consultant/favorite', {agentNoList}) |
| | | } |
| | | |
| | | // é ç´åè©¢å |
| | | export function appointmentDemand(data: AppointmentParams) { |
| | | return service.post('/appointment/customer/create', data) |
| | | } |
| | | |
| | | //é¡§å詳細è³è¨ |
| | | export function getConsultantDetail(agentNo:string){ |
| | | return service.get('/consultant/detail', {params:{agentNo:agentNo}}) |
| | | } |
| | | export interface Consultants { |
| | | agentNo: string, |
| | | name: string, |
| | | img: string, |
| | | new: boolean, |
| | | avgScore: number, |
| | | expertise: string[], |
| | | updateTime: Date, |
| | | seniority: string, |
| | | contactStatus?: string; |
| | | } |
| | | |
| | | export interface FastQueryParams { |
| | | gender: string, |
| | | communicationStyles: string[], |
| | | avgScore: number, |
| | | status: string |
| | | } |
| | | |
| | | export interface AppointmentParams { |
| | | phone: string, |
| | | email: string, |
| | | contactType: string, |
| | | gender: string, |
| | | age: string, |
| | | job: string, |
| | | requirement: string, |
| | | hopeContactTime: string, |
| | | otherRequirement: string, |
| | | agentNo: string |
| | | } |
| | | export interface StrictQueryParams{ |
| | | gender: string; |
| | | avgScore: number; |
| | | status: string; //phase 1 disable |
| | | area: string; |
| | | requirements: string[]; |
| | | otherRequirement: string; |
| | | seniority: string; |
| | | popularTags: string[]; |
| | | otherPopularTags: string; |
| | | } |
| | | export interface AgentOfStrictQuery { |
| | | agentNo: string; |
| | | name: string; |
| | | img: string; |
| | | expertise: string[]; |
| | | avgScore: number; |
| | | contactStatus: null; |
| | | updateTime: null; |
| | | seniority: string; |
| | | new: boolean; |
| | | } |
¤ñ¹ï·sÀÉ®× |
| | |
| | | export function isLogin() { |
| | | return !!localStorage.getItem('id_token') |
| | | } |
¤ñ¹ï·sÀÉ®× |
| | |
| | | import { Consultants } from "./api/consultant"; |
| | | |
| | | export function getFavoriteFromStorage(): Consultants[] { |
| | | const consultantList = localStorage.getItem('favoriteConsultant'); |
| | | return consultantList ? JSON.parse(consultantList) : []; |
| | | } |
| | | |
| | | export function setFavoriteToStorage(consultants: Consultants[]) { |
| | | localStorage.setItem('favoriteConsultant', JSON.stringify(consultants)); |
| | | } |
¤ñ¹ï·sÀÉ®× |
| | |
| | | <template> |
| | | <el-row type="flex" justify="center" :class="cusClass"> |
| | | <el-button @click="addConsultant(agentInfo)"> |
| | | <span> + 顧忏
å®</span> |
| | | </el-button> |
| | | <el-button |
| | | @click="reserveCommunication" |
| | | type="primary" |
| | | >é²è¡é ç´</el-button> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop, Emit } from 'nuxt-property-decorator'; |
| | | import { addFavoriteConsultant, Consultants } from '~/assets/ts/api/consultant'; |
| | | import { isLogin } from '~/assets/ts/auth'; |
| | | import { getFavoriteFromStorage, setFavoriteToStorage } from '~/assets/ts/storageConsultant'; |
| | | |
| | | @Component |
| | | export default class AddAndReservedBtns extends Vue { |
| | | @Prop() agentInfo!: Consultants; |
| | | @Prop() cusClass!: string; |
| | | isVisiblePopUp = false; |
| | | addConsultant(item: Consultants) { |
| | | console.log('click') |
| | | if (isLogin()) { |
| | | addFavoriteConsultant([item.agentNo]).then(res => this.openPopUp()) |
| | | } else { |
| | | this.addConsultantToStorage(item); |
| | | } |
| | | } |
| | | |
| | | addConsultantToStorage(item: Consultants) { |
| | | let agentList = [item]; |
| | | const consultantList = getFavoriteFromStorage(); |
| | | |
| | | if (consultantList) { |
| | | const isRepeat = consultantList.findIndex(i => i.agentNo === item.agentNo) === -1; |
| | | isRepeat |
| | | ? this.storageFavoriteAndPopUp(consultantList.concat(agentList)) |
| | | : this.openPopUp('å·²ç¶å å
¥é¡§åæ¸
å®'); |
| | | |
| | | } else { |
| | | this.storageFavoriteAndPopUp(agentList); |
| | | } |
| | | } |
| | | |
| | | storageFavoriteAndPopUp(item: Consultants[]) { |
| | | setFavoriteToStorage(item); |
| | | this.openPopUp(); |
| | | } |
| | | |
| | | reserveCommunication() { |
| | | isLogin() ? this.$router.push(`/questionnaire/${this.agentInfo.agentNo}`) : this.$router.push('/login'); |
| | | } |
| | | |
| | | @Emit('openPopUp') openPopUp(popUpTxt: string = 'æåå å
¥é¡§åæ¸
å®') { |
| | | return popUpTxt |
| | | } |
| | | } |
| | | </script> |
| | |
| | | <template> |
| | | <div class="text--center"> |
| | | <div class="subTitle mb-10">æå¨å°å</div> |
| | | <div class="text--center" @click="close"> |
| | | <div class="subTitle mb-10" @click="close">æå¨å°å</div> |
| | | <el-input |
| | | type="text" |
| | | class="p mt-10" |
| | |
| | | <Ui-ScrollPicker |
| | | :options="filterOptions" |
| | | :initValue="district" |
| | | @change="change" |
| | | @change="selectDistrict" |
| | | ></Ui-ScrollPicker> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component } from 'nuxt-property-decorator'; |
| | | import { Vue, Component, Emit } from 'nuxt-property-decorator'; |
| | | |
| | | @Component |
| | | export default class AddressPicker extends Vue { |
| | |
| | | this.filterOptions = JSON.parse(JSON.stringify(this.options)); |
| | | } |
| | | |
| | | |
| | | searchDistrict() { |
| | | this.filterOptions = this.options.filter(e => e.match(this.keyWord)); |
| | | } |
| | | |
| | | change(value: string) { |
| | | console.log('change', value) |
| | | @Emit('change') |
| | | selectDistrict(value: string): void { |
| | | this.district = value; |
| | | } |
| | | |
| | | @Emit() |
| | | close(): void { |
| | | console.log('close district drawer!'); |
| | | } |
| | | |
| | | } |
| | | </script> |
| | | |
| | |
| | | @Component |
| | | export default class UiCarousel extends Vue { |
| | | |
| | | label = 'back-action-label-text'; |
| | | get label(): string { |
| | | if (this.$route.name) { |
| | | const routeName = this.$route.name.split('-')[0]; |
| | | let featureLabel = ''; |
| | | switch(routeName) { |
| | | case 'login': |
| | | featureLabel = 'ç»å
¥'; |
| | | break; |
| | | case 'recommendConsultant': |
| | | featureLabel = 'å´é¸é
å°'; |
| | | break; |
| | | case 'quickFilter': |
| | | featureLabel = 'å¿«é篩é¸'; |
| | | break; |
| | | case 'myConsultantList': |
| | | featureLabel = 'æç顧忏
å®'; |
| | | break; |
| | | case 'agentInfo': |
| | | featureLabel = 'æ¥åå¡è³è¨' |
| | | break; |
| | | default: |
| | | featureLabel = 'åé¦é '; |
| | | break; |
| | | } |
| | | return featureLabel; |
| | | } else { |
| | | return 'åé¦é '; |
| | | } |
| | | } |
| | | |
| | | } |
| | | </script> |
| | |
| | | <div class="pam-tags"> |
| | | <div class="pb-10" v-for="(qaItem,index) in questionList" :key="index"> |
| | | <el-button class="tags" :class="{'active': qaItem.selected}" |
| | | @click="qaItem.selected = !qaItem.selected"> |
| | | @click="selectQuestion(index)"> |
| | | {{qaItem.name}} |
| | | </el-button> |
| | | </div> |
| | | <el-button class="tags" @click="other = !other" :class="{'active':other=other}">å
¶ä»</el-button> |
| | | </div> |
| | | <div class="pb-10 pam-tags con-input"> |
| | | <input v-if="other" class="other-input" placeholder="è«è¼¸å
¥,éXå" v-model="otherQuestion"> |
| | | </div> |
| | | |
| | | </div> |
| | | </template> |
| | | <script> |
| | | import { Vue, Component} from 'vue-property-decorator'; |
| | | <script lang="ts"> |
| | | import { Vue, Component, Emit} from 'vue-property-decorator'; |
| | | @Component |
| | | export default class ConsultantQues extends Vue{ |
| | | |
| | |
| | | } |
| | | ]; |
| | | |
| | | @Emit('change') |
| | | selectQuestion(questionIndex: number): any[] { |
| | | this.questionList[questionIndex].selected = !this.questionList[questionIndex].selected; |
| | | return this.questionList; |
| | | } |
| | | |
| | | } |
| | | </script> |
| | | <style lang="scss"> |
| | |
| | | :size="50" |
| | | :src="agentInfo.img" |
| | | class="cursor--pointer" |
| | | @click.native="$router.push('/agentInfo')" |
| | | @click.native="showAgentDetail(agentInfo.agentNo);" |
| | | ></el-avatar> |
| | | <div class="satisfaction"> |
| | | <i class="icon-star pam-icon icon--yellow satisfaction"></i> |
| | | <span>{{agentInfo.satisfaction}}</span> |
| | | <span>{{agentInfo.avgScore }}</span> |
| | | </div> |
| | | </el-col> |
| | | <el-col :xs="10" :sm="15"> |
| | |
| | | <div class="professionals"> |
| | | <span |
| | | class="professionalsTxt" |
| | | v-for="(professional, index) in agentInfo.professionals" |
| | | v-for="(expertise, index) in agentInfo.expertise" |
| | | :key="index" |
| | | >#{{professional}}</span> |
| | | >#{{expertise}}</span> |
| | | </div> |
| | | <div |
| | | class="delete" |
| | | v-if="agentInfo.contactStatus === 'picked'" |
| | | v-if="agentInfo.contactStatus !== 'reserved' |
| | | || agentInfo.contactStatus !== 'contacted'" |
| | | @click="removeAgent" |
| | | >ç§»é¤</div> |
| | | </el-col> |
| | |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop, Emit } from 'nuxt-property-decorator'; |
| | | import { Agents } from '~/plugins/api/home'; |
| | | import { Consultants } from '~/assets/ts/api/consultant'; |
| | | import { isLogin } from '~/assets/ts/auth'; |
| | | import { isMobileDevice } from '~/assets/ts/device'; |
| | | |
| | | @Component |
| | | export default class ConsultantCard extends Vue { |
| | | @Prop() agentInfo!: Agents; |
| | | @Prop() agentInfo!: Consultants; |
| | | isVisibleDialog = false; |
| | | width: string = ''; |
| | | |
| | |
| | | let date = newDate.getDate(); |
| | | let hours = newDate.getHours(); |
| | | let minutes = newDate.getMinutes(); |
| | | return `${year}/${month}/${date} ${hours} : ${minutes}` |
| | | return isLogin() ? `${year}/${month}/${date} ${hours} : ${minutes}` : '' |
| | | } |
| | | |
| | | reserveCommunication() { |
| | | if (this.agentInfo.contactStatus === 'picked') { |
| | | this.$router.push('/communication/myDemand') |
| | | const contactStatus = this.agentInfo.contactStatus; |
| | | if (contactStatus !== 'reserved' && contactStatus !== 'contacted') { |
| | | isLogin() ? this.$router.push(`/questionnaire/${this.agentInfo.agentNo}`) : this.$router.push('/login'); |
| | | } else { |
| | | this.width = isMobileDevice() ? '80%' : ''; |
| | | this.isVisibleDialog = true; |
| | |
| | | @Emit('removeAgent') removeAgent() { |
| | | return this.agentInfo.agentNo; |
| | | } |
| | | |
| | | showAgentDetail(agentNo: string): void { |
| | | this.$router.push(`/agentInfo/${agentNo}`); |
| | | } |
| | | } |
| | | </script> |
| | | |
| | |
| | | <template> |
| | | <div> |
| | | <template v-if="agents.length > 0 && noLogin"> |
| | | <template v-if="agents.length > 0"> |
| | | <ConsultantCard |
| | | v-for="(agent, index) in agents" |
| | | :key="index" |
| | |
| | | @removeAgent="removeAgent" |
| | | ></ConsultantCard> |
| | | </template> |
| | | <template v-else-if="agents.length === 0"> |
| | | <template v-else> |
| | | <div class="emptyRowStyle"> |
| | | <div class="smTxt txt">æ¨ç®åç¡å·²é¸é¡§å</div> |
| | | </div> |
| | | </template> |
| | | <template v-else> |
| | | <template v-if="!isLogin && agents.length > 0"> |
| | | <div class="emptyRowStyle"> |
| | | <div class="mdTxt login" @click="$router.push('/login')">ç»å
¥</div> |
| | | <div class="smTxt txt">æ¥çæ´å¤å·²é¸é¡§å</div> |
| | | <div class="smTxt txt">æ¥çæ´å¤</div> |
| | | </div> |
| | | </template> |
| | | </div> |
| | |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop, Emit } from 'nuxt-property-decorator'; |
| | | import { Agents } from '~/plugins/api/home'; |
| | | import { Consultants } from '~/assets/ts/api/consultant'; |
| | | import { isLogin } from '~/assets/ts/auth'; |
| | | |
| | | @Component |
| | | export default class ConsultantList extends Vue { |
| | | @Prop() agents!: Agents[]; |
| | | @Prop() agents!: Consultants[]; |
| | | |
| | | noLogin = true; |
| | | get isLogin() { |
| | | return isLogin(); |
| | | } |
| | | |
| | | @Emit('removeAgent') removeAgent(agentId: number) { |
| | | return agentId; |
| | |
| | | <div class="name">{{agentInfo.name}}</div> |
| | | <div> |
| | | <i class="icon-star pam-icon icon--yellow"></i> |
| | | <span class="satisfaction">{{agentInfo.satisfaction}}</span> |
| | | <span class="satisfaction">{{agentInfo.avgScore}}</span> |
| | | </div> |
| | | </div> |
| | | </swiper-slide> |
| | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop } from 'vue-property-decorator'; |
| | | import { SwiperOptions } from 'swiper'; |
| | | import { Agents } from '~/plugins/api/home' |
| | | import { Consultants } from '~/assets/ts/api/consultant' |
| | | |
| | | @Component |
| | | export default class UiSwiper extends Vue { |
| | | @Prop() agents!: Agents[]; |
| | | @Prop() agents!: Consultants[]; |
| | | |
| | | swiperOptions: SwiperOptions = { |
| | | loop: true, |
| | |
| | | } |
| | | |
| | | clkItem(loopIndex: number, realIndex: number) { |
| | | this.$router.push('/agentInfo'); |
| | | const agentNo = this.agents[realIndex].agentNo; |
| | | this.$router.push(`/agentInfo/${agentNo}`); |
| | | console.log(loopIndex, realIndex, 'clkItem') |
| | | } |
| | | |
| | |
| | | <template> |
| | | <header class="pam-header"> |
| | | <img class="pam-header__logo" src="~/assets/images/logo.png" alt="" @click="$router.push('/login')"> |
| | | <img class="pam-header__logo" src="~/assets/images/logo.png" alt="" @click="$router.push('/')"> |
| | | <div class="pam-header__title"> |
| | | æçå¹¸ç¦æä½ä¸» |
| | | <div class="pam-header__sub-title"> |
| | |
| | | <el-dropdown @command="handleCommand"> |
| | | <i class="icon-avatar text--dark-blue cursor--pointer"></i> |
| | | <el-dropdown-menu slot="dropdown" class="pam-header__dropdown"> |
| | | <li class="pam-header__dropdown-item" @click="$router.push('/login')">ç»å
¥</li> |
| | | <li class="pam-header__dropdown-item" @click="$router.push('/accountSetting')">å人帳èè¨å®</li> |
| | | <li class="pam-header__dropdown-item" @click="$router.push('/record/contactRecord')">æ¥çç´é</li> |
| | | <li class="pam-header__dropdown-item" @click="$router.push('/myConsultantList/consultantList')">æç顧忏
å®</li> |
| | |
| | | border-left: 1px solid #CCCCCC; |
| | | font-size: 16px; |
| | | font-weight: bold; |
| | | color: #68737A; |
| | | color: $PRUDENTIAL_GREY; |
| | | letter-spacing: 3.6px; |
| | | flex-basis: 140px; |
| | | .pam-header__sub-title { |
| | | padding-top: 2px; |
| | | font-size: 13px; |
| | | font-weight: bold; |
| | | color: #F09491; |
| | | color: $CORAL; |
| | | letter-spacing: 1.2px |
| | | } |
| | | } |
| | |
| | | ref="carouselRef" |
| | | > |
| | | <el-carousel-item |
| | | v-for="(item, index) in 5" |
| | | v-for="(item, index) in consultantList" |
| | | :key="index" |
| | | > |
| | | <div |
| | |
| | | <el-avatar |
| | | :size="200" |
| | | class="mx-auto cursor--pointer" |
| | | @click="$router.push('/agentInfo')" |
| | | src="" |
| | | @click.native="showAgentDetail(item.agentNo)" |
| | | :src="item.img" |
| | | /> |
| | | <div class="mdTxt mt-30 mb-10 text--center">è¡ç¾è(伯æ¨ä¿éªç¶ç´äºº)</div> |
| | | <div class="mdTxt mt-30 mb-30 text--center">{{item.name}}(伯æ¨ä¿éªç¶ç´äºº)</div> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <div class="smTxt_bold mb-10 text--prudential_grey">æåè³æ·</div> |
| | | <div class="mb-10">ä¸å¹´12åæ</div> |
| | | <div class="mb-10">{{item.seniority}}</div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="smTxt_bold mb-10 text--prudential_grey">å®¢æ¶æ»¿æåº¦</div> |
| | | <div> |
| | | <i class="icon-star pam-icon"></i> |
| | | 4.8</div> |
| | | <i class="icon-star pam-icon icon--yellow "></i> |
| | | {{item.avgScore}}</div> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="smTxt_bold mb-10 text--prudential_grey">å°é·é å</div> |
| | | <div class="p bold">#財åè¦å</div> |
| | | <div class="smTxt_bold mt-10 mb-10 text--prudential_grey">å°é·é å</div> |
| | | <div> |
| | | <span |
| | | v-for="(i, index) in item.expertise" |
| | | :key="index" |
| | | class="p bold mr-30 mb-10 inline-block" |
| | | >#{{i}}</span> |
| | | </div> |
| | | <div class="fixedBtn text--center"> |
| | | <el-button @click="addConsultant"> |
| | | <i class="icon-add smTxt"></i> |
| | | <span>顧忏
å®</span> |
| | | </el-button> |
| | | <el-button |
| | | @click="$router.push('/communication/myDemand')" |
| | | type="primary" |
| | | >é²è¡é ç´</el-button> |
| | | <AddAndReservedBtns |
| | | :cusClass="'fixedBtn'" |
| | | :agentInfo="item" |
| | | @openPopUp="openPopUp" |
| | | ></AddAndReservedBtns> |
| | | </div> |
| | | </el-carousel-item> |
| | | </el-carousel> |
| | | |
| | | <div class="absolute arrow-left-position" @click="nextCard"> |
| | | <div class="absolute arrow-left-position" @click="prevCard"> |
| | | <i class="icon-left pam-left-arrow"></i> |
| | | </div> |
| | | <div class="absolute arrow-right-position" @click="nextCard"> |
| | | <i class="icon-right pam-right-arrow"></i> |
| | | </div> |
| | | |
| | | <Ui-Drawer |
| | | :isVisible.sync="isVisibleDrawer" |
| | | <PopUpFrame :isOpen.sync="isVisiblePopUp" |
| | | > |
| | | <div class="text--center mdTxt"> |
| | | <p class="mb-50">æåå å
¥é¡§åæ¸
å®</p> |
| | | <p class="mb-50">{{popUpTxt}}</p> |
| | | <p class="text--primary cursor--pointer" |
| | | @click="isVisibleDrawer = false">æç¥éäº</p> |
| | | @click="isVisiblePopUp = false">æç¥éäº</p> |
| | | </div> |
| | | </Ui-Drawer> |
| | | |
| | | <Ui-Dialog |
| | | :isVisible.sync="isVisibleDialog" |
| | | > |
| | | <div class="text--center mdTxt"> |
| | | <p class="mb-50">æåå å
¥é¡§åæ¸
å®</p> |
| | | <p class="text--primary cursor--pointer" |
| | | @click="isVisibleDialog = false">æç¥éäº</p> |
| | | </div> |
| | | </Ui-Dialog> |
| | | </PopUpFrame> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { ElCarousel } from 'element-ui/types/carousel'; |
| | | import { Vue, Component } from 'vue-property-decorator'; |
| | | import { isMobileDevice } from '~/assets/ts/device'; |
| | | import { Vue, Component, Prop } from 'vue-property-decorator'; |
| | | import { Consultants } from '~/assets/ts/api/consultant'; |
| | | |
| | | @Component |
| | | export default class QuickFilterConsultantList extends Vue { |
| | | isVisibleDrawer = false; |
| | | isVisibleDialog = false; |
| | | @Prop() consultantList!: Consultants[]; |
| | | isVisiblePopUp = false; |
| | | startPosition = 0; |
| | | endPosition = 0; |
| | | popUpTxt = 'æåå å
¥é¡§åæ¸
å®'; |
| | | |
| | | touchStart(event: TouchEvent) { |
| | | this.startPosition = event.changedTouches[0].clientX; |
| | |
| | | this.endPosition = event.changedTouches[0].clientX; |
| | | if (this.endPosition < this.startPosition) { |
| | | this.nextCard(); |
| | | return; |
| | | } |
| | | |
| | | if (this.endPosition > this.startPosition) { |
| | | this.prevCard(); |
| | | return; |
| | | } |
| | | } |
| | | |
| | |
| | | (this.$refs.carouselRef as ElCarousel).prev(); |
| | | } |
| | | |
| | | addConsultant() { |
| | | isMobileDevice() |
| | | ? this.isVisibleDrawer = true |
| | | : this.isVisibleDialog = true; |
| | | openPopUp(txt: string) { |
| | | this.popUpTxt = txt; |
| | | this.isVisiblePopUp = true; |
| | | } |
| | | showAgentDetail(agentNo: string): void { |
| | | this.$router.push(`/agentInfo/${agentNo}`); |
| | | } |
| | | |
| | | |
| | | } |
| | | </script> |
| | |
| | | bottom: 30px; |
| | | left: 50%; |
| | | transform: translateX(-50%); |
| | | width: 100%; |
| | | } |
| | | |
| | | .pam-left-arrow,.pam-right-arrow { |
| | |
| | | position: absolute; |
| | | } |
| | | |
| | | .inline-block { |
| | | display: inline-block; |
| | | } |
| | | |
| | | @media (min-width: 768px) { |
| | | .relative { |
| | | overflow: hidden; |
| | |
| | | </span> |
| | | <span |
| | | class="smTxt_bold text--primary" |
| | | v-if="questionOption.name === 'style'" |
| | | v-if="questionOption.name === 'communicationStyles'" |
| | | >å¯è¤é¸</span> |
| | | <span |
| | | class="smTxt_bold text--primary" |
| | | v-if="questionOption.name === 'satisfaction'" |
| | | v-if="questionOption.name === 'avgScore'" |
| | | >é¸åææ</span> |
| | | </div> |
| | | |
| | | <div class="quickBtnBlock" v-if="questionOption.name === 'style'"> |
| | | <el-checkbox-group class="pam-quickFilter-checkbox" v-model="pickedItem.style"> |
| | | <div class="quickBtnBlock" v-if="questionOption.name === 'communicationStyles'"> |
| | | <el-checkbox-group class="pam-quickFilter-checkbox" v-model="pickedItem.communicationStyles"> |
| | | <el-checkbox |
| | | v-for="(i, index) in questionOption.detail" |
| | | :key="index" |
| | | :label="i" |
| | | :name="i" |
| | | :label="i.value" |
| | | :name="i.value" |
| | | :class="i.className" |
| | | ></el-checkbox> |
| | | </el-checkbox-group> |
| | | </div> |
| | |
| | | <el-radio |
| | | v-for="(i, index) in questionOption.detail" |
| | | :key="index" |
| | | :label="i"></el-radio> |
| | | :label="i.value" |
| | | :class="i.className" |
| | | >{{i.name}}</el-radio> |
| | | </el-radio-group> |
| | | </div> |
| | | |
| | | <div class="quickBtnBlock" v-else-if="questionOption.name === 'loginState'"> |
| | | <el-radio-group class="pam-quickFilter-radio" v-model="pickedItem.loginState"> |
| | | <div class="quickBtnBlock" v-else-if="questionOption.name === 'status'"> |
| | | <el-radio-group class="pam-quickFilter-radio" v-model="pickedItem.status"> |
| | | <el-radio |
| | | v-for="(i, index) in QuestionOption.detail" |
| | | :key="index" |
| | | :label="i"></el-radio> |
| | | :label="i.value" |
| | | :class="i.className" |
| | | ></el-radio> |
| | | </el-radio-group> |
| | | </div> |
| | | |
| | | <div v-else> |
| | | <el-rate class="pam-quickFilter-rate" v-model="pickedItem.satisfaction"></el-rate> |
| | | <el-rate class="pam-quickFilter-rate" v-model="pickedItem.avgScore"></el-rate> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, PropSync, Prop, Watch, Emit } from 'nuxt-property-decorator'; |
| | | import { QuestionOption, selectedItem } from '~/pages/quickFilter/index.vue'; |
| | | import { Vue, Component, PropSync, Prop, Watch } from 'nuxt-property-decorator'; |
| | | import { FastQueryParams } from '~/assets/ts/api/consultant'; |
| | | import { QuestionOption } from '~/pages/quickFilter/index.vue'; |
| | | |
| | | @Component |
| | | export default class QuickFilterDrawer extends Vue { |
| | | |
| | | pickedItem: selectedItem = { |
| | | style: [], |
| | | onlineState: '', |
| | | pickedItem: FastQueryParams = { |
| | | communicationStyles: [], |
| | | status: '', |
| | | gender: '', |
| | | satisfaction: 0 |
| | | avgScore: 0 |
| | | } |
| | | |
| | | @PropSync('drawerVisible') isVisible!: boolean; |
| | | @Prop() selectedItem!: selectedItem; |
| | | @Prop() selectedItem!: FastQueryParams; |
| | | @Prop() questionOption!: QuestionOption; |
| | | |
| | | @Watch('selectedItem', {deep: true, immediate: true}) watchSelected(newValue: selectedItem) { |
| | | @Watch('selectedItem', {deep: true, immediate: true}) watchSelected(newValue: FastQueryParams) { |
| | | if (newValue) { |
| | | this.pickedItem = JSON.parse(JSON.stringify(this.selectedItem)) |
| | | } |
| | | } |
| | | |
| | | } |
| | | </script> |
| | | |
| | |
| | | |
| | | created() { |
| | | if (process.browser) { |
| | | window.onscroll = () => { this.scrollFunction() }; |
| | | document.body.addEventListener('scroll', this.scrollFunction); |
| | | } |
| | | } |
| | | |
| | |
| | | document.body.scrollTop = 0; |
| | | document.documentElement.scrollTop = 0; |
| | | } |
| | | |
| | | destroyed() { |
| | | document.body.removeEventListener('scroll', this.scrollFunction); |
| | | } |
| | | } |
| | | </script> |
| | | |
| | |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop, Emit, Watch } from 'nuxt-property-decorator'; |
| | | import { Agents } from '~/plugins/api/home'; |
| | | import { Consultants } from '~/assets/ts/api/consultant'; |
| | | |
| | | @Component |
| | | export default class UiPagination extends Vue { |
| | | @Prop() totalList!: Agents[]; |
| | | @Prop() totalList!: Consultants[]; |
| | | pageSize = 5; |
| | | currentPage = 1; |
| | | pageList: Agents[] = []; |
| | | pageList: Consultants[] = []; |
| | | |
| | | mounted() { |
| | | this.handleCurrentChange(this.currentPage); |
| | | } |
| | | |
| | | @Emit('changePage') chagnePage(): Agents[] { |
| | | @Emit('changePage') chagnePage(): Consultants[] { |
| | | return this.pageList |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | @Watch('totalList') watchtotalList(newValue: Agents[]) { |
| | | @Watch('totalList') watchtotalList(newValue: Consultants[]) { |
| | | if (newValue) { |
| | | this.handleCurrentChange(this.currentPage); |
| | | } |
| | |
| | | <el-checkbox |
| | | v-for="(option, index) in options" |
| | | :key="index" |
| | | :label="option" |
| | | :name="option" |
| | | ></el-checkbox> |
| | | :label="option.label"> |
| | | {{option.title}} |
| | | </el-checkbox> |
| | | <template v-if="nameOfSelectAll"> |
| | | <button class="pam-selectAll-btn cursor--pointer" :class="{'selected':isSelectAll}" :model="isSelectAll" @click="selectAll"> |
| | | <span>{{nameOfSelectAll}}</span> |
| | | </button> |
| | | </template> |
| | | <template v-if="nameOfOtherOption"> |
| | | <button class="pam-selectAll-btn cursor--pointer" :class="{'selected':isSelectOtherOption}" :model="isSelectOtherOption" @click="selectOther"> |
| | | <span>{{nameOfOtherOption}}</span> |
| | | </button> |
| | | <div> |
| | | <input class="pam-muti-select-other cursor--pointer" v-if="isSelectOtherOption" v-model="syncOtherSelect" placeholder="è«è¼¸å
¥,é20å"> |
| | | </div> |
| | | </template> |
| | | </el-checkbox-group> |
| | | </div> |
| | |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop, PropSync} from 'vue-property-decorator'; |
| | | import { OptionBtnDto } from './singleSelectBtn.vue'; |
| | | |
| | | @Component |
| | | export default class MultiSelectBtn extends Vue { |
| | | @PropSync('mutiSelect',{type:Array,default:()=>[]}) syncMutiSelect!:string[]; |
| | | @Prop({default:()=>[]}) options!:OptionBtnDto[]; |
| | | @Prop({default:''}) nameOfSelectAll!:string; |
| | | @Prop({default:()=>[]}) options!:string[]|[]; |
| | | @PropSync('otherSelect',{default:''}) syncOtherSelect!:string; |
| | | @Prop({type:String,default:''}) nameOfOtherOption!:string; |
| | | isSelectOtherOption=false; |
| | | isSelectAll=false; |
| | | |
| | | updated() { |
| | |
| | | |
| | | selectAll():void{ |
| | | this.isSelectAll= !this.isSelectAll; |
| | | this.syncMutiSelect = this.isSelectAll ? this.options:[]; |
| | | this.syncMutiSelect = this.isSelectAll ? this.optionsFormat(this.options):[]; |
| | | } |
| | | |
| | | optionsFormat(optios:OptionBtnDto[]):string[]{ |
| | | return optios.map(o=>o.title); |
| | | } |
| | | selectOther():void{ |
| | | this.isSelectOtherOption = !this.isSelectOtherOption; |
| | | if(!this.isSelectOtherOption){ |
| | | this.syncOtherSelect = ''; |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | |
| | | color: $PRIMARY_WHITE; |
| | | } |
| | | } |
| | | .pam-muti-select-other { |
| | | height: 50px; |
| | | padding: 5px; |
| | | -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ |
| | | -moz-box-sizing: border-box; /* Firefox, other Gecko */ |
| | | box-sizing: border-box; |
| | | width: 316px; |
| | | border: 1px solid #CCCCCC; |
| | | } |
| | | </style> |
| | |
| | | |
| | | <PopUpFrame class="pam-popUpFrame" |
| | | :isOpen.sync="isOpenByStep_1" |
| | | :model="isOpenByStep_1" |
| | | :drawerSize="drawerSize" |
| | | :dialogWidth="dialogWidth"> |
| | | <div class="pam-popUp-title">{{popUpTitle}}</div> |
| | |
| | | <script lang="ts"> |
| | | import { Component,PropSync,Vue } from "nuxt-property-decorator"; |
| | | import * as _ from "lodash"; |
| | | import { OptionBtnDto } from "./singleSelectBtn.vue"; |
| | | @Component |
| | | export default class PhoneContactTimePicker extends Vue { |
| | | @PropSync('scheduleList',{type:Array,default:()=>[]}) syncScheduleList!:scheduleDto[]; |
| | | private weekOptions ={ |
| | | selectAll:'æ¯å¤©', |
| | | options:['禮æä¸','禮æäº','禮æä¸','禮æå','禮æäº','禮æå
','ç¦®ææ¥'], |
| | | options:[ |
| | | { |
| | | title:'禮æä¸', |
| | | label:'禮æä¸' |
| | | }, |
| | | { |
| | | title:'禮æäº', |
| | | label:'禮æäº' |
| | | }, |
| | | { |
| | | title:'禮æä¸', |
| | | label:'禮æä¸' |
| | | }, |
| | | { |
| | | title:'禮æå', |
| | | label:'禮æå' |
| | | }, |
| | | { |
| | | title:'禮æäº', |
| | | label:'禮æäº' |
| | | }, { |
| | | title:'禮æå
', |
| | | label:'禮æå
' |
| | | }, |
| | | { |
| | | title:'ç¦®ææ¥', |
| | | label:'ç¦®ææ¥' |
| | | }, |
| | | ], |
| | | }; |
| | | private timesOfDayOptions ={ |
| | | selectAll:'å
¨å¤©', |
| | | options:['9:00~12:00','12:00~14:00','14:00~18:00','18:00~21:00'], |
| | | options:[ |
| | | { |
| | | title:'9:00~12:00', |
| | | label:'9:00~12:00', |
| | | }, |
| | | { |
| | | title:'12:00~14:00', |
| | | label:'12:00~14:00', |
| | | }, |
| | | { |
| | | title:'14:00~18:00', |
| | | label:'14:00~18:00', |
| | | }, |
| | | { |
| | | title:'18:00~21:00', |
| | | label:'18:00~21:00', |
| | | } |
| | | ], |
| | | }; |
| | | private drawerSize="40%"; |
| | | private dialogWidth="376px"; |
| | |
| | | this.selectedSchedule.selectWeekOptions = this.getOptionsBySort(this.weekOptions.options,this.initPickerControl.selectWeekOptions); |
| | | this.selectedSchedule.selectTimesOptions = this.getOptionsBySort(this.timesOfDayOptions.options,this.initPickerControl.selectTimesOptions); |
| | | } |
| | | getOptionsBySort(options:string[],selectedOptions:string[]):string[]{ |
| | | return options.filter( o => _.includes(selectedOptions,o)); |
| | | getOptionsBySort(options:OptionBtnDto[],selectedOptions:string[]):string[]{ |
| | | return options.map( o => _.includes(selectedOptions,o.title) ? o.title :'').filter(String); |
| | | // return |
| | | } |
| | | addNewSchedule():void{ |
| | | const newScheduleDto={ |
| | |
| | | const chineseNumber = ['ä¸','äº','ä¸','å','äº','å
','ä¸','å
«','ä¹','å'] |
| | | return 'ææ®µ'+chineseNumber[index]; |
| | | } |
| | | optionsFormat(options:string[],needToCompareList:OptionDto):string{ |
| | | optionsFormat(options:OptionBtnDto[],needToCompareList:OptionDto):string{ |
| | | return _.isEqual(options.length,needToCompareList.options.length) ? needToCompareList.selectAll: _.join(options,','); |
| | | } |
| | | } |
¤ñ¹ï·sÀÉ®× |
| | |
| | | <template> |
| | | <div> |
| | | <el-radio-group class="pam-single-btn" |
| | | v-model="syncSingleSelected"> |
| | | <el-radio v-for="(option,index) in options" |
| | | :key="index" |
| | | :label="option.label" |
| | | @click.native.prevent="patchValue(option.label)"> |
| | | <span class="text--middle"> |
| | | {{option.title}} |
| | | </span> |
| | | <span class="radio-sub-title" |
| | | v-if="option.subTitle"> |
| | | {{option.subTitle}} |
| | | </span> |
| | | </el-radio> |
| | | </el-radio-group> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Component, Prop, PropSync, Vue } from "nuxt-property-decorator"; |
| | | import * as _ from 'lodash'; |
| | | @Component |
| | | export default class SingleSelectBtn extends Vue { |
| | | @PropSync('singleSelected', { default: '' }) syncSingleSelected!: string | number; |
| | | @Prop({ type:Array , default:()=>[] }) options!:OptionBtnDto[]; |
| | | |
| | | // 主è¦è§£æ±ºæé黿å
©æ¬¡è½åå°ï¼æªé»é¸ççæ
|
| | | patchValue(value: string): void { |
| | | this.syncSingleSelected = _.isEqual(this.syncSingleSelected, value) ? "" : value; |
| | | } |
| | | } |
| | | export interface OptionBtnDto { |
| | | title: string, |
| | | subTitle?: string, |
| | | label: string | number, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" |
| | | scoped> |
| | | |
| | | </style> |
| | |
| | | <UiGoToTop></UiGoToTop> |
| | | <BackActionBar></BackActionBar> |
| | | <div class="banner" :class="bannerClassName"></div> |
| | | <Nuxt class="page-container" :style="{ height: pageHieght}" ref="pageContainer"></Nuxt> |
| | | <Nuxt class="page-container"></Nuxt> |
| | | <Footer ref="defaultLayoutFooter"></Footer> |
| | | </div> |
| | | </template> |
| | |
| | | } |
| | | |
| | | noBanner(routerName : string) { |
| | | return routerName.match('communication') || routerName.match('agentInfo'); |
| | | } |
| | | |
| | | mounted() { |
| | | window.addEventListener('resize', this.handleResize); |
| | | this.handleResize(); |
| | | } |
| | | |
| | | handleResize(): void { |
| | | const pageContainer: any = this.$refs.pageContainer; |
| | | const footer: any = this.$refs.defaultLayoutFooter; |
| | | const pageAlignPadding = 80; |
| | | const deviceExtraHeight = 36; |
| | | if ((pageContainer.$el.clientHeight + footer.$el.clientHeight) < window.innerHeight) { |
| | | this.pageHieght = (window.innerHeight - footer.$el.clientHeight - pageAlignPadding - deviceExtraHeight) + 'px'; |
| | | } |
| | | return routerName.match('questionnaire') || routerName.match('agentInfo'); |
| | | } |
| | | |
| | | } |
| | |
| | | <style lang="scss" scoped> |
| | | .pam-background { |
| | | background-color: #F8F9FA; |
| | | display: flex; |
| | | flex-direction: column; |
| | | min-height: 100vh; |
| | | .page-container { |
| | | flex: 1; |
| | | } |
| | | } |
| | | |
| | | .page-container { |
| | |
| | | '~/plugins/element-ui.js', |
| | | { src: '~/plugins/vue-awesome-swiper.js', mode: 'client' }, |
| | | '~/plugins/service.ts', |
| | | '~/plugins/vue-scroll-picker' |
| | | '~/plugins/vue-scroll-picker', |
| | | '~/plugins/filters/date.filter.ts' |
| | | ], |
| | | |
| | | // Auto import components: https://go.nuxtjs.dev/config-components |
| | |
| | | scss: [ |
| | | '~/assets/scss/main.scss' |
| | | ] |
| | | }, |
| | | router: { |
| | | scrollBehavior (to, from, savedPosition) { |
| | | if (savedPosition) { |
| | | return savedPosition; |
| | | } else { |
| | | document.body.scrollTop = 0; |
| | | document.documentElement.scrollTop = 0; |
| | | } |
| | | } |
| | | } |
| | | } |
File was renamed from PAMapp/pages/agentInfo/index.vue |
| | |
| | | justify="center" |
| | | align="middle"> |
| | | <i class="pam-icon icon--primary icon-star"></i> |
| | | <h3 class="mdTxt">{{ agentInfo.avgReviews }}</h3> |
| | | <h3 class="mdTxt">{{ agentInfo.avgScore }}</h3> |
| | | </el-row> |
| | | |
| | | <el-row |
| | |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Context } from '@nuxt/types'; |
| | | import { Vue, Component } from 'vue-property-decorator'; |
| | | import { getConsultantDetail } from '~/assets/ts/api/consultant'; |
| | | |
| | | @Component |
| | | export default class AgentInfoComponent extends Vue { |
| | | agentInfo: AgentInfo = { |
| | | name: 'è¡ç¾ç', |
| | | role: '伯æ¨ä¿éªç¶ç´äºº', |
| | | avgReviews: 4.8, |
| | | title: 'å°æ¡ç¶ç', |
| | | phoneNumber: '0912345689', |
| | | serveArea: 'å°åå¸å°åãæ°åå¸å°å', |
| | | companyAddress: 'å°åå¸ä¿¡ç¾©åå¿ åæ±è·¯ä¸æ®µ1è', |
| | | lastestLoginTime: new Date(), |
| | | seniority: '4å¹´2åæ', |
| | | suitability: 53, |
| | | evaluation: 31, |
| | | expertises: ['財åè¦å', 'è³ç¢ç§»è½', 'ç¯ç¨
', 'æ¨æ´»éä¼'], |
| | | concept: '壽éªè·¯ä¸æ²ææ·å¾ï¼å¯æçµ¦å®¢æ¶ä¿¡ä»»æãå®å
¨æï¼ææ¯æå¥½çæ¹æ³ã徿¥ä»¥ä¾ï¼æä¸ç´ç§æèãå©äººçºå¿«æ¨ä¹æ¬ãç信念å
æèï¼å¥¹ç¸ä¿¡ï¼ä¸åå¥½çæ¥å人å¡ï¼å¿
é æ±æèä¸é¡ç±å¿å©äººçå¿ï¼ææ¯æ°¸çºç¶ç壽éªäºæ¥çä¸äºæ³éã', |
| | | experiences: ['å°å¤§è²¡éç³»', 'ç¾èæç²¾ç®å¸«å·ç
§'], |
| | | awards: 'å
¥é¸ï¼2020年伯æ¨å大æä½³æ¥åå¡ ææèç
§ï¼äººèº«ä¿éªæ¥åå¡èç
§ãå¤å¹£æ¶ä»ä¿éªèç
§ã人身ä¿éªä»£ç人èç
§ã財ç¢ä¿éªä»£ç人èç
§' |
| | | agentInfo!: AgentInfo; |
| | | |
| | | 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})`; |
| | |
| | | |
| | | interface AgentInfo { |
| | | name: string; |
| | | agentNo:string; |
| | | role: string; |
| | | avgReviews: number; |
| | | image: string; |
| | | avgScore: number; |
| | | title: string; |
| | | phoneNumber: string; |
| | | serveArea: string; |
| | | companyAddress: string; |
| | | lastestLoginTime: Date; |
| | | lastestLoginTime: Date | null; |
| | | seniority: string; |
| | | suitability: number; |
| | | evaluation: number; |
| | |
| | | <template> |
| | | <div> |
| | | <el-button @click="login">ç»å
¥</el-button> |
| | | <el-button @click="remove">ç»åº</el-button> |
| | | <Ui-Carousel></Ui-Carousel> |
| | | <div class="page-container"> |
| | | <h5 class="mdTxt mb-30">é ç´ä¿éªé¡§å</h5> |
| | |
| | | <span class="mdTxt">æç顧忏
å®</span> |
| | | <span class="smTxt_bold amount">å
± {{consultantList.length}} ç</span> |
| | | </el-col> |
| | | <el-col :span="8" class="mdTxt readMore" |
| | | <el-col |
| | | :span="8" |
| | | class="mdTxt readMore" |
| | | v-if="consultantList.length > 3" |
| | | @click.native="routerPush('/myConsultantList/consultantList')">æ¥çæ´å¤</el-col> |
| | | </el-row> |
| | | <ConsultantList |
| | |
| | | <h5 class="mdTxt">æ¨è¦ä¿éªé¡§å</h5> |
| | | <img class="absulate img" src="~/assets/images/index_recommend.svg" alt=""> |
| | | </div> |
| | | <ConsultantSwiper :agents="agents"></ConsultantSwiper> |
| | | <ConsultantSwiper :agents="recommendList"></ConsultantSwiper> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component } from 'nuxt-property-decorator'; |
| | | import { Agents } from '~/plugins/api/home'; |
| | | import { Context } from '@nuxt/types/app'; |
| | | import { Vue, Component, State, Action } from 'nuxt-property-decorator'; |
| | | import { getFavoriteFromStorage, setFavoriteToStorage } from '~/assets/ts/storageConsultant'; |
| | | import { addFavoriteConsultant, Consultants } from '~/assets/ts/api/consultant'; |
| | | import { login, getFavoriteConsultant } from '~/assets/ts/api/consultant'; |
| | | import { isLogin } from '~/assets/ts/auth'; |
| | | |
| | | @Component({ |
| | | layout: 'home' |
| | | }) |
| | | export default class MainComponent extends Vue { |
| | | agents: Agents[] = []; |
| | | consultantList: Agents[] = []; |
| | | consultantList: Consultants[] = []; |
| | | agents: Consultants[] = []; |
| | | @State('recommendList') recommendList!: Consultants[]; |
| | | @Action storeRecommendList!: any; |
| | | |
| | | async asyncData(context: Context) { |
| | | let agents: Agents[] = []; |
| | | let consultantList: Agents[] = []; |
| | | await context.$service.home.recommendConsultantList().then((result: Agents[]) => { |
| | | agents = result; |
| | | }) |
| | | mounted() { |
| | | if (!this.recommendList) { |
| | | this.storeRecommendList(); |
| | | } |
| | | |
| | | consultantList = agents.filter(item => item.contactStatus !== 'contacted'); |
| | | if (isLogin()) { |
| | | this.addFavoriteFromStorageToApi(); |
| | | getFavoriteConsultant().then((response) => this.consultantList = response.data); |
| | | } else { |
| | | this.consultantList = getFavoriteFromStorage(); |
| | | } |
| | | } |
| | | |
| | | return { |
| | | agents, |
| | | consultantList |
| | | addFavoriteFromStorageToApi() { |
| | | const agentNoList = getFavoriteFromStorage().map(i => i.agentNo) |
| | | if (agentNoList.length > 0) { |
| | | addFavoriteConsultant(agentNoList).then(res => res); |
| | | localStorage.removeItem('favoriteConsultant'); |
| | | } |
| | | } |
| | | |
| | |
| | | this.$router.push(path); |
| | | } |
| | | |
| | | removeAgent(agentNo: number) { |
| | | removeAgent(agentNo: string) { |
| | | const findIndex = this.consultantList.findIndex((item, i) => { |
| | | return item.agentNo === agentNo; |
| | | }) |
| | | this.consultantList.splice(findIndex, 1) |
| | | this.consultantList.splice(findIndex, 1); |
| | | if (!isLogin()) { |
| | | setFavoriteToStorage(this.consultantList) |
| | | } |
| | | } |
| | | |
| | | // TODO: å
OTPèªèéç¼å æ«æä½¿ç¨ |
| | | login() { |
| | | const user = { |
| | | username: "user", |
| | | password: "user" |
| | | } |
| | | login(user).then((res) => { |
| | | localStorage.setItem('id_token', res.data.id_token); |
| | | this.$router.go(0); |
| | | }) |
| | | } |
| | | |
| | | // TODO: å
OTPèªèéç¼å æ«æä½¿ç¨ |
| | | remove() { |
| | | localStorage.removeItem('id_token'); |
| | | this.$router.go(0) |
| | | } |
| | | |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | <template> |
| | | <div>ç»å
¥</div> |
| | | <div class="pam-login-page"> |
| | | <div class="text--middle">ç»å
¥</div> |
| | | |
| | | <div class="pam-paragraph"> |
| | | <div class="mdTxt"> |
| | | ç¶å®æ¹å¼ |
| | | </div> |
| | | <div class="pam-tags"> |
| | | <el-row type="flex" class="pt-10"> |
| | | <el-button |
| | | :class="{ 'active': connectDevice === 'MOBILE'}" |
| | | @click="connectDevice = 'MOBILE'">ææ©è碼</el-button> |
| | | <el-button |
| | | :class="{ 'active': connectDevice === 'EMAIL'}" |
| | | @click="connectDevice = 'EMAIL'">Email</el-button> |
| | | </el-row> |
| | | |
| | | |
| | | </div> |
| | | <el-row type="flex" class="pt-10" v-show="connectDevice === 'MOBILE'"> |
| | | <input |
| | | class="pam-input" |
| | | :class="{ |
| | | 'is-invalid': !phoneNumber |
| | | }" |
| | | v-model="phoneNumber" |
| | | placeholder="è«è¼¸å
¥ææ©è碼" |
| | | > |
| | | </el-row> |
| | | |
| | | <el-row class="pt-10" v-show="connectDevice === 'EMAIL'"> |
| | | <input |
| | | class="pam-input" |
| | | :class="{ |
| | | 'is-invalid': !phoneNumber |
| | | }" |
| | | v-model="email" |
| | | placeholder="è«è¼¸å
¥ Email å°å" |
| | | > |
| | | </el-row> |
| | | |
| | | <div class="pt-30" v-show="showPhoneOtpCodeField"> |
| | | <el-row type="flex" justify="space-between"> |
| | | <div class="mdTxt">輸å
¥é©è碼</div> |
| | | <div class="otp-count-timer"> |
| | | 13:50 |
| | | </div> |
| | | </el-row> |
| | | |
| | | <el-row class="pt-10"> |
| | | <input |
| | | class="pam-input" |
| | | :class="{ |
| | | 'is-invalid': !otpCode |
| | | }" |
| | | v-model="otpCode" |
| | | placeholder="è«è¼¸å
¥é©è碼" |
| | | > |
| | | </el-row> |
| | | |
| | | <el-row class="pt-10"> |
| | | <button |
| | | class="pam-otp-resend-btn" |
| | | :class="{'disabled': true}"> |
| | | <i class="icon-arrow"></i> |
| | | éç¼é©è碼({{ otpResendCounter }}) |
| | | </button> |
| | | </el-row> |
| | | </div> |
| | | |
| | | <div v-show="showEmailVerifyField"> |
| | | <el-row class="pt-10"> |
| | | <button |
| | | class="pam-otp-resend-btn" |
| | | :class="{'disabled': onEmailVerifyResendStatus === 'CANNOT_RESEND'}"> |
| | | <i class="icon-arrow"></i> |
| | | éç¼é©è碼({{ emailResendCounter }}) |
| | | </button> |
| | | </el-row> |
| | | </div> |
| | | </div> |
| | | |
| | | <el-row type="flex" justify="center" class="pam-login-page__action-bar"> |
| | | <div v-if="connectDevice === 'MOBILE'"> |
| | | <el-button |
| | | type="primary" |
| | | v-if="onPhoneVerifyStep === 'APPLY_OTP'" |
| | | :disabled="!phoneNumber" |
| | | @click="applyOtpVerification"> |
| | | ç¼éé©è碼 |
| | | </el-button> |
| | | |
| | | <el-button |
| | | type="primary" |
| | | v-if="connectDevice === 'MOBILE' && onPhoneVerifyStep === 'INPUT_OTP'" |
| | | :disabled="!otpCode" |
| | | @click="registerDialogVisable = true"> |
| | | éåº |
| | | </el-button> |
| | | </div> |
| | | |
| | | </el-row> |
| | | |
| | | <el-dialog |
| | | title="æ¡è¿æ°ä½¿ç¨è
" |
| | | :custom-class="'pam-register-dialog'" |
| | | :visible.sync="registerDialogVisable" |
| | | :fullscreen="true" |
| | | :close-on-click-modal="false" |
| | | :show-close="false" |
| | | center> |
| | | <span> |
| | | <el-row> |
| | | <input |
| | | class="pam-input" |
| | | :class="{ |
| | | 'is-invalid': !name |
| | | }" |
| | | v-model="name" |
| | | placeholder="è«è¼¸å
¥å§å" |
| | | > |
| | | </el-row> |
| | | <el-row class="pt-30"> |
| | | <div class="mdTxt"> |
| | | è«å¯©é±æ¢æ¬¾ï¼ä¸¦æ ¸å¾ç¢ºèªå·²é±è®ä¸åæç¸éæ¢æ¬¾å
§å®¹ |
| | | </div> |
| | | </el-row> |
| | | <el-row class="pt-10"> |
| | | <div class="mdTxt pam-register-dialog__contract"> |
| | | èéåäººè³æåç¥äºé
|
| | | éµå®åäººè³æä¿è·æ³è¦å®ï¼å¨æ¨æä¾åäººè³æäºæ¬èåï¼ä¾æ³å |
| | | ç¥ä¸åäºé
ï¼ |
| | | ä¸ãç²åæ¨ä¸ååäººè³æé¡å¥ï¼å§åãåºçå¹´ææ¥ãåæ°èº«åèçµ±ä¸ç·¨èãæ§å¥ãè·æ¥ãæè²ã |
| | | é£çµ¡æ¹å¼(å
æ¬ä½ä¸éæ¼é»è©±è碼ãE-MAILãå±
使工ä½å°å)çï¼æå
¶ä»å¾ä»¥ç´æ¥ |
| | | æéæ¥è奿¨å人ä¹è³æã |
| | | äºãæ¬èå°ä¾åäººè³æä¿è·æ³åç¸éæ³ä»¤ä¹è¦å®ä¸ï¼ä¾æ¬èé±ç§æ¬ä¿è·æ¿çï¼èéã |
| | | èçåå©ç¨æ¨çåäººè³æã |
| | | ä¸ãæ¬èå°æ¼èéç®çä¹åçºæéåçå©ç¨æ¨çåäººè³æã |
| | | åãé¤èéä¹ç®çæ¶åå鿥忿´»åå¤ï¼æ¬èå
æ¼ä¸è¯æ°åé åå
§å©ç¨æ¨çåäººè³ |
| | | æã |
| | | äºãæ¬èå°æ¼åèéä¹ç¹å®ç®çãæ¬æ¬¡ä»¥å¤ä¹ç¢æ¥ä¹æ¨å»£ã宣å°åè¼å°ã以åå
¶ä»å
¬ |
| | | åæ©éè«æ±è¡æ¿åå©ä¹ç®çç¯åå
§ï¼åçå©ç¨æ¨çåäººè³æã |
| | | å
ãæ¨å¯ä¾åäººè³æä¿è·æ³ç¬¬ 3 æ¢è¦å®ï¼å°±æ¨çåäººè³æåæ¬èè¡ä½¿ä¹ä¸åæ¬å©ï¼ |
| | | (ä¸) æ¥è©¢æè«æ±é±è¦½ã |
| | | (äº) è«æ±è£½çµ¦è¤è£½æ¬ã |
| | | (ä¸) è«æ±è£å
ææ´æ£ã |
| | | (å) è«æ±åæ¢èéãèçåå©ç¨ã |
| | | (äº) è«æ±åªé¤ã |
| | | æ¨å è¡ä½¿ä¸è¿°æ¬å©èå°è´å°æ¨çæ¬çç¢çæ¸ææï¼æ¬èä¸è² ç¸éè³ å責任ãå¦ä¾ |
| | | åäººè³æä¿è·æ³ç¬¬ 14 æ¢è¦å®ï¼æ¬èå¾é
æ¶è¡æ¿ä½æ¥è²»ç¨ã |
| | | ä¸ãè¥æ¨æªæä¾æ£ç¢ºä¹åäººè³æï¼æ¬èå°ç¡æ³çºæ¨æä¾ç¹å®ç®çä¹ç¸éæ¥åã |
| | | å
«ãæ¬èå æ¥åéè¦èå§è¨å
¶ä»æ©éèçæ¨çåäººè³ææï¼æ¬èå°æåç¡ç£ç£ä¹è²¬ã |
| | | ä¹ãæ¨çè§£æ¤ä¸åææ¸ç¬¦ååäººè³æä¿è·æ³åç¸éæ³è¦ä¹è¦æ±ï¼ä¸åææ¬èç忤å |
| | | ææ¸ï¼ä¾æ¥å¾ååºæ¥é©ã |
| | | åäººè³æä¹åææä¾ |
| | | ä¸ãæ¬äººå·²å
åç¥æè²´èä¸è¿°åç¥äºé
ã |
| | | äºãæ¬äººåæè²´èèéãèçãå©ç¨æ¬äººä¹åäººè³æï¼ä»¥åå
¶ä»å
¬åæ©éè«æ±è¡æ¿å |
| | | å©ç®ç乿ä¾ã |
| | | </div> |
| | | </el-row> |
| | | <el-row class="pt-30"> |
| | | <div class="pam-agree-radio"> |
| | | <label for="agreeControct" class="pam-radio"> |
| | | <input |
| | | type="radio" |
| | | id="agreeControct" |
| | | @click="agreeControct = !agreeControct" |
| | | value="agreeControct"> |
| | | <i :class="agreeControct ?'icon-checkbox-1': 'icon-checkbox'"></i>æåæä¸¦ç¹¼çº |
| | | </label> |
| | | </div> |
| | | </el-row> |
| | | </span> |
| | | <span slot="footer" class="dialog-footer"> |
| | | <el-button |
| | | type="primary" |
| | | :disabled="!name || !agreeControct" |
| | | @click="applyAccount" |
| | | >å»ºç«æ°å¸³è |
| | | </el-button> |
| | | </span> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | |
| | | |
| | | @Component |
| | | export default class Login extends Vue { |
| | | connectDevice: 'MOBILE' | 'EMAIL' = 'MOBILE'; |
| | | |
| | | phoneNumber = ''; |
| | | otpCode = ''; |
| | | onPhoneVerifyStep: 'APPLY_OTP' | 'INPUT_OTP' | 'SUBMIT_OTP' = 'APPLY_OTP'; |
| | | otpResendCounter = 30; |
| | | |
| | | email = ''; |
| | | onEmailVerifyResendStatus: 'CAN_RESEND' | 'CANNOT_RESEND' = 'CANNOT_RESEND'; |
| | | emailResendCounter = 30; |
| | | |
| | | registerDialogVisable = false; |
| | | name = ''; |
| | | agreeControct = false; |
| | | |
| | | get showPhoneOtpCodeField(): boolean { |
| | | return this.connectDevice === 'MOBILE' && this.onPhoneVerifyStep === 'INPUT_OTP'; |
| | | } |
| | | |
| | | get showEmailVerifyField(): boolean { |
| | | return this.connectDevice === 'EMAIL'; |
| | | } |
| | | |
| | | applyOtpVerification(): void { |
| | | this.onPhoneVerifyStep = 'INPUT_OTP'; |
| | | } |
| | | |
| | | applyAccount(): void { |
| | | console.log('apply new account!') |
| | | } |
| | | |
| | | } |
| | | </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; |
| | | } |
| | | } |
| | | |
| | | .pam-input { |
| | | height: 26px; |
| | | width: calc(100% - 36px); |
| | | border-radius: 10px !important; |
| | | padding: 12px 18px !important; |
| | | border-width: 1px; |
| | | outline: none; |
| | | @extend .text--middle; |
| | | &::placeholder { |
| | | color: $PRUDENTIAL_GREY; |
| | | } |
| | | &.is-invalid { |
| | | border: 1px solid $PRIMARY_RED !important; |
| | | border-radius: 20px; |
| | | } |
| | | } |
| | | |
| | | .pam-otp-resend-btn { |
| | | background: transparent; |
| | | border: none; |
| | | color: $PRIMARY_RED; |
| | | font-weight: bold; |
| | | i { |
| | | margin-right: 10px; |
| | | } |
| | | &.disabled { |
| | | color: $LIGHT_GREY; |
| | | } |
| | | } |
| | | |
| | | .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; |
| | | } |
| | | |
| | | .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-register-dialog { |
| | | padding: 30px 20px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | border-radius: 0; |
| | | &.el-dialog { |
| | | border-radius: 0; |
| | | } |
| | | .el-dialog__header { |
| | | padding: 0; |
| | | margin-bottom: 30px; |
| | | .el-dialog__title { |
| | | @extend .subTitle; |
| | | } |
| | | } |
| | | .el-dialog__body { |
| | | flex: 1; |
| | | padding: 0; |
| | | margin-bottom: 30px; |
| | | } |
| | | .el-dialog__footer { |
| | | padding: 0 !important; |
| | | } |
| | | } |
| | | |
| | | </style> |
| | |
| | | import { Context } from '@nuxt/types'; |
| | | import { Vue, Component, Watch } from 'vue-property-decorator'; |
| | | import { Route } from 'vue-router/types/router.d' |
| | | import { Agents } from '~/plugins/api/home'; |
| | | import { getFavoriteFromStorage, setFavoriteToStorage } from '~/assets/ts/storageConsultant'; |
| | | import { Consultants, getFavoriteConsultant } from '~/assets/ts/api/consultant'; |
| | | import { isLogin } from '~/assets/ts/auth'; |
| | | |
| | | @Component |
| | | export default class myConsultantList extends Vue { |
| | | activeTabName = 'consultantList'; |
| | | agents: Agents[] = []; |
| | | contactedList: Agents[] = []; |
| | | consultantList: Agents[] = []; |
| | | agents: Consultants[] = []; |
| | | contactedList: Consultants[] = []; |
| | | consultantList: Consultants[] = []; |
| | | |
| | | tabClick(path: string) { |
| | | this.activeTabName = path; |
| | |
| | | } |
| | | |
| | | async asyncData(context: Context) { |
| | | let agents: Agents[] = []; |
| | | let contactedList: Agents[] = []; |
| | | let consultantList: Agents[] = []; |
| | | let agents: Consultants[] = []; |
| | | let contactedList: Consultants[] = []; |
| | | let consultantList: Consultants[] = []; |
| | | |
| | | await context.$service.home.recommendConsultantList().then((result: Agents[]) => { |
| | | agents = result; |
| | | }) |
| | | if (isLogin()) { |
| | | await getFavoriteConsultant().then((response) => agents = response.data); |
| | | } else { |
| | | agents = getFavoriteFromStorage(); |
| | | } |
| | | |
| | | contactedList = agents.filter(item => item.contactStatus === 'contacted'); |
| | | consultantList = agents.filter(item => item.contactStatus !== 'contacted'); |
| | |
| | | } |
| | | } |
| | | |
| | | removeAgent(agentNo: number) { |
| | | removeAgent(agentNo: string) { |
| | | const fintIndex = this.consultantList.findIndex(item => item.agentNo === agentNo); |
| | | this.consultantList.splice(fintIndex, 1); |
| | | if (!isLogin()) { |
| | | setFavoriteToStorage(this.consultantList); |
| | | } |
| | | } |
| | | |
| | | @Watch('$route') watchRouter(currentRoute: Route) { |
| | |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop, Emit } from 'nuxt-property-decorator'; |
| | | import { Agents } from '~/plugins/api/home'; |
| | | import { Vue, Component, Prop, Emit, Getter } from 'nuxt-property-decorator'; |
| | | import { Consultants } from '~/assets/ts/api/consultant'; |
| | | |
| | | @Component |
| | | export default class ConsultantPage extends Vue { |
| | | @Prop() consultantList!: Agents[]; |
| | | pageList: Agents[] = []; |
| | | @Prop() consultantList!: Consultants[]; |
| | | @Getter isLogin!: boolean; |
| | | pageList: Consultants[] = []; |
| | | |
| | | @Emit('remove') remove(agentNo: number) { |
| | | @Emit('remove') removeAgent(agentNo: number) { |
| | | return agentNo; |
| | | } |
| | | |
| | | changePage(pageList: Agents[]) { |
| | | changePage(pageList: Consultants[]) { |
| | | this.pageList = pageList; |
| | | } |
| | | |
| | | removeAgent(agentNo: number) { |
| | | this.remove(agentNo); |
| | | } |
| | | } |
| | | </script> |
| | |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop } from 'nuxt-property-decorator' ; |
| | | import { Agents } from '~/plugins/api/home'; |
| | | import { Consultants } from '~/assets/ts/api/consultant'; |
| | | |
| | | @Component |
| | | export default class ContactedList extends Vue { |
| | | @Prop() contactedList!: Agents[]; |
| | | pageList: Agents[] = []; |
| | | @Prop() contactedList!: Consultants[]; |
| | | pageList: Consultants[] = []; |
| | | |
| | | changePage(pageList: Agents[]) { |
| | | changePage(pageList: Consultants[]) { |
| | | this.pageList = pageList; |
| | | } |
| | | } |
File was renamed from PAMapp/pages/questionnaire/index.vue |
| | |
| | | <div class="pb-10 mt-10 mdTxt required">æ³è¦è©¢åçåé¡ |
| | | <span class="hint text--bold" @click="showDrawer = true"> |
| | | <i class="icon-information text--bold" @click="showDrawer = true"></i>å¯è¤é¸</span></div> |
| | | <ConsultantQues /> |
| | | <ConsultantQues @change="selectedQuestion = $event" class="mb-30"/> |
| | | </div> |
| | | </div> |
| | | <div> |
| | |
| | | |
| | | <i class="icon-down down-icon " style="margin-right:18px" @click="showJobDrawer = true" ></i> |
| | | </div> |
| | | |
| | | <div class="ques-footer pt-30"> |
| | | <el-button type="primary" @click="sendReserve = true">éåº</el-button> |
| | | <el-button type="primary" |
| | | :disabled=" isInitScheduleDisabled || !isSelected" |
| | | @click="sentDemand">éåº</el-button> |
| | | </div> |
| | | |
| | | <UiDrawer :is-visible.sync="showDrawer" size='95%'> |
| | | |
| | | <div class="qaTextTitle mdTxt">æ³è¦è©¢åçåé¡</div> |
| | | |
| | | <PopUpFrame :isOpen.sync="showDrawer" :drawerSize=" '95%' "> |
| | | <div class="qaTextTitle mdTxt"><strong>æ³è¦è©¢åçåé¡</strong></div> |
| | | <div class="qa-dialog"> |
| | | <div v-for="(qaText,index) in queaAboutList" :key="index" > |
| | | <div class="pt-10"> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="qa-dialog-footer mdTxt" @click="showDrawer = false"><p>æç¥éäº</p></div> |
| | | </UiDrawer> |
| | | |
| | | <UiDrawer :is-visible.sync="showJobDrawer" size='60%'> |
| | | |
| | | </PopUpFrame> |
| | | <PopUpFrame :isOpen.sync="showJobDrawer" drawerSize='60%'> |
| | | <div class="job-drawerTxt fz-20"> |
| | | <div class="subTitle mt-18">è·æ¥</div> |
| | | <!-- <p class="mt-30 fz-20" @click="staff ='å
§å¤'" :class="{'jobBtn':staff === 'å
§å¤' }">å
§å¤</p> --> |
| | | |
| | | <div class="radio-btn"> |
| | | <el-radio-group class="pam-radio-group--col" v-model="staff"> |
| | | <el-radio-button style="margin-top:30px" label="å¤å¤"></el-radio-button> |
| | | <el-radio-button style="margin-top:30px" text-color='#F09491' label="å¤å¤"></el-radio-button> |
| | | <el-radio-button style="margin-top:30px" label="å
§å¤"></el-radio-button> |
| | | <el-radio-button style="margin-top:30px" label="å
¶ä»"></el-radio-button> |
| | | </el-radio-group> |
| | |
| | | <div class="job-inputDiv"><input v-if="staff === 'å
¶ä»'" class="job-input mb-30 fz-20 pl-20" v-model="inputValue" > </div> |
| | | <el-button type="primary" class="job-drawerBtn" @click="showJobDrawer = false">確å®</el-button> |
| | | </div> |
| | | </UiDrawer> |
| | | <UiDrawer :is-visible.sync="sendReserve"> |
| | | <div class="fz-20 mt-30">é ç´æåï¼æ¨é ç´çä¿éªé¡§åæ</div> |
| | | </PopUpFrame> |
| | | <PopUpFrame :isOpen.sync="sendReserve" @update:isOpen="closeReservePopUp"> |
| | | <div class="fz-20 mt-30 sendReserve-txt">é ç´æåï¼æ¨é ç´çä¿éªé¡§åæ</div> |
| | | <div class="fz-20 sendReserve-txt">åéèæ¨è¯çµ¡ï¼</div> |
| | | <div class="qa-dialog-footer mdTxt" @click="sendReserve = false"><p>æç¥éäº</p></div> |
| | | </UiDrawer> |
| | | <div class="qa-dialog-footer mdTxt" @click="closeReservePopUp"><p>æç¥éäº</p></div> |
| | | </PopUpFrame> |
| | | |
| | | </div> |
| | | </template> |
| | | <script lang="ts"> |
| | | import { Vue, Component } from 'vue-property-decorator'; |
| | | import { appointmentDemand } from '~/assets/ts/api/consultant'; |
| | | |
| | | |
| | | @Component |
| | | export default class Questionnaire extends Vue { |
| | | |
| | | gender: 'male'|'female' = 'male'; |
| | | // connectTarget:'mobile'|'email'='mobile'; |
| | | connectDevices = ['1111']; |
| | | connectDevices = new Array(); |
| | | mobileNumber = ''; |
| | | email = ''; |
| | | inputValue=''; |
| | | // staff:'in'|'out'|'jobOther'='in'; |
| | | selectedQuestion: SelectedQuestion[] = []; |
| | | staff = 'å¤å¤'; |
| | | |
| | | |
| | | age:'20'|'30'|'40'|'50'|'55'|'60'|'70'|'71' = '20'; |
| | | showDrawer= false; |
| | | showJobDrawer = false; |
| | | sendReserve = false; |
| | | // datepicker Dto |
| | | initScheduleList=[ |
| | | { |
| | | initScheduleList=[{ |
| | | selectWeekOptions:[], |
| | | selectTimesOptions:[], |
| | | } |
| | | ] |
| | | }] |
| | | |
| | | // editJob(targetJob: string): void { |
| | | // const isExist = this.jobList.find((job) => job === targetJob); |
| | | // if (isExist) { |
| | | // const jobIndex = this.jobList.findIndex((job) => job === targetJob); |
| | | // this.jobList.splice(jobIndex, 1); |
| | | // } else { |
| | | // this.jobList.push(targetJob); |
| | | // } |
| | | // } |
| | | queaAboutList=[ |
| | | { |
| | | title:'å¥åº·èä¿é', |
| | |
| | | content:'å¹é
度æ¯ééå´é¸é
å°æå¿«é篩é¸å¾ï¼å°æ¯ä¸ä½ä¿éªé¡§åè³æé²è¡æ¯å°å¾æåºæ¨è¦çµ¦æ¨çåªåæ¸å¼ï¼æ¨å¯ä»¥ä½çºé¸æé©åé¡§åçåèå¼ã' |
| | | }, |
| | | ] |
| | | |
| | | agentNo!: string; |
| | | |
| | | get disableActionButton(): boolean { |
| | | return true; |
| | | }; |
| | | |
| | | |
| | | get isConnectMobile(): boolean { |
| | | return this.connectDevices.includes('mobile'); |
| | |
| | | return this.connectDevices.includes('email'); |
| | | } |
| | | |
| | | mounted() { |
| | | this.agentNo = this.$route.params.agentNo; |
| | | } |
| | | get isSelected() { |
| | | return this.selectedQuestion.findIndex(i => i.selected)>=0 |
| | | } |
| | | |
| | | toggleConnectDevice(selectDevice: 'mobile' | 'email'): void { |
| | | const deviceSelected = this.connectDevices.includes(selectDevice); |
| | | if (deviceSelected) { |
| | | const deviceIndex = this.connectDevices.findIndex((device) => device === selectDevice); |
| | | this.connectDevices.splice(deviceIndex, 1); |
| | | |
| | | if (selectDevice === 'mobile') { |
| | | this.initScheduleList = [{ |
| | | selectWeekOptions:[], |
| | | selectTimesOptions:[], |
| | | }] |
| | | } |
| | | |
| | | if (selectDevice === 'email') { |
| | | this.email = ''; |
| | | } |
| | | return; |
| | | } |
| | | this.connectDevices.push(selectDevice); |
| | | |
| | | } |
| | | |
| | | sentDemand() { |
| | | const data = { |
| | | phone: '09123456789', |
| | | email: this.email, |
| | | contactType: this.connectDevices.toString(), |
| | | gender: this.gender, |
| | | age: this.age, |
| | | job: this.staff, |
| | | requirement: this.getRequirement(), |
| | | hopeContactTime: this.getHopeContactTime(), |
| | | otherRequirement: '', |
| | | agentNo: this.agentNo |
| | | } |
| | | appointmentDemand(data).then(res => { |
| | | this.sendReserve = true |
| | | }) |
| | | } |
| | | |
| | | getRequirement() { |
| | | const requirement = this.selectedQuestion.filter(item => item.selected) |
| | | return requirement.map(item => item.name).toString(); |
| | | } |
| | | |
| | | getHopeContactTime() { |
| | | const initScheduleList = this.initScheduleList.map(item => { |
| | | return { |
| | | selectWeekOptions: item.selectWeekOptions.toString(), |
| | | selectTimesOptions: item.selectTimesOptions.toString() |
| | | } |
| | | }) |
| | | |
| | | return initScheduleList.map(i => { |
| | | return `'${i.selectWeekOptions},${i.selectTimesOptions}'`} |
| | | ).toString() |
| | | } |
| | | |
| | | closeReservePopUp() { |
| | | this.sendReserve = false; |
| | | this.$router.push('/') |
| | | } |
| | | |
| | | get isInitScheduleDisabled() { |
| | | console.log(this.isConnectMobile) |
| | | if (this.isConnectMobile && this.isConnectEmail) { |
| | | return !this.initScheduleList[0].selectWeekOptions.length || !this.initScheduleList[0].selectTimesOptions.length || !this.email |
| | | } else if (this.isConnectMobile) { |
| | | return !this.initScheduleList[0].selectWeekOptions.length || !this.initScheduleList[0].selectTimesOptions.length |
| | | } else if (this.isConnectEmail) { |
| | | return !this.email |
| | | } |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | export interface SelectedQuestion { |
| | | name: string; |
| | | selected: boolean; |
| | | } |
| | | </script> |
| | | <style lang="scss"> |
| | |
| | | .ques-footer{ |
| | | display: flex; |
| | | justify-content: center; |
| | | |
| | | } |
| | | .job-inputDiv{ |
| | | height:90px; |
| | |
| | | border:1px solid #D0D0CE ; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | background-color: #FFFFFF; |
| | | } |
| | | |
| | | .qa-dialog-footer{ |
| | |
| | | padding-right: 16px; |
| | | padding-top: 11px; |
| | | } |
| | | |
| | | .addDate{ |
| | | margin-left: -20px; |
| | | } |
| | | .ageTags{ |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | |
| | | v-for="(question, index) in questionList" |
| | | :key="index" |
| | | class="subTitle quickBtn" |
| | | :disabled="question.name === 'onlineState'" |
| | | |
| | | :disabled="question.name === 'status'" |
| | | @click="openPopUp(question)" |
| | | >{{question.title}}</el-button> |
| | | </div> |
| | |
| | | v-if="selectedItem.gender" |
| | | @removeTag="removeTag('gender')" |
| | | > |
| | | {{selectedItem.gender}} |
| | | {{selectedItem.gender === 'male' ? 'ç·æ§' : '女æ§'}} |
| | | </Ui-Tags> |
| | | <Ui-Tags |
| | | v-if="selectedItem.satisfaction" |
| | | @removeTag="removeTag('satisfaction')" |
| | | v-if="selectedItem.avgScore" |
| | | @removeTag="removeTag('avgScore')" |
| | | > |
| | | {{selectedItem.satisfaction + 'æä»¥ä¸æ»¿æåº¦'}} |
| | | {{selectedItem.avgScore + 'æä»¥ä¸æ»¿æåº¦'}} |
| | | </Ui-Tags> |
| | | <template v-if="selectedItem.style.length > 0"> |
| | | <template v-if="selectedItem.communicationStyles"> |
| | | <Ui-Tags |
| | | v-for="(item, index) in selectedItem.style" |
| | | v-for="(item, index) in selectedItem.communicationStyles" |
| | | :key="index" |
| | | @removeTag="removeTag('style', index)" |
| | | @removeTag="removeTag('communicationStyles', index)" |
| | | > |
| | | {{item}} |
| | | </Ui-Tags> |
| | |
| | | |
| | | <div class="mb-10" v-if="selectedItem.onlineState"></div> |
| | | <div class="emptyBox text--mid_grey" |
| | | v-if="!selectedItem.gender && !selectedItem.satisfaction && selectedItem.style.length === 0 && !selectedItem.onlineState"> |
| | | v-if="isEmpty"> |
| | | <p class="smTxt">å°ç¡ç¯©é¸</p> |
| | | </div> |
| | | </div> |
| | | |
| | | <h5 class="mdTxt mb-10 mt-30">å¿«éç¯©é¸æ¨è¦</h5> |
| | | <div class="mb-10 mt-30"> |
| | | <span class="mdTxt">å¿«éç¯©é¸æ¨è¦</span> |
| | | <span class="smTxt_bold text--prudential_grey ml-10">å
± {{consultantList.length}} ç</span> |
| | | </div> |
| | | <div class="recommend"> |
| | | <img class="img" src="~/assets/images/quickFilter/recommend.svg" alt=""> |
| | | |
| | | <template v-if="consultantList.length > 0"> |
| | | <QuickFilterConsultantList></QuickFilterConsultantList> |
| | | <QuickFilterConsultantList :consultantList="consultantList"></QuickFilterConsultantList> |
| | | </template> |
| | | |
| | | <template v-else> |
| | | <div class="emptyBox bg-white"></div> |
| | | <div class="emptyBox text--mid_grey recommendStyle"> |
| | | <p class="smTxt">å°ç¡æ¨è¦è³æ</p> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | |
| | | <Ui-Drawer |
| | | :isVisible.sync="questionDrawer" |
| | | :size="questionOption.name === 'style' ? '50%' : '30%'" |
| | | @closeDrawer="closePopUp" |
| | | <PopUpFrame |
| | | :isOpen.sync="questionPopUp" |
| | | :drawerSize="questionOption.name === 'communicationStyles' ? '50%' : '30%'" |
| | | @update:isOpen="closePopUp" |
| | | > |
| | | <QuickFilterSelector |
| | | ref="quickFilterRef" |
| | | :drawerVisible.sync="questionDrawer" |
| | | :drawerVisible.sync="questionPopUp" |
| | | :questionOption="questionOption" |
| | | :selectedItem="selectedItem" |
| | | ></QuickFilterSelector> |
| | | </Ui-Drawer> |
| | | </PopUpFrame> |
| | | |
| | | <Ui-Dialog :isVisible.sync="dialog" |
| | | @closeDialog="closePopUp" |
| | | > |
| | | <QuickFilterSelector |
| | | ref="quickFilterRef" |
| | | :drawerVisible.sync="questionDrawer" |
| | | :questionOption="questionOption" |
| | | :selectedItem="selectedItem" |
| | | ></QuickFilterSelector> |
| | | </Ui-Dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Context } from '@nuxt/types'; |
| | | import { Vue, Component } from 'nuxt-property-decorator'; |
| | | import { Agents } from '~/plugins/api/home'; |
| | | import { isMobileDevice } from '~/assets/ts/device'; |
| | | import { Consultants, FastQueryParams } from '~/assets/ts/api/consultant'; |
| | | import QuickFilterDrawer from '~/components/QuickFilter/QuickFilterSelector.vue'; |
| | | import { fastQuery } from '~/assets/ts/api/consultant'; |
| | | |
| | | @Component |
| | | export default class QuickFilter extends Vue { |
| | | dialog = false; |
| | | consultantList = []; |
| | | questionDrawer = false; |
| | | questionPopUp = false; |
| | | consultantList: Consultants[] = []; |
| | | questionOption = {}; |
| | | selectedItem: selectedItem = { |
| | | selectedItem: FastQueryParams = { |
| | | gender: '', |
| | | satisfaction: 0, |
| | | style: [], |
| | | onlineState: '' |
| | | avgScore: 0, |
| | | communicationStyles: [], |
| | | status: '' |
| | | }; |
| | | questionList: QuestionOption[] = [ |
| | | { |
| | | name: 'gender', |
| | | title: 'é¡§åæ§å¥', |
| | | detail: ['ç·æ§', '女æ§'], |
| | | type: 'radio' |
| | | detail: [ |
| | | { name: 'ç·æ§', value: 'male', className: 'btn_man'}, |
| | | { name: '女æ§', value: 'female', className: 'btn_woman'} |
| | | ], |
| | | type: 'radio', |
| | | }, |
| | | { |
| | | name: 'satisfaction', |
| | | name: 'avgScore', |
| | | title: 'é¡§åæ»¿æåº¦', |
| | | detail: [], |
| | | type: '' |
| | | }, |
| | | { |
| | | name: 'style', |
| | | name: 'communicationStyles', |
| | | title: 'æºéé¢¨æ ¼', |
| | | detail: ['謹æ
å實', 'æå¿«ä¸»å', 'èå¿å¾è½', 'å¥è«é¢¨è¶£'], |
| | | detail: [ |
| | | { value: '謹æ
å實', className: 'btn_owl'}, |
| | | { value: 'æå¿«ä¸»å', className: 'btn_tiger'}, |
| | | { value: 'èå¿å¾è½', className: 'btn_koala'}, |
| | | { value: 'å¥è«é¢¨è¶£', className: 'btn_peacock'} |
| | | ], |
| | | type: 'checkbox' |
| | | }, |
| | | { |
| | | name: 'onlineState', |
| | | name: 'status', |
| | | title: 'ä¸ç·çæ
', |
| | | detail: [], |
| | | type: 'radio' |
| | | } |
| | | ]; |
| | | |
| | | async asyncData(context: Context) { |
| | | let consultantList: Agents[] = []; |
| | | |
| | | await context.$service.home.recommendConsultantList().then((result: Agents[]) => { |
| | | consultantList = result; |
| | | }) |
| | | |
| | | return { |
| | | consultantList, |
| | | } |
| | | get isEmpty() { |
| | | return !this.selectedItem.gender |
| | | && !this.selectedItem.avgScore |
| | | && this.selectedItem.communicationStyles.length === 0 |
| | | && !this.selectedItem.status |
| | | } |
| | | |
| | | openPopUp(question: QuestionOption) { |
| | | this.questionOption = question; |
| | | isMobileDevice() ? this.questionDrawer = true : this.dialog = true; |
| | | this.questionPopUp =true; |
| | | } |
| | | |
| | | removeTag(type: string, index: number = 0) { |
| | |
| | | this.selectedItem.gender = '' |
| | | } |
| | | |
| | | if (type === 'satisfaction') { |
| | | this.selectedItem.satisfaction = 0 |
| | | if (type === 'avgScore') { |
| | | this.selectedItem.avgScore = 0 |
| | | } |
| | | |
| | | if (type === 'style') { |
| | | this.selectedItem.style.splice(index, 1) |
| | | if (type === 'communicationStyles') { |
| | | this.selectedItem.communicationStyles.splice(index, 1) |
| | | } |
| | | |
| | | this.isEmpty ? this.consultantList = [] : this.getRecommendList(); |
| | | } |
| | | |
| | | closePopUp() { |
| | | this.selectedItem = JSON.parse(JSON.stringify((this.$refs.quickFilterRef as QuickFilterDrawer).pickedItem)); |
| | | this.getRecommendList(); |
| | | } |
| | | |
| | | getRecommendList() { |
| | | const data = { |
| | | gender: this.selectedItem.gender, |
| | | communicationStyles: this.selectedItem.communicationStyles, |
| | | avgScore: this.selectedItem.avgScore, |
| | | status: this.selectedItem.status |
| | | } |
| | | |
| | | fastQuery(data).then((res) => this.consultantList = res.data) |
| | | } |
| | | |
| | | } |
| | | |
| | | export interface QuestionOption { |
| | | title: string; |
| | | detail: string[]; |
| | | detail: Detail[]; |
| | | type: string; |
| | | name: string; |
| | | } |
| | | |
| | | export interface selectedItem { |
| | | interface Detail { |
| | | value: string; |
| | | name?: string; |
| | | gender: string; |
| | | satisfaction: number; |
| | | style: string[]; |
| | | onlineState: 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; |
| | | } |
| | | } |
| | | |
| | | .bg-white { |
| | | .recommendStyle { |
| | | box-shadow: 0 0 6px #00000029; |
| | | background-color: $PRIMARY_WHITE; |
| | | } |
| | | |
| | |
| | | height: 56px; |
| | | text-align: center; |
| | | box-shadow: 0 0 6px #22222229; |
| | | border-color: $PRIMARY_WHITE; |
| | | border-radius: 10px; |
| | | color: $PRIMARY_BLACK; |
| | | |
| | | &:hover,&:focus { |
| | | color: $PRIMARY_BLACK; |
| | | border-color: $PRIMARY_WHITE; |
| | | background-color: $PRIMARY_WHITE; |
| | | } |
| | | color: $PRIMARY_WHITE; |
| | | background-size: cover; |
| | | background-position: center; |
| | | background-repeat: no-repeat; |
| | | background-image: url('~/assets/images/quickFilter/btn_bg.svg'); |
| | | |
| | | &:disabled { |
| | | color: $PRIMARY_WHITE; |
| | | border-color: $LIGHT_GREY; |
| | | background-color: $LIGHT_GREY; |
| | | background-image: none; |
| | | } |
| | | } |
| | | .quickBtn+.quickBtn { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | .is-disabled { |
| | | background-color: $LIGHT_GREY; |
| | | color: $PRIMARY_WHITE; |
| | | |
| | | &:hover,&:focus { |
| | | color: $PRIMARY_WHITE; |
| | | border-color: $LIGHT_GREY; |
| | | background-color: $LIGHT_GREY; |
| | | } |
| | | |
| | | .recommend { |
| | | position: relative; |
| | | |
| | | .img { |
| | | position: absolute; |
| | | top: -50px; |
| | | right: 10px; |
| | | } |
| | | } |
| | | |
| | |
| | | <template> |
| | | <div class="pam-page"> |
| | | <div class="pb-10 mdTxt">æ¨çæ§å¥</div> |
| | | <div class="mb-30 pam-tags "> |
| | | <el-button style="margin-right:10px" @click="gender = 'male'" :class="{ 'active': gender ==='male'}">ç·æ§</el-button> |
| | | <el-button @click="gender = 'female'" :class="{'active': gender === 'female'}">女æ§</el-button> |
| | | </div> |
| | | <div class="mb-30"> |
| | | <SingleSelectBtn :singleSelected.sync="strictQueryDto.gender" :options="genderOptions"/> |
| | | <div class="mt-30"> |
| | | <div class="pb-10 mdTxt required">æå¨å°å</div> |
| | | <div class="area-choice"><div class="fz-20 area-txt">æ°åå¸</div><i class="icon-down area-icon"></i></div> |
| | | <div class="job-pick cursor--pointer" |
| | | @click="showAddress = true"> |
| | | <input class="fz-20 input cursor--pointer pl-10" |
| | | :value="strictQueryDto.area" |
| | | placeholder="è«é¸æ"> |
| | | <i class="icon-down down-icon"></i> |
| | | </div> |
| | | <div class="mb-10"> |
| | | <div class="pb-10 mdTxt required">æ³è¦è©¢åçåé¡<span class="hint text--bold" @click="showDialog = true"><i class="icon-information text--bold" @click="showDialog = true"></i>å¯è¤é¸</span></div> |
| | | |
| | | <PopUpFrame :isOpen.sync="showAddress" |
| | | :drawerSize="'45%'"> |
| | | <AddressPicker @close="showAddress = false" |
| | | @change="area => strictQueryDto.area = area" /> |
| | | </PopUpFrame> |
| | | </div> |
| | | <ConsultantQues class="mb-30"/> |
| | | |
| | | |
| | | <div class="mb-30 pam-tags"> |
| | | <div class="mt-30"> |
| | | <div class="pb-10 mdTxt required" @click="showDialog = true"> |
| | | æ³è¦è©¢åçåé¡ |
| | | <span class="hint text--bold"> |
| | | <i class="icon-information text--bold"></i>å¯è¤é¸ |
| | | </span> |
| | | </div> |
| | | <MultiSelectBtn :mutiSelect.sync="strictQueryDto.requirements" :options="requirementOptions" /> |
| | | </div> |
| | | <div class="mt-30 pam-tags"> |
| | | <div class= "pb-10 mdTxt">é¡§åå¹´è³</div> |
| | | <div class="rec-ageDesktop"> |
| | | <el-button class="mb-10 qaTags" @click="seniority = 'unlimited'" :class="{'active':seniority === 'unlimited'}"> |
| | | <span class="text--bold">ä¸é </span><span>年齡䏿¯åé¡</span> |
| | | </el-button> |
| | | <el-button class="mb-10 qaTags" @click="seniority = 'junior'" :class="{'active':seniority === 'junior'}"> |
| | | <span class="text--bold">å¹´è¼ </span><span>給年è¼äººä¸åæ©æ</span> |
| | | </el-button> |
| | | <el-button class="mb-10 qaTags" @click="seniority = 'senior'" :class="{'active':seniority === 'senior'}"> |
| | | <span class="text--bold">è³æ·± </span><span>èæ¯èçè¾£</span> |
| | | </el-button> |
| | | <SingleSelectBtn :singleSelected.sync="strictQueryDto.seniority" :options="seniorityOptions"/> |
| | | </div> |
| | | |
| | | |
| | | </div> |
| | | |
| | | <div class="rate-consultant mb-30"> |
| | | <div> |
| | | <div class="rate-consultant mt-30"> |
| | | <div class="pb-10 mdTxt">ä¿éªé¡§å滿æåº¦</div> |
| | | <el-rate v-model="strictQueryDto.avgScore" |
| | | :colors="elRateColors" |
| | | class="rate"> |
| | | </el-rate> |
| | | </div> |
| | | <el-rate v-model="ratevalue" :colors="elRateColors" class="rate" @change="selected"></el-rate> |
| | | </div> |
| | | |
| | | <div class="mb-30"> |
| | | <div class="mt-30"> |
| | | <div class="rec-popular"> |
| | | <div class="pb-10 mdTxt">ç±é檢索</div> |
| | | <div class="hint text--bold ml-10">å¯è¤é¸</div> |
| | | </div> |
| | | <div class="pop-tag pam-tags"> |
| | | <div v-for="(popularItem,index) in popularList" :key="index"> |
| | | <el-button class="rec-pop-btn" :class="{'active': popularItem.reversation}" |
| | | @click="popularTarget(index)">{{'#'+popularItem.name}} |
| | | </el-button> |
| | | <MultiSelectBtn :mutiSelect.sync="strictQueryDto.popularTags" |
| | | :options="popularOptions" |
| | | :nameOfOtherOption="'#å
¶ä»'" :otherSelect.sync="strictQueryDto.otherPopularTags" /> |
| | | </div> |
| | | <div class="pam-tags popOtherBtn"> |
| | | <el-button class="other-PopBtn " @click="popOther=!popOther" :class="{'active':popOther=popOther}">#å
¶ä»</el-button> |
| | | </div> |
| | | </div> |
| | | <div> |
| | | <input v-if="popOther" class="other-input " placeholder="è«è¼¸å
¥,éXå"> |
| | | </div> |
| | | <div class="rec-footer mt-30"> |
| | | <el-button type="primary" |
| | | :disabled="notFinishByRequireRules" |
| | | @click="makePair">馬ä¸é
å°</el-button> |
| | | </div> |
| | | |
| | | <div class="rec-footer"> |
| | | <el-button |
| | | :disabled="disableActionButton" |
| | | @click="$router.push('recommendConsultant/result')">馬ä¸é
å°</el-button> |
| | | <PopUpFrame :isOpen.sync="showDialog" |
| | | :drawerSize=" '95%' "> |
| | | <div class="qaTextTitle mdTxt"> |
| | | <strong>æ³è¦è©¢åçåé¡</strong> |
| | | </div> |
| | | <UiDrawer :is-visible.sync="showDialog" size='95%'> |
| | | |
| | | <div class="qaTextTitle mdTxt"><strong>æ³è¦è©¢åçåé¡</strong></div> |
| | | |
| | | <div class="qa-dialog"> |
| | | <div v-for="(qaText,index) in queaAboutList" :key="index" > |
| | | <div v-for="(qaText,index) in queaAboutList" |
| | | :key="index"> |
| | | <div class="pt-10"> |
| | | <p class=" p bold">{{qaText.title}}</p> |
| | | <p class="p">{{qaText.content}}</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="qa-dialog-footer mdTxt" @click="showDialog = false"><p>æç¥éäº</p></div> |
| | | </UiDrawer> |
| | | <!-- <UiDialog :is-visible.sync="showDialog" > |
| | | <div class="qa-dialog-footer mdTxt" |
| | | @click="showDialog = false"> |
| | | <p>æç¥éäº</p> |
| | | </div> |
| | | </PopUpFrame> |
| | | |
| | | |
| | | |
| | | |
| | | </UiDialog> --> |
| | | </div> |
| | | </template> |
| | | <script lang="ts"> |
| | | import { Vue, Component } from 'vue-property-decorator'; |
| | | import { |
| | | Vue, |
| | | Component |
| | | } from 'vue-property-decorator'; |
| | | import {strictQuery} from '~/assets/ts/api/consultant'; |
| | | import * as _ from 'lodash'; |
| | | @Component |
| | | export default class RecommendConsultant extends Vue { |
| | | |
| | | ratevalue = null; |
| | | showDialog = false; |
| | | elRateColors=['#ED1B2E','#ED1B2E','#ED1B2E']; |
| | | gender: 'male'|'female' = 'male'; |
| | | seniority:'unlimited'|'junior'|'senior' = 'unlimited' ; |
| | | popOther = ''; |
| | | yearList=[ |
| | | 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:'é²ç«ä¿å®ç¸é', |
| | | }, |
| | | ]; |
| | | seniorityOptions=[ |
| | | { |
| | | title:'ä¸é ', |
| | | subTitle:'年齡䏿¯åé¡', |
| | | reversation:false |
| | | label:'ä¸é', |
| | | }, |
| | | { |
| | | title:'å¹´è¼ ', |
| | | subTitle:'給年è¼äººä¸åæ©æ', |
| | | reversation:false |
| | | label:'å¹´è¼', |
| | | }, |
| | | { |
| | | title:'è³æ·± ', |
| | | subTitle:'èæ¯èçè¾£', |
| | | reversation:false |
| | | }, |
| | | ] |
| | | popularList=[ |
| | | { |
| | | name:'é²ç«', |
| | | reversation:false |
| | | }, |
| | | { |
| | | name:'失è½', |
| | | reversation:false |
| | | }, |
| | | { |
| | | name:'é²ç', |
| | | reversation:false |
| | | }, |
| | | { |
| | | name:'é«ç', |
| | | reversation:false |
| | | }, |
| | | { |
| | | name:'壽éª', |
| | | reversation:false |
| | | }, |
| | | { |
| | | name:'å²è', |
| | | reversation:false |
| | | }, |
| | | { |
| | | name:'æè³', |
| | | reversation:false |
| | | }, |
| | | { |
| | | name:'æå¤', |
| | | reversation:false |
| | | label:'è³æ·±', |
| | | } |
| | | ] |
| | | ]; |
| | | popularOptions=[ |
| | | { |
| | | title: '#é²ç«', |
| | | label:'' |
| | | }, |
| | | { |
| | | title: '#失è½', |
| | | label:'失è½' |
| | | }, |
| | | { |
| | | title: '#é²ç', |
| | | label:'é²ç' |
| | | }, |
| | | { |
| | | title: '#é«ç', |
| | | label:'é«ç' |
| | | }, |
| | | { |
| | | title: '#壽éª', |
| | | label: '壽éª' |
| | | }, |
| | | { |
| | | title: '#å²è', |
| | | label:'å²è' |
| | | }, |
| | | { |
| | | title: '#æè³', |
| | | label:'æè³' |
| | | }, |
| | | { |
| | | title: '#æå¤', |
| | | label:'æå¤' |
| | | } |
| | | ]; |
| | | queaAboutList=[ |
| | | { |
| | | title:'å¥åº·èä¿é', |
| | |
| | | title:'å
¶ä»', |
| | | content:'å¹é
度æ¯ééå´é¸é
å°æå¿«é篩é¸å¾ï¼å°æ¯ä¸ä½ä¿éªé¡§åè³æé²è¡æ¯å°å¾æåºæ¨è¦çµ¦æ¨çåªåæ¸å¼ï¼æ¨å¯ä»¥ä½çºé¸æé©åé¡§åçåèå¼ã' |
| | | }, |
| | | ] |
| | | ageTarget(index: any){ |
| | | this.yearList[index].reversation = !this.yearList[index].reversation ; |
| | | ]; |
| | | showDialog = false; |
| | | showAddress = false; |
| | | elRateColors = ['#ED1B2E', '#ED1B2E', '#ED1B2E']; |
| | | |
| | | makePair():void{ |
| | | strictQuery(this.strictQueryDto).then(res=>{ |
| | | console.log('resultData',res.data); |
| | | this.$router.push('/recommendConsultant/result'); |
| | | }); |
| | | } |
| | | popularTarget(index: any){ |
| | | this.popularList[index].reversation = !this.popularList[index].reversation ; |
| | | get notFinishByRequireRules():boolean{ |
| | | const area = this.strictQueryDto.area; |
| | | const requirementLength = this.strictQueryDto.requirements.length; |
| | | return !(area && requirementLength >0) |
| | | } |
| | | |
| | | get disableActionButton(): boolean { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | // @Prop() ilist |
| | | |
| | | // remove() { |
| | | |
| | | // } |
| | | |
| | | // get agentList() { |
| | | // return |
| | | // } |
| | | selected() { |
| | | console.log(this.ratevalue); |
| | | } |
| | | enum Gender{ |
| | | MALE="male", |
| | | FEMALE="female", |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .popOtherBtn{ |
| | | 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; |
| | | height: auto; |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .qaTextTitle{ |
| | | margin-top:30px |
| | | } |
| | | |
| | | .qa-dialog-footer{ |
| | | display: flex; |
| | | justify-content: center; |
| | | margin-bottom: 81px; |
| | | color: #ED1B2E; |
| | | } |
| | | |
| | | .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; |
| | |
| | | justify-content: space-between; |
| | | background-color: #FFFFFF; |
| | | } |
| | | |
| | | .area-icon{ |
| | | color:#ED1B2E; |
| | | font-size: 25px; |
| | |
| | | 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; |
| | |
| | | background-color: #A7A8AA; |
| | | border:1px solid #A7A8AA; |
| | | } |
| | | |
| | | .rec-footer{ |
| | | height:70px; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | margin: -10px; |
| | | } |
| | | |
| | | .other-PopBtn{ |
| | | width: 90px; |
| | | height: 47px; |
| | | margin-top: 10px; |
| | | } |
| | | .other-input{ |
| | | margin-top: 20px; |
| | | height: 50px; |
| | | width:316px; |
| | | border:1px solid #CCCCCC; |
| | | ; |
| | | } |
| | | |
| | | |
| | | |
| | | .rec-ques-location{ |
| | | display:flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .pop-tag{ |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | margin: -10px; |
| | | |
| | | } |
| | | |
| | | .rec-popular{ |
| | | display: flex; |
| | | align-items: baseline; |
| | |
| | | .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; |
| | |
| | | width: 90px; |
| | | height:47px; |
| | | } |
| | | |
| | | .rate-consultant{ |
| | | |
| | | .el-rate__icon{ |
| | | font-size:35px |
| | | } |
| | | } |
| | | |
| | | .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; |
| | |
| | | font-size: 16px; |
| | | color: #ED1B2E; |
| | | font-weight: bold; |
| | | |
| | | .icon-information { |
| | | padding: 0 5px; |
| | | } |
| | |
| | | } |
| | | |
| | | @include desktop { |
| | | .other-input{ |
| | | height: 50px; |
| | | width:316px; |
| | | border:1px solid #CCCCCC; |
| | | margin-left: 10px; |
| | | } |
| | | |
| | | .desktopBtn{ |
| | | margin-right: 10px; |
| | | height:47px |
| | | |
| | | } |
| | | |
| | | .popOtherBtn{ |
| | | margin-left:10px; |
| | | margin-top:-10px; |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | </style> |
| | |
| | | <div> |
| | | <div class="mdTxt pb-10">å´é¸é¡§åæ¨è¦</div> |
| | | <ul class="pam-rec-agent__list"> |
| | | <li class="pam-rec-agent-card" v-for="(info,index) in recAgentList" :key="index"> |
| | | <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"> |
| | | <img :src="info.avatar" class="avatar"> |
| | | </div> |
| | | <div class="pam-rec-agent-card__main-info"> |
| | | <div class="fz-20 pt-10">{{ info.name }}</div> |
| | | <div class="fz-20 pt-10 rec-desktop-name">{{ info.name }}</div> |
| | | <div class="rec-role">{{ info.role }}</div> |
| | | <span class="rec-detail pt-30">è©³ç´°è³æ</span> |
| | | <span class="rec-detail">è©³ç´°è³æ</span> |
| | | </div> |
| | | </div> |
| | | <div class="pam-rec-agent-card__content-body"> |
| | |
| | | å®¢æ¶æ»¿æåº¦ |
| | | </div> |
| | | <div class="field__content"> |
| | | <i class="icon-star" style="color:#F2C75C"></i> |
| | | {{ info.avgScore }} |
| | | </div> |
| | | </el-col> |
| | |
| | | <el-row |
| | | type="flex" |
| | | justify="center" |
| | | class=""> |
| | | <el-button>+ 顧忏
å®</el-button> |
| | | <el-button type="primary" style="margin-left: 10px">é²è¡é ç´</el-button> |
| | | > |
| | | <el-button class="btn">+ 顧忏
å®</el-button> |
| | | <el-button class="btn2" type="primary" style="margin-left: 10px" @click="$router.push('/questionnaire')" |
| | | >é²è¡é ç´</el-button> |
| | | </el-row> |
| | | </div> |
| | | |
| | | </div> |
| | | </li> |
| | | </ul> |
| | | |
| | | <div class="mt-30"> |
| | | åé å¨ |
| | | </div> |
| | | <UiPagination |
| | | :totalList="recAgentList" |
| | | @changePage="changePage" |
| | | ></UiPagination> |
| | | |
| | | </div> |
| | | </template> |
| | | <script> |
| | | <script lang="ts"> |
| | | import {Vue,Component} from 'vue-property-decorator'; |
| | | |
| | | @Component |
| | |
| | | avgScore:4.8 |
| | | } |
| | | ]; |
| | | pageList: any[] = []; |
| | | |
| | | changePage(pageList: any[]) { |
| | | this.pageList = pageList; |
| | | } |
| | | |
| | | |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .btn{ |
| | | width: 139px; |
| | | height: 47px; |
| | | } |
| | | .btn2{ |
| | | width: 120px; |
| | | height: 47px; |
| | | } |
| | | .pam-rec-agent-card { |
| | | margin-bottom: 10px; |
| | | border-radius: 10px; |
| | | border: 1px solid $LIGHT_GREY; |
| | | padding: 20px 33px; |
| | | margin-right:-20px; |
| | | margin-left:-20px; |
| | | |
| | | .pam-rec-agent-card__content { |
| | | width: 270px; |
| | | .pam-rec-agent-card__content-header { |
| | |
| | | font-size: 20px; |
| | | color:$PRIMARY_RED; |
| | | font-weight: bold; |
| | | padding-top: 30px; |
| | | } |
| | | } |
| | | } |
| | |
| | | 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; |
| | | } |
| | | .pam-paragraph{ |
| | | margin-top: 10px; |
| | | } |
| | | .pam-rec-agent-card { |
| | | margin-right: 20px; |
| | | margin-bottom: 10px; |
| | | border-radius: 10px; |
| | | border: 1px solid $LIGHT_GREY; |
| | | padding-top: 15px; |
| | | padding-bottom: 15px; |
| | | padding-left: 28px; |
| | | padding-right: 20px; |
| | | width: 30%; |
| | | margin-left: 10px; |
| | | |
| | | .pam-rec-agent-card__content { |
| | | width: 190px; |
| | | .pam-rec-agent-card__content-header { |
| | | display: flex; |
| | | .pam-rec-agent-card__avatar { |
| | | display: flex; |
| | | flex-direction: row; |
| | | margin-right: 20px; |
| | | .avatar{ |
| | | width: 80px; |
| | | height: 80px; |
| | | border-radius: 50%; |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | .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; |
| | | |
| | | } |
| | | .btn{ |
| | | width: 90px; |
| | | height: 43px; |
| | | font-size: 14px; |
| | | display: flex; |
| | | justify-content: center; |
| | | padding-top: 12px; |
| | | margin-right: 20px; |
| | | } |
| | | .btn2{ |
| | | width: 90px; |
| | | height: 43px; |
| | | font-size: 14px; |
| | | display: flex; |
| | | justify-content: center; |
| | | padding-top: 12px; |
| | | margin-right: -10px; |
| | | } |
| | | .el-row--flex.is-justify-center{ |
| | | justify-content:none; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | return CommonService.prototype.withDebugData(debugData, '') |
| | | } |
| | | }) |
| | | |
| | | export interface Agents { |
| | | agentNo: number, |
| | | name: string, |
| | | img: string, |
| | | new: boolean, |
| | | satisfaction: number, |
| | | professionals: string[], |
| | | contactStatus: string, |
| | | updateTime: Date |
| | | } |
¤ñ¹ï·sÀÉ®× |
| | |
| | | import Vue from 'vue' |
| | | |
| | | Vue.filter('formatDate', (value: string): string => { |
| | | const date = new Date(value); |
| | | const today = new Date(); |
| | | |
| | | const isToday = (compareDate: Date): boolean => { |
| | | return compareDate.getFullYear() === today.getFullYear() |
| | | && compareDate.getMonth() === today.getMonth() |
| | | && compareDate.getDate() === today.getDate(); |
| | | }; |
| | | |
| | | const isThisYear = (compareDate: Date): boolean => { |
| | | return compareDate.getFullYear() === today.getFullYear(); |
| | | } |
| | | |
| | | if (!value) { |
| | | return 'å°ç¡ç´é'; |
| | | } |
| | | |
| | | if (isThisYear(date)) { |
| | | return isToday(date) |
| | | ? `ä»å¤© ${date.getHours()}:${date.getMinutes()}` |
| | | : `${date.getMonth() + 1}æ${date.getDate()}æ¥ ${date.getHours()}:${date.getMinutes()}`; |
| | | } else { |
| | | return `${date.getFullYear()}å¹´${date.getMonth() + 1}æ${date.getDate()}æ¥ ${date.getHours()}:${date.getMinutes()}`; |
| | | } |
| | | |
| | | }) |
| | |
| | | import { Module, VuexModule } from 'vuex-module-decorators' |
| | | import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators' |
| | | import { Consultants,recommend,AgentOfStrictQuery} from '~/assets/ts/api/consultant'; |
| | | |
| | | @Module |
| | | export default class Store extends VuexModule { |
| | | recommendList: Consultants[] | null = null; |
| | | strictQueryList: AgentOfStrictQuery[] = []; |
| | | |
| | | @Mutation updateRecommend(data: Consultants[]) { |
| | | this.recommendList = data; |
| | | } |
| | | |
| | | @Mutation updateStrictQueryList(data: AgentOfStrictQuery[]) { |
| | | this.strictQueryList = data; |
| | | } |
| | | |
| | | @Action storeRecommendList() { |
| | | recommend().then(res => { |
| | | this.context.commit('updateRecommend', res.data) |
| | | }) |
| | | } |
| | | |
| | | } |