| | |
| | | public R exportDetail(@PathVariable("id") Long id) { |
| | | // 获取月结统计信息 |
| | | MonthlySettleStatisticsVO statistics = monthlySettleService.getSettleStatistics(id); |
| | | if (statistics == null || statistics.getDetails() == null) { |
| | | if (statistics == null) { |
| | | return R.error("月结明细不存在"); |
| | | } |
| | | |
| | | List<MonthlySettleDetail> details = statistics.getDetails(); |
| | | List<MonthlySettleDetail> details = statistics.getDetails() != null ? statistics.getDetails() : new ArrayList<>(); |
| | | List<com.zy.asrs.entity.result.MonthlySettleDetailFlowVO> detailFlows = statistics.getDetailFlows() != null ? statistics.getDetailFlows() : new ArrayList<>(); |
| | | |
| | | // 定义导出字段 |
| | | List<String> fields = new ArrayList<>(); |
| | | fields.add("matnr"); |
| | | fields.add("maktx"); |
| | | fields.add("batch"); |
| | | fields.add("brand"); |
| | | fields.add("beginningQty"); |
| | | fields.add("endingQty"); |
| | | fields.add("diffQty"); |
| | | fields.add("inQty"); |
| | | fields.add("outQty"); |
| | | // 定义明细流水导出字段 |
| | | List<String> flowFields = new ArrayList<>(); |
| | | flowFields.add("orderNo"); |
| | | flowFields.add("orderTime"); |
| | | flowFields.add("pakinPakoutStatusName"); |
| | | flowFields.add("matnr"); |
| | | flowFields.add("maktx"); |
| | | flowFields.add("batch"); |
| | | flowFields.add("brand"); |
| | | flowFields.add("specs"); |
| | | flowFields.add("qty"); |
| | | flowFields.add("unit"); |
| | | |
| | | return R.ok(exportSupport(details, fields)); |
| | | // 定义汇总导出字段 |
| | | List<String> summaryFields = new ArrayList<>(); |
| | | summaryFields.add("matnr"); |
| | | summaryFields.add("maktx"); |
| | | summaryFields.add("batch"); |
| | | summaryFields.add("brand"); |
| | | summaryFields.add("beginningQty"); |
| | | summaryFields.add("endingQty"); |
| | | summaryFields.add("diffQty"); |
| | | summaryFields.add("inQty"); |
| | | summaryFields.add("outQty"); |
| | | |
| | | // 构建返回数据结构:第一页是明细流水,第二页是汇总 |
| | | java.util.Map<String, Object> result = new java.util.HashMap<>(); |
| | | result.put("detailFlows", exportSupport(detailFlows, flowFields)); |
| | | result.put("details", exportSupport(details, summaryFields)); |
| | | result.put("flowTitles", new String[]{"订单编号", "业务时间", "类型", "物料编码", "物料名称", "批次", "品牌", "规格", "数量", "单位"}); |
| | | result.put("summaryTitles", new String[]{"物料编码", "物料名称", "批次", "品牌", "期初库存", "期末库存", "差异数量", "本期入库", "本期出库"}); |
| | | |
| | | return R.ok(result); |
| | | } |
| | | |
| | | } |
| | |
| | | import com.zy.asrs.entity.result.WrkTraceVo; |
| | | import com.zy.asrs.service.*; |
| | | import com.zy.common.model.DetlDto; |
| | | import com.zy.common.properties.CrossDockProperties; |
| | | import com.zy.common.web.BaseController; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | private ClientService clientService; |
| | | @Autowired |
| | | private CrossDockService crossDockService; |
| | | @Autowired |
| | | private CrossDockProperties crossDockProperties; |
| | | |
| | | @RequestMapping(value = "/order/list/pda/page/auth") |
| | | @ManagerAuth |
| | |
| | | } |
| | | } |
| | | |
| | | // 越库功能:如果是越库入库单,调用越库服务处理 |
| | | if (param.getDocType() != null && param.getDocType().equals(crossDockProperties.getInboundDocTypeId())) { |
| | | // 越库功能:如果勾选了越库订单,无论什么类型的订单都按照越库逻辑处理 |
| | | if (Boolean.TRUE.equals(param.getIsCrossDock())) { |
| | | String outOrderNo = crossDockService.processCrossDockInbound(order, param, getUserId()); |
| | | return R.ok("越库入库单创建成功,已自动生成越库出库单:" + outOrderNo); |
| | | } |
| | |
| | | import com.core.common.R; |
| | | import com.zy.asrs.entity.*; |
| | | import com.zy.asrs.mapper.ReportQueryMapper; |
| | | import com.zy.asrs.service.LocDetlService; |
| | | import com.zy.common.web.BaseController; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | |
| | | @RequestMapping("/report") |
| | | public class ReportQueryController extends BaseController { |
| | | |
| | | @Autowired |
| | | private LocDetlService locDetlService; |
| | | @Autowired |
| | | private ReportQueryMapper reportQueryMapper; |
| | | |
| | |
| | | import com.core.common.SpringUtils; |
| | | import com.zy.asrs.service.DocTypeService; |
| | | import com.zy.asrs.service.OrderSettleService; |
| | | import com.zy.common.properties.CrossDockProperties; |
| | | import com.zy.system.entity.User; |
| | | import com.zy.system.service.UserService; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | |
| | | DocTypeService service = SpringUtils.getBean(DocTypeService.class); |
| | | DocType docType = service.selectById(this.docType); |
| | | if (!Cools.isEmpty(docType)) { |
| | | return String.valueOf(docType.getDocName()); |
| | | String docName = String.valueOf(docType.getDocName()); |
| | | // 如果是越库单据,添加"越库"标识 |
| | | if (isCrossDock()) { |
| | | return docName + "(越库)"; |
| | | } |
| | | return docName; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 判断是否为越库单据 |
| | | * 通过备注字段判断(备注中包含"越库")或通过订单编号判断(关联的越库出库单) |
| | | * |
| | | * @return true: 越库单据, false: 普通单据 |
| | | */ |
| | | public boolean isCrossDock() { |
| | | // 判断备注中是否包含"越库" |
| | | if (!Cools.isEmpty(this.memo) && this.memo.contains("越库")) { |
| | | return true; |
| | | } |
| | | // 判断是否为越库入库单类型(虽然现在所有订单类型都可以是越库,但历史数据可能还是通过类型判断) |
| | | try { |
| | | CrossDockProperties crossDockProperties = SpringUtils.getBean(CrossDockProperties.class); |
| | | if (crossDockProperties != null && this.docType != null |
| | | && this.docType.equals(crossDockProperties.getInboundDocTypeId())) { |
| | | return true; |
| | | } |
| | | } catch (Exception e) { |
| | | // 如果获取配置失败,忽略异常 |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | public String getPayType$() { |
| | | if (null == this.payType) { |
| | | return null; |
| | |
| | | import com.core.common.SpringUtils; |
| | | import com.zy.asrs.service.DocTypeService; |
| | | import com.zy.asrs.service.OrderSettleService; |
| | | import com.zy.common.properties.CrossDockProperties; |
| | | import com.zy.system.entity.User; |
| | | import com.zy.system.service.UserService; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | |
| | | DocTypeService service = SpringUtils.getBean(DocTypeService.class); |
| | | DocType docType = service.selectById(this.docType); |
| | | if (!Cools.isEmpty(docType)) { |
| | | return String.valueOf(docType.getDocName()); |
| | | String docName = String.valueOf(docType.getDocName()); |
| | | // 如果是越库单据,添加"越库"标识 |
| | | if (isCrossDock()) { |
| | | return docName + "(越库)"; |
| | | } |
| | | return docName; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 判断是否为越库单据 |
| | | * 通过订单编号判断(越库出库单以"CK"开头)或通过备注字段判断(备注中包含"越库") |
| | | * |
| | | * @return true: 越库单据, false: 普通单据 |
| | | */ |
| | | public boolean isCrossDock() { |
| | | // 判断订单编号是否以"CK"开头(越库出库单编号格式) |
| | | if (!Cools.isEmpty(this.orderNo) && this.orderNo.startsWith("CK")) { |
| | | return true; |
| | | } |
| | | // 判断备注中是否包含"越库" |
| | | if (!Cools.isEmpty(this.memo) && this.memo.contains("越库")) { |
| | | return true; |
| | | } |
| | | // 判断是否为越库出库单类型 |
| | | try { |
| | | CrossDockProperties crossDockProperties = SpringUtils.getBean(CrossDockProperties.class); |
| | | if (crossDockProperties != null && this.docType != null |
| | | && this.docType.equals(crossDockProperties.getOutboundDocTypeId())) { |
| | | return true; |
| | | } |
| | | } catch (Exception e) { |
| | | // 如果获取配置失败,忽略异常 |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | public String getPayType$() { |
| | | if (null == this.payType) { |
| | | return null; |
| | |
| | | import com.zy.asrs.entity.OrderDetlPakout; |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | |
| | | private String cstmrName; |
| | | |
| | | /** |
| | | * 是否越库订单 |
| | | * true: 勾选越库订单,无论什么类型的订单都按照越库逻辑处理 |
| | | * false: 不勾选,按照正常流程处理 |
| | | */ |
| | | private Boolean isCrossDock; |
| | | |
| | | private List<OrderDetl> orderDetlList; |
| | | private List<OrderDetlPakin> orderDetlPakinList; |
| | | private List<OrderDetlPakout> orderDetlPakoutList; |
| New file |
| | |
| | | package com.zy.asrs.entity.result; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * 月结明细流水VO(订单明细) |
| | | */ |
| | | @Data |
| | | public class MonthlySettleDetailFlowVO implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 订单ID |
| | | */ |
| | | @ApiModelProperty(value = "订单ID") |
| | | private Long orderId; |
| | | |
| | | /** |
| | | * 订单编号 |
| | | */ |
| | | @ApiModelProperty(value = "订单编号") |
| | | private String orderNo; |
| | | |
| | | /** |
| | | * 业务时间 |
| | | */ |
| | | @ApiModelProperty(value = "业务时间") |
| | | private String orderTime; |
| | | |
| | | /** |
| | | * 订单明细ID |
| | | */ |
| | | @ApiModelProperty(value = "订单明细ID") |
| | | private Long orderDetlId; |
| | | |
| | | /** |
| | | * 物料编码 |
| | | */ |
| | | @ApiModelProperty(value = "物料编码") |
| | | private String matnr; |
| | | |
| | | /** |
| | | * 物料名称 |
| | | */ |
| | | @ApiModelProperty(value = "物料名称") |
| | | private String maktx; |
| | | |
| | | /** |
| | | * 批次 |
| | | */ |
| | | @ApiModelProperty(value = "批次") |
| | | private String batch; |
| | | |
| | | /** |
| | | * 品牌 |
| | | */ |
| | | @ApiModelProperty(value = "品牌") |
| | | private String brand; |
| | | |
| | | /** |
| | | * 规格 |
| | | */ |
| | | @ApiModelProperty(value = "规格") |
| | | private String specs; |
| | | |
| | | /** |
| | | * 型号 |
| | | */ |
| | | @ApiModelProperty(value = "型号") |
| | | private String model; |
| | | |
| | | /** |
| | | * 颜色 |
| | | */ |
| | | @ApiModelProperty(value = "颜色") |
| | | private String color; |
| | | |
| | | /** |
| | | * 单位 |
| | | */ |
| | | @ApiModelProperty(value = "单位") |
| | | private String unit; |
| | | |
| | | /** |
| | | * 数量 |
| | | */ |
| | | @ApiModelProperty(value = "数量") |
| | | private BigDecimal qty; |
| | | |
| | | /** |
| | | * 入出库类型(1:入库,2:出库) |
| | | */ |
| | | @ApiModelProperty(value = "入出库类型(1:入库,2:出库)") |
| | | private Integer pakinPakoutStatus; |
| | | |
| | | /** |
| | | * 入出库类型名称 |
| | | */ |
| | | @ApiModelProperty(value = "入出库类型名称") |
| | | private String pakinPakoutStatusName; |
| | | } |
| | |
| | | private MonthlySettle settle; |
| | | |
| | | /** |
| | | * 月结明细列表 |
| | | * 月结明细列表(汇总) |
| | | */ |
| | | @ApiModelProperty(value = "月结明细列表") |
| | | @ApiModelProperty(value = "月结明细列表(汇总)") |
| | | private List<MonthlySettleDetail> details; |
| | | |
| | | /** |
| | | * 月结明细流水列表(订单明细) |
| | | */ |
| | | @ApiModelProperty(value = "月结明细流水列表(订单明细)") |
| | | private List<MonthlySettleDetailFlowVO> detailFlows; |
| | | } |
| | | |
| | |
| | | * 清除出库订单的月结信息 |
| | | */ |
| | | int clearOrderSettleInfoPakout(@Param("settleId") Long settleId); |
| | | |
| | | /** |
| | | * 查询月结明细流水(入库订单明细) |
| | | */ |
| | | List<com.zy.asrs.entity.result.MonthlySettleDetailFlowVO> selectDetailFlowFromPakin(@Param("settleId") Long settleId); |
| | | |
| | | /** |
| | | * 查询月结明细流水(出库订单明细) |
| | | */ |
| | | List<com.zy.asrs.entity.result.MonthlySettleDetailFlowVO> selectDetailFlowFromPakout(@Param("settleId") Long settleId); |
| | | } |
| | | |
| | |
| | | throw new CoolException("月结记录不存在"); |
| | | } |
| | | |
| | | // 关联物料表查询明细 |
| | | // 关联物料表查询明细(汇总) |
| | | List<MonthlySettleDetail> details = monthlySettleDetailMapper.selectDetailWithMat(settleId); |
| | | |
| | | // 查询明细流水(订单明细) |
| | | List<com.zy.asrs.entity.result.MonthlySettleDetailFlowVO> pakinFlows = this.baseMapper.selectDetailFlowFromPakin(settleId); |
| | | List<com.zy.asrs.entity.result.MonthlySettleDetailFlowVO> pakoutFlows = this.baseMapper.selectDetailFlowFromPakout(settleId); |
| | | |
| | | // 合并入库和出库的明细流水 |
| | | List<com.zy.asrs.entity.result.MonthlySettleDetailFlowVO> detailFlows = new java.util.ArrayList<>(); |
| | | if (pakinFlows != null && !pakinFlows.isEmpty()) { |
| | | detailFlows.addAll(pakinFlows); |
| | | } |
| | | if (pakoutFlows != null && !pakoutFlows.isEmpty()) { |
| | | detailFlows.addAll(pakoutFlows); |
| | | } |
| | | |
| | | // 按业务时间和订单编号排序 |
| | | detailFlows.sort((a, b) -> { |
| | | int timeCompare = (a.getOrderTime() != null ? a.getOrderTime() : "").compareTo(b.getOrderTime() != null ? b.getOrderTime() : ""); |
| | | if (timeCompare != 0) { |
| | | return timeCompare; |
| | | } |
| | | return (a.getOrderNo() != null ? a.getOrderNo() : "").compareTo(b.getOrderNo() != null ? b.getOrderNo() : ""); |
| | | }); |
| | | |
| | | MonthlySettleStatisticsVO result = new MonthlySettleStatisticsVO(); |
| | | result.setSettle(settle); |
| | | result.setDetails(details); |
| | | result.setDetailFlows(detailFlows); |
| | | return result; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | wrapper.orderBy("create_time", false); |
| | | List<MonthlySettle> list = this.selectList(wrapper); |
| | | |
| | | EntityWrapper<MonthlySettle> countWrapper = new EntityWrapper<>(); |
| | | countWrapper.eq("is_deleted", 0); |
| | | if (condition != null) { |
| | | if (condition.get("settleNo") != null) { |
| | | countWrapper.like("settle_no", condition.get("settleNo").toString()); |
| | | } |
| | | if (condition.get("status") != null) { |
| | | countWrapper.eq("status", condition.get("status")); |
| | | } |
| | | if (condition.get("startDate") != null && condition.get("endDate") != null) { |
| | | countWrapper.ge("start_date", condition.get("startDate")); |
| | | countWrapper.le("end_date", condition.get("endDate")); |
| | | } |
| | | } |
| | | page.setRecords(list); |
| | | page.setTotal(this.selectCount(countWrapper)); |
| | | return page; |
| | | // 使用分页查询,在数据库层面进行分页,而不是查询所有记录 |
| | | Page<MonthlySettle> resultPage = this.selectPage(page, wrapper); |
| | | return resultPage; |
| | | } |
| | | |
| | | /** |
| | |
| | | WHERE monthly_settle_id = #{settleId} |
| | | </update> |
| | | |
| | | <!-- 查询月结明细流水(入库订单明细) --> |
| | | <select id="selectDetailFlowFromPakin" resultType="com.zy.asrs.entity.result.MonthlySettleDetailFlowVO"> |
| | | SELECT |
| | | molpi.id as orderId, |
| | | molpi.order_no as orderNo, |
| | | molpi.order_time as orderTime, |
| | | modlpi.id as orderDetlId, |
| | | modlpi.matnr, |
| | | modlpi.maktx, |
| | | modlpi.batch, |
| | | modlpi.brand, |
| | | modlpi.specs, |
| | | modlpi.model, |
| | | modlpi.color, |
| | | modlpi.unit, |
| | | modlpi.qty, |
| | | COALESCE(modlpi.pakin_pakout_status, molpi.pakin_pakout_status) as pakinPakoutStatus, |
| | | CASE |
| | | WHEN COALESCE(modlpi.pakin_pakout_status, molpi.pakin_pakout_status) = 1 THEN '入库' |
| | | WHEN COALESCE(modlpi.pakin_pakout_status, molpi.pakin_pakout_status) = 2 THEN '出库' |
| | | ELSE '未知' |
| | | END as pakinPakoutStatusName |
| | | FROM man_order_log_pakin molpi |
| | | INNER JOIN man_order_detl_log_pakin modlpi ON molpi.id = modlpi.order_id |
| | | WHERE molpi.monthly_settle_id = #{settleId} |
| | | AND molpi.status = 1 |
| | | AND COALESCE(modlpi.pakin_pakout_status, molpi.pakin_pakout_status) IN (1, 2) |
| | | ORDER BY molpi.order_time, molpi.order_no, modlpi.id |
| | | </select> |
| | | |
| | | <!-- 查询月结明细流水(出库订单明细) --> |
| | | <select id="selectDetailFlowFromPakout" resultType="com.zy.asrs.entity.result.MonthlySettleDetailFlowVO"> |
| | | SELECT |
| | | molpo.id as orderId, |
| | | molpo.order_no as orderNo, |
| | | molpo.order_time as orderTime, |
| | | modlpo.id as orderDetlId, |
| | | modlpo.matnr, |
| | | modlpo.maktx, |
| | | modlpo.batch, |
| | | modlpo.brand, |
| | | modlpo.specs, |
| | | modlpo.model, |
| | | modlpo.color, |
| | | modlpo.unit, |
| | | modlpo.qty, |
| | | COALESCE(modlpo.pakin_pakout_status, molpo.pakin_pakout_status) as pakinPakoutStatus, |
| | | CASE |
| | | WHEN COALESCE(modlpo.pakin_pakout_status, molpo.pakin_pakout_status) = 1 THEN '入库' |
| | | WHEN COALESCE(modlpo.pakin_pakout_status, molpo.pakin_pakout_status) = 2 THEN '出库' |
| | | ELSE '未知' |
| | | END as pakinPakoutStatusName |
| | | FROM man_order_log_pakout molpo |
| | | INNER JOIN man_order_detl_log_pakout modlpo ON molpo.id = modlpo.order_id |
| | | WHERE molpo.monthly_settle_id = #{settleId} |
| | | AND molpo.status = 1 |
| | | AND COALESCE(modlpo.pakin_pakout_status, molpo.pakin_pakout_status) IN (1, 2) |
| | | ORDER BY molpo.order_time, molpo.order_no, modlpo.id |
| | | </select> |
| | | |
| | | </mapper> |
| | | |
| | | |
| | |
| | | var pageCurr; |
| | | layui.config({ |
| | | base: baseUrl + "/static/layui/lay/modules/" |
| | | }).use(['layer', 'form', 'table', 'util', 'admin', 'laydate', 'laytpl'], function () { |
| | | }).use(['layer', 'form', 'table', 'util', 'admin', 'laydate', 'laytpl', 'element'], function () { |
| | | var $ = layui.jquery; |
| | | var layer = layui.layer; |
| | | var form = layui.form; |
| | |
| | | var admin = layui.admin; |
| | | var layDate = layui.laydate; |
| | | var laytpl = layui.laytpl; |
| | | var element = layui.element; |
| | | |
| | | // 渲染表格 |
| | | tableIns = table.render({ |
| | |
| | | } |
| | | pageCurr = curr; |
| | | // 延迟调用权限控制,确保表格操作列的按钮已经渲染完成 |
| | | // 改为异步请求,避免阻塞页面渲染 |
| | | setTimeout(function() { |
| | | var param = window.location.href.split("?")[1]; |
| | | if (null != param) { |
| | |
| | | url: baseUrl+"/power/menu/"+resourceId+"/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | method: 'GET', |
| | | async: false, |
| | | async: true, // 改为异步,不阻塞页面渲染 |
| | | success: function (res) { |
| | | if (res.code === 200){ |
| | | for(var i = 0, len = res.data.length; i < len; i++) { |
| | |
| | | layer.closeAll('loading'); |
| | | if (res.code === 200) { |
| | | var settle = res.data.settle; |
| | | var details = res.data.details; |
| | | var details = res.data.details || []; |
| | | var detailFlows = res.data.detailFlows || []; |
| | | |
| | | // 先渲染模板 |
| | | var template = $('#detailDialog').html(); |
| | |
| | | content: html, |
| | | area: ['90%', '80%'], |
| | | success: function (layero, dIndex) { |
| | | // 渲染明细表格(对账单格式) |
| | | // 初始化tab组件,使其可以切换 |
| | | element.render('tab', 'monthlySettleDetailTab'); |
| | | |
| | | // 渲染明细流水表格(第一页) |
| | | table.render({ |
| | | elem: '#detailFlowTable', |
| | | data: detailFlows, |
| | | page: true, |
| | | cellMinWidth: 100, |
| | | width: '100%', |
| | | cols: [[ |
| | | {type: 'numbers', title: '序号', width: 60, align: 'center'}, |
| | | {field: 'orderNo', title: '订单编号', width: 150}, |
| | | {field: 'orderTime', title: '业务时间', width: 180}, |
| | | {field: 'pakinPakoutStatusName', title: '类型', width: 80, align: 'center'}, |
| | | {field: 'matnr', title: '物料编码', width: 150}, |
| | | {field: 'maktx', title: '物料名称', width: 200}, |
| | | {field: 'batch', title: '批次', width: 120}, |
| | | {field: 'brand', title: '品牌', width: 120}, |
| | | {field: 'specs', title: '规格', width: 120}, |
| | | { |
| | | field: 'qty', |
| | | align: 'right', |
| | | title: '数量', |
| | | width: 120, |
| | | templet: function (d) { |
| | | var qty = parseFloat(d.qty || 0); |
| | | return qty.toFixed(2); |
| | | } |
| | | }, |
| | | {field: 'unit', title: '单位', width: 80} |
| | | ]] |
| | | }); |
| | | |
| | | // 渲染汇总表格(第二页) |
| | | table.render({ |
| | | elem: '#detailTable', |
| | | data: details, |
| | |
| | | }); |
| | | } |
| | | |
| | | // 动态加载 xlsx.js 库 |
| | | function loadXLSXLibrary(callback) { |
| | | // 如果已经加载,直接执行回调 |
| | | if (typeof XLSX !== 'undefined') { |
| | | callback(); |
| | | return; |
| | | } |
| | | |
| | | // 检查是否正在加载 |
| | | if (window._xlsxLoading) { |
| | | // 如果正在加载,等待加载完成 |
| | | var checkInterval = setInterval(function() { |
| | | if (typeof XLSX !== 'undefined') { |
| | | clearInterval(checkInterval); |
| | | callback(); |
| | | } |
| | | }, 100); |
| | | return; |
| | | } |
| | | |
| | | // 开始加载 |
| | | window._xlsxLoading = true; |
| | | layer.load(2, {content: '正在加载导出库...'}); |
| | | |
| | | var script = document.createElement('script'); |
| | | script.type = 'text/javascript'; |
| | | script.src = 'https://cdn.sheetjs.com/xlsx-0.20.1/package/dist/xlsx.full.min.js'; |
| | | script.onload = function() { |
| | | window._xlsxLoading = false; |
| | | layer.closeAll('loading'); |
| | | callback(); |
| | | }; |
| | | script.onerror = function() { |
| | | window._xlsxLoading = false; |
| | | layer.closeAll('loading'); |
| | | layer.msg('加载导出库失败,请检查网络连接', {icon: 2}); |
| | | }; |
| | | document.head.appendChild(script); |
| | | } |
| | | |
| | | // 导出月结明细 |
| | | function exportDetail(data) { |
| | | layer.confirm('确定导出月结明细 "' + data.settleNo + '" 吗?', { |
| | |
| | | skin: 'layui-layer-admin' |
| | | }, function (i) { |
| | | layer.close(i); |
| | | layer.load(2); |
| | | $.ajax({ |
| | | url: baseUrl + '/monthlySettle/detail/export/' + data.id + '/auth', |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | method: 'POST', |
| | | success: function (res) { |
| | | layer.closeAll('loading'); |
| | | if (res.code === 200) { |
| | | // 定义表头 |
| | | var titles = [ |
| | | '物料编码', |
| | | '物料名称', |
| | | '批次', |
| | | '品牌', |
| | | '期初库存', |
| | | '期末库存', |
| | | '差异数量', |
| | | '本期入库', |
| | | '本期出库' |
| | | ]; |
| | | // 使用 table.exportFile 导出 |
| | | table.exportFile(titles, res.data, 'xls'); |
| | | layer.msg('导出成功', {icon: 1}); |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | } else { |
| | | layer.msg(res.msg || '导出失败', {icon: 2}); |
| | | |
| | | // 先加载 xlsx.js 库,然后再执行导出 |
| | | loadXLSXLibrary(function() { |
| | | layer.load(2); |
| | | $.ajax({ |
| | | url: baseUrl + '/monthlySettle/detail/export/' + data.id + '/auth', |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | method: 'POST', |
| | | success: function (res) { |
| | | layer.closeAll('loading'); |
| | | if (res.code === 200) { |
| | | var exportData = res.data; |
| | | // 第一页:明细流水 |
| | | var flowTitles = exportData.flowTitles || ['订单编号', '业务时间', '类型', '物料编码', '物料名称', '批次', '品牌', '规格', '数量', '单位']; |
| | | var flowData = exportData.detailFlows || []; |
| | | // 第二页:汇总 |
| | | var summaryTitles = exportData.summaryTitles || ['物料编码', '物料名称', '批次', '品牌', '期初库存', '期末库存', '差异数量', '本期入库', '本期出库']; |
| | | var summaryData = exportData.details || []; |
| | | |
| | | try { |
| | | // 使用 xlsx.js 创建包含两个sheet的Excel文件 |
| | | var wb = XLSX.utils.book_new(); |
| | | |
| | | // 创建明细流水sheet |
| | | var flowWS = XLSX.utils.aoa_to_sheet([flowTitles].concat(flowData)); |
| | | XLSX.utils.book_append_sheet(wb, flowWS, "明细流水"); |
| | | |
| | | // 创建汇总sheet |
| | | var summaryWS = XLSX.utils.aoa_to_sheet([summaryTitles].concat(summaryData)); |
| | | XLSX.utils.book_append_sheet(wb, summaryWS, "汇总"); |
| | | |
| | | // 导出Excel文件 |
| | | var fileName = '月结明细_' + data.settleNo + '.xlsx'; |
| | | XLSX.writeFile(wb, fileName); |
| | | |
| | | layer.msg('导出成功', {icon: 1, time: 2000}); |
| | | } catch (e) { |
| | | console.error('导出失败:', e); |
| | | layer.msg('导出失败:' + (e.message || '未知错误'), {icon: 2}); |
| | | } |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | } else { |
| | | layer.msg(res.msg || '导出失败', {icon: 2}); |
| | | } |
| | | }, |
| | | error: function() { |
| | | layer.closeAll('loading'); |
| | | layer.msg('导出失败', {icon: 2}); |
| | | } |
| | | }, |
| | | error: function() { |
| | | layer.closeAll('loading'); |
| | | layer.msg('导出失败', {icon: 2}); |
| | | } |
| | | }); |
| | | }); |
| | | }); |
| | | } |
| | |
| | | } |
| | | pageCurr=curr; |
| | | // 延迟调用权限控制,确保表格操作列的按钮已经渲染完成 |
| | | // 改为异步请求,避免阻塞页面渲染 |
| | | setTimeout(function() { |
| | | var param = window.location.href.split("?")[1]; |
| | | if (null != param) { |
| | |
| | | url: baseUrl+"/power/menu/"+resourceId+"/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | method: 'GET', |
| | | async: false, |
| | | async: true, // 改为异步,不阻塞页面渲染 |
| | | success: function (res) { |
| | | if (res.code === 200){ |
| | | for(var i = 0, len = res.data.length; i < len; i++) { |
| | |
| | | { align: 'center', title: '明细', toolbar: '#tbLook', minWidth: 160, width: 160 }, |
| | | { field: 'createTime$', title: '创建时间', minWidth: 200, width: 200 }, |
| | | { field: 'settle$', align: 'center', title: '状态', templet: '#settleTpl', minWidth: 160, width: 160 }, |
| | | { field: 'monthlySettleNo', align: 'center', title: '月结状态', templet: '#monthlySettleTpl', minWidth: 120, width: 120 }, |
| | | { field: 'memo', align: 'center', title: '备注', hide: true }, |
| | | { align: 'center', title: '操作', toolbar: '#operate', width: 180 } |
| | | ]], |
| | |
| | | { align: 'center', title: '明细', toolbar: '#tbLook', minWidth: 160, width: 160 }, |
| | | { field: 'createTime$', title: '创建时间', minWidth: 200, width: 200 }, |
| | | { field: 'settle$', align: 'center', title: '状态', templet: '#settleTpl', minWidth: 160, width: 160 }, |
| | | { field: 'monthlySettleNo', align: 'center', title: '月结状态', templet: '#monthlySettleTpl', minWidth: 120, width: 120 }, |
| | | { field: 'memo', align: 'center', title: '备注', hide: true }, |
| | | { align: 'center', title: '操作', toolbar: '#operate', width: 120 } |
| | | ]], |
| | |
| | | </div> |
| | | </div> |
| | | <hr class="layui-bg-gray"> |
| | | <div style="overflow-x: auto; width: 100%;"> |
| | | <table id="detailTable" lay-filter="detailTable"></table> |
| | | <div class="layui-tab layui-tab-brief" lay-filter="monthlySettleDetailTab"> |
| | | <ul class="layui-tab-title"> |
| | | <li class="layui-this">明细流水</li> |
| | | <li>汇总</li> |
| | | </ul> |
| | | <div class="layui-tab-content" style="padding: 10px 0;"> |
| | | <div class="layui-tab-item layui-show"> |
| | | <div style="overflow-x: auto; width: 100%;"> |
| | | <table id="detailFlowTable" lay-filter="detailFlowTable"></table> |
| | | </div> |
| | | </div> |
| | | <div class="layui-tab-item"> |
| | | <div style="overflow-x: auto; width: 100%;"> |
| | | <table id="detailTable" lay-filter="detailTable"></table> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </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> |
| | | <!-- xlsx.js 改为按需加载,避免阻塞页面渲染 --> |
| | | <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/monthlySettle/monthlySettle.js" charset="utf-8"></script> |
| | |
| | | {{# } }} |
| | | >{{d.settle$}}</span> |
| | | </script> |
| | | <script type="text/html" id="monthlySettleTpl"> |
| | | {{# if(d.monthlySettleId && d.monthlySettleId > 0){ }} |
| | | <span class="layui-badge layui-bg-orange" title="月结编号:{{d.monthlySettleNo}}">已月结</span> |
| | | {{# } else { }} |
| | | <span class="layui-badge layui-badge-gray">未月结</span> |
| | | {{# } }} |
| | | </script> |
| | | <!-- 订单任务追溯 --> |
| | | <script id="wrkTraceDialog" type="text/html" style="position: relative"> |
| | | <div style="position: absolute; top: 0; left: 0;"> |
| | |
| | | {{# } }} |
| | | >{{d.settle$}}</span> |
| | | </script> |
| | | <script type="text/html" id="monthlySettleTpl"> |
| | | {{# if(d.monthlySettleId && d.monthlySettleId > 0){ }} |
| | | <span class="layui-badge layui-bg-orange" title="月结编号:{{d.monthlySettleNo}}">已月结</span> |
| | | {{# } else { }} |
| | | <span class="layui-badge layui-badge-gray">未月结</span> |
| | | {{# } }} |
| | | </script> |
| | | <!-- 订单任务追溯 --> |
| | | <script id="wrkTraceDialog" type="text/html" style="position: relative"> |
| | | <div style="position: absolute; top: 0; left: 0;"> |