采购计划开发

This commit is contained in:
huangdeliang
2021-03-10 17:35:19 +08:00
parent 7709c85cb0
commit aa555d98c2
10 changed files with 394 additions and 40 deletions

View File

@ -36,6 +36,7 @@ public class SysWapController extends BaseController {
/**
* 获取用户信息
*
* @param outId
* @return
*/
@ -46,6 +47,7 @@ public class SysWapController extends BaseController {
/**
* 获取某天食谱菜品
*
* @param id
* @return
*/
@ -56,6 +58,7 @@ public class SysWapController extends BaseController {
/**
* 系统字典
*
* @param dictType
* @return
*/
@ -63,4 +66,14 @@ public class SysWapController extends BaseController {
public AjaxResult sysDict(@PathVariable String dictType) {
return AjaxResult.success(iSysDictTypeService.selectDictDataByType(dictType));
}
/**
* 获取完整食谱
* @param id
* @return
*/
@GetMapping(value = "recipes/{id}")
public AjaxResult recipesDetail(@PathVariable Long id) {
return AjaxResult.success(iSysRecipesService.selectSysRecipesByRecipesId(id));
}
}

View File

@ -11,6 +11,8 @@ public class SysRecipesPlanListInfo {
private Long id;
private Long recipesId;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date startDate;

View File

@ -234,6 +234,7 @@
<result property="endDate" column="end_date"/>
<result property="startNumDay" column="start_num_day"/>
<result property="endNumDay" column="end_num_day"/>
<result property="recipesId" column="recipes_id"/>
<association property="menus" column="recipes_id" select="selectMenuIds"/>
</resultMap>

View File

@ -1,6 +1,5 @@
import request from "@/utils/request";
export function getRecipesPlans(id) {
return request({
url: "/wap/recipes/plans/" + id,
@ -40,3 +39,13 @@ export function getDicts(id) {
}
});
}
export function getRecipesFullInfo(id) {
return request({
url: "/wap/recipes/" + id,
method: "get",
headers: {
isToken: false
}
});
}

View File

@ -1,9 +1,18 @@
import { getRecipesFullInfo, getDicts } from "@/api/custom/recipesShow";
const oriState = {
recipes: {},
shoppingCart: {}
cusUnitDict: {},
cusWeightDict: {},
menuTypeDict: {},
idgTypeDict: {}
};
const mutations = {
setRecipesData(state, payload) {
// console.log(payload);
state.recipes[payload.recipesId] = payload.data;
},
updateStateData(state, payload) {
Object.keys(payload).forEach(key => {
state[key] = payload[key];
@ -17,8 +26,97 @@ const mutations = {
};
const actions = {
async fetchFullRecipes({commit, dispatch},payload ) {
async init({ commit, dispatch }, payload) {
getDicts("cus_cus_unit").then(response => {
const cusUnitDict = response.data.reduce((obj, cur) => {
obj[cur.dictValue] = cur.dictLabel;
return obj;
}, {});
commit("updateStateData", { cusUnitDict });
});
getDicts("cus_cus_weight").then(response => {
const cusWeightDict = response.data.reduce((obj, cur) => {
obj[cur.dictValue] = cur.dictLabel;
return obj;
}, {});
commit("updateStateData", { cusWeightDict });
});
getDicts("cus_dishes_type").then(response => {
const menuTypeDict = response.data.reduce((obj, cur) => {
obj[cur.dictValue] = cur.dictLabel;
return obj;
}, {});
commit("updateStateData", { menuTypeDict });
});
getDicts("cus_ing_type").then(response => {
const idgTypeDict = response.data.reduce((obj, cur) => {
obj[cur.dictValue] = cur.dictLabel;
return obj;
}, {});
commit("updateStateData", { idgTypeDict });
});
},
async fetchFullRecipes({ commit, dispatch }, payload) {
return new Promise((res, rej) => {
getRecipesFullInfo(payload.recipesId).then(response => {
if (response.code === 200) {
commit("setRecipesData", {
recipesId: payload.recipesId,
data: response.data.reduce((outArr, dayData, idx) => {
outArr.push({
id: dayData.id,
numDay: dayData.numDay,
dishes: dayData.dishes.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,
remark: cur.remark,
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
);
if (tarDetail) {
igdArr.push({
id: igdData.id,
name: igdData.name,
carbonRatio: igdData.carbonRatio,
fatRatio: igdData.fatRatio,
proteinRatio: igdData.proteinRatio,
cusUnit: tarDetail.cus_unit,
cusWeight: tarDetail.cus_weight,
weight: parseFloat(tarDetail.weight),
notRec: igdData.notRec,
rec: igdData.rec,
type: igdData.type
});
}
}
return igdArr;
}, [])
});
}
return arr;
}, [])
});
return outArr;
}, [])
});
}
res();
});
});
}
};

View File

