瀏覽代碼

新增:物料配置、配方配置

tags/小炒逻辑变更前
yangwenhua 2 年之前
父節點
當前提交
c63c1341f6
共有 4 個文件被更改,包括 914 次插入2 次删除
  1. +269
    -0
      src/pages/quickStart/components/BomConfig/index.jsx
  2. +536
    -0
      src/pages/quickStart/components/MaterialConfig/index.jsx
  3. +25
    -2
      src/pages/quickStart/index.jsx
  4. +84
    -0
      src/pages/quickStart/service.js

+ 269
- 0
src/pages/quickStart/components/BomConfig/index.jsx 查看文件

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

/**
* 配方配置
* @returns
*/
const BomConfig = (props) => {

const [editBomForm] = Form.useForm();

const optionsWithDisabled = [
{
label: '新建配方',
value: true,
},
{
label: '选择配方',
value: false,
}
];

const [isCreate, setIsCreate] = useState(props.bomConfig.id ? false : true);

const onChangeState = ({ target: { value } }) => {
setIsCreate(value);
let emptyObj = {
id: "",
code: "",
name: "",
bomTypeList: [],
sort: 0
}
props.onFinishForm('bomConfig', emptyObj);
editBomForm.setFieldsValue(emptyObj);
setSelectRowKeys([]);
setSelectedRows([]);
}

const onFinish = (values) => {
props.onFinishForm('bomConfig', values, true);
}

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

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

const [selectedRowsState, setSelectedRows] = useState(props.bomConfig.id ? [props.bomConfig] : []);
const [selectedRowKeys, setSelectRowKeys] = useState(props.bomConfig.id ? [props.bomConfig.id] : []);
//配方类型
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);
}
}

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

return <>
<div className={indexStyles.choose_change_state}>
<Radio.Group
options={optionsWithDisabled}
onChange={onChangeState}
value={isCreate}
optionType="button"
buttonStyle="solid"
/>
</div>

<div className={indexStyles.common_row}>
<Form
labelCol={{ span: 4 }}
layout="horizontal"
preserve={false}
initialValues={props.bomConfig}
onFinish={onFinish}
style={{ width: '600px', marginRight: '30px' }}
form={editBomForm}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
<Form.Item name="code" label="配方编码" rules={[{ required: true }]} >
<Input placeholder="配方编码" disabled={!isCreate || props.bomConfig.id} />
</Form.Item>
<Form.Item name="name" label="配方名称" rules={[{ required: true }]}>
<Input placeholder="配方名称" disabled={!isCreate || props.bomConfig.id} />
</Form.Item>

<div className={indexStyles.add_row_content}>
<Form.Item name="bomTypeList" label="配方类型" rules={[{ required: true }]}>
<Select
disabled={!isCreate || props.bomConfig.id}
style={{ width: '75%' }}
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 disabled={!isCreate || props.bomConfig.id} type="primary" className={indexStyles.add_row_btn} onClick={() => setIsShowBomModal(true)} >添加配方类型</Button>
</div>

<Form.Item name="isMain" label="配方类型" >
<Switch disabled={!isCreate || props.bomConfig.id} checkedChildren="主料" unCheckedChildren="辅料" />
</Form.Item>
<Form.Item name="sort" label="排序" rules={[{ required: true }]}>
<InputNumber placeholder="排序" min={1} disabled={!isCreate || props.bomConfig.id} />
</Form.Item>
<Form.Item>
<StepsButton current={props.current} steps={props.steps} prev={props.prev}></StepsButton>
</Form.Item>
</Form>

<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>

{
!isCreate && <ProTable
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}
rowSelection={{
type: 'radio',
onChange: (selectedRowKeys, selectedRows) => {
setSelectRowKeys(selectedRowKeys);
setSelectedRows(selectedRows);
if (selectedRows.length > 0) {
props.onFinishForm('bomConfig', selectedRows[0]);
editBomForm.setFieldsValue(selectedRows[0]);
} else {
let emptyObj = {
id: "",
code: "",
name: "",
bomTypeList: [],
sort: 0
}
editBomForm.setFieldsValue(emptyObj);
props.onFinishForm('bomConfig', emptyObj);
}
},
selectedRowKeys: selectedRowKeys
}}
/>
}
</div>
</>
}

export default BomConfig;

+ 536
- 0
src/pages/quickStart/components/MaterialConfig/index.jsx 查看文件

@@ -0,0 +1,536 @@
import React, { useState, useEffect, useRef } from 'react';
import ProTable from '@ant-design/pro-table';
import { Form, Input, Select, InputNumber, TreeSelect, message, Button, Modal, Radio, Upload, Switch, Row, Col } from 'antd';
import ProForm, { ProFormSelect, ProFormText, ProFormDigit } from '@ant-design/pro-form';
import quickAPI from "../../service";
import indexStyles from "../../index.less";
import StepsButton from "../StepsButton";
const { Option, OptGroup } = Select;

const fieldLabels = {
name: '物料名称',
stockUint: '库存单位',
specs: '物料规格',
code: '物料编码',
aittribute: '物料属性',
typeID: '物料类别',
status: '物料状态',
price: '成本价',
netrecovery: '净料率(%)',
OutstockUint: '出库单位',
proportion: '换算比例(%)',
};

const MaterialConfig = (props) => {

const [materialForm] = Form.useForm();

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

const [selectedRowsState, setSelectedRows] = useState(props.materialConfig.id ? [props.materialConfig] : []);
const [selectedRowKeys, setSelectRowKeys] = useState(props.materialConfig.id ? [props.materialConfig.id] : []);

const optionsWithDisabled = [
{
label: '新建物料',
value: true,
},
{
label: '选择物料',
value: false,
}
];

const [isCreate, setIsCreate] = useState(props.materialConfig.id ? false : true);

const onChangeState = ({ target: { value } }) => {
setIsCreate(value);
let emptyObj = {
id: "",
code: "",
name: "",
specs: "",
aittribute: "",
price: 0,
netrecovery: 0,
typeID: "",
stockUint: "",
outstockUint: "",
proportion: 1,
status: ""
}
props.onFinishForm('materialConfig', emptyObj);
materialForm.setFieldsValue(emptyObj);
setSelectRowKeys([]);
setSelectedRows([]);
}

const onFinish = (values) => {
props.onFinishForm('materialConfig', values, true);
}

const columns = [
{
title: '物料名称',
dataIndex: 'name',
ellipsis: true,
formItemProps: {
rules: [
{
required: true,
message: '名称为必填项',
},
],
},
},
{
title: '物料属性',
dataIndex: 'aittribute',
valueEnum: {
0: {
text: '成品',
},
1: {
text: '半成品',
},
2: {
text: '易耗品',
},
},
},
{
title: '状态',
dataIndex: 'status',
hideInForm: true,
valueEnum: {
0: {
text: '正常',
status: 'Processing',
},
1: {
text: '停用',
status: 'Success',
},
},
},
];

const [materialTypeList, setMaterialTypeList] = useState([]);
const [materialUnitList, setMaterialUnitList] = useState([]);

/**
* 获取物料类别
*/
const onFetchMaterialTypeList = async () => {
const response = await quickAPI.GetMaterialTypeList();
if (response.statusCode === 200) {
response.data.forEach(item => {
item.value = item.id,
item.label = item.name;
})
setMaterialTypeList(response.data);
} else {
message.error(response.errors || '获取物料类别出错');
}
}

/**
* 获取物料单位
*/
const onFetchMaterialUnit = async () => {
const response = await quickAPI.GetMaterialUintList();
if (response.statusCode === 200) {
response.data.forEach(item => {
item.value = item.id,
item.label = item.name;
})
setMaterialUnitList(response.data);
} else {
message.error(response.errors || '获取物料类别出错');
}
}

const [showMaterialTypeModal, setShowMaterialTypeModal] = useState(false);
const [showMaterialUnitModal, setShowMaterialUnitModal] = useState(false);

useEffect(() => {
onFetchMaterialTypeList();
onFetchMaterialUnit();
}, []);

return <>
<div className={indexStyles.choose_change_state}>
<Radio.Group
options={optionsWithDisabled}
onChange={onChangeState}
value={isCreate}
optionType="button"
buttonStyle="solid"
/>
</div>

<div className={indexStyles.common_row}>
<ProForm
form={materialForm}
labelCol={{ span: 6 }}
layout="horizontal"
hideRequiredMark
initialValues={props.materialConfig}
onFinish={onFinish}
submitter={false}
style={{ width: '800px', marginRight: '30px', flexShrink: 0 }}
>
<Row gutter={16}>
<Col lg={12} md={12} sm={24}>
<ProFormText
disabled={!isCreate || props.materialConfig.id}
label={fieldLabels.code}
name="code"
rules={[
{
required: true,
max: 50,
},
]}
placeholder="请输入原料编码"
/>
</Col>
<Col lg={12} md={12} sm={24}>
<ProFormText name="id" hidden={true} />
<ProFormText
disabled={!isCreate || props.materialConfig.id}
label={fieldLabels.name}
name="name"
rules={[
{
required: true,
max: 50,
},
]}
placeholder="请输入原料名称"
/>
</Col>
<Col lg={12} md={12} sm={24}>
<ProFormText
disabled={!isCreate || props.materialConfig.id}
label={fieldLabels.specs}
name="specs"
rules={[
{
required: true,
max: 500,
},
]}
placeholder="请输入规格型号"
/>
</Col>
<Col lg={12} md={12} sm={24}>
<ProFormSelect
disabled={!isCreate || props.materialConfig.id}
label={fieldLabels.aittribute}
name="aittribute"
rules={[
{
required: true,
message: '请选择物料属性',
},
]}
options={[
{
value: '0',
label: '成品',
},
{
value: '1',
label: '半成品',
},
{
value: '2',
label: '易耗品',
},
]}
placeholder="请选择物料属性"
/>
</Col>
<Col lg={12} md={12} sm={24}>
<ProFormDigit
disabled={!isCreate || props.materialConfig.id}
label={fieldLabels.price}
name="price"
placeholder="请输入成本价"
min={1}
/>
</Col>
<Col lg={12} md={12} sm={24}>
<ProFormDigit
disabled={!isCreate || props.materialConfig.id}
label={fieldLabels.netrecovery}
name="netrecovery"
min={1}
max={100}
placeholder="请输入净料率"
/>
</Col>
<Col lg={12} md={12} sm={24}>
<div className={indexStyles.add_row_content}>
<ProFormSelect
style={{ width: '65%' }}
disabled={!isCreate || props.materialConfig.id}
label={fieldLabels.typeID}
name="typeID"
rules={[
{
required: true,
message: '请选择物料类别',
},
]}
options={materialTypeList}
placeholder="请选择物料类别"
/>
<Button onClick={() => setShowMaterialTypeModal(true)} disabled={!isCreate || props.materialConfig.id} type="primary" className={indexStyles.add_row_btn}>添加类别</Button>
</div>
</Col>
<Col lg={12} md={12} sm={24}>
<div className={indexStyles.add_row_content}>
<ProFormSelect
style={{ width: '65%' }}
disabled={!isCreate || props.materialConfig.id}
label={fieldLabels.stockUint}
name="stockUint"
rules={[
{
required: true,
message: '请选择单位',
},
]}
options={materialUnitList}
placeholder="请选择单位"
/>
<Button onClick={() => setShowMaterialUnitModal(true)} disabled={!isCreate || props.materialConfig.id} type="primary" className={indexStyles.add_row_btn}>添加单位</Button>
</div>

</Col>
<Col lg={12} md={12} sm={24}>
<div className={indexStyles.add_row_content}>
<ProFormSelect
style={{ width: '65%' }}
disabled={!isCreate || props.materialConfig.id}
label={fieldLabels.OutstockUint}
name="outstockUint"
options={materialUnitList}
rules={[
{
required: true,
message: '请选择出库单位',
},
]}
placeholder="请选择出库单位"
/>
<Button onClick={() => setShowMaterialUnitModal(true)} disabled={!isCreate || props.materialConfig.id} type="primary" className={indexStyles.add_row_btn}>添加单位</Button>
</div>
</Col>
<Col lg={12} md={12} sm={24}>
<ProFormDigit
disabled={!isCreate || props.materialConfig.id}
label={fieldLabels.proportion}
name="proportion"
rules={[
{
required: true,
message: '请输入出入库换算比例',
},
]}
placeholder="请输入换算比例"
/>
</Col>
<Col lg={12} md={12} sm={24}>
<ProFormSelect
disabled={!isCreate || props.materialConfig.id}
label={fieldLabels.status}
name="status"
rules={[
{
required: true,
message: '请选择状态',
},
]}
options={[
{
value: '0',
label: '正常',
},
{
value: '1',
label: '停用',
},
]}
placeholder="请选择状态"
/>
</Col>
</Row>
<Form.Item>
<StepsButton current={props.current} steps={props.steps} prev={props.prev}></StepsButton>
</Form.Item>
</ProForm>

{
!isCreate && <ProTable
headerTitle="物料列表"
rowKey="id"
search={{
labelWidth: 120,
}}
request={async (params) => {
let UserData = [];
let total = 0;
await quickAPI.GetMaterialPage(params).then((r) => {
UserData = r.data.data;
total = r.data.total;
});
return {
data: UserData,
success: true,
total: total,
};
}}
columns={columns}
rowSelection={{
type: 'radio',
onChange: (selectedRowKeys, selectedRows) => {
setSelectRowKeys(selectedRowKeys);
setSelectedRows(selectedRows);
if (selectedRows.length > 0) {
props.onFinishForm('materialConfig', selectedRows[0]);
materialForm.setFieldsValue(selectedRows[0]);
} else {
let emptyObj = {
id: "",
code: "",
name: "",
specs: "",
aittribute: "",
price: 0,
netrecovery: 0,
typeID: "",
stockUint: "",
outstockUint: "",
proportion: 1,
status: ""
}
materialForm.setFieldsValue(emptyObj);
props.onFinishForm('materialConfig', emptyObj);
}
},
selectedRowKeys: selectedRowKeys
}}
/>
}
<Modal
title="添加物料单位"
width={640}
visible={showMaterialUnitModal}
bodyStyle={{ padding: '32px 40px 48px' }}
footer={null}
onCancel={() => {
setShowMaterialUnitModal(false)
}}
destroyOnClose
maskClosable={false}
>
<Form
layout="vertical"
preserve={false}
onFinish={async (values) => {
const response = await quickAPI.AddMaterialUnit(values);
if (response.data) {
message.success('添加成功');
setShowMaterialUnitModal(false);
onFetchMaterialUnit();
} else {
message.error(response.errors || '物料单位添加失败');
}
}}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
<Form.Item name="name" label="物料单位名称" rules={[{ required: true, max: 64 }]}>
<Input placeholder="物料单位名称" />
</Form.Item>
<Form.Item
name="status"
label="状态"
rules={[{ required: true, message: '请选择状态' }]}
>
<Select placeholder="请选择状态">
<OptGroup>
<Select.Option value="0">正常</Select.Option>
<Select.Option value="1">停用</Select.Option>
</OptGroup>
</Select>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
保存
</Button>
</Form.Item>
</Form>
</Modal>
<Modal
title="添加物料分类"
width={640}
visible={showMaterialTypeModal}
bodyStyle={{ padding: '32px 40px 48px' }}
footer={null}
onCancel={() => {
setShowMaterialTypeModal(false);
}}
destroyOnClose
maskClosable={false}
>
<Form
layout="vertical"
preserve={false}
onFinish={async (values) => {
const response = await quickAPI.AddMaterialType(values);
if (response.data) {
message.success('添加成功');
setShowMaterialTypeModal(false);
onFetchMaterialTypeList();
} 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="status"
label="状态"
rules={[{ required: true, message: '请选择物料分类状态' }]}
>
<Select placeholder="请选择物料分类状态">
<OptGroup>
<Select.Option value="0">正常</Select.Option>
<Select.Option value="1">停用</Select.Option>
</OptGroup>
</Select>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
保存
</Button>
</Form.Item>
</Form>
</Modal>
</div>
</>
}

export default MaterialConfig;

+ 25
- 2
src/pages/quickStart/index.jsx 查看文件

@@ -6,6 +6,8 @@ import StoreConfig from './components/StoreConfig';
import DeviceConfig from './components/DeviceConfig';
import FoodMenuConfig from './components/FoodMenuConfig';
import GoodsConfig from './components/GoodsConfig';
import BomConfig from './components/BomConfig';
import MaterialConfig from './components/MaterialConfig';

const { Step } = Steps;

@@ -54,6 +56,27 @@ const QuickStart = () => {
status: 0,
imgUrl: "",
isWeigh: ""
},
bomConfig: {
id: "",
code: "",
name: "",
bomTypeList: [],
sort: 0
},
materialConfig: {
id: "",
code: "",
name: "",
specs: "",
aittribute: "",
price: 0,
netrecovery: 0,
typeID: "",
stockUint: "",
outstockUint: "",
proportion: 1,
status: ""
}
});

@@ -87,8 +110,8 @@ const QuickStart = () => {
<DeviceConfig deviceConfig={quickStartObj.deviceConfig} current={current} steps={stepsText} onFinishForm={onFinishForm} prev={prev}></DeviceConfig>,
<FoodMenuConfig foodMenuConfig={quickStartObj.foodMenuConfig} current={current} steps={stepsText} onFinishForm={onFinishForm} prev={prev}></FoodMenuConfig>,
<GoodsConfig goodsConfig={quickStartObj.goodsConfig} current={current} steps={stepsText} onFinishForm={onFinishForm} prev={prev}></GoodsConfig>,
<h1>配方配置</h1>,
<h1>物料配置</h1>,
<BomConfig bomConfig={quickStartObj.bomConfig} current={current} steps={stepsText} onFinishForm={onFinishForm} prev={prev}></BomConfig>,
<MaterialConfig materialConfig={quickStartObj.materialConfig} current={current} steps={stepsText} onFinishForm={onFinishForm} prev={prev}></MaterialConfig>,
<h1>确认配置</h1>
];



+ 84
- 0
src/pages/quickStart/service.js 查看文件

@@ -169,6 +169,90 @@ export default {
method: 'Post',
data: data,
});
},

/**
* 获取配方分页
* @param {*} data
* @returns
*/
GetBomPage(data) {
return request(`/kitchen/api/bom/getpage`, {
method: 'Post',
data: data,
});
},

/**
* 获取菜谱分类
* @param {*} data
* @returns
*/
GetBomTypePage(data) {
return request(`/kitchen/api/bom/getbomtypepage`, {
method: 'Post',
data: data,
});
},

//添加菜谱分类
CreateBomType(data) {
return request(`/kitchen/api/bom/addbomtype`, {
method: 'Post',
data: data,
});
},

/**获取物料基础信息 */
GetMaterialPage(params) {
return request('/kitchen/api/product/product-list', {
method: 'Post',
data: params,
});
},

/**获取物料类别 */
GetMaterialTypeList(params) {
return request('/kitchen/api/product-type/type-list', {
method: 'GET',
params: {
...params,
},
});
},

/**获取物料单位 */
GetMaterialUintList(params) {
return request('/kitchen/api/unit/uint-list', {
method: 'GET',
params: {
...params,
},
});
},

/**
* 添加物料单位
* @param {*} data
* @returns
*/
AddMaterialUnit(data) {
return request('/kitchen/api/unit', {
method: 'POST',
data: data,
});
},

/**
* 添加物料分类
* @param {*} data
* @returns
*/
AddMaterialType(data) {
return request('/kitchen/api/product-type', {
method: 'POST',
data: data,
});
}

}

Loading…
取消
儲存