!280 添加食谱计划页面

Merge pull request !280 from 德仔/develop
This commit is contained in:
德仔 2021-06-07 19:43:36 +08:00 committed by Gitee
commit ddab13bc79
8 changed files with 328 additions and 37 deletions

View File

@ -2,8 +2,8 @@ package com.stdiet.web.controller.custom;
import com.alibaba.fastjson.JSONObject;
import com.stdiet.common.core.controller.BaseController;
import com.stdiet.custom.utils.WsUtils;
import com.stdiet.custom.server.WebSocketServer;
import com.stdiet.custom.utils.WsUtils;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
@ -38,16 +38,16 @@ public class WebSocketController extends BaseController {
}
// @Scheduled(fixedRate = 30000)
// public void boardCast() {
// try {
// JSONObject heartBeat = new JSONObject();
// heartBeat.put("type", WsUtils.WS_TYPE_HEART_BEAT);
// heartBeat.put("msg", "ping");
//
// WebSocketServer.sendInfo(heartBeat.toJSONString(), null);
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
@Scheduled(fixedRate = 1800000)
public void boardCast() {
try {
JSONObject heartBeat = new JSONObject();
heartBeat.put("type", WsUtils.WS_TYPE_SYSTEM_MESSAGE_CLEAN);
heartBeat.put("msg", "clean");
WebSocketServer.sendInfo(heartBeat.toJSONString(), null);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -6,6 +6,8 @@ public class WsUtils {
public static final String WS_TYPE_SYSTEM_MESSAGE = "WS_TYPE_SYSTEM_MESSAGE";
public static final String WS_TYPE_SYSTEM_MESSAGE_CLEAN = "WS_TYPE_SYSTEM_MESSAGE_CLEAN";
public static final String WS_TYPE_MESSAGE_COUNT = "WS_TYPE_MESSAGE_COUNT";
public static final String WS_TYPE_NEW_CUSTOMER_REPLY = "WS_TYPE_NEW_CUSTOMER_REPLY";

View File

@ -192,7 +192,7 @@ export default {
},
methods: {
showDrawer(data) {
// console.log(data);
console.log(data);
this.data = data;
if (!this.data) {
return;

View File

@ -1,5 +1,9 @@
import { getCustomerPhysicalSignsByCusId } from "@/api/custom/customer";
import { dealHealthy } from "@/utils/healthyData";
import {
listRecipesPlanByCusId,
updateRecipesPlan
} from "@/api/custom/recipesPlan";
import {
fetchTopicList,
@ -16,7 +20,10 @@ const oriState = {
healthyData: {},
healthDataLoading: false,
healthyDataType: 0,
avoidFoodIds: []
avoidFoodIds: [],
//
planList: [],
planListLoading: false
};
const mutations = {
@ -71,12 +78,17 @@ const actions = {
},
async fetchTopicDetailActions({ commit, dispatch, state }, payload) {
const { topicId, id, uid } = payload;
const { healthyData } = state;
const { healthyData, planList } = state;
commit("save", { selTopicId: topicId });
// 客户信息
if (healthyData.customerId !== parseInt(uid)) {
dispatch("getHealthyData", { cusId: uid, callback: payload.callback });
}
// 食谱计划
if (!planList.length || planList[0].cusId !== parseInt(uid)) {
dispatch("getRecipesPlanActions", { cusId: uid });
}
//
const result = await fetchTopicDetail({ topicId, id });
if (result.code === 200) {
@ -130,13 +142,39 @@ const actions = {
obj => obj.id
);
}
} else {
throw new Error(healthyDataResult.msg);
}
commit("save", {
healthDataLoading: false,
...newState
});
},
async getRecipesPlanActions({ commit }, payload) {
commit("save", { planListLoading: true, planList: [] });
const result = await listRecipesPlanByCusId(payload.cusId);
let planList = [];
if (result.code === 200) {
planList = result.data;
}
commit("save", {
planList,
planListLoading: false
});
},
async updateRecipesPlanActions({ commit, state }, payload) {
const { id, sendFlag, callback } = payload;
const { planList } = state;
const result = await updateRecipesPlan({ id, sendFlag });
if (result.code === 200) {
callback && callback("success", result.msg);
const newPlanList = JSON.parse(JSON.stringify(planList));
const tarPlan = newPlanList.find(obj => obj.id === id);
if (tarPlan) {
tarPlan.sendFlag = sendFlag;
}
commit("save", {
planList: newPlanList
});
}
}
};

View File

@ -31,6 +31,7 @@ export default {
dietician: "主任营养师",
after_sale: "售后营养师",
dietician_assistant: "营养师助理",
manager: "总经理",
},
};
},

View File

@ -353,6 +353,13 @@ export default {
.topic_detail_title {
display: flex;
cursor: pointer;
& > :nth-child(1) {
flex: 0 0 40px;
}
& > :nth-child(2) {
flex: 1 0 0;
}
}
.comment_reply_item {

View File

@ -1,5 +1,10 @@
<template>
<div v-loading="healthDataLoading">
<el-tabs v-model="activeName">
<el-tab-pane label="客户信息" name="health">
<div
v-loading="healthDataLoading"
:style="{ height: getTabContentHeight(), overflow: 'auto' }"
>
<HealthyView
dev
:data="healthyDataType === 0 ? healthyData : {}"
@ -11,28 +16,46 @@
v-show="healthyDataType === 1"
/>
</div>
</el-tab-pane>
<el-tab-pane label="食谱计划" name="plan">
<div :style="{ height: getTabContentHeight(), overflow: 'auto' }">
<RecipesPlan />
</div>
</el-tab-pane>
</el-tabs>
</template>
<script>
import { createNamespacedHelpers } from "vuex";
import HealthyView from "@/components/HealthyView";
import BodySignView from "@/components/BodySignView";
const {
mapActions,
mapState,
mapMutations,
mapGetters,
} = createNamespacedHelpers("message");
import RecipesPlan from "./recipesPlan";
const { mapActions, mapState, mapMutations, mapGetters } =
createNamespacedHelpers("message");
export default {
name: "SignUserInfo",
components: {
HealthyView,
BodySignView,
RecipesPlan,
},
data() {
return {};
return {
activeName: "health",
};
},
methods: {
getTabContentHeight() {
const tabPanelElm = document.querySelector(".el-tabs");
if (tabPanelElm) {
return `${tabPanelElm.clientHeight - 68}px`;
}
return "";
},
},
computed: {
...mapState(["healthyData", "healthyDataType", "healthDataLoading"]),
},
};
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,220 @@
<template>
<div class="recipes_plan_wrapper">
<div class="header">
<section>
<el-button
v-if="cusOutId"
type="primary"
icon="el-icon-share"
size="mini"
class="copyBtn"
:data-clipboard-text="copyValue"
@click="handleOnRecipesLinkClick"
>食谱链接
</el-button>
<el-popover
placement="top"
trigger="click"
v-if="cusOutId"
style="margin: 0 12px"
>
<VueQr :text="copyValue" :logoSrc="logo" :size="256" />
<el-button
slot="reference"
size="mini"
icon="el-icon-picture-outline"
type="primary"
@click="handleCopy(scope.row.path)"
>二维码</el-button
>
</el-popover>
<!-- <el-button icon="el-icon-view" size="mini" @click="handleInnerOpen"
>查看暂停记录
</el-button> -->
</section>
<section>
<el-button
icon="el-icon-refresh"
size="mini"
@click="getRecipesPlanActions({ cusId })"
circle
/>
</section>
</div>
<el-table :data="planList" v-loading="planListLoading">
<el-table-column label="审核状态" align="center">
<template slot-scope="scope">
<el-tag :type="getReviewType(scope.row.reviewStatus)">
{{ getReviewStatusName(scope.row.reviewStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="计划" align="center" width="130">
<template slot-scope="scope">
{{ `${scope.row.startNumDay}${scope.row.endNumDay}` }}
</template>
</el-table-column>
<el-table-column label="日期" align="center" width="200">
<template slot-scope="scope">
{{ `${scope.row.startDate}${scope.row.endDate}` }}
</template>
</el-table-column>
<el-table-column label="订阅情况" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.subscribed ? 'success' : 'danger'">
{{ scope.row.subscribed ? "已订阅" : "未订阅" }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="发送" align="center">
<template slot-scope="scope">
<el-switch
v-model="!!scope.row.sendFlag"
@change="(val) => handleOnSendChange(val, scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button
type="text"
:icon="
scope.row.recipesId ? 'el-icon-edit' : 'el-icon-edit-outline'
"
@click="handleOnRecipesEditClick(scope.row)"
>
{{ `${scope.row.recipesId ? "编辑" : "制作"}` }}
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 暂停记录抽屉 -->
<!-- <PlanPauseDrawer ref="planPauseRef" /> -->
</div>
</template>
<script>
import Clipboard from "clipboard";
import { createNamespacedHelpers } from "vuex";
const { mapActions, mapState, mapMutations, mapGetters } =
createNamespacedHelpers("message");
// import PlanPauseDrawer from "./PlanPauseDrawer";
import VueQr from "vue-qr";
const logo = require("@/assets/logo/logo_b.png");
export default {
name: "RecipesPlanDrawer",
components: {
// PlanPauseDrawer,
VueQr,
},
data() {
return {
logo,
title: "",
cusOutId: "",
copyValue: "",
cusId: "",
};
},
watch: {
planList(val, newVal) {
console.log({ val, newVal });
this.cusOutId = val.reduce((str, cur) => {
if (!str && cur.recipesId && cur.reviewStatus === 2) {
str = cur.outId;
this.cusId = cur.cusId;
}
return str;
}, "");
if (this.cusOutId) {
this.copyValue =
window.location.origin.replace("manage", "sign") +
"/recipes/detail/" +
this.cusOutId;
}
},
},
computed: {
...mapState(["planList", "planListLoading", "healthyData"]),
},
methods: {
getReviewStatusName(status) {
switch (status) {
case 1:
return "未审核";
case 2:
return "已审核";
case 3:
return "制作中";
case 0:
default:
return "未制作";
}
},
getReviewType(status) {
switch (status) {
case 1:
return "danger";
case 2:
return "success";
case 3:
return "";
case 0:
default:
return "info";
}
},
// handleInnerOpen() {
// this.$refs["planPauseRef"].showDrawer(this.data);
// this.innerVisible = true;
// this.innerTitle = `${this.data.name}`;
// },
handleOnRecipesLinkClick() {
new Clipboard(".copyBtn");
this.$message({
message: "拷贝成功",
type: "success",
});
},
handleOnRecipesEditClick(data) {
window.open(
"/recipes/build/" + this.healthyData.name + "/" + data.id,
"_blank"
);
},
handleOnSendChange(val, data) {
console.log({ val, data });
const { id } = data;
if (data.reviewStatus === 2) {
this.updateRecipesPlanActions({
id,
sendFlag: val ? 1 : 0,
callback: (type, msg) => {
this.$message[type](msg);
},
});
} else {
this.$message.error("未审核的食谱不能发送");
}
},
...mapActions(["getRecipesPlanActions", "updateRecipesPlanActions"]),
},
};
</script>
<style lang="scss" scoped>
/deep/ :focus {
outline: 0;
}
.recipes_plan_wrapper {
// height: calc(100vh - 77px);
.header {
margin-bottom: 8px;
display: flex;
align-items: center;
justify-content: space-between;
}
}
</style>