8a698e31 by simon

更改联络方式交互样式,含三语和mock数据结构

1 parent ae2b9504

269 Bytes | W: | H:

477 Bytes | W: | H:

  • 2-up
  • Swipe
  • Onion skin

194 Bytes | W: | H:

264 Bytes | W: | H:

  • 2-up
  • Swipe
  • Onion skin

283 Bytes | W: | H:

500 Bytes | W: | H:

  • 2-up
  • Swipe
  • Onion skin
module.exports = {
common: {
Confirm:"Confirm",
Cancel:"Cancel",
Confirm: "Confirm",
Cancel: "Cancel",
Male: "Male",
Female: "Female",
Sex: "Sex",
Age: "Age",
},
message: {
login: 'Login',
......@@ -373,53 +377,35 @@ module.exports = {
customService: "contact customer service hotline",
},
index: {
// news: "新聞資訊",
// newMore: "查看更多",
// recommend: {
// t1: "Online Quotation",
// t2: "Customer Service",
// t3: "Products",
// t4: "Latest News",
// item1: {
// btn: "了解更多產品",
// t1: "為自己和家人尋找壹份保障",
// },
// item2: {
// btn: "立即預約",
// t1: "在線預約 專業服務",
// },
// item3: {
// btn: "客户服务",
// t1: "專業客服為妳服務",
// t2: "想了解更多,可致電",
// t3: "95511",
// t4: "聯絡我們,或進入",
// }
// },
recommend:{
title:"為何選擇平安人壽?",
contact:"Contact us",
item1:{
desc:"E-service at Finger Tips",
recommend: {
title: "Why choose us?",
contact: "Contact us",
item1: {
desc: "E-service at Finger Tips",
},
item2:{
desc:"Serving more than 200 million customers",
item2: {
desc: "Serving more than 200 million customers",
},
item3:{
desc:"International risk management standard",
item3: {
desc: "International risk management standard",
},
},
contact:{
t1:"Contact us for more product information.",
t2:"Leave your contact or call us at 2983 8866.",
form:{
Title:"Title",
Name:"Name",
PhoneNumber:"Phone number",
Email:"Email",
Time:"Preferred contact time slot",
Inquiry:"Inquiry",
Submit:"Submit",
quote: {
quote: "Quote now",
want: "",
service: "Contact customer service",
},
contact: {
t1: "Contact us for more product information.",
t2: "Leave your contact or call us at 2983 8866.",
form: {
Title: "Title",
Name: "Name",
PhoneNumber: "Phone number",
Email: "Email",
Time: "Preferred contact time slot",
Inquiry: "Inquiry",
Submit: "Submit",
}
}
......@@ -717,6 +703,14 @@ module.exports = {
e2: "請填寫聯繫地址",
e3: "Please enter the collect E-mail"
},
form:{
InternationalArea:"International area",
Mobile:"Mobile",
Nation:"Nation(Region)",
District:"District",
Address:"Address",
Mail:"Please enter",
},
success: "Success",
},
policyChangeInformation: {
......@@ -775,10 +769,10 @@ module.exports = {
SentOutDate: "Sent Out Date",
DownloadLink: "Download link",
Status: "Status",
letterName : "Notice of Policy Issuance and Cooling-off Period",
DownloadDoc : "Download document",
Read : "Read",
UnRead : "Unread"
letterName: "Notice of Policy Issuance and Cooling-off Period",
DownloadDoc: "Download document",
Read: "Read",
UnRead: "Unread"
},
customService: {
name: "Customer service",
......@@ -1149,7 +1143,7 @@ module.exports = {
num1: "(i)",
num2: "(ii)",
title: "Plan At-a-glance",
titleLt:"Basic Information",
titleLt: "Basic Information",
titleT1: "",
titleT2: "",
titleNum: "",
......@@ -1168,20 +1162,20 @@ module.exports = {
v5: "The higher of the following, less any indebtedness:",
v51: "110% of the sum of the Total Basic Premiums Paid;",
v52: "Guaranteed Cash Value plus the face value of accumulated Reversionary Bonus and face value of Terminal Bonus (if any).",
k6:"Additional accidental death benefit for the Insured Person",
v6:"Equivalent to the Basic Total Premiums Paid",
v61:"Maximum USD 125,000 for all Ping An GenRich Insurance Plans",
k7:"Accidental death benefit for the Policy Owner",
v7:"Equivalent to the future premiums payable for the remainder of the Premium Payment Term.",
v71:"Maximum USD 125,000 for all Ping An GenRich Insurance Plans",
v72:"Not applicable if the Policy Owner is also the Insured Person",
v73:"Not applicable if the Insured Person and the Policy Holder both died in the same accident.",
k8:"Surrender benefit",
v8:"The sum of guaranteed surrender value, accumulated cash value of reversionary bonus and cash value of terminal bonus (if any) less any indebtedness.",
k9:"Bonus withdrawal",
v9:"While this Policy is in effect, the Policy Holder may withdraw some or all of the cash value of accumulated Reversionary Bonus at any time, subject to our prevailing administrative rules regarding the minimum and maximum amount of each withdrawals. The cash value of the corresponding Terminal Bonus (on the withdrawn Reversionary Bonus), if any, will also be withdrawn.",
k10:"Policy loan",
v10:"The Policy Holder can apply for a policy loan for an amount not exceeding 80% of the sum of guaranteed surrender value and cash value of accumulated reversionary bonus of the policy. The policy may also be subject to an automatic policy loan if premium remains unpaid at the end of the Grace Period to cover the outstanding premium and levy payable (if any). Any policy loan and automatic policy loan will be charged with loan interest, where the loan interest rate is solely determined by the Company.",
k6: "Additional accidental death benefit for the Insured Person",
v6: "Equivalent to the Basic Total Premiums Paid",
v61: "Maximum USD 125,000 for all Ping An GenRich Insurance Plans",
k7: "Accidental death benefit for the Policy Owner",
v7: "Equivalent to the future premiums payable for the remainder of the Premium Payment Term.",
v71: "Maximum USD 125,000 for all Ping An GenRich Insurance Plans",
v72: "Not applicable if the Policy Owner is also the Insured Person",
v73: "Not applicable if the Insured Person and the Policy Holder both died in the same accident.",
k8: "Surrender benefit",
v8: "The sum of guaranteed surrender value, accumulated cash value of reversionary bonus and cash value of terminal bonus (if any) less any indebtedness.",
k9: "Bonus withdrawal",
v9: "While this Policy is in effect, the Policy Holder may withdraw some or all of the cash value of accumulated Reversionary Bonus at any time, subject to our prevailing administrative rules regarding the minimum and maximum amount of each withdrawals. The cash value of the corresponding Terminal Bonus (on the withdrawn Reversionary Bonus), if any, will also be withdrawn.",
k10: "Policy loan",
v10: "The Policy Holder can apply for a policy loan for an amount not exceeding 80% of the sum of guaranteed surrender value and cash value of accumulated reversionary bonus of the policy. The policy may also be subject to an automatic policy loan if premium remains unpaid at the end of the Grace Period to cover the outstanding premium and levy payable (if any). Any policy loan and automatic policy loan will be charged with loan interest, where the loan interest rate is solely determined by the Company.",
},
download: {
t1: "Download Product Brochure",
......
@import "@/styles/_support.scss";
.list-container {
overflow-x: auto;
margin-bottom: 24px;
......@@ -19,7 +18,6 @@
position: relative;
display: flex;
align-items: center;
&-tips {
display: none;
position: absolute;
......@@ -31,11 +29,10 @@
min-width: 88px;
padding: 4px;
}
.icon-download {
margin-right: 4px;
}
.desc{
.desc {
padding: 0;
}
}
......@@ -46,8 +43,7 @@
cursor: pointer;
width: 12px;
height: 8px;
background: url("~@/assets/images/insurance-query/triangle-down2.png")
no-repeat center center;
background: url("~@/assets/images/insurance-query/triangle-down2.png") no-repeat center center;
background-size: 100% 100%;
top: 16px;
right: 26px;
......@@ -60,29 +56,23 @@
.cell-group {
margin-bottom: 12px;
&:last-child {
margin-bottom: 0;
}
div {
color: #4c4948;
}
.td {
position: relative;
@extend .fcc;
text-align: center;
}
.w1 {
width: 180px;
}
.w2 {
width: 240px;
}
.w3 {
width: 140px;
}
......@@ -92,7 +82,6 @@
.w5 {
width: 100px;
}
.table-header {
height: 50px;
border-top-left-radius: 8px;
......@@ -100,7 +89,6 @@
background-color: #f2f2f2;
display: flex;
align-items: center;
.normal-header {
// width: 706px;
@extend .bb;
......@@ -110,32 +98,26 @@
display: flex;
justify-content: space-between;
align-items: center;
.title {
font-weight: bold;
color: #575453;
}
.guide {
transition: all 0.5s;
cursor: pointer;
width: 12px;
height: 8px;
background: url("~@/assets/images/insurance-query/triangle-down.png")
no-repeat center center;
background: url("~@/assets/images/insurance-query/triangle-down.png") no-repeat center center;
background-size: 100% 100%;
}
.rotate180 {
transform: rotate(180deg);
transition: all 0.5s;
}
}
}
.table-content {
// width: 770px;
height: auto;
max-height: 600px;
// display: inline-block;
......@@ -147,29 +129,25 @@
padding: 0 32px;
transition: max-height ease-out 0.3s !important;
overflow: auto;
.data-line {
// padding: 0 32px;
height: 50px;
height: 58px;
margin: auto;
display: flex;
justify-content: space-between;
align-items: center;
.td {
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.cell1 {
width: 98%;
display: flex;
justify-content: space-between;
margin: auto;
}
.separator-v {
height: 30px;
width: 2px;
......@@ -177,43 +155,35 @@
margin: 0 11px;
}
}
.label span {
color: $cOrange;
margin-left: 7px;
cursor: pointer;
text-decoration: underline;
}
.separator-h {
width: 100%;
height: 1px;
height: 2px;
background-color: #f2f2f2;
}
}
.orange {
background-color: $cOrange;
div {
color: #ffffff;
}
}
.new {
@include linear-bg;
}
.hide {
max-height: 0;
border-bottom: none;
}
.sp {
text-decoration: underline;
padding: 0 4.8px;
}
.ac {
color: $cOrange !important;
}
......@@ -234,7 +204,6 @@
.activity {
background-color: $cOrange !important;
opacity: 0.5;
div {
color: #ffffff !important;
}
......@@ -245,16 +214,13 @@
display: flex;
align-items: center;
justify-content: center;
.tips {
align-items: center;
display: flex;
.icon {
margin-right: 5px;
display: inline-block;
}
.btn {
color: $cOrange;
}
......
import api from '@/api/api'
import {
httpGet,
httpPost
} from '@/api/fetch-api.js'
import api from "@/api/api";
import { httpGet, httpPost } from "@/api/fetch-api.js";
import { contactMethodCheck } from '@utils/utils.js';
import { setTitle } from '@/utils/utils.js';
import { contactMethodCheck } from "@utils/utils.js";
import { setTitle } from "@/utils/utils.js";
import Auth from '@components/auth/auth.vue';
import modalComp from '@/components/modal-comp/modal-comp.vue';
import Auth from "@components/auth/auth.vue";
import modalComp from "@/components/modal-comp/modal-comp.vue";
import PolicyHeadList from "./policy-head-list.vue";
import Vue from 'vue';
import { Loading } from 'vant';
import Vue from "vue";
import { Loading } from "vant";
Vue.use(Loading);
export default {
......@@ -19,7 +16,7 @@ export default {
return {
loading: false,
showForm: false,
key: 'value',
key: "value",
checked1: false,
checked2: false,
checked3: false,
......@@ -30,6 +27,8 @@ export default {
mobile: "",
email: "",
address: "",
areaCode: ""
},
errorTips: {
e1: "",
......@@ -42,7 +41,30 @@ export default {
targetPath: "",
modalIcon: "succ",
modalContent: "",
}
// 新增
// 国际号码区号列表
areaCodeList: [
{
v: "abc",
n: "abc"
},
{
v: "efg",
n: "efg"
}
],
countryList:[
{
v: "cn",
n: "中国"
},
{
v: "en",
n: "美国"
}
]
};
},
components: {
Auth,
......@@ -51,10 +73,12 @@ export default {
},
computed: {
locale() {
return this.$i18n.locale || 'tc';
return this.$i18n.locale || "tc";
},
i18n() {
return this.$i18n.messages && this.$i18n.locale ? this.$i18n.messages[this.$i18n.locale] : {};
return this.$i18n.messages && this.$i18n.locale
? this.$i18n.messages[this.$i18n.locale]
: {};
},
submitBtnDisabled() {
let b1 = !this.selectedPolicies || this.selectedPolicies.length == 0;
......@@ -100,27 +124,29 @@ export default {
addressAcceptMsg: this.checked2 ? 1 : 0,
emailAcceptMsg: this.checked3 ? 1 : 0,
policies: policies
}
};
this.loading = true;
httpPost({
url: api.updatePolicyContanct,
data: data,
sid: true
}).then(() => {
})
.then(() => {
this.loading = false;
this.showSuccess();
}).catch(err => {
})
.catch(err => {
this.loading = false;
if (err.code == 404) {
this.$refs.auth.noAuth();
}
})
});
}
},
checkMobile() {
if (this.data.mobile) {
let hkMobile = contactMethodCheck('hkmobile', this.data.mobile);
let zhMobile = contactMethodCheck('mobile', this.data.mobile);
let hkMobile = contactMethodCheck("hkmobile", this.data.mobile);
let zhMobile = contactMethodCheck("mobile", this.data.mobile);
if (!hkMobile && !zhMobile) {
this.errorTips.e1 = this.i18n.policyChangeContact.errorTips.e1;
return false;
......@@ -132,7 +158,7 @@ export default {
return true;
},
checkEmail() {
if (this.data.email && !contactMethodCheck('email', this.data.email)) {
if (this.data.email && !contactMethodCheck("email", this.data.email)) {
this.errorTips.e3 = this.i18n.policyChangeContact.errorTips.e3;
return false;
}
......@@ -155,7 +181,8 @@ export default {
url: api.policyDetail,
data: param,
sid: true
}).then(response => {
})
.then(response => {
this.data = {};
if (response) {
this.loading = false;
......@@ -167,7 +194,8 @@ export default {
this.data.email = response.clientEmail;
this.checked3 = "1" == response.clientEmailAcceptMessage;
}
}).catch(res => {
})
.catch(res => {
if (res.code == "404") {
this.$refs.auth.noAuth();
}
......@@ -193,17 +221,17 @@ export default {
}
},
watch: {
'data.mobile': function () {
"data.mobile": function() {
this.errorTips.e1 = "";
},
'data.address': function () {
"data.address": function() {
this.errorTips.e2 = "";
},
'data.email': function () {
"data.email": function() {
this.errorTips.e3 = "";
}
},
mounted() {
this.initTitle();
}
}
};
......
@import '@/styles/_support.scss';
@import "@/styles/_support.scss";
.comp {
font-size: $fontSize-M2;
}
.container {
@extend .bb;
padding: 22px 36px 30px 26px;
padding: 24px 32px;
}
.border {
......@@ -15,29 +17,47 @@
.form {
display: flex;
flex-wrap: wrap;
&-item {
position: relative;
margin-bottom: 28px;
width: 100%;
&:last-child {
margin-bottom: 0;
}
.label {
color: #f05a23;
display: flex;
align-items: center;
margin-bottom: 8.4px;
.icon {
width: 26px;
display: flex;
margin-right: 14px;
}
img {
height: 12px;
}
}
.ipt-gird {
&-item {
margin: 0 auto 48px;
padding-left: 18px;
padding-right: 18px;
&:first-child {
margin-right: 0;
padding-left: 0;
}
&:last-child {
margin-right: 0;
padding-right: 0;
}
}
.w1 {
width: 210px;
}
.w2 {
width: 300px;
}
.w3 {
width: 360px;
}
}
......@@ -46,26 +66,18 @@
justify-content: space-between;
align-items: center;
position: relative;
// input和下拉
.ipt {
flex: 1;
}
.agree {
cursor: pointer;
}
.name-ipt {
width: 164px;
}
.phone-ipt {
width: 164px;
}
.mail-ipt {}
.mail-ipt {
}
// 长文本
.textarea {
min-height: 105px;
......@@ -73,62 +85,58 @@
@extend .bb;
padding: 9px;
}
.down-arrow {
position: absolute;
top: 26.4px;
right: 24px;
background-image: url('~@/assets/images/reservation/re-down-arrow.png');
background-image: url("~@/assets/images/reservation/re-down-arrow.png");
width: 12px;
height: 8px;
pointer-events: none;
cursor: default;
}
.check-icon {
display: inline-block;
margin-left: 26px;
margin-right: 8px;
}
}
.validator {
color: $cOrange;
color: $cOrange2;
margin-top: 6px;
position: absolute;
right: 192px;
// right: 0;
left: 0;
display: flex;
align-items: center;
// bottom: 0;
img {
display: inline-block;
margin-right: 4.8px;
}
}
}
}
.agree {
width: 100%;
display: flex;
align-items: center;
// margin-top: 48px;
font-size: $fontSizeSmall-M2;
.check-icon {
margin-right: 8px;
width: 18px;
height: 18px;
}
}
.submit-btn {
width: 163px;
height: 49px;
margin: 0 auto 0;
line-height: 49px;
box-shadow: 0px 10px 13px 0 rgba(236, 100, 41, 0.2);
background-blend-mode: soft-light, ;
background-image: linear-gradient(to top, #000000, #ffffff), linear-gradient(to bottom, #ec6429, #ec6429);
text-align: center;
font-size: 15.5px;
color: #ffffff;
border-radius: 42px;
cursor: pointer;
border: none;
color: #ffffff;
background-color: #f05a23;
box-shadow: 0px 10px 13px 0 rgba(236, 100, 41, 0.2);
background-blend-mode: soft-light, ;
background-image: linear-gradient(to top, #000000, #ffffff), linear-gradient(to bottom, #ec6429, #ec6429);
@include btc4(300px, 50px, 18px);
width: 300px;
height: 50px;
border-radius: 25px;
margin: 40px auto 0;
}
.submit-btn:lang(zh) {
......@@ -141,27 +149,23 @@
overflow-x: auto;
-webkit-overflow-scrolling: touch;
width: 92vw;
}
}
@media (max-width: 768px) {
.container {
padding: 24px 16px;
}
.form {
&-item {
.ipt-wrap {
display: block;
}
.agree {
margin-top: $marginSmall-M;
.check-icon {
margin-left: 0;
.ipt-gird {
&-item {
padding: 0;
}
}
}
}
}
......
<template>
<div>
<div class="policy-change-contact">
<!-- 该input用于防止chrome自动填充 -->
<input type="password" style="display: none;" />
<auth @onLogin="userLogin" @onLogout="userLogout" :checkProfile="true" ref="auth" :tipModel="'m2'"></auth>
<modal-comp :visible="modalVisiable" :show-confirm="false" :icon="modalIcon" :content="modalContent" :confirm="modalCallback" :overlay="modalCallback"></modal-comp>
<template v-if="showForm">
<policy-head-list :multiSelectable="true" @onSelect="handlePolicySelect"></policy-head-list>
<div class="container border" v-if="selectedPolicies.length > 0 && data">
<!-- 表单 -->
<div class="form">
<!-- 1 -->
<div class="form-item">
<div class="label">
<div class="icon"><img src="@/assets/images/policy-change-contact/icon-pcc-phone.png"></div>{{$t('policyChangeContact.phone')}}
</div>
<div class="ipt-wrap">
<input class="ipt mail-ipt" :class="{err : errorTips.e1.length > 0}" type="text" v-model="data.mobile">
<div class="agree" @click="checked1 = !checked1">
<img v-if="!checked1" class="check-icon pointer" src="@/assets/images/reservation/un-check.png">
<img v-else class="check-icon pointer" src="@/assets/images/reservation/check.png">
<span>{{$t("policyChangeContact.checkTips")}}</span>
<div class="gird-g ipt-gird">
<div class="pure-u-1 pure-u-md-6-24 ipt-gird-item">
<div class="ipt-wrap-linear">
<div class="down-arrow"></div>
<div class="cont">
<el-select class="ipt" v-model="data.areaCode" :placeholder="$t('policyChangeContact.form.InternationalArea')">
<el-option v-for="(item, index) in areaCodeList" :key="index" :label="item.n" :value="item.v"></el-option>
</el-select>
</div>
</div>
<div class="validator" v-if="errorTips.e1.length > 0">
<img src="@/assets/images/common/icon-notice.png" alt="">{{errorTips.e1}}
</div>
</div>
<div class="pure-u-1 pure-u-md-8-24 ipt-gird-item">
<div class="ipt-wrap-linear">
<input class="ipt mail-ipt" :class="{err : errorTips.e1.length > 0}" type="text" v-model="data.mobile" autocomplete="new-password" :placeholder="$t('policyChangeContact.form.Mobile')">
</div>
<div class="validator" v-if="errorTips.e1.length > 0">
<img src="@/assets/images/common/icon-notice.png" alt="">{{errorTips.e1}}
</div>
</div>
</div>
</div>
<!-- 2 -->
<div class="form-item">
<div class="label">
<div class="icon"><img src="@/assets/images/policy-change-contact/icon-pcc-location.png"></div>{{$t('policyChangeContact.address')}}
</div>
<div class="ipt-wrap">
<input class="ipt mail-ipt" type="text" :class="{err : errorTips.e2.length > 0}" v-model="data.address">
<div class="agree" @click="checked2 = !checked2">
<img v-if="!checked2" class="check-icon pointer" src="@/assets/images/reservation/un-check.png">
<img v-else class="check-icon pointer" src="@/assets/images/reservation/check.png">
<span>{{$t("policyChangeContact.checkTips")}}</span>
<div class="gird-g ipt-gird">
<div class="pure-u-1 pure-u-md-6-24 ipt-gird-item">
<div class="ipt-wrap-linear">
<div class="down-arrow"></div>
<div class="cont">
<el-select class="ipt" v-model="data.countryCode" :placeholder="$t('policyChangeContact.form.Nation')">
<el-option v-for="(item, index) in countryList" :key="index" :label="item.n" :value="item.v"></el-option>
</el-select>
</div>
</div>
<div class="validator" v-if="errorTips.e2.length > 0">
<img src="@/assets/images/common/icon-notice.png" alt="">{{errorTips.e2}}
</div>
</div>
<div class="pure-u-1 pure-u-md-6-24 ipt-gird-item">
<div class="ipt-wrap-linear">
<input class="ipt" type="text" :class="{err : errorTips.e2.length > 0}" v-model="data.address" autocomplete="new-password" :placeholder="$t('policyChangeContact.form.District')">
</div>
<div class="validator" v-if="errorTips.e2.length > 0">
<img src="@/assets/images/common/icon-notice.png" alt="">{{errorTips.e2}}
</div>
</div>
<div class="pure-u-1 pure-u-md-12-24 ipt-gird-item">
<div class="ipt-wrap-linear">
<input class="ipt" type="text" :class="{err : errorTips.e2.length > 0}" v-model="data.address" autocomplete="new-password" :placeholder="$t('policyChangeContact.form.Address')">
</div>
<div class="validator" v-if="errorTips.e2.length > 0">
<img src="@/assets/images/common/icon-notice.png" alt="">{{errorTips.e2}}
</div>
</div>
</div>
</div>
<!-- 3 -->
<div class="form-item">
<div class="label">
<div class="icon"><img src="@/assets/images/policy-change-contact/icon-pcc-mail.png"></div>{{$t('policyChangeContact.email')}}
</div>
<div class="ipt-wrap">
<input class="ipt mail-ipt" type="text" :class="{err : errorTips.e3.length > 0}" v-model="data.email">
<div class="agree" @click="checked3 = !checked3">
<img v-if="!checked3" class="check-icon pointer" src="@/assets/images/reservation/un-check.png">
<img v-else class="check-icon pointer" src="@/assets/images/reservation/check.png">
<span>{{$t("policyChangeContact.checkTips")}}</span>
</div>
<div class="gird-g ipt-gird">
<div class="pure-u-1 ipt-gird-item">
<div class="pure-u-1 pure-u-md-12-24 ipt-wrap-linear">
<input class="ipt" type="text" :class="{err : errorTips.e3.length > 0}" v-model="data.email" autocomplete="new-password" :placeholder="$t('policyChangeContact.form.Mail')">
</div>
<div class="validator" v-if="errorTips.e3.length > 0">
<img src="@/assets/images/common/icon-notice.png" alt="">{{errorTips.e3}}
</div>
</div>
<div class="submit-btn flex-center" @click="updateContactsHandler" :class="{disabled: submitBtnDisabled}">
</div>
</div>
<div class="agree" @click="checked1 = !checked1">
<img v-if="!checked1" class="check-icon pointer" src="@/assets/images/reservation/un-check.png">
<img v-else class="check-icon pointer" src="@/assets/images/reservation/check.png">
<span>{{$t("policyChangeContact.checkTips")}}</span>
</div>
<div class="submit-btn" @click="updateContactsHandler" :class="{disabled: submitBtnDisabled}">
<van-loading v-if="loading" />
<span>{{$t('policyChangeContact.submit')}}</span>
</div>
</div>
</div>
<!-- <div v-else style="height:400px"></div> -->
</template>
</div>
</template>
......
/**
* 组件描述:保单查询列表
*/
import api from '@/api/api';
import {
httpPost,
requestDomain
} from '@/api/fetch-api.js';
import {
mapState
} from 'vuex';
import {
formatMoney,
getInsuredPeriod,
getInsuredState,
getPolicyName
} from "@/utils/biz.js";
import Modal2Comp from '@/components/modal2-comp/modal2-comp.vue';
export default {
props: {
multiSelectable: {
type: Boolean,
default: false
},
model: {
type: String,
default: "download"
},
},
name: "PolicyHeadList",
data() {
return {
myPolicyList: [],
maxShow: 2,
selectPolicyCode: "",
selectPolicyCodes: {},
hide: false,
showDownloadError: false
}
},
computed: {
...mapState({
policyList: state => state.policyList
}),
lan() {
return this.$i18n.locale;
},
i18n() {
return this.$i18n.messages && this.$i18n.locale ? this.$i18n.messages[this.$i18n.locale] : {};
},
},
methods: {
onShowTipsOverHandler(event, item, index) {
let child = event.currentTarget.childNodes[0];
child.style.display = "block";
},
onShowTipsOutHandler(event, item, index) {
let child = event.currentTarget.childNodes[0];
child.style.display = "none";
},
toContactUs() {
this.$router.push({
path: "/custom/service",
query: {
q: "m1"
}
});
},
queryList() {
if (this.policyList && this.policyList.length > 0) {
this.myPolicyList = this.policyList;
this.myPolicyList.forEach(element => {
element.activity = false;
})
this.initSelected();
} else {
this.checkCustomer().then(() => {
httpPost({
url: api.policyList,
sid: true
}).then(res => {
if (!res || res.length == 0) {
this.myPolicyList = null;
} else {
res.forEach(element => {
element.activity = false;
// let len = element.policyCode.length;
// element.policyCodeStr = element.policyCode && len > 5 ?
// element.policyCode.substring(0, 2) + "**********"
// + element.policyCode.substring(len - 4, len) : element.policyCode;
});
this.$store.commit("CACHE_POLICY_LIST", res);
this.myPolicyList = res;
}
this.initSelected();
}).catch(e => {
this.myPolicyList = null;
switch (e.code) {
case "2002":
// 不是客户,没有购买保单
break;
}
});
});
}
},
initSelected() {
let selectPolicy = null;
try {
let data = sessionStorage.getItem("_hklife_policy");
if (data) {
sessionStorage.removeItem("_hklife_policy");
selectPolicy = JSON.parse(decodeURIComponent(data));
if (selectPolicy) {
if (this.multiSelectable) {
this.selectPolicyCodes[selectPolicy.code] = selectPolicy;
} else {
this.selectPolicyCode = selectPolicy.code;
}
this.$emit("onSelect", [selectPolicy]);
// 判断最大显示
let index = -1;
for (let i = 0; i < this.myPolicyList.length; i++) {
if (selectPolicy.code == this.myPolicyList[i].policyCode) {
this.myPolicyList[i].activity = true;
index = i;
}
}
this.$set(this, "myPolicyList", this.myPolicyList);
if (index > 2) {
this.maxShow = this.myPolicyList.length;
}
}
}
} catch (e) {
}
if (!selectPolicy) {
let firstPolicy = this.myPolicyList[0];
this.myPolicyList[0].activity = true;
selectPolicy = {
id: firstPolicy.policyId,
code: firstPolicy.policyCode
};
if (this.multiSelectable) {
this.selectPolicyCodes[selectPolicy.code] = selectPolicy;
} else {
this.selectPolicyCode = selectPolicy.code;
}
this.$emit("onSelect", [selectPolicy]);
}
},
handlePolicySelect(item, index) {
let code = item.policyCode;
if (this.multiSelectable) {
let c = this.selectPolicyCodes[code];
if (!c || typeof c == "undefined") {
item.activity = true;
this.selectPolicyCodes[code] = {
code: code,
id: item.policyId
};
} else {
item.activity = false;
delete this.selectPolicyCodes[code];
}
// this.$set(this, 'myPolicyList', this.myPolicyList);
let data = [];
for (let key in this.selectPolicyCodes) {
data.push(this.selectPolicyCodes[key]);
}
this.$emit("onSelect", data);
} else {
if (code != this.selectPolicyCode) {
this.selectPolicyCode = code;
this.$emit("onSelect", [{
code: code,
id: item.policyId
}]);
}
}
},
isPolicySelect(item, index) {
let code = item.policyCode;
if (this.multiSelectable) {
let c = this.selectPolicyCodes[code];
if (!c || typeof c == "undefined") {
return false;
} else {
return true;
}
}
return false;
},
checkCustomer() {
return new Promise(resolve => {
resolve();
// httpPost({ url: api.profile, sid: true }).then(res => {
// if (res.isCustomer == 1) {
// resolve();
// } else {
// this.gotoCustomerAuthPage();
// }
// }).catch(res => {
// });
});
},
gotoCustomerAuthPage() {
let c = this.$route.fullPath;
this.$router.push({
name: "customerAuth",
query: {
c: c
}
});
},
formatMoney(s, t) {
if (typeof t == "undefined") {
t = 1;
}
return formatMoney(s, t);
},
// 保障年限,保n年
formatInsuredPeriod(t, v) {
return getInsuredPeriod(this.$i18n.locale, t, v);
},
formatInsuredState(c) {
return getInsuredState(this.$i18n.locale, c);
},
formatPolicyName(c, n) {
return getPolicyName(this.$i18n.locale, c, n);
},
downloadPolicy(policy) {
if (policy) {
httpPost({
url: api.getDownloadPath,
sid: true,
data: {
policyCode: policy.policyCode
}
}).then(res => {
if (res) {
let url = requestDomain() + api.downloadPolicy + "/" + res;
window.open(url);
} else {
this.showDownloadError = true;
}
});
}
}
},
components: {
Modal2Comp
},
mounted() {
this.queryList();
},
}
@import '@/styles/_support.scss';
.list-container {
overflow-x: auto;
margin-bottom: 24px;
}
.hide {
max-height: 0;
border-bottom: none;
}
.table-contaner {
position: relative;
}
.download {
position: relative;
&-tips {
display: none;
position: absolute;
top: -3px;
left: 20px;
z-index: 11;
padding: 2px;
@include border-tans();
min-width: 80px;
}
}
.guide {
position: absolute;
transition: all 0.5s;
cursor: pointer;
width: 12px;
height: 8px;
background: url("~@/assets/images/insurance-query/triangle-down2.png") no-repeat center center;
background-size: 100% 100%;
top: 16px;
right: 26px;
}
.rotate180 {
transform: rotate(180deg);
transition: all 0.5s;
}
.cell-group {
margin-bottom: 12px;
&:last-child {
margin-bottom: 0;
}
div {
color: #4c4948;
}
.w1 {
// width: 120px;
width: 240px;
text-align: center;
}
.w2 {
// width: 75px;
width: 150px;
text-align: center;
}
.table-header {
// width: 770px;
height: 39px;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
background-color: #f2f2f2;
display: flex;
align-items: center;
.normal-header {
// width: 706px;
@extend .bb;
padding: 0 32px;
width: 100%;
margin: auto;
display: flex;
justify-content: space-between;
align-items: center;
.title {
font-weight: bold;
color: #575453;
}
.guide {
transition: all 0.5s;
cursor: pointer;
width: 12px;
height: 8px;
background: url("~@/assets/images/insurance-query/triangle-down.png") no-repeat center center;
background-size: 100% 100%;
}
.rotate180 {
transform: rotate(180deg);
transition: all 0.5s;
}
}
}
.table-content {
// width: 770px;
height: auto;
max-height: 600px;
// display: inline-block;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
border-left: solid 1px #f2f2f2;
border-right: solid 1px #f2f2f2;
border-bottom: solid 1px #f2f2f2;
padding: 0 32px;
transition: max-height ease-out 0.3s !important;
overflow: auto;
.data-line {
// padding: 0 32px;
height: 50px;
margin: auto;
display: flex;
justify-content: space-between;
align-items: center;
.td {
display: flex;
justify-content: center;
align-items: center;
}
.cell1 {
width: 98%;
display: flex;
justify-content: space-between;
margin: auto;
}
.separator-v {
height: 30px;
width: 2px;
background-color: #f2f2f2;
margin: 0 11px;
}
}
.label span {
color: $cOrange;
margin-left: 7px;
cursor: pointer;
text-decoration: underline;
}
.separator-h {
width: 100%;
height: 1px;
background-color: #f2f2f2;
}
}
.orange {
background-color: $cOrange;
div {
color: #ffffff;
}
}
.hide {
max-height: 0;
border-bottom: none;
}
.sp {
text-decoration: underline;
padding: 0 4.8px;
}
.ac {
color: $cOrange !important;
}
}
.show-more-btn {
width: 100%;
color: $cOrange !important;
text-decoration: underline;
cursor: pointer;
justify-content: center !important;
}
.pointer {
cursor: pointer;
}
.activity {
background-color: $cOrange !important;
opacity: .5;
div {
color: #FFFFFF !important;
}
}
.empty {
height: 500px;
display: flex;
align-items: center;
justify-content: center;
.tips {
align-items: center;
display: flex;
.icon {
margin-right: 5px;
display: inline-block;
}
.btn {
color: $cOrange;
}
}
}
<template>
<div class="list-container">
<modal2-comp :visible="showDownloadError" :close="()=>{showDownloadError = false}" :content="$t('glbalTips.sysError')"></modal2-comp>
<div class="cell-group">
<div class="table-contaner">
<div class="table-header orange" >
<div class="normal-header">
<div class="td w1">{{$t('customService.insuranceQuery.InsurantNumber')}}</div>
<div class="td w2">{{$t('customService.insuranceQuery.policyState')}}</div>
<div class="td w2">{{$t('customService.insuranceQuery.activeDate')}}</div>
<div class="td w2">{{$t('customService.insuranceQuery.Insurant')}}</div>
<div class="td w1">{{$t('customService.insuranceQuery.InsurantName')}}</div>
<div class="td w2">{{$t('customService.insuranceQuery.InsurantAmount')}}</div>
<div class="td w2">{{$t('customService.insuranceQuery.effectiveDate')}}</div>
<div class="td w2">{{$t('customService.insuranceQuery.period')}}</div>
</div>
</div>
<div class="guide" :class="{rotate180 : hide}" @click="hide = !hide"></div>
</div>
<div class="table-content" :class="{hide : hide}">
<template v-if="myPolicyList">
<div v-for="(item,index) in myPolicyList" :key="index">
<template v-if="index < maxShow">
<div class="data-line" @click="handlePolicySelect(item,index)">
<div class="td w1 pointer">
<template v-if="multiSelectable">
<img v-if="item.activity" class="icon-check pointer" src="@/assets/images/insurance-query/check.png">
<img v-else class="icon-check pointer" src="@/assets/images/insurance-query/un-check.png">
<span class="sp" :class="{ac: item.activity}">{{item.policyCode}}</span>
</template>
<template v-else>
<template v-if="model != 'download'">
<img v-if="selectPolicyCode == item.policyCode" class="icon-check pointer" src="@/assets/images/insurance-query/check.png">
<img v-else class="icon-check pointer" src="@/assets/images/insurance-query/un-check.png">
</template>
<span class="sp" :class="{ac: selectPolicyCode == item.policyCode}">{{item.policyCode}}</span>
<template v-if="model == 'download'">
<div class="download" @mouseover="onShowTipsOverHandler($event,item,index)" @mouseout="onShowTipsOutHandler($event,item,index)" @click="downloadPolicy(item)">
<div class="download-tips">
<div class="cont">{{$t('customService.insuranceQuery.downloadClick')}}</div>
</div>
<img class="icon-download" src="@/assets/images/insurance-query/icon-down-load.png" alt="">
</div>
</template>
</template>
</div>
<div class="td w2">{{formatInsuredState(item.policyState)}}</div>
<div class="td w2">{{item.activeDate?item.activeDate.split(" ")[0]:""}}</div>
<div class="td w2">{{lan == 'en' ? (item.insuredNameEn ? item.insuredNameEn : item.insuredNameCn) : (item.insuredNameCn ? item.insuredNameCn : item.insuredNameEn)}}</div>
<div class="td w1">{{formatPolicyName(item.productCode, item.productName)}}</div>
<div class="td w2">{{item.moneyCode}} {{formatMoney(item.amount,0)}}</div>
<div class="td w2">{{item.expireAt?item.expireAt.split(" ")[0]:""}}</div>
<!-- <div class="td w2">{{item.guaranteeAge?item.guaranteeAge.split(" ")[0]:""}}</div> -->
<div class="td w2">{{formatInsuredPeriod(item.insuredPeriodType,item.insuredPeriodValue)}}</div>
</div>
<div class="separator-h" v-if="index < myPolicyList.length - 1 && index < maxShow - 1"></div>
</template>
</div>
<template v-if="!policyList || maxShow < policyList.length">
<div class="separator-h"></div>
<div class="data-line show-more-btn" @click="maxShow = policyList.length">{{$t('customService.insuranceQuery.showMore')}}</div>
</template>
</template>
<template v-else>
<div class="empty">
<div class="tips">
<img class="icon" src="@/assets/images/common/icon-alert-i.png" alt="">
<div class="txt">
{{$t('customService.insuranceQuery.noPolicy')}}
<span class="pointer btn" @click="toContactUs">{{$t('customService.insuranceQuery.customService')}}</span>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</template>
<script src="./policy-head-list.js"></script>
<style lang="scss" scoped>
@import "./policy-head-list.scss";
</style>
@import '@/styles/_support.scss';
@import "@/styles/_support.scss";
.list-container {
overflow-x: auto;
margin-bottom: 24px;
font-size: $fontSize-M2;
}
.hide {
......@@ -16,7 +16,6 @@
.download {
position: relative;
&-tips {
display: none;
position: absolute;
......@@ -35,7 +34,8 @@
cursor: pointer;
width: 12px;
height: 8px;
background: url("~@/assets/images/insurance-query/triangle-down2.png") no-repeat center center;
background: url("~@/assets/images/insurance-query/triangle-down2.png")
no-repeat center center;
background-size: 100% 100%;
top: 16px;
right: 26px;
......@@ -48,36 +48,30 @@
.cell-group {
margin-bottom: 12px;
&:last-child {
margin-bottom: 0;
}
div {
color: #4c4948;
}
.w1 {
// width: 120px;
width: 240px;
text-align: center;
}
.w2 {
// width: 75px;
width: 150px;
text-align: center;
}
.table-header {
// width: 770px;
height: 39px;
height: 50px;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
background-color: #f2f2f2;
display: flex;
align-items: center;
.normal-header {
// width: 706px;
@extend .bb;
......@@ -87,31 +81,27 @@
display: flex;
justify-content: space-between;
align-items: center;
.title {
font-weight: bold;
color: #575453;
}
.guide {
transition: all 0.5s;
cursor: pointer;
width: 12px;
height: 8px;
background: url("~@/assets/images/insurance-query/triangle-down.png") no-repeat center center;
background: url("~@/assets/images/insurance-query/triangle-down.png")
no-repeat center center;
background-size: 100% 100%;
}
.rotate180 {
transform: rotate(180deg);
transition: all 0.5s;
}
}
}
.table-content {
// width: 770px;
height: auto;
max-height: 600px;
// display: inline-block;
......@@ -123,30 +113,24 @@
padding: 0 32px;
transition: max-height ease-out 0.3s !important;
overflow: auto;
.data-line {
// padding: 0 32px;
height: 50px;
height: 58px;
margin: auto;
display: flex;
justify-content: space-between;
align-items: center;
.td {
display: flex;
justify-content: center;
align-items: center;
}
.cell1 {
width: 98%;
display: flex;
justify-content: space-between;
margin: auto;
}
.separator-v {
height: 30px;
width: 2px;
......@@ -154,39 +138,35 @@
margin: 0 11px;
}
}
.label span {
color: $cOrange;
margin-left: 7px;
cursor: pointer;
text-decoration: underline;
}
.separator-h {
width: 100%;
height: 1px;
height: 2px;
background-color: #f2f2f2;
}
}
.orange {
background-color: $cOrange;
div {
color: #ffffff;
}
}
.new {
@include linear-bg;
}
.hide {
max-height: 0;
border-bottom: none;
}
.sp {
text-decoration: underline;
padding: 0 4.8px;
}
.ac {
color: $cOrange !important;
}
......@@ -206,10 +186,9 @@
.activity {
background-color: $cOrange !important;
opacity: .5;
opacity: 0.5;
div {
color: #FFFFFF !important;
color: #ffffff !important;
}
}
......@@ -218,19 +197,24 @@
display: flex;
align-items: center;
justify-content: center;
.tips {
align-items: center;
display: flex;
.icon {
margin-right: 5px;
display: inline-block;
}
.btn {
color: $cOrange;
}
}
}
@media (max-width: 1200px) {
.list-container {
display: -webkit-box;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
width: 92vw;
}
}
\ No newline at end of file
......
......@@ -3,11 +3,11 @@
<modal2-comp :visible="showDownloadError" :close="()=>{showDownloadError = false}" :content="$t('glbalTips.sysError')"></modal2-comp>
<div class="cell-group">
<div class="table-contaner">
<div class="table-header orange" >
<div class="table-header orange new" >
<div class="normal-header">
<div class="td w1">{{$t('customService.insuranceQuery.InsurantNumber')}}</div>
<div class="td w2">{{$t('customService.insuranceQuery.policyState')}}</div>
<div class="td w2">{{$t('customService.insuranceQuery.activeDate')}}</div>
<!-- <div class="td w2">{{$t('customService.insuranceQuery.policyState')}}</div>
<div class="td w2">{{$t('customService.insuranceQuery.activeDate')}}</div> -->
<div class="td w2">{{$t('customService.insuranceQuery.Insurant')}}</div>
<div class="td w1">{{$t('customService.insuranceQuery.InsurantName')}}</div>
<div class="td w2">{{$t('customService.insuranceQuery.InsurantAmount')}}</div>
......@@ -45,8 +45,8 @@
</template>
</div>
<div class="td w2">{{formatInsuredState(item.policyState)}}</div>
<div class="td w2">{{item.activeDate?item.activeDate.split(" ")[0]:""}}</div>
<!-- <div class="td w2">{{formatInsuredState(item.policyState)}}</div> -->
<!-- <div class="td w2">{{item.activeDate?item.activeDate.split(" ")[0]:""}}</div> -->
<div class="td w2">{{lan == 'en' ? (item.insuredNameEn ? item.insuredNameEn : item.insuredNameCn) : (item.insuredNameCn ? item.insuredNameCn : item.insuredNameEn)}}</div>
<div class="td w1">{{formatPolicyName(item.productCode, item.productName)}}</div>
<div class="td w2">{{item.moneyCode}} {{formatMoney(item.amount,0)}}</div>
......
......@@ -87,20 +87,20 @@
.eye-act {
background-image: url("~@/assets/images/common/icon-eyes-on.png");
}
}
.ipt:focus {
.ipt:focus {
border-color: $cOrange !important;
}
}
.ipt.err {
.ipt.err {
border-color: $cOrange !important;
}
}
.err {
.err {
.ipt {
border-color: $cOrange !important;
}
}
}
// 输入框
......@@ -122,7 +122,7 @@
flex: 1;
display: flex;
align-items: center;
font-size: 22px;
font-size: 18px;
color: $cFontGray2;
&:lang(zh) {
......
......@@ -17,7 +17,7 @@
}
// 超过多少行自动省略 默认一行
@mixin ellipsis($line:1) {
@mixin ellipsis($line: 1) {
display: -webkit-box;
word-break: break-all;
-webkit-box-orient: vertical;
......@@ -50,13 +50,11 @@
// 清除浮动
@mixin clearfix() {
&:before,
&:after {
content: " "; // 1
display: table; // 2
}
&:after {
clear: both;
}
......@@ -101,9 +99,8 @@
border: 0;
}
// 橙色按钮
@mixin btc2($wid:63px, $hei:30px, $fontSize:12px) {
@mixin btc2($wid: 63px, $hei: 30px, $fontSize: 12px) {
width: $wid;
height: $hei;
line-height: $hei;
......@@ -119,11 +116,9 @@
background-blend-mode: soft-light;
background-image: linear-gradient(to bottom, #ec6429, #ec6429), linear-gradient(to top, #000000, #ffffff);
// background-image: linear-gradient(to top, #000000, #ffffff), linear-gradient(to bottom, #ec6429, #ec6429);
}
@mixin btc3($wid:63px, $hei:30px, $fontSize:12px) {
@mixin btc3($wid: 63px, $hei: 30px, $fontSize: 12px) {
width: $wid;
height: $hei;
line-height: $hei;
......@@ -134,7 +129,7 @@
border: solid 1px #006441;
}
@mixin btc4($wid:288px, $hei:60px, $fontSize:12px) {
@mixin btc4($wid: 288px, $hei: 60px, $fontSize: 18px) {
width: $wid;
height: $hei;
line-height: $hei;
......@@ -148,14 +143,12 @@
letter-spacing: 1.4px;
}
@mixin content-percent($percent:4%) {
@mixin content-percent($percent: 4%) {
box-sizing: border-box;
padding: 0 $percent;
}
@mixin border-tans($borderRadius:1px, $borderSize:2px) {
@mixin border-tans($borderRadius: 1px, $borderSize: 2px) {
border: $borderSize solid transparent;
background-clip: padding-box, border-box;
background-origin: padding-box, border-box;
......
......@@ -60,3 +60,8 @@ $--font-path: "~element-ui/lib/theme-chalk/fonts";
font-size: 22px;
font-weight: bold;
}
.policy-change-contact .el-input__inner {
font-size: 18px;
color: $cFontGray2;
}
......