!77 食谱展示界面开发

Merge pull request !77 from 德仔/develop
This commit is contained in:
德仔
2021-02-26 20:16:12 +08:00
committed by Gitee
38 changed files with 1536 additions and 382 deletions

View File

@ -1,68 +1,74 @@
import request from '@/utils/request'
import request from "@/utils/request";
// 查询合同列表
export function listContract(query) {
return request({
url: '/custom/contract/list',
method: 'get',
url: "/custom/contract/list",
method: "get",
params: query
})
});
}
// 查询合同详细
export function getContract(id) {
return request({
url: '/custom/contract/' + id,
method: 'get'
})
url: "/custom/contract/" + id,
method: "get"
});
}
// 新增合同
export function addContract(data) {
return request({
url: '/custom/contract',
method: 'post',
url: "/custom/contract",
method: "post",
data: data
})
});
}
// 修改合同
export function updateContract(data) {
return request({
url: '/custom/contract',
method: 'put',
url: "/custom/contract",
method: "put",
data: data
})
});
}
// 删除合同
export function delContract(id) {
return request({
url: '/custom/contract/' + id,
method: 'delete'
})
url: "/custom/contract/" + id,
method: "delete"
});
}
// 导出合同
export function exportContract(query) {
return request({
url: '/custom/contract/export',
method: 'get',
url: "/custom/contract/export",
method: "get",
params: query
})
});
}
export function getFile(id) {
return request({
url: '/custom/contract/file/' + id,
method: 'get',
})
url: "/custom/contract/file/" + id,
method: "get",
headers: {
isToken: false
}
});
}
export function signContract(data) {
return request({
url: '/custom/contract/sign',
method: 'post',
data: data
})
url: "/custom/contract/sign",
method: "post",
data: data,
headers: {
isToken: false
}
});
}

View File

@ -0,0 +1,31 @@
import request from "@/utils/request";
export function getRecipesPlans(id) {
return request({
url: "/wap/recipes/plans/" + id,
method: "get",
headers: {
isToken: false
}
});
}
export function getHealthyInfo(id) {
return request({
url: "/wap/healthyInfo/" + id,
method: "get",
headers: {
isToken: false
}
});
}
export function getRecipesMenuInfoApi(id) {
return request({
url: "/wap/recipes/menu/" + id,
method: "get",
headers: {
isToken: false
}
});
}

View File

@ -1,43 +1,52 @@
import router from './router'
import store from './store'
import {Message} from 'element-ui'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import {getToken} from '@/utils/auth'
import router from "./router";
import store from "./store";
import { Message } from "element-ui";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { getToken } from "@/utils/auth";
NProgress.configure({showSpinner: false})
NProgress.configure({ showSpinner: false });
const whiteList = ['/login', '/auth-redirect', '/bind', '/register', '/question', '/subhealthyInvestigation']
const whiteList = [
"/login",
"/auth-redirect",
"/bind",
"/register",
"/question",
"/subhealthyInvestigation"
];
router.beforeEach((to, from, next) => {
NProgress.start()
NProgress.start();
if (getToken()) {
/* has token*/
if (to.path === '/login') {
next({path: '/'})
NProgress.done()
if (to.path === "/login") {
next({ path: "/" });
NProgress.done();
} else {
if (store.getters.roles.length === 0) {
// 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(res => {
// 拉取user_info
const roles = res.roles
store.dispatch('GenerateRoutes', {roles}).then(accessRoutes => {
// 测试 默认静态页面
// store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => {
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({...to, replace: true}) // hack方法 确保addRoutes已完成
store
.dispatch("GetInfo")
.then(res => {
// 拉取user_info
const roles = res.roles;
store.dispatch("GenerateRoutes", { roles }).then(accessRoutes => {
// 测试 默认静态页面
// store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => {
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes); // 动态添加可访问路由表
next({ ...to, replace: true }); // hack方法 确保addRoutes已完成
});
})
})
.catch(err => {
store.dispatch('FedLogOut').then(() => {
Message.error(err)
next({path: '/'})
})
})
store.dispatch("FedLogOut").then(() => {
Message.error(err);
next({ path: "/" });
});
});
} else {
next()
next();
// 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
// if (hasPermission(store.getters.roles, to.meta.roles)) {
// next()
@ -49,17 +58,22 @@ router.beforeEach((to, from, next) => {
}
} else {
// 没有token
if (whiteList.indexOf(to.path) !== -1 || to.path.startsWith('/f/contract/') || to.path.startsWith('/subhealthyInvestigation/')
|| to.path.startsWith('/foodHeatCalculator/')) {
if (
whiteList.indexOf(to.path) !== -1 ||
to.path.startsWith("/f/contract/") ||
to.path.startsWith("/recipes/detail/") ||
to.path.startsWith("/subhealthyInvestigation/") ||
to.path.startsWith("/foodHeatCalculator/")
) {
// 在免登录白名单,直接进入
next()
next();
} else {
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
NProgress.done()
next(`/login?redirect=${to.fullPath}`); // 否则全部重定向到登录页
NProgress.done();
}
}
})
});
router.afterEach(() => {
NProgress.done()
})
NProgress.done();
});

View File

