Browse Source

菜谱设置【新增管理菜品】,优化菜谱关联门店

dev
ywh 1 year ago
parent
commit
a6cfc02707
7 changed files with 571 additions and 410 deletions
  1. +1
    -1
      config/proxy.js
  2. +7
    -7
      config/routes.js
  3. +8
    -8
      src/app.jsx
  4. +107
    -0
      src/pages/foodMenu/foodMenuInfo/components/MenuGoods.jsx
  5. +203
    -180
      src/pages/foodMenu/foodMenuInfo/index.jsx
  6. +62
    -21
      src/pages/foodMenu/foodMenuInfo/services.js
  7. +183
    -193
      src/pages/foodMenu/storeFoodMenu/index.jsx

+ 1
- 1
config/proxy.js View File

@@ -9,7 +9,7 @@
export default {
dev: {
'/kitchen/': {
target: 'https://localhost:5001',
target: 'http://kitchen.dev1.com',
changeOrigin: true,
secure: false, //关闭证书验证
pathRewrite: {


+ 7
- 7
config/routes.js View File

@@ -554,13 +554,13 @@ export default [
component: './foodMenu/storeFoodMenu',
access: 'k14',
},
{
name: '菜谱关联菜品',
icon: 'smile',
path: '/foodMenu/foodMenu',
component: './foodMenu/foodMenu',
access: 'k14',
}
// {
// name: '菜谱关联菜品',
// icon: 'smile',
// path: '/foodMenu/foodMenu',
// component: './foodMenu/foodMenu',
// access: 'k14',
// }
]
},
{


+ 8
- 8
src/app.jsx View File

@@ -152,14 +152,14 @@ export async function getInitialState() {
component: './foodMenu/storeFoodMenu',
access: 'k14',
},
{
code: 'foodMenu',
name: '菜谱关联菜品',
icon: 'smile',
path: '/foodMenu/foodMenu',
component: './foodMenu/foodMenu',
access: 'k14',
}
// {
// code: 'foodMenu',
// name: '菜谱关联菜品',
// icon: 'smile',
// path: '/foodMenu/foodMenu',
// component: './foodMenu/foodMenu',
// access: 'k14',
// }
]
},
{


+ 107
- 0
src/pages/foodMenu/foodMenuInfo/components/MenuGoods.jsx View File

@@ -0,0 +1,107 @@
import { Modal, message } from 'antd';
import { useEffect, useRef, useState } from "react";
import { GetAllGoodsMenuPage, getpage_v2, EditFoodMenuGoods } from '../services';
import ProTable from '@ant-design/pro-table';

const columns = [
{
title: '商品id',
dataIndex: 'id',
tip: '规则名称是唯一的 key',
hideInSearch: true,
hideInTable: true,
},
{
title: '商品名称',
dataIndex: 'name',
},
];

/**
* 菜谱关联加盟商商品
* @param {*} props
* @returns
*/
const MenuGoods = (props) => {
const actionRef = useRef();

// 当前选中的商品
const [selectedRowKeys, setSelectedRowKeys] = useState([]);

const handleOk = async () => {
if (!props.foodMenu?.id) return;
const jsonData = {
goodsIds: [],
foodMenuId: props.foodMenu.id
}
selectedRowKeys.forEach(item => {
jsonData.goodsIds.push({
goodsId: item
});
});
const response = await EditFoodMenuGoods(jsonData);
if (response.statusCode === 200) {
message.success("更新菜谱商品成功!");
props.onOk();
} else {
message.error(JSON.stringify(response.errors) || '更新菜谱商品出错')
}
}

/**
* 根据菜谱ID 查询菜品信息
*/
const onFetchMenuGoods = async () => {
if (props.foodMenu.id) {
const response = await getpage_v2({
current: 1,
pageSize: 999,
FoodMenuId: props.foodMenu.id
});
if (response.statusCode === 200) {
const selectedIds = [];
response.data?.data?.forEach(item => {
selectedIds.push(item.goodid);
});
setSelectedRowKeys(selectedIds);
}
}
}

useEffect(() => {
onFetchMenuGoods();
}, []);

return <Modal width={800} title={props.foodMenu.name} visible={props.open} onOk={handleOk} onCancel={props.onCancel}>
<ProTable
columns={columns}
actionRef={actionRef}
pagination={{
pageSize: 10
}}
rowSelection={{
type: 'checkbox',
selectedRowKeys,
onChange: (selectedChangeRowKeys, selectedRows) => {
setSelectedRowKeys(selectedChangeRowKeys);
}
}}
request={async (params = {}, sort, filter) => {
const response = await GetAllGoodsMenuPage(params);
if (response.statusCode === 200) {
return {
data: response.data.data,
success: true,
total: response.data.total,
};
} else {
return []
}
}}
rowKey="id"
headerTitle="商品列表"
/>
</Modal>
}

export default MenuGoods;

+ 203
- 180
src/pages/foodMenu/foodMenuInfo/index.jsx View File

@@ -1,209 +1,232 @@

import { Modal,Button, message, } from 'antd';
import { Modal, Button, message, } from 'antd';
import React, { useState, useRef } from 'react';
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout';
import { PlusOutlined } from '@ant-design/icons';
import ProTable from '@ant-design/pro-table';
import CreateForm from './components/CreateForm';
import { GetFoodMenuInfoPage, UpdateFoodMenu, AddFoodMenu, DelFoodMenu, } from "./services"
import { GetFoodMenuInfoPage, UpdateFoodMenu, AddFoodMenu, DelFoodMenu, } from "./services";
import MenuGoods from './components/MenuGoods';

const key = 'message';

//添加
const handleAdd = async (fields) => {
try {
message.loading('正在添加', key);
await AddFoodMenu(JSON.stringify(fields)).then((r) => {
message.destroy(key);
if (r.data) {
message.success('添加成功');
return true;
} else {
message.error('添加失败');
return false;
}
});
} catch (error) {
message.error('添加失败请重试!');
return false;
}
try {
message.loading('正在添加', key);
await AddFoodMenu(JSON.stringify(fields)).then((r) => {
message.destroy(key);
if (r.data) {
message.success('添加成功');
return true;
} else {
message.error('添加失败');
return false;
}
});
} catch (error) {
message.error('添加失败请重试!');
return false;
}
};


//修改
const handleUpdate = async (fields) => {
try {
message.loading('正在修改', key);
message.destroy(key);
await UpdateFoodMenu(JSON.stringify(fields)).then((r) => {
message.destroy(key);
if (r.data) {
message.success('修改成功',);
return true;
} else {
message.error('修改失败');
return false;
}
});
} catch (error) {
message.error('修改失败请重试!');
return false;
}
try {
message.loading('正在修改', key);
message.destroy(key);
await UpdateFoodMenu(JSON.stringify(fields)).then((r) => {
message.destroy(key);
if (r.data) {
message.success('修改成功',);
return true;
} else {
message.error('修改失败');
return false;
}
});
} catch (error) {
message.error('修改失败请重试!');
return false;
}
};


//删除
const handleRemove = async (selectedRows) => {
try {
message.loading('正在删除');
let ids = [];
selectedRows.forEach((item) => {
ids.push(item.id);
});
await DelFoodMenu(ids).then((r) => {
message.destroy();
if (r.data) {
message.success('删除成功');
return true;
} else {
message.error('菜谱已关联到商品,删除失败');
return false;
}
});
} catch (error) {
message.error('删除失败请重试!');
return false;
}
try {
message.loading('正在删除');
let ids = [];
selectedRows.forEach((item) => {
ids.push(item.id);
});
await DelFoodMenu(ids).then((r) => {
message.destroy();
if (r.data) {
message.success('删除成功');
return true;
} else {
message.error('菜谱已关联到商品,删除失败');
return false;
}
});
} catch (error) {
message.error('删除失败请重试!');
return false;
}
};

const GoodsTypeManage = () => {
const [createModalVisible, handleModalVisible] = useState(false);
const actionRef = useRef();
const [currentRow, setCurrentRow] = useState();
const [selectedRowsState, setSelectedRows] = useState([]);
const columns = [
{
title: '主键',
dataIndex: 'id',
hideInSearch: true,
hideInTable: true,
tip: '规则名称是唯一的 key'
},
{
title: '菜谱编码',
dataIndex: 'code',
valueType: 'textarea',
},
{
title: '菜谱名称',
dataIndex: 'name',
valueType: 'textarea',
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
key="config"
onClick={() => {
handleModalVisible(true);
setCurrentRow(record);
}} > 更新</a>
],
},
];
const [createModalVisible, handleModalVisible] = useState(false);
const actionRef = useRef();
const [currentRow, setCurrentRow] = useState();
const [selectedRowsState, setSelectedRows] = useState([]);
// 是否展示 关联加盟商商品 弹窗
const [menuGoodsModal, setMenuGoodsModal] = useState(false);
const columns = [
{
title: '主键',
dataIndex: 'id',
hideInSearch: true,
hideInTable: true,
tip: '规则名称是唯一的 key'
},
{
title: '菜谱名称',
dataIndex: 'name',
valueType: 'textarea',
},
{
title: '菜谱编码',
dataIndex: 'code',
valueType: 'textarea',
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
key="config"
onClick={() => {
handleModalVisible(true);
setCurrentRow(record);
}} >
编辑
</a>,
<a key="food" onClick={() => {
setCurrentRow(record);
setMenuGoodsModal(true);
}}>
关联加盟商商品
</a>
],
},
];

return (
<PageContainer>
<ProTable
headerTitle="菜谱基础信息"
actionRef={actionRef}
rowKey="id"
search={{
labelWidth: 120,
}}
toolBarRender={() => [
<Button
type="primary"
key="primary"
onClick={() => {
handleModalVisible(true);
}} >
<PlusOutlined /> 新建
</Button>,
]}
request={async (params) => {
var data = [];
var total = 0;
await GetFoodMenuInfoPage(params).then((r) => {
data = r.data.data;
total = r.data.total;
});
return {
data: data,
success: true,
total: total,
};
}}
columns={columns}
rowSelection={{
onChange: (_, selectedRows) => {
setSelectedRows(selectedRows);
},
}}
/>
{selectedRowsState?.length > 0 && (
<FooterToolbar
extra={
<div>
已选择{' '}
<a
style={{
fontWeight: 600,
}}
>
{selectedRowsState.length}
</a>{' '}
项 &nbsp;&nbsp;
</div>
}
>
<Button
onClick={async () => {
await handleRemove(selectedRowsState);
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
}}
>
删除
</Button>
</FooterToolbar>
)}
/**
* 关联加盟商商品成功 回调函数
*/
const handleMenuGoodsOk = () => {
setMenuGoodsModal(false);
}

<CreateForm
onFinish={async (value) => {
var success = false;
if (value.id) {
success = handleUpdate(value);
} else {
success = handleAdd(value);
}
if (success) {
handleModalVisible(false);
setCurrentRow(undefined);
}
actionRef.current?.reloadAndRest?.();
}}
onCancel={() => {
handleModalVisible(false);
setCurrentRow(undefined);
}}
createModalVisible={createModalVisible}
values={currentRow || {}}
/>
</PageContainer>
);
return (
<PageContainer>
<ProTable
headerTitle="菜谱基础信息"
actionRef={actionRef}
rowKey="id"
search={{
labelWidth: 120,
}}
toolBarRender={() => [
<Button
type="primary"
key="primary"
onClick={() => {
handleModalVisible(true);
}} >
<PlusOutlined /> 新建
</Button>,
]}
request={async (params) => {
var data = [];
var total = 0;
await GetFoodMenuInfoPage(params).then((r) => {
data = r.data.data;
total = r.data.total;
});
return {
data: data,
success: true,
total: total,
};
}}
columns={columns}
rowSelection={{
onChange: (_, selectedRows) => {
setSelectedRows(selectedRows);
},
}}
/>
{selectedRowsState?.length > 0 && (
<FooterToolbar
extra={
<div>
已选择{' '}
<a
style={{
fontWeight: 600,
}}
>
{selectedRowsState.length}
</a>{' '}
项 &nbsp;&nbsp;
</div>
}
>
<Button
onClick={async () => {
await handleRemove(selectedRowsState);
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
}}
>
删除
</Button>
</FooterToolbar>
)}

<CreateForm
onFinish={async (value) => {
var success = false;
if (value.id) {
success = handleUpdate(value);
} else {
success = handleAdd(value);
}
if (success) {
handleModalVisible(false);
setCurrentRow(undefined);
}
actionRef.current?.reloadAndRest?.();
}}
onCancel={() => {
handleModalVisible(false);
setCurrentRow(undefined);
}}
createModalVisible={createModalVisible}
values={currentRow || {}}
/>

{
// 菜谱关联加盟商商品 弹窗
currentRow && menuGoodsModal && <MenuGoods foodMenu={currentRow} open={menuGoodsModal} onOk={handleMenuGoodsOk} onCancel={() => setMenuGoodsModal(false)}></MenuGoods>
}
</PageContainer>
);
};

