PAMapp/assets/scss/utilities/_heading.scss | ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程 | |
PAMapp/assets/ts/const/quickFilter-questionList.ts | ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程 | |
PAMapp/assets/ts/models/quickFilter.model.ts | ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程 | |
PAMapp/components/QuickFilter/QuickFilterSelector.vue | ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程 | |
PAMapp/pages/quickFilter/index.vue | ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程 |
PAMapp/assets/scss/utilities/_heading.scss
@@ -22,6 +22,10 @@ font-weight: bold; } .lighter { font-weight: lighter; } .smTxt_bold { font-size: 16px; font-weight: bold; PAMapp/assets/ts/const/quickFilter-questionList.ts
@@ -1,3 +1,4 @@ import { Seniority } from "../models/enum/seniority"; import { QuestionOption } from "../models/quickFilter.model"; export const questionList: QuestionOption[] = [ @@ -27,6 +28,16 @@ ], type: 'checkbox' }, { name: 'seniority', title: '年資', detail: [ { name: '年輕', value: Seniority.YOUNG, subTitle: '給年輕人一個機會', className: '' }, { name: '資深', value: Seniority.SENIOR, subTitle: '薑是老的辣', className: '' }, { name: '不限', value: Seniority.UNLIMITED, subTitle: '年齡不是問題', className: '' } ], type: 'radio' } // { // name: 'status', // title: '上線狀態', PAMapp/assets/ts/models/quickFilter.model.ts
@@ -9,13 +9,16 @@ value: string; name?: string; className: string; subTitle?: string } export interface FastQueryParams { gender : string, communicationStyles: string[], avgScore : number, status : string status : string, /** "資深"帶"SENIOR"、"年輕"帶"YOUNG"、"不限"帶"UNLIMITED" */ seniority : string } export interface Selected { PAMapp/components/QuickFilter/QuickFilterSelector.vue
@@ -2,7 +2,7 @@ <div> <div class="mb-10" v-if="questionOption.title !== '顧問性別'"> <span class="mdTxt" >{{questionOption.title === '顧問滿意度' ? '保險顧問滿意度' : questionOption.title}} >{{questionOption.title}} </span> <span class="smTxt_bold text--primary" @@ -14,7 +14,10 @@ >選取星星</span> </div> <div class="quickBtnBlock" v-if="questionOption.name === 'communicationStyles'"> <!-------------------- 溝通風格 --------------------> <div class="quickBtnBlock" v-if="questionOption.name === 'communicationStyles'" > <el-checkbox-group class="pam-quickFilter-checkbox" v-model="pickedItem.communicationStyles" @@ -29,8 +32,37 @@ ></el-checkbox> </el-checkbox-group> </div> <div class="quickBtnBlock" v-else-if="questionOption.name === 'gender'"> <!-------------------- 年資 --------------------> <div class="quickBtnBlock pam-radio-group" v-else-if="questionOption.name === 'seniority'" > <div v-for="(i, index) in questionOption.detail" :key="index" class="pam-radio" > <input :id="i.value" type="radio" name="seniority" :value="i.value" class="el-radio-input" v-model="pickedItem.seniority" > <label :for="i.value" class="el-radio-label" :class="i.className" > <p>{{i.name}}</p> <p class="subtitle">{{i.subTitle}}</p> </label> </div> </div> <!-------------------- 性別 --------------------> <div class="quickBtnBlock" v-else-if="questionOption.name === 'gender'" > <el-radio-group class="pam-quickFilter-radio" v-model="pickedItem.gender" @@ -43,8 +75,8 @@ >{{i.name}}</el-radio> </el-radio-group> </div> <div v-else> <!-------------------- 滿意度 --------------------> <div v-else> <el-rate v-if="!hideReviews" class="pam-quickFilter-rate" @@ -74,7 +106,8 @@ communicationStyles: [], status: '', gender: '', avgScore: 0 avgScore: 0, seniority: '' } hideReviews = hideReviews ; @@ -82,36 +115,34 @@ @Prop() isOpenQuestionPopUp!: boolean; @Prop() confirmItem!: Selected[]; @Watch('isOpenQuestionPopUp', {immediate: true}) onPopUpChange() { @Watch('isOpenQuestionPopUp', {immediate: true}) onPopUpChange() { this.pickedItem = { communicationStyles: this.communicationStyles, communicationStyles: this.getCommunicationStyles(), status: '', gender: this.gender, avgScore: this.avgScore gender: this.getGender(), avgScore: this.getAvgScore(), seniority: this.getSeniority() } } get gender() { const filter = this.confirmItem.filter(item => item.option === 'gender'); return filter.length > 0 ? filter[0].value : ''; @Emit('confirm') confirm() { const name = this.questionOption.name; return { option: name, value: this.pickedItem[name] } } get avgScore() { const filter = this.confirmItem.filter(item => item.option === 'avgScore'); return filter.length > 0 ? filter[0].value : 0; } get communicationStyles() { return this.confirmItem .filter(item => item.option === 'communicationStyles') .map(item => item.value); } ////////////////////////////////////////////////////////////////// get isDisabled() { const name = this.questionOption.name; return name === 'gender' && !this.pickedItem[name] || name === 'avgScore' && !this.pickedItem[name] || name === 'communicationStyles' && !this.pickedItem[name].length || name === 'seniority' && !this.pickedItem[name] } selectedCommunicationStyles() { @@ -120,13 +151,31 @@ } } @Emit('confirm') confirm() { const name = this.questionOption.name; return { option: this.questionOption.name, value: this.pickedItem[name] } ////////////////////////////////////////////////////////////////// private getGender(): string { return this.filterSingleSelected('gender'); } private getAvgScore(): number { return this.filterSingleSelected('avgScore'); } private getCommunicationStyles(): string[] { return this.confirmItem .filter(item => item.option === 'communicationStyles') .map(item => item.value); } private getSeniority(): string { return this.filterSingleSelected('seniority'); } private filterSingleSelected(name: string) { const filter = this.confirmItem.filter(item => item.option === name); return filter.length > 0 ? filter[0].value : (name === 'avgScore' ? 0 : ''); } } </script> @@ -136,8 +185,46 @@ .quickBtnBlock { display: flex; justify-content: space-between; align-content: space-between; flex-wrap: wrap; } .pam-radio-group { height: 240px; .pam-radio { width: 48%; height: 110px; .el-radio-input { display: none; } .el-radio-label { display: flex; flex-direction: column; justify-content: center; align-items: center; width: 100%; height: 100%; box-shadow: 0 0 6px #22222229; border-radius: 10px; -webkit-tap-highlight-color: transparent; font-size: 20px; font-weight: bold; color: $PRIMARY_BLACK; cursor: pointer; .subtitle { font-size: 16px; font-weight: lighter; } } .el-radio-input:checked ~ .el-radio-label { background-color: $PEACH; color: $PRIMARY_WHITE; } } } </style> PAMapp/pages/quickFilter/index.vue
@@ -17,6 +17,10 @@ @removeTag="removeTag(item.value)" > <span v-if="item.option === 'gender'">{{item.value === 'male' ? '男性' : '女性'}}</span> <span v-else-if="item.option === 'seniority'" class="mdTxt lighter"> {{item.value | formatSeniorityTitle}} <span class="smTxt">{{item.value | formatSenioritySubTitle}}</span> </span> <!-- TODO:隱藏滿意度 --> <!-- <span v-else-if="item.option === 'avgScore'">{{item.value + '星以上滿意度'}}</span> --> <span v-else>{{item.value}}</span> @@ -67,12 +71,25 @@ <script lang="ts"> import { Vue, Component, namespace } from 'nuxt-property-decorator'; import { Consultant } from '~/assets/ts/models/consultant.model'; import { fastQuery } from '~/assets/ts/api/consultant'; import { questionList } from '~/assets/ts/const/quickFilter-questionList'; import { FastQueryParams, QuestionOption, Selected } from '~/assets/ts/models/quickFilter.model'; import { fastQuery } from '~/assets/ts/api/consultant'; const localStorage = namespace('localStorage'); @Component @Component({ filters: { formatSeniorityTitle(value) { if (value === 'SENIOR') return '資深'; if (value === 'YOUNG') return '年輕'; return '不限'; }, formatSenioritySubTitle(value) { if (value === 'SENIOR') return '薑是老的辣'; if (value === 'YOUNG') return '給年輕人一個機會'; return '年齡不是問題'; } } }) export default class QuickFilter extends Vue { @localStorage.Mutation storageQuickFilter!: (token: string) => void; @localStorage.Getter quickFilterSelectedData!: Selected[]; @@ -110,25 +127,35 @@ } isActive(name: string) { return name === 'gender' && !!this.gender() || name === 'avgScore' && !!this.avgScore() || name === 'communicationStyles' && !!this.communicationStyles().length return name === 'gender' && !!this.getGender() || name === 'avgScore' && !!this.getAvgScore() || name === 'communicationStyles' && !!this.getCommunicationStyles().length || name === 'seniority' && !!this.getSeniority() } //////////////// private //////////////// private gender(): string { const filter = this.confirmItem.filter(item => item.option === 'gender').map(i => i.value); return filter.length === 0 ? '' : filter[0]; private getGender(): string { return this.filterSingleSelected('gender'); } private avgScore(): number { const filter = this.confirmItem.filter(item => item.option === 'avgScore').map(i => i.value); return filter.length === 0 ? '' : filter[0]; private getAvgScore(): number { return this.filterSingleSelected('avgScore'); } private communicationStyles(): string[] { private getSeniority(): string { return this.filterSingleSelected('seniority'); } private getCommunicationStyles(): string[] { return this.confirmItem.filter(item => item.option === 'communicationStyles').map(i => i.value); } private filterSingleSelected(name: string) { const filter = this.confirmItem.filter(item => item.option === name); return filter.length > 0 ? filter[0].value : (name === 'avgScore' ? 0 : ''); } private setConfirmData(event: Selected) { @@ -162,10 +189,11 @@ private getRecommendList() { const data: FastQueryParams = { gender: this.gender(), communicationStyles: this.communicationStyles(), avgScore: this.avgScore(), status: '' gender: this.getGender(), communicationStyles: this.getCommunicationStyles(), avgScore: this.getAvgScore(), status: '', seniority: this.getSeniority() } fastQuery(data).then((consultantList) => { @@ -199,7 +227,7 @@ .quickBtnBlock { display: flex; width: 100%; // height: 132px; height: 132px; flex-wrap: wrap; justify-content: space-between;