@ -146,6 +146,13 @@ export const constantRoutes = [
meta: { title: "食谱制作" },
hidden: true
},
{
path: "/recipes/detail/:id",
component: resolve => require(["@/views/custom/recipesShow"], resolve),
props: true,
meta: { title: "健康食谱" },
hidden: true
},
{
path: "/f/contract/:id(\\d+)",
hidden: true,

View File

@ -20,7 +20,6 @@ const oriState = {
recipesDataLoading: false,
cusUnitOptions: [],
cusWeightOptions: [],
dishesTypeOptions: [],
typeOptions: [],
currentDay: -1,
startNum: 0,
@ -87,9 +86,6 @@ const actions = {
getDicts("cus_dishes_type").then(response => {
commit("updateStateData", { typeOptions: response.data });
});
getDicts("cus_dishes_type").then(response => {
commit("updateStateData", { dishesTypeOptions: response.data });
});
// 健康数据
if (payload.cusId) {

View File

@ -290,14 +290,14 @@
/>
</template>
</el-table-column>
<el-table-column prop="proteinRatio" label="P/100g">
<el-table-column prop="proteinRatio" label="蛋白质/100g">
</el-table-column>
<el-table-column prop="fatRatio" label="F/100g">
<el-table-column prop="fatRatio" label="脂肪/100g">
</el-table-column>
<el-table-column prop="carbonRatio" label="C/100g">
</el-table-column>
<el-table-column prop="remark" label="备注">
<el-table-column prop="carbonRatio" label="碳水/100g">
</el-table-column>
<!-- <el-table-column prop="remark" label="备注">
</el-table-column> -->
</el-table>
</el-form-item>
</el-col>

View File

@ -87,7 +87,7 @@ export default {
`${seriesName.substring(0, 1)}Weight`
].toFixed(1);
arr.push(
`${cur.marker} ${nutriName}${heatVal}千卡${weightVal}`
`${cur.marker} ${nutriName}${weightVal}${heatVal}千卡`
);
return arr;
},
@ -110,7 +110,7 @@ export default {
source,
},
grid: {
top: 40,
top: 55,
left: 20,
right: 20,
bottom: 10,
@ -121,6 +121,10 @@ export default {
},
yAxis: {
type: "value",
name: "热量(千卡)",
nameTextStyle: {
color: "#262626",
},
},
series: ["pHeat", "fHeat", "cHeat"].map((dim, idx) => ({
name: dim,

View File

@ -14,25 +14,14 @@
class="small_table"
>
<el-table-column label="营养" prop="type" align="center" width="60" />
<el-table-column
label="重量(g)"
prop="weight"
align="center"
width="80"
/>
<el-table-column
label="热量(Kcal)"
prop="heat"
align="center"
width="90"
/>
<el-table-column
label="热量占比"
prop="heatRate"
align="center"
width="80"
/>
<el-table-column label="蛋白质" prop="p" align="center" width="80" />
<el-table-column label="脂肪" prop="f" align="center" width="80" />
<el-table-column label="碳水" prop="c" align="center" width="80" />
</el-table>
<div class="summary">
<div style="font-size: 12px; color: #606266;">总热量约等于</div>
<div style="color: #515a6e; font-weight: bold">{{ totalHeat.toFixed(1) }}千卡</div>
</div>
</div>
</div>
</template>
@ -69,35 +58,37 @@ export default {
data() {
return {
chart: null,
totalHeat: 0,
nameDict: {
p: "蛋白质",
f: "脂肪",
c: "碳水",
},
typeDict: {
Weight: "摄入量",
Rate: "供能比",
},
};
},
computed: {
mData() {
const [data] = this.data;
let totalHeat = 0;
return data
? ["p", "f", "c"].map((type) => {
if (totalHeat === 0) {
totalHeat = ["p", "f", "c"].reduce((heat, cur) => {
heat += data[`${cur}Heat`];
return heat;
}, 0);
}
return {
type: this.nameDict[type],
weight: data[`${type}Weight`].toFixed(1),
heat: data[`${type}Heat`].toFixed(1),
heatRate: `${((data[`${type}Heat`] / totalHeat) * 100).toFixed(
2
)}%`,
};
})
: [];
if (!data) {
this.totalHeat = 0;
return [];
}
this.totalHeat = data.cHeat + data.fHeat + data.pHeat;
const mData = ["Weight", "Rate"].map((t, idx) => ({
type: this.typeDict[t],
...["p", "f", "c"].reduce((obj, cur) => {
obj[cur] = idx
? `${((data[`${cur}Heat`] / this.totalHeat) * 100).toFixed(2)}%`
: `${data[`${cur}Weight`].toFixed(1)}`;
return obj;
}, {}),
}));
console.log(mData);
return mData;
},
},
mounted() {
@ -121,10 +112,10 @@ export default {
this.chart.clear();
this.chart.setOption({
title: {
text: `${data.name}营养统计`,
text: `${data.name}营养分析`,
},
tooltip: {
position: 'right',
position: "right",
trigger: "item",
appendToBody: true,
formatter: (params) => {
@ -136,9 +127,9 @@ export default {
} = params;
return [
`${marker} ${name}`,
`量:${oriData[`${dim}Weight`].toFixed(1)}`,
`热量:${value.toFixed(1)}千卡`,
`热量占比:${percent}%`,
`摄入量:${oriData[`${dim}Weight`].toFixed(1)}`,
`摄入热量:${value.toFixed(1)}千卡`,
`供能比:${percent}%`,
].join("</br>");
},
},
@ -199,5 +190,17 @@ export default {
}
}
// }
.summary {
padding: 2px;
border-bottom: 1px solid #dfe6ec;
border-left: 1px solid #dfe6ec;
border-right: 1px solid #dfe6ec;
& > div {
padding: 3px;
text-align: center;
}
}
}
</style>

View File

@ -24,7 +24,7 @@
<ConfigDishes
v-show="active === 1"
v-bind="selDishes"
:typeOptions="typeOptions"
:typeOptions="dishesTypeOptions"
@onChange="handleOnConfigChange"
/>
</div>
@ -65,7 +65,7 @@ export default {
return {
visible: false,
active: 0,
typeOptions: [],
dishesTypeOptions: [],
selDishes: {
name: "",
type: "",
@ -76,7 +76,7 @@ export default {
};
},
computed: {
...mapState(["dishesTypeOptions"]),
...mapState(["typeOptions"]),
},
methods: {
showDrawer() {
@ -95,11 +95,11 @@ export default {
// console.log(data);
this.selDishes = data;
this.active = 1;
this.typeOptions = data.type.split(",").reduce((arr, cur, idx) => {
this.dishesTypeOptions = data.type.split(",").reduce((arr, cur, idx) => {
if (idx === 0) {
this.selDishes.type = cur;
}
const tarOpt = this.dishesTypeOptions.find(
const tarOpt = this.typeOptions.find(
(obj) => obj.dictValue === cur
);
if (tarOpt) {

View File

@ -24,8 +24,8 @@ const {
mapGetters,
} = createNamespacedHelpers("recipes");
import HealthyView from "./HealthyView";
import BodySignView from "./BodySignView";
import HealthyView from "@/components/HealthyView";
import BodySignView from "@/components/BodySignView";
import RecipesView from "./RecipesView/index";
import RecommondView from "./RecommondView";

View File

@ -0,0 +1,87 @@
<template>
<el-dialog
:visible.sync="visible"
:title="title"
width="80%"
top="30%"
:close-on-click-modal="false"
class="dishes_detail_dialog_wrapper"
>
<section class="section_zone">
<div class="section_title">
食材<em class="el-icon-shopping-cart-1" style="margin-left: 8px" />
</div>
<div v-for="igd in data.igdList" :key="igd.id" class="igd_item">
<span>{{ igd.name }}</span>
<span class="cusstr_style">
<span>{{ igd.cusStr }}</span>
<span>{{ igd.weight }}</span>
</span>
</div>
</section>
<section class="section_zone">
<div class="section_title">
做法<em class="el-icon-dish" style="margin-left: 8px" />
</div>
<div class="methods">{{ data.methods }}</div>
</section>
</el-dialog>
</template>
<script>
export default {
name: "dishesDetailDialog",
data() {
return {
visible: false,
data: {},
title: "",
};
},
methods: {
showDialog(data) {
if (!data || !data.igdList.length) {
return;
}
this.data = data;
this.visible = true;
this.title = `${data.name}`;
},
},
};
</script>
<style lang="scss" scoped>
.dishes_detail_dialog_wrapper {
.section_zone {
margin-bottom: 16px;
.section_title {
color: #262626;
margin-bottom: 8px;
}
}
.igd_item {
height: 32px;
padding: 0 8px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #dfe6ec;
.cusstr_style {
width: 40%;
display: flex;
justify-content: space-between;
align-items: center;
}
}
.methods {
padding: 0 8px;
margin-top: 14px;
}
}
</style>
<style lang="scss">
.el-dialog__body {
padding: 12px 18px;
}
</style>

View File

@ -0,0 +1,159 @@
<template>
<div class="nutri_compute_com_wrapper">
<div class="header">{{ date }}</div>
<div class="content">
<section class="left">
<div style="font-size: 18px">营养分析</div>
<div class="total">
<div>总热量约等于</div>
<div>{{ totalHeat }}千卡</div>
</div>
</section>
<section class="right">
<table class="my_table" border="1">
<thead>
<tr>
<th></th>
<th>蛋白质</th>
<th>脂肪</th>
<th>碳水</th>
</tr>
</thead>
<tbody>
<tr>
<td style="font-size: 12px">摄入量</td>
<td>{{ pWeight }}</td>
<td>{{ fWeight }}</td>
<td>{{ cWeight }}</td>
</tr>
<tr>
<td style="font-size: 12px">供能比</td>
<td>{{ pRate }}</td>
<td>{{ fRate }}</td>
<td>{{ cRate }}</td>
</tr>
</tbody>
</table>
<div class="mask" />
</section>
</div>
</div>
</template>
<script>
export default {
name: "nutriComputeCom",
props: ["date", "value"],
data() {
return {
totalHeat: 0,
pWeight: "0克",
fWeight: "0克",
cWeight: "0克",
pRate: "0%",
fRate: "0%",
cRate: "0%",
};
},
watch: {
value(val) {
if (!val || !val.length) {
return;
}
let pWeight = 0,
fWeight = 0,
cWeight = 0;
val.forEach((dishes) => {
dishes.igdList.forEach((igd) => {
pWeight += (igd.proteinRatio * igd.weight) / 100;
fWeight += (igd.fatRatio * igd.weight) / 100;
cWeight += (igd.carbonRatio * igd.weight) / 100;
});
});
this.totalHeat = (pWeight * 4 + fWeight * 9 + cWeight * 4).toFixed(1);
this.pWeight = pWeight.toFixed(1) + "克";
this.fWeight = fWeight.toFixed(1) + "克";
this.cWeight = cWeight.toFixed(1) + "克";
this.pRate = (((pWeight * 4) / this.totalHeat) * 100).toFixed(2) + "%";
this.fRate = (((fWeight * 9) / this.totalHeat) * 100).toFixed(2) + "%";
this.cRate = (((cWeight * 4) / this.totalHeat) * 100).toFixed(2) + "%";
},
},
};
</script>
<style lang="scss" scoped>
.nutri_compute_com_wrapper {
padding: 10px 14px;
background: #409eff;
border-radius: 4px;
color: white;
.header {
text-align: center;
font-weight: bold;
}
.content {
display: flex;
margin-top: 12px;
.left {
padding-top: 10px;
& > div:nth-child(1) {
text-align: center;
flex: 1;
}
.total {
text-align: center;
margin-top: 16px;
border: 1px solid white;
padding: 8px 16px;
& > div:nth-child(1) {
font-size: 12px;
margin-bottom: 8px;
}
}
}
.right {
flex: 2;
border: 1px solid white;
margin-left: 10px;
padding: 4px;
position: relative;
display: flex;
justify-content: center;
align-items: center;
.my_table {
width: 100%;
height: 100%;
border-spacing: 0;
border: 1px solid white;
border-collapse: collapse;
table-layout: fixed;
th {
font-size: 12px;
text-align: center;
height: 30px;
}
td {
font-size: 10px;
text-align: center;
height: 30px;
}
}
.mask {
position: absolute;
width: calc(100% - 8px);
height: calc(100% - 8px);
top: 4px;
border: 1px solid #409eff;
}
}
}
}
</style>

View File

@ -0,0 +1,141 @@
<template>
<div class="menu_detail_wrapper">
<!-- 营养分析 -->
<NutriComputeCom :date="date" :value="value" />
<!-- 食谱详细 -->
<el-card v-for="obj in menus" :key="obj.type" style="margin-top: 12px">
<div slot="header">
<span>{{ obj.typeName }}</span>
</div>
<div v-for="mObj in obj.values" :key="mObj.id">
<div class="dishes_item">
<div v-if="!mObj.methods" class="simple_dishes">
<span>{{ mObj.name }}</span>
<span class="weight_style">
<span style="margin-right: 20px">{{ mObj.cusStr }}</span>
<span>{{ mObj.weight }}</span>
</span>
</div>
<div v-else class="complex_dishes" @click="handleOnDetailClick(mObj)">
<span>{{ mObj.name }}</span>
<em class="el-icon-arrow-right" />
</div>
</div>
</div>
</el-card>
<!-- 复杂菜品展示 -->
<DishesDetailDialog ref="detailDialogRef" />
</div>
</template>
<script>
import NutriComputeCom from "./NutriComputeCom";
import DishesDetailDialog from "./DishesDetailDialog";
export default {
name: "menuDetail",
props: ["value", "date"],
components: {
NutriComputeCom,
DishesDetailDialog,
},
created() {
this.getDicts("cus_cus_unit").then((response) => {
this.curUnitDict = response.data.reduce((obj, cur) => {
obj[cur.dictValue] = cur.dictLabel;
return obj;
}, {});
});
this.getDicts("cus_cus_weight").then((response) => {
this.cusWeightDict = response.data.reduce((obj, cur) => {
obj[cur.dictValue] = cur.dictLabel;
return obj;
}, {});
});
this.getDicts("cus_dishes_type").then((response) => {
this.menuTypeDict = response.data.reduce((obj, cur) => {
obj[cur.dictValue] = cur.dictLabel;
return obj;
}, {});
});
},
data() {
return {
menuTypeDict: {},
curUnitDict: {},
cusWeightDict: {},
};
},
computed: {
menus() {
const mData = this.value.reduce((obj, cur) => {
if (!obj[cur.type]) {
obj[cur.type] = [];
}
let tarMenu = cur;
if (!tarMenu.methods && tarMenu.igdList.length === 1) {
tarMenu = tarMenu.igdList[0];
tarMenu.cusStr = `${this.cusWeightDict[tarMenu.cusWeight] || ""}${
this.curUnitDict[tarMenu.cusUnit] || ""
}`;
} else {
tarMenu.igdList.forEach((igd) => {
igd.cusStr = `${this.cusWeightDict[igd.cusWeight] || ""}${
this.curUnitDict[igd.cusUnit] || ""
}`;
});
}
obj[cur.type].push(tarMenu);
return obj;
}, {});
const mMenus = Object.keys(mData).map((type) => ({
type,
typeName: this.menuTypeDict[type],
values: mData[type],
}));
console.log(mMenus);
return mMenus;
},
},
methods: {
handleOnDetailClick(data) {
this.$refs["detailDialogRef"].showDialog(data);
},
},
};
</script>
<style lang="scss" scoped>
.menu_detail_wrapper {
padding: 0 12px 12px 12px;
.dishes_item {
height: 38px;
padding: 0 8px;
border-bottom: 1px solid #dfe6ec;
&:active {
background: #409eff;
color: white;
}
.simple_dishes {
display: flex;
height: 100%;
align-items: center;
justify-content: space-between;
.weight_style {
width: 40%;
display: flex;
align-items: center;
justify-content: space-between;
}
}
.complex_dishes {
display: flex;
height: 100%;
align-items: center;
justify-content: space-between;
}
}
}
</style>

View File

@ -0,0 +1,120 @@
<template>
<el-drawer
:visible.sync="visible"
:with-header="false"
direction="ltr"
size="60%"
class="plan_drawer_wrapper"
>
<div class="header">
<span>食谱列表</span>
</div>
<div class="content">
<el-collapse v-model="curPlanId" accordion>
<el-collapse-item
v-for="plan in data"
:key="plan.id"
:title="plan.label"
:name="plan.id"
:class="plan.id === hitPlanId ? 'collapse_item_hit' : ''"
>
<div
v-for="menu in plan.menus"
:class="`item ${menu.id === curMenuId ? 'sel_item' : ''}`"
:key="menu.id"
@click="handleOnCurrentChange(plan.id, menu)"
>
<div class="item_content">
{{ menu.date }}
<em class="el-icon-arrow-right" style="font-weight: bold" />
</div>
</div>
</el-collapse-item>
</el-collapse>
</div>
</el-drawer>
</template>
<script>
export default {
name: "planDrawer",
data() {
return {
visible: false,
curPlanId: 0,
curMenuId: 0,
hitPlanId: 0,
};
},
props: ["data", "planId", "menuId"],
methods: {
showDrawer() {
this.visible = true;
},
handleOnCurrentChange(planId, menu) {
// console.log({ planId, menuId });
this.hitPlanId = planId;
this.visible = false;
this.curMenuId = menu.id;
this.curPlanId = planId;
this.$emit("plan-change", menu);
},
},
computed: {
},
watch: {
planId(val) {
this.curPlanId = val;
this.hitPlanId = val;
},
menuId(val) {
this.curMenuId = val;
},
},
};
</script>
<style lang="scss" scoped>
.plan_drawer_wrapper {
.header {
padding: 2px 6px;
display: flex;
justify-content: center;
align-items: center;
height: 44px;
}
.content {
height: calc(100vh - 44px);
padding: 12px;
overflow: auto;
.item {
font-size: 14px;
height: 36px;
cursor: pointer;
}
.item_content {
display: flex;
padding: 2px 8px 2px 24px;
align-items: center;
height: 100%;
justify-content: space-between;
}
.sel_item {
background: #409eff;
color: white;
}
}
}
</style>
<style lang="scss">
.collapse_item_hit .el-collapse-item__header {
color: #409eff;
}
.el-collapse-item__header.focusing {
color: unset !important;
}
</style>

View File

@ -0,0 +1,84 @@
<template>
<el-drawer
:visible.sync="visible"
:with-header="false"
size="100%"
class="user_info_drawer_wrapper"
>
<div class="header">
<el-button
type="text"
icon="el-icon-back"
@click="handleOnBackClick"
class="icon_btn"
/>
<span>个人信息</span>
<span class="hold" />
</div>
<div class="content">
<HealthView v-if="healthyData.type === 0" :data="healthyData.data" />
<BodySignView v-else :data="healthyData.data" />
</div>
</el-drawer>
</template>
<script>
import HealthView from "@/components/HealthyView";
import BodySignView from "@/components/BodySignView";
export default {
name: "UserInfoDrawer",
props: {
healthyData: {
type: Object,
default: {
type: 0,
data: {},
},
},
},
components: {
BodySignView,
HealthView,
},
data() {
return {
visible: false,
};
},
methods: {
showDrawer() {
this.visible = true;
},
handleOnBackClick() {
this.visible = false;
},
},
};
</script>
<style lang="scss" scoped>
.user_info_drawer_wrapper {
.header {
padding: 2px 6px;
display: flex;
justify-content: space-between;
align-items: center;
height: 44px;
.icon_btn {
font-size: 24px;
padding: 6px;
color: #696969;
}
.hold {
display: block;
width: 39px;
}
}
.content {
padding: 20px;
height: calc(100vh - 44px);
overflow: auto;
}
}
</style>

View File

@ -0,0 +1,161 @@
<template>
<div class="recipes_show_wrapper">
<div class="header">
<el-button
icon="el-icon-date"
type="text"
class="icon_btn"
@click="handleOnPlanClick"
/>
<img :src="logo" style="width: auto; height: 32px" alt="logo" />
<el-button
icon="el-icon-user"
type="text"
class="icon_btn"
@click="handleUserInfoClick"
/>
</div>
<div class="content" v-loading="loading">
<MenuDetail :value="menuData" :date="curDate" />
</div>
<!-- 食谱计划 -->
<PlanDrawer
ref="planRef"
:data="planList"
:planId="curPlanId"
:menuId="curMenuId"
@plan-change="handleOnPlanChange"
/>
<!-- 用户信息 -->
<UserInfoDrawer ref="userInfoRef" :healthyData="healthyData" />
</div>
</template>
<script>
import {
getRecipesPlans,
getHealthyInfo,
getRecipesMenuInfoApi,
} from "@/api/custom/recipesShow";
import { dealHealthy } from "@/utils/healthyData";
import UserInfoDrawer from "./UserInfoDrawer";
import PlanDrawer from "./PlanDrawer";
import MenuDetail from "./MenuDetail";
import dayjs from "dayjs";
import { getProcessMenuData } from "./utils";
export default {
name: "recipesShow",
components: {
UserInfoDrawer,
PlanDrawer,
MenuDetail,
},
props: ["id"],
data() {
return {
logo: require("@/assets/logo/st_logo.png"),
planList: [],
curPlanId: 0,
curMenuId: 0,
curDate: "",
loading: false,
healthyData: {
type: 0,
data: {},
},
menuData: [],
};
},
created() {
getRecipesPlans(this.id).then((response) => {
if (response.code === 200) {
let curPlanId, curMenuId, curDate;
const toDay = dayjs().format("YYYY-MM-DD");
this.planList = response.data.map((plan) => ({
menus: plan.menus.map((menu, idx) => {
const date = dayjs(plan.startDate)
.add(idx, "day")
.format("YYYY-MM-DD");
if (toDay === date) {
curPlanId = plan.id;
curMenuId = menu.id;
curDate = date;
}
return {
date,
id: menu.id,
};
}),
label: `${plan.startNumDay}${plan.endNumDay}`,
id: plan.id,
}));
if (!curMenuId) {
curMenuId = this.planList[0].menus[0].id;
curPlanId = this.planList[0].id;
curDate = this.planList[0].menus[0].date;
}
this.curMenuId = curMenuId;
this.curPlanId = curPlanId;
this.curDate = curDate;
this.fetchRecipesInfo(this.curMenuId);
}
});
getHealthyInfo(this.id).then((response) => {
if (response.code === 200) {
this.healthyData = {
type: response.data.type,
data: dealHealthy(response.data.customerHealthy),
};
}
});
},
methods: {
handleOnPlanClick() {
this.$refs["planRef"].showDrawer();
},
handleUserInfoClick() {
this.$refs["userInfoRef"].showDrawer();
},
fetchRecipesInfo(id) {
this.loading = true;
getRecipesMenuInfoApi(id).then((response) => {
if (response.code === 200) {
this.loading = false;
this.menuData = getProcessMenuData(response.data);
console.log(this.menuData);
}
});
},
handleOnPlanChange({ date, id }) {
this.curDate = date;
this.fetchRecipesInfo(id);
},
},
watch: {},
};
</script>
<style lang="scss" scoped>
.recipes_show_wrapper {
height: 100vh;
.header {
padding: 2px 6px;
display: flex;
justify-content: space-between;
align-items: center;
height: 44px;
.icon_btn {
font-size: 24px;
padding: 6px;
color: #696969;
}
}
.content {
height: calc(100vh - 44px);
overflow: auto;
}
}
</style>

View File

@ -0,0 +1,42 @@
export function getProcessMenuData(menuData) {
return menuData.reduce((arr, cur) => {
if (
cur.dishesId > -1 &&
cur.name &&
cur.igdList.length > 0 &&
cur.type !== "0"
) {
arr.push({
id: cur.id,
dishesId: cur.dishesId,
name: cur.name,
menuId: cur.menuId,
methods: cur.methods,
type: cur.type,
isMain: cur.isMain,
igdList: cur.igdList.reduce((igdArr, igdData) => {
if (igdData.id > 0) {
const tarDetail = cur.detail.find(obj => obj.id === igdData.id);
igdArr.push({
id: igdData.id,
name: igdData.name,
carbonRatio: igdData.carbonRatio,
fatRatio: igdData.fatRatio,
proteinRatio: igdData.proteinRatio,
cusUnit: tarDetail ? tarDetail.cus_unit : igdData.cusUnit,
cusWeight: tarDetail
? parseFloat(tarDetail.cus_weight)
: igdData.cusWeight,
weight: tarDetail ? parseFloat(tarDetail.weight) : igdData.weight,
notRec: igdData.notRec,
rec: igdData.rec,
type: igdData.type
});
}
return igdArr;
}, [])
});
}
return arr;
}, []);
}

View File

@ -1,33 +1,71 @@
<template>
<section>
<div style="padding: 5px; text-align: center">
<img :src="logo" style="width: 150px; height: 35px" alt="logo" />
<img :src="logo" style="width: auto; height: 35px" alt="logo" />
</div>
<div style="margin: 10px 15px 10px 15px;" >
<div style="margin: 10px 15px 10px 15px">
<el-steps :active="stepActive" finish-status="success">
<el-step v-for="(item,index) in stepArray" title=""></el-step>
<el-step
v-for="(item, index) in stepArray"
:key="index"
title=""
></el-step>
</el-steps>
</div>
<el-form ref="form" label-position="top" :model="form" :rules="rules" label-width="100px" style="padding: 16px">
<healthy-form1 v-show="stepArray[0]" :form.sync="form"></healthy-form1>
<healthy-form2 v-show="stepArray[1]" :form.sync="form"></healthy-form2>
<healthy-form3 v-show="stepArray[2]" :form.sync="form"></healthy-form3>
<healthy-form4 v-show="stepArray[3]" :form.sync="form"></healthy-form4>
<healthy-form5 v-show="stepArray[4]" :form.sync="form"></healthy-form5>
<healthy-form6 v-show="stepArray[5]" :form.sync="form"></healthy-form6>
<healthy-form7 v-show="stepArray[6]" :form.sync="form"></healthy-form7>
<healthy-form8 v-show="stepArray[7]" :form.sync="form"></healthy-form8>
<healthy-form9 v-show="stepArray[8]" ref="fileForm" @addOrEditHealthy="addCustomerHealthy()" :form.sync="form"></healthy-form9>
<el-form-item style="text-align: center; margin: 30px auto" >
<el-button @click="nextStep(-1)" style="margin-right: 10px;width: 40%" v-show="stepActive != 0">上一步</el-button>
<el-button type="primary" @click="nextStep(1)" style="width: 40%" v-show="stepActive != stepArray.length-1">下一步</el-button>
<el-button type="primary" @click="submit()" style="width: 40%" v-show="stepActive == stepArray.length-1">提交数据</el-button>
</el-form-item>
<el-form
ref="form"
label-position="top"
:model="form"
:rules="rules"
label-width="100px"
style="padding: 16px"
>
<healthy-form1 v-show="stepArray[0]" :form.sync="form"></healthy-form1>
<healthy-form2 v-show="stepArray[1]" :form.sync="form"></healthy-form2>
<healthy-form3 v-show="stepArray[2]" :form.sync="form"></healthy-form3>
<healthy-form4 v-show="stepArray[3]" :form.sync="form"></healthy-form4>
<healthy-form5 v-show="stepArray[4]" :form.sync="form"></healthy-form5>
<healthy-form6 v-show="stepArray[5]" :form.sync="form"></healthy-form6>
<healthy-form7 v-show="stepArray[6]" :form.sync="form"></healthy-form7>
<healthy-form8 v-show="stepArray[7]" :form.sync="form"></healthy-form8>
<healthy-form9
v-show="stepArray[8]"
ref="fileForm"
@addOrEditHealthy="addCustomerHealthy()"
:form.sync="form"
></healthy-form9>
<el-form-item style="text-align: center; margin: 30px auto">
<el-button
@click="nextStep(-1)"
style="margin-right: 10px; width: 40%"
v-show="stepActive != 0"
>上一步</el-button
>
<el-button
type="primary"
@click="nextStep(1)"
style="width: 40%"
v-show="stepActive != stepArray.length - 1"
>下一步</el-button
>
<el-button
type="primary"
@click="submit()"
style="width: 40%"
v-show="stepActive == stepArray.length - 1"
>提交数据</el-button
>
</el-form-item>
</el-form>
</section>
</template>
<script>
import { getDictData,addCustomerHealthy,physicalSignsList,getCustomerBaseMessage } from "@/api/custom/customerInvestigation";
import {
getDictData,
addCustomerHealthy,
physicalSignsList,
getCustomerBaseMessage,
} from "@/api/custom/customerInvestigation";
import * as healthyData from "@/utils/healthyData";
const logo = require("@/assets/logo/st_logo.png");
import Form1 from "@/components/HealthyForm/Form1";
@ -44,11 +82,11 @@ export default {
data() {
return {
//客户是否存在标识
customerExistFlag:false,
healthyData:healthyData,
customerExistFlag: false,
healthyData: healthyData,
logo,
submitFlag: false,
stepArray: [true,false,false,false,false,false,false,false,false],
stepArray: [true, false, false, false, false, false, false, false, false],
stepActive: 0,
form: {
customerEncId: null,
@ -59,23 +97,23 @@ export default {
age: null,
tall: null,
weight: null,
condiment:["1","2","3"],
otherCondiment:null,
cookingStyle: ["8","9","4","11"],
cookingStyleRate:[1,1,1,1,1,1],
washVegetablesStyle:["2"],
condiment: ["1", "2", "3"],
otherCondiment: null,
cookingStyle: ["8", "9", "4", "11"],
cookingStyleRate: [1, 1, 1, 1, 1, 1],
washVegetablesStyle: ["2"],
otherWashVegetablesStyle: null,
breakfastType:"2",
breakfastType: "2",
breakfastFood: null,
lunchType:["3"],
dinner:["2"],
lunchType: ["3"],
dinner: ["2"],
vegetableRate: 5,
commonMeat: null,
dinnerTime: "19:00",
supperNum:1,
supperFood:null,
supperNum: 1,
supperFood: null,
dietHotAndCold: "3",
dietFlavor: ["1","2"],
dietFlavor: ["1", "2"],
vegetablesNum: 1,
vegetablesRateType: "3",
fruitsNum: 1,
@ -85,28 +123,28 @@ export default {
riceFull: 8,
eatingSpeed: "3",
snacks: ["1"],
otherSnacks:null,
otherSnacks: null,
healthProductsFlag: 0,
healthProductsBrand:null,
healthProductsBrand: null,
healthProductsName: null,
healthProductsWeekRate:0,
healthProductsDayRate:0,
healthProductsWeekRate: 0,
healthProductsDayRate: 0,
waterNum: 1500,
waterType: ["3"],
waterHabit: ["5"],
drinksNum:[0,0,0,0,0,0,0,0],
drinksNum: [0, 0, 0, 0, 0, 0, 0, 0],
drinkWineFlag: "3",
drinkWineClassify:["3"],
drinkWineClassify: ["3"],
otherWineClassify: null,
drinkWineAmount:[0,0,0],
drinkWineAmount: [0, 0, 0],
smokeFlag: 0,
smokeRate:[0,0,0],
smokeRate: [0, 0, 0],
secondSmoke: 0,
workIndustry: null,
workType:["2"],
workType: ["2"],
defecationNum: 1,
otherDefecationNum:0,
otherDefecationNum: 0,
defecationTime: ["1"],
defecationShape: null,
defecationSmell: null,
@ -117,46 +155,46 @@ export default {
motionDuration: 40,
motionTime: "08:00",
//motionMode:"有氧",
aerobicMotionClassify:["2"],
anaerobicMotionClassify:[],
anaerobicAerobicMotionClassify:[],
aerobicMotionClassify: ["2"],
anaerobicMotionClassify: [],
anaerobicAerobicMotionClassify: [],
otherMotionClassify: null,
motionField:["1"],
otherMotionField:null,
motionField: ["1"],
otherMotionField: null,
sleepTime: "23:00",
sleepQuality:["2"],
sleepQuality: ["2"],
sleepDrugFlag: 0,
sleepDrug: null,
stayupLateFlag: 0,
stayupLateWeekNum: 0,
physicalSignsId:[],
physicalSignsId: [],
otherPhysicalSigns: null,
bloodData:[],
moistureDate:[],
familyIllnessHistory:[],
otherFamilyIllnessHistory:null,
operationHistory:[],
otherOperationHistory:null,
nearOperationFlag:0,
recoveryeSituation:null,
longEatDrugFlag:0,
longEatDrugClassify:[],
otherLongEatDrugClassify:null,
bloodData: [],
moistureDate: [],
familyIllnessHistory: [],
otherFamilyIllnessHistory: null,
operationHistory: [],
otherOperationHistory: null,
nearOperationFlag: 0,
recoveryeSituation: null,
longEatDrugFlag: 0,
longEatDrugClassify: [],
otherLongEatDrugClassify: null,
allergyFlag: 0,
allergySituation: null,
allergen:[],
otherAllergen:null,
medicalReport:[],
medicalReportName:[],
position:0,
allergen: [],
otherAllergen: null,
medicalReport: [],
medicalReportName: [],
position: 0,
experience: null,
rebound: 1,
difficulty:null,
crux:1,
dishesIngredient:null,
makeFoodType:3
difficulty: null,
crux: 1,
dishesIngredient: null,
makeFoodType: 3,
},
timer: null,
rules: {
@ -188,57 +226,59 @@ export default {
message: "体重格式不正确",
},
],
conditioningProjectId:[
{ required: true, trigger: "blur", message: "请选择调理项目" }
],
position:[
{ required: true, trigger: "blur", message: "请选择地理位置" }
]
}
conditioningProjectId: [
{ required: true, trigger: "blur", message: "请选择调理项目" },
],
position: [
{ required: true, trigger: "blur", message: "请选择地理位置" },
],
},
};
},
components: {
'healthy-form1': Form1,
'healthy-form2': Form2,
'healthy-form3': Form3,
'healthy-form4': Form4,
'healthy-form5': Form5,
'healthy-form6': Form6,
'healthy-form7': Form7,
'healthy-form8': Form8,
'healthy-form9': Form9,
"healthy-form1": Form1,
"healthy-form2": Form2,
"healthy-form3": Form3,
"healthy-form4": Form4,
"healthy-form5": Form5,
"healthy-form6": Form6,
"healthy-form7": Form7,
"healthy-form8": Form8,
"healthy-form9": Form9,
},
methods: {
//根据用户ID获取用户基本信息手机号、姓名
getCustomerBase(id){
if(id == null || id == undefined){
return;
}
getCustomerBaseMessage(id).then((response) => {
getCustomerBase(id) {
if (id == null || id == undefined) {
return;
}
getCustomerBaseMessage(id)
.then((response) => {
if (response.code === 200) {
if(response.data){
this.customerExistFlag = true;
this.form.name = response.data.name;
this.form.phone = response.data.phone;
}
if (response.data) {
this.customerExistFlag = true;
this.form.name = response.data.name;
this.form.phone = response.data.phone;
}
}
}).catch(function() {
})
.catch(function () {
console.log("error");
});
});
},
submit(){
if (this.submitFlag) {
this.$message({
message: "请勿重复提交1分钟后重试",
type: "warning",
});
return;
}
submit() {
if (this.submitFlag) {
this.$message({
message: "请勿重复提交1分钟后重试",
type: "warning",
});
return;
}
this.$refs.form.validate((valid) => {
if (valid) {
this.submitFlag = true;
this.timer = setTimeout(this.fail,1000*60);
this.$refs.fileForm.uploadFile();
this.submitFlag = true;
this.timer = setTimeout(this.fail, 1000 * 60);
this.$refs.fileForm.uploadFile();
} else {
this.$message({
message: "数据未填写完整",
@ -247,51 +287,53 @@ export default {
}
});
},
addCustomerHealthy(){
//数据处理
let cusMessage = Object.assign({}, this.form);
this.healthyData['arrayName'].forEach(function (item, index) {
cusMessage[item] = cusMessage[item] != null ? cusMessage[item].join(",") : null;
});
addCustomerHealthy(cusMessage).then((response) => {
if (response.code === 200) {
this.$notify({
title: "提交成功",
message: "",
type: "success",
});
}
}).catch(function() {
console.log("error");
addCustomerHealthy() {
//数据处理
let cusMessage = Object.assign({}, this.form);
this.healthyData["arrayName"].forEach(function (item, index) {
cusMessage[item] =
cusMessage[item] != null ? cusMessage[item].join(",") : null;
});
addCustomerHealthy(cusMessage)
.then((response) => {
if (response.code === 200) {
this.$notify({
title: "提交成功",
message: "",
type: "success",
});
}
})
.catch(function () {
console.log("error");
});
},
fail(){
fail() {
// console.log("定时--------");
this.submitFlag = false;
},
nextStep(step){
if(!this.customerExistFlag){
this.$message.error('客户不存在');
nextStep(step) {
if (!this.customerExistFlag) {
this.$message.error("客户不存在");
return;
}
this.$refs.form.validate((valid) => {
if(valid || step < 0){
if (valid || step < 0) {
this.stepArray[this.stepActive] = false;
this.stepActive = this.stepActive + step;
this.stepArray[this.stepActive] = true;
this.goTop();
}else{
} else {
this.$message({
message: "数据未填写完整",
type: "warning",
});
}
});
});
},
goTop (){
goTop() {
window.scroll(0, 0);
},
},
created() {
this.form.customerEncId = this.$route.params.id;
@ -304,45 +346,42 @@ export default {
</script>
<style scoped>
.el-form-item {
margin-bottom: 8px;
}
.el-form-item {
margin-bottom: 8px;
}
.p_title_1{
font-size: 18px;
font-weight: bold;
margin-top: 30px;
}
.p_title_2{
font-size: 16px;
font-weight: bold;
margin-top: 30px;
}
.p_title_3{
font-size: 14px;
font-weight: bold;
margin-top: 30px;
}
.margin-left{
margin-left: 14px;
}
.el-input__inner{
width: 30%;
}
.margin-top-10{
margin-top: 10px;
}
.width-50-left-8-right-5{
width:50%;
margin-left: 8px;
margin-right: 5px;
}
.width-70-left-8-right-5{
width:70%;
margin-left: 8px;
margin-right: 5px;
}
.p_title_1 {
font-size: 18px;
font-weight: bold;
margin-top: 30px;
}
.p_title_2 {
font-size: 16px;
font-weight: bold;
margin-top: 30px;
}
.p_title_3 {
font-size: 14px;
font-weight: bold;
margin-top: 30px;
}
.margin-left {
margin-left: 14px;
}
.el-input__inner {
width: 30%;
}
.margin-top-10 {
margin-top: 10px;
}
.width-50-left-8-right-5 {
width: 50%;
margin-left: 8px;
margin-right: 5px;
}
.width-70-left-8-right-5 {
width: 70%;
margin-left: 8px;
margin-right: 5px;
}
</style>