自动化立体仓库 - WMS系统
371af76976cec152184123fac0073efcba2b5a70..51889b97a85b070cbb80a5bb2893149c80448d5d
8 天以前 1
#导出优化
51889b 对比 | 目录
8 天以前 1
#快速查看码垛数量页面优化
8a2733 对比 | 目录
8 天以前 1
#手动下发页面优化
47131a 对比 | 目录
8 天以前 1
#
648bc1 对比 | 目录
8 天以前 1
#
6387bf 对比 | 目录
1个文件已添加
23个文件已修改
832 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/LocDetlController.java 113 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/ExportParam.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/LocDetlMapper.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/OrderDetlPakinMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/OrderMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/LocDetlService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/OrderDetlPakinService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/OrderService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OrderDetlPakinServiceImpl.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OrderServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/kingdee/SaveOrderSyncScheduler.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/kingdee/SubmitOrderSyncScheduler.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/kingdee/handler/ReviewOrderSyncHandler.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/kingdee/handler/SaveOrderSyncHandler.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/erp/kingdee/enums/KingDeeUtilType.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocDetlMapper.xml 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/OrderDetlPakinMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/OrderMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/basArmMastExp/basArmMastExp.js 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/locDetlStatis/locDetlStatis.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/basArmMastExp/basArmMastExp.html 168 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/locDetlStatis/locDetlStatis.html 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/orderCargoGrouping/orderCargoGroupingOperate.html 179 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/LocDetlController.java
@@ -17,6 +17,7 @@
import com.zy.asrs.entity.LocOwner;
import com.zy.asrs.entity.Mat;
import com.zy.asrs.entity.param.AbnormalLocDetlParam;
import com.zy.asrs.entity.param.ExportParam;
import com.zy.asrs.entity.result.LocDetlAll;
import com.zy.asrs.entity.result.LocDetlDTO;
import com.zy.asrs.mapper.LocDetlMapper;
@@ -26,7 +27,7 @@
import com.zy.common.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
@@ -297,51 +298,27 @@
        }
        List<LocDetl> list = locDetlService.selectList(wrapper);
        List<LocDetl> result = new ArrayList<>();
        Page<LocDetl> groupLocDetl = locDetlService.getStockStatis2(toPage(1, 10000, param, LocDetl.class));
//        for (LocDetl locDetl : groupLocDetl.getRecords()) {
        for (LocDetl locDetl : list) {
//            AbnormalLocDetlParam abnormalLocDetlParam = new AbnormalLocDetlParam();
//            Mat mat = matService.selectOne(new EntityWrapper<Mat>()
//                    .eq("matnr", locDetl.getMatnr()));
//            if (Cools.isEmpty(mat)) {
//                continue;
//            }
//            if (!Cools.isEmpty(mat.getStoreMax()) || !Cools.isEmpty(mat.getStoreMin())) {
//                abnormalLocDetlParam.setStoreMax(mat.getStoreMax());
//                abnormalLocDetlParam.setStoreMaxDate(mat.getStoreMaxDate());
//                abnormalLocDetlParam.setStoreMin(mat.getStoreMin());
//                abnormalLocDetlParam.setAnfme(locDetl.getAnfme());//数量
//                abnormalLocDetlParam.setMaktx(mat.getMaktx());//商品名称
//                abnormalLocDetlParam.setMatnr(mat.getMatnr());//商品编号
//                abnormalLocDetlParam.setSpecs(mat.getSpecs());
//                abnormalLocDetlParam.setBatch(locDetl.getBatch());
//                abnormalLocDetlParam.setLocNo(locDetl.getLocNo());//库位号
//                abnormalLocDetlParam.setZpallet(locDetl.getZpallet());//托盘条码
//                abnormalLocDetlParam.setBarcode(locDetl.getStandby2());//条码upc
//                abnormalLocDetlParam.setUnit(locDetl.getStandby1());//客户po
//                abnormalLocDetlParam.setSku(locDetl.getSku());//客户sku
//                abnormalLocDetlParam.setSupp(locDetl.getSupp());//供应商
//                abnormalLocDetlParam.setManu(locDetl.getBoxType1());//货主
//                abnormalLocDetlParam.setOrderNo(locDetl.getOrderNo());//采购单号
//                abnormalLocDetlParam.setMemo(locDetl.getMemo());//备注
//                abnormalLocDetlParam.setModiTime(locDetl.getModiTime());//修改时间
//                SimpleDateFormat simple = new SimpleDateFormat("yyyyMMdd");
//                Date maxDate = simple.parse(locDetl.getBatch());
//                long time = maxDate.getTime();
//                Date now = new Date();
//                long time1 = now.getTime();
//                abnormalLocDetlParam.setNowTime((int) ((time1 - time) / (1000 * 60 * 60 * 24)));
//                if (!Cools.isEmpty(mat.getStoreMax()) && locDetl.getAnfme() > mat.getStoreMax()) {
                    result.add(locDetl);
//                } else if (!Cools.isEmpty(mat.getStoreMin()) && locDetl.getAnfme() < mat.getStoreMin()) {
//                    result.add(abnormalLocDetlParam);
//                }
//            }
            result.add(locDetl);
        }
        return R.ok(exportSupport(result, fields));
    }
//
//    @RequestMapping(value = "/locDetl/statis/export/auth")
//    @ManagerAuth(memo = "库存统计导出(当前筛选条件)")
//    public R statisExport(@RequestBody JSONObject json) {
//        // 获取前端传的字段列表
//        List<String> fields = JSONObject.parseArray(json.getJSONArray("fields").toJSONString(), String.class);
//
//        // 获取搜索参数,转成 DTO
//        ExportParam param = json.getJSONObject("locDetl").toJavaObject(ExportParam.class);
//
//        // 直接调用 Mapper 方法(全量数据,不分页)
//        List<LocDetl> list = locDetlMapper.selectStatisForExport(param);
//
//        // 导出
//        return R.ok(exportSupport(list, fields));
//    }
    @RequestMapping(value = "/locDetl/selectOwner/list/auth")
    @ManagerAuth
