保誠-保戶業務員媒合平台
Mila
2021-11-30 c75b2fc79f5aa811ba3f5d028633f3765a017bbb
Merge branch 'master' of https://192.168.0.10:8443/r/pcalife/PAM
修改7個檔案
新增1個檔案
396 ■■■■■ 已變更過的檔案
PAMapp/assets/ts/api/consultant.ts 18 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/assets/ts/models/account.model.ts 5 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/BackActionBar.vue 13 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/Consultant-ques.vue 2 ●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/NavBar.vue 11 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/accountSetting/index.vue 310 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/questionnaire/_agentNo.vue 15 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/recommendConsultant/index.vue 22 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/assets/ts/api/consultant.ts
@@ -3,6 +3,7 @@
import { AppointmentDetail } from '../models/AppointmentDetail';
import { ConsultantLoginInfo } from '../models/ConsultantLoginInfo';
import _ from 'lodash';
import { UserSetting } from '../models/account.model';
// é¡§å®¢ç™»å…¥(TODO: OTP認證開發前 æš«æ™‚使用)
export function login(user: any) {
@@ -105,6 +106,23 @@
    }
    return service.get('/appointment/getDetail/'+apointmentId, {headers})
}
//取得使用者帳號資訊
export function getUserAccountSetting() : Promise<UserSetting> {
    const headers = {
        Authorization: 'Bearer ' + localStorage.getItem('id_token')
    }
    return service.get<UserSetting>('/customer/info', {headers}).then(res => res.data);
}
//更新使用者帳號資訊
export function updateAccountSetting(params: any) : any {
    const headers = {
        Authorization: 'Bearer ' + localStorage.getItem('id_token')
    }
    return service.put('/customer/info', params ,{headers}).then(res => res.data);
}
export interface Consultants {
    agentNo            : string,
    name               : string,
PAMapp/assets/ts/models/account.model.ts
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,5 @@
export interface UserSetting {
    name: string;
    phone?: string;
    email?: string;
}
PAMapp/components/BackActionBar.vue
@@ -41,6 +41,19 @@
          break;
        case 'questionnaire':
          featureLabel = '進行預約';
          break;
        case 'notification':
          featureLabel = '通知';
          break;
        case 'record':
          featureLabel = '查看紀錄';
          break;
        case 'accountSetting':
          featureLabel = '個人帳號設定';
          break;
        case 'consultantAccountSetting':
          featureLabel = '查看帳號資訊';
          break;
      }
      return featureLabel;
    } else {
PAMapp/components/Consultant-ques.vue
@@ -57,7 +57,7 @@
            selected:false
          },
          {
            name:'防疫保單相關',
            name:'分紅保單',
            selected:false
          }
        ];