export default GoodsTypeManage;

+ 62
- 21
src/pages/foodMenu/foodMenuInfo/services.js View File

@@ -2,33 +2,74 @@ import { request } from 'umi';

/** 设备菜谱列表 */
export async function GetFoodMenuInfoPage(data) {
return request(`/kitchen/api/FoodMenu/GetFoodMenuInfoPage`, {
method: 'POST',
data: data,
});
}
return request(`/kitchen/api/FoodMenu/GetFoodMenuInfoPage`, {
method: 'POST',
data: data,
});
}

/** 添加菜谱类型 */
/** 添加菜谱类型 */
export async function UpdateFoodMenu(data) {
return request(`/kitchen/api/FoodMenu/AddUpdateFoodMenu`, {
method: 'POST',
data: data,
});
}
return request(`/kitchen/api/FoodMenu/AddUpdateFoodMenu`, {
method: 'POST',
data: data,
});
}

export async function AddFoodMenu(data) {
export async function AddFoodMenu(data) {
return request(`/kitchen/api/FoodMenu/AddUpdateFoodMenu`, {
method: 'POST',
data: data,
});
method: 'POST',
data: data,
});
}

/** 删除菜谱类型 */
/** 删除菜谱类型 */
export async function DelFoodMenu(data) {
return request(`​/kitchen/api/FoodMenu/DelFoodMenu`, {
method: 'POST',
data: data,
});
}
return request(`​/kitchen/api/FoodMenu/DelFoodMenu`, {
method: 'POST',
data: data,
});
}

