保誠-保戶業務員媒合平台
Mila
2021-11-04 7c9f9647fbc4ebb671cb297743b21322eda0fde3
TODO#129071 顧問-客戶預約 畫面刻版
修改4個檔案
新增5個檔案
476 ■■■■■ 已變更過的檔案
PAMapp/assets/scss/_common.scss 20 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/Client/ClientCard.vue 166 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/Client/ClientList.vue 43 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/components/Ui/UiPagination.vue 7 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/clientReservedList.vue 74 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/clientReservedList/contactedList.vue 28 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/clientReservedList/reservedList.vue 28 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/pages/myConsultantList.vue 27 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/plugins/api/home.ts 83 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
PAMapp/assets/scss/_common.scss
@@ -41,4 +41,24 @@
    &:disabled {
        background-color: $LIGHT_GREY;
    }
}
.pam-cus-tabs {
    display: flex;
    width: 100%;
    height: 45px;
    .cus-tab-item {
        width: 50%;
        text-align: center;
        font-size: 24px;
        border-bottom: solid 3px $LIGHT_GREY;
        cursor: pointer;
    }
    .is-active {
        font-weight: bold;
        border-bottom: solid 3px $PRIMARY_BLACK;
    }
}
PAMapp/components/Client/ClientCard.vue
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,166 @@
<template>
    <div>
        <el-row type="flex" class="rowStyle">
            <el-col :xs="5" :sm="3">
                <el-avatar
                    :size="50"
                    src=""
                    class="cursor--pointer"
                ></el-avatar>
                <div class="satisfaction">
                    <i class="icon-star pam-icon icon--yellow satisfaction"></i>
                    <span>{{'1'}}</span>
                </div>
            </el-col>
            <el-col :xs="14" :sm="15">
                <div class="smTxt_bold name">{{client.name}}</div>
                <div class="message">預約成功</div>
                <div class="professionals">
                    <template v-if="client.requirements.length > 0">
                        <span
                            v-for="(item, index) in client.requirements"
                            :key="index"
                            class="professionalsTxt"
                        >#{{item}}</span>
                    </template>
                    <template v-else>
                        <span class="professionalsTxt noProfessionalsTxt"
                        >(客戶未提供需求項目)</span>
                    </template>
                </div>
            </el-col>
            <el-col class="flex-column contactInfo" :xs="5" :sm="6">
                <div class="smTxt_bold cursor--pointer"
                    :class="client.communicateStatus"
                    @click="openDetail"
                >{{isReserved ? '已預約' : '已聯絡'}}
                </div>
                <div class="date xsTxt text--mid_grey">{{date}}</div>
                <div class="xsTxt text--mid_grey">{{time}}</div>
            </el-col>
        </el-row>
        <Ui-Dialog
            :isVisible.sync="isVisibleDialog"
            :width="width"
        >
            <h5 class="subTitle text--center mb-30"
            >{{isReserved ? '預約成功' : '已聯絡資訊'}}</h5>
            <p class="smTxt text-right">今天 10:00</p>
            <div class="dialogTxt">
                <p>姓名:{{client.name}}</p>
                <p>電話:0912345678</p>
                <p>Email:</p>
                <p>性別:{{client.gender === 'male' ? '男性' : '女性'}}</p>
                <p>年齡:{{client.age}}</p>
                <p>職業:一般職業</p>
                <p>需求:{{client.requirements}}</p>
                <p>連絡時段一:星期一,星期日 18:00~21:00</p>
                <div class="mt-30 text--center">
                    <el-button>{{isReserved ? '標註為已連絡' : '發送滿意度'}}</el-button>
                </div>
            </div>
        </Ui-Dialog>
    </div>
