Commit 07fa0346 authored by 郝聪敏's avatar 郝聪敏

feature: 添加智能测评

parent 94879c04
...@@ -2,6 +2,15 @@ import good01 from "@/assets/images/goods/goods-01.png"; ...@@ -2,6 +2,15 @@ import good01 from "@/assets/images/goods/goods-01.png";
import good02 from "@/assets/images/goods/goods-02.png"; import good02 from "@/assets/images/goods/goods-02.png";
import good03 from "@/assets/images/goods/goods-03.png"; import good03 from "@/assets/images/goods/goods-03.png";
import good04 from "@/assets/images/goods/goods-04.png"; import good04 from "@/assets/images/goods/goods-04.png";
import medical_closed from "@/assets/images/user/medical_closed@2x.png";
import casualty_closed from "@/assets/images/user/casualty_closed@2x.png";
import illness_closed from "@/assets/images/user/illness_closed@2x.png";
import life_closed from "@/assets/images/user/life_closed@2x.png";
import medical from "@/assets/images/user/medical@2x.png";
import casualty from "@/assets/images/user/casualty@2x.png";
import illness from "@/assets/images/user/illness@2x.png";
import life from "@/assets/images/user/life@2x.png";
export default [ export default [
{ {
title: "住院医疗险", title: "住院医疗险",
...@@ -16,7 +25,12 @@ export default [ ...@@ -16,7 +25,12 @@ export default [
glory: "好评榜第1名", glory: "好评榜第1名",
price: "0", price: "0",
unit: "", unit: "",
allow: true allow: true,
termType: "short",
icon_closed: medical_closed,
icon: medical,
guarantee_title: "医疗保障",
guarantee_sub: "看病报销医药费,最高600万"
} }
] ]
}, },
...@@ -25,7 +39,7 @@ export default [ ...@@ -25,7 +39,7 @@ export default [
sub: "责任内疾病确诊即赔", sub: "责任内疾病确诊即赔",
children: [ children: [
{ {
id: 1, id: 2,
itype: "cii", itype: "cii",
img: good02, img: good02,
title: "万家保·重疾轻症险", title: "万家保·重疾轻症险",
...@@ -33,7 +47,28 @@ export default [ ...@@ -33,7 +47,28 @@ export default [
glory: "", glory: "",
price: "3", price: "3",
unit: "首月", unit: "首月",
allow: true allow: true,
termType: "short",
icon_closed: illness_closed,
icon: illness,
guarantee_title: "重疾保障",
guarantee_sub: "100种重症+40种轻症"
},
{
id: 3,
itype: "cii",
img: good02,
title: "康惠保2020终身重疾险",
sub: "100种重疾+40种轻症",
glory: "",
price: "3",
unit: "首月",
allow: true,
termType: "long",
icon_closed: illness_closed,
icon: illness,
guarantee_title: "重疾保障",
guarantee_sub: "100种重症+40种轻症"
} }
] ]
}, },
...@@ -42,7 +77,7 @@ export default [ ...@@ -42,7 +77,7 @@ export default [
sub: "意外保障无等待期", sub: "意外保障无等待期",
children: [ children: [
{ {
id: 1, id: 4,
itype: "ai", itype: "ai",
img: good03, img: good03,
title: "万家保·综合意外险", title: "万家保·综合意外险",
...@@ -50,7 +85,12 @@ export default [ ...@@ -50,7 +85,12 @@ export default [
glory: "开车必备", glory: "开车必备",
price: "0", price: "0",
unit: "", unit: "",
allow: true allow: true,
termType: "short",
icon_closed: casualty_closed,
icon: casualty,
guarantee_title: "意外保障",
guarantee_sub: "意外风险覆盖全,最高100万保额"
} }
] ]
}, },
...@@ -59,7 +99,7 @@ export default [ ...@@ -59,7 +99,7 @@ export default [
sub: "家庭顶梁柱必备", sub: "家庭顶梁柱必备",
children: [ children: [
{ {
id: 1, id: 5,
itype: "li", itype: "li",
img: good04, img: good04,
title: "华贵大麦2020定期寿险", title: "华贵大麦2020定期寿险",
...@@ -67,7 +107,12 @@ export default [ ...@@ -67,7 +107,12 @@ export default [
glory: "", glory: "",
price: "0", price: "0",
unit: "", unit: "",
allow: true allow: true,
termType: "long",
icon_closed: life_closed,
icon: life,
guarantee_title: "人寿保障",
guarantee_sub: "最高350万保额,顶梁柱必备"
} }
] ]
} }
......
import req from "@/service/http";
// 查询订单列表
export const getPolicyList = () => {
return req.get("policy_order/list");
};
// 查询订单详情
export const addPolicyDetail = param => {
return req.post("user/info", param);
};
...@@ -25,7 +25,27 @@ export const getCaptchaImg = param => { ...@@ -25,7 +25,27 @@ export const getCaptchaImg = param => {
return req.post("captcha/image", param); return req.post("captcha/image", param);
}; };
// 获取图形验证码 // 获取用户信息
export const getUserInfo = () => { export const getUserInfo = () => {
return req.get("user/me"); return req.get("user/me");
}; };
// 查询家人列表
export const getFamilyList = () => {
return req.get("user/info/list");
};
// 新增个人信息
export const addFamily = param => {
return req.post("user/info", param);
};
// 修改个人信息
export const updateFamily = param => {
return req.post("/user/info/update", param);
};
// 修改个人信息
export const delFamily = param => {
return req.post("/user/info/delete", param);
};
import cherry from "@qg/cherry-ui";
const { Notify } = cherry;
export default {
methods: {
onFailed(errorInfo) {
Notify(errorInfo?.errors?.[0]?.message || '校验失败')
}
}
};
\ No newline at end of file
...@@ -14,6 +14,11 @@ const routes = [ ...@@ -14,6 +14,11 @@ const routes = [
name: "Home", name: "Home",
component: () => import("../views/Home/index.vue") component: () => import("../views/Home/index.vue")
}, },
{
path: "/home/smart-measure",
name: "SmartMeasure",
component: () => import("../views/Home/SmartMeasure/index.vue")
},
{ {
path: "/goods", path: "/goods",
name: "Goods", name: "Goods",
...@@ -69,6 +74,11 @@ const routes = [ ...@@ -69,6 +74,11 @@ const routes = [
name: "Family", name: "Family",
component: () => import("../views/User/Family/index.vue") 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", path: "/user/help-center",
name: "Family", name: "Family",
......
//引入axios //引入axios
import store from "@/store"; import store from "@/store";
import axios from "axios"; import axios from "axios";
import { Notify } from "@qg/cherry-ui"; import cherry from "@qg/cherry-ui";
import config from "../config"; import config from "../config";
import localStorage from "./localStorage"; import localStorage from "./localStorage";
const ERR_MESSAGE_MAP = {
status: {
400: "错误请求",
401: "未授权,请重新登录",
403: "拒绝访问",
404: "请求错误,未找到该资源",
405: "请求方法未允许",
408: "请求超时",
500: "服务器端出错",
501: "网络未实现",
502: "网络错误",
503: "服务不可用",
504: "网络超时",
505: "http版本不支持该请求"
}
};
const { Notify } = cherry;
const CancelToken = axios.CancelToken; const CancelToken = axios.CancelToken;
let pending = {}; let pending = {};
let reqNum = 0; let reqNum = 0;
...@@ -40,7 +57,7 @@ axios.interceptors.request.use( ...@@ -40,7 +57,7 @@ axios.interceptors.request.use(
config.cancelToken = new CancelToken(c => (pending[config.url] = c)); config.cancelToken = new CancelToken(c => (pending[config.url] = c));
// 添加token // 添加token
const token = localStorage.get("token"); const token = localStorage.get("mongoToken");
if (token) { if (token) {
config.headers["x-auth-token"] = token; config.headers["x-auth-token"] = token;
} }
...@@ -56,112 +73,35 @@ axios.interceptors.request.use( ...@@ -56,112 +73,35 @@ axios.interceptors.request.use(
axios.interceptors.response.use( axios.interceptors.response.use(
response => { response => {
afterRequest(); afterRequest();
delete pending[response.config.url]; delete pending[response.config.url];
if (response.data.code === "0") { if (response.data.code === "0") return response.data.data;
return response.data.data;
}
Notify({ type: "danger", message: response.data.msg || "后端服务异常" }); Notify({ type: "danger", message: response.data.msg || "后端服务异常" });
return Promise.reject(response.data);
}, },
err => { err => {
afterRequest(); afterRequest();
if (err && err.response) {
switch (err.response.status) { // 判断是否取消请求
case 400: if (err.message === "取消重复请求") {
err.message = "错误请求"; const res = {
break; status: 409,
case 401: data: {}
err.message = "未授权,请重新登录"; };
break; return Promise.resolve(res);
case 403: }
err.message = "拒绝访问";
break; // 错误提示
case 404: if (err.response) {
err.message = "请求错误,未找到该资源"; err.message = ERR_MESSAGE_MAP.status[err.response.status] || `连接错误${err.response.status}`;
break;
case 405:
err.message = "请求方法未允许";
break;
case 408:
err.message = "请求超时";
break;
case 500:
err.message = "服务器端出错";
break;
case 501:
err.message = "网络未实现";
break;
case 502:
err.message = "网络错误";
break;
case 503:
err.message = "服务不可用";
break;
case 504:
err.message = "网络超时";
break;
case 505:
err.message = "http版本不支持该请求";
break;
default:
err.message = `连接错误${err.response.status}`;
}
} else { } else {
if (err.message == "取消重复请求") { err.message = "连接到服务器失败";
err.response = {};
err.response.status = 409;
err.response.data = {};
return Promise.resolve(err.response);
} else {
err.message = "连接到服务器失败";
}
} }
afterRequest();
Notify({ type: "danger", message: err.message }); Notify({ type: "danger", message: err.message });
return Promise.resolve(err.response);
return Promise.reject(err.response);
} }
); );
export default { export default axios;
axios,
//get请求
get(url, params = {}) {
return new Promise((resolve, reject) => {
axios({
method: "get",
// url: url + "?" + qs.stringify(params),
url: url,
params,
headers: {
"Content-Type": "application/json",
"x-auth-token": localStorage.getItem("mongoToken") || null
}
})
.then(res => {
resolve(res);
})
.catch(e => {
reject(e);
});
});
},
//post请求
post(url, params = {}) {
return new Promise((resolve, reject) => {
axios({
method: "post",
url,
data: params,
headers: {
"Content-Type": "application/json",
"x-auth-token": localStorage.getItem("mongoToken") || null
}
})
.then(res => {
resolve(res);
})
.catch(e => {
reject(e);
});
});
}
};
import Vue from "vue"; import Vue from "vue";
import Vuex from "vuex"; import Vuex from "vuex";
import user from "./modules/user";
Vue.use(Vuex); Vue.use(Vuex);
...@@ -31,5 +32,7 @@ export default new Vuex.Store({ ...@@ -31,5 +32,7 @@ export default new Vuex.Store({
commit("setIsShowLogin", args); commit("setIsShowLogin", args);
} }
}, },
modules: {} modules: {
user
}
}); });
import GOODS_LIST from "@/api/goodsList.mock";
import { getUserInfo, getFamilyList } from "@/api/user";
import { getPolicyList } from "@/api/policy";
const CONSTANT = {
avatar: {
man: "../../../assets/images/user/man@2x.png",
woman: "../../../assets/images/user/woman@2x.png"
},
relation: ["本人", "父母", "配偶", "子女"]
};
function getReletion(relation, gender) {
let result = "";
if ([1, 3].includes(+relation)) {
if (+relation === 1) {
result = +gender ? "父亲" : "母亲";
} else {
result = +gender ? "儿子" : "女儿";
}
} else {
result = CONSTANT.relation[+relation];
}
return result;
}
export default {
namespaced: true,
state: {
familyList: [],
userInfo: {
name: "未登录",
phoneNoMask: "点击登录",
avatar: "../../assets/images/user/avatar@2x.png",
auth: false
}
},
mutations: {
setFamilyList(state, value) {
state.familyList = value;
},
setUserInfo(state, value) {
state.userInfo = value;
}
},
actions: {
async setFamilyList({ commit }) {
let familyList = await getFamilyList();
const policyList = await getPolicyList();
familyList = familyList.concat(familyList);
// todo 家人保单列表筛选
const result = familyList.map(family => ({
...family,
avatar: +family.gender === 0 ? CONSTANT.avatar.man : CONSTANT.avatar.woman,
relation: getReletion(family.relation, family.gender),
policyList: GOODS_LIST.map(goods => {
// todo 家人保单列表推荐
const filterPolicyList = policyList
.map(policy => {
const goodsChild = goods.children.find(child => child.id === +policy.productNo) || {};
return {
...policy,
...goodsChild
};
})
.filter(policy => policy.insuredUserSecId === family.userInfoSecId && policy.id)
.sort((a, b) => a.termType > b.termType);
return filterPolicyList?.[0] || goods.children[0];
})
}));
commit("setFamilyList", result);
},
async setUserInfo({ commit }) {
const userInfo = await getUserInfo();
commit("setUserInfo", userInfo);
}
}
};
...@@ -94,7 +94,14 @@ input::-webkit-input-placeholder { ...@@ -94,7 +94,14 @@ input::-webkit-input-placeholder {
.cr-notify { .cr-notify {
font-size: @font-size-14; font-size: @font-size-14;
} }
.table {
.cr-field--error-message {
display: none;
}
.cr-picker {
font-size: 14px;
}.table {
margin: 0; margin: 0;
width: 100%; width: 100%;
thead { thead {
......
@import "../../../style/index.less";
.measure {
box-sizing: border-box;
min-height: 100%;
background: #EDEDED;
padding: 20px 15px;
.measure-dialogue {
margin-bottom: 20px;
&-robot {
display: flex;
.Md-robot-avatar {
margin-right: 12px;
width: 40px;
height: 40px;
}
.Md-robot-container {
padding: 14px;
width: 244px;
background: #FFFFFF;
border-radius: 0px 14px 14px 14px;
.Mdr-container-question {
margin-bottom: 4px;
font-size: 16px;
font-weight: 400;
color: #000000;
line-height: 21px;
}
.Mdr-container-progress {
font-size: 12px;
font-weight: 400;
color: #999999;
line-height: 21px;
}
.Mdr-container-component {
display: flex;
justify-content: space-between;
margin-top: 10px;
.Mdrc-component-box {
position: relative;
.Mdrcc-box-bg {
margin-top: 31px;
width: 102px;
height: 71px;
background: #F6F7F9;
border-radius: 12px;
}
.Mdrcc-box-image {
position: absolute;
bottom: 0;
width: 102px;
height: 102px;
}
}
.Mdrc-component-button {
// width: 100%;
// height: 52px;
background: #FFC842 !important;
// border-radius: 14px;
// font-size: 16px;
// font-weight: 600;
// color: #333333;
// line-height: 22px;
}
}
.Mdrc-component-marriage {
margin-top: 12px;
p {
display: flex;
align-items: center;
margin-bottom: 8px;
padding-left: 13px;
height: 32px;
background: #F6F7FA;
border-radius: 8px;
font-size: 12px;
font-weight: 400;
color: #666666;
line-height: 14px;
}
}
.Mdrc-component-income {
margin-top: 12px;
.Mdrcc-income-item {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
.Mdrcci-item_selected {
background: #FFC842;
color: #333333;
}
p {
display: flex;
align-items: center;
padding-left: 12px;
width: 105px;
height: 32px;
background: #F6F7FA;
border-radius: 8px;
font-size: 12px;
font-weight: 400;
color: #666666;
line-height: 14px;
}
}
.Mdrcc-income-jump {
display: flex;
align-items: center;
padding-left: 12px;
height: 32px;
background: #F6F7FA;
border-radius: 8px;
font-size: 12px;
font-weight: 400;
color: #666666;
line-height: 14px;
}
.Mdrcci-jump_selected {
background: #FFC842;
color: #333333;
}
}
}
}
&-operation {
display: flex;
.Md-operation-back {
display: flex;
justify-content: center;
align-items: center;
margin: 12px 0 0 52px;
width: 95px;
height: 28px;
background: #FFFFFF;
border-radius: 8px;
font-size: 14px;
font-weight: 400;
color: #666666;
line-height: 16px;
}
.Md-operation-submit {
display: flex;
justify-content: center;
align-items: center;
margin: 12px 0 0 20px;
width: 95px;
height: 28px;
background: #FFC842;
border-radius: 8px;
font-size: 14px;
font-weight: 400;
color: #333333;
line-height: 16px;
}
}
&-user {
display: flex;
justify-content: flex-end;
margin-top: 20px;
.Md-user-answer {
display: flex;
justify-content: center;
align-items: center;
margin-right: 12px;
padding: 0 14px;
height: 40px;
background: #FFC842;
border-radius: 14px 0px 14px 14px;
font-size: 16px;
font-weight: 400;
color: #333333;
line-height: 16px;
}
.Md-user-avatar {
width: 40px;
height: 40px;
}
}
}
.measure-loading {
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
margin-top: 40px;
}
}
\ No newline at end of file
<template>
<div ref="measure" class="measure">
<div class="measure-dialogue" v-for="(item, index) in smartMeasure" :key="item.id">
<div class="measure-dialogue-robot">
<cr-image
class="Md-robot-avatar"
width=""
height=""
fit="cover"
src="@/assets/images/user/avatar@2x.png"
/>
<div class="Md-robot-container">
<p class="Mdr-container-question">{{ item.question }}</p>
<p class="Mdr-container-progress">{{ item.id + "/" + dataList.length }}</p>
<component
v-if="!item.answer || index === dataList.length - 1"
:is="item.component"
:type="item.type"
@select="select"
@submit="submit"
></component>
</div>
</div>
<div class="measure-dialogue-operation">
<div
class="Md-operation-back"
v-show="index === smartMeasure.length - 1 && index !== 0"
@click="goBack(item.id)"
>
上一题
</div>
<div
class="Md-operation-submit"
@click="submit"
v-show="index === dataList.length - 1 && item.answer"
>
确认提交
</div>
</div>
<div class="measure-dialogue-user" v-show="index !== dataList.length - 1 && item.answer">
<p class="Md-user-answer">{{ item.answer }}</p>
<cr-image
class="Md-user-avatar"
width=""
height=""
fit="cover"
src="@/assets/images/user/male@2x.png"
/>
</div>
</div>
<cr-loading v-if="isLoading" class="measure-loading" size="24px">测评报告生成中...</cr-loading>
</div>
</template>
<script>
import Age from "./modules/Age";
import Gender from "./modules/Gender";
import Select from "./modules/Select";
const dataList = [
{
id: 1,
question: "请问您的性别是?",
component: "Gender",
type: "gender",
answer: ""
},
{
id: 2,
question: "请问您的年龄是?",
component: "Age",
type: "age",
answer: ""
},
{
id: 3,
question: "请问您结婚了吗?",
component: "Select",
type: "marrige",
answer: ""
},
{
id: 4,
question: "嘘…悄悄告诉我您月收入是多少?",
component: "Select",
type: "income",
answer: ""
},
{
id: 5,
question: "生活中,您有下面的习惯、环境吗",
component: "Select",
type: "environment",
answer: ""
},
{
id: 6,
question: "您平时的出行方式是什么呢?",
component: "Select",
type: "travel",
answer: ""
},
{
id: 7,
question: "您目前是否还有其他保险呢?",
component: "Select",
type: "insurance",
answer: ""
}
];
export default {
name: "SmartMeasure",
components: {
Age,
Gender,
Select
},
data() {
return {
dataList,
isLoading: false
};
},
computed: {
smartMeasure() {
let result = this.dataList.filter(data => data.answer);
if (result.length < this.dataList.length) {
result.push(this.dataList[result.length]);
}
this.scrollToBottom();
return JSON.parse(JSON.stringify(result));
}
},
methods: {
select(answer) {
const id = this.smartMeasure[this.smartMeasure.length - 1].id;
this.smartMeasure[this.smartMeasure.length - 1].answer = answer;
this.$forceUpdate();
if (this.smartMeasure.length < this.dataList.length) {
setTimeout(() => {
this.dataList = this.dataList.map(data => {
if (data.id === id) data.answer = answer;
return data;
});
}, 600);
}
},
goBack(id) {
this.dataList[id - 1].answer = "";
this.dataList[id - 2].answer = "";
},
submit() {
this.isLoading = true;
this.scrollToBottom();
setTimeout(() => {});
console.log("submit", this.dataList);
},
scrollToBottom() {
this.$nextTick(() => {
const element = document.querySelector(".measure");
document.documentElement.scrollTop = element.scrollHeight;
});
}
}
};
</script>
<style lang="less" src="./index.less" scoped></style>
<template>
<div class="Mdr-container-component">
<cr-button class="Mdrc-component-button" @click="showPicker">
选择出生年份
</cr-button>
<cr-popup v-model="showPopup" position="bottom">
<cr-picker
ref="picker"
show-toolbar
:columns="ageScope"
@confirm="onConfirm"
@cancel="showPopup = false"
/>
</cr-popup>
</div>
</template>
<script>
import male from "@/assets/images/user/male@2x.png";
import female from "@/assets/images/user/female@2x.png";
const ageScope = new Array(120)
.fill(0)
.map((v, index) => 1901 + index + "")
.sort((a, b) => (a === b ? 0 : a < b ? 1 : -1));
const dataList = [
{
image: male,
value: "male"
},
{
image: female,
value: "female"
}
];
export default {
name: "Age",
props: {},
data() {
return {
showPopup: false,
dataList,
ageScope,
refreshed: false
};
},
methods: {
showPicker() {
this.showPopup = true;
if (!this.refreshed) {
this.$refs.picker.refreshColumns();
this.refreshed = true;
}
},
onCancel() {
this.showPopup = false;
},
onConfirm(picker, res) {
this.showPopup = false;
this.$emit("select", res[0]);
}
}
};
</script>
<style lang="less" src="../index.less" scoped></style>
<template>
<div class="Mdr-container-component">
<div
class="Mdrc-component-box"
v-for="item in dataList"
:key="item.value"
@click="select(item.answer)"
>
<div class="Mdrcc-box-bg"></div>
<cr-image class="Mdrcc-box-image" width="" height="" fit="cover" :src="item.image" />
</div>
</div>
</template>
<script>
import male from "@/assets/images/user/male@2x.png";
import female from "@/assets/images/user/female@2x.png";
const dataList = [
{
image: male,
value: "male",
answer: "男神"
},
{
image: female,
value: "female",
answer: "女神"
}
];
export default {
name: "Age",
props: {},
data() {
return {
dataList
};
},
methods: {
select(value) {
this.$emit("select", value);
}
}
};
</script>
<style lang="less" src="../index.less" scoped></style>
<template>
<div class="Mdrc-component-marriage Mdrc-component-income">
<template v-if="type === 'marrige'">
<p v-for="(item, index) in answers[type].data" :key="index" @click="select(item)">
{{ item }}
</p>
</template>
<template v-else>
<div v-for="(list, index) in answers[type].data" :key="index" class="Mdrcc-income-item">
<p
:class="{ 'Mdrcci-item_selected': answers[type].selected.includes(item) }"
v-for="item in list"
:key="item"
@click="select(item, answers[type].type, type)"
>
{{ item }}
</p>
</div>
<p
v-if="!answers[type].required"
class="Mdrcc-income-jump"
:class="{ 'Mdrcci-jump_selected': answers[type].selected.includes('没有,下一题') }"
@click="select('没有,下一题', answers[type].type, type)"
>
没有,下一题
</p>
</template>
</div>
</template>
<script>
const answers = {
marrige: {
data: ["单身贵族爱自由", "幸福的二人世界", "家有儿女初长成"],
type: "radio",
selected: [],
required: true
},
income: {
data: [
["3000元以下", "3000~5000元"],
["5000~8000元", "8000~12000元"],
["12000~18000元", "18000元以上"]
],
type: "radio",
selected: [],
required: true
},
environment: {
data: [
["喝酒", "抽烟/二手烟"],
["熬夜", "不按时吃饭"],
["工作压力大", "不常运动"]
],
type: "radio",
selected: [],
required: true
},
travel: {
data: [
["开车", "公共交通"],
["非机动车", "步行"],
["坐火车", "坐飞机"]
],
tye: "radio",
selected: [],
required: false
},
insurance: {
data: [["社保", "医疗险"], ["重疾险", "意外险"], ["寿险"]],
type: "multi-select",
selected: [],
required: false
}
};
export default {
name: "Select",
props: {
type: {
type: String,
default: "marrige"
}
},
data() {
return {
answers: JSON.parse(JSON.stringify(answers))
};
},
methods: {
select(value, type, name) {
console.log(value, type, name);
if (value === "没有,下一题" && name === "insurance") {
this.answers.insurance.selected = ["没有,下一题"];
this.$emit("select", value);
this.$emit("submit");
return;
}
if (type === "multi-select") {
this.answers[name].selected = this.answers[name].selected.filter(v => v !== "没有,下一题");
this.answers[name].selected.includes(value)
? (this.answers[name].selected = this.answers[name].selected.filter(v => v !== value))
: this.answers[name].selected.push(value);
this.$emit("select", this.answers[name].selected.join(","));
} else {
this.$emit("select", value);
}
}
},
created() {
// this.answers[this.type] = answers[this.type];
console.log(answers.insurance);
}
};
</script>
<style lang="less" src="../index.less" scoped></style>
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
background-color: @background-color; background-color: @background-color;
&-tab { &-tab {
width: 100% !important; width: 100% !important;
& > div { @{deep} & > div {
width: 100% !important; width: 100% !important;
z-index: 100; z-index: 100;
} }
...@@ -200,7 +200,7 @@ ...@@ -200,7 +200,7 @@
&-button { &-button {
width: 296px; width: 296px;
height: 50px; height: 50px;
background: #FFC842; background: #FFC842 !important;
border-radius: 14px; border-radius: 14px;
z-index: 0; z-index: 0;
&:after { &:after {
......
...@@ -9,27 +9,27 @@ ...@@ -9,27 +9,27 @@
<cr-tabbar-item>子女</cr-tabbar-item> <cr-tabbar-item>子女</cr-tabbar-item>
</cr-tabbar> </cr-tabbar>
</cr-sticky> </cr-sticky>
<!-- <policy-item></policy-item> <policy-item></policy-item>
<cr-divider class="policy-divider">我是有底线的</cr-divider> <cr-divider class="policy-divider">我是有底线的</cr-divider>
<insurance-recommend></insurance-recommend> --> <insurance-recommend></insurance-recommend>
<div class="policy-none"> <!-- <div class="policy-none">
<cr-image class="policy-none-image" round width="" height="" :src="policyDefault" /> <cr-image class="policy-none-image" round width="" height="" :src="policyDefault" />
<p class="policy-none-title">暂无保单</p> <p class="policy-none-title">暂无保单</p>
<p class="policy-none-desc">赶紧去看看有哪些精品保险吧</p> <p class="policy-none-desc">赶紧去看看有哪些精品保险吧</p>
</div> </div> -->
</div> </div>
</template> </template>
<script> <script>
import policyDefault from "@/assets/images/policy/policy-default@2x.png"; import policyDefault from "@/assets/images/policy/policy-default@2x.png";
// import InsuranceRecommend from "./modules/InsuranceRecommend"; import InsuranceRecommend from "./modules/InsuranceRecommend";
// import PolicyItem from "./modules/PolicyItem"; import PolicyItem from "./modules/PolicyItem";
export default { export default {
name: "PolicyList", name: "PolicyList",
// components: { components: {
// InsuranceRecommend, InsuranceRecommend,
// PolicyItem PolicyItem
// }, },
data() { data() {
return { return {
active: 0, active: 0,
......
<template> <template>
<div> <div>
<div class="policy-item"> <div class="policy-item" v-for="item in list" :key="item.orderNo">
<div class="policy-item-pro"> <div class="policy-item-pro">
<p class="policy-item-pro-name">国民保·百万医疗险</p> <p class="policy-item-pro-name">国民保·百万医疗险</p>
<p class="policy-item-pro-type policy-item-pro-type_medical">医疗保障</p> <p class="policy-item-pro-type policy-item-pro-type_medical">医疗保障</p>
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
width="" width=""
height="" height=""
fit="cover" fit="cover"
:src="guarantee" src="@/assets/images/policy/guarantee@2x.png"
/> />
</div> </div>
<div class="policy-item"> <div class="policy-item">
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
width="" width=""
height="" height=""
fit="cover" fit="cover"
:src="guarantee" src="@/assets/images/policy/guarantee@2x.png"
/> />
</div> </div>
<div class="policy-item"> <div class="policy-item">
...@@ -117,14 +117,22 @@ ...@@ -117,14 +117,22 @@
</div> </div>
</template> </template>
<script> <script>
import guarantee from "@/assets/images/policy/guarantee@2x.png"; import GOODS_LIST from "@/api/goodsList.mock";
import { getPolicyList } from "@/api/policy";
export default { export default {
name: "InsuranceRecommend", name: "InsuranceRecommend",
data() { data() {
return { return {
guarantee list: []
}; };
},
async created() {
const goodsList = GOODS_LIST.reduce((pre, next) => {
return pre.concat(next.children);
}, []);
let list = await getPolicyList();
this.list = list.map(v => goodsList.find(goods => goods.id === +v.productNo));
} }
}; };
</script> </script>
......
<template>
<div class="family">
<user-family-form type="update" title="修改信息" :information="information"></user-family-form>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import form from "../modules/FamilyForm";
export default {
name: "FamilyDetail",
components: {
userFamilyForm: form
},
data() {
return {
information: {
userInfoSecId: "",
nameMask: "",
idNoMask: "",
socialSecurity: "",
relation: ""
}
};
},
created() {
const information = this.familyList.find(
family => family.userInfoSecId === this.$route.params.id
);
this.information = {
...information,
socialSecurity: information.socialSecurity ? "true" : "false"
};
},
computed: {
...mapState("user", ["familyList"])
},
methods: {
...mapActions("user", ["setFamilyList"])
}
};
</script>
<style lang="less" src="../index.less" scoped></style>
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
&-list { &-list {
border:1px solid transparent; border:1px solid transparent;
margin: 16px 0 20px; margin: 16px 0 0;
&-item { &-item {
display: flex; display: flex;
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
height: 16px; height: 16px;
background: #FFEAB7; background: #FFEAB7;
border-radius: 2px 8px 2px 8px; border-radius: 2px 8px 2px 8px;
text-align: center;
font-size: 11px; font-size: 11px;
font-weight: 400; font-weight: 400;
color: #EAAD1A; color: #EAAD1A;
...@@ -68,19 +69,21 @@ ...@@ -68,19 +69,21 @@
&_overlay { &_overlay {
border-radius: 17px; border-radius: 17px;
margin-top: 35px; margin-top: 35px;
box-shadow: 0px -5px 25px 0px rgba(0,0,0,0.07), 0px -20px 0 -10px #FFFFFF, 0px -25px 25px 0px rgba(0,0,0,0.07), 0px -35px 0 -15px #FFFFFF; box-shadow: 0px -5px 25px 0px rgba(0,0,0,0.07), 0px -20px 0 -10px #FFFFFF, 0px -25px 25px 0px rgba(0,0,0,0.07), 0px -33px 0 -14px #FFFFFF;
} }
} }
}
&-collapse { &-collapse {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin-bottom: 20px;
height: 30px; height: 30px;
background: #FFFFFF; background: #FFFFFF;
border-radius: 14px; border-radius: 14px;
.Fl-collapse-text { &-text {
margin-right: 4px; margin-right: 4px;
font-size: 12px; font-size: 12px;
font-weight: 500; font-weight: 500;
...@@ -88,13 +91,15 @@ ...@@ -88,13 +91,15 @@
line-height: 17px; line-height: 17px;
} }
.Fl-collapse-svg { &-svg {
transform: rotate(180deg); transform: rotate(0deg);
width: 16px; width: 16px;
height: 16px; height: 16px;
&_opened {
transform: rotate(180deg);
}
} }
} }
}
&-form { &-form {
padding: 20px 20px 28px; padding: 20px 20px 28px;
...@@ -227,6 +232,10 @@ ...@@ -227,6 +232,10 @@
font-weight: 600; font-weight: 600;
color: #333333; color: #333333;
line-height: 22px; line-height: 22px;
&_deleted {
margin-top: 15px;
background: #F6F7FA !important;
}
} }
} }
...@@ -246,12 +255,13 @@ ...@@ -246,12 +255,13 @@
.Fc-modal-item { .Fc-modal-item {
display: flex; display: flex;
justify-content: space-between; // justify-content: space-between;
font-size: 12px; font-size: 12px;
color: #333333; color: #333333;
line-height: 30px; line-height: 30px;
span:nth-child(1) { span:nth-child(1) {
width: 65px;
font-weight: 400; font-weight: 400;
} }
......
<template> <template>
<div class="family"> <div class="family">
<p class="family-title">已添加家人</p> <div v-if="familyList.length">
<div class="family-list"> <p class="family-title">已添加家人</p>
<div class="family-list-item family-list-item_overlay"> <div class="family-list" v-if="!isCollapse">
<div class="Fl-item-left"> <div
<cr-image :class="[{ 'family-list-item_overlay': isCollapse && index === 0 }, 'family-list-item']"
class="Fli-left-image" v-for="(item, index) in familyList"
src="../../../assets/images/user/man@2x.png" @click="go(`/user/family/detail/${item.userInfoSecId}`)"
width="" :key="index"
height="" >
/> <div class="Fl-item-left">
<span class="Fli-left-name">王小闹</span> <cr-image class="Fli-left-image" :src="item.avatar" width="" height="" />
<span class="Fli-left-relation">本人</span> <span class="Fli-left-name">{{ item.name }}</span>
<span class="Fli-left-relation">{{ item.relation }}</span>
</div>
<p class="Fl-item-right" v-if="item.auth">已认证</p>
</div> </div>
<p class="Fl-item-right">已认证</p>
</div> </div>
<!-- <div class="family-list-item"> <div class="family-list" v-else>
<div class="Fl-item-left"> <div
<cr-image class="family-list-item_overlay family-list-item"
class="Fli-left-image" @click="go(`/user/family/detail/${familyList[0].userInfoSecId}`)"
src="../../../assets/images/user/man@2x.png" >
width="" <div class="Fl-item-left">
height="" <cr-image class="Fli-left-image" :src="familyList[0].avatar" width="" height="" />
/> <span class="Fli-left-name">{{ familyList[0].name }}</span>
<span class="Fli-left-name">王爸爸</span> <span class="Fli-left-relation">{{ familyList[0].relation }}</span>
<span class="Fli-left-relation">父亲</span> </div>
<p class="Fl-item-right" v-if="familyList[0].auth">已认证</p>
</div> </div>
<p class="Fl-item-right">已认证</p>
</div> </div>
<div class="family-list-item"> <div class="family-collapse" @click="isCollapse = !isCollapse">
<div class="Fl-item-left"> <span class="family-collapse-text">{{ collapseText }}</span>
<cr-image <svg-icon
class="Fli-left-image" icon-class="triangle-down"
src="../../../assets/images/user/woman@2x.png" :class-name="[{ 'family-collapse-svg_opened': !isCollapse }, 'family-collapse-svg']"
width="" />
height=""
/>
<span class="Fli-left-name">王妈妈</span>
<span class="Fli-left-relation">母亲</span>
</div>
<p class="Fl-item-right">已认证</p>
</div> -->
<div class="family-list-collapse">
<span class="Fl-collapse-text">点击收起</span>
<svg-icon icon-class="triangle-down " class-name="Fl-collapse-svg" />
</div> </div>
</div> </div>
<p class="family-title">为家人添加保障</p> <user-family-form type="add" title="为家人添加保障"></user-family-form>
<!-- <p class="family-title">为家人添加保障</p>
<cr-form ref="form" class="family-form" @submit="onSubmit" @failed="onFailed"> <cr-form ref="form" class="family-form" @submit="onSubmit" @failed="onFailed">
<cr-field <cr-field
class="family-form-item" class="family-form-item"
v-model="formData.username" v-model="formData.name"
name="姓名" name="姓名"
label="姓名" label="姓名"
placeholder="请输入投保人姓名" placeholder="请输入投保人姓名"
...@@ -58,11 +51,12 @@ ...@@ -58,11 +51,12 @@
/> />
<cr-field <cr-field
class="family-form-item" class="family-form-item"
v-model="formData.idcard" v-model="formData.idNo"
type="password" type="password"
name="身份证号" name="身份证号"
label="身份证号" label="身份证号"
placeholder="请填写家人身份证号" placeholder="请填写家人身份证号"
:rules="[{ required: true, message: '请填写身份证号' }]"
/> />
<cr-field <cr-field
@click.native="showPopups" @click.native="showPopups"
...@@ -72,6 +66,7 @@ ...@@ -72,6 +66,7 @@
name="与本人的关系" name="与本人的关系"
label="与本人的关系" label="与本人的关系"
placeholder="请选择与本人的关系" placeholder="请选择与本人的关系"
:rules="[{ required: true, message: '请选择与本人的关系' }]"
/> />
<div class="family-form-radio"> <div class="family-form-radio">
<div class="Ff-radio-title"> <div class="Ff-radio-title">
...@@ -85,7 +80,7 @@ ...@@ -85,7 +80,7 @@
<cr-field <cr-field
class="Ff-radio-options" class="Ff-radio-options"
name="社保" name="社保"
:rules="[{ required: true, message: '请填写用户名' }]" :rules="[{ required: true, message: '请选择有无社保' }]"
> >
<cr-radio-btn <cr-radio-btn
class="" class=""
...@@ -98,104 +93,34 @@ ...@@ -98,104 +93,34 @@
<cr-button class="family-form-button" native-type="submit"> <cr-button class="family-form-button" native-type="submit">
生成保障方案 生成保障方案
</cr-button> </cr-button>
</cr-form> </cr-form> -->
<cr-popup v-model="showPopup" position="bottom">
<cr-picker
ref="picker"
show-toolbar
:columns="relations"
@confirm="onConfirm"
@cancel="showPopup = false"
/>
</cr-popup>
<Modal
class="family-modal"
v-model="modal.question"
:closeable="false"
cancel-btn=""
title="我们常说的社保都包括哪些?"
confirm-btn="我知道了"
>
常见的社保包括农村合作医疗(新农合)、城镇居民社保、城镇职工医保、少儿医保等政府主导的基本医疗保障项目,满足最基本的医疗保障要求。
</Modal>
<Modal
v-model="modal.confirm"
:closeable="false"
cancel-btn="取消"
confirm-btn="确认无误"
title="信息确认"
>
<div class="family-confirm-modal">
<div class="Fc-modal-item">
<span>首月保费</span>
<span>1元</span>
</div>
<div class="Fc-modal-item">
<span>次月保费</span>
<span>100.00元/月 (共11期)</span>
</div>
<div class="Fc-modal-item">
<span>次月保费</span>
<span>100.00元/月 (共11期)</span>
</div>
<div class="Fc-modal-item">
<span>次月保费</span>
<span>100.00元/月 (共11期)</span>
</div>
</div>
</Modal>
<Modal
class="family-modal"
v-model="modal.delete"
:closeable="false"
cancel-btn="确认删除"
confirm-btn="继续保留"
title="删除确认"
>确认删除【王大闹】的个人信息吗?为提供全面的家庭保障,建议您保留家庭成员信息。
</Modal>
</div> </div>
</template> </template>
<script> <script>
import CrRadioBtn from "@/components/CrRadioBtn"; import { mapState, mapActions } from "vuex";
import Modal from "@/components/Modal"; import form from "./modules/FamilyForm";
const planOptions = [
{ label: "有社保", value: "1" },
{ label: "无社保", value: "2" }
];
const relations = ["本人", "配偶", "父母", "子女"];
export default { export default {
name: "Family", name: "Family",
components: { components: {
CrRadioBtn, userFamilyForm: form
Modal
}, },
data() { data() {
return { return {
showPopup: false, isCollapse: true
relations,
planOptions,
modal: {
question: false,
confirm: false,
delete: false
},
formData: {
username: "",
idcard: "",
relation: "",
socialSecurity: ""
}
}; };
}, },
computed: {
...mapState("user", ["familyList"]),
collapseText() {
return this.isCollapse ? "点击展开" : "点击收起";
}
},
created() {
this.setFamilyList();
},
methods: { methods: {
async onSubmit() { ...mapActions("user", ["setFamilyList"]),
// console.log('sucess', values);
},
onFailed() {
// console.log('fail', errorInfo);
},
onConfirm(picker, res) { onConfirm(picker, res) {
this.formData.relation = res[0]; this.formData.relation = res[0];
this.showPopup = false; this.showPopup = false;
...@@ -206,6 +131,10 @@ export default { ...@@ -206,6 +131,10 @@ export default {
this.$refs.picker.refreshColumns(); this.$refs.picker.refreshColumns();
this.refreshed = true; this.refreshed = true;
} }
},
go(path) {
console.log(path);
this.$router.push(path);
} }
} }
}; };
......
<template>
<div class="user-family">
<p class="family-title">{{ title }}</p>
<cr-form ref="form" class="family-form" @submit="modal.confirm = true" @failed="onFailed">
<cr-field
class="family-form-item"
v-model="formData.nameMask"
:readonly="readOnlyProperty.nameMask"
name="姓名"
label="姓名"
placeholder="请输入投保人姓名"
:rules="[{ required: true, message: '请填写用户名' }]"
/>
<cr-field
class="family-form-item"
v-model="formData.idNoMask"
:readonly="readOnlyProperty.idNoMask"
type="password"
name="身份证号"
label="身份证号"
placeholder="请填写家人身份证号"
:rules="[{ required: true, message: '请填写身份证号' }]"
/>
<cr-field
@click.native="showPopups"
class="family-form-item"
v-model="formData.relation"
:readonly="true"
name="与本人的关系"
label="与本人的关系"
placeholder="请选择与本人的关系"
:rules="[{ required: true, message: '请选择与本人的关系' }]"
/>
<div class="family-form-radio">
<div class="Ff-radio-title">
<span class="Ffr-title-text">有无社保</span>
<svg-icon
icon-class="doubt"
@click.native="modal.question = true"
class-name="Ffr-title-svg"
/>
</div>
<cr-field class="Ff-radio-options" name="社保">
<cr-radio-btn slot="input" v-model="formData.socialSecurity" :radio-data="planOptions" />
</cr-field>
</div>
<cr-button class="family-form-button" native-type="submit">
{{ saveText }}
</cr-button>
<cr-button class="family-form-button_deleted" @click="modal.delete = true" v-if="isShowDel">
删除成员
</cr-button>
</cr-form>
<Modal
class="family-modal"
v-model="modal.question"
:closeable="false"
@cancel="modal.question = false"
cancel-btn=""
title="我们常说的社保都包括哪些?"
confirm-btn="我知道了"
>
常见的社保包括农村合作医疗(新农合)、城镇居民社保、城镇职工医保、少儿医保等政府主导的基本医疗保障项目,满足最基本的医疗保障要求。
</Modal>
<Modal
v-model="modal.confirm"
:closeable="false"
@confirm="onSubmit"
@cancel="modal.confirm = false"
cancel-btn="取消"
confirm-btn="确认无误"
title="信息确认"
>
<div class="family-confirm-modal">
<div class="Fc-modal-item">
<span v-html="'姓&#12288;&#12288;名:'"></span>
<span>{{ formData.nameMask }}</span>
</div>
<div class="Fc-modal-item">
<span>身份证号:</span>
<span>{{ formData.idNoMask }}</span>
</div>
<div class="Fc-modal-item">
<span>与您关系:</span>
<span>{{ formData.relation }}</span>
</div>
<div class="Fc-modal-item">
<span>有无社保:</span>
<span>{{ formData.socialSecurity === "true" ? "有社保" : "无社保" }}</span>
</div>
</div>
</Modal>
<Modal
class="family-modal"
v-model="modal.delete"
@confirm="modal.delete = false"
@cancel="delFamily"
:closeable="false"
cancel-btn="确认删除"
confirm-btn="继续保留"
title="删除确认"
>确认删除【王大闹】的个人信息吗?为提供全面的家庭保障,建议您保留家庭成员信息。
</Modal>
<cr-popup v-model="showPopup" position="bottom">
<cr-picker
ref="picker"
show-toolbar
:columns="relations"
@confirm="onConfirm"
@cancel="showPopup = false"
/>
</cr-popup>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import formValidMixin from "@/mixins/formValidate.mixin";
import { addFamily, updateFamily, delFamily } from "@/api/user";
import CrRadioBtn from "@/components/CrRadioBtn";
import Modal from "@/components/Modal";
const relations = ["本人", "配偶", "父母", "子女"];
const planOptions = [
{ label: "有社保", value: "true" },
{ label: "无社保", value: "false" }
];
export default {
name: "FamilyForm",
components: {
CrRadioBtn,
Modal
},
mixins: [formValidMixin],
props: {
title: {
type: String,
default: "为家人添加保障"
},
type: {
type: String,
default: "add"
},
information: {
type: Object,
default: () => ({})
}
},
data() {
return {
showPopup: false,
relations,
planOptions,
modal: {
question: false,
confirm: false,
delete: false
},
formData: this.information,
isCollapse: true
};
},
computed: {
...mapState("user", ["familyList"]),
readOnlyProperty() {
if (this.type === "add") return {};
let result = { relation: true };
if (this.formData?.relation === "本人") {
result = {
...result,
...{
nameMask: true,
idNoMask: true
}
};
}
return result;
},
saveText() {
return this.type === "add" ? "生成保障方案" : "保存修改";
},
isShowDel() {
return this.type === "update" && this.formData.relation !== "本人" ? true : false;
}
},
created() {
console.log(this.formData);
},
methods: {
...mapActions("user", ["setFamilyList"]),
async onSubmit() {
this.modal.confirm = false;
// 组件不支持boolean,需转换
const params = {
...this.formData,
socialSecurity: this.formData?.socialSecurity === "true" ? true : false
};
if (this.type === "add") {
await addFamily(params);
} else {
await updateFamily(params);
}
},
onConfirm(picker, res) {
this.formData.relation = res[0];
this.showPopup = false;
},
showPopups() {
if (this.readOnlyProperty.relation) return;
this.showPopup = true;
if (!this.refreshed) {
this.$refs.picker.refreshColumns();
this.refreshed = true;
}
},
async delFamily() {
this.modal.delete = false;
await delFamily();
this.$router.push("/user/family");
}
}
};
</script>
<style lang="less" src="../index.less" scoped></style>
...@@ -117,6 +117,9 @@ ...@@ -117,6 +117,9 @@
&:not(:first-child) { &:not(:first-child) {
margin-left: 25px; margin-left: 25px;
} }
&_placeholder {
margin-right: 65px;
}
&-svg { &-svg {
width: 40px; width: 40px;
height: 40px; height: 40px;
...@@ -137,7 +140,7 @@ ...@@ -137,7 +140,7 @@
border-radius: 3px; border-radius: 3px;
} }
&_fixed { &_fixed {
position: fixed; position: absolute;
right: 36px; right: 36px;
height: 71px; height: 71px;
background: #fff; background: #fff;
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
</div> </div>
</template> </template>
<script> <script>
import { getUserInfo } from "@/api/user"; import { mapState, mapActions } from "vuex";
import customerService from "@/assets/images/user/customer-service@2x.png"; import customerService from "@/assets/images/user/customer-service@2x.png";
import help from "@/assets/images/user/help@2x.png"; import help from "@/assets/images/user/help@2x.png";
import avatar from "@/assets/images/user/avatar@2x.png"; import avatar from "@/assets/images/user/avatar@2x.png";
...@@ -76,12 +76,6 @@ export default { ...@@ -76,12 +76,6 @@ export default {
}, },
data() { data() {
return { return {
userInfo: {
name: "未登录",
phoneNoMask: "点击登录",
avatar,
auth: false
},
avatar, avatar,
customerService, customerService,
help, help,
...@@ -89,10 +83,16 @@ export default { ...@@ -89,10 +83,16 @@ export default {
showLayer: false showLayer: false
}; };
}, },
computed: {
...mapState("user", ["familyList", "userInfo"])
},
async created() { async created() {
this.userInfo = await getUserInfo(); await this.setUserInfo();
await this.setFamilyList();
console.log(this.familyList, this.userInfo);
}, },
methods: { methods: {
...mapActions("user", ["setFamilyList", "setUserInfo"]),
go(path, isOverlay = false) { go(path, isOverlay = false) {
if (isOverlay) { if (isOverlay) {
this.showLayer = true; this.showLayer = true;
......
<template> <template>
<div class="user-family"> <div class="user-family">
<p class="user-family-title">家庭配置保障</p> <p class="user-family-title">家庭配置保障</p>
<div class="user-family-info"> <div class="user-family-info" :class="{ 'user-family-info-item_placeholder': isFixed }">
<!-- <div class="user-family-info-item"> <div
<cr-image class="user-family-info-item"
round @click="activeIndex = index"
width="40px" v-for="(item, index) in familyList"
height="40px" :key="item.id"
fit="cover" >
src="http://desk.fd.zol-img.com.cn/g5/M00/00/07/ChMkJ1ZqMb2IWITEAAbRDaofaNIAAGBHwO3hh0ABtEl380.jpg" <cr-image
/> round
<span class="user-family-info-item-name">王斌</span> width="40px"
<div class="user-family-info-item-divider"></div> height="40px"
</div>--> fit="cover"
src="http://desk.fd.zol-img.com.cn/g5/M00/00/07/ChMkJ1ZqMb2IWITEAAbRDaofaNIAAGBHwO3hh0ABtEl380.jpg"
/>
<span class="user-family-info-item-name">王斌</span>
<div class="user-family-info-item-divider" v-show="index === activeIndex"></div>
</div>
<div <div
class="user-family-info-item" class="user-family-info-item"
:class="{ 'user-family-info-item_fixed': isFixed }" :class="{ 'user-family-info-item_fixed': isFixed }"
@click="go" @click="go('/user/family')"
> >
<svg-icon icon-class="add-family" class-name="user-family-info-item-svg" /> <svg-icon icon-class="add-family" class-name="user-family-info-item-svg" />
<span class="user-family-info-item-name">添加</span> <span class="user-family-info-item-name">添加</span>
</div> </div>
</div> </div>
<div class="user-family-insurance" @click="go"> <div class="user-family-insurance">
<div class="user-family-insurance-item"> <!-- user-family-insurance-item-middle_enable 保障中 -->
<cr-image round width="" height="" class="user-family-insurance-item-left" :src="medical" /> <div class="user-family-insurance-item" v-for="item in policyList" :key="item.id">
<cr-image
round
width=""
height=""
class="user-family-insurance-item-left"
:src="item.productNo ? item.icon : item.icon_closed"
/>
<div class="user-family-insurance-item-middle"> <div class="user-family-insurance-item-middle">
<div class="Ufii-middle-main"> <div class="Ufii-middle-main">
<span class="Ufii-middle-main-title">医疗保障</span> <span class="Ufii-middle-main-title">{{ item.guarantee_title }}</span>
<!-- <span class="status">保障中</span> --> <span class="Ufii-middle-main-status" v-if="item.productNo">保障中</span>
</div> </div>
<div class="Ufii-middle-footer">看病报销医药费,最高600万</div> <div class="Ufii-middle-footer">{{ item.guarantee_sub }}</div>
</div> </div>
<p class="user-family-insurance-item-right">开启保障</p> <p class="user-family-insurance-item-right" v-if="!item.productNo">开启保障</p>
</div> </div>
<div class="user-family-insurance-item"> <!-- <div class="user-family-insurance-item">
<cr-image round width="" height="" class="user-family-insurance-item-left" :src="illness" /> <cr-image round width="" height="" class="user-family-insurance-item-left" :src="illness" />
<div class="user-family-insurance-item-middle"> <div class="user-family-insurance-item-middle">
<div class="Ufii-middle-main"> <div class="Ufii-middle-main">
<span class="Ufii-middle-main-title">重疾保障</span> <span class="Ufii-middle-main-title">重疾保障</span>
<!-- <span class="status">保障中</span> --> <span class="status">保障中</span>
</div> </div>
<div class="Ufii-middle-footer">100种重症+40种轻症</div> <div class="Ufii-middle-footer">100种重症+40种轻症</div>
</div> </div>
...@@ -53,11 +65,10 @@ ...@@ -53,11 +65,10 @@
class="user-family-insurance-item-left" class="user-family-insurance-item-left"
:src="casualty" :src="casualty"
/> />
<!-- user-family-insurance-item-middle_enable 保障中 -->
<div class="user-family-insurance-item-middle"> <div class="user-family-insurance-item-middle">
<div class="Ufii-middle-main"> <div class="Ufii-middle-main">
<span class="Ufii-middle-main-title">意外保障</span> <span class="Ufii-middle-main-title">意外保障</span>
<!-- <span class="Ufii-middle-main-status">保障中</span> --> <span class="Ufii-middle-main-status">保障中</span>
</div> </div>
<div class="Ufii-middle-footer">意外风险覆盖全,最高100万保额</div> <div class="Ufii-middle-footer">意外风险覆盖全,最高100万保额</div>
</div> </div>
...@@ -68,43 +79,48 @@ ...@@ -68,43 +79,48 @@
<div class="user-family-insurance-item-middle"> <div class="user-family-insurance-item-middle">
<div class="Ufii-middle-main"> <div class="Ufii-middle-main">
<span class="Ufii-middle-main-title">人寿保障</span> <span class="Ufii-middle-main-title">人寿保障</span>
<!-- <span class="status">保障中</span> --> <span class="status">保障中</span>
</div> </div>
<div class="Ufii-middle-footer">最高350万保额,顶梁柱必备</div> <div class="Ufii-middle-footer">最高350万保额,顶梁柱必备</div>
</div> </div>
<p class="user-family-insurance-item-right">开启保障</p> <p class="user-family-insurance-item-right">开启保障</p>
</div> </div> -->
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import medical from "@/assets/images/user/medical_closed@2x.png"; import { mapState } from "vuex";
import casualty from "@/assets/images/user/casualty_closed@2x.png";
import illness from "@/assets/images/user/illness_closed@2x.png";
import life from "@/assets/images/user/life_closed@2x.png";
export default { export default {
name: "UserFamily",
data() { data() {
return { return {
medical, isFixed: false,
casualty, activeIndex: 0
illness,
life,
isFixed: false
}; };
}, },
methods: { computed: {
go() { ...mapState("user", ["familyList"]),
this.$emit("go", "", true); policyList() {
// console.log(this.activeIndex, this.familyList[this.activeIndex]?.policyList);
return this.familyList[this.activeIndex]?.policyList;
}
},
watch: {
familyList() {
this.$nextTick(() => {
console.log(this.familyList.length);
const offsetWidth = document.querySelector(".user-family-info").offsetWidth;
const scrollWidth = document.querySelector(".user-family-info").scrollWidth;
this.isFixed = scrollWidth > offsetWidth;
console.log(scrollWidth, offsetWidth, this.isFixed);
});
} }
}, },
mounted() { methods: {
this.$nextTick(() => { go(path) {
const offsetWidth = document.querySelector(".user-family-info").offsetWidth; this.$emit("go", path);
const scrollWidth = document.querySelector(".user-family-info").scrollWidth; }
this.isFixed = scrollWidth > offsetWidth;
console.log(scrollWidth, offsetWidth, this.isFixed);
});
} }
}; };
</script> </script>
......
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