| | |
| | | top: "top", |
| | | resort: "sort", |
| | | start: 'Start', |
| | | stopPub: 'Stop Pub', |
| | | pause: 'Pause', |
| | | subzone: 'subzone', |
| | | bindmatnr: 'bind matnr', |
| | |
| | | }, |
| | | asnOrderItem: { |
| | | asnId: "主单标识", |
| | | asnCode: "主单编码", |
| | | asnCode: "单号", |
| | | poDetlId: "PO单ID", |
| | | poDetlCode: "PO单", |
| | | platItemId: '行号', |
| | |
| | | batch: '批量操作', |
| | | confirm: '确认', |
| | | start: '自动下发', |
| | | stopPub: '终止下发', |
| | | pause: '暂停', |
| | | pick: '拣料', |
| | | check: '盘点', |
| | |
| | | drawerVal={drawerVal} |
| | | setDrawerVal={setDrawerVal} |
| | | > |
| | | <OutStockPublic record={select} open={drawerVal} setOpen={setDrawerVal} setManualDialog={setManualDialog}/> |
| | | <OutStockPublic record={select} open={drawerVal} setOpen={setDrawerVal} /> |
| | | </PageEditDrawer> |
| | | </Box > |
| | | ) |
| | |
| | | </Stack> |
| | | |
| | | </Grid> |
| | | <Grid item xs={8} md={2}> |
| | | <Typography variant="h6" gutterBottom> |
| | | {translate('common.edit.title.common')} |
| | | </Typography> |
| | | <StatusSelectInput /> |
| | | <Box mt="2em" /> |
| | | <MemoInput /> |
| | | </Grid> |
| | | </Grid> |
| | | </SimpleForm> |
| | | </Edit > |
| | |
| | | > |
| | | <StyledDatagrid |
| | | preferenceKey='waveItem' |
| | | bulkActionButtons={ |
| | | <> |
| | | <BulkStartButton /> |
| | | </> |
| | | } |
| | | bulkActionButtons={false} |
| | | rowClick={(id, resource, record) => false} |
| | | expand={false} |
| | | expandSingle={false} |
| | |
| | | <DateField source="createTime" label="common.field.createTime" showTime /> |
| | | <TextField source="memo" label="common.field.memo" sortable={false} /> |
| | | <TextField source="exceStatus$" label="table.field.waveItem.exceStatus" /> |
| | | <WrapperField cellClassName="opt" label="common.field.opt"> |
| | | <PauseButton /> |
| | | <ContinueButton /> |
| | | </WrapperField> |
| | | </StyledDatagrid> |
| | | </List> |
| | | <WaveItemEdit |
| | |
| | | event.stopPropagation() |
| | | setEditDialog(true) |
| | | } |
| | | |
| | | return ( |
| | | <Button label="ra.action.edit" onClick={editClick} startIcon={<ContentCreate />} /> |
| | | ) |
| | | } |
| | | |
| | | |
| | | const BulkStartButton = () => { |
| | | const { data, selectedIds, onUnselectItems } = useListContext(); |
| | | const waveId = useGetRecordId(); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh() |
| | | const startClick = async () => { |
| | | onUnselectItems(); |
| | | const { data: { code, data, msg } } = await request.post('/wave/selects/task', { wave: waveId, waveItem: selectedIds }); |
| | | if (code === 200) { |
| | | notify(msg); |
| | | setAutoExce(false) |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | refresh() |
| | | } |
| | | return ( |
| | | <Button label="toolbar.publicWorking" onClick={startClick} startIcon={<PlayArrowOutlinedIcon />} variant="outlined" /> |
| | | ) |
| | | } |
| | | |
| | | const PauseButton = () => { |
| | | const notify = useNotify() |
| | | const refresh = useRefresh(); |
| | | const record = useRecordContext(); |
| | | const pauseClick = async () => { |
| | | const { data: { code, data, msg } } = await request.post('/waveItem/pause/pub/' + record?.id); |
| | | if (code === 200) { |
| | | notify(msg); |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | refresh() |
| | | } |
| | | return ( |
| | | record?.exceStatus == 1 ? <Button label="toolbar.pause" onClick={pauseClick} startIcon={<StopCircleOutlinedIcon />} /> : <></> |
| | | ) |
| | | } |
| | | |
| | | const ContinueButton = () => { |
| | | const notify = useNotify() |
| | | const refresh = useRefresh(); |
| | | const record = useRecordContext(); |
| | | const continueClick = async () => { |
| | | const { data: { code, data, msg } } = await request.post('/waveItem/continue/pub/' + record?.id); |
| | | if (code === 200) { |
| | | notify(msg); |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | refresh() |
| | | } |
| | | return ( |
| | | record?.exceStatus == 2 ? <Button label="toolbar.continuePub" onClick={continueClick} startIcon={<PauseCircleOutlineIcon />} /> : <></> |
| | | ) |
| | | } |
| | |
| | | import PlayArrowOutlinedIcon from '@mui/icons-material/PlayArrowOutlined'; |
| | | import PauseCircleOutlineIcon from '@mui/icons-material/PauseCircleOutline'; |
| | | import StopCircleOutlinedIcon from '@mui/icons-material/StopCircleOutlined'; |
| | | import StopOutlinedIcon from '@mui/icons-material/StopOutlined'; |
| | | import { Box, Typography, Card, Stack, LinearProgress } from '@mui/material'; |
| | | import ConfirmButton from "../../components/ConfirmButton"; |
| | | import PageDrawer from "../../components/PageDrawer"; |
| | |
| | | return ( |
| | | <Box display="flex"> |
| | | <List |
| | | queryOptions={{ refetchInterval: 5000 }} |
| | | sx={{ |
| | | flexGrow: 1, |
| | | "& .css-k008qs": { |
| | | display: 'block' |
| | | }, |
| | | transition: (theme) => |
| | | theme.transitions.create(['all'], { |
| | | duration: theme.transitions.duration.enteringScreen, |
| | |
| | | rowClick={(id, resource, record) => false} |
| | | expand={<WavePannel />} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'memo', 'createBy$']} |
| | | omit={['id', 'createTime', 'createBy', 'createBy$']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="code" label="table.field.wave.code" /> |
| | |
| | | <CustomProcess source="progress" /> |
| | | <TextField source="exceStatus$" label="table.field.wave.exceStatus" sortable={false} /> |
| | | <WrapperField cellClassName="opt" label="common.field.opt"> |
| | | <PublicTaskButton setSelectIds={setSelectIds} setDetailDialog={setDetailDialog} /> |
| | | <PauseButton /> |
| | | <ContinueButton /> |
| | | <StopWaveButton /> |
| | | <EditButton label="toolbar.detail" sx={{ padding: '1px', fontSize: '.75rem' }} /> |
| | | </WrapperField> |
| | | </StyledDatagrid> |
| | |
| | | <> |
| | | <LinearProgress variant="determinate" value={progress} /> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | |
| | | const StopWaveButton = () => { |
| | | const record = useRecordContext() |
| | | const translate = useTranslate() |
| | | const refresh = useRefresh() |
| | | const notify = useNotify() |
| | | |
| | | const stopClick = async (event) => { |
| | | event.stopPropagation() |
| | | const { data: { code, data, msg } } = await request.post('', { val: true, flag: 'WaveAutoExce' }); |
| | | if (code === 200) { |
| | | notify(msg); |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <ConfirmButton label={"toolbar.stopPub"} startIcon={<StopOutlinedIcon />} onConfirm={stopClick} size='small' /> |
| | | ) |
| | | } |
| | | |
| | |
| | | notify(msg); |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | } |
| | | refresh() |
| | | } |
| | | return ( |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material'; |
| | | import { |
| | | useTranslate, |
| | | List, |
| | | DatagridConfigurable, |
| | | useRecordContext, |
| | | useTranslate, |
| | | TextField, |
| | | NumberField, |
| | | DateField, |
| | | BooleanField, |
| | | ReferenceField, |
| | | useListContext, |
| | | ListContextProvider, |
| | | useList, |
| | | useGetList, |
| | | } from 'react-admin'; |
| | | import PanelTypography from "../../components/PanelTypography"; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import * as Common from '@/utils/common' |
| | | import { styled } from '@mui/material/styles'; |
| | | import { width } from "@mui/system"; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .column-name': { |
| | | }, |
| | | '& .opt': { |
| | | width: 200 |
| | | }, |
| | | })); |
| | | |
| | | const WavePanel = () => { |
| | | const record = useRecordContext(); |
| | | if (!record) return null; |
| | | const translate = useTranslate(); |
| | | const [createDialog, setCreateDialog] = useState(false); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | |
| | | const { data, total, isPending, error, refetch, meta } = useGetList('/waveOrderRela', { filter: { waveId: record?.id } }); |
| | | const listContext = useList({ data, isPending }); |
| | | |
| | | if (data == null || data == undefined) { |
| | | return |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}> |
| | | <CardContent> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}> |
| | | <Typography variant="h6" gutterBottom align="left" sx={{ |
| | | maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' }, |
| | | whiteSpace: 'nowrap', |
| | | overflow: 'hidden', |
| | | textOverflow: 'ellipsis', |
| | | }}> |
| | | {Common.camelToPascalWithSpaces(translate('table.field.wave.id'))}: {record.id} |
| | | </Typography> |
| | | {/* inherit, primary, secondary, textPrimary, textSecondary, error */} |
| | | <Typography variant="h6" gutterBottom align="right" > |
| | | ID: {record.id} |
| | | </Typography> |
| | | </Grid> |
| | | </Grid> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={12} container alignContent="flex-end"> |
| | | <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}> |
| | | {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo} |
| | | </Typography> |
| | | </Grid> |
| | | </Grid> |
| | | <Box height={20}> </Box> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.code" |
| | | property={record.code} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.type" |
| | | property={record.type$} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.exceStatus" |
| | | property={record.exceStatus$} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.anfme" |
| | | property={record.anfme} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.qty" |
| | | property={record.qty} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.orderNum" |
| | | property={record.orderNum} |
| | | /> |
| | | </Grid> |
| | | |
| | | </Grid> |
| | | </CardContent> |
| | | </Card > |
| | | <Box display="flex"> |
| | | <ListContextProvider |
| | | value={listContext} |
| | | sx={{ |
| | | flexGrow: 1, |
| | | transition: (theme) => |
| | | theme.transitions.create(['all'], { |
| | | duration: theme.transitions.duration.enteringScreen, |
| | | }), |
| | | marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0, |
| | | }} |
| | | pagination={false} |
| | | empty={false} |
| | | actions={false} |
| | | > |
| | | <StyledDatagrid |
| | | preferenceKey='waveOrderRela' |
| | | bulkActionButtons={false} |
| | | rowClick={false} |
| | | expandSingle |
| | | omit={['id', 'createTime', 'createBy', 'memo', 'taskId', 'orderId', 'orderItemId', 'matnrId']} |
| | | > |
| | | <NumberField source="id" />, |
| | | <TextField source="asnCode" label="table.field.asnOrderItem.asnCode" /> |
| | | <TextField source="matnrCode" label="table.field.asnOrderItem.matnrCode" /> |
| | | <TextField source="maktx" label="table.field.asnOrderItem.maktx" /> |
| | | <TextField source="splrBatch" label="table.field.asnOrderItem.splrBatch" /> |
| | | <TextField source="platOrderCode" label="table.field.asnOrderItem.platOrderCode" /> |
| | | <TextField source="spec" label="table.field.asnOrderItem.spec" /> |
| | | <TextField source="model" label="table.field.asnOrderItem.model" /> |
| | | <NumberField source="anfme" label="table.field.asnOrderItem.anfme" /> |
| | | <TextField source="stockUnit" label="table.field.asnOrderItem.stockUnit" /> |
| | | <TextField source="splrName" label="table.field.asnOrderItem.splrName" /> |
| | | </StyledDatagrid> |
| | | </ListContextProvider> |
| | | </Box> |
| | | </> |
| | | ); |
| | | }; |
| | |
| | | "sys_menu", |
| | | "man_loc_type_rela", |
| | | "man_qly_inspect_result", |
| | | "view_stock_manage" |
| | | "view_stock_manage", |
| | | "man_wave_order_rela" |
| | | ).contains(tableName); |
| | | } |
| | | }; |
| | |
| | | } |
| | | |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveItem:update')") |
| | | @ApiOperation("终止下发任务") |
| | | @PostMapping("/wave/stop/pub/{id}") |
| | | public R stopPublicTask(@PathVariable Long id) { |
| | | if (Objects.isNull(id)) { |
| | | return R.error("参数不能为空!!"); |
| | | } |
| | | Wave wave = waveService.getById(id); |
| | | if (Objects.isNull(wave)) { |
| | | throw new CoolException("波次单不存在!!"); |
| | | } |
| | | waveService.update(new LambdaUpdateWrapper<Wave>() |
| | | .eq(Wave::getId, id) |
| | | .set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_TASK.val)); |
| | | return R.ok(); |
| | | } |
| | | |
| | | } |
| | |
| | | package com.vincent.rsf.server.manager.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.vincent.rsf.framework.common.Cools; |
| | | import com.vincent.rsf.framework.common.R; |
| | |
| | | @Autowired |
| | | private WaveOrderRelaService waveOrderRelaService; |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveOrderRela:list')") |
| | | @PreAuthorize("hasAuthority('manager:waveItem:list')") |
| | | @PostMapping("/waveOrderRela/page") |
| | | public R page(@RequestBody Map<String, Object> map) { |
| | | BaseParam baseParam = buildParam(map, BaseParam.class); |
| | | PageParam<WaveOrderRela, BaseParam> pageParam = new PageParam<>(baseParam, WaveOrderRela.class); |
| | | return R.ok().add(waveOrderRelaService.page(pageParam, pageParam.buildWrapper(true))); |
| | | Map<String, Object> param = new HashMap<>(); |
| | | BaseParam baseParam = buildParam(param, BaseParam.class); |
| | | return waveOrderRelaService.relaPage(baseParam, map); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveOrderRela:list')") |
| | |
| | | @OperationLog("Create 波次策略") |
| | | @PostMapping("/waveOrderRela/save") |
| | | public R save(@RequestBody WaveOrderRela waveOrderRela) { |
| | | waveOrderRela.setCreateBy(getLoginUserId()); |
| | | waveOrderRela.setCreateTime(new Date()); |
| | | waveOrderRela.setUpdateBy(getLoginUserId()); |
| | | waveOrderRela.setUpdateTime(new Date()); |
| | | if (!waveOrderRelaService.save(waveOrderRela)) { |
| | | return R.error("Save Fail"); |
| | | } |
| | |
| | | @OperationLog("Update 波次策略") |
| | | @PostMapping("/waveOrderRela/update") |
| | | public R update(@RequestBody WaveOrderRela waveOrderRela) { |
| | | waveOrderRela.setUpdateBy(getLoginUserId()); |
| | | waveOrderRela.setUpdateTime(new Date()); |
| | | if (!waveOrderRelaService.updateById(waveOrderRela)) { |
| | | return R.error("Update Fail"); |
| | | } |
| | |
| | | import com.vincent.rsf.framework.common.SpringUtils; |
| | | import com.vincent.rsf.server.system.service.UserService; |
| | | import com.vincent.rsf.server.system.entity.User; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | @Data |
| | | @Accessors(chain = true) |
| | | @TableName("man_wave_order_rela") |
| | | public class WaveOrderRela implements Serializable { |
| | | |
| | |
| | | // null, // 订单明细ID |
| | | // null // 备注 |
| | | // ); |
| | | |
| | | |
| | | |
| | | public Boolean getStatusBool(){ |
| | | if (null == this.status){ return null; } |
| | | switch (this.status){ |
| | | case 1: |
| | | return true; |
| | | case 0: |
| | | return false; |
| | | default: |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | package com.vincent.rsf.server.manager.service; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.vincent.rsf.framework.common.R; |
| | | import com.vincent.rsf.server.common.domain.BaseParam; |
| | | import com.vincent.rsf.server.common.domain.PageParam; |
| | | import com.vincent.rsf.server.manager.entity.WaveOrderRela; |
| | | |
| | | import java.util.Map; |
| | | |
| | | public interface WaveOrderRelaService extends IService<WaveOrderRela> { |
| | | |
| | | R relaPage(BaseParam map, Map<String, Object> params); |
| | | } |
| | |
| | | private DeviceSiteService deviceSiteService; |
| | | @Autowired |
| | | private LocService locService; |
| | | @Autowired |
| | | private WaveOrderRelaServiceImpl waveOrderRelaService; |
| | | |
| | | |
| | | /** |
| | |
| | | if (orderItems.isEmpty()) { |
| | | throw new CoolException("单据不存在!!"); |
| | | } |
| | | |
| | | //合并物料,生成波次明细 |
| | | List<WaveItem> waveItems = mergeWave(orderItems, wave); |
| | | |
| | | if (!waveItemService.saveBatch(waveItems)) { |
| | | throw new CoolException("波次明细保存失败!!"); |
| | | } |
| | |
| | | for (int i = 0; i < orderItems.size(); i++) { |
| | | orderItems.get(i).setWorkQty(orderItems.get(i).getAnfme()); |
| | | } |
| | | |
| | | /** |
| | | *订单信息存储至逻辑关联表 |
| | | */ |
| | | for (WaveItem item : waveItems) { |
| | | List<AsnOrderItem> items = orderItems.stream() |
| | | .filter(orderItem -> item.getMatnrId() |
| | | .equals(orderItem.getMatnrId())) |
| | | .collect(Collectors.toList()); |
| | | |
| | | items.forEach(orderItem -> { |
| | | WaveOrderRela orderRela = new WaveOrderRela(); |
| | | orderRela.setId(null) |
| | | .setOrderId(orderItem.getAsnId()) |
| | | .setOrderItemId(orderItem.getId()) |
| | | .setWaveId(wave.getId()) |
| | | .setWaveItemId(item.getId()); |
| | | if (!waveOrderRelaService.saveOrUpdate(orderRela)) { |
| | | throw new CoolException("<UNK>"); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | | if (!asnOrderItemService.saveOrUpdateBatch(orderItems)) { |
| | | throw new CoolException("出库单执行数量修改失败!!"); |
| | | } |
| | |
| | | package com.vincent.rsf.server.manager.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.vincent.rsf.framework.common.R; |
| | | import com.vincent.rsf.server.common.domain.BaseParam; |
| | | import com.vincent.rsf.server.common.domain.PageParam; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrderItem; |
| | | import com.vincent.rsf.server.manager.mapper.WaveOrderRelaMapper; |
| | | import com.vincent.rsf.server.manager.entity.WaveOrderRela; |
| | | import com.vincent.rsf.server.manager.service.AsnOrderItemService; |
| | | import com.vincent.rsf.server.manager.service.WaveOrderRelaService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service("waveOrderRelaService") |
| | | public class WaveOrderRelaServiceImpl extends ServiceImpl<WaveOrderRelaMapper, WaveOrderRela> implements WaveOrderRelaService { |
| | | |
| | | @Autowired |
| | | private AsnOrderItemService asnOrderItemService; |
| | | |
| | | |
| | | @Override |
| | | public R relaPage(BaseParam baseParam, Map<String, Object> params) { |
| | | List<WaveOrderRela> orderRelas = this.baseMapper.selectList(new LambdaQueryWrapper<WaveOrderRela>() |
| | | .eq(WaveOrderRela::getWaveId, Long.parseLong(params.get("waveId").toString()))); |
| | | if (orderRelas.isEmpty()) { |
| | | return R.ok(); |
| | | } |
| | | List<Long> orderIds = orderRelas.stream().map(WaveOrderRela::getOrderItemId).collect(Collectors.toList()); |
| | | PageParam<AsnOrderItem, BaseParam> pageParam = new PageParam<>(baseParam, AsnOrderItem.class); |
| | | QueryWrapper<AsnOrderItem> wrapper = pageParam.buildWrapper(true); |
| | | wrapper.in("id", orderIds); |
| | | return R.ok().add(asnOrderItemService.page(pageParam, wrapper)); |
| | | } |
| | | } |
| | |
| | | } else { |
| | | wave.setExceStatus(WaveExceStatus.WAVE_EXCE_STATUS_EXCING.val); |
| | | } |
| | | wave.setMemo("-->库存不足"); |
| | | waveService.updateById(wave); |
| | | return R.ok(); |
| | | } |