保誠-保戶業務員媒合平台
劉鈞霖
2021-12-28 ef8ad4faedd0cbcfbc2288528bdd1099b8815b86
[ Ref ] : refactor phoneContactTimePicker Component,相關interface 移出
修改5個檔案
新增1個檔案
208 ■■■■ 已變更過的檔案
PAMapp/components/phoneContactTimePicker.vue 173 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/popUpFrame.vue 14 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/singleSelectBtn.vue 7 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/questionnaire/_agentNo.vue 4 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/quickFilter/index.vue 1 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/shared/models/optionBtnDto.model.ts 9 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/phoneContactTimePicker.vue
@@ -2,13 +2,13 @@
<template>
  <div>
    <div class="mt-10" v-for="(scheduleDto,index) in syncScheduleList" :key="index">
      <div class="mdTxt">{{titleFormatByIndex(index)}}</div>
    <div class="mt-10" v-for="(scheduleDto,index) in scheduleList" :key="index">
      <div class="mdTxt">{{index | titleFormatByIndex}}</div>
      <div class="pam-contact-schedule cursor--pointer fix-chrome-click--issue" @click="openPopUp(scheduleDto,index)">
        <div class="pam-contact-schedule__text">
          <template v-if="checkFormHasDone(scheduleDto)">
            <p>{{optionsFormat(scheduleDto.selectWeekOptions,weekOptions)}}</p>
            <p>{{optionsFormat(scheduleDto.selectTimesOptions,timesOfDayOptions)}}</p>
            <p>{{ scheduleDto.selectWeekOptions | optionsFormat(weekOptions)}}</p>
            <p>{{ scheduleDto.selectTimesOptions| optionsFormat(timesOfDayOptions)}}</p>
          </template>
          <template v-else>
            è«‹é¸æ“‡
@@ -17,24 +17,24 @@
        <div class="pam-contact-schedule__icon">
          <i v-if="checkFormHasDone(scheduleDto)"
            class="icon-delet"
            :class="{'disable':syncScheduleList.length===1}"
            @click.stop="deleteScheduleItem(index)">
            :class="{'disable':scheduleList.length===1}"
            @click.stop="deleteScheduleByIndex(index)">
          </i>
          <i v-else class="icon-calender"></i>
        </div>
      </div>
    </div>
    <div class="pam-add-schedule cursor--pointer"
      :class="{'disable':!checkFormHasDone(syncScheduleList[syncScheduleList && syncScheduleList.length && syncScheduleList.length - 1])|| syncScheduleList.length ===7}"
      :class="{'disable': !checkFormHasDone(scheduleList[scheduleList.length && scheduleList.length - 1]) || scheduleList.length===7 }"
      @click="addNewSchedule">
      <i class="icon-add"></i>
      æ–°å¢žæ™‚段
    </div>
    <PopUpFrame class="pam-popUpFrame"
      :isOpen.sync="isOpenByStep_1"
      :dialogWidth="dialogWidth">
        <div class="pam-popUp-title">{{popUpTitle}}</div>
      dialogWidth="376px"
      :isOpen.sync="isOpenByDayPopUp">
        <div class="pam-popUp-title">{{scheduleIndex | titleFormatByIndex}}</div>
          <MultiSelectBtn class="mt-30"
            :mutiSelect.sync="initPickerControl.selectWeekOptions"
            :options="weekOptions.options"
@@ -43,16 +43,16 @@
          <div class="pam-popUp-confirm-block  mt-30">
            <button class="pam-select-confirm"
              :class="[initPickerControl.selectWeekOptions.length?'el-button--primary' :'is-disabled']"
              @click="confirmByStep_1">
              @click="confirmBySelectDay">
              ç¢ºå®š
            </button>
          </div>
    </PopUpFrame>
    <PopUpFrame class="pam-popUpFrame"
      :isOpen.sync="isOpenByStep_2"
      :dialogWidth="dialogWidth">
        <div class="pam-popUp-title">{{popUpTitle}}</div>
      dialogWidth="376px"
      :isOpen.sync="isOpenByTimePopUp">
        <div class="pam-popUp-title">{{scheduleIndex | titleFormatByIndex}}</div>
        <MultiSelectBtn class="mt-30"
          :mutiSelect.sync="initPickerControl.selectTimesOptions"
          :options="timesOfDayOptions.options"
@@ -61,7 +61,7 @@
        <div class="pam-popUp-confirm-block  mt-30">
          <button class="pam-select-confirm"
            :class="[initPickerControl.selectTimesOptions.length ?'el-button--primary' :'is-disabled']"
            @click="confirmByStep_2">
            @click="confirmBySelectTime">
            ç¢ºå®š
          </button>
        </div>