PAMapp/components/NavBar.vue
@@ -58,12 +58,17 @@
      },
      {
        authorityOfRoleList: [Role.ADMIN],
        routeUrl: '/notFinish',
        routeUrl: '/consultantAccountSetting',
        title: '查看帳號資訊',
      },
      {
        authorityOfRoleList: [Role.USER, Role.ADMIN],
        routeUrl: '/record/contactRecord',
        authorityOfRoleList:[Role.ADMIN],
        routeUrl: '/record',
        title: '查看紀錄',
      },
      {
        authorityOfRoleList: [Role.USER],
        routeUrl: '/userReviewsRecord',
        title: '查看紀錄',
      },
      {
PAMapp/pages/accountSetting/index.vue
@@ -1,13 +1,315 @@
<template>
    <div>個人帳號設定</div>
<div class="account-page">
    <div class="account-page-title">個人帳號設定</div>
    <section class="account-card" :class="{'edit': !userNameDisabled }">
        <div class="header">
            <div class="block">
                <div class="setting-title">姓名</div>
                <div class="contact-type">
                    <input
                        :disabled="userNameDisabled"
                        v-model="userNameValue"
                        ref="userName"
                        class="input name-input"
                        >
                    <div class="error-txt">
                        <span v-show="!nameValid" class="error">此欄位必填</span>
                    </div>
                </div>
            </div>
            <i class="icon-edit icon" @click="editField('userName')" :class="{'icon-color-change': !userNameDisabled}"></i>
        </div>
    </section>
    <section class="account-card" :class="{'edit': !userPhoneDisabled }">
        <div class="header">
            <div class="block">
            <div class="setting-title">綁定</div>
            <div class="contact-type">
                æ‰‹æ©Ÿè™Ÿç¢¼
                <input
                    :disabled="userPhoneDisabled"
                    v-model="phoneValue"
                    :class="{
                    'is-invalid': !phoneValid
                    }"
                    ref="userPhone"
                    class="contact-input input"
                    :placeholder="phoneValue || '尚未提供手機號碼'"
                >
                <div class="error-txt">
                    <span v-show="!phoneValid" class="error">手機號碼格式有誤</span>
                </div>
            </div>
            </div>
            <i class="icon-edit icon"
                @click="editField('userPhone')"
                :class="{'icon-color-change': !userPhoneDisabled}"></i>
        </div>
    </section>
    <section class="account-card" :class="{'edit': !userEmailDisabled }">
        <div class="header">
            <div class="block">
            <div class="setting-title">綁定</div>
                <div class="contact-type">Email
                    <input
                        :disabled="userEmailDisabled"
                        v-model="emailValue"
                        :class="{
                        'is-invalid': !emailValid
                        }"
                        ref="userEmail"
                        class="contact-input input"
                        :placeholder="emailValue || '尚未提供 Email'"
                        >
                    <div class="error-txt">
                        <span v-show="!emailValid" class="error">信箱格式有誤</span>
                    </div>
                </div>
                </div>
                <i class="icon-edit icon" @click="editField('userEmail')"
                        :class="{'icon-color-change': !userEmailDisabled}"></i>
        </div>
    </section>
    <div class="account-setting-btn mb-30">
        <el-button
            :disabled="isSubmitBtnDisabled"
            @click.native="updateAccountSetting">送出</el-button>
    </div>
