Browse Source

门店模块优化

tags/小炒逻辑变更前
yangwenhua 2 years ago
parent
commit
d941fc456e
11 changed files with 1303 additions and 1266 deletions
  1. +1
    -0
      src/pages/document.ejs
  2. +114
    -0
      src/pages/quickStart/components/BaiDuMapPostion/index.jsx
  3. +440
    -498
      src/pages/quickStart/components/BomConfig/index.jsx
  4. +99
    -105
      src/pages/quickStart/components/ConfirmConfig/index.jsx
  5. +389
    -423
      src/pages/quickStart/components/DeviceConfig/index.jsx
  6. +186
    -209
      src/pages/quickStart/components/FoodMenuConfig/index.jsx
  7. +0
    -1
      src/pages/quickStart/components/GoodsConfig/index.jsx
  8. +0
    -2
      src/pages/quickStart/components/MaterialConfig/index.jsx
  9. +37
    -19
      src/pages/quickStart/components/StoreConfig/index.jsx
  10. +21
    -9
      src/pages/quickStart/index.jsx
  11. +16
    -0
      src/pages/quickStart/index.less

+ 1
- 0
src/pages/document.ejs View File

@@ -23,6 +23,7 @@
/>
<title>Ant Design Pro</title>
<link rel="icon" href="<%= context.config.publicPath +'favicon.ico'%>" type="image/x-icon" />
<script src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=Rvf71uBzNi7rWo1bhCvzbmLTFbPihNur"></script>
</head>
<body>
<noscript>Out-of-the-box mid-stage front/design solution!</noscript>


+ 114
- 0
src/pages/quickStart/components/BaiDuMapPostion/index.jsx View File

@@ -0,0 +1,114 @@
import React, { useState, useEffect, useRef } from 'react';
import { Modal, Select, message } from 'antd';

const { Option } = Select;
let timeout;

const BaiDuMapPostion = (props) => {

const [baiduMap, setBaiduMap] = useState(null);
const [searchLocal, setSearchLocal] = useState(null);
const [searchList, setSearchList] = useState([]);
const [currentPos, setCurrentPos] = useState(null);

const handleOk = () => {
if (currentPos) {
props.handleOk(currentPos);
} else {
message.error('请选择店铺地址');
}
}

const onChange = (value) => {
if (value && baiduMap) {
baiduMap.clearOverlays();
const findPos = searchList.find(item => item.uid === value);
if (findPos) {
setCurrentPos(findPos);
const point = new BMapGL.Point(findPos.point.lng, findPos.point.lat);
baiduMap.centerAndZoom(point, 16);
const marker = new BMapGL.Marker(point);
baiduMap.addOverlay(marker);
const infoWindow = new BMapGL.InfoWindow(findPos.address, {
width: 200, // 信息窗口宽度
height: 100, // 信息窗口高度
title: findPos.title, // 信息窗口标题
message: findPos.address
}); // 创建信息窗口对象
marker.addEventListener("click", () => {
baiduMap.openInfoWindow(infoWindow, point); //开启信息窗口
});
}
}
};

const onSearch = (value) => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
if (baiduMap) {
if (searchLocal === null) {
const local = new BMapGL.LocalSearch(baiduMap, {
onSearchComplete: result => {
if (result) {
setSearchList(JSON.parse(JSON.stringify(result._pois)));
}
}
});
timeout = setTimeout(() => {
local.search(value);
}, 300);
setSearchLocal(local);
} else {
timeout = setTimeout(() => {
searchLocal.search(value);
}, 300);
}
}
};

const initBaiduMap = () => {
const map = new BMapGL.Map('baidu_map_container'); // 创建Map实例
map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
map.setHeading(64.5);
map.setTilt(73);
const localcity = new BMapGL.LocalCity();
localcity.get(e => {
if (e) {
map.centerAndZoom(new BMapGL.Point(e.center.lng, e.center.lat), 12); // 初始化地图,设置中心点坐标和地图级别
}
});
setBaiduMap(map);
}

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

return <>
<Modal width={800} title="选择店铺坐标" visible={props.isShowBaiduMap} onOk={handleOk} onCancel={props.handleCancel}>
<Select
showSearch
placeholder="请输入地址"
onChange={onChange}
onSearch={onSearch}
defaultActiveFirstOption={false}
showArrow={false}
filterOption={false}
notFoundContent={null}
style={{ width: '100%', marginBottom: '10px' }}
size="large"
>
{
searchList?.map(item => {
return <Option key={item.uid} value={item.uid}>{item.title} 【{item.address}】</Option>
})
}
</Select>
<div id="baidu_map_container" style={{ width: '750px', height: '700px' }}></div>
</Modal>
</>
}

export default BaiDuMapPostion;

+ 440
- 498
src/pages/quickStart/components/BomConfig/index.jsx View File

@@ -1,553 +1,495 @@
import React, { useState, useEffect, useRef } from 'react';
import ProTable from '@ant-design/pro-table';
import {
Form,
Input,
Select,
InputNumber,
Space,
Tag,
message,
Button,
Modal,
Switch,
Drawer,
Table,
notification,
} from 'antd';
import { Form, Input, Select, InputNumber, Space, Tag, message, Button, Modal, Switch, Drawer, Table, notification } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import quickAPI from '../../service';
import indexStyles from '../../index.less';
import StepsButton from '../StepsButton';
import quickAPI from "../../service";
import indexStyles from "../../index.less";