@@ -430,29 +407,57 @@
        }
        return R.ok().add(stockStatis);
    }
    @RequestMapping(value = "/locDetl/statis/export/auth")
    @ManagerAuth(memo = "库存统计导出")
    public R statisExport(@RequestBody JSONObject json) {
        // 获取搜索参数
        ExportParam param = json.getJSONObject("locDetl").toJavaObject(ExportParam.class);
    @Autowired
    private LocDetlMapper LocDetlMapper;
        // 查询全量汇总数据
        List<LocDetl> list = locDetlMapper.selectStockStatisExport(param);
    @RequestMapping(value = "/locDetl/statis/export")
//    @ManagerAuth
    public void statisExport(HttpServletResponse response) throws IOException {
        List<LocDetl> excel = LocDetlMapper.getStockStatisExcel();
        for (LocDetl locDetl : excel) {
        // 同步物料信息(保持原有逻辑)
        for (LocDetl locDetl : list) {
            Mat mat = matService.selectByMatnr(locDetl.getMatnr());
            if (mat != null) {
                locDetl.sync(mat);
            }
        }
        // 直接返回 JSON 数据数组
        return R.ok(list);  // 或 R.ok().put("data", list)
    }
    private void exportExcel(HttpServletResponse response, List<LocDetl> list, List<String> fields, String fileName) throws Exception {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("库存明细统计报表", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
        EasyExcel.write(response.getOutputStream(), LocDetl.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .sheet("表1")
                .doWrite(excel);
                .sheet("库存统计")
                .doWrite(list);
    }
    @Autowired
    private LocDetlMapper LocDetlMapper;
//    @RequestMapping(value = "/locDetl/statis/export")
////    @ManagerAuth
//    public void statisExport(HttpServletResponse response) throws IOException {
//        List<LocDetl> excel = LocDetlMapper.getStockStatisExcel();
//        for (LocDetl locDetl : excel) {
//            Mat mat = matService.selectByMatnr(locDetl.getMatnr());
//            if (mat != null) {
//                locDetl.sync(mat);
//            }
//        }
//        response.setContentType("application/vnd.ms-excel");
//        response.setCharacterEncoding("utf-8");
//        String fileName = URLEncoder.encode("库存明细统计报表", "UTF-8");
//        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
//        EasyExcel.write(response.getOutputStream(), LocDetl.class)
//                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
//                .sheet("表1")
//                .doWrite(excel);
//    }
    /**
     * 获取库存总数
src/main/java/com/zy/asrs/entity/param/ExportParam.java
New file
@@ -0,0 +1,17 @@
package com.zy.asrs.entity.param;
import com.zy.common.utils.Synchro;
import lombok.Data;
@Data
public class ExportParam {
    private Double anfme;
    private String matnr;
    private String standby1;
    private String standby2;
    private String boxType3;
    public void sync(Object source) {
        Synchro.Copy(source, this);
    }
}
src/main/java/com/zy/asrs/mapper/LocDetlMapper.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.zy.asrs.entity.LocDetl;
import com.zy.asrs.entity.param.ExportParam;
import com.zy.asrs.entity.result.LocDetlAll;
import com.zy.asrs.entity.result.LocDetlDTO;
import com.zy.asrs.entity.result.StockVo;
@@ -52,7 +53,8 @@
    List<String> selectSameDetlTodayBatch(@Param("matnr") String matnr,@Param("batch") String batch, @Param("start") Integer start, @Param("end") Integer end);
    List<LocDetl> getStockStatis(Map<String, Object> map);
    List<LocDetl> selectStatisForExport(ExportParam param);
    List<LocDetl> selectStockStatisExport( ExportParam param);
    Integer getStockStatisCount(Map<String, Object> map);
    List<LocDetl> getStockStatis2(Map<String, Object> map);
src/main/java/com/zy/asrs/mapper/OrderDetlPakinMapper.java
@@ -60,5 +60,5 @@
    List<OrderDetlPakin> selectOrderDetls(@Param("orderNo")String orderNo,@Param("sku")String sku,@Param("upc") String upc);
    List<OrderDetlPakin> selectOrderDetlsByOrderNo(@Param("orderNo")String orderNo);
    boolean morpt(@Param("orderNo")String orderNo);
    boolean morpt(@Param("orderNo")String orderNo,@Param("matnr")String matnr);
}
src/main/java/com/zy/asrs/mapper/OrderMapper.java
@@ -30,4 +30,7 @@
    List<String> AllStatusSatisfyOrder(@Param("moveStatus") Integer moveStatus);
    boolean updateOrderStatus(@Param("orderNo")String orderNo);
    boolean updateOrderStatus4(@Param("orderNo")String orderNo);
}
src/main/java/com/zy/asrs/service/LocDetlService.java
@@ -54,6 +54,7 @@
    List<String> getSameDetlToday(String matnr, String batch, Integer start, Integer end);
    Page<LocDetl> getStockStatis(Page<LocDetl> page);
//    List<LocDetl> getStockStatisList(Page<LocDetl> page);
    Double getSumAnfme(String matnr);
src/main/java/com/zy/asrs/service/OrderDetlPakinService.java
@@ -35,7 +35,7 @@
    boolean increaseQtyByOrderNo(String orderNo, String matnr, String batch, String brand, String standby1, String standby2, String standby3
            , String boxType1, String boxType2, String boxType3, Double qty);
    boolean morpt(String orderNo);
    boolean morpt(String orderNo,String orderNo1);
    /**
     * 入出库任务生成时,更新单据表中作业数量
     * @param orderId
src/main/java/com/zy/asrs/service/OrderService.java
@@ -42,4 +42,6 @@
    boolean updateOrderStatus(String orderNo);
    boolean updateOrderStatus4(String orderNo);
}
src/main/java/com/zy/asrs/service/impl/OrderDetlPakinServiceImpl.java
@@ -4,17 +4,20 @@
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.core.common.Cools;
import com.core.exception.CoolException;
import com.zy.asrs.entity.OrderDetlPakin;
import com.zy.asrs.entity.param.OrderDetlByCode;
import com.zy.asrs.mapper.OrderDetlPakinMapper;
import com.zy.asrs.service.OrderDetlPakinService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("orderDetlPakinService")
public class OrderDetlPakinServiceImpl extends ServiceImpl<OrderDetlPakinMapper, OrderDetlPakin> implements OrderDetlPakinService {
    @Autowired
    private OrderDetlPakinService orderDetlPakinService;
    @Override
    public List<OrderDetlPakin> selectByOrderId(Long orderId) {
        return this.selectList(new EntityWrapper<OrderDetlPakin>().eq("order_id", orderId));
@@ -114,8 +117,25 @@
    }
    
    @Override
    public boolean morpt(String orderNo){
        return this.baseMapper.morpt(orderNo);
    public boolean morpt(String orderNo,String orderNo1){
        List<OrderDetlPakin> list1 = orderDetlPakinService.selectList(new EntityWrapper<OrderDetlPakin>().eq("order_no",orderNo1));
        try{
            for (OrderDetlPakin item : list1) {
                Double anfme = item.getAnfme();
                Double qty = item.getQty();
                String matnr = item.getMatnr();
                if(anfme.equals(qty)){
                    OrderDetlPakin orderDetlPakin = orderDetlPakinService.selectOne(
                            new EntityWrapper<OrderDetlPakin>().eq("matnr", matnr).eq("order_no", orderNo)
                    );
                    this.baseMapper.morpt(orderNo,matnr);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new CoolException("汇报单转换失败:" + e.getMessage());
        }
        return true;
    }
}
src/main/java/com/zy/asrs/service/impl/OrderServiceImpl.java
@@ -227,5 +227,9 @@
        return this.baseMapper.updateOrderStatus(orderNo);
    }
    @Override
    public boolean updateOrderStatus4(String orderNo){
        return this.baseMapper.updateOrderStatus4(orderNo);
    }
}
src/main/java/com/zy/asrs/task/kingdee/SaveOrderSyncScheduler.java
@@ -59,7 +59,7 @@
                        orderService.updateById(order);
                    }else if(order.getPayType() == 1 || order.getSalesman() != null){
                        Order order1 = orderService.selectByNo(order.getSalesman());
                        if(orderDetlPakinService.morpt(order.getSalesman())){
                        if(orderDetlPakinService.morpt(order.getSalesman(),order.getOrderNo())){
                            order.setSettle(11L); //yu/cheng/dan/deng/dai/chu/ku/dan
                            orderService.updateById(order);
                        }
src/main/java/com/zy/asrs/task/kingdee/SubmitOrderSyncScheduler.java
@@ -34,7 +34,7 @@
    @Value("${erp.switch.ReviewOrderSwitch}")
    private boolean ReviewOrderSwitch;
//    @Scheduled(cron = "0/20 * * * * ?")
    @Scheduled(cron = "0/20 * * * * ?")
    @Async("orderThreadPool")
    public void completeAndReport(){
        if(!ReviewOrderSwitch){
src/main/java/com/zy/asrs/task/kingdee/handler/ReviewOrderSyncHandler.java
@@ -234,9 +234,7 @@
                }else{
                    if(order.getDocType() == 23L){
                        Order order1 = orderService.selectOne(new EntityWrapper<Order>().eq("salesman",order.getOrderNo()));
                        order1.setPayType(null);
                        order1.setSettle(4L);
                        orderService.updateById(order1);
                        orderService.updateOrderStatus4(order1.getOrderNo());
                    }
                    order.setSettle(8L); // 更新状态为已上报审核 9->8
                }
src/main/java/com/zy/asrs/task/kingdee/handler/SaveOrderSyncHandler.java
@@ -273,7 +273,7 @@
                                        .fluentPut("billno", UUID.randomUUID().toString().replace("-", "").substring(0, 16))
                                        .fluentPut("bizorg_number", "BU-00001")
                                        .fluentPut("dept_number", "Org-00002")
                                        .fluentPut("billstatus", "B")
                                        .fluentPut("billstatus", "A")
                                        .fluentPut("customer_number", "Cus-000004")
                                        .fluentPut("biztime", sdf1.format(nowMis))
                                        .fluentPut("biztype_number", "210")
@@ -407,8 +407,13 @@
                        String billNo = resultItem.getString("number");  // 获取返回的单据号
                        String billId = resultItem.getString("id");      // 获取返回的ID
                        order.setNumber(billId);
                        order.setShipCode(add.getString("billno"));
                        String jsonString = add.toJSONString();
                        JSONObject jsonObject = JSONObject.parseObject(jsonString);
                        String billno = jsonObject.getJSONArray("data")
                                .getJSONObject(0)
                                .getString("billno");
                        order.setShipCode(billno);  // 设置到 order 对象中
                    }
                } else {
                    log.error("接口调用失败,失败的操作数量: {}", failCount);
src/main/java/com/zy/erp/kingdee/enums/KingDeeUtilType.java
@@ -13,7 +13,7 @@
    PRD_ReturnMtrl(12, "生产退料单","PRD_ReturnMtrl","","","",1),
    PRD_FeedMtrl(14, "生产补料单","PRD_FeedMtrl","","","",0),
    PRD_MORPT(16, "生产汇报单","PRD_MORPT","","生产入库单","",1),
//    STK_InspectionForm(20, "产品检验单","STK_InspectionForm","","","",0),
//  (20, "委外入库单","STK_InspectionForm","","","",0),
    //    PUR_MRB(2, "采购退料单","PUR_MRB","FRMREALQTY","","",1),
//    STK_TransferDirect(6, "直接调拨单","STK_TransferDirect","","FQty","",1),
src/main/resources/application.yml
@@ -169,6 +169,11 @@
    #汇报单->自生成出库单上报
    imSaloutbillSave: /kapi/v2/eap7/im/im_saloutbill/save
    imSaloutbillSaveSubmit: kapi/v2/im/im_saloutbill/batchSubmit
    #委外入库指令
    omOutsourcereceiptQuery: /kapi/v2/eap7/om/om_outsourcereceipt/query
    imMdcOmprdinbillSave: /kapi/v2/eap7/im/im_mdc_omprdinbill/save
    imMdcOmprdinbillBatchSubmit: /kapi/v2/im/im_mdc_omprdinbill/batchSubmit
    imMdcOmprdinbillBatchAudit: /kapi/v2/im/im_mdc_omprdinbill/batchAudit
  #  登录账号管理
  login :
    xAcfwIdentity: "djF8MTlhNTNhZjJhOWEwMWRlODhlMDF8NDkxNTk0MDU4MTQxNXwus9WaEHKRh0daJe1TWmVoMkv3zQY2knNTZRzaOhRgwnw"
src/main/resources/mapper/LocDetlMapper.xml
@@ -358,7 +358,22 @@
            and a.standby3 like '%' + #{standby3} + '%'
        </if>
        <if test="boxType3!=null and boxType3!='' ">
            and a.boxType3 like '%' + #{boxType3} + '%'
            and a.box_type3 like '%' + #{boxType3} + '%'
        </if>
    </sql>
    <sql id="stockOutCondition1">
        <if test="matnr!=null and matnr!='' ">
            and a.matnr like '%' + #{matnr} + '%'
        </if>
        <if test="standby1!=null and standby1!='' ">
            and a.standby1 like '%' + #{standby1} + '%'
        </if>
        <if test="standby2!=null and standby2!='' ">
            and a.standby2 like '%' + #{standby2} + '%'
        </if>
        <if test="boxType3!=null and boxType3!='' ">
            and a.box_type3 like '%' + #{boxType3} + '%'
        </if>
    </sql>
@@ -386,21 +401,48 @@
        <include refid="stockOutCondition"></include>
    </select>
    <select id="getStockStatis" resultType="com.zy.asrs.entity.LocDetl">
        select * from
        (
            select
            ROW_NUMBER() over (order by sum(a.anfme) desc) as row
            , a.matnr
            , a.batch
            , a.standby1
            , a.standby2
            , sum(a.anfme) as anfme
            from asr_loc_detl a
            where 1=1
            <include refid="stockOutCondition"></include>
            group by a.matnr, a.batch, a.standby1, a.standby2
         ) t where t.row between ((#{pageNumber}-1)*#{pageSize}+1) and (#{pageNumber}*#{pageSize})
    <select id="getStockStatis" resultMap="BaseResultMap">
        SELECT * FROM (
            SELECT
                ROW_NUMBER() OVER (ORDER BY SUM(a.anfme) DESC) AS row,
                a.matnr,
                a.batch,
                a.standby1,
                a.standby2,
                MAX(a.box_type3) AS box_type3,  -- 关键:用 MAX 避免 null 或不确定性
                SUM(a.anfme) AS anfme
                FROM asr_loc_detl a
                WHERE 1=1
                <include refid="stockOutCondition"/>
                GROUP BY
                a.matnr,
                a.batch,
                a.standby1,
                a.standby2,
                a.box_type3  -- 保留,因为业务需要按采购单区分
            ) t
        WHERE t.row BETWEEN ((#{pageNumber}-1)*#{pageSize}+1) AND (#{pageNumber}*#{pageSize})
    </select>
    <!-- 库存统计导出:全量汇总数据(不分页) -->
    <select id="selectStockStatisExport" resultMap="BaseResultMap">
        SELECT
        a.matnr,
        a.batch,
        a.standby1,
        a.standby2,
        MAX(a.box_type3) AS box_type3,
        SUM(a.anfme) AS anfme
        FROM asr_loc_detl a
        WHERE 1=1
        <include refid="stockOutCondition1"/>
        GROUP BY
        a.matnr,
        a.batch,
        a.standby1,
        a.standby2,
        a.box_type3
        ORDER BY SUM(a.anfme) DESC
    </select>
    <select id="getStockStatisCount" parameterType="java.util.Map" resultType="java.lang.Integer">
src/main/resources/mapper/OrderDetlPakinMapper.xml
@@ -267,7 +267,7 @@
    <update id="morpt" parameterType="String">
        UPDATE man_order_detl_pakin
        SET qty = anfme, work_qty = anfme
        WHERE order_no = #{orderNo}
        WHERE order_no = #{orderNo} and matnr = #{matnr}
    </update>
</mapper>
src/main/resources/mapper/OrderMapper.xml
@@ -149,4 +149,12 @@
        and order_no = #{orderNo}
    </update>
    <update id="updateOrderStatus4">
        update man_order
        set pay_type = null,
        settle = 4
        where 1=1
        and order_no = #{orderNo}
    </update>
</mapper>
src/main/webapp/static/js/basArmMastExp/basArmMastExp.js
@@ -8,10 +8,9 @@
    var layDate = layui.laydate;
    var form = layui.form;
    var admin = layui.admin;
    // 数据渲染
    tableIns = table.render({
        elem: '#basArmMast',
        elem: '#basArmMastExp',
        headers: {token: localStorage.getItem('token')},
        url: baseUrl+'/basArmMast/list/auth',
        page: true,
@@ -21,42 +20,81 @@
        cellMinWidth: 50,
        height: 'full-120',
        cols: [[
            {type: 'checkbox'}
            ,
            {field: 'id', align: 'center',title: 'ID',hide: true}
            ,{field: 'armNo', align: 'center',title: '机械臂编号',hide: false}
            ,{field: 'orderNo', align: 'center',title: '订单号',hide: false}
            ,{field: 'armDirection', align: 'center',title: '操作方向',hide: true}
            ,{field: 'staNo', align: 'center',title: '终点',hide: false}
            ,{field: 'sortingLine', align: 'center',title: '起点',hide: false}
            ,{field: 'matnr', align: 'center',title: '商品编号',hide: false}
            ,{field: 'sku', align: 'center',title: 'sku',hide: true}
            // ,{field: 'po', align: 'center',title: 'po',hide: false}
            // ,{field: 'upc', align: 'center',title: 'upc',hide: false}
            // ,{field: 'status', align: 'center',title: '作业状态',hide: true}
            // ,{field: 'status$', align: 'center',title: '作业状态',hide: false}
            // ,{field: 'bindingTags', align: 'center',title: '分拣绑定标记',hide: false}
            // ,{field: 'priority', align: 'center',title: '优先级',hide: true}
            // ,{field: 'supplier', align: 'center',title: '货源',hide: false}
            ,{field: 'ctns', align: 'center',title: '总箱数',hide: true}
            // ,{field: 'createTime', align: 'center',title: '时间戳',hide: true}
            // ,{field: 'barcode', align: 'center',title: '托盘码',hide: false}
            // ,{field: 'armError', align: 'center',title: '异常代码',hide: true}
            // ,{field: 'armMsg', align: 'center',title: '异常信息',hide: true}
            ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:120}
            {type: 'checkbox'},
            {field: 'armNo', align: 'center', title: '机械臂编号'},
            {field: 'orderNo', align: 'center', title: '订单号'},
            {field: 'matnr', align: 'center', title: '商品编号'},
            {field: 'po', align: 'center', title: 'PO'},
            {field: 'upc', align: 'center', title: 'UPC'},
            {field: 'sortingLine', align: 'center', title: '起点'},
            {field: 'status', align: 'center', title: '作业状态', templet: function(d){
                    return '2.单码完成等待托盘完成';  // 因为现在只显示状态2,固定显示
                }},
            {field: 'barcode', align: 'center', title: '托盘码'},
            {field: 'supplier', align: 'center', title: '货源'},
            {field: 'quantity', align: 'center', title: '数量', sort: true, style: 'background-color: #fffbe6; font-weight: bold;'},  // 高亮显示数量
            // {fixed: 'right', title: '操作', align: 'center', toolbar: '#operate', width: 120}
        ]],
        request: {
            pageName: 'curr',
            pageSize: 'limit'
        },
        parseData: function (res) {
            return {
                'code': res.code,
                'msg': res.msg,
                'count': res.data.total,
                'data': res.data.records
            if (res.code !== 200) {
                return {
                    'code': res.code,
                    'msg': res.msg,
                    'count': 0,
                    'data': []
                };
            }
            var records = res.data.records || [];
            var groupMap = new Map();  // 用来汇总状态为2的数据
            records.forEach(function(item) {
                // 只处理状态为2的记录,其他状态直接忽略(隐藏)
                if (String(item.status) === '2') {
                    // 生成唯一标识(5个字段组合)
                    var key = [
                        item.armNo || '',
                        item.sortingLine || '',
                        item.barcode || '',
                        item.matnr || '',
                        item.orderNo || ''
                    ].join('|||||');  // 用多个|分隔,避免字段值冲突
                    if (groupMap.has(key)) {
                        // 已存在相同组合,数量+1
                        groupMap.get(key).quantity += 1;
                    } else {
                        // 新组合,创建一条汇总记录
                        groupMap.set(key, {
                            armNo: item.armNo,
                            orderNo: item.orderNo,
                            matnr: item.matnr,
                            po: item.po || '',
                            upc: item.upc || '',
                            sortingLine: item.sortingLine,
                            barcode: item.barcode,
                            supplier: item.supplier || '',
                            status: '2',           // 固定显示为2
                            quantity: 1            // 初始数量1
                        });
                    }
                }
                // 状态不为2的记录直接跳过,不加入任何数据
            });
            // 转换为数组
            var finalData = Array.from(groupMap.values());
            return {
                'code': 200,
                'msg': res.msg,
                'count': finalData.length,   // 分页总数 = 合并后的行数
                'data': finalData
            };
        },
        response: {
            statusCode: 200
@@ -69,7 +107,6 @@
            limit();
        }
    });
    // 监听排序事件
    table.on('sort(basArmMast)', function (obj) {
        var searchData = {};
@@ -83,7 +120,6 @@
            page: {curr: 1}
        });
    });
    // 监听头工具栏事件
    table.on('toolbar(basArmMast)', function (obj) {
        var checkStatus = table.checkStatus(obj.config.id).data;
@@ -92,14 +128,14 @@
                showEditModel();
                break;
            case 'deleteData':
               if (checkStatus.length === 0) {
                   layer.msg('请选择要删除的数据', {icon: 2});
                   return;
               }
               del(checkStatus.map(function (d) {
                   return d.id;
               }));
               break;
                if (checkStatus.length === 0) {
                    layer.msg('请选择要删除的数据', {icon: 2});
                    return;
                }
                del(checkStatus.map(function (d) {
                    return d.id;
                }));
                break;
            case 'exportData':
                admin.confirm('确定导出Excel吗', {shadeClose: true}, function(){
                    var titles=[];
@@ -140,7 +176,6 @@
                break;
        }
    });
    // 监听行工具事件
    table.on('tool(basArmMast)', function(obj){
        var data = obj.data;
@@ -153,7 +188,6 @@
                break;
        }
    });
    /* 弹窗 - 新增、修改 */
    function showEditModel(mData) {
        admin.open({
@@ -191,7 +225,6 @@
            }
        });
    }
    /* 删除 */
    function del(ids) {
        layer.confirm('确定要删除选中数据吗?', {
@@ -219,20 +252,17 @@
            })
        });
    }
    // 搜索
    form.on('submit(search)', function (data) {
        pageCurr = 1;
        tableReload(false);
    });
    // 重置
    form.on('submit(reset)', function (data) {
        pageCurr = 1;
        clearFormVal($('#search-box'));
        tableReload(false);
    });
    // 时间选择器
    function layDateRender(data) {
        setTimeout(function () {
@@ -241,18 +271,14 @@
                ,type: 'datetime'
                ,range: true
            });
        }, 300);
    }
    layDateRender();
});
// 关闭动作
$(document).on('click','#data-detail-close', function () {
    parent.layer.closeAll();
});
function tableReload(child) {
    var searchData = {};
    $.each($('#search-box [name]').serializeArray(), function() {
@@ -261,5 +287,5 @@
    tableIns.reload({
        where: searchData,
        page: {curr: pageCurr}
     });
}
    });
}
src/main/webapp/static/js/locDetlStatis/locDetlStatis.js
@@ -5,6 +5,8 @@
    ];
    arrRemove(detlCols, "field", "anfme")
    arrRemove(detlCols, "field", "zpallet")
    arrRemove(detlCols, "field", "orderNo")
    arrRemove(detlCols, "field", "memo")
    cols.push.apply(cols, detlCols);
    // cols.push({field: 'anfme', align: 'center',title: '数量', style: 'font-weight: bold'}
    // )
