@@ -1,5 +1,5 @@ | |||
import { PlusOutlined } from '@ant-design/icons'; | |||
import { Button, message, Input, Drawer, Popconfirm } from 'antd'; | |||
import { PlusOutlined, DownloadOutlined } from '@ant-design/icons'; | |||
import { Button, message, Input, Drawer, Popconfirm, Modal, Select } from 'antd'; | |||
import React, { useState, useRef, useEffect } from 'react'; | |||
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout'; | |||
import ProTable from '@ant-design/pro-table'; | |||
@@ -14,7 +14,10 @@ import { | |||
goodsType, | |||
getBomInfo, | |||
AddBomApi, | |||
getbompage | |||
getbompage, | |||
getDevice, | |||
getGoodsWithDeviceId, | |||
goodsSimpleExport | |||
} from './service'; | |||
/** | |||
@@ -122,6 +125,14 @@ const GoodsManage = () => { | |||
const [getGoodsBoms, setGoodsBoms] = useState(); | |||
/** 商品配方调整新建/更新窗口的弹窗 */ | |||
const [setGoodsBomModalVisible, handleGoodsBomModalVisible] = useState(); | |||
const [deviceData, setDeviceData] = useState([]); | |||
const [deviceGoodData, setDeviceGoodData] = useState([]); | |||
const [deviceId, setDeviceId] = useState(''); | |||
const [deviceName, setDeviceName] = useState(''); | |||
const [goodsId, setGoodsId] = useState([]); | |||
const [isDataModalOpen, setIsDataModalOpen] = useState(false); | |||
const [ids, setIds] =useState(''); | |||
/** 国际化配置 */ | |||
useEffect(() => { | |||
@@ -145,7 +156,41 @@ const GoodsManage = () => { | |||
}); | |||
} | |||
initGoodsType(); | |||
initGetDevice(); | |||
}, []); | |||
const initGetDevice = () =>{ | |||
getDevice().then((r) => { | |||
var arr = r.data; | |||
if (r.succeeded) { | |||
var list = []; | |||
arr.forEach((item) => { | |||
list.push({ | |||
value: item.id, | |||
label: item.deviceName | |||
}); | |||
}); | |||
setDeviceData(list); | |||
} | |||
}); | |||
} | |||
const initGetdevicegoodsList = (deviceId) =>{ | |||
getGoodsWithDeviceId(deviceId).then((r) => { | |||
var arr = r.data; | |||
if (r.succeeded) { | |||
var list = []; | |||
var idList = []; | |||
arr.forEach((item) => { | |||
list.push({ | |||
value: item.id, | |||
label: item.name | |||
}); | |||
idList.push(item.id); | |||
}); | |||
setIds(idList); | |||
setDeviceGoodData(list); | |||
} | |||
}); | |||
} | |||
const columns = [ | |||
{ | |||
title: '主键', | |||
@@ -342,6 +387,49 @@ const GoodsManage = () => { | |||
], | |||
}, | |||
]; | |||
const handleGoodChange = (value, option) => { | |||
setGoodsId(value); | |||
} | |||
const handleDataDeviceChange = (value, option) => { | |||
setDeviceId(option?.value); | |||
setDeviceName(option?.label); | |||
initGetdevicegoodsList(option?.value); | |||
} | |||
const handleDataDownload = async()=>{ | |||
if(deviceName == '') | |||
{ | |||
message.error('请选择一个设备!'); | |||
return; | |||
} | |||
const base64String = await goodsSimpleExport({ goodsId: goodsId, deviceId: deviceId, ids: ids }); | |||
// 解码 Base64 数据 | |||
const binaryString = atob(base64String); | |||
// 转换为 Uint8Array | |||
const bytes = new Uint8Array(binaryString.length); | |||
for (let i = 0; i < binaryString.length; i++) { | |||
bytes[i] = binaryString.charCodeAt(i); | |||
} | |||
// 创建 Blob 对象 | |||
const blob = new Blob([bytes], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); | |||
// 创建一个临时的 URL,指向 Blob 对象 | |||
const url = window.URL.createObjectURL(blob); | |||
// 创建一个 <a> 元素 | |||
const link = document.createElement('a'); | |||
const fileName = "商品.xlsx"; | |||
link.href = url; | |||
link.setAttribute('download', fileName); | |||
// 将 <a> 元素添加到页面中 | |||
document.body.appendChild(link); | |||
// 模拟用户点击下载链接,触发文件下载 | |||
link.click(); | |||
// 下载完成后,移除 <a> 元素 | |||
document.body.removeChild(link); | |||
setDeviceId(''); | |||
setDeviceName(''); | |||
setGoodsId([]); | |||
setIds([]); | |||
setIsDataModalOpen(false); | |||
} | |||
return ( | |||
<PageContainer> | |||
<ProTable | |||
@@ -368,6 +456,14 @@ const GoodsManage = () => { | |||
> | |||
<PlusOutlined /> 新建 | |||
</Button>, | |||
<Button | |||
key="primary" | |||
onClick={async () => { | |||
setIsDataModalOpen(true); | |||
}} | |||
> | |||
<DownloadOutlined /> 下载商品工艺 | |||
</Button> | |||
]} | |||
request={async (params) => { | |||
var goodsData = []; | |||
@@ -451,7 +547,67 @@ const GoodsManage = () => { | |||
createModalVisible={createModalVisible} | |||
values={currentRow || {}} | |||
/> | |||
<Modal | |||
title="下载商品工艺" | |||
open={isDataModalOpen} | |||
footer={false} | |||
width={450} | |||
maskClosable={false} | |||
destroyOnClose={true} | |||
onCancel={() => { | |||
setDeviceGoodData([]) | |||
setDeviceId('') | |||
setDeviceName('') | |||
setGoodsId([]) | |||
setIds('') | |||
setIsDataModalOpen(false) | |||
}}> | |||
<div style={{ marginBottom: 10 }}> | |||
<span style={{ marginRight: 10 }}><span style={{color:'red',marginRight: 3}}>*</span>选择设备:</span> | |||
<Select | |||
showSearch | |||
allowClear | |||
style={{ | |||
width: 300, | |||
marginRight: 10 | |||
}} | |||
placeholder="请选择设备" | |||
optionFilterProp="children" | |||
filterOption={(input, option) => (option?.label ?? '').includes(input)} | |||
filterSort={(optionA, optionB) => | |||
(optionA?.label ?? '').toLowerCase().localeCompare((optionB?.label ?? '').toLowerCase()) | |||
} | |||
onChange={async (value, option) => { handleDataDeviceChange(value, option) }} | |||
options={deviceData} | |||
required | |||
/> | |||
</div> | |||
<div style={{ marginBottom: 10 }}> | |||
<span style={{ marginLeft: 9, marginRight: 10 }}>选择商品:</span> | |||
<Select | |||
mode='multiple' | |||
showSearch | |||
allowClear | |||
style={{ | |||
width: 300, | |||
marginRight: 10 | |||
}} | |||
placeholder="选择商品下载工艺" | |||
optionFilterProp="children" | |||
filterOption={(input, option) => (option?.label ?? '').includes(input)} | |||
filterSort={(optionA, optionB) => | |||
(optionA?.label ?? '').toLowerCase().localeCompare((optionB?.label ?? '').toLowerCase()) | |||
} | |||
onChange={async (value, option) => { handleGoodChange(value, option) }} | |||
options={deviceGoodData} | |||
/> | |||
</div> | |||
<Button | |||
icon={<DownloadOutlined />} | |||
style={{ marginLeft: '22.2%' }} | |||
onClick = {handleDataDownload} | |||
>下载</Button> | |||
</Modal> | |||
<Drawer | |||
width={600} | |||
visible={showDetail} | |||
@@ -87,3 +87,21 @@ export async function getgoodsTaste(data) { | |||
return request(`/kitchen/api/goodstaste/getlist`); | |||
} | |||
export async function getDevice() { | |||
return request(`/kitchen/api/goodstechnology/getDevice`, { | |||
method: 'Get', | |||
}); | |||
} | |||
export async function getGoodsWithDeviceId(deviceId) { | |||
return request(`/kitchen/api/goodes/GetGoodsWithDeviceId?deviceId=` + deviceId, { | |||
method: 'Get' | |||
}); | |||
} | |||
export async function goodsSimpleExport(data) { | |||
return request(`/kitchen/api/goodes/GoodsSimpleExport`, { | |||
method: 'POST', | |||
data: data | |||
}); | |||
} |
@@ -0,0 +1,116 @@ | |||
import React, { useState, useEffect } from 'react'; | |||
import { Modal, Form, Input, DatePicker, Checkbox, Button, Select, InputNumber, message } from 'antd'; | |||
import moment from 'moment'; | |||
import { getGoods } from '../services'; | |||
const RuleForm = (props) => { | |||
const { RangePicker } = DatePicker; | |||
const [checked, setChecked] = useState(false); | |||
const [dateDisable, setDateDisable] = useState(false); | |||
const [itemDisable, setItemDisable] = useState(false); | |||
useEffect(() => { | |||
const ruleAts = []; | |||
if (props.values) { | |||
if (props.values.startAt) { | |||
props.values.startAt = moment(props.values.startAt); | |||
} | |||
ruleAts.push(props.values.startAt); | |||
if (props.values.endAt) { | |||
props.values.endAt = moment(props.values.endAt); | |||
} | |||
ruleAts.push(props.values.endAt); | |||
props.values.ruleAt = ruleAts; | |||
} | |||
if (props.values.ruleType == 2) { | |||
setItemDisable(true); | |||
setDateDisable(true); | |||
if (props.values.isLong == 1) { | |||
setChecked(true); | |||
} else { | |||
setChecked(false); | |||
} | |||
} else { | |||
setItemDisable(false); | |||
setDateDisable(false); | |||
if (props.values.isLong == 1) { | |||
setChecked(true); | |||
setDateDisable(true); | |||
} else { | |||
setChecked(false); | |||
setDateDisable(false); | |||
} | |||
} | |||
}, [props.values]); | |||
const CheckboxChange = (e) => { | |||
if (e.target.checked) { | |||
setChecked(true); | |||
setDateDisable(true); | |||
} | |||
else { | |||
setChecked(false); | |||
setDateDisable(false); | |||
} | |||
} | |||
const ruleTypeChange = (value) => { | |||
if (value == 1) { | |||
setItemDisable(false); | |||
if (checked) { | |||
setDateDisable(true); | |||
} else { | |||
setDateDisable(false); | |||
} | |||
} else { | |||
setItemDisable(true); | |||
setDateDisable(true); | |||
} | |||
} | |||
return ( | |||
<Modal | |||
title={'编辑销售规则'} | |||
width={640} | |||
visible={props.ruleModelVisible} | |||
bodyStyle={{ padding: '32px 40px 48px' }} | |||
footer={null} | |||
onCancel={() => { | |||
props.onCancel(); | |||
}} | |||
destroyOnClose | |||
> | |||
<Form | |||
layout="Horizontal" | |||
initialValues={props.values} | |||
onFinish={props.onFinish} | |||
> | |||
<Form.Item name="id" hidden={true}> | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item name="ruleType" label="规则类型" rules={[{ required: true }]}> | |||
<Select style={{ width: '100%' }} onChange={ruleTypeChange}> | |||
<Select.Option value={1}>时间范围</Select.Option> | |||
<Select.Option value={2}>每日</Select.Option> | |||
</Select> | |||
</Form.Item> | |||
<Form.Item name="ruleAt" label="销售时间" style={{ marginLeft: '10px' }}> | |||
<RangePicker showTime format="YYYY-MM-DD HH:mm:ss" style={{ width: '100%' }} disabled={dateDisable} /> | |||
</Form.Item> | |||
<Form.Item name="isLong" valuePropName="checked" label="是否长期有效" style={{ marginLeft: '10px' }}> | |||
<Checkbox style={{ marginLeft: '10px' }} onChange={CheckboxChange} disabled={itemDisable} checked={checked}></Checkbox> | |||
</Form.Item> | |||
<Form.Item name="saleCount" label="销售数量" rules={[{ required: true }]}> | |||
<InputNumber style={{ width: '100%' }} min={0} /> | |||
</Form.Item> | |||
<Form.Item style={{ marginLeft: '10px' }}> | |||
<Button type="primary" htmlType="submit"> | |||
保存 | |||
</Button> | |||
</Form.Item> | |||
</Form> | |||
</Modal> | |||
) | |||
}; | |||
export default RuleForm; |
@@ -1,14 +1,16 @@ | |||
import { PlusOutlined } from '@ant-design/icons'; | |||
import { Tabs, Card, Pagination, Table, message, Button, Popconfirm, Modal } from 'antd'; | |||
import { Tabs, Card, Pagination, Table, message, Button, Popconfirm, Modal, Form } from 'antd'; | |||
const { TabPane } = Tabs; | |||
import React, { useState, useRef, useEffect } from 'react'; | |||
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout'; | |||
import { GetStoreInfoPage, GetStoreGoods, AddStoreGood, UpdateStoreGoods, DelStoreGoods, UpdateStoreGoodsStatusAsync, stopgoods,StoreGoodsAllUpdate } from "./services" | |||
import { GetStoreInfoPage, GetStoreGoods, AddStoreGood, UpdateStoreGoods, DelStoreGoods, UpdateStoreGoodsStatusAsync, stopgoods,StoreGoodsAllUpdate,UpdateStoreFoodSaleRule } from "./services" | |||
import ProTable from '@ant-design/pro-table'; | |||
import CreateForm from './components/CreateForm'; | |||
import LogForm from './components/Logs'; | |||
import { UnorderedListOutlined } from '@ant-design/icons'; | |||
import { history } from 'umi'; | |||
import RuleForm from './components/Rule'; | |||
import moment from 'moment'; | |||
const key = 'message'; | |||
//修改 | |||
@@ -22,7 +24,7 @@ const handleUpdate = async (fields) => { | |||
message.success('修改成功'); | |||
return true; | |||
} else { | |||
message.success('修改失败'); | |||
message.error('修改失败'); | |||
return false; | |||
} | |||
}); | |||
@@ -62,13 +64,14 @@ const storeGoodsInfo = (props) => { | |||
const [total, SetTotal] = useState(0); | |||
const [loading, SetLoading] = useState(false); | |||
const [storeId, SetstoreId] = useState(); | |||
const [ruleModelVisible, setRuleModelVisible] = useState(false); | |||
const [ruleRow, setRuleRow] = useState(); | |||
const [createModalVisible, handleModalVisible] = useState(false); | |||
const [currentRow, setCurrentRow] = useState(); | |||
const [currentTabRow, setCurrentTabRow] = useState(); | |||
const actionRef = useRef(); | |||
const [logVisible, SetLogVisible] = useState(false); | |||
const [foodId, setFoodId] = useState(); | |||
useEffect(() => { | |||
getStoreInfoPageInfo(1); | |||
@@ -96,6 +99,26 @@ const storeGoodsInfo = (props) => { | |||
}; | |||
const ruleUpdate = async (fields) => { | |||
try { | |||
message.loading('正在修改', key); | |||
message.destroy(key); | |||
await UpdateStoreFoodSaleRule(JSON.stringify(fields)).then((r) => { | |||
message.destroy(key); | |||
if (r.data) { | |||
message.success('修改成功'); | |||
return true; | |||
} else { | |||
message.error('修改失败'); | |||
return false; | |||
} | |||
}); | |||
} catch (error) { | |||
message.error('修改失败请重试!'); | |||
return false; | |||
} | |||
} | |||
const getStoreInfoPageInfo = async (page) => { | |||
SetLoading(true); | |||
try { | |||
@@ -244,6 +267,16 @@ const storeGoodsInfo = (props) => { | |||
> | |||
加购商品 | |||
</a>, | |||
<a | |||
key="config" | |||
onClick={() => { | |||
setRuleModelVisible(true); | |||
setFoodId(record.foodId); | |||
setRuleRow(record.storeFoodSaleRuleDto); | |||
}} | |||
> | |||
销售规则 | |||
</a> | |||
], | |||
}, | |||
]; | |||
@@ -368,6 +401,36 @@ const storeGoodsInfo = (props) => { | |||
values={currentRow || {}} | |||
/> | |||
<RuleForm | |||
onFinish={async (value) => { | |||
value.storeId = storeId; | |||
value.foodId = foodId; | |||
if (value.ruleAt != null) { | |||
value.startAt = moment(value.ruleAt[0]).format('YYYY-MM-DD HH:mm:ss'); | |||
value.endAt = moment(value.ruleAt[1]).format('YYYY-MM-DD HH:mm:ss'); | |||
} | |||
else { | |||
value.startAt = moment(new Date(Date.now())).format('YYYY-MM-DD HH:mm:ss'); | |||
value.endAt = moment(new Date(Date.now())).format('YYYY-MM-DD HH:mm:ss'); | |||
} | |||
value.isLong = value.isLong ? '1' : '0'; | |||
var success = ruleUpdate(value); | |||
if (success) { | |||
setFoodId(undefined); | |||
setRuleModelVisible(false); | |||
setRuleRow(undefined); | |||
actionRef.current.reload(); | |||
} | |||
}} | |||
onCancel={() => { | |||
setFoodId(undefined); | |||
setRuleModelVisible(false); | |||
setRuleRow(undefined); | |||
}} | |||
ruleModelVisible={ruleModelVisible} | |||
values={ruleRow || {}} | |||
/> | |||
<Modal | |||
destroyOnClose={true} | |||
width={800} | |||
@@ -91,3 +91,10 @@ export function GetRequestLogPageAsync(data) { | |||
data: data, | |||
}); | |||
} | |||
export async function UpdateStoreFoodSaleRule(data) { | |||
return request(`/kitchen/api/Store/UpdateStoreFoodSaleRule`, { | |||
method: 'post', | |||
data: data | |||
}); | |||
} |