/**
* 获取所有菜品
* @param {*} params
* @returns
*/
export async function GetAllGoodsMenuPage(params) {
return request('/kitchen/api/FoodMenu/GetGoodsByMenuIdPage', {
method: 'POST',
data: {
...params,
},
});
}

/**
* 根据菜谱ID,查询菜品列表
* @param {*} params
* @param {*} options
* @returns
*/
export async function getpage_v2(params) {
return request('/kitchen/api/FoodMenu/GetFoodMenuGoodsPage_V2', {
method: 'POST',
data: {
...params,
},
});
}

/**
* 添加/删除 菜谱商品
* @param {*} params
* @param {*} options
* @returns
*/
export async function EditFoodMenuGoods(params) {
return request('/kitchen/api/FoodMenu/EditFoodMenuGoods', {
method: 'POST',
data: params,
});
}


+ 183
- 193
src/pages/foodMenu/storeFoodMenu/index.jsx View File

@@ -1,9 +1,8 @@
import { PlusOutlined } from '@ant-design/icons';
import { Card, Tree, Button, message, Input, Drawer, Divider } from 'antd';
import { Card, Tree, Button, message, Popconfirm } from 'antd';
import React, { useState, useRef, useEffect } from 'react';
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout';
import { PageContainer } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import ProDescriptions from '@ant-design/pro-descriptions';
import CreateForm from './components/CreateForm';
import { add, getpage, gettree, DelStoreFoodMenu } from './service';
/**
@@ -13,209 +12,200 @@ import { add, getpage, gettree, DelStoreFoodMenu } from './service';
*/