@@ -103,45 +105,55 @@
        var checkStatus = table.checkStatus(obj.config.id);
        switch(obj.event) {
            case 'exportAll':
                layer.closeAll();
                layer.load(1, {shade: [0.1,'#fff']});
                location.href = baseUrl + "/locDetl/statis/export";
                layer.closeAll('loading');
                break;
            case 'exportData':
                layer.confirm('确定导出Excel吗', {shadeClose: true}, function(){
                    var titles=[];
                    var fields=[];
                    obj.config.cols[0].map(function (col) {
                        if (col.type === 'normal' && col.hide === false && col.toolbar == null) {
                            titles.push(col.title);
                            fields.push(col.field);
                        }
                    });
                layer.confirm('确定导出Excel吗?', {shadeClose: true}, function(){
                    // 收集搜索条件
                    var exportData = {};
                    $.each($('#search-box [name]').serializeArray(), function() {
                        exportData[this.name] = this.value;
                    });
                    var param = {
                        'locDetl': exportData,
                        'fields': fields
                        locDetl: exportData
                    };
                    $.ajax({
                        url: baseUrl+"/locDetl/export/auth",
                        url: baseUrl + "/locDetl/statis/export/auth",
                        headers: {'token': localStorage.getItem('token')},
                        data: JSON.stringify(param),
                        dataType:'json',
                        contentType:'application/json;charset=UTF-8',
                        dataType: 'json',
                        contentType: 'application/json;charset=UTF-8',
                        method: 'POST',
                        success: function (res) {
                            layer.closeAll();
                            if (res.code === 200) {
                                table.exportFile(titles,res.data,'xls');
                            if (res.code === 200 && res.data && res.data.length > 0) {
                                var titles = ['库存数量', '商品编号', '商品名称', '采购单号', '条码UPC', '单箱净重(kg)', '客户PO'];
                                var fieldKeys = ['anfme', 'matnr', 'maktx', 'boxType3', 'standby2', 'weight', 'standby1'];
                                var exportData = res.data.map(function(item) {
                                    return [
                                        item.anfme || '',
                                        item.matnr || '',
                                        item.maktx || '',  // 如果 maktx 为空可默认
                                        item.boxType3 || '',
                                        item.standby2 || '',
                                        item.weight || '',
                                        item.standby1 || ''  // 如字段是 order_no 改成 item.order_no
                                    ];
                                });
                                table.exportFile(titles, exportData, 'xls');
                                layer.msg('导出成功,共 ' + res.data.length + ' 条数据', {icon: 1});
                            } else if (res.code === 200) {
                                layer.msg('没有符合条件的数据可导出', {icon: 2});
                            } else if (res.code === 403) {
                                top.location.href = baseUrl+"/";
                                top.location.href = baseUrl + "/";
                            } else {
                                layer.msg(res.msg)
                                layer.msg(res.msg || '导出失败');
                            }
                        },
                        error: function() {
                            layer.closeAll();
                            layer.msg('网络错误,导出失败');
                        }
                    });
                });
src/main/webapp/views/basArmMastExp/basArmMastExp.html
@@ -11,17 +11,11 @@
    <link rel="stylesheet" href="../../static/css/cool.css" media="all">
</head>
<body>
<div class="layui-fluid">
    <div class="layui-card">
        <div class="layui-card-body">
            <div class="layui-form toolbar" id="search-box">
                <div class="layui-form-item">
<!--                    <div class="layui-inline">-->
<!--                        <div class="layui-input-inline">-->
<!--                            <input class="layui-input" type="text" name="id" placeholder="编号" autocomplete="off">-->
<!--                        </div>-->
<!--                    </div>-->
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="arm_no" placeholder="机械臂编号" autocomplete="off">
@@ -34,7 +28,17 @@
                    </div>
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="sta_no" placeholder="终点、码垛位" autocomplete="off">
                            <input class="layui-input" type="text" name="matnr" placeholder="商品编号" autocomplete="off">
                        </div>
                    </div>
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="po" placeholder="po" autocomplete="off">
                        </div>
                    </div>
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="upc" placeholder="upc" autocomplete="off">
                        </div>
                    </div>
                    <div class="layui-inline">
@@ -45,7 +49,6 @@
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <select name="status" id="status" class="layui-input" type="text" placeholder="作业状态" autocomplete="off">
<!--                                <option style="display: none"></option>-->
                                <option value="">作业状态</option>
                                <option value="0">0.等待下发至机械臂</option>
                                <option value="1">1.机械臂作业中</option>
@@ -59,39 +62,14 @@
                    </div>
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="sku" placeholder="sku" autocomplete="off">
                        </div>
                    </div>
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="po" placeholder="po" autocomplete="off">
                        </div>
                    </div>
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="upc" placeholder="upc" autocomplete="off">
                        </div>
                    </div>
<!--                     <div class="layui-inline" style="width: 300px">-->
<!--                        <div class="layui-input-inline">-->
<!--                            <input class="layui-input layui-laydate-range" name="create_time" type="text" placeholder="起始时间 - 终止时间" autocomplete="off" style="width: 300px">-->
<!--                        </div>-->
<!--                    </div>-->
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="binding_tags" placeholder="分拣绑定标记" autocomplete="off">
                        </div>
                    </div>
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="barcode" placeholder="托盘码" autocomplete="off">
                        </div>
                    </div>
<!--                    <div class="layui-inline">-->
<!--                        <div class="layui-input-inline">-->
<!--                            <input class="layui-input" type="text" name="condition" placeholder="请输入" autocomplete="off">-->
<!--                        </div>-->
<!--                    </div>-->
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="supplier" placeholder="货源" autocomplete="off">
                        </div>
                    </div>
                    <div class="layui-inline">&emsp;
                        <button class="layui-btn icon-btn" lay-filter="search" lay-submit>
                            <i class="layui-icon">&#xe615;</i>搜索
@@ -102,29 +80,26 @@
                    </div>
                </div>
            </div>
            <table class="layui-hide" id="basArmMast" lay-filter="basArmMast"></table>
            <table class="layui-hide" id="basArmMastExp" lay-filter="basArmMastExp"></table>
        </div>
    </div>
</div>
<script type="text/html" id="toolbar">
    <div class="layui-btn-container">
        <button class="layui-btn layui-btn-sm" id="btn-add" lay-event="addData">新增</button>
        <button class="layui-btn layui-btn-sm layui-btn-danger" id="btn-delete" lay-event="deleteData">删除</button>
        <button class="layui-btn layui-btn-primary layui-btn-sm" id="btn-export" lay-event="exportData" style="float: right">导出</button>
<!--        <button class="layui-btn layui-btn-sm" id="btn-add" lay-event="addData">新增</button>-->
<!--        <button class="layui-btn layui-btn-sm layui-btn-danger" id="btn-delete" lay-event="deleteData">删除</button>-->
<!--        <button class="layui-btn layui-btn-primary layui-btn-sm" id="btn-export" lay-event="exportData" style="float: right">导出</button>-->
    </div>
</script>
<script type="text/html" id="operate">
    <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="edit">修改</a>
    <a class="layui-btn layui-btn-danger layui-btn-xs btn-edit" lay-event="del">删除</a>
<!--    <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="edit">修改</a>-->
<!--    <a class="layui-btn layui-btn-danger layui-btn-xs btn-edit" lay-event="del">删除</a>-->
</script>
<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/basArmMast/basArmMast.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/basArmMastExp/basArmMastExp.js" charset="utf-8"></script>
</body>
<!-- 表单弹窗 -->
<script type="text/html" id="editDialog">
@@ -132,49 +107,6 @@
        <input name="id" type="hidden">
        <div class="layui-row">
            <div class="layui-col-md12">
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">机械臂编号: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="armNo" placeholder="请输入机械臂编号" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">操作方向: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="armDirection" placeholder="请输入操作方向" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">终点: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="staNo" placeholder="请输入终点" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">起点: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="sortingLine" placeholder="请输入起点" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">分拣绑定标记: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="bindingTags" placeholder="请输入分拣绑定标记" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">优先级: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="priority" placeholder="请输入优先级" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">状态: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="status" placeholder="请输入状态" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
                <!-- 工作状态 -->
                <div class="layui-form-item">
                    <label class="layui-form-label layui-form-required">状态:</label>
@@ -190,54 +122,6 @@
                        </select>
                    </div>
                </div>
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="matnr" placeholder="请输入" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="sku" placeholder="请输入" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="po" placeholder="请输入" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="upc" placeholder="请输入" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">货源: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="supplier" placeholder="请输入货源" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="orderNo" placeholder="请输入" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">箱数: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="ctns" placeholder="请输入箱数" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="layui-form-item">-->
<!--                    <label class="layui-form-label layui-form-required">时间戳: </label>-->
<!--                    <div class="layui-input-block">-->
<!--                        <input class="layui-input" name="createTime" placeholder="请输入时间戳" lay-vertype="tips" lay-verify="required">-->
<!--                    </div>-->
<!--                </div>-->
                <div class="layui-form-item">
                    <label class="layui-form-label layui-form-required">托盘码: </label>
                    <div class="layui-input-block">
@@ -256,8 +140,7 @@
                        <input class="layui-input" name="armMsg" placeholder="请输入异常信息">
                    </div>
                </div>
             </div>
            </div>
        </div>
        <hr class="layui-bg-gray">
        <div class="layui-form-item text-right">
@@ -266,5 +149,4 @@
        </div>
    </form>
</script>
</html>
</html>
src/main/webapp/views/locDetlStatis/locDetlStatis.html
@@ -16,7 +16,16 @@
<div id="search-box" class="layui-form layui-card-header">
    <div class="layui-inline">
        <div class="layui-input-inline">
            <input class="layui-input" type="text" name="matnr" placeholder="商品编号" autocomplete="off">
            <input class="layui-input" type="text" name="matnr" placeholder="SKU" autocomplete="off">
        </div>
        <div class="layui-input-inline">
            <input class="layui-input" type="text" name="boxType3" placeholder="采购单号" autocomplete="off">
        </div>
        <div class="layui-input-inline">
            <input class="layui-input" type="text" name="standby2" placeholder="UPC" autocomplete="off">
        </div>
        <div class="layui-input-inline">
            <input class="layui-input" type="text" name="standby1" placeholder="PO" autocomplete="off">
        </div>
    </div>
    <!-- 待添加 -->
src/main/webapp/views/orderCargoGrouping/orderCargoGroupingOperate.html
@@ -225,9 +225,41 @@
            </el-descriptions>
            <h3 style="margin-top: 20px;">订单明细</h3>
            <!-- 明细表格搜索栏 -->
            <div class="search-container" style="margin: 20px 0; padding: 15px; background: #f5f7fa; border-radius: 4px;">
                <el-form :inline="true" class="search-form">
                    <div class="search-item">
                        <span class="search-label">客户SKU:</span>
                        <el-input
                                v-model="detailSearch.standby3"
                                placeholder="请输入客户SKU"
                                clearable
                                style="width: 180px;"
                                @input="handleDetailSearch"
                                @keyup.enter.native="handleDetailSearch"
                        ></el-input>
                    </div>
                    <div class="search-item">
                        <span class="search-label">采购单号:</span>
                        <el-input
                                v-model="detailSearch.boxType3"
                                placeholder="请输入采购单号"
                                clearable
                                style="width: 180px;"
                                @input="handleDetailSearch"
                                @keyup.enter.native="handleDetailSearch"
                        ></el-input>
                    </div>
<!--                    <div class="search-actions" style="margin-left: auto;">-->
<!--                        <el-button type="primary" icon="el-icon-search" @click="handleDetailSearch">搜索</el-button>-->
<!--                        <el-button icon="el-icon-refresh" @click="handleDetailReset">重置</el-button>-->
<!--                    </div>-->
                </el-form>
            </div>
            <el-table
                    border
                    :data="tableDataB"
                    ref="detailTable"
                    :data="filteredTableDataB"
                    style="width: 100%"
                    v-loading="detailLoading">
                <el-table-column prop="id" label="id" min-width="50" align="center"></el-table-column>
@@ -240,7 +272,7 @@
                <el-table-column prop="anfme" label="数量" min-width="80" align="center">
                    <template slot-scope="scope">
                        <el-input-number
                                v-model="scope.row.anfme"
                                v-model="scope.row.anfmeRow"
                                :min="0"
                                :precision="0"
                                controls-position="right"
@@ -324,6 +356,12 @@
                cstmrName: '',
                settle: ''
            },
            detailSearch: {
                standby3: '',
                boxType3: ''
            },
            // 新增:用于缓存原始明细数据(分页加载后的完整当前页数据)
            originalTableDataB: [],
            // 排序相关
            orderByField: '',
            orderByType: 'asc',
@@ -355,6 +393,34 @@
        created() {
            this.init();
        },
        computed: {
            // 明细表格过滤后的数据
            filteredTableDataB() {
                if (!this.originalTableDataB || this.originalTableDataB.length === 0) {
                    return [];
                }
                let data = this.originalTableDataB;
                // 客户SKU 模糊搜索(不区分大小写)
                if (this.detailSearch.standby3 && this.detailSearch.standby3.trim()) {
                    const keyword = this.detailSearch.standby3.trim().toLowerCase();
                    data = data.filter(item =>
                            item.standby3 && item.standby3.toLowerCase().includes(keyword)
                    );
                }
                // 采购单号 模糊搜索
                if (this.detailSearch.boxType3 && this.detailSearch.boxType3.trim()) {
                    const keyword = this.detailSearch.boxType3.trim().toLowerCase();
                    data = data.filter(item =>
                            item.boxType3 && item.boxType3.toLowerCase().includes(keyword)
                    );
                }
                return data;
            }
        },
        methods: {
            init() {
                this.getTableDataA();
@@ -363,6 +429,17 @@
                setInterval(() => {
                    this.getTableDataA();
                }, 10000);
            },
            handleDetailSearch() {
                // 触发计算属性重新计算即可,无需额外操作
                this.$forceUpdate(); // 可选,确保立即刷新(通常不需要)
            },
            // 明细搜索重置
            handleDetailReset() {
                this.detailSearch.standby3 = '';
                this.detailSearch.boxType3 = '';
                // 重置后表格自动恢复原数据
            },
            // 获取主表A数据
@@ -420,18 +497,15 @@
                    }
                });
            },
            // 获取子表B数据