</template>
<script lang="ts">
import { Vue, Component, Prop } from 'nuxt-property-decorator';
import { isMobileDevice } from '~/assets/ts/device';
import { Clients } from '~/pages/clientReservedList.vue';
@Component
export default class ClientList extends Vue {
    @Prop() client!: Clients;
    isVisibleDialog = false;
    width = '';
    get time() {
        const hours = this.client.time.getHours();
        const minutes = this.client.time.getMinutes();
        return `${hours} : ${minutes}`
    }
    get date() {
        const month = this.client.time.getMonth();
        const date = this.client.time.getDate();
        return `${month} / ${date}`
    }
    get isReserved() {
        return this.client.communicateStatus === 'reserved';
    }
    openDetail() {
        this.width = isMobileDevice() ? '80%' : '';
        this.isVisibleDialog = true;
    }
}
</script>
<style lang="scss" scoped>
    .rowStyle {
        padding: 10px;
        background-color: $PRIMARY_WHITE;
        margin-bottom: 10px;
        display: flex;
        justify-content: space-between;
        .satisfaction {
            font-size: 12px;
            font-weight: bold;
            margin-top: 5px;
        }
        .message {
            margin:10px 0;
        }
        .professionals {
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            .professionalsTxt {
                font-size: 12px;
                font-weight: bold;
                margin-right: 5px;
            }
            .noProfessionalsTxt {
                color: $PRUDENTIAL_GREY;
                font-weight: lighter;
            }
        }
        .contactInfo {
            text-align: right;
            .date {
                font-size: 12px;
            }
        }
        .reserved {
            @extend .text--primary;
        }
        .contacted {
            color: $SKY_BLUE;
        }
    }
    .flex-column {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
    }
    .dialogTxt {
        font-size: 20px;
    }
    .text-right {
        text-align: right;
    }
</style>
PAMapp/components/Client/ClientList.vue
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,43 @@
<template>
    <div>
        <template v-if="clients.length > 0">
            <ClientCard
                v-for="(client, index) in clients"
                :key="index"
                :client="client"
            ></ClientCard>
        </template>
        <template v-else>
            <div class="emptyRowStyle">
                <div class="smTxt txt">{{title === 'reservedList' ? '您目前無已預約客戶' : '您目前無已聯絡客戶'}}</div>
            </div>
        </template>
    </div>
</template>
<script lang='ts'>
import { Vue, Component, Prop } from 'nuxt-property-decorator';
import { Clients } from '~/pages/clientReservedList.vue';
@Component
export default class ClientList extends Vue {
    @Prop() clients!: Clients[];
    @Prop() title!: string;
}
</script>
<style lang="scss" scoped>
    .emptyRowStyle {
        background-color: $PRIMARY_WHITE;
        width: 100%;
        height: 100px;
        display: flex;
        justify-content: center;
        align-items: center;
        .txt {
            color: $PRUDENTIAL_GREY;
            margin-left: 17px;
        }
    }
</style>
PAMapp/components/Ui/UiPagination.vue
@@ -1,9 +1,11 @@
<template>
    <el-pagination
        :current-page.sync="currentPage"
        layout="prev, pager, next"
        :total="totalList.length"
        :page-size="pageSize"
        @current-change="handleCurrentChange"
        class="mt-10"
    >
    </el-pagination>