const handleAdd = async (fields) => {
if (fields.FoodMenuId == undefined) {
message.error('请选择菜谱');
return false;
}
const hide = message.loading('正在添加');
try {
add({ ...fields }).then((r) => {
if (!r.succeeded) {
message.error(r.errors);
hide();
return false;
} else {
hide();
message.success('添加成功');
return true;
}
});
return true;
} catch (error) {
hide();
message.error('添加失败请重试!');
return false;
}
if (fields.FoodMenuId == undefined) {
message.error('请选择菜谱');
return false;
}
const hide = message.loading('正在添加');
try {
add({ ...fields }).then((r) => {
if (!r.succeeded) {
message.error(r.errors);
hide();
return false;
} else {
hide();
message.success('添加成功');
return true;
}
});
return true;
} catch (error) {
hide();
message.error('添加失败请重试!');
return false;
}
};
/**
* 删除节点
*
* @param selectedRows
*/
const handleRemove = async (selectedRows,FoodMenuId) => {
debugger
try {
const hide = message.loading('正在删除');
let ids = [];
selectedRows.forEach((item) => {
ids.push(item.id);
});
debugger
await DelStoreFoodMenu({
"storeIds": ids,
"foodMenuId": FoodMenuId
}).then((r) => {
hide();
if (r.data) {
message.success('删除成功');
return true;
} else {
message.error('删除失败');
return false;
}
});
} catch (error) {
message.error('删除失败请重试!');
return false;
}
const handleRemove = async (selectedRows, FoodMenuId) => {
try {
const hide = message.loading('正在删除');
let ids = [];
selectedRows.forEach((item) => {
ids.push(item.id);
});
await DelStoreFoodMenu({
"storeIds": ids,
"foodMenuId": FoodMenuId
}).then((r) => {
hide();
if (r.data) {
message.success('删除成功');
return true;
} else {
message.error('删除失败');
return false;
}
});
} catch (error) {
message.error('删除失败请重试!');
return false;
}
};
const TableList = () => {
/** 新建窗口的弹窗 */
const [createModalVisible, handleModalVisible] = useState();
/*绑定数据 */
const actionRef = useRef();
const [treeData, setTreeData] = useState();
/*选中*/
const [selectedRowsState, setSelectedRows] = useState();
/** 新建窗口的弹窗 */
const [createModalVisible, handleModalVisible] = useState();
/*绑定数据 */
const actionRef = useRef();
const [treeData, setTreeData] = useState();
/*选中*/
const [selectedRowsState, setSelectedRows] = useState();

const [FoodMenuId, setKey] = useState();
/** 国际化配置 */
useEffect(() => {
function initfranchiseeType() {
gettree().then((r) => {
setTreeData(r.data);
});
}
initfranchiseeType();
}, []);
const columns = [
{
title: '店铺名称',
dataIndex: 'name',
search:false
}
];
return (
<PageContainer>
<ProTable
headerTitle="店铺列表"
actionRef={actionRef}
rowKey="id"
search={{
labelWidth: 120,
}}
tableRender={(_, dom) => (
<div
style={{
display: 'flex',
width: '100%',
}}
>
<Card title="菜谱列表">
<Tree defaultExpandAll={true} onSelect={(e) => setKey(e[0])} treeData={treeData} />
</Card>
<div
style={{
flex: 1,
}}
>
{dom}
</div>
</div>
)}
toolBarRender={() => [
<Button
type="primary"
key="primary"
onClick={() => {
handleModalVisible(true);
}}
>
<PlusOutlined /> 选择店铺
</Button>,
]}
params={{
FoodMenuId,
}}
request={async (params) => {
let UserData = [];
var total = 0;
const [FoodMenuId, setKey] = useState();
/** 国际化配置 */
useEffect(() => {
function initfranchiseeType() {
gettree().then((r) => {
setTreeData(r.data);
});
}
initfranchiseeType();
}, []);
const columns = [
{
title: '店铺名称',
dataIndex: 'name',
search: false
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<Popconfirm
title={`确定要将【${record.name}】移出此菜谱吗?`}
onConfirm={() => handleRemoveStore(record)}
okText="确定"
cancelText="取消"
>
<a
key="delete"
>
移除门店
</a>
</Popconfirm>,
],
},
];
/**
* 将门店移出当前菜谱
*/
const handleRemoveStore = async (store) => {
await handleRemove([store], FoodMenuId);
actionRef.current?.reloadAndRest?.();
}
return (
<PageContainer>
<ProTable
headerTitle="店铺列表"
actionRef={actionRef}
rowKey="id"
search={{
labelWidth: 120,
}}
tableRender={(_, dom) => (
<div
style={{
display: 'flex',
width: '100%',
}}
>
<Card title="菜谱列表">
<Tree defaultExpandAll={true} onSelect={(e) => setKey(e[0])} treeData={treeData} />
</Card>
<div
style={{
flex: 1,
}}
>
{dom}
</div>
</div>
)}
toolBarRender={() => [
<Button
type="primary"
key="primary"
onClick={() => {
handleModalVisible(true);
}}
>
<PlusOutlined /> 选择店铺
</Button>,
]}
params={{
FoodMenuId,
}}
request={async (params) => {
let UserData = [];
var total = 0;

await getpage(params).then((r) => {
UserData = r.data.data;
total = r.data.total;
});
return {
data: UserData,
success: true,
total: total,
};
}}
columns={columns}
rowSelection={{
onChange: (_, selectedRows) => {
setSelectedRows(selectedRows);
},
}}
/>
{selectedRowsState?.length > 0 && (
<FooterToolbar
extra={
<div>
已选择{' '}
<a
style={{
fontWeight: 600,
}}
>
{selectedRowsState.length}
</a>{' '}
项 &nbsp;&nbsp;
</div>
}
>
<Button
onClick={async () => {
await handleRemove(selectedRowsState,FoodMenuId);
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
}}
>
批量删除
</Button>
</FooterToolbar>
)}
<CreateForm
onSubmit={async (value) => {
await getpage(params).then((r) => {
UserData = r.data.data;
total = r.data.total;
});
return {
data: UserData,
success: true,
total: total,
};
}}
columns={columns}
/>

if (typeof (FoodMenuId) == undefined) {
handleModalVisible(false);
} else {
const defaultData = [];
value.map((data) => {
defaultData.push({ StoreId: data.id });
});
const valuejson = { FoodMenuId: FoodMenuId, StoreIds: defaultData }
var success = false;
success = await handleAdd(valuejson);
if (success) {
handleModalVisible(false);
if (actionRef.current) {
actionRef.current.reload();
}
}
}
<CreateForm
onSubmit={async (value) => {

if (typeof (FoodMenuId) == undefined) {
handleModalVisible(false);
} else {
const defaultData = [];
value.map((data) => {
defaultData.push({ StoreId: data.id });
});
const valuejson = { FoodMenuId: FoodMenuId, StoreIds: defaultData }
var success = false;
success = await handleAdd(valuejson);
if (success) {
handleModalVisible(false);
actionRef.current?.reload();
}
}

}}
onCancel={() => {
handleModalVisible(false);
}}
modalVisible={createModalVisible}
values={FoodMenuId}
/>
</PageContainer>
);

}}
onCancel={() => {
handleModalVisible(false);
}}
modalVisible={createModalVisible}
values={FoodMenuId}
/>
</PageContainer>
);
};

export default TableList;

Loading…
Cancel
Save