/**
* 配方配置
* @returns
* @returns
*/
const BomConfig = (props) => {
const [editBomForm] = Form.useForm();

const onFinish = async (values) => {
if (values.id) {
quickAPI.UpdateBom(values).then((r) => {
if (r.data) {
message.success('修改成功');
} else {
message.error('修改失败请重试!');
}
//刷新数据
actionRef.current.reload();
setIsShowModal(false);
});
} else {
quickAPI.AddBom(values).then((r) => {
if (r.data) {
message.success('添加成功');
//刷新数据
actionRef.current.reload();
setIsShowModal(false);
const [editBomForm] = Form.useForm();

const onFinish = async (values) => {
if (values.id) {
quickAPI.UpdateBom(values).then((r) => {
if (r.data) {
message.success('修改成功');
} else {
message.error('修改失败请重试!');
}
//刷新数据
actionRef.current.reload();
setIsShowModal(false);
});
} else {
message.error('添加失败请重试!');
quickAPI.AddBom(values).then((r) => {
if (r.data) {
message.success('添加成功');
//刷新数据
actionRef.current.reload();
setIsShowModal(false);
} else {
message.error('添加失败请重试!');
}
});
}
});
}
};

const columns = [
{
title: '主键',
dataIndex: 'id',
hideInTable: true,
hideInSearch: true,
},
{
title: '配方编码',
dataIndex: 'code',
hideInForm: true,
hideInSearch: true,
},
{
title: '配方名称',
dataIndex: 'name',
hideInForm: true,
hideInSearch: true,
},
{
title: '排序',
dataIndex: 'sort',
hideInForm: true,
hideInSearch: true,
},
{
title: '配方分类',
dataIndex: 'bomTypeList',
search: false,
width: 450,
render: (_, record) => (
<Space>
{bomtype
.filter((x) => {
let findId = record.bomTypeList.find((findItem) => findItem === x.id);
let findBomType = bomtype.find((bomItem) => bomItem.id === findId);
return findBomType != null || undefined;
})
.map((item) => (
<Tag color="#87d068" key={item.id}>
{item.name}
</Tag>
))}
</Space>
),
},
{
title: '配方类型',
dataIndex: 'isMain',
hideInForm: true,
valueEnum: {
false: {
text: '辅料配方',
status: 'Processing',
const columns = [
{
title: '主键',
dataIndex: 'id',
hideInTable: true,
hideInSearch: true,
},
true: {
text: '主料配方',
status: 'Success',
{
title: '配方编码',
dataIndex: 'code',
hideInForm: true,
hideInSearch: true,
},
},
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
key="primary3"
type="primary"
onClick={() => {
setIsShowModal(true);
setCurrentOption(record);
editBomForm.setFieldsValue(record);
}}
>
更新
</a>,
],
},
];
{
title: '配方名称',
dataIndex: 'name',
hideInForm: true,
hideInSearch: true,
},
{
title: '排序',
dataIndex: 'sort',
hideInForm: true,
hideInSearch: true,
},
{
title: '配方分类',
dataIndex: 'bomTypeList',
search: false,
width: 450,
render: (_, record) => (
<Space>
{
bomtype.filter(x => {
let findId = record.bomTypeList.find(findItem => findItem === x.id);
let findBomType = bomtype.find(bomItem => bomItem.id === findId);
return findBomType != null || undefined;
}).map(item => (
<Tag color="#87d068" key={item.id}>
{item.name}
</Tag>
))
}
</Space>
),
},
{
title: '配方类型',
dataIndex: 'isMain',
hideInForm: true,
valueEnum: {
false: {
text: '辅料配方',
status: 'Processing',
},
true: {
text: '主料配方',
status: 'Success',
},
},
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
key="primary3"
type="primary"
onClick={() => {
setIsShowModal(true);
setCurrentOption(record);
editBomForm.setFieldsValue(record);
}}
>
更新
</a>
],
},
];

const columnsChoose = [
{
title: '配方名称',
dataIndex: 'name',
hideInForm: true,
hideInSearch: true,
},
];
const columnsChoose = [
{
title: '配方名称',
dataIndex: 'name',
hideInForm: true,
hideInSearch: true,
}
];

const [currentPage, setCurrentPage] = useState(0);
const [pageSize, setPageSize] = useState(5);
const [currentPage, setCurrentPage] = useState(0);
const [pageSize, setPageSize] = useState(5);

const [selectedRows, setSetSelectedRows] = useState([]);
const [selectedRowKeys, setSelectRowKeys] = useState([]);
//配方类型
const [bomtype, setBomtype] = useState([]);
//是否展示配方弹窗
const [isShowBomModal, setIsShowBomModal] = useState(false);
const [selectedRows, setSetSelectedRows] = useState([]);
const [selectedRowKeys, setSelectRowKeys] = useState([]);
//配方类型
const [bomtype, setBomtype] = useState([]);
//是否展示配方弹窗
const [isShowBomModal, setIsShowBomModal] = useState(false);

/**
* 获取配方分类
*/
const onFetchBomType = async () => {
const response = await quickAPI.GetBomTypePage({
current: 1,
pagesize: 1000,
});
if (response.statusCode === 200) {
setBomtype(response.data.data);
/**
* 获取配方分类
*/
const onFetchBomType = async () => {
const response = await quickAPI.GetBomTypePage({
current: 1,
pagesize: 1000
});
if (response.statusCode === 200) {
setBomtype(response.data.data);
}
}
};

//当前操作的配方对象
const [currentOption, setCurrentOption] = useState({ id: '' });
//是否显示 新增/编辑 菜谱弹窗
const [isShowModal, setIsShowModal] = useState(false);
const actionRef = useRef();
//当前操作的配方对象
const [currentOption, setCurrentOption] = useState({ id: '' });
//是否显示 新增/编辑 菜谱弹窗
const [isShowModal, setIsShowModal] = useState(false);
const actionRef = useRef();

//商品绑定菜谱弹窗
const [showMenuDrawer, setShowMenuDrawer] = useState(false);
//当前选中的商品
const [currentSelectedFood, setCurrentSelectedFood] = useState('');
//商品下拉列表
const [foodDropDown, setFoodDropDown] = useState([]);
//某商品下面的配方列表
const [bomBelongToGoods, setBomBelongToGoods] = useState([]);
//商品绑定菜谱弹窗
const [showMenuDrawer, setShowMenuDrawer] = useState(false);
//当前选中的商品
const [currentSelectedFood, setCurrentSelectedFood] = useState('');
//商品下拉列表
const [foodDropDown, setFoodDropDown] = useState([]);
//某商品下面的配方列表
const [bomBelongToGoods, setBomBelongToGoods] = useState([]);

const goodsBomColumns = [
{
title: '配方名称',
dataIndex: 'name',
hideInForm: true,
hideInSearch: true,
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
key="primary3"
type="primary"
onClick={() => {
props.onBomRelationGoods(record.goodsId, record, false);
}}
>
移除配方
</a>,
],
},
];
const goodsBomColumns = [
{
title: '配方名称',
dataIndex: 'name',
hideInForm: true,
hideInSearch: true,
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
key="primary3"
type="primary"
onClick={() => {
props.onBomRelationGoods(record.goodsId, record, false);
}}
>
移除配方
</a>
],
}
]

/**
* 初始化商品下拉列表
*/
const initFoodDropDown = () => {
const goodsArray = [];
props.foodMenuConfig.forEach((menuItem) => {
const foodMenuId = menuItem.id;
if (menuItem.goodsConfig) {
menuItem.goodsConfig.forEach((goodsItem) => {
goodsItem.foodMenuId = foodMenuId;
const findRepet = goodsArray.find((item) => item.id === goodsItem.id);
if (!findRepet) {
goodsArray.push(goodsItem);
}
/**
* 初始化商品下拉列表
*/
const initFoodDropDown = () => {
const goodsArray = [];
props.foodMenuConfig.forEach(menuItem => {
const foodMenuId = menuItem.id;
if (menuItem.goodsConfig) {
menuItem.goodsConfig.forEach(goodsItem => {
goodsItem.foodMenuId = foodMenuId;
const findRepet = goodsArray.find(item => item.id === goodsItem.id);
if (!findRepet) {
goodsArray.push(goodsItem);
}
});
}
});
}
});
if (!currentSelectedFood) {
setCurrentSelectedFood(goodsArray[0].id);
if (!currentSelectedFood) {
setCurrentSelectedFood(goodsArray[0].id);
}
setFoodDropDown(goodsArray);
}
setFoodDropDown(goodsArray);
};

//根据商品ID渲染配方列表
const initGoodsBom = () => {
const findGoods = foodDropDown.find((item) => item.id === currentSelectedFood);
if (findGoods && findGoods.bomConfig) {
setBomBelongToGoods(findGoods.bomConfig);
} else {
setBomBelongToGoods([]);
//根据商品ID渲染配方列表
const initGoodsBom = () => {
const findGoods = foodDropDown.find(item => item.id === currentSelectedFood);
if (findGoods && findGoods.bomConfig) {
setBomBelongToGoods(findGoods.bomConfig);
} else {
setBomBelongToGoods([]);
}
}
};

/**
* 配方关联商品
*/
const bomRelationGoods = () => {
if (selectedRows.length === 0) {
notification.error({
message: '配方关联商品出错',
description: '请选择配方',
placement: 'topRight',
});
return;
}
const findGoods = foodDropDown.find((item) => item.id === currentSelectedFood);
if (findGoods) {
selectedRows.forEach((item) => {
item.foodMenuId = findGoods.foodMenuId;
item.goodsId = findGoods.id;
});
props.onBomRelationGoods(findGoods.id, selectedRows);
setSelectRowKeys([]);
setSetSelectedRows([]);
/**
* 配方关联商品
*/
const bomRelationGoods = () => {
if (selectedRows.length === 0) {
notification.error({
message: '配方关联商品出错',
description: '请选择配方',
placement: 'topRight'
});
return;
}
const findGoods = foodDropDown.find(item => item.id === currentSelectedFood);
if (findGoods) {
selectedRows.forEach(item => {
item.foodMenuId = findGoods.foodMenuId;
item.goodsId = findGoods.id;
});
props.onBomRelationGoods(findGoods.id, selectedRows);
setSelectRowKeys([]);
setSetSelectedRows([]);
}
}
};

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

useEffect(() => {
initFoodDropDown();
}, [props.foodMenuConfig]);
useEffect(() => {
initFoodDropDown();
}, [props.foodMenuConfig]);

useEffect(() => {
initGoodsBom();
}, [foodDropDown, currentSelectedFood]);
useEffect(() => {
initGoodsBom();
}, [foodDropDown, currentSelectedFood]);

return (
<>
<Modal
width={600}
title={currentOption.id ? '编辑配方' : '新增配方'}
visible={isShowModal}
footer={false}
onCancel={() => setIsShowModal(false)}
>
<Form
labelCol={{ span: 4 }}
layout="horizontal"
preserve={false}
onFinish={onFinish}
form={editBomForm}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
return <>
<Modal width={600} title={currentOption.id ? '编辑配方' : '新增配方'} visible={isShowModal} footer={false} onCancel={() => setIsShowModal(false)}>
<Form
labelCol={{ span: 4 }}
layout="horizontal"
preserve={false}
onFinish={onFinish}
form={editBomForm}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>

<Form.Item name="code" label="配方编码" rules={[{ required: true }]}>
<Input placeholder="配方编码" />
</Form.Item>
<Form.Item name="code" label="配方编码" rules={[{ required: true }]} >
<Input placeholder="配方编码" />
</Form.Item>

<Form.Item name="name" label="配方名称" rules={[{ required: true }]}>
<Input placeholder="配方名称" />
</Form.Item>
<Form.Item name="name" label="配方名称" rules={[{ required: true }]}>
<Input placeholder="配方名称" />
</Form.Item>

<div className={indexStyles.add_row_content}>
<Form.Item name="bomTypeList" label="配方类型" rules={[{ required: true }]}>
<Select style={{ width: '70%' }} mode="multiple" allowClear>
{bomtype.map((item, index) => {
return (
<Select.Option index={item.id} value={item.id} key={item.id}>
{item.name}
</Select.Option>
);
})}
</Select>
</Form.Item>
<Button
type="primary"
className={indexStyles.add_row_btn}
onClick={() => setIsShowBomModal(true)}
>
添加配方类型
</Button>
</div>
<div className={indexStyles.add_row_content}>
<Form.Item name="bomTypeList" label="配方类型" rules={[{ required: true }]}>
<Select
style={{ width: '70%' }}
mode="multiple"
allowClear
>
{bomtype.map((item, index) => {
return (
<Select.Option index={item.id} value={item.id} key={item.id}>
{item.name}
</Select.Option>
);
})}
</Select>
</Form.Item>
<Button type="primary" className={indexStyles.add_row_btn} onClick={() => setIsShowBomModal(true)} >添加配方类型</Button>
</div>

<Form.Item name="isMain" label="配方类型">
<Switch checkedChildren="主料" unCheckedChildren="辅料" />
</Form.Item>
<Form.Item name="isMain" label="配方类型" >
<Switch checkedChildren="主料" unCheckedChildren="辅料" />
</Form.Item>

<Form.Item name="sort" label="排序" rules={[{ required: true }]}>
<InputNumber placeholder="排序" min={1} />
</Form.Item>
<Form.Item name="sort" label="排序" rules={[{ required: true }]}>
<InputNumber placeholder="排序" min={1} />
</Form.Item>

<Form.Item>
<Button type="primary" htmlType="submit">
确定
</Button>
</Form.Item>
</Form>
</Modal>
<Form.Item>
<Button type="primary" htmlType="submit">
确定
</Button>
</Form.Item>
</Form>
</Modal>

<Modal
title="新建配方类型"
width={640}
bodyStyle={{ padding: '32px 40px 48px' }}
visible={isShowBomModal}
footer={null}
onCancel={() => {
setIsShowBomModal(false);
}}
destroyOnClose
maskClosable={false}
>
<Form
layout="vertical"
preserve={false}
initialValues={props?.values}
onFinish={async (values) => {
const response = await quickAPI.CreateBomType(values);
if (response.data) {
message.success('配方类别添加成功');
setIsShowBomModal(false);
onFetchBomType();
} else {
message.error(response.errors || '配方类别添加失败');
}
}}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
<Form.Item
name="name"
label="配方类型名称"
rules={[{ required: true, max: 64, whitespace: true }]}
>
<Input placeholder="请输入配方类型名称" />
</Form.Item>
<Form.Item
name="pertain"
label="归属"
defaultValue={props?.values?.pertain}
rules={[{ required: true, message: '请选择类型归属' }]}
>
<Select placeholder="请选择类型归属">
<Option value="1">无</Option>
<Option value="2">TMC </Option>
</Select>
</Form.Item>
<Form.Item
name="status"
label="状态"
defaultValue={props?.values?.status}
rules={[{ required: true, message: '请选择状态' }]}
>
<Select placeholder="请选择状态">
<Option value="0">正常</Option>
<Option value="1">停用</Option>
</Select>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
保存
</Button>
</Form.Item>
</Form>
</Modal>

<ProTable
actionRef={actionRef}
style={{ width: '100%' }}
headerTitle="配方列表"
rowKey="id"
pagination={{
current: currentPage,
pageSize: pageSize,
onChange: (page, pageSize) => {
setCurrentPage(page);
setPageSize(pageSize);
},
}}
search={false}
//数据绑定
request={async (params) => {
var goodsBomsData = [];
var total = 0;
await quickAPI.GetBomPage(params).then((r) => {
goodsBomsData = r.data.data;
total = r.data.total;
});
return {
data: goodsBomsData,
success: true,
total: total,
};
}}
columns={columns}
toolBarRender={() => [
<Button
key="button"
icon={<PlusOutlined />}
type="primary"
onClick={() => {
editBomForm.resetFields();
setCurrentOption({ id: '' });
setIsShowModal(true);
}}
>
新建
</Button>,
<Button
key="button"
type="primary"
onClick={() => {
setShowMenuDrawer(true);
<Modal
title="新建配方类型"
width={640}
bodyStyle={{ padding: '32px 40px 48px' }}
visible={isShowBomModal}
footer={null}
onCancel={() => {
setIsShowBomModal(false);
}}
>
关联商品
</Button>,
]}
/>
destroyOnClose
maskClosable={false}
>
<Form
layout="vertical"
preserve={false}
initialValues={props?.values}
onFinish={async (values) => {
const response = await quickAPI.CreateBomType(values);
if (response.data) {
message.success('配方类别添加成功');
setIsShowBomModal(false);
onFetchBomType();
} else {
message.error(response.errors || '配方类别添加失败');
}
}}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
<Form.Item name="name" label="配方类型名称" rules={[{ required: true, max: 64, whitespace: true }]}>
<Input placeholder="请输入配方类型名称" />
</Form.Item>
<Form.Item
name="pertain"
label="归属"
defaultValue={props?.values?.pertain}
rules={[{ required: true, message: '请选择类型归属' }]} >
<Select placeholder="请选择类型归属">
<Option value="1">无</Option>
<Option value="2">TMC </Option>
</Select>
</Form.Item>
<Form.Item
name="status"
label="状态"
defaultValue={props?.values?.status}
rules={[{ required: true, message: '请选择状态' }]}
>
<Select placeholder="请选择状态">
<Option value="0">正常</Option>
<Option value="1">停用</Option>
</Select>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
保存
</Button>
</Form.Item>
</Form>
</Modal>

<Drawer
width={800}
title="配方关联商品"
placement="right"
onClose={() => setShowMenuDrawer(false)}
visible={showMenuDrawer}
>
<div style={{ display: 'flex', alignItems: 'center', marginBottom: '10px' }}>
<div className={indexStyles.current_selected_obj}>当前商品:</div>
<Select
className={indexStyles.current_selected_cmp}
onChange={(item) => {
setCurrentSelectedFood(item);
}}
placeholder="请选择商品"
value={currentSelectedFood}
size="large"
>
{foodDropDown.map((item) => {
return (
<Option key={item.id} value={item.id}>
{item.name}
</Option>
);
})}
</Select>
</div>
<div className={indexStyles.add_to_some_box}>
<ProTable
<ProTable
actionRef={actionRef}
className={indexStyles.wait_add_list}
style={{ width: '100%' }}
headerTitle="配方列表"
rowKey="id"
pagination={{
current: currentPage,
pageSize: pageSize,
onChange: (page, pageSize) => {
setCurrentPage(page);
setPageSize(pageSize);
},
current: currentPage,
pageSize: pageSize,
onChange: (page, pageSize) => {
setCurrentPage(page);
setPageSize(pageSize);
}
}}
search={false}
//数据绑定
request={async (params) => {
var goodsBomsData = [];
var total = 0;
await quickAPI.GetBomPage(params).then((r) => {
goodsBomsData = r.data.data;
total = r.data.total;
});
return {
data: goodsBomsData,
success: true,
total: total,
};
}}
columns={columnsChoose}
rowSelection={{
type: 'checkbox',
onChange: (selectedRowKeys, selectedRows) => {
setSelectRowKeys(selectedRowKeys);
setSetSelectedRows(selectedRows);
},
selectedRowKeys: selectedRowKeys,
var goodsBomsData = [];
var total = 0;
await quickAPI.GetBomPage(params).then((r) => {
goodsBomsData = r.data.data;
total = r.data.total;
});
return {
data: goodsBomsData,
success: true,
total: total,
};
}}
/>
<Table
className={indexStyles.success_add_list}
rowKey="id"
columns={goodsBomColumns}
dataSource={bomBelongToGoods}
/>
</div>
<Button className={indexStyles.sure_add_btn} type="primary" onClick={bomRelationGoods}>
确定关联
</Button>
</Drawer>
columns={columns}
toolBarRender={() => [
<Button key="button" icon={<PlusOutlined />} type="primary" onClick={() => {
editBomForm.resetFields();
setCurrentOption({ id: '' });
setIsShowModal(true);
}}>
新建
</Button>,
<Button key="button" type="primary" onClick={() => {
setShowMenuDrawer(true);
}}>
关联商品
</Button>,
]}
/>

<Drawer width={800} title="配方关联商品" placement="right" onClose={() => setShowMenuDrawer(false)} visible={showMenuDrawer}>
<div style={{ display: 'flex', alignItems: 'center', marginBottom: '10px' }}>
<div className={indexStyles.current_selected_obj}>
当前商品:
</div>
<Select
className={indexStyles.current_selected_cmp}
onChange={(item) => {
setCurrentSelectedFood(item);
}}
placeholder="请选择商品"
value={currentSelectedFood}
size="large"
>
{
foodDropDown.map(item => {
return <Option key={item.id} value={item.id}>{item.name}</Option>
})
}
</Select>

<StepsButton
foodMenuConfig={props.foodMenuConfig}
current={props.current}
steps={props.steps}
prev={props.prev}
next={props.next}
></StepsButton>
</div>
<div className={indexStyles.add_to_some_box}>
<ProTable
actionRef={actionRef}
className={indexStyles.wait_add_list}
headerTitle="配方列表"
rowKey="id"
pagination={{
current: currentPage,
pageSize: pageSize,
onChange: (page, pageSize) => {
setCurrentPage(page);
setPageSize(pageSize);
}
}}
search={false}
//数据绑定
request={async (params) => {
var goodsBomsData = [];
var total = 0;
await quickAPI.GetBomPage(params).then((r) => {
goodsBomsData = r.data.data;
total = r.data.total;
});
return {
data: goodsBomsData,
success: true,
total: total,
};
}}
columns={columnsChoose}
rowSelection={{
type: 'checkbox',
onChange: (selectedRowKeys, selectedRows) => {
setSelectRowKeys(selectedRowKeys);
setSetSelectedRows(selectedRows);
},
selectedRowKeys: selectedRowKeys
}}
/>
<Table className={indexStyles.success_add_list} rowKey="id" columns={goodsBomColumns} dataSource={bomBelongToGoods} />
</div>
<Button className={indexStyles.sure_add_btn} type='primary' onClick={bomRelationGoods}>确定关联</Button>
</Drawer>
</>
);
};
}

export default BomConfig;
export default BomConfig;

+ 99
- 105
src/pages/quickStart/components/ConfirmConfig/index.jsx View File

@@ -1,128 +1,122 @@
import React, { useState, useEffect, useRef } from 'react';

import quickAPI from '../../service';
import indexStyles from '../../index.less';
import StepsButton from '../StepsButton';
import quickAPI from "../../service";
import indexStyles from "../../index.less";
import { message } from 'antd';



/**
* 确认配置
* @returns
* @returns
*/
const ConfirmConfig = (props) => {
const data = {
id: 'root',
value: {
name: '股东会',
},
children: [
{
id: 'joel',

const data = {
id: 'root',
value: {
name: 'Joel Alan',
name: '股东会',
},
children: [
{
id: 'c1',
value: {
name: 'c1',
},
children: [
{
id: 'c1-1',
value: {
name: 'c1-1',
},
},
{
id: 'c1-2',
{
id: 'joel',
value: {
name: 'c1-2',
name: 'Joel Alan',
},
children: [
{
id: 'c1-2-1',
value: {
name: 'c1-2-1',
{
id: 'c1',
value: {
name: 'c1',
},
children: [
{
id: 'c1-1',
value: {
name: 'c1-1',
},
},
{
id: 'c1-2',
value: {
name: 'c1-2',
},
children: [
{
id: 'c1-2-1',
value: {
name: 'c1-2-1',
},
},
{
id: 'c1-2-2',
value: {
name: 'c1-2-2',
},
},
],
},
],
},
},
{
id: 'c1-2-2',
value: {
name: 'c1-2-2',
{
id: 'c2',
value: {
name: 'c2',
},
},
},
],
},
],
},
{
id: 'c2',
value: {
name: 'c2',
},
},
{
id: 'c3',
value: {
name: 'c3',
},
children: [
{
id: 'c3-1',
value: {
name: 'c3-1',
},
},
{
id: 'c3-2',
value: {
name: 'c3-2',
},
children: [
{
id: 'c3-2-1',
value: {
name: 'c3-2-1',
},
},
{
id: 'c3-2-2',
value: {
name: 'c3-2-2',
{
id: 'c3',
value: {
name: 'c3',
},
children: [
{
id: 'c3-1',
value: {
name: 'c3-1',
},
},
{
id: 'c3-2',
value: {
name: 'c3-2',
},
children: [
{
id: 'c3-2-1',
value: {
name: 'c3-2-1',
},
},
{
id: 'c3-2-2',
value: {
name: 'c3-2-2',
},
},
{
id: 'c3-2-3',
value: {
name: 'c3-2-3',
},
},
],
},
{
id: 'c3-3',
value: {
name: 'c3-3',
},
},
],
},
},
{
id: 'c3-2-3',
value: {
name: 'c3-2-3',
},
},
],
},
{
id: 'c3-3',
value: {
name: 'c3-3',
},
},
],
},
},
],
},
],
};
};

return (
<>
<StepsButton
quickStartObj={props.quickStartObj}
current={props.current}
steps={props.steps}
prev={props.prev}
></StepsButton>
return <>
</>
);
};
}

export default ConfirmConfig;

+ 389
- 423
src/pages/quickStart/components/DeviceConfig/index.jsx View File

@@ -1,443 +1,409 @@
import React, { useState, useEffect, useRef } from 'react';
import { Form, Input, Select, InputNumber, TreeSelect, message, Button, Modal, Radio } from 'antd';
import ProTable from '@ant-design/pro-table';
import quickAPI from '../../service';
import StepsButton from '../StepsButton';
import styles from './index.less';
import indexStyles from '../../index.less';
import quickAPI from "../../service";
import styles from "./index.less";
import indexStyles from "../../index.less";
import { PlusOutlined } from '@ant-design/icons';

const key = 'message';
const key = "message";


const DeviceConfig = (props) => {
const { Option, OptGroup } = Select;
const [addDeviceTypeForm] = Form.useForm();
const [editDeviceForm] = Form.useForm();

//设备类型列表
const [deviceTypeList, setDeviceTypeList] = useState([]);
//设备分类
const [deviceClassList, setDeviceClassList] = useState([]);
const [deviceClassEnum, setDeviceClassEnum] = useState({});
//组织树
const [orgTree, setOrgTree] = useState([]);
//设备版本
const [deviceVersion, setDeviceVersion] = useState([]);
//是否显示设备分类弹窗
const [isModalOpen, setIsModalOpen] = useState(false);

//当前操作的设备对象
const [currentOption, setCurrentOption] = useState({ id: '' });

//是否显示 新增/编辑 菜谱弹窗
const [isShowModal, setIsShowModal] = useState(false);

/**
* 提交表单
* @param {*} formValues
*/
const onFinishSubmit = async (formValues) => {
message.loading('正在配置', key);
if (formValues.id) {
const response = await quickAPI.UpdateDeviceInfo(formValues);
if (response.succeeded) {
message.success('修改成功');
setIsShowModal(false);
actionRef.current.reload();
} else {
message.error(response.errors || '修改出错');
}
} else {
const response = await quickAPI.AddDeviceInfo(formValues);
if (response.succeeded) {
message.success('添加成功');
const { Option, OptGroup } = Select;
const [addDeviceTypeForm] = Form.useForm();
const [editDeviceForm] = Form.useForm();

//设备类型列表
const [deviceTypeList, setDeviceTypeList] = useState([]);
//设备分类
const [deviceClassList, setDeviceClassList] = useState([]);
const [deviceClassEnum, setDeviceClassEnum] = useState({});
//组织树
const [orgTree, setOrgTree] = useState([]);
//设备版本
const [deviceVersion, setDeviceVersion] = useState([]);
//是否显示设备分类弹窗
const [isModalOpen, setIsModalOpen] = useState(false);

//当前操作的设备对象
const [currentOption, setCurrentOption] = useState({ id: '' });

//是否显示 新增/编辑 菜谱弹窗
const [isShowModal, setIsShowModal] = useState(false);

/**
* 提交表单
* @param {*} formValues
*/
const onFinishSubmit = async (formValues) => {
message.loading('正在配置', key);
if (formValues.id) {
const response = await quickAPI.UpdateDeviceInfo(formValues);
if (response.succeeded) {
message.success('修改成功');
setIsShowModal(false);
actionRef.current.reload();
} else {
message.error(response.errors || '修改出错');
}
} else {
const response = await quickAPI.AddDeviceInfo(formValues);
if (response.succeeded) {
message.success('添加成功');
actionRef.current.reload();
setIsShowModal(false);
} else {
message.error(response.errors || '添加成出错');
}
}
message.destroy(key);
actionRef.current.reload();
setIsShowModal(false);
} else {
message.error(response.errors || '添加成出错');
}
}
message.destroy(key);
actionRef.current.reload();
};

/**
* 获取设备类型列表
*/
const onFetchDeviceTypeList = async () => {
const response = await quickAPI.GetDicList('DeviceClientType');
if (response.statusCode === 200) {
response.data.forEach((item) => {
item.code = item.code;
item.value = item.code;
});
setDeviceTypeList(response.data);
} else {
message.error(response.errors || '获取设备类型出错');
}
};

//获取组织树
const onFetchOrgTree = async () => {
const response = await quickAPI.getOrgTree();
if (response.statusCode === 200) {
setOrgTree(response.data);
} else {
message.error(response.errors || '获取组织架构出错');

/**
* 获取设备类型列表
*/
const onFetchDeviceTypeList = async () => {
const response = await quickAPI.GetDicList('DeviceClientType');
if (response.statusCode === 200) {
response.data.forEach(item => {
item.code = item.code;
item.value = item.code;
})
setDeviceTypeList(response.data);
} else {
message.error(response.errors || '获取设备类型出错');
}
}
};

/**
* 获取设备分类
*/
const onFetchDeviceClass = async () => {
const response = await quickAPI.GetDeviceType();
if (response.statusCode === 200) {
const deviceEnum = {};
response.data.forEach((item) => {
deviceEnum[item.id] = {
text: item.name,
};
});
setDeviceClassEnum(deviceEnum);
setDeviceClassList(response.data);
} else {
message.error(response.errors || '获取设备分类出错');

//获取组织树
const onFetchOrgTree = async () => {
const response = await quickAPI.getOrgTree();
if (response.statusCode === 200) {
setOrgTree(response.data);
} else {
message.error(response.errors || '获取组织架构出错');
}
}
};

/**
* 获取设备版本
*/
const onFetchDeviceVersion = async () => {
const response = await quickAPI.GetDeviceVersions();
if (response.statusCode === 200) {
setDeviceVersion(response.data);
} else {
message.error(response.errors || '获取设备版本出错');

/**
* 获取设备分类
*/
const onFetchDeviceClass = async () => {
const response = await quickAPI.GetDeviceType();
if (response.statusCode === 200) {
const deviceEnum = {};
response.data.forEach(item => {
deviceEnum[item.id] = {
text: item.name
}
});
setDeviceClassEnum(deviceEnum);
setDeviceClassList(response.data);
} else {
message.error(response.errors || '获取设备分类出错');
}
}
};

/**
* 添加设备分类
*/
const onSaveDeviceType = async (values) => {
const response = await quickAPI.AddDeviceType(values);
if (response.data) {
message.success('设备分类添加成功!');
setIsModalOpen(false);
onFetchDeviceClass();
} else {
message.error(response.errors || '添加设备分类出错');

/**
* 获取设备版本
*/
const onFetchDeviceVersion = async () => {
const response = await quickAPI.GetDeviceVersions();
if (response.statusCode === 200) {
setDeviceVersion(response.data);
} else {
message.error(response.errors || '获取设备版本出错');
}
}
};

const actionRef = useRef();
const [selectedRowKeys, setSelectRowKeys] = useState([]);
const columns = [
{
title: '主键',
dataIndex: 'id',
hideInSearch: true,
hideInTable: true,
tip: '规则名称是唯一的 key',
},
{
title: '设备名称',
dataIndex: 'deviceName',
valueType: 'textarea',
},
{
title: '设备类型',
dataIndex: 'deviceTypeKey',
valueEnum: deviceTypeList,
hideInSearch: true,
},
{
title: '归属门店',
dataIndex: 'orgId',
search: false,
// valueEnum: OrgListArray,
},
{
title: '设备分类',
dataIndex: 'deviceTypeId',
valueEnum: deviceClassEnum,
},
{
title: '状态',
dataIndex: 'status',
valueEnum: {
0: { text: '正常', status: 'Processing' },
1: { text: '停用', status: 'Success' },
},
hideInSearch: true,
},

{
title: '设备地址',
dataIndex: 'deviceAddr',
search: false,
valueType: 'textarea',
},
{
title: '坐标',
dataIndex: 'deviceLoc',
valueType: 'textarea',
search: false,
},
{
title: '设备通道数量',
dataIndex: 'materialQuantity',
valueType: 'textarea',
search: false,
},

{
title: '设备唯一key',
dataIndex: 'autoKey',
search: false,
},
{
title: '归属门店唯一key',
dataIndex: 'orgKey',
search: false,
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
key="config"
onClick={() => {
setCurrentOption(record);
setIsShowModal(true);
editDeviceForm.setFieldsValue(record);
}}
>
更新
</a>,
],
},
];

const [currentPage, setCurrentPage] = useState(0);
const [pageSize, setPageSize] = useState(10);

useEffect(() => {
if (props.deviceConfig?.id) {
setSelectRowKeys([props.deviceConfig.id]);

/**
* 添加设备分类
*/
const onSaveDeviceType = async (values) => {
const response = await quickAPI.AddDeviceType(values);
if (response.data) {
message.success('设备分类添加成功!');
setIsModalOpen(false);
onFetchDeviceClass();
} else {
message.error(response.errors || '添加设备分类出错');
}
}
onFetchOrgTree();
onFetchDeviceClass();
onFetchDeviceTypeList();
onFetchDeviceVersion();
}, []);

return (
<>
<ProTable
style={{ width: '100%' }}
headerTitle="设备信息"
actionRef={actionRef}
rowKey="id"
search={false}
pagination={{
current: currentPage,
pageSize: pageSize,
onChange: (page, pageSize) => {
setCurrentPage(page);
setPageSize(pageSize);
},
}}
request={async (params) => {
let data = [];
let total = 0;
await quickAPI.GetDeviceInfoPage(params).then((r) => {
data = r.data.data;
total = r.data.total;
});
return {
data: data,
success: true,
total: total,
};
}}
columns={columns}
rowSelection={{
type: 'radio',
onChange: (selectedRowKeys, selectedRows) => {
setSelectRowKeys(selectedRowKeys);
props.onSelectedChange('deviceConfig', selectedRows[0]);
},
selectedRowKeys: selectedRowKeys,
}}
toolBarRender={() => [
<Button
key="button"
icon={<PlusOutlined />}
type="primary"
onClick={() => {
editDeviceForm.resetFields();
setCurrentOption({ id: '' });
setIsShowModal(true);

const actionRef = useRef();
const [selectedRowKeys, setSelectRowKeys] = useState([]);
const columns = [
{
title: '主键',
dataIndex: 'id',
hideInSearch: true,
hideInTable: true,
tip: '规则名称是唯一的 key',
},
{
title: '设备名称',
dataIndex: 'deviceName',
valueType: 'textarea',
},
{
title: '设备类型',
dataIndex: 'deviceTypeKey',
valueEnum: deviceTypeList,
hideInSearch: true,
},
{
title: '归属门店',
dataIndex: 'orgId',
search: false,
// valueEnum: OrgListArray,
},
{
title: '设备分类',
dataIndex: 'deviceTypeId',
valueEnum: deviceClassEnum,
},
{
title: '状态',
dataIndex: 'status',
valueEnum: {
0: { text: '正常', status: 'Processing' },
1: { text: '停用', status: 'Success' },
},
hideInSearch: true,
},

{
title: '设备地址',
dataIndex: 'deviceAddr',
search: false,
valueType: 'textarea',
},
{
title: '坐标',
dataIndex: 'deviceLoc',
valueType: 'textarea',
search: false,
},
{
title: '设备通道数量',
dataIndex: 'materialQuantity',
valueType: 'textarea',
search: false,
},

{
title: '设备唯一key',
dataIndex: 'autoKey',
search: false,
},
{
title: '归属门店唯一key',
dataIndex: 'orgKey',
search: false,
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
key="config"
onClick={() => {
setCurrentOption(record);
setIsShowModal(true);
editDeviceForm.setFieldsValue(record);
}}>更新</a>
]
}
];

const [currentPage, setCurrentPage] = useState(0);
const [pageSize, setPageSize] = useState(10);

useEffect(() => {
if (props.deviceConfig?.id) {
setSelectRowKeys([props.deviceConfig.id]);
}
onFetchOrgTree();
onFetchDeviceClass();
onFetchDeviceTypeList();
onFetchDeviceVersion();
}, []);

return <>
<ProTable
style={{ width: '100%' }}
headerTitle="设备信息"
actionRef={actionRef}
rowKey="id"
search={false}
pagination={{
current: currentPage,
pageSize: pageSize,
onChange: (page, pageSize) => {
setCurrentPage(page);
setPageSize(pageSize);
}
}}
request={async (params) => {
let data = [];
let total = 0;
await quickAPI.GetDeviceInfoPage(params).then((r) => {
data = r.data.data;
total = r.data.total;
});
return {
data: data,
success: true,
total: total,
};
}}
columns={columns}
rowSelection={{
type: 'radio',
onChange: (selectedRowKeys, selectedRows) => {
setSelectRowKeys(selectedRowKeys);
props.onSelectedChange('deviceConfig', selectedRows[0]);
},
selectedRowKeys: selectedRowKeys
}}
>
新建
</Button>,
]}
/>
<StepsButton
deviceConfig={props.deviceConfig}
current={props.current}
steps={props.steps}
prev={props.prev}
next={props.next}
></StepsButton>
<Modal
width={600}
title={currentOption.id ? '编辑设备' : '新增设备'}
visible={isShowModal}
footer={false}
onCancel={() => setIsShowModal(false)}
>
<Form
layout="Horizontal"
labelCol={{ span: 6 }}
preserve={false}
form={editDeviceForm}
onFinish={onFinishSubmit}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>

<Form.Item label={'设备名称'} name="deviceName" rules={[{ required: true, max: 50 }]}>
<Input />
</Form.Item>

<Form.Item label={'设备类型'} name="deviceTypeKey" rules={[{ required: true }]}>
<Select>
{deviceTypeList.map((item, index) => {
return (
<Select.Option index={index} value={item.code} key={item.code}>
{item.value}
</Select.Option>
);
})}
</Select>
</Form.Item>

<Form.Item name="orgId" label="归属门店" rules={[{ required: true }]}>
<TreeSelect
style={{ width: '100%' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={orgTree}
placeholder="归属门店"
treeDefaultExpandAll
/>
</Form.Item>

<div className={styles.add_row_content}>
<Form.Item label={'设备分类'} name="deviceTypeId" rules={[{ required: true }]}>
<Select style={{ width: '75%' }}>
{deviceClassList.map((item, index) => {
return (
<Select.Option index={index} value={item.id} key={item.id}>
{item.name}
</Select.Option>
);
})}
</Select>
</Form.Item>
<Button
type="primary"
className={styles.add_row_btn}
onClick={() => {
setIsModalOpen(true);
addDeviceTypeForm.resetFields();
}}
toolBarRender={() => [
<Button key="button" icon={<PlusOutlined />} type="primary" onClick={() => {
editDeviceForm.resetFields();
setCurrentOption({ id: '' });
setIsShowModal(true);
}}>
新建
</Button>
]}
/>
<Modal width={600} title={currentOption.id ? '编辑设备' : '新增设备'} visible={isShowModal} footer={false} onCancel={() => setIsShowModal(false)}>
<Form
layout="Horizontal"
labelCol={{ span: 6 }}
preserve={false}
form={editDeviceForm}
onFinish={onFinishSubmit}
>
添加分类
</Button>
</div>

<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) =>
prevValues.deviceTypeKey !== currentValues.deviceTypeKey
}
>
{({ getFieldValue }) =>
getFieldValue('deviceTypeKey') === 'TMC' ? (
<Form.Item name="deviceVersion" label="设备版本" initialValue="WorryFreeEdition">
<Select>
{deviceVersion.map((item, index) => {
return (
<Select.Option index={index} value={item.code} key={item.code}>
{item.name}
</Select.Option>
);
})}
</Select>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
) : null
}
</Form.Item>

<Form.Item label={'设备坐标'} name="deviceLoc">
<Input placeholder="104.070734,30.575041" />
</Form.Item>

<Form.Item label={'状态'} name="status" rules={[{ required: true }]}>
<Select placeholder="请选择状态">
<OptGroup>
<Select.Option value={0}>正常</Select.Option>
<Select.Option value={1}>停用</Select.Option>
</OptGroup>
</Select>
</Form.Item>

<Form.Item label={'设备通道数量'} name="materialQuantity">
<InputNumber style={{ width: '100%' }} />
</Form.Item>

<Form.Item label={'设备详细地址'} name="deviceAddr">
<Input placeholder="成都市武侯区桂溪街道环球中心N5-9111C" />
</Form.Item>

<Form.Item>
<Button type="primary" htmlType="submit">
确定
</Button>
</Form.Item>
</Form>
</Modal>

<Modal
title="添加设备分类"
visible={isModalOpen}
footer={false}
onCancel={() => setIsModalOpen(false)}
>
<Form layout="vertical" onFinish={onSaveDeviceType} form={addDeviceTypeForm}>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
<Form.Item label={'类型名称'} name="name" rules={[{ required: true, max: 50 }]}>
<Input />
</Form.Item>

<Form.Item>
<Button type="primary" htmlType="submit">
保存
</Button>
</Form.Item>
</Form>
</Modal>

<Form.Item label={'设备名称'} name="deviceName" rules={[{ required: true, max: 50 }]}>
<Input />
</Form.Item>

<Form.Item label={'设备类型'} name="deviceTypeKey" rules={[{ required: true }]}>
<Select >
{deviceTypeList.map((item, index) => {
return (
<Select.Option index={index} value={item.code} key={item.code}>
{item.value}
</Select.Option>
);
})}
</Select>
</Form.Item>

<Form.Item name="orgId" label="归属门店" rules={[{ required: true }]}>
<TreeSelect

style={{ width: '100%' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={orgTree}
placeholder="归属门店"
treeDefaultExpandAll
/>
</Form.Item>

<div className={styles.add_row_content}>
<Form.Item label={'设备分类'} name="deviceTypeId" rules={[{ required: true }]} >
<Select style={{ width: '75%' }} >
{deviceClassList.map((item, index) => {
return (
<Select.Option index={index} value={item.id} key={item.id}>
{item.name}
</Select.Option>
);
})}
</Select>
</Form.Item>
<Button type="primary" className={styles.add_row_btn} onClick={() => { setIsModalOpen(true); addDeviceTypeForm.resetFields(); }}>添加分类</Button>
</div>

<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.deviceTypeKey !== currentValues.deviceTypeKey}
>
{({ getFieldValue }) =>
getFieldValue('deviceTypeKey') === 'TMC' ? (
<Form.Item name="deviceVersion" label="设备版本" initialValue="WorryFreeEdition">
<Select >
{deviceVersion.map((item, index) => {
return (
<Select.Option index={index} value={item.code} key={item.code}>
{item.name}
</Select.Option>
);
})}
</Select>
</Form.Item>
) : null
}
</Form.Item>

<Form.Item label={'设备坐标'} name="deviceLoc">
<Input placeholder="104.070734,30.575041" />
</Form.Item>

<Form.Item label={'状态'} name="status" rules={[{ required: true }]}>
<Select placeholder="请选择状态" >
<OptGroup>
<Select.Option value={0}>正常</Select.Option>
<Select.Option value={1}>停用</Select.Option>
</OptGroup>
</Select>
</Form.Item>

<Form.Item label={'设备通道数量'} name="materialQuantity">
<InputNumber style={{ width: '100%' }} />
</Form.Item>

<Form.Item label={'设备详细地址'} name="deviceAddr">
<Input placeholder="成都市武侯区桂溪街道环球中心N5-9111C" />
</Form.Item>

<Form.Item>
<Button type="primary" htmlType="submit">
确定
</Button>
</Form.Item>
</Form>
</Modal>

<Modal title="添加设备分类" visible={isModalOpen} footer={false} onCancel={() => setIsModalOpen(false)}>
<Form
layout="vertical"
onFinish={onSaveDeviceType}
form={addDeviceTypeForm}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
<Form.Item label={"类型名称"} name="name" rules={[{ required: true, max: 50 }]} >
<Input />
</Form.Item>

<Form.Item>
<Button type="primary" htmlType="submit">
保存
</Button>
</Form.Item>
</Form>
</Modal>
</>
);
};
}

export default DeviceConfig;

+ 186
- 209
src/pages/quickStart/components/FoodMenuConfig/index.jsx View File

@@ -1,222 +1,199 @@
import React, { useState, useEffect, useRef } from 'react';
import ProTable from '@ant-design/pro-table';
import { Form, Input, message, Button, Modal, Radio } from 'antd';
import quickAPI from '../../service';
import StepsButton from '../StepsButton';
import styles from './index.less';
import indexStyles from '../../index.less';
import quickAPI from "../../service";
import styles from "./index.less";
import indexStyles from "../../index.less";
import { PlusOutlined } from '@ant-design/icons';
const key = 'message';

const FoodMenuConfig = (props) => {
//表单实例
const [editFoodMenuForm] = Form.useForm();

/**
* 提交表单
*/
const onFinishSubmit = async (formValues) => {
if (formValues.id) {
try {
message.loading('正在修改', key);
await quickAPI.UpdateFoodMenu(formValues).then((r) => {
message.destroy(key);
if (r.data) {
message.success('修改成功');
setIsShowModal(false);
actionRef.current.reload();
} else {
message.error('修改失败');
}
});
} catch (error) {
message.destroy(key);
message.error('修改失败请重试!');
}
} else {
try {
message.loading('正在添加', key);
await quickAPI.AddFoodMenu(formValues).then((r) => {
message.destroy(key);
if (r.data) {
message.success('添加成功');
setIsShowModal(false);
actionRef.current.reload();
} else {
message.error('添加失败');
}
});
} catch (error) {
message.destroy(key);
message.error('添加失败请重试!');
}

//表单实例
const [editFoodMenuForm] = Form.useForm();

/**
* 提交表单
*/
const onFinishSubmit = async (formValues) => {
if (formValues.id) {
try {
message.loading('正在修改', key);
await quickAPI.UpdateFoodMenu(formValues).then((r) => {
message.destroy(key);
if (r.data) {
message.success('修改成功');
setIsShowModal(false);
actionRef.current.reload();
} else {
message.error('修改失败');
}
});
} catch (error) {
message.destroy(key);
message.error('修改失败请重试!');
}
} else {
try {
message.loading('正在添加', key);
await quickAPI.AddFoodMenu(formValues).then((r) => {
message.destroy(key);
if (r.data) {
message.success('添加成功');
setIsShowModal(false);
actionRef.current.reload();
} else {
message.error('添加失败');
}
});
} catch (error) {
message.destroy(key);
message.error('添加失败请重试!');
}
}
}
};

//当前操作的菜谱对象
const [currentOption, setCurrentOption] = useState({ id: '' });

//是否显示 新增/编辑 菜谱弹窗
const [isShowModal, setIsShowModal] = useState(false);

//表格实例
const actionRef = useRef();
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(5);

const [selectedRowKeys, setSelectRowKeys] = 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={() => {
setCurrentOption(record);
setIsShowModal(true);
editFoodMenuForm.setFieldsValue(record);
}}
>
更新
</a>,
],
},
];

/**
* 回显 选中的菜谱
*/
const onSetSelectedState = () => {
if (props.foodMenuConfig.length > 0) {
const selected = [];
props.foodMenuConfig.forEach((item) => {
selected.push(item.id);
});
setSelectRowKeys(selected);

//当前操作的菜谱对象
const [currentOption, setCurrentOption] = useState({ id: '' });

//是否显示 新增/编辑 菜谱弹窗
const [isShowModal, setIsShowModal] = useState(false);

//表格实例
const actionRef = useRef();
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(5);

const [selectedRowKeys, setSelectRowKeys] = 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={() => {
setCurrentOption(record);
setIsShowModal(true);
editFoodMenuForm.setFieldsValue(record);
}}>更新</a>
]
}
]

/**
* 回显 选中的菜谱
*/
const onSetSelectedState = () => {
if (props.foodMenuConfig.length > 0) {
const selected = [];
props.foodMenuConfig.forEach(item => {
selected.push(item.id);
});
setSelectRowKeys(selected);
}
}
};

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

return (
<>
<ProTable
style={{ width: '100%' }}
headerTitle="菜谱列表"
actionRef={actionRef}
rowKey="id"
search={false}
pagination={{
current: currentPage,
pageSize: pageSize,
onChange: (page, pageSize) => {
setCurrentPage(page);
setPageSize(pageSize);
},
}}
request={async (params) => {
let data = [];
let total = 0;
await quickAPI.GetFoodMenuInfoPage(params).then((r) => {
data = r.data.data;
total = r.data.total;
});
return {
data: data,
success: true,
total: total,
};
}}
columns={columns}
rowSelection={{
type: 'checkbox',
onChange: (selectedRowKeys, selectedRows) => {
setSelectRowKeys(selectedRowKeys);
props.onSelectedChange('foodMenuConfig', selectedRows);
},
selectedRowKeys: selectedRowKeys,
}}
toolBarRender={() => [
<Button
key="button"
icon={<PlusOutlined />}
type="primary"
onClick={() => {
editFoodMenuForm.resetFields();
setCurrentOption({ id: '' });
setIsShowModal(true);

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

return <>
<ProTable
style={{ width: '100%' }}
headerTitle="菜谱列表"
actionRef={actionRef}
rowKey="id"
search={false}
pagination={{
current: currentPage,
pageSize: pageSize,
onChange: (page, pageSize) => {
setCurrentPage(page);
setPageSize(pageSize);
}
}}
request={async (params) => {
let data = [];
let total = 0;
await quickAPI.GetFoodMenuInfoPage(params).then((r) => {
data = r.data.data;
total = r.data.total;
});
return {
data: data,
success: true,
total: total,
};
}}
columns={columns}
rowSelection={{
type: 'checkbox',
onChange: (selectedRowKeys, selectedRows) => {
setSelectRowKeys(selectedRowKeys);
props.onSelectedChange('foodMenuConfig', selectedRows);
},
selectedRowKeys: selectedRowKeys
}}
>
新建
</Button>,
]}
/>

<StepsButton
foodMenuConfig={props.foodMenuConfig}
current={props.current}
steps={props.steps}
prev={props.prev}
next={props.next}
></StepsButton>

<Modal
width={600}
title={currentOption.id ? '编辑菜谱' : '新增菜谱'}
visible={isShowModal}
footer={false}
onCancel={() => setIsShowModal(false)}
>
<Form
form={editFoodMenuForm}
layout="Horizontal"
preserve={false}
onFinish={onFinishSubmit}
style={{ width: '100%' }}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>

<Form.Item label={'菜谱编码'} name="code" rules={[{ required: true, max: 20 }]}>
<Input />
</Form.Item>

<Form.Item label={'菜谱名称'} name="name" rules={[{ required: true, max: 20 }]}>
<Input />
</Form.Item>

<Form.Item>
<Button type="primary" htmlType="submit">
确定
</Button>
</Form.Item>
</Form>
</Modal>
toolBarRender={() => [
<Button key="button" icon={<PlusOutlined />} type="primary" onClick={() => {
editFoodMenuForm.resetFields();
setCurrentOption({ id: '' });
setIsShowModal(true);
}}>
新建
</Button>
]}
/>


<Modal width={600} title={currentOption.id ? '编辑菜谱' : '新增菜谱'} visible={isShowModal} footer={false} onCancel={() => setIsShowModal(false)}>
<Form
form={editFoodMenuForm}
layout="Horizontal"
preserve={false}
onFinish={onFinishSubmit}
style={{ width: '100%' }}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>

<Form.Item label={"菜谱编码"} name="code" rules={[{ required: true, max: 20 }]}>
<Input />
</Form.Item>

<Form.Item label={"菜谱名称"} name="name" rules={[{ required: true, max: 20 }]} >
<Input />
</Form.Item>

<Form.Item>
<Button type="primary" htmlType="submit">
确定
</Button>
</Form.Item>
</Form>
</Modal>
</>
);
};
}

export default FoodMenuConfig;

+ 0
- 1
src/pages/quickStart/components/GoodsConfig/index.jsx View File

@@ -3,7 +3,6 @@ import { PlusOutlined, UploadOutlined } from '@ant-design/icons';
import ProTable from '@ant-design/pro-table';
import { Form, Input, Select, InputNumber, message, Button, Modal, Drawer, Upload, Switch, Table, notification } from 'antd';
import quickAPI from "../../service";
import StepsButton from "../StepsButton";
import indexStyles from "../../index.less";
import axios from 'axios';



+ 0
- 2
src/pages/quickStart/components/MaterialConfig/index.jsx View File

@@ -4,7 +4,6 @@ import { Form, Input, Select, Drawer, message, Button, Modal, Row, Col, Table, n
import ProForm, { ProFormSelect, ProFormText, ProFormDigit } from '@ant-design/pro-form';
import quickAPI from "../../service";
import indexStyles from "../../index.less";
import StepsButton from "../StepsButton";
import { PlusOutlined } from '@ant-design/icons';

const { Option, OptGroup } = Select;
@@ -696,7 +695,6 @@ const MaterialConfig = (props) => {
<Button className={indexStyles.sure_add_btn} type='primary' onClick={onMaterialRelationBom}>确定关联</Button>
</Drawer>

<StepsButton foodMenuConfig={props.foodMenuConfig} current={props.current} steps={props.steps} prev={props.prev} next={props.next}></StepsButton>
</>
}


+ 37
- 19
src/pages/quickStart/components/StoreConfig/index.jsx View File

@@ -1,10 +1,12 @@
import React, { useState, useEffect, useRef } from 'react';
import { Form, Input, Select, InputNumber, TreeSelect, message, Modal, Button } from 'antd';
import { ProTable } from '@ant-design/pro-table';
import StepsButton from "../StepsButton";
import quickAPI from "../../service";
import styles from "./index.less";
import indexStyles from "../../index.less";
import { PlusOutlined } from '@ant-design/icons';
import { nanoid } from 'nanoid'
import BaiDuMapPostion from '../BaiDuMapPostion';

const key = 'message';

@@ -34,13 +36,14 @@ const StoreConfig = (props) => {
message.error(response.errors || '修改出错');
}
} else {
formValues.code = nanoid();
const response = await quickAPI.AddOrg(formValues);
if (response.succeeded) {
message.success('添加成功');
actionRef.current.reload();
setIsShowModal(false);
} else {
message.error(response.errors.sort[0] || '添加成出错');
message.error(JSON.stringify(response.errors) || '添加出错');
}
}
message.destroy(key);
@@ -151,6 +154,17 @@ const StoreConfig = (props) => {

const [selectedRowKeys, setSelectRowKeys] = useState([]);

const [isShowBaiduMap, setIsShowBaiduMap] = useState(false);

const handleBaiduMapOk = (pos) => {
const formValues = storeForm.getFieldsValue(true);
formValues.store_Loc = `${pos.point.lng},${pos.point.lat}`;
formValues.store_Addr = pos.address;
storeForm.setFieldsValue(formValues);
setIsShowBaiduMap(false);
message.success('门店坐标设置成功!')
}

useEffect(() => {
if (props.storeConfig.id) {
setSelectRowKeys([props.storeConfig.id]);
@@ -160,6 +174,9 @@ const StoreConfig = (props) => {
}, []);

return <>
{
isShowBaiduMap && <BaiDuMapPostion isShowBaiduMap={isShowBaiduMap} handleOk={handleBaiduMapOk} handleCancel={() => setIsShowBaiduMap(false)}></BaiDuMapPostion>
}
<Modal width={600} title={currentOption.id ? '编辑门店架构' : '新增门店架构'} visible={isShowModal} footer={false} onCancel={() => setIsShowModal(false)}>
<Form
form={storeForm}
@@ -174,7 +191,7 @@ const StoreConfig = (props) => {
<Input />
</Form.Item>

<Form.Item name="code" label="门店编码" rules={[{ required: true, max: 64 }]}>
<Form.Item name="code" hidden={true} label="门店编码">
<Input placeholder="请输入门店编码" />
</Form.Item>

@@ -182,12 +199,12 @@ const StoreConfig = (props) => {
<Input placeholder="请输入名称" />
</Form.Item>

<Form.Item name="pid" label="上级名称" rules={[{ required: true }]}>
<Form.Item name="pid" label="所属机构" rules={[{ required: true }]}>
<TreeSelect
style={{ width: '100%' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={orgTree}
placeholder="请选择上级名称"
placeholder="请选择所属机构"
treeDefaultExpandAll
/>
</Form.Item>
@@ -199,8 +216,6 @@ const StoreConfig = (props) => {
>
<Select placeholder="请选择机构类型" >
<OptGroup>
<Select.Option value={0}>机构</Select.Option>
<Select.Option value={1}>配送中心</Select.Option>
<Select.Option value={2}>直营店</Select.Option>
<Select.Option value={3}>加盟店</Select.Option>
</OptGroup>
@@ -209,9 +224,9 @@ const StoreConfig = (props) => {

<Form.Item
name="payTemplateId"
label="支付方式"
label="支付模板"
>
<Select placeholder="请选择支付方式" >
<Select placeholder="请选择支付模板" >
{
payTypeList?.map(item => {
return <Option value={item.id} key={item.id}>{item.name}</Option>
@@ -219,24 +234,27 @@ const StoreConfig = (props) => {
}
</Select>
</Form.Item>
<div className={indexStyles.add_row_content}>
<Form.Item label={'店铺坐标'} name="store_Loc" rules={[{
required: true, max: 100, pattern: /^[-\+]?\d+(\.\d+)\,[-\+]?\d+(\.\d+)$/,
message: '经纬度格式不对'
}]}>
<Input style={{ width: '75%' }} placeholder="104.070734,30.575041" />
</Form.Item>
<Button type="primary" className={indexStyles.add_row_btn} onClick={() => { setIsShowBaiduMap(true); }}>打开地图</Button>
</div>


<Form.Item label={'店铺地址'} name="store_Addr" rules={[{ required: true, max: 100 }]}>
<Input placeholder="成都市武侯区桂溪街道环球中心N5-9111C" />
</Form.Item>

<Form.Item label={'店铺坐标'} name="store_Loc" rules={[{
required: true, max: 100, pattern: /^[-\+]?\d+(\.\d+)\,[-\+]?\d+(\.\d+)$/,
message: '经纬度格式不对'
}]}>
<Input placeholder="104.070734,30.575041" />
</Form.Item>

<Form.Item name="tel" label="电话" rules={[{ max: 20 }]}>
<Input placeholder="请输入联系电话" />
</Form.Item>

<Form.Item name="sort" label="排序">
<InputNumber min={1} step={1} precision={0} defaultValue={1} />
<InputNumber min={1} step={1} precision={0} />
</Form.Item>

<Form.Item name="remark" label="备注">
@@ -272,8 +290,9 @@ const StoreConfig = (props) => {
UserData = r.data.data;
total = r.data.total;
});
let filterData = UserData.filter(item => item.type === 2 || item.type === 3);
return {
data: UserData,
data: filterData,
success: true,
total: total,
};
@@ -297,7 +316,6 @@ const StoreConfig = (props) => {
</Button>
]}
/>
<StepsButton storeConfig={props.storeConfig} current={props.current} steps={props.steps} prev={props.prev} next={props.next}></StepsButton>
</>
}


+ 21
- 9
src/pages/quickStart/index.jsx View File

@@ -9,6 +9,7 @@ import GoodsConfig from './components/GoodsConfig';
import BomConfig from './components/BomConfig';
import MaterialConfig from './components/MaterialConfig';
import ConfirmConfig from './components/ConfirmConfig';
import StepsButton from "./components/StepsButton";

const { Step } = Steps;

@@ -108,28 +109,39 @@ const QuickStart = () => {
<StoreConfig storeConfig={quickStartObj.storeConfig} current={current} steps={stepsText} next={next} onSelectedChange={onSelectedChange}></StoreConfig>,
<DeviceConfig deviceConfig={quickStartObj.deviceConfig} current={current} steps={stepsText} prev={prev} next={next} onSelectedChange={onSelectedChange} ></DeviceConfig>,
<FoodMenuConfig foodMenuConfig={quickStartObj.foodMenuConfig} current={current} steps={stepsText} prev={prev} next={next} onSelectedChange={onSelectedChange}></FoodMenuConfig>,
<GoodsConfig foodMenuConfig={quickStartObj.foodMenuConfig} current={current} steps={stepsText} onAddGoodsToFoodMenu={onAddGoodsToFoodMenu} prev={prev} next={next} ></GoodsConfig>,
<BomConfig foodMenuConfig={quickStartObj.foodMenuConfig} current={current} steps={stepsText} prev={prev} next={next} onBomRelationGoods={onBomRelationGoods}></BomConfig>,
<MaterialConfig foodMenuConfig={quickStartObj.foodMenuConfig} current={current} steps={stepsText} onMaterialRelationBom={onMaterialRelationBom} prev={prev} next={next}></MaterialConfig>,
<GoodsConfig foodMenuConfig={quickStartObj.foodMenuConfig} current={current} steps={stepsText} onAddGoodsToFoodMenu={onAddGoodsToFoodMenu} prev={prev} next={next} ></GoodsConfig>,
<BomConfig foodMenuConfig={quickStartObj.foodMenuConfig} current={current} steps={stepsText} prev={prev} next={next} onBomRelationGoods={onBomRelationGoods}></BomConfig>,
<MaterialConfig foodMenuConfig={quickStartObj.foodMenuConfig} current={current} steps={stepsText} onMaterialRelationBom={onMaterialRelationBom} prev={prev} next={next}></MaterialConfig>,
<ConfirmConfig quickStartObj={quickStartObj} current={current} steps={stepsText} prev={prev}></ConfirmConfig>
];

useEffect(() => {
if(current > 4) {
if (current > 4) {
console.log('终极JSON对象:', JSON.stringify(quickStartObj));
}
console.log('JSON对象更新啦', quickStartObj);
}, [quickStartObj]);

return <PageContainer>
<div className={styles.steps_navbar}>
<Card >
<Steps current={current}>
{stepsText.map((item) => (
<Step key={item} title={item} />
))}
</Steps>
</Card>
</div>

<Card>
<Steps current={current}>
{stepsText.map((item) => (
<Step key={item} title={item} />
))}
</Steps>
<div className={styles.steps_content}>{stepsContent[current]}</div>
</Card>

<div className={styles.steps_navbar_bottom}>
<Card>
<StepsButton {...quickStartObj} current={current} steps={stepsText} prev={prev} next={next}></StepsButton>
</Card>
</div>
</PageContainer>

}


+ 16
- 0
src/pages/quickStart/index.less View File

@@ -1,3 +1,19 @@
.steps_navbar {
position: sticky;
top: 0;
z-index: 999;
margin-bottom: 10px;
box-shadow: 2px 4px 8px rgb(7 17 27 / 12%);
}

.steps_navbar_bottom {
position: sticky;
bottom: 0;
z-index: 999;
margin-top: 10px;
background-color: rgb(172, 168, 168);
}

.steps_content {
margin: 40px 0 20px 0;
display: flex;


Loading…
Cancel
Save