</template>
@@ -28,6 +30,11 @@
    }
    handleCurrentChange(currentPage: number) {
        if (this.totalList.length <= this.pageSize && currentPage !== 1) {
            currentPage -= 1;
        }
        if (this.totalList) {
            this.pageList = this.totalList.slice(this.pageSize * currentPage - this.pageSize, this.pageSize * currentPage)
            this.chagnePage();
PAMapp/pages/clientReservedList.vue
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,74 @@
<template>
    <div>
        <div class="pam-cus-tabs mb-30">
            <div
                class="cus-tab-item"
                :class="{'is-active': activeTabName === 'reservedList'}"
                @click="tabClick('reservedList')"
            >客戶預約
                <span class="p">({{reservedList.length}})</span>
            </div>
            <div
                class="cus-tab-item"
                :class="{'is-active': activeTabName === 'contactedList'}"
                @click="tabClick('contactedList')"
            >已聯絡
                <span class="p">({{contactedList.length}})</span>
            </div>
        </div>
        <NuxtChild
            :contactedList="contactedList"
            :reservedList="reservedList"
        ></NuxtChild>
    </div>
</template>
<script lang="ts">
import { Context } from '@nuxt/types';
import { Vue, Component } from 'nuxt-property-decorator';
@Component
export default class ClientReservedList extends Vue {
    activeTabName = 'reservedList';
    reservedList: Clients[] = [];
    contactedList: Clients[] = [];
    clients: Clients[] = [];
    async asyncData(context: Context) {
        let reservedList: Clients[] = [];
        let contactedList: Clients[] = [];
        let clients: Clients[] = [];
        await context.$service.home.clientReservedList().then((result: Clients[]) => {
            clients = result;
        })
        contactedList = clients.filter(item => item.communicateStatus === 'contacted');
        reservedList = clients.filter(item => item.communicateStatus === 'reserved');
        return {
            clients,
            contactedList,
            reservedList
        }
    }
    tabClick(path: string) {
        this.activeTabName = path;
        this.$router.push('/clientReservedList/' + this.activeTabName)
    }
}
export interface Clients {
    name: string,
    clientId: string,
    phone: string,
    time: Date,
    gender: string,
    age: string,
    job: string,
    requirements: string[],
    communicateStatus: string
}
</script>
PAMapp/pages/clientReservedList/contactedList.vue
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,28 @@
<template>
    <div>
        <ClientList
            :clients="pageList"
            :title="'contactedList'"
        ></ClientList>
        <UiPagination
            :totalList="contactedList"
            @changePage="changePage"
        ></UiPagination>
    </div>
</template>
<script lang="ts">
import { Vue, Component, Prop } from 'nuxt-property-decorator';
import { Clients } from '../clientReservedList.vue';
@Component
export default class ClientContactedList extends Vue {
    @Prop() contactedList!: Clients[];
    pageList: Clients[] = [];
    changePage(pageList: Clients[]) {
        this.pageList = pageList;
    }
}
</script>
PAMapp/pages/clientReservedList/reservedList.vue
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,28 @@
<template>
    <div>
        <ClientList
            :clients="pageList"
            :title="'reservedList'"
        ></ClientList>
        <UiPagination
            :totalList="reservedList"
            @changePage="changePage"
        ></UiPagination>
    </div>
</template>
<script lang="ts">
import { Vue, Component, Prop } from 'nuxt-property-decorator';
import { Clients } from '../clientReservedList.vue';
@Component
export default class ClientReservedList extends Vue {
    @Prop() reservedList!: Clients[];
    pageList: Clients[] = [];
    changePage(pageList: Clients[]) {
        this.pageList = pageList;
    }
}
</script>
PAMapp/pages/myConsultantList.vue
@@ -1,6 +1,6 @@
<template>
    <div>
        <div class="flex mb-30">
        <div class="pam-cus-tabs mb-30">
            <div
                class="cus-tab-item"
                :class="{'is-active': activeTabName === 'consultantList'}"
@@ -73,27 +73,4 @@
    }
}
</script>
<style lang="scss" scoped>
    .flex {
        display: flex;
        width: 100%;
        height: 45px;
        .cus-tab-item {
            width: 50%;
            text-align: center;
            font-size: 24px;
            border-bottom: solid 3px $LIGHT_GREY;
            cursor: pointer;
        }
        .is-active {
            font-weight: bold;
            border-bottom: solid 3px $PRIMARY_BLACK;
        }
    }
</style>
</script>
PAMapp/plugins/api/home.ts
@@ -8,7 +8,7 @@
                new: true,
                agentNo: 0,
                name: '張小美',
                img: 'https://randomuser.me/api/portraits/women/31.jpg',
                img: '',
                professionals: ['財務規劃', '資產轉移'],
                satisfaction: 4.8,
                contactStatus: 'reserved',
@@ -18,7 +18,7 @@
                new: true,
                agentNo: 1,
                name: '蔣帥哥',
                img: 'https://randomuser.me/api/portraits/men/32.jpg',
                img: '',
                professionals: [],
                satisfaction: 4,
                contactStatus: 'contacted',
@@ -28,7 +28,7 @@
                new: false,
                agentNo: 2,
                name: '林美女',
                img: 'https://randomuser.me/api/portraits/women/33.jpg',
                img: '',
                professionals: ['財務規劃', '資產轉移'],
                satisfaction: 5,
                contactStatus: 'picked',