@@ -70,50 +70,90 @@
</template>
<script lang="ts">
  import { Component,PropSync,Vue } from "nuxt-property-decorator";
  import * as _ from "lodash";
  import { weekDays } from "~/shared/const/week-days";
  import { Component, Prop, PropSync, Vue } from "nuxt-property-decorator";
  import { dayTimeFrames } from "~/shared/const/day-time-frames";
import { OptionBtnDto } from "./singleSelectBtn.vue";
  @Component
  import { OptionBtnDto, OptionDto } from "~/shared/models/optionBtnDto.model";
  import { weekDays } from "~/shared/const/week-days";
  import * as _ from "lodash";
  @Component({
    filters:{
      titleFormatByIndex(index:number):string{
        const chineseNumber = ['一','二','三','四','五','六','七','八','九','十'];
        return '時段'+chineseNumber[index];
      },
      optionsFormat(selectedOptions:string[]|[], compareOptions:OptionDto): string{
        return _.isEqual(selectedOptions.length,compareOptions.options.length)
                ? compareOptions.selectAll
                : _.join(selectedOptions,',');
      },
    }
  })
  export default class PhoneContactTimePicker extends Vue {
    @Prop({type:Array,default:()=>[]})
    scheduleList!:scheduleDto[];
    @PropSync('scheduleList',{type:Array,default:()=>[]})
    syncScheduleList!:scheduleDto[];
    private weekOptions ={
    weekOptions = {
      selectAll: '每天',
      options  : weekDays,
    };
    private timesOfDayOptions ={
    timesOfDayOptions = {
      selectAll: '全天',
      options  : dayTimeFrames,
    };
    private initPickerControl = {
      selectWeekOptions:[] as string[],
      selectTimesOptions:[] as string[],
    initPickerControl:scheduleDto = {
      selectWeekOptions : [],
      selectTimesOptions: [],
    }
    // popUp frame
    private dialogWidth      : string = "376px";
    private isOpenByStep_1   : boolean = false;
    private isOpenByStep_2   : boolean = false;
    private popUpTitle       : string= '';
    private selectedSchedule!: scheduleDto;
    popUpMode     : TimePickerMode = TimePickerMode.NONE;
    scheduleIndex : number         = 0;
    //////////////////////////////////////////////////////////////////////
    get isOpenByDayPopUp(): boolean{
      return _.isEqual(this.popUpMode , TimePickerMode.SELECT_DAY)
    }
    set isOpenByDayPopUp(value:boolean){
      this.popUpMode = TimePickerMode.NONE;
    }
    get isOpenByTimePopUp(): boolean{
      return _.isEqual(this.popUpMode , TimePickerMode.SELECT_TIME);
    }
    set isOpenByTimePopUp(value:boolean){
      this.popUpMode = TimePickerMode.NONE;
    }
    //////////////////////////////////////////////////////////////////////
    openPopUp(schedule:scheduleDto,index:number):void{
      this.isOpenByStep_1 = true;
      this.popUpTitle = this.titleFormatByIndex(index);
      this.selectedSchedule = schedule;
      this.initPickerControl = _.cloneDeep(schedule);
      this.popUpMode = TimePickerMode.SELECT_DAY;
      this.scheduleIndex = index;
    }
    confirmBySelectDay(): void {
      this.popUpMode = TimePickerMode.SELECT_TIME;
    }
    confirmBySelectTime(): void {
      this.popUpMode = TimePickerMode.NONE;
      // detect array change to parent
      this.$set( this.scheduleList, this.scheduleIndex, this.initPickerFormatSort(this.initPickerControl) );
    }
    private initPickerFormatSort(initPickerControl:scheduleDto):scheduleDto{
      _.keys(initPickerControl).forEach(keyName=>{
        const options = _.isEqual(keyName,'selectWeekOptions') ? weekDays : dayTimeFrames;
        initPickerControl[keyName] = this.getOptionsBySort(initPickerControl[keyName],options);
      })
      return initPickerControl;
    }
    // è³‡æ–™é‡æ–°æŽ’序,回復一開始清單順序
    private getOptionsBySort( selectedOptions:string[] , options:OptionBtnDto[]): string[] {
      return options.map( o => _.includes(selectedOptions , o.label) ? o.label as string : '').filter(String);
    }
    addNewSchedule(): void {
@@ -121,55 +161,26 @@
        selectWeekOptions:[],
        selectTimesOptions:[],
      }
      this.syncScheduleList.push(newScheduleDto)
      this.scheduleList.push(newScheduleDto)
    }
    confirmByStep_1(): void {
      this.isOpenByStep_1 = false;
      this.isOpenByStep_2 = true;
    deleteScheduleByIndex(index:number): void {
      this.scheduleList.splice(index,1);
    }
    confirmByStep_2(): void {
      this.isOpenByStep_2=false;
      // TODO: code ref
      this.selectedSchedule.selectWeekOptions = this.getOptionsBySort(this.weekOptions.options,this.initPickerControl.selectWeekOptions);
      this.selectedSchedule.selectTimesOptions = this.getOptionsBySort(this.timesOfDayOptions.options,this.initPickerControl.selectTimesOptions);
    }
    private getOptionsBySort(options:OptionBtnDto[],selectedOptions:string[]): string[] {
      return options.map( o => _.includes(selectedOptions,o.title) ? o.title :'').filter(String);
    }
    deleteScheduleItem(index:number): void {
      this.syncScheduleList.splice(index,1);
    }
    checkFormHasDone(item:scheduleDto): boolean {
      if (!item) return false;
      return item.selectWeekOptions?.length > 0
      return item&&item.selectWeekOptions?.length > 0
          && item.selectTimesOptions?.length > 0;
    }
    titleFormatByIndex(index:number): string {
      const chineseNumber = ['一','二','三','四','五','六','七','八','九','十']
      return '時段'+chineseNumber[index];
    }
    optionsFormat(options:OptionBtnDto[],needToCompareList:OptionDto): string {
      return _.isEqual(options.length,needToCompareList.options.length) ? needToCompareList.selectAll: _.join(options,',');
  enum TimePickerMode{
    SELECT_DAY="selectDay",
    SELECT_TIME="selectTime",
    NONE=""
    }
  }
  export interface scheduleDto {
  interface scheduleDto {
    selectWeekOptions : string[]|[];
    selectTimesOptions: string[]|[];
  }
  interface OptionDto{
    selectAll: string,
    options  : string[],
  }
</script>
<style lang="scss" scoped>
PAMapp/components/popUpFrame.vue
@@ -18,7 +18,6 @@
<script lang="ts">
  import { Vue, Component, Prop, Emit, PropSync} from 'vue-property-decorator';
  import UtilsService from '~/shared/services/utils.service';
  @Component
@@ -41,21 +40,20 @@
    //////////////////////////////////////////////////////////////////////
    private get isUseDrawer() : boolean {
    get isUseDrawer() : boolean {
      return this.syncIsOpen && UtilsService.isMobileDevice();
    }
    private set isUseDrawer(value: boolean) {
      this.$emit('update:isOpen',value);
    set isUseDrawer(value: boolean) {
      this.syncIsOpen = value
    }
    private get isUseDialog() : boolean {
    get isUseDialog() : boolean {
      return this.syncIsOpen && !UtilsService.isMobileDevice();
    }
    private set isUseDialog(value: boolean) {
      this.$emit('update:isOpen',value);
    set isUseDialog(value: boolean) {
      this.syncIsOpen = value
    }
  }
</script>
PAMapp/components/singleSelectBtn.vue
@@ -20,7 +20,7 @@
<script lang="ts">
  import { Component, Prop, PropSync, Vue } from "nuxt-property-decorator";
  import { OptionBtnDto } from "~/shared/models/optionBtnDto.model";
  import * as _ from 'lodash';
  @Component
@@ -37,10 +37,5 @@
      // ä¸»è¦è§£æ±ºæŒ‰éˆ•點擊兩次能回到,未點選的狀態
      this.syncSingleSelected = _.isEqual(this.syncSingleSelected, value) ? "" : value;
    }
  }
  export interface OptionBtnDto {
    title    : string,
    subTitle?: string,
    label    : string | number,
  }
</script>
PAMapp/pages/questionnaire/_agentNo.vue
@@ -16,7 +16,7 @@
              <div class="datepicker required">
                  <span class="mdTxt">手機連絡的方便時間</span>
                  <PhoneContactTimePicker
                  :scheduleList.sync="myRequest.hopeContactTime"/>
                  :scheduleList="myRequest.hopeContactTime"/>
              </div>
          </div>
          <div class="mt-30">
@@ -55,7 +55,7 @@
              <div class="datepicker">
                  <span class="mdTxt">手機連絡的方便時間</span>
                  <PhoneContactTimePicker
                  :scheduleList.sync="myRequest.hopeContactTime"/>
                  :scheduleList="myRequest.hopeContactTime"/>
              </div>
          </div>
        </div>
PAMapp/pages/quickFilter/index.vue
@@ -89,7 +89,6 @@
      subTitle:'年齡不是問題'
    },
  }
  // TODO: Vue3 å·²æŠŠfilter ç§»é™¤ï¼Œfilter and computed éƒ½å¯ä»¥åšåˆ°ç›¸åŒçš„事 å“ªå€‹æ¯”較好 ?
  @Component({
    filters: {
      formatSeniorityTitle(value): string{
PAMapp/shared/models/optionBtnDto.model.ts
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,9 @@
export interface OptionBtnDto {
  title    : string,
  subTitle?: string,
  label    : string | number,
}
export interface OptionDto{
  selectAll: string,
  options  : OptionBtnDto[],
}