7172f29c54a04164674212f4ead303603dff0548..985fb87ddf52860446f58056be4ca49844f57147
2025-07-02 skyouc
终止下发波次优化
985fb8 对比 | 目录
2025-07-02 skyouc
代码优化 波次功能优化
459235 对比 | 目录
2025-07-02 skyouc
终止波次功能优化
a6f417 对比 | 目录
2025-07-02 skyouc
新增播种列表
6974d5 对比 | 目录
7个文件已添加
8个文件已修改
811 ■■■■ 已修改文件
rsf-admin/src/i18n/zh.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/wave/WaveList.jsx 81 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveSowItemController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/TaskItemLog.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveSowItem.java 330 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WaveSowItemMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/PakinSchedules.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveSowItemService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveSowItemServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/WaveSowItemMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js
@@ -866,7 +866,7 @@
            wave: {
                code: "波次号",
                type: "单据类型",
                exceStatus: "状态",
                exceStatus: "执行状态",
                anfme: "数量",
                groupQty: '品类数',
                qty: "完成数量",
rsf-admin/src/page/orders/wave/WaveList.jsx
@@ -1,5 +1,4 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
@@ -23,6 +22,7 @@
    NumberInput,
    useRefresh,
    useRedirect,
    AutocompleteInput,
    Button,
} from 'react-admin';
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_WAVE_AUTO_EXCE } from '@/config/setting';
@@ -54,39 +54,7 @@
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="code" label="table.field.wave.code" />,
    <SelectInput source="type" label="table.field.wave.type"
        choices={[
            { id: 0, name: '手动' },
            { id: 1, name: '自动' },
        ]}
    />,
    <SelectInput source="exceStatus" label="table.field.wave.exceStatus"
        choices={[
            { id: 0, name: '初始化' },
            { id: 1, name: '生成任务' },
            { id: 2, name: '任务播种' },
            { id: 3, name: '完成' },
        ]}
    />,
    <NumberInput source="anfme" label="table.field.wave.anfme" />,
    <NumberInput source="qty" label="table.field.wave.qty" />,
    <NumberInput source="orderNum" label="table.field.wave.orderNum" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const WaveList = () => {
    const translate = useTranslate();
@@ -95,6 +63,44 @@
    const [detailDialog, setDetailDialog] = useState(false);
    const [select, setSelectIds] = useState({});
    const [drawerVal, setDrawerVal] = useState(false);
    const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_wave_exce_status')) || [];
    const filters = [
        <SearchInput source="condition" alwaysOn />,
        <DateInput label='common.time.after' source="timeStart" alwaysOn />,
        <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
        <TextInput source="code" label="table.field.wave.code" />,
        <AutocompleteInput
            choices={dicts}
            optionText="label"
            label="table.field.wave.exceStatus"
            source="exceStatus"
            format={value => value || '0'}
            optionValue="value"
            parse={v => v}
            alwaysOn
        />,
        <SelectInput source="type" label="table.field.wave.type"
            choices={[
                { id: 0, name: '手动' },
                { id: 1, name: '自动' },
            ]}
        />,
        <NumberInput source="anfme" label="table.field.wave.anfme" />,
        <NumberInput source="qty" label="table.field.wave.qty" />,
        <NumberInput source="orderNum" label="table.field.wave.orderNum" />,
        <TextInput label="common.field.memo" source="memo" />,
        <SelectInput
            label="common.field.status"
            source="status"
            choices={[
                { id: '1', name: 'common.enums.statusTrue' },
                { id: '0', name: 'common.enums.statusFalse' },
            ]}
            resettable
        />,
    ]
    useEffect(() => {
        getConfig()
@@ -227,9 +233,8 @@
    const refresh = useRefresh()
    const notify = useNotify()
    const stopClick = async (event) => {
        event.stopPropagation()
        const { data: { code, data, msg } } = await request.post('', { val: true, flag: 'WaveAutoExce' });
    const stopClick = async () => {
        const { data: { code, data, msg } } = await request.post('/wave/stop/pub/' + record?.id);
        if (code === 200) {
            notify(msg);
        } else {
@@ -238,7 +243,7 @@
    }
    return (
        <ConfirmButton label={"toolbar.stopPub"} startIcon={<StopOutlinedIcon />} onConfirm={stopClick} size='small' />
        record?.exceStatus != 3 ? <ConfirmButton label={"toolbar.stopPub"} startIcon={<StopOutlinedIcon />} onConfirm={stopClick} size='small' /> : <></>
    )
}
rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java
@@ -22,7 +22,7 @@
//        generator.username="sa";
//        generator.password="Zoneyung@zy56$";
        generator.table = "man_wave_order_rela";
        generator.table = "man_wave_sow_item";
        generator.tableDesc = "波次策略";
        generator.packagePath = "com.vincent.rsf.server.manager";
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java
@@ -14,12 +14,17 @@
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.manager.entity.TaskItem;
import com.vincent.rsf.server.manager.entity.TaskItemLog;
import com.vincent.rsf.server.manager.entity.Wave;
import com.vincent.rsf.server.manager.entity.WaveItem;
import com.vincent.rsf.server.manager.enums.WaveExceStatus;
import com.vincent.rsf.server.manager.enums.WaveItemExceStatus;
import com.vincent.rsf.server.manager.service.OutStockService;
import com.vincent.rsf.server.manager.service.TaskItemLogService;
import com.vincent.rsf.server.manager.service.TaskItemService;
import com.vincent.rsf.server.manager.service.WaveService;
import com.vincent.rsf.server.manager.service.impl.TaskItemLogServiceImpl;
import com.vincent.rsf.server.manager.service.impl.WaveItemServiceImpl;
import com.vincent.rsf.server.system.controller.BaseController;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
@@ -37,6 +42,12 @@
    private WaveService waveService;
    @Autowired
    private TaskItemService taskItemService;
    @Autowired
    private OutStockService outStockService;
    @Autowired
    private TaskItemLogService taskItemLogService;
    @Autowired
    private WaveItemServiceImpl waveItemService;
    @PreAuthorize("hasAuthority('manager:wave:list')")
    @PostMapping("/wave/page")
@@ -185,14 +196,11 @@
        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();
                .set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_PAUSE.val));
        return waveService.stopPubTask(id);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveSowItemController.java
New file
@@ -0,0 +1,110 @@
package com.vincent.rsf.server.manager.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.manager.entity.WaveSowItem;
import com.vincent.rsf.server.manager.service.WaveSowItemService;
import com.vincent.rsf.server.system.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@RestController
public class WaveSowItemController extends BaseController {
    @Autowired
    private WaveSowItemService waveSowItemService;
    @PreAuthorize("hasAuthority('manager:waveSowItem:list')")
    @PostMapping("/waveSowItem/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<WaveSowItem, BaseParam> pageParam = new PageParam<>(baseParam, WaveSowItem.class);
        return R.ok().add(waveSowItemService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('manager:waveSowItem:list')")
    @PostMapping("/waveSowItem/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(waveSowItemService.list());
    }
    @PreAuthorize("hasAuthority('manager:waveSowItem:list')")
    @PostMapping({"/waveSowItem/many/{ids}", "/waveSowItems/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(waveSowItemService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('manager:waveSowItem:list')")
    @GetMapping("/waveSowItem/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(waveSowItemService.getById(id));
    }
    @PreAuthorize("hasAuthority('manager:waveSowItem:save')")
    @OperationLog("Create 波次策略")
    @PostMapping("/waveSowItem/save")
    public R save(@RequestBody WaveSowItem waveSowItem) {
        waveSowItem.setCreateBy(getLoginUserId());
        waveSowItem.setCreateTime(new Date());
        waveSowItem.setUpdateBy(getLoginUserId());
        waveSowItem.setUpdateTime(new Date());
        if (!waveSowItemService.save(waveSowItem)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(waveSowItem);
    }
    @PreAuthorize("hasAuthority('manager:waveSowItem:update')")
    @OperationLog("Update 波次策略")
    @PostMapping("/waveSowItem/update")
    public R update(@RequestBody WaveSowItem waveSowItem) {
        waveSowItem.setUpdateBy(getLoginUserId());
        waveSowItem.setUpdateTime(new Date());
        if (!waveSowItemService.updateById(waveSowItem)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(waveSowItem);
    }
    @PreAuthorize("hasAuthority('manager:waveSowItem:remove')")
    @OperationLog("Delete 波次策略")
    @PostMapping("/waveSowItem/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!waveSowItemService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('manager:waveSowItem:list')")
    @PostMapping("/waveSowItem/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<WaveSowItem> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(WaveSowItem::getId, condition);
        }
        waveSowItemService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getId()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('manager:waveSowItem:list')")
    @PostMapping("/waveSowItem/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(waveSowItemService.list(), WaveSowItem.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/TaskItemLog.java
@@ -78,6 +78,15 @@
    @ApiModelProperty("项目号")
    private String projectCode;
    @ApiModelProperty("源编码")
    private Long source;
    @ApiModelProperty("源单号")
    private String sourceCode;
    @ApiModelProperty("源主单ID")
    private Long sourceId;
    /**
     * 物料编码
     */
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveSowItem.java
New file
@@ -0,0 +1,330 @@
package com.vincent.rsf.server.manager.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("man_wave_sow_item")
public class WaveSowItem implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
    @ApiModelProperty(value= "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 波次ID
     */
    @ApiModelProperty(value= "波次ID")
    private Long waveId;
    /**
     * 波次明细ID
     */
    @ApiModelProperty(value= "波次明细ID")
    private Long waveItemId;
    /**
     * 订单ID
     */
    @ApiModelProperty(value= "订单ID")
    private Long orderId;
    /**
     * 订单明细ID
     */
    @ApiModelProperty(value= "订单明细ID")
    private Long orderItemId;
    /**
     * 任务ID
     */
    @ApiModelProperty(value= "任务ID")
    private Long taskId;
    /**
     * 任务明细ID
     */
    @ApiModelProperty(value= "任务明细ID")
    private Long taskItemId;
    /**
     * 平台ID(行号)
     */
    @ApiModelProperty(value= "平台ID(行号)")
    private String platItemId;
    /**
     * 客户订单号
     */
    @ApiModelProperty(value= "客户订单号")
    private String platOrderCode;
    /**
     * 工单号
     */
    @ApiModelProperty(value= "工单号")
    private String platWorkCode;
    /**
     * 项目号
     */
    @ApiModelProperty(value= "项目号")
    private String projectCode;
    /**
     * 物料ID
     */
    @ApiModelProperty(value= "物料ID")
    private Long matnrId;
    /**
     * 物料名称
     */
    @ApiModelProperty(value= "物料名称")
    private String maktx;
    /**
     * 物料编码
     */
    @ApiModelProperty(value= "物料编码")
    private String matnrCode;
    /**
     * 物料跟踪码
     */
    @ApiModelProperty(value= "物料跟踪码")
    private String trackCode;
    /**
     * 库存单位
     */
    @ApiModelProperty(value= "库存单位")
    private String unit;
    /**
     * 数量
     */
    @ApiModelProperty(value= "数量")
    private Double anfme;
    /**
     * 库存批次
     */
    @ApiModelProperty(value= "库存批次")
    private String batch;
    /**
     * 规格
     */
    @ApiModelProperty(value= "规格")
    private String spec;
    /**
     * 型号
     */
    @ApiModelProperty(value= "型号")
    private String model;
    /**
     * 字段索引
     */
    @ApiModelProperty(value= "字段索引")
    private String fieldsIndex;
    /**
     * 状态 1: 正常  0: 冻结
     */
    @ApiModelProperty(value= "状态 1: 正常  0: 冻结  ")
    private Integer status;
    /**
     * 是否删除 1: 是  0: 否
     */
    @ApiModelProperty(value= "是否删除 1: 是  0: 否  ")
    @TableLogic
    private Integer deleted;
    /**
     * 租户
     */
    @ApiModelProperty(value= "租户")
    private Integer tenantId;
    /**
     * 添加人员
     */
    @ApiModelProperty(value= "添加人员")
    private Long createBy;
    /**
     * 添加时间
     */
    @ApiModelProperty(value= "添加时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * 修改人员
     */
    @ApiModelProperty(value= "修改人员")
    private Long updateBy;
    /**
     * 修改时间
     */
    @ApiModelProperty(value= "修改时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    /**
     * 备注
     */
    @ApiModelProperty(value= "备注")
    private String memo;
    public WaveSowItem() {}
    public WaveSowItem(Long waveId,Long waveItemId,Long orderId,Long orderItemId,Long taskId,Long taskItemId,String platItemId,String platOrderCode,String platWorkCode,String projectCode,Long matnrId,String maktx,String matnrCode,String trackCode,String unit,Double anfme,String batch,String spec,String model,String fieldsIndex,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.waveId = waveId;
        this.waveItemId = waveItemId;
        this.orderId = orderId;
        this.orderItemId = orderItemId;
        this.taskId = taskId;
        this.taskItemId = taskItemId;
        this.platItemId = platItemId;
        this.platOrderCode = platOrderCode;
        this.platWorkCode = platWorkCode;
        this.projectCode = projectCode;
        this.matnrId = matnrId;
        this.maktx = maktx;
        this.matnrCode = matnrCode;
        this.trackCode = trackCode;
        this.unit = unit;
        this.anfme = anfme;
        this.batch = batch;
        this.spec = spec;
        this.model = model;
        this.fieldsIndex = fieldsIndex;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
    }
//    WaveSowItem waveSowItem = new WaveSowItem(
//            null,    // 波次ID
//            null,    // 波次明细ID
//            null,    // 订单ID
//            null,    // 订单明细ID
//            null,    // 任务ID
//            null,    // 任务明细ID
//            null,    // 平台ID(行号)
//            null,    // 客户订单号
//            null,    // 工单号
//            null,    // 项目号
//            null,    // 物料ID
//            null,    // 物料名称
//            null,    // 物料编码
//            null,    // 物料跟踪码
//            null,    // 库存单位
//            null,    // 数量
//            null,    // 库存批次
//            null,    // 规格
//            null,    // 型号
//            null,    // 字段索引
//            null,    // 状态[非空]
//            null,    // 是否删除[非空]
//            null,    // 租户
//            null,    // 添加人员
//            null,    // 添加时间[非空]
//            null,    // 修改人员
//            null,    // 修改时间[非空]
//            null    // 备注
//    );
    public String getStatus$(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return "正常";
            case 0:
                return "冻结";
            default:
                return String.valueOf(this.status);
        }
    }
    public String getCreateBy$(){
        UserService service = SpringUtils.getBean(UserService.class);
        User user = service.getById(this.createBy);
        if (!Cools.isEmpty(user)){
            return String.valueOf(user.getNickname());
        }
        return null;
    }
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateBy$(){
        UserService service = SpringUtils.getBean(UserService.class);
        User user = service.getById(this.updateBy);
        if (!Cools.isEmpty(user)){
            return String.valueOf(user.getNickname());
        }
        return null;
    }
    public String getUpdateTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
    public Boolean getStatusBool(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return true;
            case 0:
                return false;
            default:
                return null;
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WaveSowItemMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.mapper;
import com.vincent.rsf.server.manager.entity.WaveSowItem;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface WaveSowItemMapper extends BaseMapper<WaveSowItem> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/PakinSchedules.java
New file
@@ -0,0 +1,94 @@
package com.vincent.rsf.server.manager.schedules;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.manager.entity.WaitPakin;
import com.vincent.rsf.server.manager.entity.WaitPakinItem;
import com.vincent.rsf.server.manager.entity.WaitPakinItemLog;
import com.vincent.rsf.server.manager.entity.WaitPakinLog;
import com.vincent.rsf.server.manager.enums.PakinIOStatus;
import com.vincent.rsf.server.manager.service.WaitPakinItemLogService;
import com.vincent.rsf.server.manager.service.WaitPakinItemService;
import com.vincent.rsf.server.manager.service.WaitPakinLogService;
import com.vincent.rsf.server.manager.service.WaitPakinService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class PakinSchedules {
    @Autowired
    private WaitPakinService waitPakinService;
    @Autowired
    private WaitPakinItemService waitPakinItemService;
    @Autowired
    private WaitPakinLogService waitPakinLogService;
    @Autowired
    private WaitPakinItemLogService waitPakinItemLogService;
    /**
     * @param
     * @return
     * @author Ryan
     * @description 组拖历史档
     * @time 2025/3/29 12:36
     */
    @Scheduled(cron = "0/25 * * * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void pakinLog() {
        List<WaitPakin> pakinIds = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>()
                .eq(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val)
                .select(WaitPakin::getId));
        if (pakinIds.isEmpty()) {
            return;
        }
        List<Long> list = pakinIds.stream().map(WaitPakin::getId).collect(Collectors.toList());
        List<WaitPakin> pakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().in(WaitPakin::getId, list));
        if (pakins.isEmpty()) {
            throw new CoolException("组拖单为空!!");
        }
        pakins.forEach(pakin -> {
            WaitPakinLog log = new WaitPakinLog();
            BeanUtils.copyProperties(pakin, log);
            log.setPakinId(pakin.getId()).setIoStatus(PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val);
            if (!waitPakinLogService.save(log)) {
                throw new CoolException("组托日志保存失败!!");
            }
            List<WaitPakinItem> pakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().in(WaitPakinItem::getPakinId, pakin.getId()));
            if (pakinItems.isEmpty()) {
                throw new CoolException("组拖明细为空!!");
            }
            List<WaitPakinItemLog> itemLogs = new ArrayList<>();
            pakinItems.forEach(item -> {
                WaitPakinItemLog itemLog = new WaitPakinItemLog();
                BeanUtils.copyProperties(item, itemLog);
                itemLog.setPakinItemId(item.getId())
                        .setLogId(log.getId())
                        .setQty(item.getWorkQty())
                        .setWorkQty(0.0)
                        .setPakinId(item.getPakinId());
                itemLogs.add(itemLog);
            });
            if (!waitPakinItemLogService.saveBatch(itemLogs)) {
                throw new CoolException("历史明细档保存失败!!");
            }
        });
        if (!waitPakinService.removeByIds(list)) {
            throw new CoolException("原单据删除失败!!");
        }
        if (!waitPakinItemService.remove(new LambdaQueryWrapper<WaitPakinItem>().in(WaitPakinItem::getPakinId, list))) {
            throw new CoolException("原单据明细删除失败!!");
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java
@@ -58,14 +58,6 @@
    @Resource
    private SysStockProperties flowProperties;
    @Autowired
    private WaitPakinService waitPakinService;
    @Autowired
    private WaitPakinItemService waitPakinItemService;
    @Autowired
    private WaitPakinLogService waitPakinLogService;
    @Autowired
    private WaitPakinItemLogService waitPakinItemLogService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private WarehouseAreasService warehouseAreasService;
@@ -318,64 +310,4 @@
            throw new CoolException("生成编码失败!!");
        }
    }
    /**
     * @param
     * @return
     * @author Ryan
     * @description 组拖历史档
     * @time 2025/3/29 12:36
     */
    @Scheduled(cron = "0/25 * * * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void pakinLog() {
        List<WaitPakin> pakinIds = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>()
                .eq(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val)
                .select(WaitPakin::getId));
        if (pakinIds.isEmpty()) {
            return;
        }
        List<Long> list = pakinIds.stream().map(WaitPakin::getId).collect(Collectors.toList());
        List<WaitPakin> pakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().in(WaitPakin::getId, list));
        if (pakins.isEmpty()) {
            throw new CoolException("组拖单为空!!");
        }
        pakins.forEach(pakin -> {
            WaitPakinLog log = new WaitPakinLog();
            BeanUtils.copyProperties(pakin, log);
            log.setPakinId(pakin.getId()).setIoStatus(PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val);
            if (!waitPakinLogService.save(log)) {
                throw new CoolException("组托日志保存失败!!");
            }
            List<WaitPakinItem> pakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().in(WaitPakinItem::getPakinId, pakin.getId()));
            if (pakinItems.isEmpty()) {
                throw new CoolException("组拖明细为空!!");
            }
            List<WaitPakinItemLog> itemLogs = new ArrayList<>();
            pakinItems.forEach(item -> {
                WaitPakinItemLog itemLog = new WaitPakinItemLog();
                BeanUtils.copyProperties(item, itemLog);
                itemLog.setPakinItemId(item.getId())
                        .setLogId(log.getId())
                        .setQty(item.getWorkQty())
                        .setWorkQty(0.0)
                        .setPakinId(item.getPakinId());
                itemLogs.add(itemLog);
            });
            if (!waitPakinItemLogService.saveBatch(itemLogs)) {
                throw new CoolException("历史明细档保存失败!!");
            }
        });
        if (!waitPakinService.removeByIds(list)) {
            throw new CoolException("原单据删除失败!!");
        }
        if (!waitPakinItemService.remove(new LambdaQueryWrapper<WaitPakinItem>().in(WaitPakinItem::getPakinId, list))) {
            throw new CoolException("原单据明细删除失败!!");
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveService.java
@@ -47,4 +47,11 @@
     * @time 2025/4/25 16:24
     */
    R waveToTask(Map<String, Object> map, Long loginUserId);
    /**
     * 终止下发
     * @param id
     * @return
     */
    R stopPubTask(Long id);
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveSowItemService.java
New file
@@ -0,0 +1,8 @@
package com.vincent.rsf.server.manager.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.manager.entity.WaveSowItem;
public interface WaveSowItemService extends IService<WaveSowItem> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java
@@ -56,6 +56,8 @@
    private WaveService waveService;
    @Autowired
    private WaveRuleServiceImpl waveRuleService;
    @Autowired
    private WaveOrderRelaServiceImpl waveOrderRelaService;
    /**
     * @param
@@ -213,6 +215,55 @@
    }
    /**
     * 终止波次下发任务
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R stopPubTask(Long id) {
        Wave wave = this.getById(id);
        if (Objects.isNull(wave)) {
            throw new CoolException("波次单不存在!!");
        }
        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>()
                .eq(TaskItem::getSourceId, wave.getId()));
        if (!taskItems.isEmpty()) {
            throw new CoolException("已生成任务不可终止当前波次!!");
        }
        List<WaveOrderRela> orderRelas = waveOrderRelaService.list(new LambdaQueryWrapper<WaveOrderRela>().eq(WaveOrderRela::getWaveId, id));
        if (orderRelas.isEmpty()) {
            throw new CoolException("无关联明细!!");
        }
        List<Long> orderIds = orderRelas.stream().map(WaveOrderRela::getOrderItemId).collect(Collectors.toList());
        List<AsnOrderItem> orderItems = asnOrderItemService.list(new LambdaQueryWrapper<AsnOrderItem>().in(AsnOrderItem::getId, orderIds));
        orderItems.forEach(asnOrderItem -> {
            asnOrderItem.setWorkQty(0.0);
            if (!asnOrderItemService.updateById(asnOrderItem)) {
                throw new CoolException("单据明细更新失败!!");
            }
        });
        List<Long> orders = orderRelas.stream().map(WaveOrderRela::getOrderId).collect(Collectors.toList());
        if (!asnOrderService.update(new LambdaUpdateWrapper<AsnOrder>()
                .set(AsnOrder::getWorkQty, 0.0)
                .set(AsnOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)
                .in(AsnOrder::getId, orders))) {
            throw new CoolException("单据更新失败!!");
        }
        this.update(new LambdaUpdateWrapper<Wave>()
                .eq(Wave::getId, id)
                .set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_TASK.val));
        return R.ok();
    }
    /**
     * @param
     * @param loginUserId
     * @param wave
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveSowItemServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.service.impl;
import com.vincent.rsf.server.manager.mapper.WaveSowItemMapper;
import com.vincent.rsf.server.manager.entity.WaveSowItem;
import com.vincent.rsf.server.manager.service.WaveSowItemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("waveSowItemService")
public class WaveSowItemServiceImpl extends ServiceImpl<WaveSowItemMapper, WaveSowItem> implements WaveSowItemService {
}
rsf-server/src/main/resources/mapper/manager/WaveSowItemMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.manager.mapper.WaveSowItemMapper">
</mapper>