@@ -38,7 +38,7 @@
                new: false,
                agentNo: 3,
                name: '蔡美眉',
                img: 'https://randomuser.me/api/portraits/women/34.jpg',
                img: '',
                professionals: ['財務規劃', '資產轉移'],
                satisfaction: 4.3,
                contactStatus: 'picked',
@@ -48,7 +48,7 @@
                new: true,
                agentNo: 4,
                name: '張小美',
                img: 'https://randomuser.me/api/portraits/women/35.jpg',
                img: '',
                professionals: [],
                satisfaction: 4.8,
                contactStatus: 'picked',
@@ -58,7 +58,7 @@
                new: true,
                agentNo: 5,
                name: '蔣帥哥',
                img: 'https://randomuser.me/api/portraits/men/36.jpg',
                img: '',
                professionals: ['財務規劃', '資產轉移'],
                satisfaction: 4.8,
                contactStatus: 'reserved',
@@ -68,7 +68,7 @@
                new: false,
                agentNo: 6,
                name: '林美女',
                img: 'https://randomuser.me/api/portraits/women/37.jpg',
                img: '',
                professionals: ['財務規劃', '資產移轉', '節稅', '樂活退休'],
                satisfaction: 4.8,
                contactStatus: 'picked',
@@ -78,14 +78,79 @@
                new: false,
                agentNo: 7,
                name: '蔡美眉',
                img: 'https://randomuser.me/api/portraits/women/38.jpg',
                img: '',
                professionals: ['財務規劃', '節稅', '樂活退休'],
                satisfaction: 4.8,
                contactStatus: 'picked',
                updateTime: 'Tue Sep 02 2021 09:40:02 GMT+0800 (台北標準時間)'
            }
        ]
        return CommonService.prototype.withDebugData(debugData, 'https://randomuser.me/api/')
        return CommonService.prototype.withDebugData(debugData, '')
    },
    clientReservedList() {
        const debugData = [{
            name: '王聰明',
            clientId: '1',
            phone: '091234567',
            time: new Date('Tue Nov 02 2021 11:23:14 GMT+0800 (台北標準時間)'),
            gender: 'male',
            age: '26-30',
            job: 'general',
            requirements: ['保單健檢/規劃', '防疫保單相關'],
            communicateStatus: 'reserved'
        },{
            name: 'Ariel',
            clientId: '2',
            phone: '091234567',
            time: new Date('Tue Oct 15 2020 11:23:14 GMT+0800 (台北標準時間)'),
            gender: 'female',
            age: '30-40',
            job: 'general',
            requirements: ['保單健檢/規劃', '資產轉移', '防疫保單相關'],
            communicateStatus: 'contacted'
        },{
            name: 'Donna',
            clientId: '3',
            phone: '091234567',
            time: new Date('Tue Oct 31 2021 10:23:14 GMT+0800 (台北標準時間)'),
            gender: 'female',
            age: '10-20',
            job: 'general',
            requirements: ['防疫保單相關'],
            communicateStatus: 'reserved'
        },{
            name: '陳爸爸',
            clientId: '4',
            phone: '091234567',
            time: new Date('Tue Dec 31 2020 19:23:14 GMT+0800 (台北標準時間)'),
            gender: 'female',
            age: '50-60',
            job: 'general',
            requirements: ['資產轉移', '節稅'],
            communicateStatus: 'reserved'
        },{
            name: '李伯伯',
            clientId: '5',
            phone: '091234567',
            time: new Date('Tue Oct 15 2020 11:23:14 GMT+0800 (台北標準時間)'),
            gender: 'male',
            age: '60-70',
            job: 'general',
            requirements: ['節稅', '資產轉移', '防疫保單相關'],
            communicateStatus: 'contacted'
        },{
            name: '蔡媽媽',
            clientId: '6',
            phone: '091234567',
            time: new Date('Tue Dec 31 2020 19:23:14 GMT+0800 (台北標準時間)'),
            gender: 'female',
            age: '50-60',
            job: 'general',
            requirements: [],
            communicateStatus: 'reserved'
        }]
        return CommonService.prototype.withDebugData(debugData, '')
    }
})