skyouc
4 天以前 d727cdfbd0315850f3c7572149e77f5421db5682
生成波次功能优化
10个文件已修改
1个文件已添加
198 ■■■■■ 已修改文件
rsf-admin/src/i18n/en.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderList.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutStockWaveDialog.jsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/wave/WaveItemList.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/wave/WaveList.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/common/utils/FieldsUtils.java 73 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveItem.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/AsnOrderLogSchedule.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js
@@ -848,6 +848,7 @@
                matnrName: "matnrName",
                matnrCode: "matnrCode",
                batch: "batch",
                exceStatus: 'Exce Status',
                splrBatch: "splrBatch",
                orderCode: "orderCode",
                orderItemId: "orderItemId",
rsf-admin/src/i18n/zh.js
@@ -882,6 +882,7 @@
                orderCode: "源单号",
                orderItemId: "源单明细ID",
                unit: "单位",
                exceStatus: '执行状态',
                trackCode: "跟踪码",
                fieldsIndex: "动态扩展",
                anfme: "数量",
@@ -1141,7 +1142,7 @@
        continue: '继续收货',
        batch: '批量操作',
        confirm: '确认',
        start: '开始下发',
        start: '自动下发',
        pause: '暂停',
        pick: '拣料',
        check: '盘点',
rsf-admin/src/page/orders/outStock/OutOrderList.jsx
@@ -130,16 +130,13 @@
  //获取波次规则
  const closeDialog = async (value) => {
    setWaveRule(false)
    refresh()
    console.log('=====>');
    console.log(value);
    console.log(selectIds);
    const res = await request.post(`/outStock/generate/wave`, { ids: selectIds, waveRuleId: value.id });
    if (res?.data?.code === 200) {
      notify(res.data.msg);
    } else {
      notify(res.data.msg);
    }
    refresh()
  }
  return (
rsf-admin/src/page/orders/outStock/OutStockWaveDialog.jsx
New file
@@ -0,0 +1,65 @@
import { Box, Card, Grid, List, LinearProgress, Select, MenuItem, ListItemText, ListItemAvatar, Avatar, ListItemButton, Dialog, DialogTitle, ListItem, DialogContent, DialogActions, Button } from "@mui/material";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE, DEFAULT_TYPE } from '@/config/setting';
import { SimpleForm, TextInput, ReferenceInput, useTranslate, AutocompleteInput } from "react-admin";
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Delete, Edit, Add } from '@mui/icons-material';
import SaveIcon from '@mui/icons-material/Save';
import request from '@/utils/request';
const OutStockWaveDialog = (props) => {
    const translate = useTranslate();
    const { onClose, selectedValue, open, setOpen } = props;
    const [siteNos, setSiteNos] = useState([]);
    const [formData, setFormData] = useState({
        id: DEFAULT_TYPE
    });
    const handleClose = () => {
        onClose(null);
    }
    const handleSelect = () => {
        onClose(formData);
    }
    const handleListItemClick = (value) => {
        onClose(value);
    }
    const handleChange = (event) => {
        console.log(event);
        setFormData({ id: event })
    };
    return (
        <Dialog
            onClose={handleClose}
            open={open}
            aria-labelledby="alert-dialog-title"
            aria-describedby="alert-dialog-description"
        >
            <DialogTitle id="alert-dialog-title">{translate("toolbar.selectWave")}</DialogTitle>
            <DialogContent sx={{ width: 600 }}>
                <SimpleForm toolbar={false} defaultValue={formData}>
                    <ReferenceInput source="id" reference="waveRule" >
                        <AutocompleteInput
                            label={'toolbar.selectWave'}
                            defaultValue={DEFAULT_TYPE}
                            onChange={handleChange}
                        />
                    </ReferenceInput>
                </SimpleForm>
            </DialogContent>
            <DialogActions>
                <Button onClick={handleClose} variant="outlined">{translate('toolbar.cancel')}</Button>
                <Button onClick={handleSelect} autoFocus startIcon={<SaveIcon />} variant="contained">
                    {translate('toolbar.confirm')}
                </Button>
            </DialogActions>
        </Dialog>
    );
}
export default OutStockWaveDialog;
rsf-admin/src/page/orders/wave/WaveItemList.jsx
@@ -123,7 +123,7 @@
            >
                <StyledDatagrid
                    preferenceKey='waveItem'
                    bulkActionButtons= {
                    bulkActionButtons={
                        <>
                            <BulkStartButton />
                            <BulkPauseButton />
@@ -146,6 +146,7 @@
                    <TextField source="fieldsIndex" label="table.field.waveItem.fieldsIndex" />
                    <NumberField source="workQty" label="table.field.waveItem.workQty" />
                    <TextField source="unit" label="table.field.waveItem.unit" />
                    <TextField source="exceStatus" label="table.field.waveItem.exceStatus" />
                    <TextField source="updateBy$" label="common.field.updateBy" />
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <TextField source="createBy$" label="common.field.createBy" />
rsf-admin/src/page/orders/wave/WaveList.jsx
@@ -89,6 +89,7 @@
const WaveList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [autoExce, setAutoExce] = useState(false);
    const [detailDialog, setDetailDialog] = useState(false);
    const [select, setSelectIds] = useState({});
    const [drawerVal, setDrawerVal] = useState(false);
@@ -110,8 +111,8 @@
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <BulkStartButton />
                        <BulkPauseButton />
                        <BulkStartButton autoExce={autoExce} setAutoExce={setAutoExce} />
                        <BulkPauseButton autoExce={autoExce} setAutoExce={setAutoExce} />
                        <FilterButton />
                        <SelectColumnsButton preferenceKey='wave' />
                    </TopToolbar>
@@ -182,24 +183,26 @@
    );
}
const BulkStartButton = () => {
const BulkStartButton = ({ autoExce, setAutoExce }) => {
    const { data, selectedIds, onUnselectItems } = useListContext();
    const startClick = () => {
        onUnselectItems()
        setAutoExce(true)
    }
    return (
        <Button label="toolbar.start" onClick={startClick} startIcon={<PlayArrowOutlinedIcon />}  />
        !autoExce ? <Button label="toolbar.start" onClick={startClick} startIcon={<PlayArrowOutlinedIcon />} /> : <></>
    )
}
const BulkPauseButton = () => {
const BulkPauseButton = ({ autoExce, setAutoExce }) => {
    const { data, selectedIds, onUnselectItems } = useListContext();
    const pauseClick = () => {
        onUnselectItems()
        setAutoExce(false)
    }
    return (
        <Button label="toolbar.pause" onClick={pauseClick} startIcon={<PauseCircleOutlineIcon />}  />
        autoExce ? <Button label="toolbar.pause" onClick={pauseClick} startIcon={<PauseCircleOutlineIcon />} /> : <></>
    )
}
rsf-server/src/main/java/com/vincent/rsf/server/common/utils/FieldsUtils.java
@@ -30,10 +30,10 @@
public class FieldsUtils {
    /**
     * @author Ryan
     * @description 通过字段唯一标识获取动态字段对象key-value
     * @param
     * @return 扩展字段对象
     * @author Ryan
     * @description 通过字段唯一标识获取动态字段对象key-value
     * @time 2025/3/12 12:50
     */
    public static Map<String, String> getFields(String uuid) {
@@ -45,7 +45,7 @@
        }
        FieldsItemService fieldsItemService = SpringUtils.getBean(FieldsItemService.class);
        List<FieldsItem> fieldsItems = fieldsItemService.list(new LambdaQueryWrapper<FieldsItem>().eq(FieldsItem::getUuid, uuid));
        for (Fields field : fields ) {
        for (Fields field : fields) {
            if (fieldsItems.isEmpty()) {
                fieldsMap.put(field.getFields(), null);
                continue;
@@ -57,14 +57,14 @@
            });
        }
        return  fieldsMap;
        return fieldsMap;
    }
    /**
     * @param
     * @return 包含扩展字段的集合对象
     * @author Ryan
     * @description 获取集合扩展字段key-value值
     * @param
     * @return  包含扩展字段的集合对象
     * @time 2025/3/15 15:05
     */
    public static List<Map<String, Object>> getExtendFields(List<Map<String, Object>> params) {
@@ -104,7 +104,7 @@
     * @time 2025/3/18 15:00
     */
    @Transactional(rollbackFor = Exception.class)
    public static boolean saveFields(Map<String, ?> template, String uuid) throws Exception{
    public static boolean saveFields(Map<String, ?> template, String uuid) throws Exception {
        List<Fields> fields = getFieldsSta();
        FieldsItemService fieldsItemService = SpringUtils.getBean(FieldsItemService.class);
        List<FieldsItem> fieldsItems = new ArrayList<>();
@@ -132,6 +132,7 @@
    /**
     * 获取所有开启动态扩展字段
     *
     * @return
     */
    public static List<Fields> getFieldsSta() {
@@ -140,43 +141,45 @@
    }
    /**
     * @author Ryan
     * @description 动态字段修改
     * @param
     * @return
     * @author Ryan
     * @description 动态字段修改
     * @time 2025/4/7 15:28
     */
    @Synchronized
    @Transactional(rollbackFor = Exception.class)
    public static void updateFieldsValue(Map<String, Object> params) throws Exception {
        List<Fields> fields = getFieldsSta();
        if (fields.isEmpty()) { return; }
        if (fields.isEmpty()) {
            return;
        }
        Object fieldsIndex = params.get("fieldsIndex");
        if (!Objects.isNull(fieldsIndex) && StringUtils.isNotBlank(fieldsIndex.toString())) {
            String index = fieldsIndex.toString();
            FieldsItemService fieldsItemService = SpringUtils.getBean(FieldsItemService.class);
            for (Fields field : fields) {
                    if (!Objects.isNull(params.get(field.getFields()))) {
                        FieldsItem indexItem = fieldsItemService.getOne(new LambdaQueryWrapper<FieldsItem>()
                                .eq(FieldsItem::getUuid, index)
                                .eq(FieldsItem::getFieldsId, field.getId()));
                        //如果子表为空,执行插入操作,否则就执行修改操作
                        if (Objects.isNull(indexItem)) {
                            FieldsItem item = new FieldsItem();
                            item.setUuid(index)
                                    .setFieldsId(field.getId())
                                    .setMatnrId(!Objects.isNull(params.get("matnrId")) ? Long.parseLong(params.get("matnrId").toString()) : null)
                                    .setValue(params.get(field.getFields()).toString());
                            if (!fieldsItemService.save(item)) {
                                throw new CoolException("扩展字段修改失败!!");
                            }
                        } else {
                            indexItem.setValue(params.get(field.getFields()).toString());
                            if (!fieldsItemService.updateById(indexItem)) {
                                throw new CoolException("扩展字段修改失败!!");
                            }
                if (!Objects.isNull(params.get(field.getFields()))) {
                    FieldsItem indexItem = fieldsItemService.getOne(new LambdaQueryWrapper<FieldsItem>()
                            .eq(FieldsItem::getUuid, index)
                            .eq(FieldsItem::getFieldsId, field.getId()));
                    //如果子表为空,执行插入操作,否则就执行修改操作
                    if (Objects.isNull(indexItem)) {
                        FieldsItem item = new FieldsItem();
                        item.setUuid(index)
                                .setFieldsId(field.getId())
                                .setMatnrId(!Objects.isNull(params.get("matnrId")) ? Long.parseLong(params.get("matnrId").toString()) : null)
                                .setValue(params.get(field.getFields()).toString());
                        if (!fieldsItemService.save(item)) {
                            throw new CoolException("扩展字段修改失败!!");
                        }
                    } else {
                        indexItem.setValue(params.get(field.getFields()).toString());
                        if (!fieldsItemService.updateById(indexItem)) {
                            throw new CoolException("扩展字段修改失败!!");
                        }
                    }
                }
            }
        } else {
            saveFields(params, params.get("index").toString());
@@ -196,12 +199,12 @@
            Fields fields = fieldsService.getOne(new LambdaQueryWrapper<Fields>().eq(Fields::getFields, key));
            if (!Cools.isEmpty(fields)) {
                String applySql = String.format(
                    "EXISTS (SELECT 1 FROM sys_fields_item fie " +
                    "WHERE %s.fields_index IS NOT NULL " +
                    "AND fie.uuid = %s.fields_index " +
                    "AND fie.fields_id = '%s' " +
                    "AND fie.value = '%s')",
                    tableName, tableName, fields.getId(), val
                        "EXISTS (SELECT 1 FROM sys_fields_item fie " +
                                "WHERE %s.fields_index IS NOT NULL " +
                                "AND fie.uuid = %s.fields_index " +
                                "AND fie.fields_id = '%s' " +
                                "AND fie.value = '%s')",
                        tableName, tableName, fields.getId(), val
                );
                queryWrapper.apply(applySql);
            }
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveItem.java
@@ -139,6 +139,12 @@
    private Integer status;
    /**
     * 执行状态 0:未执行 1:待执行 2:执行中 3:已取消
     */
    @ApiModelProperty("执行状态")
    private Short exceStatus;
    /**
     * 是否删除 1: 是  0: 否  
     */
    @ApiModelProperty(value= "是否删除 1: 是  0: 否  ")
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/AsnOrderLogSchedule.java
@@ -71,12 +71,12 @@
    * @return
    * @time 2025/6/16 08:35
    */
    @Scheduled(cron = "0/30 * * * * ?  ")
//    @Scheduled(cron = "0/30 * * * * ?  ")
    @Transactional(rollbackFor = Exception.class)
    public void outStockComplete() {
        List<AsnOrder> asnOrders = asnOrderService.list(new LambdaQueryWrapper<AsnOrder>()
                        .eq(AsnOrder::getType, OrderType.ORDER_OUT.type)
                .apply("anfme=work_qty")
                .apply("anfme = work_qty")
        );
        if (asnOrders.isEmpty()) {
            return;
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java
@@ -31,6 +31,7 @@
import com.vincent.rsf.server.manager.service.CompanysService;
import com.vincent.rsf.server.manager.service.MatnrService;
import com.vincent.rsf.server.system.constant.SerialRuleCode;
import com.vincent.rsf.server.system.entity.Fields;
import com.vincent.rsf.server.system.service.DictDataService;
import com.vincent.rsf.server.system.service.FieldsItemService;
import com.vincent.rsf.server.system.service.FieldsService;
@@ -243,13 +244,7 @@
        try {
            StringBuffer sb = new StringBuffer();
            if (Objects.isNull(asnOrderItem.getFieldsIndex()) || StringUtils.isBlank(asnOrderItem.getFieldsIndex())) {
                if (!Objects.isNull(asnOrderItem.getExtendFields()) && !asnOrderItem.getExtendFields().isEmpty()) {
                    Map<String, String> fields = asnOrderItem.getExtendFields();
                    asnOrderItem.getExtendFields().keySet().forEach(key -> {
                        sb.append(fields.get(key));
                    });
                }
                sb.append(asnOrderItem.getAsnCode() + asnOrderItem.getMatnrId() + asnOrderItem.getSplrBatch() + asnOrderItem.getIsptResult$());
                sb.append(asnOrderItem.getMatnrId() + asnOrderItem.getSplrBatch() );
                //获取16位uuid
                String uuid16 = Cools.md5Chinese(sb.toString());
                asnOrderItem.setFieldsIndex(uuid16);
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -295,10 +295,13 @@
        if (!waveService.save(wave)) {
            throw new CoolException("波次保存失败!!");
        }
        List<Long> list = orders.stream().map(AsnOrder::getId).collect(Collectors.toList());
        List<AsnOrderItem> orderItems = asnOrderItemService
                .list(new LambdaQueryWrapper<AsnOrderItem>()
                        .in(AsnOrderItem::getAsnId, list));
                        .in(AsnOrderItem::getAsnId, list).apply("anfme > work_qty"));
        if (orderItems.isEmpty()) {
            throw new CoolException("单据不存在!!");
        }
@@ -324,7 +327,7 @@
                    .set(AsnOrder::getWaveId, wave.getId())
                    .set(AsnOrder::getWorkQty, wkQty)
                    .set(AsnOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_WAVE.val)
                    .in(AsnOrder::getId, params.getIds()))) {
                    .eq(AsnOrder::getId, order.getId()))) {
                throw new CoolException("执行状态修改修改失败!!");
            }
        }
@@ -346,15 +349,12 @@
            throw new CoolException("主单信息不能为空");
        }
        AsnOrder orders = params.getOrders();
        if (Objects.isNull(orders)) {
            throw new CoolException("单据不能为空!!");
        }
        if (StringUtils.isBlank(orders.getWkType())) {
            throw new CoolException("业务类型不能为空!!");
        }
        String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_OUT_STOCK_CODE, orders);
        if (Objects.isNull(ruleCode) || StringUtils.isBlank(ruleCode)) {
        if (StringUtils.isBlank(ruleCode)) {
            throw new CoolException("编码规则错误:请检查「SYS_OUT_STOCK_CODE」是否设置正确!!");
        }
        orders.setCode(ruleCode)
@@ -732,7 +732,7 @@
                        p1.getUpdateBy(),
                        p1.getMemo()
                ),
                WaveItem::getSplrBatch, WaveItem::getMatnrId, WaveItem::getFieldsIndex
                WaveItem::getSplrBatch, WaveItem::getMatnrCode, WaveItem::getFieldsIndex
        );
        return waveItems;