// 获取子表B数据
            getTableDataB(orderNo) {
                let that = this;
                that.detailLoading = true;
                let params = {
                    order_no: orderNo,
                    curr: that.detailCurrentPage,
                    limit: that.detailPageSize
                };
                $.ajax({
                    url: baseUrl + "/order/pakin/orderDetl/list/auth",
                    headers: {
@@ -445,13 +519,26 @@
                        if (res.code === 200 || res.success) {
                            that.tableDataB = res.data.records || [];
                            that.detailTotal = res.data.total || 0;
                            // 初始化数量缓存
                            that.modifiedQuantities = {};
                            that.originalTableDataB = [...res.data.records || []];  // 新增:保存原始数据用于过滤
                            // ============ 新增:设置数量默认值为 ERP下发数量 - 待下发数量 ============
                            that.tableDataB.forEach(item => {
                                // 假设后端返回的字段名是 erpAnfme(ERP下发数量)和 sortingAnfme(待下发数量)
                                // 如果字段名不同,请替换成实际的
                                const erpQty = parseInt(item.anfme) || 0;        // ERP下发数量
                                const pendingQty = parseInt(item.sortingAnfme) || 0; // 待下发数量
                                // 计算默认数量:ERP总量 - 已待下发 = 还可修改/下发的数量
                                const defaultQty = erpQty - pendingQty;
                                // 设置输入框默认值(确保 >= 0)
                                that.$set(item, 'anfmeRow', Math.max(0, defaultQty));
                                // 同时初始化 modifiedQuantities 缓存
                                const itemKey = that.getItemKey(item);
                                that.$set(that.modifiedQuantities, itemKey, item.anfme);
                                that.$set(that.modifiedQuantities, itemKey, Math.max(0, defaultQty));
                            });
                            // ==========================================================================
                        } else {
                            that.$message.error(res.msg || '获取数据失败');
                            that.tableDataB = [];
@@ -461,11 +548,57 @@
                    },
                    error: function() {
                        that.detailLoading = false;
                        // 模拟数据
                        // 模拟数据也加上默认值逻辑(可选)
                        that.mockTableBData();
                        // 如果你有 mock 数据,也建议在这里加上同样的计算逻辑
                    }
                });
            },
            // // 获取子表B数据
            // getTableDataB(orderNo) {
            //     let that = this;
            //     that.detailLoading = true;
            //
            //     let params = {
            //         order_no: orderNo,
            //         curr: that.detailCurrentPage,
            //         limit: that.detailPageSize
            //     };
            //
            //     $.ajax({
            //         url: baseUrl + "/order/pakin/orderDetl/list/auth",
            //         headers: {
            //             'token': localStorage.getItem('token')
            //         },
            //         data: params,
            //         dataType: 'json',
            //         contentType: 'application/json;charset=UTF-8',
            //         method: 'get',
            //         success: function (res) {
            //             if (res.code === 200 || res.success) {
            //                 that.tableDataB = res.data.records || [];
            //                 that.detailTotal = res.data.total || 0;
            //
            //                 // 初始化数量缓存
            //                 that.modifiedQuantities = {};
            //                 that.tableDataB.forEach(item => {
            //                     const itemKey = that.getItemKey(item);
            //                     that.$set(that.modifiedQuantities, itemKey, item.anfme);
            //                 });
            //             } else {
            //                 that.$message.error(res.msg || '获取数据失败');
            //                 that.tableDataB = [];
            //                 that.detailTotal = 0;
            //             }
            //             that.detailLoading = false;
            //         },
            //         error: function() {
            //             that.detailLoading = false;
            //             // 模拟数据
            //             that.mockTableBData();
            //         }
            //     });
            // },
            // 获取商品唯一标识
            getItemKey(item) {
@@ -620,8 +753,7 @@
            },
            // 提交修改到后台
            submitModify(orderNo, id, anfme,inspect) {
                // 显示加载状态
            submitModify(orderNo, id, anfme, inspect) {
                const loadingInstance = this.$loading({
                    lock: true,
                    text: '提交修改中...',
@@ -631,25 +763,24 @@
                $.ajax({
                    url: baseUrl + "/order/pakin/orderDetl/batch/report/auth",
                    headers: {'token': localStorage.getItem('token')},
                    headers: { 'token': localStorage.getItem('token') },
                    data: top.reObject({
                        orderNo: orderNo, // 组货单号
                        id: id, // id
                        anfme: anfme, // 箱号
                        inspect: inspect // 箱号
                        orderNo: orderNo,
                        id: id,
                        anfme: anfme,
                        inspect: inspect,  // 0 或 1
                    }),
                    method: 'POST',
                    success: (res) => {
                        loadingInstance.close();
                        if (res.code === 200 || res.success) {
                            this.$message({
                                message: `修改成功!订单号: ${orderNo}, id: ${id}`,
                                type: 'success',
                                duration: 3000
                            });
                            this.getTableDataB(groupOrderNo);
                            this.getTableDataB(orderNo);//
                            // 不需要重新加载整页数据(避免丢失用户修改的数量)
                        } else {
                            this.$message.error(res.msg || '修改失败');
                        }
@@ -842,9 +973,13 @@
                this.detailDialogVisible = true;
                this.detailCurrentPage = 1;
                this.settleA = row.settle;
                // 清空缓存
                this.modifiedQuantities = {};
                this.deletedRecords = [];
                // 新增:清空明细搜索
                this.detailSearch.standby3 = '';
                this.detailSearch.boxType3 = '';
                this.getTableDataB(row.orderNo);
            },