@ -34,9 +34,15 @@
</div>
</template>
<script>
import { createNamespacedHelpers } from "vuex";
const {
mapActions,
mapState,
mapMutations,
mapGetters,
} = createNamespacedHelpers("recipesShow");
// import NutriComputeCom from "./NutriComputeCom";
import DishesDetailDialog from "./DishesDetailDialog";
import { getDicts } from "@/api/custom/recipesShow";
export default {
name: "menuDetail",
props: ["value", "date"],
@ -44,26 +50,6 @@ export default {
// NutriComputeCom,
DishesDetailDialog,
},
created() {
getDicts("cus_cus_unit").then((response) => {
this.curUnitDict = response.data.reduce((obj, cur) => {
obj[cur.dictValue] = cur.dictLabel;
return obj;
}, {});
});
getDicts("cus_cus_weight").then((response) => {
this.cusWeightDict = response.data.reduce((obj, cur) => {
obj[cur.dictValue] = cur.dictLabel;
return obj;
}, {});
});
getDicts("cus_dishes_type").then((response) => {
this.menuTypeDict = response.data.reduce((obj, cur) => {
obj[cur.dictValue] = cur.dictLabel;
return obj;
}, {});
});
},
data() {
return {
logo: require("@/assets/logo/st_logo.png"),
@ -71,9 +57,6 @@ export default {
2: "10:00 - 10:30",
4: "15:00 - 15:30",
},
menuTypeDict: {},
curUnitDict: {},
cusWeightDict: {},
};
},
computed: {
@ -86,12 +69,12 @@ export default {
if (!tarMenu.methods && tarMenu.igdList.length === 1) {
tarMenu = tarMenu.igdList[0];
tarMenu.cusStr = `${this.cusWeightDict[tarMenu.cusWeight] || ""}${
this.curUnitDict[tarMenu.cusUnit] || ""
this.cusUnitDict[tarMenu.cusUnit] || ""
}`;
} else {
tarMenu.igdList.forEach((igd) => {
igd.cusStr = `${this.cusWeightDict[igd.cusWeight] || ""}${
this.curUnitDict[igd.cusUnit] || ""
this.cusUnitDict[igd.cusUnit] || ""
}`;
});
}
@ -106,6 +89,7 @@ export default {
// console.log(mMenus);
return mMenus;
},
...mapState(["cusUnitDict", "cusWeightDict", "menuTypeDict"]),
},
methods: {
handleOnDetailClick(data) {

View File

@ -3,7 +3,7 @@
:visible.sync="visible"
width="80%"
center
title="选择时间段"
title="选择采购天数"
append-to-body
class="plan_time_wrapper"
>
@ -14,7 +14,7 @@
</div>
<div class="seperate_day">
<el-button @click="handleOnTimeClick(3)">前3天计划</el-button>
<el-button @click="handleOnTimeClick(4)">天计划</el-button>
<el-button @click="handleOnTimeClick(4)">4天计划</el-button>
</div>
</el-dialog>
</template>
@ -25,17 +25,21 @@ export default {
return {
visible: false,
recipesId: "",
label: "",
};
},
methods: {
showDialog(recipesId) {
showDialog({ recipesId, label }) {
this.visible = true;
this.label = label;
this.recipesId = recipesId;
},
handleOnTimeClick(num) {
this.visible = false;
this.$emit("onConfirm", {
num,
label: this.label,
recipesId: this.recipesId,
});
},
@ -51,8 +55,11 @@ export default {
margin-top: 10px;
display: flex;
& > button {
flex: 1;
& > button:nth-child(1) {
flex: 3;
}
& > button:nth-child(2) {
flex: 4;
}
}
}

View File

@ -0,0 +1,220 @@
<template>
<el-drawer
:visible.sync="visible"
:with-header="false"
direction="rtl"
size="100%"
append-to-body
class="shopping_plan_drawer_wrapper"
>
<div class="header">
<el-button
type="text"
icon="el-icon-back"
@click="handleOnBackClick"
class="icon_btn"
/>
<span>{{ label }}</span>
<span class="hold" />
</div>
<div class="content" v-loading="loading">
<div class="top">
<!-- <img :src="logo" style="width: auto; height: 32px" alt="logo" /> -->
{{ title }}
</div>
<div class="notice">
<div>1. 以下采购计划仅供参考</div>
<div>2. 主食和油类可按斤购买</div>
<div>3. 调味食材可按半斤购买</div>
</div>
<el-card
v-for="typeName in Object.keys(shoppingCart)"
:key="typeName"
style="margin-top: 12px"
>
<div slot="header" class="clearfix">
<span>{{ typeName }}</span>
</div>
<div
v-for="igdObj in shoppingCart[typeName]"
:key="igdObj.name"
class="item_style"
>
<span>{{ igdObj.name }}</span>
<span>
<span style="margin-right: 2px">{{ igdObj.weight }}</span>
<span>{{ igdObj.unit }}</span>
</span>
</div>
</el-card>
</div>
</el-drawer>
</template>
<script>
import { createNamespacedHelpers } from "vuex";
const {
mapActions,
mapState,
mapMutations,
mapGetters,
} = createNamespacedHelpers("recipesShow");
export default {
name: "ShoppingPlanDrawer",
data() {
return {
visible: false,
loading: false,
title: "",
logo: require("@/assets/logo/st_logo.png"),
shoppingCart: {},
igdUnitDict: {
鸡蛋: "个",
牛奶: "盒",
},
};
},
methods: {
showDrawer(data) {
// console.log(data);
const { recipesId, num, label } = data;
this.label = label;
// num < 0 全部计算
this.title = `${
num === 3 ? "前3" : num === 4 ? "后4" : Math.abs(num)
}天采购计划`;
this.visible = true;
if (this.recipes[recipesId]) {
this.processShoppingCart(num, recipesId);
} else {
this.loading = true;
this.fetchFullRecipes({
recipesId,
}).then(() => {
this.loading = false;
setTimeout(() => {
this.processShoppingCart(num, recipesId);
}, 0);
});
}
},
processShoppingCart(num, recipesId) {
this.shoppingCart = (this.recipes[recipesId] || []).reduce(
(obj, cur, idx) => {
if (
num < 0 || // 全部计算
num === 7 ||
(num === 3 && num > idx) ||
(num === 4 && idx > 2)
) {
cur.dishes.forEach((dObj) => {
dObj.igdList.forEach((iObj) => {
const tarTypeName = this.idgTypeDict[iObj.type];
const tarObj = obj[tarTypeName];
if (tarObj) {
const tarIObj = tarObj.find(
(zObj) => zObj.name === iObj.name
);
if (tarIObj) {
tarIObj.weight += this.igdUnitDict[iObj.name]
? iObj.cusWeight
: iObj.weight;
} else {
tarObj.push({
type: iObj.type,
name: iObj.name,
weight: this.igdUnitDict[iObj.name]
? iObj.cusWeight
: iObj.weight,
unit: this.igdUnitDict[iObj.name] || "g",
});
}
} else {
obj[tarTypeName] = [
{
type: iObj.type,
name: iObj.name,
weight: this.igdUnitDict[iObj.name]
? iObj.cusWeight
: iObj.weight,
unit: this.igdUnitDict[iObj.name] || "g",
},
];
}
});
});
}
return obj;
},
{}
);
console.log(this.shoppingCart);
},
handleOnBackClick() {
this.visible = false;
this.shoppingCart = {};
},
...mapActions(["fetchFullRecipes"]),
},
computed: {
...mapState(["recipes", "idgTypeDict"]),
},
};
</script>
<style lang="scss" scoped>
.shopping_plan_drawer_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;
}
.hold {
display: block;
width: 39px;
}
}
.content {
height: calc(100vh - 44px);
overflow: auto;
padding: 12px;
.top {
text-align: center;
padding-bottom: 10px;
}
.notice {
font-size: 12px;
color: #d96969;
& > div {
padding: 2px 0;
}
& > div:not(:first-child) {
margin-left: 24px;
}
}
.item_style {
display: flex;
padding: 0 12px;
height: 28px;
font-size: 14px;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #e6ebf5;
}
}
}
</style>

View File

@ -21,7 +21,6 @@
<div class="title_style">
<span>{{ plan.label }}</span>
<em
v-show="false"
class="el-icon-shopping-cart-full icon_style"
@click="(e) => handleOnShoppingPlanClick(e, plan)"
/>
@ -42,11 +41,15 @@
</el-collapse>
</div>
<!-- 时间选择弹窗 -->
<plan-time-dialog ref="planRef" @onConfirm="handleOnTimeConfirm" />
<!-- 采购计划 -->
<shopping-plan-drawer ref="drawerRef" />
</el-drawer>
</template>
<script>
import PlanTimeDialog from "./PlanTimeDialog";
import ShoppingPlanDrawer from "./ShoppingPlanDrawer";
export default {
name: "planDrawer",
data() {
@ -59,6 +62,7 @@ export default {
},
components: {
PlanTimeDialog,
ShoppingPlanDrawer,
},
props: ["data", "planId", "menuId"],
methods: {
@ -74,13 +78,24 @@ export default {
this.$emit("plan-change", menu);
},
handleOnShoppingPlanClick(e, data) {
handleOnShoppingPlanClick(e, plan) {
e.stopPropagation();
this.$refs.planRef.showDialog(data.id);
// console.log(plan);
const { recipesId, menus, label } = plan;
if (menus.length === 7) {
this.$refs.planRef.showDialog({ recipesId, label });
} else {
this.$refs.drawerRef.showDrawer({
num: menus.length * -1, // 全部计算
recipesId,
label,
});
}
this.visible = false;
},
handleOnTimeConfirm(val) {
console.log(val);
handleOnTimeConfirm({ num, recipesId, label }) {
// console.log(val);
this.$refs.drawerRef.showDrawer({ num, recipesId, label });
},
},
computed: {},

View File

@ -79,6 +79,9 @@ export default {
};
},
created() {
//
this.init();
//
getRecipesPlans(this.id).then((response) => {
if (response.code === 200) {
let curPlanId, curMenuId, curDate;
@ -100,6 +103,7 @@ export default {
id: menu.id,
};
}),
recipesId: plan.recipesId,
label: `${plan.startNumDay}${plan.endNumDay}`,
id: plan.id,
});
@ -152,6 +156,7 @@ export default {
this.curDate = date;
this.fetchRecipesInfo(id);
},
...mapActions(["init"]),
},
watch: {},
};