Commit cf3a2b25 authored by 郝聪敏's avatar 郝聪敏

Merge branch 'feature/consultant' into 'master'

Feature/consultant

See merge request !29
parents e576e898 2b8eed7a
......@@ -5,6 +5,7 @@
"scripts": {
"serve": "vue-cli-service serve --open",
"build": "vue-cli-service build",
"report": "vue-cli-service build --report",
"release": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
......
......@@ -5,17 +5,20 @@
<cr-loading class="loading" size="24px">加载中...</cr-loading>
</div>
<login-modal />
<auth-from-xyqb v-if="showAuthXyqb !== -1" />
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import LoginModal from "@/components/LoginModal";
import AuthFromXyqb from "@/components/AuthFromXyqb";
export default {
components: {
LoginModal
LoginModal,
AuthFromXyqb
},
computed: {
...mapState(["isLoading"])
...mapState(["isLoading", "showAuthXyqb"])
},
methods: {
...mapActions(["setIsLoading"])
......
import req from "@/service/http";
// 创建顾问订单
export const create = param => {
return req.post("consultant/order/create", param);
};
// 创建顾问订单-发起支付
export const goPay = param => {
return req.post("consultant/order/gopay", param);
};
// 创建顾问订单-提交咨询问卷
export const subCulQus = param => {
return req.post("consultant/questionnaire/submit", param);
};
// 创建顾问订单-顾问建议
export const getCulsuggestion = param => {
return req.get("consultant/suggestion/detail", param);
};
// 查询顾问订单信息
export const getCulOrder = param => {
return req.get("consultant/order/query", param);
};
// 查询顾问订单支付状态
export const getPayState = param => {
return req.post("/consultant/order/pay-state", param);
};
// 获取顾问
export const getCulState = param => {
return req.post("user/consultant", param);
};
......@@ -12,13 +12,10 @@ import illness from "@/assets/images/user/illness@2x.png";
import life from "@/assets/images/user/life@2x.png";
export default [
{
title: "住院医疗险",
sub: "报销医药费,有无社保均可保",
children: [
{
id: 1,
itype: "mi",
scope: [1, 2, 3], // 范围,列表中区分类型用,1成人 2老年 3少儿
img: good01,
title: "万家保·百万医疗险",
sub: "产品优势",
......@@ -31,16 +28,11 @@ export default [
icon: medical,
guarantee_title: "医疗保障",
guarantee_sub: "看病报销医药费,最高600万"
}
]
},
{
title: "重大疾病险",
sub: "责任内疾病确诊即赔",
children: [
{
id: 2,
itype: "cii",
scope: [1, 2, 3],
img: good02,
title: "万家保·重疾轻症险",
sub: "100种重疾+40种轻症",
......@@ -57,6 +49,7 @@ export default [
{
id: 3,
itype: "cii",
scope: [1, 2],
img: good02,
title: "康惠保2020终身重疾险",
sub: "100种重疾+40种轻症",
......@@ -69,16 +62,11 @@ export default [
icon: illness,
guarantee_title: "重疾保障",
guarantee_sub: "100种重症+40种轻症"
}
]
},
{
title: "意外伤害险",
sub: "意外保障无等待期",
children: [
{
id: 4,
itype: "ai",
scope: [1, 2, 3],
img: good03,
title: "万家保·综合意外险",
sub: "产品优势",
......@@ -91,16 +79,11 @@ export default [
icon: casualty,
guarantee_title: "意外保障",
guarantee_sub: "意外风险覆盖全,最高100万保额"
}
]
},
{
title: "人寿保险",
sub: "家庭顶梁柱必备",
children: [
{
id: 5,
itype: "li",
scope: [1, 3],
img: good04,
title: "华贵大麦2020定期寿险",
sub: "产品优势",
......@@ -114,6 +97,4 @@ export default [
guarantee_title: "人寿保障",
guarantee_sub: "最高350万保额,顶梁柱必备"
}
]
}
];
import req from "@/service/http";
// 产品列表
export const list = param => {
return req.get("product/list", param);
};
// 产品详情
export const addPolicyDetail = param => {
return req.get("product/detail", param);
};
// 产品算价
export const trail = param => {
return req.post("product/price/trail", param);
};
// 下单流程
export const placeOrder = {
// 创建保单订单
......
......@@ -6,7 +6,7 @@ export const loginByPhone = param => {
};
// 信用钱包用户自动登录
export const loginByxyqb = param => {
export const authByxyqb = param => {
return req.get("xyqb_user_info", param);
};
......
<?xml version="1.0" encoding="utf-8"?>
<svg width="19px" height="24px" viewBox="0 0 19 24" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
<desc>Created with Lunacy</desc>
<g id="编组-16">
<g id="Group-4">
<g id="编组-6备份-2" transform="translate(0 5.49753)">
<path d="M14.7907 8.12161C14.928 7.5971 15.0011 7.04668 15.0011 6.47923C15.0011 2.90085 12.0944 0 8.5087 0C5.37816 0 2.76513 2.21116 2.1522 5.15389C1.94346 6.06961 1.97458 6.74032 2.00379 7.37005C2.05333 8.43799 2.09741 9.38809 0.956865 11.2155C-1.04322 14.4201 -0.0668537 17.7948 5.40055 17.3018C9.34282 16.9463 14.0045 12.609 14.7907 8.12161Z" transform="translate(0.01797025 0)" id="形状结合备份" fill="#FFC842" fill-rule="evenodd" stroke="none" />
</g>
<g id="编组-9" transform="matrix(0.9063078 -0.4226183 0.4226183 0.9063078 10.52739 1.996085)">
<path d="M2.55122 2.85733C3.31589 1.52494 3.1481 1.37214e-13 3.1481 1.37214e-13C3.1481 1.37214e-13 -0.22388 1.52175 0.0159214 4.82779C0.0159214 4.82779 1.78654 4.18971 2.55122 2.85733Z" transform="translate(0.1109306 0.04346367)" id="路径-10" fill="#6EA372" stroke="none" />
<path d="M1.69558 1.90091C2.27613 0.973579 2.17791 1.51344e-14 2.17791 1.51344e-14C2.17791 1.51344e-14 -0.0543487 0.926454 0.00135625 3.22707C0.00135625 3.22707 1.11504 2.82824 1.69558 1.90091Z" transform="matrix(0.6427876 0.7660444 -0.7660444 0.6427876 3.112117 3.625421)" id="路径-10备份" fill="#6EA372" stroke="none" />
</g>
</g>
<path d="M4.41006 0.364952C4.44825 0.128299 4.67106 -0.0325839 4.90771 0.00560971C5.14436 0.0438034 5.30525 0.26661 5.26705 0.503263C4.86031 3.02353 3.29455 4.90914 0.614453 6.13307C0.396399 6.23265 0.138907 6.13661 0.0393278 5.91856C-0.0602516 5.7005 0.0357906 5.44301 0.253844 5.34343C2.68135 4.23485 4.05186 2.58437 4.41006 0.364952Z" transform="matrix(0.8746197 -0.4848096 0.4848096 0.8746197 7.804443 11.72031)" id="路径-12" fill="#FFFFFF" stroke="none" />
</g>
</svg>
\ No newline at end of file
<template>
<cr-popup v-model="showAuth" get-container="body" position="bottom" class="auth-popup">
<div class="auth">
<div class="auth-title">
<svg-icon icon-class="mongo" />
<strong>芒果保险</strong>申请获取
</div>
<div class="auth-list">
<div class="auth-item" v-for="(item, index) in userInfo" :key="index">
<div class="auth-item-title">你的{{ item.label }}</div>
<div class="auth-item-info">
<strong>{{ item.value }}</strong>
信用钱包绑定{{ item.label }}
</div>
<cr-divider />
</div>
</div>
<div class="auth-protocol">
允许即表示同意
<a href>《用户协议》</a>
<a href>《隐私政策》</a>
</div>
<div class="auth-foot">
<cr-button class="wx-default" @click="setAuthXyqb(3)">拒绝</cr-button>
<cr-button class="wx-primary" @click="setAuthXyqb(4)">允许</cr-button>
</div>
</div>
</cr-popup>
</template>
<script>
import { mapState, mapActions } from "vuex";
import localStorage from "@/service/localStorage";
const xyqbUserInfo = localStorage.get("xyqbUserInfo") || {};
export default {
name: "AuthFromXyqb",
data() {
return {
showAuth: true,
userInfo: [
{
label: "手机号码",
value: xyqbUserInfo.phoneNoMask
},
{
label: "姓名",
value: xyqbUserInfo.nameMask
},
{
label: "身份证号码",
value: xyqbUserInfo.idNoMask
}
]
};
},
watch: {
showAuthXyqb: {
immediate: true,
handler(val) {
this.showAuth = val === 2;
}
}
},
computed: {
...mapState(["showAuthXyqb"])
},
methods: {
...mapActions(["setAuthXyqb"])
}
};
</script>
<style lang="less" scoped>
@import "../style/var.less";
@import "../style/mixins.less";
.auth {
padding: 30px 20px;
&-popup {
border-top-left-radius: @border-radius-sm;
border-top-right-radius: @border-radius-sm;
}
&-title {
color: @black;
font-size: @font-size-16;
padding: 2px 0 26px;
.svg-icon {
width: 18px;
height: 18px;
}
strong {
font-weight: @font-weight-bold;
margin: 0 10px 0 12px;
}
}
&-list {
margin-bottom: -8px;
}
&-item {
&-title {
font-size: 24px;
font-weight: @font-weight-bold;
color: @black;
line-height: @line-height-lg;
margin: 20px 0;
}
&-info {
.sub-text-mixins();
font-size: 14px;
strong {
font-size: 16px;
font-weight: @font-weight-bold;
color: @black;
}
}
}
&-protocol {
.sub-text-mixins();
margin: 20px 0;
}
&-foot {
display: flex;
justify-content: space-between;
.cr-button {
width: 160px;
height: 40px;
line-height: 40px;
font-size: 18px;
border-radius: 4px !important;
}
.wx-default {
color: #00be57 !important;
}
.wx-primary {
background-color: #09c060 !important;
color: #fff !important;
}
}
}
</style>
<template>
<div class="goods-list">
<div v-if="hasChildren">
<template v-for="(item, index) in list">
<template v-for="(item, index) in goodsList">
<div class="goods-list-head" :key="'head' + index">
<slot :data="item">
<h5>{{ item.title || "-" }}</h5>
......@@ -44,7 +44,7 @@
type="flex"
class="goods-list-item"
:class="{ 'not-allow': !it.allow }"
v-for="(it, idx) in list"
v-for="(it, idx) in goodsList"
:key="idx"
@click.native="clickItem(it)"
>
......@@ -80,12 +80,28 @@ export default {
default() {
return [];
}
},
sort: {
type: Number,
default: 0
}
},
computed: {
// TODO
hasChildren: function() {
return this.list[0] && this.list[0].children && this.list[0].children.length > 0;
},
goodsList() {
const { sort, list, hasChildren } = this;
if (sort === 0) {
return list;
} else {
if (hasChildren) {
return list;
} else {
return list.filter(item => item.scope.includes(sort));
}
}
}
},
methods: {
......
......@@ -82,10 +82,12 @@ export default {
this.formData.loginChannel = isWeixinBrower ? 1 : 2;
this.formData.openId = localStorage.getItem("openId") || null;
const res = await loginByPhone(this.formData);
if (res.code === "0") {
if (res) {
this.$notify("登录成功");
this.setIsShowLogin(false);
localStorage.setItem("mongoToken", res.data.token);
// localStorage.setItem("mongoToken", res.token);
// TODO 开发目前使用这个token
localStorage.setItem("mongoToken", "6ae7da7dd4c543f1a36c702c6f419f12");
}
},
async getCode() {
......@@ -97,7 +99,7 @@ export default {
return;
}
const res = await getCaptchaSms({ phoneNo });
if (res.code === "0" && !this.timer) {
if (res && !this.timer) {
this.count = TIME_COUNT;
this.showCount = true;
this.timer = setInterval(() => {
......
export default {
basicHost: "http://yapi.quantgroups.com/mock/329/",
// basicHost: "http://192.168.29.211:80/",
wxAppId: "wx514de17b23d53a20"
};
export default {
basicHost: "http://127.0.0.1:8964/",
basicHost: "http://192.168.29.211:80/",
// basicHost: "http://127.0.0.1:8964/",
// basicHost: "https://hathaway-mg.liangkebang.net/",
wxAppId: "wx514de17b23d53a20"
};
......@@ -17,5 +17,6 @@ new Vue({
}).$mount("#app");
// if (process.env.NODE_ENV !== "development") {
// ! 上线后务必取掉
// new vConsole();
// }
......@@ -4,7 +4,7 @@ const { Notify } = cherry;
export default {
methods: {
onFailed(errorInfo) {
Notify(errorInfo?.errors?.[0]?.message || '校验失败')
Notify(errorInfo?.errors?.[0]?.message || "校验失败");
}
}
};
import Vue from "vue";
import VueRouter from "vue-router";
import routes from "./routes";
import { parseSearch } from "@/service/utils";
import { isXyqb, isWeixinBrower } from "@/service/validation";
import cfg from "@/config";
import { authByxyqb, getwxOpenId } from "@/api/user";
import localStorage from "@/service/localStorage";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "Default",
redirect: "/goods"
},
{
path: "/home",
name: "Home",
component: () => import("../views/Home/index.vue")
},
{
path: "/home/smart-measure",
name: "SmartMeasure",
component: () => import("../views/Home/SmartMeasure/index.vue")
},
{
path: "/goods",
name: "Goods",
component: () => import("../views/Goods/index.vue")
},
{
path: "/goods/detail",
name: "GoodsDetail",
component: () => import("../views/Goods/Detail/index.vue")
},
{
path: "/goods/plan",
name: "GoodsPlan",
component: () => import("../views/Goods/Plan/index.vue")
},
{
path: "/goods/inform",
name: "GoodsInform",
component: () => import("../views/Goods/Inform/index.vue")
},
{
path: "/consultant",
name: "Consultant",
component: () => import("../views/Consultant/index.vue")
},
{
path: "/consultant/success",
name: "ConsultantSuccess",
component: () => import("../views/Consultant/Success/index.vue")
},
{
path: "/consultant/question",
name: "ConsultantQuestion",
component: () => import("../views/Consultant/Question/index.vue")
},
{
path: "/consultant/exclusive",
name: "ConsultantExclusive",
component: () => import("../views/Consultant/Exclusive/index.vue")
},
{
path: "/consultant/plan",
name: "ConsultantPlan",
component: () => import("../views/Consultant/Plan/index.vue")
},
{
path: "/user",
name: "User",
component: () => import("../views/User/index.vue")
},
{
path: "/user/family",
name: "Family",
component: () => import("../views/User/Family/index.vue")
},
{
path: "/user/family/detail/:id",
name: "Family",
component: () => import("../views/User/Family/Detail/index.vue")
},
{
path: "/user/help-center",
name: "Family",
component: () => import("../views/User/HelpCenter/index.vue")
},
{
path: "/policy",
name: "Policy",
component: () => import("../views/Policy/index.vue")
},
{
path: "/policy/detail",
name: "Detail",
component: () => import("../views/Policy/Detail/index.vue")
},
{
path: "/policy/add",
name: "AddPolicy",
component: () => import("../views/Policy/Add/index.vue")
},
{
path: "/policy/payment-record",
name: "PaymentRecord",
component: () => import("../views/Policy/PaymentRecord/index.vue")
},
{
path: "/policy/renewal",
name: "Renewal",
component: () => import("../views/Policy/Renewal/index.vue")
},
{
path: "/introduction",
name: "Introduction",
component: () => import("../views/Introduction/index.vue")
},
{
path: "/paytest",
name: "Introduction",
component: () => import("../views/paytest")
},
{
path: "*",
redirect: "/goods"
}
];
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err);
};
......@@ -140,4 +22,29 @@ const router = new VueRouter({
}
});
router.beforeEach((to, from, next) => {
const urlParams = parseSearch(window.location.href);
if (isXyqb) getAuthInfo(urlParams.token);
if (isWeixinBrower) getWxOpenId(urlParams.code);
next();
});
async function getAuthInfo(xyqbToken) {
if (localStorage.get("xyqbToken")) return;
const res = await authByxyqb({ xyqbToken });
if (res) {
localStorage.set("mongoToken", res.token);
localStorage.set("xyqbUserInfo", res);
localStorage.set("xyqbToken", xyqbToken);
}
}
async function getWxOpenId(code) {
if (localStorage.get("openId")) return;
const res = await getwxOpenId({ code, appId: cfg.wxAppId });
this.openId = res.openId;
localStorage.set("openId", res.openId);
}
// router.afterEach(() => {});
export default router;
export default [
{
path: "/",
name: "Default",
redirect: "/goods"
},
{
path: "/home",
name: "Home",
component: () => import("../views/Home/index.vue")
},
{
path: "/home/smart-measure",
name: "SmartMeasure",
component: () => import("../views/Home/SmartMeasure/index.vue")
},
{
path: "/goods",
name: "Goods",
component: () => import("../views/Goods/index.vue")
},
{
path: "/goods/detail",
name: "GoodsDetail",
component: () => import("../views/Goods/Detail/index.vue")
},
{
path: "/goods/plan",
name: "GoodsPlan",
component: () => import("../views/Goods/Plan/index.vue")
},
{
path: "/goods/inform",
name: "GoodsInform",
component: () => import("../views/Goods/Inform/index.vue")
},
{
path: "/consultant",
name: "Consultant",
component: () => import("../views/Consultant/index.vue")
},
{
path: "/consultant/plan",
name: "ConsultantPlan",
component: () => import("../views/Consultant/Plan/index.vue")
},
{
path: "/user",
name: "User",
component: () => import("../views/User/index.vue")
},
{
path: "/user/family",
name: "Family",
component: () => import("../views/User/Family/index.vue")
},
{
path: "/user/family/detail/:id",
name: "Family",
component: () => import("../views/User/Family/Detail/index.vue")
},
{
path: "/user/help-center",
name: "Family",
component: () => import("../views/User/HelpCenter/index.vue")
},
{
path: "/policy",
name: "Policy",
component: () => import("../views/Policy/index.vue")
},
{
path: "/policy/detail",
name: "Detail",
component: () => import("../views/Policy/Detail/index.vue")
},
{
path: "/policy/add",
name: "AddPolicy",
component: () => import("../views/Policy/Add/index.vue")
},
{
path: "/policy/payment-record",
name: "PaymentRecord",
component: () => import("../views/Policy/PaymentRecord/index.vue")
},
{
path: "/policy/renewal",
name: "Renewal",
component: () => import("../views/Policy/Renewal/index.vue")
},
{
path: "/introduction",
name: "Introduction",
component: () => import("../views/Introduction/index.vue")
},
{
path: "/paytest",
name: "Introduction",
component: () => import("../views/paytest")
},
{
path: "*",
redirect: "/goods"
}
];
......@@ -2,11 +2,12 @@
* @Description: 支付微信h5, jsapi, 第三方收银台,跳转)
* @Date: 2020-07-28 15:03:52
* @LastEditors: gzw
* @LastEditTime: 2020-07-31 10:46:33
* @LastEditTime: 2020-08-04 18:51:12
*/
import { Notify } from "@qg/cherry-ui";
import cherry from "@qg/cherry-ui";
import qs from "qs";
const { Notify } = cherry;
/**
* payByWeixinJsapi
......@@ -15,20 +16,12 @@ import qs from "qs";
* @param {type}
* @return:
*/
function payByWeixinJsapi(info, callback) {
function payByWeixinJsapi(info = {}, callback) {
console.log(info);
function onBridgeReady() {
// eslint-disable-next-line no-undef
WeixinJSBridge.invoke(
"getBrandWCPayRequest",
{
appId: info.appId, //公众号名称,由商户传入
timeStamp: info.timeStamp, //时间戳,自1970年以来的秒数
nonceStr: info.nonceStr, //随机串
package: `prepay_id=${info.prepayId}`,
signType: "MD5", //微信签名方式:
paySign: info.sign //微信签名
},
function(res) {
WeixinJSBridge.invoke("getBrandWCPayRequest", info, function(res) {
console.log(res);
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
......@@ -40,8 +33,7 @@ function payByWeixinJsapi(info, callback) {
// 支付失败
callback("fail");
}
}
);
});
}
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
......@@ -71,6 +63,8 @@ function payByWeixinH5(info) {
}
/**
* TODO
*
* payByThirdPartyCashier
* @description: 第三方收银台
* @param {type}
......@@ -86,6 +80,7 @@ function payByThirdPartyCashier(info) {
/**
* @description: 支付方式判断, 返回promise
* NATIVE=原生扫码支付.,APP=ap支付,,JSAPI=公众号支付/小程序支付,,MWEB=H5支付.,MICROPAY=刷卡支付,默认JSAPI
* @param {String} type 支付方式,THIRD -> 第三方,MWEB -> H5支付, JSAPI -> jsapi支付,默认支付方式,THIRD
* @param {Object/String} payInfo 支付信息
* @return {Promise} 回调
......
......@@ -100,23 +100,31 @@ export function filterEmoji(name) {
);
return str;
}
/**
* xss处理
* @param {String} s 输入字符串
* hash路由获取url参数
* @param {String} searchString 输入字符串
* @return: {String} str 字符串
*/
export function xssParse(str) {
return str
? str.replace(/&((g|l|quo)t|amp|#39|nbsp);/g, function(m) {
return {
"&lt;": "<",
"&amp;": "&",
"&quot;": '"',
"&gt;": ">",
"&#39;": "'",
"&nbsp;": " "
}[m];
})
: "";
export function parseSearch(searchString) {
if (!searchString) {
return {};
}
if (!searchString.includes("?")) {
return {};
}
return searchString
.split("?")[1]
.split("#")[0]
.split("&")
.reduce((result, next) => {
const pair = next.split("=");
try {
result[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
} catch (e) {
// eslint-disable-next-line
// result[decodeURIComponent(pair[0])] = window.$URL.decode(pair[1]);
}
return result;
}, {});
}
......@@ -250,7 +250,6 @@ export function isBankNumber(str) {
}
// 判断微信环境
export function isWeixinBrower() {
const ua = window.navigator.userAgent.toLowerCase();
return ua.match(/MicroMessenger/i) == "micromessenger";
}
export const isWeixinBrower = window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == "micromessenger";
// 判断信用钱包环境
export const isXyqb = window.navigator.userAgent.toLowerCase().match(/xyqb/i) == "xyqb";
import Vue from "vue";
import Vuex from "vuex";
import user from "./modules/user";
import { isXyqb } from "@/service/validation";
import localStorage from "@/service/localStorage";
const XYQB_AUTH_STATE = localStorage.get("xyqbAuthState") || 1;
Vue.use(Vuex);
export default new Vuex.Store({
state: {
activeIdx: 0,
isLoading: false,
isShowLogin: false
isShowLogin: false,
showAuthXyqb: isXyqb ? XYQB_AUTH_STATE : -1 // 1 已获取信息未授权,2 打开授权弹框, 3 拒绝授权,4 允许授权, -1 非信用钱包环境
},
mutations: {
setActiveIdx(state, value) {
......@@ -19,6 +23,10 @@ export default new Vuex.Store({
},
setIsShowLogin(state, value) {
state.isShowLogin = value;
},
setAuthXyqb(state, value) {
state.showAuthXyqb = value;
localStorage.set("xyqbAuthState", value);
}
},
actions: {
......@@ -30,6 +38,9 @@ export default new Vuex.Store({
},
setIsShowLogin({ commit }, args) {
commit("setIsShowLogin", args);
},
setAuthXyqb({ commit }, args) {
commit("setAuthXyqb", args);
}
},
modules: {
......
......@@ -54,38 +54,41 @@ input::-webkit-input-placeholder {
&--round {
border-radius: 1em !important;
}
&_light {
background-color: @tag-default-light-background-color !important;
color: @tag-default-light-color !important;
}
&--primary {
background-color: @tag-primary-background-color !important;
color: @tag-primary-color !important;
&_light {
background-color: @tag-primary-light-background-color !important;
color: @tag-primary-light-color !important;
}
}
&--success {
background-color: @tag-success-background-color !important;
color: @tag-success-color !important;
&_light {
background-color: @tag-success-light-background-color !important;
color: @tag-success-light-color !important;
}
}
&--danger {
background-color: @tag-danger-background-color !important;
color: @tag-danger-color !important;
&_light {
background-color: @tag-danger-light-background-color !important;
color: @tag-danger-light-color !important;
}
}
&--warning {
background-color: @tag-warning-background-color !important;
color: @tag-warning-color !important;
&_light {
}
&--plain {
background-color: @tag-default-light-background-color !important;
color: @tag-default-light-color !important;
&::after {
display: none;
}
&.cr-tag--primary {
background-color: @tag-primary-light-background-color !important;
color: @tag-primary-light-color !important;
}
&.cr-tag--success {
background-color: @tag-success-light-background-color !important;
color: @tag-success-light-color !important;
}
&.cr-tag--danger {
background-color: @tag-danger-light-background-color !important;
color: @tag-danger-light-color !important;
}
&.cr-tag--warning {
background-color: @tag-warning-light-background-color !important;
color: @tag-warning-light-color !important;
}
......
@import "../../style/var.less";
@import "../../style/mixins.less";
@import "../../../style/var.less";
@import "../../../style/mixins.less";
.item-show-mixin {
text-align: center;
......@@ -31,7 +31,7 @@
}
}
.cul-hd {
background: url("../../assets/images/consultant/bg.png") top no-repeat;
background: url("../../../assets/images/consultant/bg.png") top no-repeat;
background-size: contain;
padding: 10px 16px;
position: relative;
......@@ -66,6 +66,7 @@
background-color: #fff;
&-title {
.sub-text-mixins();
text-align: center;
}
.cr-button {
height: @button-large-height + 2;
......
<template>
<div class="container">
<div class="cul-hd">
<img src="../../../assets/logo-top.png" alt="logo" class="cul-hd-logo" />
<div class="cul-hd-rec">
<h4 class="cul-hd-rec-title">最高节省50%保费</h4>
<small class="cul-hd-rec-sub">帮你量身选保险</small>
</div>
<div class="cul-hd-card">
<div class="cul-hd-card-title">您将获得的服务</div>
<div class="cul-hd-service">
<div class="cul-hd-service-item" v-for="(item, index) in serviceList" :key="index">
<svg-icon :icon-class="item.icon" />
<h5>{{ item.title }}</h5>
<p>{{ item.sub }}</p>
</div>
</div>
<div class="cul-hd-stock">
<h4 class="cul-hd-stock-title">
还剩
<strong>{{ remain }}</strong>
</h4>
<div class="cul-hd-progress">
<cr-progress
:show-pivot="false"
stroke-width="6"
color="#FFC842"
track-color="#F9F3F3"
:percentage="25"
/>
</div>
</div>
<div class="cul-hd-card-foot">
<cr-button type="warning" block @click="checkLogin">{{ price[0] }}元聘请</cr-button>
<cr-tag class="cul-hd-discount" shape="round" v-if="price[0] !== price[1]">
<strong>限时优惠</strong>
<del>
<span>原价</span>
<em>{{ price[1] }}</em>
<span></span>
</del>
</cr-tag>
</div>
</div>
</div>
<div class="cul-det">
<card title="想买保险,你是不是也有这些疑问?">
<cr-image src="@/assets/images/consultant/intro.png" width="100%" height="auto" />
</card>
<card title="芒果保险·1对1保险顾问来帮您?">
<div class="cul-odds-sign">
<div class="cul-odds-sign-item" v-for="(item, index) in oddsList" :key="index">
<svg-icon :icon-class="item.icon" />
<h5>{{ item.title }}</h5>
<p v-for="(it, index) in item.sub" :key="index">{{ it }}</p>
</div>
</div>
<div class="cul-odds-list">
<div class="cul-odds-list-item" v-for="(item, index) in oddsInsureList" :key="index">
<div class="cul-odds-list-title">
<i class="cul-odds-list-title-icon">{{ index + 1 }}</i>
<span class="cul-odds-list-title-txt">{{ item.title }}</span>
</div>
<div class="cul-odds-list-content">
<div class="cul-odds-list-content-item" v-for="(it, idx) in item.children" :key="idx">
<div class="cul-odds-list-content-title">
<svg-icon icon-class="check-circle" />
{{ it[0] }}
</div>
<div class="cul-odds-list-content-txt">{{ it[1] }}</div>
</div>
</div>
</div>
</div>
</card>
<cps-qa :qa-data="qaInfo" :more="false" />
</div>
</div>
</template>
<script>
import localStorage from "@/service/localStorage";
import { payByWay } from "@/service/pay";
import { isXyqb } from "@/service/validation";
import { mapActions, mapState } from "vuex";
import { create, goPay } from "@/api/consultant";
import Card from "@/components/Card";
import Collapse from "@/components/Collapse";
import CpsQa from "../../Goods/Detail/modules/CpsQA";
export default {
name: "ConsultantBuy",
components: {
Card,
CpsQa,
// eslint-disable-next-line
Collapse
},
props: {
state: {
type: [Number, String],
default: 0
}
},
data() {
return {
isLogin: localStorage.get("mongoToken"),
remain: 126,
price: [0.99, 199],
consultantOrderNo: "",
tradeType: isXyqb ? "MWEB" : "JSAPI",
serviceList: [
{ icon: "team", title: "资深", sub: "保险精算团队" },
{ icon: "card", title: "专属", sub: "保险顾问" },
{ icon: "computer", title: "全程", sub: "一站式服务" }
],
oddsList: [
{ icon: "ticket-shadow", title: "省钱", sub: ["最高节省", "50%保费"] },
{ icon: "shield-shadow", title: "放心", sub: ["中立客观", "量身定制"] },
{
icon: "ok-shadow",
title: "专业",
sub: ["条款解读", "有效投保", "协助理赔"]
}
],
oddsInsureList: [
{
title: "投保前",
children: [
["全方位评估:", "360°筛查、识别、评估您的家庭风险"],
[
"量身筛选:",
"根据您的自身情况,分析对比几百款产品,选出最适合的保障方案,最高节省50%保费"
],
["保单诊断:", "全面评估已有保单,中立、客观的给您提供针对性的意见 "]
]
},
{
title: "投保中",
children: [
["条款解读:", "为您解释复杂难懂的条款"],
["有效投保:", "为您做好健康告知,做到有效投保"]
]
},
{
title: "省钱",
children: [["协助理赔:", "申请理赔时,理赔专家全程协助"]]
}
],
qaInfo: [
{
q: "有了社保,还需要买保险吗?",
a: `<p style="margin-bottom: 5px;">需要的。社保是基础保障,优势是覆盖范围广,劣势是抵御风险能力有限,社保报销外的自付部分,可以用商业保险来保障。</p>
<p style="margin-bottom: 5px;">比如【百万医疗险】的作用是补充社保,报销因大病造成的高额医疗负担;</p>
<p style="margin-bottom: 5px;">比如【重大疾病险】的作用是弥补因病造成的收入损失、维持家庭正常运转的成本;</p>
<p style="margin-bottom: 5px;">比如【意外险】的作用是保障意外风险,弥补家庭劳动力确实造成的收入损失。</p>
<p style="margin-bottom: 5px;">比如【寿险】的作用是身故赔付,是对家庭责任的延续。</p>
`
},
{
q: "我是小白,买保险应该怎么买?",
a: `<p style="margin-bottom: 5px;">健康类保险最基本的分为【医疗险】【重疾险】【意外险】【定期寿险】四类。</p>
<p style="margin-bottom: 5px;">【医疗险】通常需要提供“医疗票据”实报实销,赔付的保险金保障了因“疾病”、“意外”产生的医疗费用。</p>
<p style="margin-bottom: 5px;">【重疾险】通常需要提供“确诊证明”一次性获得赔付的保险金,前提是罹患的重大疾病在合同约定内。</p>
<p style="margin-bottom: 5px;">【意外险】通常需要提供“身故证明”或“致残证明”获得赔付的保险金,前提是“身故”、“致残”是因意外事件导致。</p>
<p style="margin-bottom: 5px;">【定期寿险】通常需要提供“身故证明”一次性赔付,赔付的保险金在一定程度上,缓解了家庭因被保人身故导致的经济压力。</p>
`
},
{
q: "百万医疗险和重大疾病险有什么区别?",
a: `<p style="margin-bottom: 5px;">【医疗险】和【重疾险】的区别主要有2种。</p>
<p style="margin-bottom: 5px;">一、【医疗险】是报销型,合理医疗费花多少报多少。<br />
【重疾险】是给付型,确诊后即可获得赔付,买多少保额赔多少钱。</p>
<p style="margin-bottom: 5px;"> 二、【医疗险】的本质是应对医疗支出。<br />
【重疾险】的本质是弥补因病导致的收入损失。</p>
`
},
{
q: "我是中低收入,应该怎么买保险?",
a: `<p style="margin-bottom: 5px;">对于大部分家庭来讲,每年比较合理的保费支出占可支配收入的5%~10%。</p>
<p style="margin-bottom: 5px;">低收入家庭:建议配置【医疗险】+【意外险】</p>
<p style="margin-bottom: 5px;">中收入家庭:建议酌情配置【医疗险】+【重疾险】+【意外险】</p>
<p style="margin-bottom: 5px;">有条件的家庭:可以配置【高端医疗险】+【重疾险】+【意外险】+【寿险】</p>`
},
{
q: "“消费型保险”和“返还型保险”是什么意思?",
a: `<p style="margin-bottom: 5px;">简单讲,“消费型保险”在合同到期后不返还保费,“返还型保险”在合同到期后返还保费。</p>
<p style="margin-bottom: 5px;">【消费型保险】重点在“保障”,合同期内发生风险,保险公司赔偿保险金,合同期外发生风险,保险公司不赔偿也不退回保费。</p>
<p style="margin-bottom: 5px;">【返还型保险】重点在“返还”,合同期内发生风险,保险公司赔偿保险金,合同到期未赔偿,保险公司退回保费。</p>
<p style="margin-bottom: 5px;">两种类型的保险各有优势,而且“返回型保险”种类繁多,建议投保人咨询“闪电保险1对1保险顾问”进行详细了解。</p>
`
},
{
q: "医疗险可以重复购买吗?",
a: `<p style="margin-bottom: 5px;">不建议重复购买。</p>
<p style="margin-bottom: 5px;">医疗险属于报销型,原则上报销后的医疗费不得高于已支付的医疗费。</p>
<p style="margin-bottom: 5px;">医疗险在报销时,通常由一家保险公司报销,如果达到报销额度上限还未报销完,且购买其他医疗险,可由第二家保险公司接着报销。</p>
<p style="margin-bottom: 5px;">现在常见的【百万医疗险】保额可达600万,基本上可以覆盖所有的医疗费用。</p>`
}
]
};
},
computed: {
...mapState(["isShowLogin"])
},
watch: {
isShowLogin(val) {
console.log(111);
if (!val) {
this.isLogin = localStorage.get("mongoToken");
}
}
},
mounted() {},
methods: {
...mapActions(["setIsShowLogin"]),
checkLogin() {
if (!this.isLogin) {
this.setIsShowLogin(true);
return;
}
if (this.state == 1) {
this.goPay();
} else {
this.generateOrder();
}
},
async generateOrder() {
const res = await create();
if (res) {
this.consultantOrderNo = res.consultantOrderNo;
this.goPay();
}
},
async goPay() {
const res = await goPay({ tradeType: this.tradeType });
if (res) {
payByWay(this.tradeType, res.payInfo).then(res => {
if (res === "ok") {
setTimeout(() => {
// this.$router.push("/consultant/success");
this.$parent.getOrderInfo();
}, 2000);
}
});
}
}
}
};
</script>
<style lang="less" src="./index.less" scoped></style>
@import "../index.less";
@import "../Buy/index.less";
.container {
background-color: @white;
}
......
......@@ -3,10 +3,10 @@
<div class="cul-hd">
<div class="cul-hd-info">
<small>“保险从业多年,口碑极佳”</small>
<h1>李玉婷</h1>
<cr-tag><svg-icon icon-class="medal" />金牌保险顾问</cr-tag>
<h1>{{ info.name }}</h1>
<cr-tag><svg-icon icon-class="medal" />{{ info.role }}</cr-tag>
<small>执业保险销售资质:</small>
<small>201920000000800<br />02020003828</small>
<small v-html="`${info.id.slice(0, 15)}<br />${info.id.slice(15)}`"></small>
</div>
<cr-image
class="cul-hd-img"
......@@ -17,7 +17,15 @@
</div>
<div class="cul-det">
<card title="" class="cul-card">
<div class="cul-contact">
<router-link tag="div" class="cul-entry" to="/consultant/plan" v-if="hasSuggestion">
<div class="cul-entry-title">
<h3>您的专属保险方案</h3>
<small>CAPTIVE INSURANC</small>
<cr-tag>自己</cr-tag>
</div>
<svg-icon icon-class="arrow-right" />
</router-link>
<div class="cul-contact" v-else>
<div class="cul-contact-qrcode">
<cr-image
src="@/assets/images/consultant/qrcode-demo.png"
......@@ -28,28 +36,20 @@
</div>
<div class="cul-rate">
<div class="cul-rate-item">
<h2>38100</h2>
<h2>{{ info.serveNum }}</h2>
<p>已服务用户人</p>
</div>
<div class="cul-rate-item">
<h2>99.8%</h2>
<h2>{{ info.rate }}</h2>
<p>满意度</p>
</div>
</div>
</div>
<router-link tag="div" class="cul-entry" to="/consultant/plan">
<div class="cul-entry-title">
<h3>您的专属保险方案</h3>
<small>CAPTIVE INSURANC</small>
<cr-tag>自己</cr-tag>
</div>
<svg-icon icon-class="arrow-right" />
</router-link>
<div class="cul-tel">
<a class="cul-tel-num" href="tel:13888888888">
<svg-icon icon-class="call" />138 8888 8888
<a class="cul-tel-num" :href="`tel:${info.tel}`">
<svg-icon icon-class="call" />{{ info.tel }}
</a>
<div class="cul-time">服务时间 9:00 ~ 21:00</div>
<div class="cul-time">服务时间 {{ info.date }}</div>
</div>
<div class="cul-slogan">
<p>“我们的价值:让客户少花钱买好保险”</p>
......@@ -90,9 +90,25 @@ export default {
Card,
copyright
},
props: {
hasSuggestion: {
type: Boolean,
default: false
}
},
data() {
return {
Info: {},
info: {
name: "李玉婷",
role: "金牌保险顾问",
id: "20192000000080002020003828",
qrcode: "",
avator: "",
serveNum: 38100,
rate: "99.8%",
tel: "13888888888",
date: "9:00 ~ 21:00"
},
oddsInsureList: [
{
title: "投保前",
......
......@@ -10,21 +10,21 @@
<card title="1">
<h5 class="cul-hd-card-title" slot="header">
总保费:
<strong>{{ baseInfo.amount }}</strong>
<strong>{{ goodInfo.totalAmount }}</strong>
{{ baseInfo.unit }}
</h5>
<p class="cul-hd-card-content">
推荐理由:
{{ baseInfo.reason }}
{{ goodInfo.remarks }}
</p>
</card>
</div>
<div class="cul-det">
<card title="保障分布">
<div class="cul-dist">
<div class="cul-dist-item" v-for="(item, index) in distList" :key="index">
<h3>{{ item.price }}</h3>
<p>{{ item.title }}</p>
<div class="cul-dist-item" v-for="(item, index) in goodInfo.ensure" :key="index">
<h3>{{ item.insuredAmount }}</h3>
<p>{{ item.productType }}</p>
</div>
</div>
</card>
......@@ -40,39 +40,41 @@
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in overviewList" :key="index">
<th>{{ item.title }}</th>
<th>{{ item.amount }}</th>
<th>{{ item.range }}</th>
<th>{{ item.way }}</th>
<th>{{ item.price }}</th>
<tr v-for="(item, index) in goodInfo.ensure" :key="index">
<th>{{ item.productType }}</th>
<th>{{ item.insuredAmount }}</th>
<th>{{ item.term }}</th>
<th>{{ item.paymentPeriod }}</th>
<th>{{ item.price || "-" }}</th>
</tr>
</tbody>
</table>
</card>
<card title="保障产品">
<div class="good-item" v-for="(item, index) in overviewList" :key="index">
<div class="good-item" v-for="(item, index) in goodInfo.ensure" :key="index">
<div class="good-title">
{{ item.goods }}
<cr-tag :type="tagFilter(item.type)">{{ item.title }}</cr-tag>
{{ item.productName || "" }}
<cr-tag :type="tagFilter(item.productType)" plain>{{ item.productType }}</cr-tag>
</div>
<div class="good-date">
<span class="good-date-item">
保额 | <strong>{{ item.amount }}</strong>
保额 | <strong>{{ item.insuredAmount }}</strong>
</span>
<span class="good-date-item">
缴费期 | <strong>{{ item.way }}</strong>
缴费期 | <strong>{{ item.paymentPeriod }}</strong>
</span>
<span class="good-date-item">
保障期限 | <strong>{{ item.range }}</strong>
保障期限 | <strong>{{ item.term }}</strong>
</span>
</div>
<div class="good-price">
<div class="good-price-item">
<strong>{{ item.goodsPirce }}</strong>
{{ item.goodsUnit }}
<strong>{{ item.firstPrice && item.firstPrice.split("")[0] }}</strong>
{{ item.firstPrice && item.firstPrice.split("")[1] }}
</div>
<cr-button type="warning" @click="goDetail(item.id, item.type)">去投保</cr-button>
<cr-button type="warning" @click="goDetail(item.productNo, item.productType)">
去投保
</cr-button>
</div>
<div class="good-reason">
<div class="good-reason-avator">
......@@ -91,6 +93,7 @@
<script>
import Card from "@/components/Card";
import { getCulsuggestion } from "@/api/consultant";
import avator from "@/assets/images/consultant/avator.png";
export default {
name: "ConsultantSuccess",
......@@ -100,6 +103,9 @@ export default {
data() {
return {
avator,
goodInfo: {
ensure: []
},
baseInfo: {
userName: "王斌",
sex: 1,
......@@ -169,31 +175,39 @@ export default {
]
};
},
mounted() {},
mounted() {
this.getSuggestion();
},
methods: {
tagFilter(type) {
let _type = "";
switch (type) {
case "mi":
case "医疗":
_type = "warning";
break;
case "cii":
case "重疾":
_type = "danger";
break;
case "ai":
case "意外":
_type = "primary";
break;
case "li":
_type = "light";
case "寿险":
_type = "";
break;
default:
_type = "light";
_type = "";
break;
}
return _type;
},
goDetail(id, type) {
this.$router.push({ url: "/goods/detail", query: { id, type } });
},
async getSuggestion() {
const res = await getCulsuggestion();
if (res) {
this.goodInfo = res;
}
}
}
};
......
......@@ -16,9 +16,15 @@
text-align: center;
a {
.sub-text-mixins();
display: block;
margin-top: 15px;
}
}
&-body {
height: 230px;
@{deep} .cr-picker--content-choose {
display: none;
}
@{deep} .wheel-item {
font-size: 16px;
}
......@@ -71,6 +77,7 @@
margin-top: 8px;
color: @gray-4;
width: 100%;
height: 32px;
}
.cul-inline {
@{deep} .cr-radio {
......
......@@ -25,9 +25,9 @@
</h5>
<div class="cul-tip">{{ stepTips[currentStep].sub }}</div>
</template>
<cr-form class="cul-hd-card-body" @submit="onSubmit" @failed="onFailed">
<cr-form class="cul-hd-card-body">
<cr-radio-btn
v-model="formData.who"
v-model="formData.relation"
class="qus-radio"
:radio-data="insuredOptions"
v-show="currentStep === 0"
......@@ -40,10 +40,11 @@
}
"
v-show="currentStep === 1"
item-height="35"
:show-toolbar="false"
/>
<cr-radio-btn
v-model="formData.social"
v-model="formData.socialSecurity"
:radio-data="hasSocialOptions"
class="qus-radio cul-inline"
v-show="currentStep === 2"
......@@ -53,10 +54,11 @@
:columns="incomeOptions"
@change="
(picker, value) => {
onPickerChange(picker, value, 'income');
onPickerChange(picker, value, 'annualIncome');
}
"
v-show="currentStep === 3"
item-height="35"
:show-toolbar="false"
/>
<cr-picker
......@@ -68,6 +70,7 @@
}
"
v-show="currentStep === 4"
item-height="35"
:show-toolbar="false"
/>
<cr-area
......@@ -75,21 +78,22 @@
:list="areaList"
@change="
(picker, value) => {
onPickerChange(picker, value, 'area');
onPickerChange(picker, value, 'addressCode');
}
"
:columns-num="2"
item-height="35"
v-show="currentStep === 5"
/>
<cr-radio-btn
v-model="formData.solve"
v-model="formData.questionType"
:radio-data="solveOptions"
class="qus-radio cul-inline"
v-show="currentStep === 6"
/>
<div class="qus-form" v-show="currentStep === 7">
<cr-field
v-model="formData.username"
v-model="formData.userName"
name="姓名"
label="姓名"
placeholder="请输入投保人姓名"
......@@ -101,9 +105,10 @@
label="您的性别"
:rules="[{ required: true, message: '请选择性别' }]"
>
<cr-radio-btn slot="input" v-model="formData.sex" :radio-data="sexOptions" />
<cr-radio-btn slot="input" v-model="formData.gender" :radio-data="sexOptions" />
</cr-field>
<cr-field
<!-- <cr-field
v-if="!isLogin"
v-model="formData.phone"
type="password"
name="预留手机"
......@@ -112,6 +117,7 @@
:rules="[{ required: true, message: '请输入手机号' }]"
/>
<cr-field
v-if="!isLogin"
v-model="formData.code"
name="验证码"
label="验证码"
......@@ -119,11 +125,13 @@
:rules="[{ required: true, message: '输入短信验证码' }]"
>
<a href="javascript:;" slot="button">发送验证码</a>
</cr-field>
</cr-field> -->
</div>
</cr-form>
<div slot="footer" class="cul-hd-card-footer">
<cr-button type="warning" size="large" block @click="nextQuestion">下一步</cr-button>
<cr-button type="warning" size="large" block @click="nextQuestion">
{{ currentStep === 7 ? "提交问卷" : "下一步" }}
</cr-button>
<a href="javascsript:;" @click="prevQuestion" v-show="currentStep > 0">返回上一步</a>
</div>
</card>
......@@ -145,7 +153,9 @@
<script>
import CrRadioBtn from "@/components/CrRadioBtn";
import Card from "@/components/Card";
import localStorage from "@/service/localStorage";
import areaList from "@qg/cherry-ui/src/area/demo/china";
import { subCulQus } from "@/api/consultant";
export default {
name: "ConsultantQuestion",
components: {
......@@ -154,65 +164,94 @@ export default {
},
data() {
return {
isLogin: localStorage.get("mongoToken"),
areaList,
formData: {},
formData: {
birthday: "",
socialSecurity: "",
annualIncome: "",
loan: "",
addressCode: "111,111,11",
questionType: "",
userName: "",
gender: "",
relation: ""
},
currentStep: 0,
showSubState: false,
stepTips: [
{
title: "您准备为谁买保险?",
tag: "relation",
rule: "请选择关系",
sub:
"想为多人买保险的情况,请在和保险顾问沟通时说明信息,保险顾问会为每一位家人量身定制方案哦~~"
},
{
title: "请选择TA的出生日期?",
tag: "birthday",
rule: "请选择出生日期",
sub: "出生日期会影响保费计算,准确的填写可让保险顾问帮您更精准的测算保费~"
},
{ title: "请选择TA有无社保", sub: "新农合也算社保哦~~" },
{
title: "请选择TA有无社保",
tag: "socialSecurity",
rule: "请选择有无社保",
sub: "新农合也算社保哦~~"
},
{
title: "请选择您的年收入?",
tag: "annualIncome",
rule: "请选择您的年收入",
sub: "保险顾问会根据您的年收入,帮您选择合适的额度和保费预算"
},
{
title: "请问您每月要还多少贷款呢?",
tag: "loan",
rule: "请选择贷款",
sub: "贷款包含房贷、车贷、信用卡等,了解您的贷款情况,能让顾问更好的帮您定制寿险额度"
},
{
title: "请选择您的居住城市?",
tag: "addressCode",
rule: "请选择居住城市",
sub: "保险产品的销售会受到地区的限制,了解您的居住城市能让顾问帮您挑选到合适的保险"
},
{
title: "您主要想解决哪方面问题?",
tag: "questionType",
rule: "请选择问题类型",
sub: "告诉保险顾问您的咨询意向,可以为您提供更专业的服务哦"
},
{
title: "请填写您的个人信息",
rule: "请完善个人信息",
sub: "请预留您的信息,保险师会在您方便时联系您"
}
],
insuredOptions: [
{ label: "本人", value: "1" },
{ label: "配偶", value: "2" },
{ label: "儿子", value: "3" },
{ label: "女儿", value: "4" },
{ label: "父亲", value: "5" },
{ label: "母亲", value: "6" }
{ label: "本人", value: "本人" },
{ label: "配偶", value: "配偶" },
{ label: "儿子", value: "儿子" },
{ label: "女儿", value: "女儿" },
{ label: "父亲", value: "父亲" },
{ label: "母亲", value: "母亲" }
],
hasSocialOptions: [
{ label: "", value: "1" },
{ label: "", value: "2" }
{ label: "", value: "0" }
],
sexOptions: [
{ label: "", value: "1" },
{ label: "", value: "2" }
{ label: "", value: "0" },
{ label: "", value: "1" }
],
incomeOptions: ["10万", "20万", "25万", "30万"],
loanOptions: ["无房贷", "1000元", "2000元", "3000元", "4000元"],
solveOptions: [
{ label: "之前从没买过保险,打算配置保险", value: "1" },
{ label: "已配置部分保险,打算再补充一些", value: "2" },
{ label: "不配置保险,就想咨询些保险疑惑", value: "3" },
{ label: "", value: "4" }
{ label: "之前从没买过保险,打算配置保险", value: "之前从没买过保险,打算配置保险" },
{ label: "已配置部分保险,打算再补充一些", value: "已配置部分保险,打算再补充一些" },
{ label: "不配置保险,就想咨询些保险疑惑", value: "不配置保险,就想咨询些保险疑惑" },
{ label: "", value: "" }
],
processList: [
{ icon: "package-active", sub: "聘请成功", active: true },
......@@ -241,12 +280,15 @@ export default {
mounted() {},
methods: {
nextQuestion() {
if (this.currentStep === 7) {
const { currentStep, stepTips, formData } = this;
const userName = formData.userName && formData.gender;
if (currentStep === 7 && userName) {
this.showSubState = true;
setTimeout(() => {
this.showSubState = false;
this.$router.push("/consultant/exclusive");
}, 3000);
this.onSubmit();
return;
}
if (!formData[stepTips[currentStep].tag] || currentStep === 7) {
this.$notify({ type: "warning", message: stepTips[currentStep].rule });
return;
}
this.currentStep++;
......@@ -258,13 +300,24 @@ export default {
this.currentStep--;
},
onPickerChange(picker, value, type) {
if (type === "birthday") {
value = value.map(item => item[0]).join("-");
}
if (type === "annualIncome" || type === "loan") {
value = value[0];
}
// if (type === "area") {}
this.formData[type] = value;
},
async onSubmit() {
// console.log('sucess', values);
},
onFailed() {
// console.log('fail', errorInfo);
const { formData } = this;
const res = await subCulQus(formData);
if (res) {
setTimeout(() => {
this.showSubState = false;
this.$parent.getOrderInfo();
}, 2000);
}
}
}
};
......
@import "../Success/index.less";
\ No newline at end of file
<template>
<div class="container">
<div class="cul-hd">
<div class="cul-hd-rec">
<h4 class="cul-hd-rec-title">{{ payStateTxt }}</h4>
<!-- <small class="cul-hd-rec-sub"></small> -->
</div>
<card title="1" footer="1">
<div class="cul-hd-card-body">
<div class="cul-tip">
订单将在1个小时后关闭
</div>
</div>
<cr-button type="warning" size="large" block slot="footer" @click="pay">
立即支付
</cr-button>
</card>
</div>
</div>
</template>
<script>
import Card from "@/components/Card";
export default {
name: "ConsultantState",
components: {
Card
},
data() {
return {
payState: 1
};
},
computed: {
payStateTxt() {
return this.payState === 1 ? "支付中" : "已支付";
}
},
mounted() {},
methods: {
pay() {}
}
};
</script>
<style lang="less" src="./index.less" scoped></style>
......@@ -22,28 +22,19 @@
为了给您提供更精准的保险定制服务,请花1分钟填写问卷,让顾问更了解您。
</div>
</div>
<cr-button
type="warning"
size="large"
block
slot="footer"
@click="$router.push('/consultant/question')"
>
<cr-button type="warning" size="large" block slot="footer" @click="startQuestion">
开始填写问卷
</cr-button>
</card>
</div>
<tabbar />
</div>
</template>
<script>
import Tabbar from "@/components/Tabbar";
import Card from "@/components/Card";
export default {
name: "ConsultantSuccess",
components: {
Tabbar,
Card
},
data() {
......@@ -55,7 +46,12 @@ export default {
]
};
},
mounted() {}
mounted() {},
methods: {
startQuestion() {
this.$parent.changeQuestion();
}
}
};
</script>
<style lang="less" src="./index.less" scoped></style>
<template>
<div class="container">
<div class="cul-hd">
<img src="../../assets/logo-top.png" alt="logo" class="cul-hd-logo" />
<div class="cul-hd-rec">
<h4 class="cul-hd-rec-title">最高节省50%保费</h4>
<small class="cul-hd-rec-sub">帮你量身选保险</small>
</div>
<div class="cul-hd-card">
<div class="cul-hd-card-title">您将获得的服务</div>
<div class="cul-hd-service">
<div class="cul-hd-service-item" v-for="(item, index) in serviceList" :key="index">
<svg-icon :icon-class="item.icon" />
<h5>{{ item.title }}</h5>
<p>{{ item.sub }}</p>
</div>
</div>
<div class="cul-hd-stock">
<h4 class="cul-hd-stock-title">
还剩
<strong>126</strong>
</h4>
<div class="cul-hd-progress">
<cr-progress
:show-pivot="false"
stroke-width="6"
color="#FFC842"
track-color="#F9F3F3"
:percentage="25"
<div>
<buy v-if="orderState <= 1" :state="orderState" />
<success v-if="orderState === 3 && isLogin && !showQuestion" />
<exclusive
v-if="(orderState === 4 || orderState === 5) && isLogin"
:has-suggestion="orderState === 5"
/>
</div>
</div>
<div class="cul-hd-card-foot">
<cr-button type="warning" block @click="$router.push('/consultant/success')">
0.99元聘请
</cr-button>
<cr-tag class="cul-hd-discount" shape="round">
<strong>限时优惠</strong>
<del>
<span>原价</span>
<em>199</em>
<span></span>
</del>
</cr-tag>
</div>
</div>
</div>
<div class="cul-det">
<card title="想买保险,你是不是也有这些疑问?">
<cr-image src="@/assets/images/consultant/intro.png" width="100%" height="auto" />
</card>
<card title="芒果保险·1对1保险顾问来帮您?">
<div class="cul-odds-sign">
<div class="cul-odds-sign-item" v-for="(item, index) in oddsList" :key="index">
<svg-icon :icon-class="item.icon" />
<h5>{{ item.title }}</h5>
<p v-for="(it, index) in item.sub" :key="index">{{ it }}</p>
</div>
</div>
<div class="cul-odds-list">
<div class="cul-odds-list-item" v-for="(item, index) in oddsInsureList" :key="index">
<div class="cul-odds-list-title">
<i class="cul-odds-list-title-icon">{{ index + 1 }}</i>
<span class="cul-odds-list-title-txt">{{ item.title }}</span>
</div>
<div class="cul-odds-list-content">
<div class="cul-odds-list-content-item" v-for="(it, idx) in item.children" :key="idx">
<div class="cul-odds-list-content-title">
<svg-icon icon-class="check-circle" />
{{ it[0] }}
</div>
<div class="cul-odds-list-content-txt">{{ it[1] }}</div>
</div>
</div>
</div>
</div>
</card>
<cps-qa :qa-data="qaInfo" :more="false" />
</div>
<question v-if="showQuestion && isLogin" />
<tabbar />
</div>
</template>
<script>
import Tabbar from "@/components/Tabbar";
import Card from "@/components/Card";
import Collapse from "@/components/Collapse";
import CpsQa from "../Goods/Detail/modules/CpsQA";
import Buy from "./Buy";
import Success from "./Success";
import Question from "./Question";
import Exclusive from "./Exclusive";
import { mapState } from "vuex";
import localStorage from "@/service/localStorage";
import { getCulOrder } from "@/api/consultant";
export default {
name: "Consultant",
components: {
Tabbar,
Card,
CpsQa,
// eslint-disable-next-line
Collapse
Buy,
Success,
Exclusive,
Question
},
data() {
return {
serviceList: [
{ icon: "team", title: "资深", sub: "保险精算团队" },
{ icon: "card", title: "专属", sub: "保险顾问" },
{ icon: "computer", title: "全程", sub: "一站式服务" }
],
oddsList: [
{ icon: "ticket-shadow", title: "省钱", sub: ["最高节省", "50%保费"] },
{ icon: "shield-shadow", title: "放心", sub: ["中立客观", "量身定制"] },
isLogin: localStorage.get("mongoToken"),
showQuestion: false,
orderInfo: [
{
icon: "ok-shadow",
title: "专业",
sub: ["条款解读", "有效投保", "协助理赔"]
consultantOrderNo: "",
state: 0
}
],
oddsInsureList: [
{
title: "投保前",
children: [
["全方位评估:", "360°筛查、识别、评估您的家庭风险"],
[
"量身筛选:",
"根据您的自身情况,分析对比几百款产品,选出最适合的保障方案,最高节省50%保费"
],
["保单诊断:", "全面评估已有保单,中立、客观的给您提供针对性的意见 "]
]
};
},
{
title: "投保中",
children: [
["条款解读:", "为您解释复杂难懂的条款"],
["有效投保:", "为您做好健康告知,做到有效投保"]
]
},
{
title: "省钱",
children: [["协助理赔:", "申请理赔时,理赔专家全程协助"]]
}
],
qaInfo: [
{
q: "有了社保,还需要买保险吗?",
a: `<p style="margin-bottom: 5px;">需要的。社保是基础保障,优势是覆盖范围广,劣势是抵御风险能力有限,社保报销外的自付部分,可以用商业保险来保障。</p>
<p style="margin-bottom: 5px;">比如【百万医疗险】的作用是补充社保,报销因大病造成的高额医疗负担;</p>
<p style="margin-bottom: 5px;">比如【重大疾病险】的作用是弥补因病造成的收入损失、维持家庭正常运转的成本;</p>
<p style="margin-bottom: 5px;">比如【意外险】的作用是保障意外风险,弥补家庭劳动力确实造成的收入损失。</p>
<p style="margin-bottom: 5px;">比如【寿险】的作用是身故赔付,是对家庭责任的延续。</p>
`
},
{
q: "我是小白,买保险应该怎么买?",
a: `<p style="margin-bottom: 5px;">健康类保险最基本的分为【医疗险】【重疾险】【意外险】【定期寿险】四类。</p>
<p style="margin-bottom: 5px;">【医疗险】通常需要提供“医疗票据”实报实销,赔付的保险金保障了因“疾病”、“意外”产生的医疗费用。</p>
<p style="margin-bottom: 5px;">【重疾险】通常需要提供“确诊证明”一次性获得赔付的保险金,前提是罹患的重大疾病在合同约定内。</p>
<p style="margin-bottom: 5px;">【意外险】通常需要提供“身故证明”或“致残证明”获得赔付的保险金,前提是“身故”、“致残”是因意外事件导致。</p>
<p style="margin-bottom: 5px;">【定期寿险】通常需要提供“身故证明”一次性赔付,赔付的保险金在一定程度上,缓解了家庭因被保人身故导致的经济压力。</p>
`
computed: {
orderState() {
return this.orderInfo[0].state;
},
{
q: "百万医疗险和重大疾病险有什么区别?",
a: `<p style="margin-bottom: 5px;">【医疗险】和【重疾险】的区别主要有2种。</p>
<p style="margin-bottom: 5px;">一、【医疗险】是报销型,合理医疗费花多少报多少。<br />
【重疾险】是给付型,确诊后即可获得赔付,买多少保额赔多少钱。</p>
<p style="margin-bottom: 5px;"> 二、【医疗险】的本质是应对医疗支出。<br />
【重疾险】的本质是弥补因病导致的收入损失。</p>
`
...mapState(["isShowLogin"])
},
{
q: "我是中低收入,应该怎么买保险?",
a: `<p style="margin-bottom: 5px;">对于大部分家庭来讲,每年比较合理的保费支出占可支配收入的5%~10%。</p>
<p style="margin-bottom: 5px;">低收入家庭:建议配置【医疗险】+【意外险】</p>
<p style="margin-bottom: 5px;">中收入家庭:建议酌情配置【医疗险】+【重疾险】+【意外险】</p>
<p style="margin-bottom: 5px;">有条件的家庭:可以配置【高端医疗险】+【重疾险】+【意外险】+【寿险】</p>`
watch: {
isShowLogin(val) {
if (!val) {
this.isLogin = localStorage.get("mongoToken");
}
}
},
{
q: "“消费型保险”和“返还型保险”是什么意思?",
a: `<p style="margin-bottom: 5px;">简单讲,“消费型保险”在合同到期后不返还保费,“返还型保险”在合同到期后返还保费。</p>
<p style="margin-bottom: 5px;">【消费型保险】重点在“保障”,合同期内发生风险,保险公司赔偿保险金,合同期外发生风险,保险公司不赔偿也不退回保费。</p>
<p style="margin-bottom: 5px;">【返还型保险】重点在“返还”,合同期内发生风险,保险公司赔偿保险金,合同到期未赔偿,保险公司退回保费。</p>
<p style="margin-bottom: 5px;">两种类型的保险各有优势,而且“返回型保险”种类繁多,建议投保人咨询“闪电保险1对1保险顾问”进行详细了解。</p>
`
mounted() {
this.getOrderInfo();
},
{
q: "医疗险可以重复购买吗?",
a: `<p style="margin-bottom: 5px;">不建议重复购买。</p>
<p style="margin-bottom: 5px;">医疗险属于报销型,原则上报销后的医疗费不得高于已支付的医疗费。</p>
<p style="margin-bottom: 5px;">医疗险在报销时,通常由一家保险公司报销,如果达到报销额度上限还未报销完,且购买其他医疗险,可由第二家保险公司接着报销。</p>
<p style="margin-bottom: 5px;">现在常见的【百万医疗险】保额可达600万,基本上可以覆盖所有的医疗费用。</p>`
methods: {
// 1-待支付,3-支付成功,4-问卷收集完成,方案配置中,5-方案配置完成, -1 -支付失败订单关闭,-2 -支付超过1小时订单关闭,-3 -订单关闭
async getOrderInfo() {
if (!this.isLogin) return;
this.showQuestion = false;
const res = await getCulOrder();
if (res) {
this.orderInfo = res;
}
]
};
},
mounted() {}
changeQuestion() {
this.showQuestion = true;
}
}
};
</script>
<style lang="less" src="./index.less" scoped></style>
<template functional>
<div class="ai-test">
<div class="ai-test-tip">
<h5>不知道怎么买保险</h5>
<small>试一试智能风险评测,推荐最适合你的保险</small>
</div>
<cr-row class="ai-test-cell" type="flex" align="center">
<cr-col span="5" class="ai-test-cell-image">
<cr-image width="60px" height="68px" src="@/assets/images/goods/ai-mongo.png" />
</cr-col>
<div class="ai-test-cell-title">
<h5>智能<span>风险测评</span></h5>
<small>AI小果:为您提供30s快速测评</small>
</div>
<div class="ai-test-cell-btn">
<cr-button type="warning">开始测评</cr-button>
</div>
</cr-row>
</div>
</template>
<script>
export default {
name: "AiTestTip"
};
</script>
<style lang="less" scoped>
@import "../../../style/var.less";
@import "../../../style/mixins.less";
.ai-test {
padding: 20px 16px 25.5px;
&-tip {
text-align: center;
.cell-title-mixin();
margin-bottom: @padding-md;
}
&-cell {
background-color: @white;
border-radius: @border-radius-md;
padding: 0 0 0 @padding-xs;
height: 72px;
&-image {
align-self: flex-end;
.cr-image {
display: block;
margin: 0 auto;
}
}
&-title {
padding: 8px 10px 0 5px;
.cell-title-mixin();
h5 {
margin: 0;
}
span {
color: @orange-dark;
font-weight: bold;
}
}
&-btn {
width: 76px;
.cr-button {
font-size: @button-default-font-size !important;
height: @button-default-height !important;
line-height: @button-default-line-height !important;
border-radius: @border-radius-sm !important;
}
}
}
}
</style>
......@@ -36,7 +36,29 @@ export default {
return {
active: 0,
showLayer: false,
goodsList: []
goodsList: [],
goodsLists: [
{
title: "住院医疗险",
sub: "报销医药费,有无社保均可保",
children: []
},
{
title: "重大疾病险",
sub: "责任内疾病确诊即赔",
children: []
},
{
title: "意外伤害险",
sub: "意外保障无等待期",
children: []
},
{
title: "人寿保险",
sub: "家庭顶梁柱必备",
children: []
}
]
};
},
mounted() {
......
......@@ -42,9 +42,9 @@
* @return:
*/
import { loginByPhone, getwxOpenId } from "@/api/user";
import { placeOrder } from "@/api/order";
import { placeOrder } from "@/api/product";
import cfg from "@/config";
import { payByWay } from "@/service/pay.service";
import { payByWay } from "@/service/pay";
let pollTimer = null;
export default {
name: "paytest",
......@@ -60,49 +60,49 @@ export default {
},
insuredOrderInfo: {
insuredUserInfo: {
phoneNo: "13209654413",
userInfoSecId: "commodo",
userName: "罗刚",
idNo: "566254180010306614",
phoneNo: "15715416416",
userName: "龚秀兰",
idNo: "640181198708118231",
longTerm: false,
validEnd: "1978-11-18",
relation: "1",
socialSecurity: false,
email: "s.yfyviye@mxxv.ki",
annualIncome: "17159",
validEnd: "2021-03-15",
relation: "2",
socialSecurity: true,
email: "r.icj@crtzzkdr.is",
annualIncome: "71067",
addressCode: "110100",
addressDetail: "海外",
occupation: "5",
height: 169,
weight: 58,
addressDetail: "六安市",
occupation: "7",
height: 183,
weight: 66,
bankCardCode: "ICBC",
bankCardNo: "6220549771082240618"
bankCardNo: "1815137475347541839"
},
productNo: "1",
productNo: "HTYLX001",
holderUserInfo: {
phoneNo: "13499177270",
userInfoSecId: "eu in",
userName: "崔静",
idNo: "16479119920330003X",
longTerm: false,
validEnd: "1985-09-23",
socialSecurity: false,
email: "n.ata@ueccvun.bz",
annualIncome: "35555",
phoneNo: "15664415945",
userName: "郭平",
idNo: "640181198708118231",
longTerm: true,
validEnd: "2021-12-03",
socialSecurity: true,
email: "y.dcqoic@bkfygg.fo",
annualIncome: "50401",
addressCode: "110100",
addressDetail: "白城",
occupation: "1",
height: 186,
weight: 54,
addressDetail: "通化",
occupation: "3",
height: 169,
weight: 66,
bankCardCode: "ICBC",
bankCardNo: "667782802278796"
bankCardNo: "9397487291495249077"
},
productItem: {
insuredAmount: "30万",
policyPeriod: "至60岁",
paymentPeriod: "20年"
},
insuredAmount: "57",
policyPeriod: "26",
paymentType: 4,
paymentPeriod: "et in",
effectiveDate: "2003-07-06 23:11:44",
autoRenewPolicy: true
effectiveDate: "2020-08-16 12:44:18",
autoRenewPolicy: false
},
orderInfo: {},
tradeType: "",
......@@ -191,7 +191,7 @@ export default {
};
if (tradeType === "JSAPI") {
payInfo = res.data.payInfo;
payInfo.appId = cfg.wxAppId;
// payInfo.appId = cfg.wxAppId;
}
payByWay(tradeType, payInfo).then(() => {
this.payBack = 1;
......
......@@ -63,6 +63,11 @@ module.exports = {
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]@qg[\\/]_?cherry-ui(.*)/ // in order to adapt to cnpm
},
// svg: {
// name: "chunk-svg",
// priority: 15,
// test: resolve("src/assets/icons/svg")
// },
commons: {
name: "chunk-commons",
test: resolve("src/components"), // can customize your rules
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment