@@ -0,0 +1,145 @@ | |||
import React, { useState, useRef } from 'react'; | |||
import { Button, Modal, Form, Input, Select, Divider, Space, message } from 'antd'; | |||
import { PlusOutlined } from '@ant-design/icons'; | |||
import { EditableProTable } from '@ant-design/pro-table'; | |||
import { AddBomType } from '../services'; | |||
const App = (props) => { | |||
const [form] = Form.useForm(); | |||
const inputRef = useRef(null); | |||
const [typename, settypename] = useState(''); | |||
const [dataSource, setDataSource] = useState([]); | |||
const [editableKeys, setEditableRowKeys] = useState([]); | |||
const onNameChange = (event) => { | |||
settypename(event.target.value); | |||
} | |||
const columns = [ | |||
{ | |||
title: '物料名称', | |||
dataIndex: 'batchingId', | |||
formItemProps: (form, { rowIndex }) => { | |||
return { | |||
rules: | |||
rowIndex > 1 ? [{ required: true, message: '此项为必填项' }] : [], | |||
}; | |||
}, | |||
valueType: 'select', | |||
fieldProps: { | |||
showSearch: true, | |||
options: props.matedata.map((item, index) => { return { label: item.name, value: item.id } }) | |||
}, | |||
width: '25%', | |||
}, | |||
{ | |||
title: '用量', | |||
dataIndex: 'dosage', | |||
valueType: 'digit', | |||
width: '15%', | |||
}, | |||
{ | |||
title: '操作', | |||
valueType: 'option', | |||
width: '15%', | |||
render: () => { | |||
return null; | |||
}, | |||
}, | |||
] | |||
const addItem = (e) => { | |||
e.preventDefault(); | |||
if (typename.length == 0) { | |||
message.error("请输入名称"); | |||
} else { | |||
var parm = { name: typename } | |||
AddBomType(parm).then((r) => { | |||
if (r.succeeded) { | |||
message.success('添加成功'); | |||
props.initTypeList(); | |||
settypename(''); | |||
} else { | |||
message.error(r.errors); | |||
} | |||
}) | |||
} | |||
} | |||
return ( | |||
<> | |||
<Modal title="Basic Modal" | |||
onCancel={props.onCancel} | |||
open={props.modalVisible} > | |||
<Form layout="horizontal" preserve={false} form={form} > | |||
<Form.Item name="bomName" label="配方名称" rules={[{ required: true, message: '配方名称' }]}> | |||
<Input placeholder="请输入配方名称" /> | |||
</Form.Item> | |||
<Form.Item name="bomTypeList" rules={[{ required: true, message: '配方分类' }]} label="配方分类" > | |||
<Select | |||
style={{ width: '100%' }} | |||
mode="tags" | |||
placeholder="请选配方分类" | |||
options={props.bomTypeData} | |||
dropdownRender={(menu) => ( | |||
<> | |||
{menu} | |||
<Divider style={{ margin: '8px 0' }} /> | |||
<Space style={{ padding: '0 8px 4px' }}> | |||
<Input | |||
placeholder="请输入配方分类" | |||
ref={inputRef} | |||
value={typename} | |||
onChange={onNameChange} | |||
onKeyDown={(e) => e.stopPropagation()} | |||
/> | |||
<Button type="text" icon={<PlusOutlined />} onClick={addItem}> | |||
新增 | |||
</Button> | |||
</Space> | |||
</> | |||
)} | |||
/> | |||
</Form.Item> | |||
</Form> | |||
<EditableProTable | |||
headerTitle={<span><span style={{ color: 'red', marginRight: 3 }}>*</span>配方详情</span>} | |||
columns={columns} | |||
rowKey="id" | |||
value={dataSource} | |||
onChange={setDataSource} | |||
recordCreatorProps={{ | |||
newRecordType: 'dataSource', | |||
record: () => ({ | |||
id: Date.now(), | |||
}), | |||
}} | |||
editable={{ | |||
type: 'multiple', | |||
editableKeys, | |||
actionRender: (row, config, defaultDoms) => { | |||
return [defaultDoms.delete, defaultDoms.Button]; | |||
}, | |||
onValuesChange: (record, recordList) => { | |||
setDataSource(recordList); | |||
}, | |||
onDelete: async (key, row) => { | |||
console.log(key) | |||
console.log(row) | |||
}, | |||
onChange: setEditableRowKeys, | |||
}} /> | |||
</Modal> | |||
</> | |||
); | |||
}; | |||
export default App; |
@@ -1,18 +1,54 @@ | |||
import { PlusOutlined } from '@ant-design/icons'; | |||
import { Button, message, Input, Drawer, Modal, Space, Tag,Popconfirm } from 'antd'; | |||
import { Button, message, Input, Drawer, Modal, Space, Tag, Popconfirm } from 'antd'; | |||
import React, { useState, useRef, useEffect } from 'react'; | |||
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout'; | |||
import ProTable from '@ant-design/pro-table'; | |||
import {bomPage} from './services'; | |||
import { bomPage, getproductpage,GetbomTypelist } from './services'; | |||
import CreateBom from './components/CreateBom'; | |||
const GoodsBomsManage = (props) => { | |||
const actionRef = useRef(); | |||
const [modalVisible, setModalVisible] = useState(false); | |||
const [matedata, setMatedata] = useState([]); | |||
const [bomTypeData,setbomTypeData]= useState([]); | |||
useEffect(() => { | |||
intBatching();//默认原料 | |||
}, []); | |||
function intBatching() { | |||
getproductpage().then((r) => { | |||
setMatedata(r.data); | |||
}); | |||
} | |||
function initTypeList() { | |||
initGetbomType(); | |||
} | |||
function initGetbomType() { | |||
GetbomTypelist().then((r) => { | |||
var list = []; | |||
if (r.data.length > 0) { | |||
r.data.forEach((item) => { | |||
list.push({ text: item.name, value: item.id, label: item.name }); | |||
}); | |||
} | |||
setbomTypeData(list) | |||
}) | |||
} | |||
function initGetbomType(){ | |||
GetbomTypelist().then((r)=>{ | |||
var list = []; | |||
if (r.data.length > 0) { | |||
r.data.forEach((item) => { | |||
list.push({ text: item.name, value: item.id, label: item.name }); | |||
}); | |||
} | |||
setbomTypeData(list) | |||
}) | |||
} | |||
const columns = [ | |||
{ | |||
@@ -76,7 +112,7 @@ const GoodsBomsManage = (props) => { | |||
okText="是" | |||
cancelText="否" | |||
onConfirm={async () => { | |||
}} | |||
onCancel={() => { }} | |||
> | |||
@@ -92,42 +128,50 @@ const GoodsBomsManage = (props) => { | |||
title: '', | |||
breadcrumb: {}, | |||
}}> | |||
<ProTable | |||
columns={columns} | |||
actionRef={actionRef} | |||
rowKey="id" | |||
toolBarRender={() => [ | |||
<Button | |||
type="primary" | |||
key="primary" | |||
onClick={() => { | |||
setModalVisible(true); | |||
}} | |||
> | |||
<PlusOutlined /> 新建 | |||
</Button>, | |||
]} | |||
<ProTable | |||
columns={columns} | |||
actionRef={actionRef} | |||
rowKey="id" | |||
toolBarRender={() => [ | |||
<Button | |||
type="primary" | |||
key="primary" | |||
onClick={() => { | |||
setModalVisible(true); | |||
}} | |||
> | |||
<PlusOutlined /> 新建 | |||
</Button>, | |||
]} | |||
request={async (params) => { | |||
var total = 0; | |||
var data = []; | |||
const res = await bomPage(params); | |||
if (res.statusCode == 200) { | |||
data = res.data.data; | |||
total = res.data.total; | |||
} | |||
return { | |||
data: data, | |||
success: true, | |||
total: total, | |||
}; | |||
}} | |||
rowSelection={{ | |||
onChange: (_, selectedRows) => setSelectedRows(selectedRows), | |||
}} | |||
/> | |||
{/* 新增菜谱 */} | |||
<CreateBom modalVisible={modalVisible} | |||
matedata={matedata} | |||
initTypeList={initTypeList} | |||
onCancel={() => { setModalVisible(false); }} | |||
/> | |||
request={async (params) => { | |||
var total = 0; | |||
var data=[]; | |||
const res = await bomPage(params); | |||
if(res.statusCode==200){ | |||
data=res.data.data; | |||
total=res.data.total; | |||
} | |||
return { | |||
data: data, | |||
success: true, | |||
total: total, | |||
}; | |||
}} | |||
rowSelection={{ | |||
onChange: (_, selectedRows) => setSelectedRows(selectedRows), | |||
}} | |||
/> | |||
</PageContainer> | |||
); | |||
}; | |||
@@ -8,4 +8,26 @@ export async function bomPage(data) { | |||
}); | |||
} | |||
export async function AddBomType (data) { | |||
return request(getDataBaseUrl()+`/api/bom/addbomtype`, { | |||
method: 'Post', | |||
data: data, | |||
// params: { ...params }, | |||
// ...(options || {}), | |||
}); | |||
} | |||
export async function getproductpage(params) { | |||
return request(getDataBaseUrl()+'/api/batching/getbatchingselectlist', { | |||
method: 'Get', | |||
}); | |||
} | |||
export async function GetbomTypelist (data) { | |||
return request(getDataBaseUrl()+`/api/bom/getbomtypelist`, { | |||
method: 'Get', | |||
// params: { ...params }, | |||
// ...(options || {}), | |||
}); | |||
} | |||
@@ -214,6 +214,8 @@ const GoodsbomFrom = (props) => { | |||
</Select> | |||
</Form.Item> | |||
</Form> | |||
<span><span style={{color:'red',marginRight: 3}}>*</span>商品属性</span> | |||
{ | |||
props.goodsAttriburteData == undefined ? '' :( | |||
@@ -1,5 +1,5 @@ | |||
import React, { useState,useRef,useEffect } from 'react'; | |||
import { PlusOutlined} from '@ant-design/icons'; | |||
import { PlusOutlined,CheckOutlined} from '@ant-design/icons'; | |||
import { Modal, Form, Input, Button, Select,Radio,message,Tag,Divider,Space } from 'antd'; | |||
import { AddBomType,getproductpage } from '../service'; | |||
import { | |||
@@ -14,6 +14,8 @@ const GoodsbomFrom = (props) => { | |||
const [form] = Form.useForm(); | |||
const [typename, settypename] = useState(''); | |||
const inputRef = useRef(null); | |||
const [disaenumbled, setdisaenumbled] = useState('block'); | |||
const [disnewd, setdisnewd] = useState('none'); | |||
const onNameChange=(event)=>{ | |||
settypename(event.target.value); | |||
} | |||
@@ -37,8 +39,8 @@ const GoodsbomFrom = (props) => { | |||
} | |||
useEffect(() => { | |||
console.log("111111111") | |||
console.log(props.defaultmatedata) | |||
console.log("props.Bomdata",props.Bomdata) | |||
console.log(props.goodsname) | |||
form.setFieldsValue({ | |||
bomName: props.goodsname, | |||
// bomType:1 | |||
@@ -97,21 +99,30 @@ const GoodsbomFrom = (props) => { | |||
.then((values) => { | |||
var check=true; | |||
var data=values; | |||
console.log(dataSource) | |||
console.log("values",values) | |||
if(checkvalue.length==0){ | |||
check=false; | |||
message.error("请选择商品属性") | |||
}else{ | |||
data.shuxing=checkvalue; | |||
} | |||
if(dataSource.length==0){ | |||
check=false; | |||
message.error("请选择物料") | |||
}else{ | |||
data.mate=dataSource.map(x=>{return {batchingId:x.batchingId,dosage:x.dosage}}); | |||
if(disnewd=="block"){ | |||
if(dataSource.length==0){ | |||
check=false; | |||
message.error("请选择物料") | |||
}else{ | |||
data.mate=dataSource.map(x=>{return {batchingId:x.batchingId,dosage:x.dosage}}); | |||
} | |||
} | |||
if(check){ | |||
form.resetFields(); | |||
if(disaenumbled=="block"){ | |||
data.Type="check" | |||
}else{ | |||
data.Type="add" | |||
} | |||
data.bomType=1; | |||
props.onFinish(data); | |||
setDataSource([]) | |||
} | |||
@@ -151,7 +162,13 @@ const GoodsbomFrom = (props) => { | |||
}); | |||
setCheckvalue(updatedValues) | |||
} | |||
const handleChange = (value) => { | |||
console.log(`selected ${value}`); | |||
form.setFieldsValue({ | |||
bomId: value, | |||
// bomType:1 | |||
}); | |||
}; | |||
return ( | |||
<Modal | |||
title={'新建配方'} | |||
@@ -167,12 +184,66 @@ const GoodsbomFrom = (props) => { | |||
maskClosable={false} | |||
destroyOnClose | |||
> | |||
<Form layout="horizontal" preserve={false} form={form} | |||
> | |||
<Form.Item name="bomName" label="配方名称" rules={[{ required: true, message: '配方名称' }]}> | |||
<Input placeholder="请输入配方名称"/> | |||
<span><span style={{color:'red',marginRight: 3}}>*</span>商品属性</span> | |||
{ | |||
props.goodsAttriburteData == undefined ? '' :( | |||
props.goodsAttriburteData.map((item, index) => { | |||
return ( | |||
<div style={{marginLeft: 80}}> | |||
<div> | |||
<span style={{marginRight: 10}}> <Tag color="blue">{item.attributeName}</Tag>:</span> | |||
<span> | |||
<Radio.Group name={"radiogroup"+index} buttonStyle="solid" size="small" onChange={onChangevalue}> | |||
{ | |||
item.goodsAttributeValueList.map((item, index)=>{ | |||
return ( | |||
<Radio.Button name={index} value={item.goodsAttributeValuId} style={{marginRight: 22, marginTop: 16}}>{item.attributeValue}</Radio.Button> | |||
) | |||
}) | |||
} | |||
</Radio.Group> | |||
</span> | |||
</div> | |||
</div> | |||
); | |||
}) | |||
) | |||
} | |||
<Form layout="horizontal" preserve={false} form={form}> | |||
<Form.Item style={{display:disaenumbled}} name="bomId" label="选择配方" rules={[{ required: false, message: '配方信息' }]}> | |||
<Select | |||
showSearch | |||
mode="multiple" | |||
style={{width:'90%'}} | |||
optionFilterProp="children" | |||
onChange={handleChange} | |||
placeholder="请选配方信息"> | |||
{props.Bomdata?.map((item, index) => { | |||
return ( | |||
<Option index={index} value={item.id} key={item.id}> | |||
{item.name} | |||
</Option> | |||
); | |||
})} | |||
</Select> | |||
<Button | |||
type="primary" | |||
key="primary" onClick={ async() => { | |||
setdisaenumbled("none") | |||
setdisnewd("block") | |||
}}><PlusOutlined />新建</Button> | |||
</Form.Item> | |||
<Form.Item style={{display:disnewd}} name="bomName" label="配方名称" rules={[{ required: false, message: '配方名称' }]}> | |||
<Input style={{width:'87%'}} placeholder="请输入配方名称"/> | |||
<Button | |||
type="primary" | |||
key="primary" onClick={ async() => { | |||
setdisaenumbled("block") | |||
setdisnewd("none") | |||
}}><CheckOutlined />选择配方</Button> | |||
</Form.Item> | |||
<Form.Item name="bomTypeList" rules={[{ required: true, message: '配方分类' }]} label="配方分类" > | |||
<Form.Item style={{display:disnewd}} name="bomTypeList" rules={[{ required: false, message: '配方分类' }]} label="配方分类" > | |||
<Select | |||
style={{width: '100%'}} | |||
mode="tags" | |||
@@ -198,7 +269,7 @@ const GoodsbomFrom = (props) => { | |||
)} | |||
/> | |||
</Form.Item> | |||
<Form.Item name="bomType" label="配方类型" initialValue='1' rules={[{ required: true, message: '配方类型' }]}> | |||
{/* <Form.Item name="bomType" label="配方类型" initialValue='1' rules={[{ required: true, message: '配方类型' }]}> | |||
<Select | |||
placeholder="请选配方类型" | |||
onChange={(value) => { | |||
@@ -212,34 +283,10 @@ const GoodsbomFrom = (props) => { | |||
<Select.Option value="0">辅料配方</Select.Option> | |||
</OptGroup> | |||
</Select> | |||
</Form.Item> | |||
</Form.Item> */} | |||
</Form> | |||
<span><span style={{color:'red',marginRight: 3}}>*</span>商品属性</span> | |||
{ | |||
props.goodsAttriburteData == undefined ? '' :( | |||
props.goodsAttriburteData.map((item, index) => { | |||
return ( | |||
<div style={{marginLeft: 80}}> | |||
<div> | |||
<span style={{marginRight: 10}}> <Tag color="blue">{item.attributeName}</Tag>:</span> | |||
<span> | |||
<Radio.Group name={"radiogroup"+index} buttonStyle="solid" size="small" onChange={onChangevalue}> | |||
{ | |||
item.goodsAttributeValueList.map((item, index)=>{ | |||
return ( | |||
<Radio.Button name={index} value={item.goodsAttributeValuId} style={{marginRight: 22, marginTop: 16}}>{item.attributeValue}</Radio.Button> | |||
) | |||
}) | |||
} | |||
</Radio.Group> | |||
</span> | |||
</div> | |||
</div> | |||
); | |||
}) | |||
) | |||
} | |||
<EditableProTable | |||
<EditableProTable style={{display:disnewd}} | |||
headerTitle={ <span><span style={{color:'red',marginRight: 3}}>*</span>配方详情</span>} | |||
columns={columns} | |||
rowKey="id" | |||
@@ -39,33 +39,19 @@ const Advanced = (props) => { | |||
const [UpdateBomVisible, setUpdateBomVisible] = useState(false); | |||
const [BomBatchingVisible,setBomBatchingVisible]= useState(false); | |||
const [goodsTypeIdvalue, setgoodsTypeIdvalue] = useState(); | |||
//设置 | |||
const [tabStatus, seTabStatus] = useState({ | |||
operationKey: props.location.query.tabStatus ? props.location.query.tabStatus : 'basis', | |||
tabActiveKey: props.location.query.tabStatus ? props.location.query.tabStatus : 'basis', | |||
}); | |||
useEffect(() => { | |||
// if(!props.location?.query?.values){ | |||
// history.push({ | |||
// pathname: '/database/goods/newgoods', | |||
// }); | |||
// }else{ | |||
SetCurrTabKey(tabStatus.tabActiveKey); | |||
initGetbomType(); | |||
intBatching();//默认原料 | |||
//} | |||
}, [tabStatus]) | |||
const onTabChange = (key) => { | |||
if (currentGoodsProp === 1) { | |||
message.info('套餐不能设置配方'); | |||
return; | |||
} | |||
seTabStatus({ operationKey: key, tabActiveKey: key }); | |||
//initGoodsType() | |||
}; | |||
}, []) | |||
function initGetbomType(){ | |||
GetbomTypelist().then((r)=>{ | |||
var list = []; | |||
@@ -86,14 +72,6 @@ const Advanced = (props) => { | |||
function initTypeList(){ | |||
initGetbomType(); | |||
} | |||
const operationTabList = [ | |||
{ | |||
key: 'goodsbom', | |||
tab: '商品配方', | |||
}, | |||
]; | |||
const bomcolumns = | |||
[ | |||
{ | |||
@@ -130,26 +108,26 @@ const Advanced = (props) => { | |||
dataIndex: 'option', | |||
valueType: 'option', | |||
render: (_, record) => [ | |||
<a | |||
key="primary" | |||
type="primary" | |||
onClick={() => { | |||
setUpdateBomVisible(true); | |||
setBomId(record.bomId) | |||
}} | |||
> | |||
更新 | |||
</a>, | |||
<a | |||
key="primary" | |||
type="primary" | |||
onClick={() => { | |||
setBomBatchingVisible(true); | |||
setBomId(record.bomId) | |||
}} | |||
> | |||
配方详情 | |||
</a>, | |||
// <a | |||
// key="primary" | |||
// type="primary" | |||
// onClick={() => { | |||
// setUpdateBomVisible(true); | |||
// setBomId(record.bomId) | |||
// }} | |||
// > | |||
// 更新 | |||
// </a>, | |||
// <a | |||
// key="primary" | |||
// type="primary" | |||
// onClick={() => { | |||
// setBomBatchingVisible(true); | |||
// setBomId(record.bomId) | |||
// }} | |||
// > | |||
// 配方详情 | |||
// </a>, | |||
<Popconfirm | |||
type="primary" | |||
key="primary" | |||
@@ -178,16 +156,21 @@ const Advanced = (props) => { | |||
], | |||
} | |||
] | |||
const contentList = { | |||
goodsbom: ( | |||
<Card | |||
title="商品配方" | |||
style={{ | |||
marginBottom: 24, | |||
}} | |||
bordered={false} | |||
> | |||
<ProTable | |||
return ( | |||
<PageContainer | |||
host header={{ | |||
title: [<a key="back" | |||
onClick={() => { | |||
history.push({ | |||
pathname: '/database/goods/newgoods', | |||
}); | |||
}}><ArrowLeftOutlined />返回</a>], | |||
breadcrumb: {}, | |||
}} | |||
> | |||
<ProTable | |||
columns={bomcolumns} | |||
actionRef={actionRef} | |||
rowKey="id" | |||
@@ -208,7 +191,7 @@ const Advanced = (props) => { | |||
// | |||
}} | |||
> | |||
<PlusOutlined /> 选择配方 | |||
<PlusOutlined /> 关联配方 | |||
</Button>, | |||
]} | |||
request={async (params) => { | |||
@@ -224,7 +207,20 @@ const Advanced = (props) => { | |||
}) | |||
setBomIds(nom) | |||
} | |||
getbomlist().then((r)=>{ | |||
console.log("nom",nom) | |||
if(nom.length>0){ | |||
var da=[] | |||
r.data.map(x=>{ | |||
var dif=nom.find(p=>p==x.id); | |||
if(!dif){ | |||
da.push(x) | |||
} | |||
}) | |||
} | |||
console.log("da",da) | |||
setBomdata(da) | |||
}) | |||
return { | |||
data: msg.data.data, | |||
success: true, | |||
@@ -240,6 +236,7 @@ const Advanced = (props) => { | |||
/> | |||
<CreateBom handleCreateoodsBomModalVisible={handleCreateoodsBomModalVisible} | |||
bomTypeData={bomTypeData} | |||
Bomdata={Bomdata} | |||
initTypeList={initTypeList} | |||
onFinish={async (value) => { | |||
value.goodsId=props.location.query.values.id; | |||
@@ -265,30 +262,6 @@ const Advanced = (props) => { | |||
setHandleCreateoodsBomModalVisible(false); | |||
}} | |||
/> | |||
{/* <UpdateBom onUpdateBomCancel={onUpdateBomCancel} bomtype={bomtype} BomId={BomId} UpdateBomVisible={UpdateBomVisible} bomTypeData={bomTypeData} onUpdateBomSave={onUpdateBomSave}/> | |||
<BomBatching matedata={matedata} onBomBatchingCancel={onBomBatchingCancel} BomId={BomId} BomBatchingVisible={BomBatchingVisible} onBomBatchingFinish={onBomBatchingFinish}/> */} | |||
</Card> | |||
), | |||
}; | |||
return ( | |||
<PageContainer | |||
host header={{ | |||
title: [<a key="back" | |||
onClick={() => { | |||
history.push({ | |||
pathname: '/database/goods/newgoods', | |||
}); | |||
}}><ArrowLeftOutlined />返回</a>], | |||
breadcrumb: {}, | |||
}} | |||
title={props.location.query.isAdd ? '商品新增' : '详情'} | |||
tabActiveKey={currTabKey} | |||
onTabChange={onTabChange} | |||
tabList={operationTabList} | |||
> | |||
{contentList[tabStatus.operationKey]} | |||
</PageContainer> | |||
); | |||
}; | |||
@@ -45,3 +45,8 @@ export async function GetGoodsBom(data) { | |||
// ...(options || {}), | |||
}); | |||
} | |||
export async function getbomlist() { | |||
return request(getDataBaseUrl()+'/api/bom/getbomlist', { | |||
method: 'Get', | |||
}); | |||
} |
@@ -217,7 +217,7 @@ const GoodsManage = () => { | |||
type="primary" | |||
onClick={() => { | |||
history.push({ | |||
pathname: '/database/goods/goodsInfo', | |||
pathname: '/database/goods/goodsbom', | |||
query: { | |||
isAdd: false, | |||
values: record, | |||