另存为模板功能

This commit is contained in:
huangdeliang 2021-03-08 16:04:36 +08:00
parent ff89b9bf5e
commit b3ce59ff25
12 changed files with 305 additions and 168 deletions

View File

@ -3,6 +3,7 @@ package com.stdiet.web.controller.custom;
import com.stdiet.common.core.controller.BaseController;
import com.stdiet.common.core.domain.AjaxResult;
import com.stdiet.common.core.page.TableDataInfo;
import com.stdiet.common.utils.StringUtils;
import com.stdiet.custom.domain.SysRecipesTemplate;
import com.stdiet.custom.service.ISysRecipesTemplateService;
import org.springframework.beans.factory.annotation.Autowired;
@ -10,6 +11,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* 食谱模板
@ -46,7 +48,11 @@ public class SysRecipesTemplateController extends BaseController {
@PreAuthorize("@ss.hasPermi('recipes:template:edit')")
@PostMapping("/add")
public AjaxResult add(@RequestBody SysRecipesTemplate sysRecipesTemplate) {
return toAjax(iSysRecipesTemplateService.insertRecipsesTemplate(sysRecipesTemplate));
Map<String, Long> result = iSysRecipesTemplateService.insertRecipsesTemplate(sysRecipesTemplate);
if (StringUtils.isEmpty(result)) {
return AjaxResult.error();
}
return AjaxResult.success(result);
}
/**

View File

@ -3,6 +3,7 @@ package com.stdiet.custom.service;
import com.stdiet.custom.domain.SysRecipesTemplate;
import java.util.List;
import java.util.Map;
/**
* 食谱计划Service接口
@ -14,7 +15,7 @@ public interface ISysRecipesTemplateService {
List<SysRecipesTemplate> selectRecipesTemplateListByCondition(SysRecipesTemplate sysRecipesTemplate);
int insertRecipsesTemplate(SysRecipesTemplate sysRecipesTemplate);
Map<String, Long> insertRecipsesTemplate(SysRecipesTemplate sysRecipesTemplate);
int updateRecipesTemplate(SysRecipesTemplate sysRecipesTemplate);

View File

@ -12,7 +12,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 食谱计划Service业务层处理
@ -36,7 +38,7 @@ public class SysRecipesTemplateServiceImpl implements ISysRecipesTemplateService
}
@Override
public int insertRecipsesTemplate(SysRecipesTemplate sysRecipesTemplate) {
public Map<String, Long> insertRecipsesTemplate(SysRecipesTemplate sysRecipesTemplate) {
SysRecipesPlan sysRecipesPlan = new SysRecipesPlan();
sysRecipesPlan.setStartNumDay(1);
sysRecipesPlan.setEndNumDay(7);
@ -47,9 +49,17 @@ public class SysRecipesTemplateServiceImpl implements ISysRecipesTemplateService
sysRecipesTemplate.setCreateBy(SecurityUtils.getUsername());
sysRecipesTemplate.setCreateTime(DateUtils.getNowDate());
sysRecipesTemplate.setPlanId(sysRecipesPlan.getId());
return sysRecipesTemplateMapper.insertRecipsesTemplate(sysRecipesTemplate);
int rows = sysRecipesTemplateMapper.insertRecipsesTemplate(sysRecipesTemplate);
if(rows > 0) {
Map<String, Long> result = new HashMap<>();
result.put("id", sysRecipesTemplate.getId());
result.put("planId", sysRecipesPlan.getId());
return result;
} else {
return null;
}
}
return 0;
return null;
}
@Override

View File

@ -12,10 +12,10 @@
>
<div class="msg-info" v-for="(info, idx) in basicInfo" :key="idx">
<text-info
v-for="con in info"
:title="con.title"
:key="con.title"
:value="data[con.value]"
v-for="i in info"
:title="i.title"
:key="i.title"
:value="data[i.value]"
extraclass="text-info-extra"
/>
</div>

View File

@ -0,0 +1,119 @@
<template>
<el-dialog
:title="title"
:visible.sync="visible"
width="520px"
append-to-body
>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="模板名称" prop="name" label-width="100px">
<el-input v-model="form.name" placeholder="请输入模板名称" />
</el-form-item>
<el-form-item label="营养师" prop="nutritionistId" label-width="100px">
<el-select v-model="form.nutritionistId" placeholder="请选择营养师">
<el-option
v-for="dict in nutritionistIdOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="营养师助理" prop="nutriAssisId" label-width="100px">
<el-select v-model="form.nutriAssisId" placeholder="请选择营养师助理">
<el-option
v-for="dict in nutriAssisIdOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark" label-width="100px">
<el-input
v-model="form.remark"
:rows="4"
type="textarea"
placeholder="请输入内容"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "TemplateDialog",
data() {
return {
title: "",
form: {
cusId: 0,
id: null,
name: null,
nutriAssisId: null,
nutritionistId: null,
remark: null,
},
//
rules: {
name: [{ required: true, message: "请输入模板名称", trigger: "blur" }],
nutritionistId: [
{ required: true, message: "请选择营养师", trigger: "blur" },
],
nutriAssisId: [
{ required: true, message: "请选择营养师助理", trigger: "blur" },
],
},
visible: false,
};
},
computed: {
...mapState({
//
nutritionistIdOptions: (state) =>
state.global.nutritionistIdOptions.slice(1),
//
nutriAssisIdOptions: (state) => state.global.nutriAssisIdOptions.slice(1),
}),
},
methods: {
showDialog(data) {
this.visible = true;
this.reset();
if (data) {
this.title = "修改模板";
this.form = data;
} else {
this.title = "创建模板";
}
},
submitForm() {
this.$refs["form"].validate((valid) => {
if (valid) {
this.$emit("onConfirm", this.form);
this.visible = false;
}
});
},
reset() {
this.form = {
cusId: 0,
id: null,
name: null,
nutriAssisId: null,
nutritionistId: null,
remark: null,
};
this.resetForm("form");
},
cancel() {
this.visible = false;
},
},
};
</script>

View File

@ -108,6 +108,7 @@ const mutations = {
const actions = {
async init({ commit, dispatch }, payload) {
//
// console.log(payload);
const planResponse = await getRecipesPlan(payload.planId);
const {
@ -262,8 +263,8 @@ const actions = {
async saveRecipes({ commit, dispatch, state }, payload) {
const { recipesData, cusId, planId } = state;
const params = {
cusId,
planId,
cusId: payload.cusId !== undefined ? payload.cusId : cusId,
planId: payload.planId || planId,
menus: recipesData.map((menu, idx) => ({
numDay: menu.numDay,
cusId,
@ -284,8 +285,11 @@ const actions = {
const result = await addRecipesApi(params);
if (result.code === 200) {
const recipesId = result.data;
commit("updateStateData", { recipesId });
dispatch("getRecipesInfo", { recipesId });
if (!payload.planId) {
// 非保存模板
commit("updateStateData", { recipesId });
dispatch("getRecipesInfo", { recipesId });
}
payload.callback &&
payload.callback({
name: state.name,

View File

@ -3,58 +3,84 @@
class="recipes_aspect_wrapper"
:style="`height: ${collapse ? 30 : 200}px`"
>
<div class="header">
<span class="font_size_style">
字体大小
<el-select
v-model="mFontSize"
size="mini"
style="width: 80px"
@change="handleOnSizeChange"
>
<el-option
v-for="size in fontSizeOpts"
:key="size.value"
:label="size.label"
:value="size.value"
/>
</el-select>
</span>
<el-button size="mini" v-if="!recipesId" @click="handleOnBack"
>返回</el-button
>
<el-popover
placement="bottom"
trigger="click"
title="修改审核状态"
style="margin-right: 12px"
v-hasPermi="['recipes:plan:review']"
>
<div>
<el-button size="mini" type="success" @click="hanldeOnReveiwChange(2)"
>审核通过</el-button
<div class="header" v-loading="loading">
<div class="header_btns">
<span>
<el-button
size="mini"
v-if="!!recipesId"
type="primary"
icon="el-icon-document-copy"
@click="handleOnTemplateClick"
>
<el-button size="mini" type="danger" @click="hanldeOnReveiwChange(1)"
>未审核通过</el-button
另存为模板
</el-button>
</span>
<span>
<span class="font_size_style">
字体大小
<el-select
v-model="mFontSize"
size="mini"
style="width: 80px"
@change="handleOnSizeChange"
>
<el-option
v-for="size in fontSizeOpts"
:key="size.value"
:label="size.label"
:value="size.value"
/>
</el-select>
</span>
<el-button size="mini" v-if="!recipesId" @click="handleOnBack"
>返回</el-button
>
</div>
<el-button
slot="reference"
size="mini"
v-if="reviewStatus"
:type="reviewStatus === 1 ? 'danger' : 'success'"
>
{{ reviewStatus === 1 ? "未审核" : "已审核" }}
</el-button>
</el-popover>
<el-popover
placement="bottom"
trigger="click"
title="修改审核状态"
style="margin-right: 12px"
v-hasPermi="['recipes:plan:review']"
>
<div>
<el-button
size="mini"
type="success"
@click="hanldeOnReveiwChange(2)"
>审核通过</el-button
>
<el-button
size="mini"
type="danger"
@click="hanldeOnReveiwChange(1)"
>未审核通过</el-button
>
</div>
<el-button
slot="reference"
size="mini"
v-if="reviewStatus"
:type="reviewStatus === 1 ? 'danger' : 'success'"
>
{{ reviewStatus === 1 ? "未审核" : "已审核" }}
</el-button>
</el-popover>
<el-button
v-if="!recipesId"
size="mini"
type="primary"
@click="handleOnSave"
>生成食谱</el-button
>
</span>
</div>
<el-button
v-if="!recipesId"
size="mini"
type="primary"
@click="handleOnSave"
>生成食谱</el-button
type="text"
@click="handleCollapseClick"
class="collapse_btn"
>
<el-button size="mini" type="text" @click="handleCollapseClick">
{{ `${collapse ? "展开" : "收起"}` }}
<em
class="el-icon-arrow-down arrow_icon"
@ -91,23 +117,29 @@
width="500px"
/>
</div>
<!-- 模板 -->
<TemplateDialog ref="templateRef" @onConfirm="handleOnCopy" />
</div>
</template>
<script>
import BarChart from "./BarChart";
import PieChart from "./PieChart";
import { addRecipesTemplate } from "@/api/custom/recipesTemplate";
import { createNamespacedHelpers } from "vuex";
const { mapActions, mapState, mapMutations } = createNamespacedHelpers(
"recipes"
);
import TemplateDialog from "@/components/TemplateDialog";
export default {
name: "RecipesAspectCom",
components: {
BarChart,
PieChart,
TemplateDialog,
},
data() {
return {
loading: false,
mFontSize: 12,
fontSizeOpts: [
{ value: 12, label: "12" },
@ -152,6 +184,29 @@ export default {
handleOnBack() {
this.updateStateData({ recipesData: [] });
},
handleOnTemplateClick() {
this.$refs.templateRef.showDialog();
},
handleOnCopy(form) {
this.loading = true;
addRecipesTemplate(form).then((response) => {
if (response.code === 200) {
const { planId, id } = response.data;
this.saveRecipes({
cusId: 0,
planId,
callback: () => {
this.$message.success(`另存为模板「${form.name}」成功`);
this.loading = false;
window.open(
"/recipes/build/" + form.name + "/" + planId + "?temId=" + id,
"_blank"
);
},
});
}
});
},
...mapActions(["saveRecipes", "updateReviewStatus"]),
...mapMutations(["updateStateData", "updateFontSize"]),
},
@ -165,6 +220,19 @@ export default {
.header {
text-align: right;
height: 30px;
display: flex;
align-items: center;
.header_btns {
display: flex;
align-items: center;
justify-content: space-between;
flex: 1;
}
.collapse_btn {
width: 42px;
}
.arrow_icon {
transition: all 0.3s;

View File

@ -77,8 +77,9 @@
icon="el-icon-delete"
class="fun_button"
@click="handleOnDelete(scope.row)"
>删除</el-button
>
删除
</el-button>
</div>
<div>
<el-button
@ -87,15 +88,18 @@
icon="el-icon-document-copy"
class="fun_button"
@click="handleOnCopy(scope.row)"
>复制</el-button
>
复制
</el-button>
<el-button
type="primary"
size="mini"
icon="el-icon-document-copy"
class="fun_button"
@click="handleOnSetting(scope.row)"
>修改餐类</el-button
>
修改餐类
</el-button>
</div>
</div>
<div class="pointer_style" slot="reference">

View File

@ -40,6 +40,8 @@ export default {
};
},
mounted() {
this.$store.dispatch("global/init", {});
//
this.init({
planId: this.planId,
name: this.name,

View File

@ -1,5 +1,7 @@
export function getProcessMenuData(menuData) {
return menuData.reduce((arr, cur) => {
// const igdPlanData = {};
const menuList = menuData.reduce((arr, cur) => {
if (
cur.dishesId > -1 &&
cur.name &&
@ -39,4 +41,5 @@ export function getProcessMenuData(menuData) {
}
return arr;
}, []);
return menuList;
}

View File

@ -180,49 +180,7 @@
/>
<!-- 添加或修改食材对话框 -->
<el-dialog :title="title" :visible.sync="open" width="520px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="模板名称" prop="name" label-width="100px">
<el-input v-model="form.name" placeholder="请输入模板名称" />
</el-form-item>
<el-form-item label="营养师" prop="nutritionistId" label-width="100px">
<el-select v-model="form.nutritionistId" placeholder="请选择营养师">
<el-option
v-for="dict in nutritionistIdOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label="营养师助理"
prop="nutriAssisId"
label-width="100px"
>
<el-select v-model="form.nutriAssisId" placeholder="请选择营养师助理">
<el-option
v-for="dict in nutriAssisIdOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark" label-width="100px">
<el-input
v-model="form.remark"
:rows="4"
type="textarea"
placeholder="请输入内容"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<TemplateDialog ref="templateDialogRef" @onConfirm="handleOnConfirm" />
</div>
</template>
@ -233,10 +191,9 @@ import {
updateRecipesTemplate,
deleteRecipesTemplate,
} from "@/api/custom/recipesTemplate";
import store from "@/store";
import { mapState } from "vuex";
import TemplateDialog from "@/components/TemplateDialog";
import { mapGetters, mapState } from "vuex";
const userId = store.getters && store.getters.userId;
export default {
name: "recipesTemplate",
data() {
@ -266,18 +223,6 @@ export default {
},
open: false,
title: "",
//
form: {},
//
rules: {
name: [{ required: true, message: "请输入模板名称", trigger: "blur" }],
nutritionistId: [
{ required: true, message: "请选择营养师", trigger: "blur" },
],
nutriAssisId: [
{ required: true, message: "请选择营养师助理", trigger: "blur" },
],
},
//
allRecipesPlanList: [],
//
@ -295,10 +240,12 @@ export default {
};
},
components: {
TemplateDialog,
// "order-dialog": OrderDetail,
// body_sign_dialog: BodySignDetail,
},
computed: {
// ...mapGetters(["userId"]),
...mapState({
//
nutritionistIdOptions: (state) =>
@ -340,9 +287,7 @@ export default {
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加模板";
this.$refs.templateDialogRef.showDialog();
},
/** 搜索按钮操作 */
handleQuery() {
@ -354,22 +299,6 @@ export default {
this.resetForm("queryForm");
this.handleQuery();
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
name: null,
remark: null,
nutritionistId: null,
nutriAssisId: null,
};
this.resetForm("form");
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
@ -402,10 +331,7 @@ export default {
.catch(() => {});
},
handleOnTemplateEdit(data) {
this.open = true;
this.title = "修改模板";
this.reset();
this.form = data;
this.$refs.templateDialogRef.showDialog(data);
},
handleOnRecipesEdit(data) {
// console.log(data);
@ -427,29 +353,24 @@ export default {
return this.selectDictLabel(this.nutriAssisIdOptions, row.nutriAssisId);
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate((valid) => {
if (valid) {
this.form.cusId = 0;
if (this.form.id != null) {
updateRecipesTemplate(this.form).then((response) => {
if (response.code === 200) {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
}
});
} else {
addRecipesTemplate(this.form).then((response) => {
if (response.code === 200) {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
}
});
handleOnConfirm(form) {
if (form.id != null) {
updateRecipesTemplate(form).then((response) => {
if (response.code === 200) {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
}
}
});
});
} else {
addRecipesTemplate(form).then((response) => {
if (response.code === 200) {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
}
});
}
},
},
};

View File

@ -268,7 +268,6 @@ import {
updateWxDistribution,
exportWxDistribution,
} from "@/api/custom/wxDistribution";
import { getOptions } from "@/api/custom/order";
import { listWxAccount } from "@/api/custom/wxAccount";
import { mapState } from "vuex";
export default {