</div>
</template>
<script>
export default {
<script lang="ts">
import { Vue,Component } from 'vue-property-decorator'
import { getUserAccountSetting, updateAccountSetting } from '~/assets/ts/api/consultant';
import { UserSetting } from '~/assets/ts/models/account.model';
@Component
export default class AccountSetting extends Vue {
        _userSetting!: UserSetting;
        userNameDisabled = true;
        userPhoneDisabled = true;
        userEmailDisabled = true ;
        userNameValue = '';
        phoneValue = '' ;
        emailValue = '' ;
        onEditMode = false;
        formValidStatus = {
            name: true,
            phone: true,
            email: true,
        };
        get nameValid(): boolean {
            this.formValidStatus.name = this.userNameValue ? true : false;
            return this.formValidStatus.name;
        }
        get phoneValid(): boolean {
            const rule = /^09[0-9]{8}$/;
            this.formValidStatus.phone = this.phoneValue ? rule.test(this.phoneValue) : true;
            return this.formValidStatus.phone;
        }
        get emailValid(): boolean {
            const rule = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
            this.formValidStatus.email = this.emailValue ? rule.test(this.emailValue) : true;;
            return this.formValidStatus.email;
        }
        editField(fieldName: string): void {
            this.onEditMode = true;
            const enablePromise = new Promise((resolve, reject) => { // æ­¤ç‚ºpromise語法
                resolve((this as any)[`${fieldName}Disabled`] = false);
            });
            const targetInput = this.$refs[fieldName] as any;
            enablePromise.then((_) => {
                targetInput.focus();
            });
        }
        get isSubmitBtnDisabled(): boolean {
            const isFormValid = this.formValidStatus.name && this.formValidStatus.phone && this.formValidStatus.email;
            return !isFormValid || !this.onEditMode
                || (!this.phoneValue && !this.emailValue);
        }
        updateAccountSetting(): void {
            // const dataChanged = (): boolean => {
            //     return this._userSetting.name !== this.userNameValue
            //         || this._userSetting.phone !== this.phoneValue
            //         || this._userSetting.email !== this.emailValue;
            // };
            // if (dataChanged) {
            // }
            if (!this.onEditMode) return;
            const editSettingInfo: UserSetting = {
                name: this.userNameValue,
                phone: this.phoneValue,
                email: this.emailValue
            }
            updateAccountSetting(editSettingInfo).then((res: any) => {
                console.log('updateRes:', res);
                this.resetSettingForm();
            });
        }
        private resetSettingForm(): void {
            this.onEditMode = false;
            this.userNameDisabled = true;
            this.userPhoneDisabled = true;
            this.userEmailDisabled = true ;
        }
        mounted(){
            getUserAccountSetting().then((userInfo: UserSetting)=>{
                this._userSetting = {
                    name: userInfo.name || '',
                    phone: userInfo.phone || '',
                    email: userInfo.email || '',
                };
                this.phoneValue = this._userSetting.phone!;
                this.userNameValue = this._userSetting.name!;
                this.emailValue = this._userSetting.email!;
            })
        }
}
</script>
<style lang="">
<style lang="scss" scoped>
.account-page{
    .block{
        display: flex;
    }
    .account-page-title{
        font-size: 20px;
        margin-bottom: 34px;
    }
    .account-card{
        display: flex;
        flex-direction: column;
        border-bottom: 1px solid gray;
        margin-bottom: 33px;
        .contact-type{
            width: 184px;
            margin-right: 16px;
            font-size: 20px;
            display: flex;
            flex-direction: column;
            align-items: flex-start;
        }
        &.edit {
            input {
                border: 1px solid lightgray;
                background-color: #fff;
            }
        }
    }
    .account-setting-btn{
        display: flex;
        justify-content: center;
    }
}
.error-txt{
    padding-bottom: 10px;
    .error {
        @extend .smTxt_bold;
        @extend .text--primary;
        height: 16px;
        }
}
.name-input{
            width: 184px;
            height:27px;
            margin-bottom: 20px;
            font-size: 20px;
            margin-top: -3px;
        }
.setting-title{
            margin-left: 28px;
            margin-bottom:10px;
            width: 58px;
            font-size: 20px;
        }
.header{
    display: flex;
    align-items: baseline;
    justify-content: space-evenly;
}
.contact-input{
    font-size: 20px;
    margin-bottom: 10px;
    text-overflow: ellipsis;
    margin-top: 10px;
    width: 184px;
}
.input{
    border: 0;
    background-color: rgba(0,0,0,0) ;
    outline-color: gainsboro;
}
.input:focus{
    background-color: #fff;
}
.icon-color-change{
    color:$PRIMARY_RED;
    font-size: 20px;
}
.icon{
    font-size:20px;
    // color:#1B365D;
}
@include desktop{
    .header{
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    }
    .setting-title{
            margin-bottom:10px;
            width: 58px;
            font-size: 18px;
            font-weight: bold;
        }
    .account-page{
    .account-page-title{
        font-size: 20px;
        margin-bottom: 34px;
        font-weight: bold;
    }
    }
    .account-card{
        display: flex;
        flex-direction: column;
        border-bottom: 1px solid gray;
        margin-bottom: 33px;
        .contact-type{
            margin-left: 10px;
            font-size: 20px;
        }
    }
    .name-input{
        width: 550px;
    }
    .contact-input{
        width:550px
    }
    }
</style>
PAMapp/pages/questionnaire/_agentNo.vue
@@ -213,27 +213,27 @@
    quesAboutList = [
      {
        title:'健康與保障',
        content:'突發的意外或疾病,往往造成個人或家庭沉重的經濟負擔,周全的保險才能擁有一個無憂的未來。'
                      content:'唯有把身體照顧好,才是保障幸福之本,不做盲目燃燒的蠟燭,只做綻開的陽光,陪孩子多走一哩路,人生的美正要開展。'
      },
      {
        title:'子女教育',
        content:'利用分紅保單,規劃教育基金 ææ—©ç‚ºå­å¥³ä½œæº–備,讓生活更有保障!'
                      content:'孩子,我們是雙方的導師也是學生,面對未來要並肩作戰,學會勇敢無畏、克服挫折、善於理財,這條路上我們一起學。'
      },
      {
        title:'資產規劃',
        content:'當財務責任加重時,規劃充足的保障、提供經濟上的庇護,是人生最堅強的後盾。'
                      content:'真正的財富來自嚴謹規劃資產傳承,為人生蓋一堵抵禦財務風險的牆,確保資產穩健成長,替全家族的未來做好萬全準備。'
      },
      {
        title:'樂活退休',
        content:'兼具保險與投資雙重功能,可靈活搭配各種附約,順應人生不同階段的靈活需要。'
                      content:'拼一輩子,退休後的日子要輕鬆快活,就得提早透過保險商品規劃退休財務,替自己創造穩定收入,為精彩的熟年人生揭開序幕。'
      },
      {
        title:'保單健檢/規劃',
        content:'全面檢視自己的保障結構是否符合現在或未來的風險移轉需求,透過「斷、捨、離」把錢花在刀口上。'
                      content:'全面檢視自己的保障結構是否符合現在或未來的風險移轉需求。'
      },
      {
        title:'防疫保單',
        content:'匹配度是透過嚴選配對或快速篩選後,將每一位保險顧問資料進行比對後排序推薦給您的媒合數值,您可以作為選擇適合顧問的參考值。'
                      title:'分紅保單',
                      content:'分紅保單 åˆ†ç´…保單是兼具「分攤風險」與「紅利共享」特色的保單,具有一定穩定度,讓你可以同時享有壽險保障及紅利!'
      }
    ];
@@ -475,3 +475,4 @@
}
</style>
PAMapp/pages/recommendConsultant/index.vue
@@ -198,32 +198,28 @@
    queaAboutList = [
      {
        title: '健康與保障',
        content: '突發的意外或疾病,往往造成個人或家庭沉重的經濟負擔,周全的保險才能擁有一個無憂的未來。'
        content: '唯有把身體照顧好,才是保障幸福之本,不做盲目燃燒的蠟燭,只做綻開的陽光,陪孩子多走一哩路,人生的美正要開展。'
      },
      {
        title: '子女教育',
        content: '利用分紅保單,規劃教育基金 ææ—©ç‚ºå­å¥³ä½œæº–備,讓生活更有保障!'
        content: '孩子,我們是雙方的導師也是學生,面對未來要並肩作戰,學會勇敢無畏、克服挫折、善於理財,這條路上我們一起學。'
      },
      {
        title: '資產規劃',
        content: '當財務責任加重時,規劃充足的保障、提供經濟上的庇護,是人生最堅強的後盾。'
        content: '真正的財富來自嚴謹規劃資產傳承,為人生蓋一堵抵禦財務風險的牆,確保資產穩健成長,替全家族的未來做好萬全準備。'
      },
      {
        title: '樂活退休',
        content: '兼具保險與投資雙重功能,可靈活搭配各種附約,順應人生不同階段的靈活需要。'
        content: '拼一輩子,退休後的日子要輕鬆快活,就得提早透過保險商品規劃退休財務,替自己創造穩定收入,為精彩的熟年人生揭開序幕。'
      },
      {
        title: '保單健檢/規劃',
        content: '全面檢視自己的保障結構是否符合現在或未來的風險移轉需求,透過「斷、捨、離」把錢花在刀口上。'
        content: '全面檢視自己的保障結構是否符合現在或未來的風險移轉需求。'
      },
      {
        title: '防疫保單',
        content: '匹配度是透過嚴選配對或快速篩選後,將每一位保險顧問資料進行比對後排序推薦給您的媒合數值,您可以作為選擇適合顧問的參考值。'
      },
      {
        title: '其他',
        content: '匹配度是透過嚴選配對或快速篩選後,將每一位保險顧問資料進行比對後排序推薦給您的媒合數值,您可以作為選擇適合顧問的參考值。'
      },
        title: '分紅保單',
        content: '分紅保單 åˆ†ç´…保單是兼具「分攤風險」與「紅利共享」特色的保單,具有一定穩定度,讓你可以同時享有壽險保障及紅利!'
      }
    ];
    showDialog = false;
    showAddress = false;
@@ -365,6 +361,7 @@
    overflow-y: auto;
    height: 500px;
    margin-top: 20px;
    text-align: justify;
  }
  .qaTextTitle {
@@ -570,7 +567,6 @@
      flex-wrap: wrap;
    }
  }
  }
}