Merge remote-tracking branch 'origin/0.8.X' into 0.8.X
This commit is contained in:
@@ -17,6 +17,8 @@ import com.klp.ems.domain.vo.EnergyCostSummaryVo;
|
||||
import com.klp.ems.domain.vo.WarehouseProductionCoilVo;
|
||||
import com.klp.ems.domain.vo.WarehouseProductionStatVo;
|
||||
import com.klp.ems.domain.vo.WmsEnergyCoilDailyVo;
|
||||
import com.klp.ems.domain.vo.AuxMaterialBreakdownVo;
|
||||
import com.klp.ems.domain.vo.SparePartBreakdownVo;
|
||||
import com.klp.ems.service.IEnergyCostReportService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -111,4 +113,16 @@ public class EnergyCostReportController extends BaseController {
|
||||
}).collect(Collectors.toList());
|
||||
ExcelUtil.exportExcel(exportList, "入场卷成本汇总", CoilTotalMergedExportVo.class, response);
|
||||
}
|
||||
|
||||
@Log(title = "辅料分摊构成", businessType = BusinessType.OTHER)
|
||||
@GetMapping("/material/aux/breakdown")
|
||||
public TableDataInfo<AuxMaterialBreakdownVo> auxMaterialBreakdown(CoilTotalCostBo bo, PageQuery pageQuery) {
|
||||
return reportService.auxMaterialBreakdown(bo, pageQuery);
|
||||
}
|
||||
|
||||
@Log(title = "备件分摊构成", businessType = BusinessType.OTHER)
|
||||
@GetMapping("/material/spare/breakdown")
|
||||
public TableDataInfo<SparePartBreakdownVo> sparePartBreakdown(CoilTotalCostBo bo, PageQuery pageQuery) {
|
||||
return reportService.sparePartBreakdown(bo, pageQuery);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,15 @@ public class WmsEnergyCoilDailyController extends BaseController {
|
||||
return R.ok(statistics);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询待操作钢卷的能源成本详情(单卷)
|
||||
*/
|
||||
@GetMapping("/pendingAction/detail")
|
||||
public R<WmsEnergyCoilDailyVo> pendingActionDetail(@NotNull @RequestParam Long coilId) {
|
||||
WmsEnergyCoilDailyVo detail = coilDailyService.queryPendingActionCoilCostDetail(coilId);
|
||||
return R.ok(detail);
|
||||
}
|
||||
|
||||
@Log(title = "钢卷能源分摊", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(WmsEnergyCoilDailyBo bo, HttpServletResponse response) {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.klp.ems.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 辅料成本分摊构成 Vo
|
||||
*/
|
||||
@Data
|
||||
public class AuxMaterialBreakdownVo {
|
||||
/** 物料编码 */
|
||||
private String itemCode;
|
||||
|
||||
/** 物料名称 */
|
||||
private String itemName;
|
||||
|
||||
/** 规格 */
|
||||
private String spec;
|
||||
|
||||
/** 单位 */
|
||||
private String unit;
|
||||
|
||||
/** 全厂消耗总数量 */
|
||||
private BigDecimal totalQty;
|
||||
|
||||
/** 全厂消耗总金额 */
|
||||
private BigDecimal totalAmount;
|
||||
|
||||
/** 分摊数量 */
|
||||
private BigDecimal allocatedQty;
|
||||
|
||||
/** 分摊金额 */
|
||||
private BigDecimal allocatedAmount;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.klp.ems.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
public class SparePartBreakdownVo {
|
||||
private String itemCode;
|
||||
private String itemName;
|
||||
private String spec;
|
||||
private String unit;
|
||||
|
||||
private BigDecimal totalQty;
|
||||
private BigDecimal totalAmount;
|
||||
|
||||
private BigDecimal allocatedQty;
|
||||
private BigDecimal allocatedAmount;
|
||||
}
|
||||
@@ -84,8 +84,14 @@ public interface WmsEnergyCoilDailyMapper extends BaseMapper<WmsEnergyCoilDaily>
|
||||
/** 入场卷号维度能源+囤积成本汇总(导出) */
|
||||
List<CoilTotalCostVo> selectCoilTotalMergedExport(@Param("bo") CoilTotalCostBo bo);
|
||||
|
||||
/** 辅料分摊构成(按物料汇总,金额与数量按卷的日分摊系数分摊) */
|
||||
IPage<AuxMaterialBreakdownVo> selectAuxMaterialBreakdown(Page<AuxMaterialBreakdownVo> page, @Param("bo") CoilTotalCostBo bo);
|
||||
|
||||
/** 备件分摊构成(按备件汇总,金额与数量按卷的日分摊系数分摊) */
|
||||
IPage<SparePartBreakdownVo> selectSparePartBreakdown(Page<SparePartBreakdownVo> page, @Param("bo") CoilTotalCostBo bo);
|
||||
|
||||
/** 查询待操作钢卷的能源成本(一次性SQL查询) */
|
||||
List<WmsEnergyCoilDailyVo> selectPendingActionCoilCost();
|
||||
List<WmsEnergyCoilDailyVo> selectPendingActionCoilCost(@Param("bo") WmsEnergyCoilDailyBo bo);
|
||||
|
||||
/** 查询待操作钢卷的能源成本统计 */
|
||||
WmsEnergyCoilDailyStatisticsVo selectPendingActionCoilCostStatistics(
|
||||
@@ -93,4 +99,7 @@ public interface WmsEnergyCoilDailyMapper extends BaseMapper<WmsEnergyCoilDaily>
|
||||
@Param("currentCoilNo") String currentCoilNo,
|
||||
@Param("warehouseId") Long warehouseId
|
||||
);
|
||||
|
||||
/** 查询待操作钢卷的能源成本详情(单卷) */
|
||||
WmsEnergyCoilDailyVo selectPendingActionCoilCostDetail(@Param("coilId") Long coilId);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import com.klp.ems.domain.vo.EnergyCostSummaryVo;
|
||||
import com.klp.ems.domain.vo.WarehouseProductionCoilVo;
|
||||
import com.klp.ems.domain.vo.WarehouseProductionStatVo;
|
||||
import com.klp.ems.domain.vo.WmsEnergyCoilDailyVo;
|
||||
import com.klp.ems.domain.vo.AuxMaterialBreakdownVo;
|
||||
import com.klp.ems.domain.vo.SparePartBreakdownVo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -49,4 +51,10 @@ public interface IEnergyCostReportService {
|
||||
|
||||
/** 入场卷号维度能源+囤积综合汇总导出 */
|
||||
java.util.List<CoilTotalCostVo> coilTotalMergedExport(CoilTotalCostBo bo);
|
||||
|
||||
/** 辅料分摊构成(按物料汇总,数量与金额按卷的日分摊系数分摊) */
|
||||
TableDataInfo<AuxMaterialBreakdownVo> auxMaterialBreakdown(CoilTotalCostBo bo, PageQuery pageQuery);
|
||||
|
||||
/** 备件分摊构成(按备件汇总,数量与金额按卷的日分摊系数分摊) */
|
||||
TableDataInfo<SparePartBreakdownVo> sparePartBreakdown(CoilTotalCostBo bo, PageQuery pageQuery);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,11 @@ public interface IWmsEnergyCoilDailyService {
|
||||
*/
|
||||
WmsEnergyCoilDailyStatisticsVo queryPendingActionCoilCostStatistics(String enterCoilNo, String currentCoilNo, Long warehouseId);
|
||||
|
||||
/**
|
||||
* 查询待操作钢卷的能源成本详情(单卷)
|
||||
*/
|
||||
WmsEnergyCoilDailyVo queryPendingActionCoilCostDetail(Long coilId);
|
||||
|
||||
Boolean insertByBo(WmsEnergyCoilDailyBo bo);
|
||||
|
||||
Boolean updateByBo(WmsEnergyCoilDailyBo bo);
|
||||
|
||||
@@ -13,6 +13,8 @@ import com.klp.ems.domain.vo.EnergyCostSummaryVo;
|
||||
import com.klp.ems.domain.vo.WarehouseProductionCoilVo;
|
||||
import com.klp.ems.domain.vo.WarehouseProductionStatVo;
|
||||
import com.klp.ems.domain.vo.WmsEnergyCoilDailyVo;
|
||||
import com.klp.ems.domain.vo.AuxMaterialBreakdownVo;
|
||||
import com.klp.ems.domain.vo.SparePartBreakdownVo;
|
||||
import com.klp.ems.mapper.WmsEnergyCoilDailyMapper;
|
||||
import com.klp.ems.service.IEnergyCostReportService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -142,4 +144,22 @@ public class EnergyCostReportServiceImpl implements IEnergyCostReportService {
|
||||
public java.util.List<CoilTotalCostVo> coilTotalMergedExport(CoilTotalCostBo bo) {
|
||||
return coilDailyMapper.selectCoilTotalMergedExport(bo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<AuxMaterialBreakdownVo> auxMaterialBreakdown(CoilTotalCostBo bo, PageQuery pageQuery) {
|
||||
if (pageQuery.getPageSize() == null) {
|
||||
pageQuery.setPageSize(15);
|
||||
}
|
||||
IPage<AuxMaterialBreakdownVo> page = coilDailyMapper.selectAuxMaterialBreakdown(pageQuery.build(), bo);
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<SparePartBreakdownVo> sparePartBreakdown(CoilTotalCostBo bo, PageQuery pageQuery) {
|
||||
if (pageQuery.getPageSize() == null) {
|
||||
pageQuery.setPageSize(15);
|
||||
}
|
||||
IPage<SparePartBreakdownVo> page = coilDailyMapper.selectSparePartBreakdown(pageQuery.build(), bo);
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class WmsEnergyCoilDailyServiceImpl implements IWmsEnergyCoilDailyService
|
||||
public TableDataInfo<WmsEnergyCoilDailyVo> queryPendingActionCoilCost(WmsEnergyCoilDailyBo bo, PageQuery pageQuery) {
|
||||
// 使用SQL一次性查询待操作钢卷的能源成本
|
||||
// 所有的关联、聚合、计算都在SQL中完成,性能更高
|
||||
List<WmsEnergyCoilDailyVo> resultList = baseMapper.selectPendingActionCoilCost();
|
||||
List<WmsEnergyCoilDailyVo> resultList = baseMapper.selectPendingActionCoilCost(bo);
|
||||
|
||||
if (CollUtil.isEmpty(resultList)) {
|
||||
log.warn("[PendingActionCoilCost] No pending action coils found");
|
||||
@@ -76,6 +76,11 @@ public class WmsEnergyCoilDailyServiceImpl implements IWmsEnergyCoilDailyService
|
||||
return baseMapper.selectPendingActionCoilCostStatistics(enterCoilNo, currentCoilNo, warehouseId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WmsEnergyCoilDailyVo queryPendingActionCoilCostDetail(Long coilId) {
|
||||
return baseMapper.selectPendingActionCoilCostDetail(coilId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean insertByBo(WmsEnergyCoilDailyBo bo) {
|
||||
WmsEnergyCoilDaily add = BeanUtil.toBean(bo, WmsEnergyCoilDaily.class);
|
||||
|
||||
@@ -33,12 +33,12 @@
|
||||
<select id="selectCoilTotalMerged" parameterType="map"
|
||||
resultType="com.klp.ems.domain.vo.CoilTotalCostVo">
|
||||
SELECT
|
||||
aid.enter_coil_no AS enterCoilNo,
|
||||
e.current_coil_no AS currentCoilNo,
|
||||
e.coil_count AS coilCount,
|
||||
e.total_duration AS totalDuration,
|
||||
e.total_consumption AS totalConsumption,
|
||||
e.energy_cost AS totalEnergyCost,
|
||||
m.enter_coil_no AS enterCoilNo,
|
||||
m.current_coil_no AS currentCoilNo,
|
||||
IFNULL(e.coil_count, 0) AS coilCount,
|
||||
IFNULL(e.total_duration, 0) AS totalDuration,
|
||||
IFNULL(e.total_consumption, 0) AS totalConsumption,
|
||||
IFNULL(e.energy_cost, 0) AS totalEnergyCost,
|
||||
IFNULL(s.stock_cost, 0) AS stockCost,
|
||||
IFNULL(x.aux_cost, 0) AS auxCost,
|
||||
IFNULL(x.spare_cost, 0) AS spareCost,
|
||||
@@ -46,47 +46,31 @@
|
||||
IFNULL(s.total_gross_weight, 0) AS totalGrossWeight,
|
||||
(IFNULL(e.energy_cost, 0) + IFNULL(s.stock_cost, 0) + IFNULL(x.aux_cost, 0) + IFNULL(x.spare_cost, 0)) AS totalCost
|
||||
FROM (
|
||||
SELECT enter_coil_no FROM (
|
||||
SELECT DISTINCT c.enter_coil_no
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id
|
||||
WHERE pa.action_status IN (0,1,2)
|
||||
AND pa.warehouse_id IS NOT NULL
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND c.enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.currentCoilNo != null and bo.currentCoilNo != ''">
|
||||
AND pa.current_coil_no LIKE CONCAT('%', #{bo.currentCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND pa.create_time <![CDATA[>=]]> CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND pa.create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
) eids
|
||||
UNION
|
||||
SELECT DISTINCT m.enter_coil_no
|
||||
FROM wms_material_coil m
|
||||
WHERE m.data_type IN (0,1)
|
||||
AND m.del_flag = 0
|
||||
SELECT
|
||||
MAX(enter_coil_no) AS enter_coil_no,
|
||||
current_coil_no,
|
||||
MIN(create_time) AS create_time
|
||||
FROM wms_material_coil
|
||||
WHERE data_type = 1
|
||||
AND del_flag = 0
|
||||
AND status = 0
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND m.enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
AND enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.currentCoilNo != null and bo.currentCoilNo != ''">
|
||||
AND m.current_coil_no LIKE CONCAT('%', #{bo.currentCoilNo}, '%')
|
||||
AND current_coil_no LIKE CONCAT('%', #{bo.currentCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND m.create_time <![CDATA[>=]]> CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
AND create_time <![CDATA[>=]]> CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND m.create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
AND create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
) aid
|
||||
GROUP BY current_coil_no
|
||||
) m
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
c.enter_coil_no,
|
||||
MIN(pa.current_coil_no) AS current_coil_no,
|
||||
pa.current_coil_no,
|
||||
COUNT(DISTINCT pa.coil_id) AS coil_count,
|
||||
SUM(
|
||||
CASE
|
||||
@@ -137,7 +121,7 @@
|
||||
END
|
||||
) AS energy_cost
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id AND c.data_type = 1 AND c.del_flag = 0 AND c.status = 0
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseMeterTime"/>
|
||||
) wmt ON pa.warehouse_id = wmt.warehouse_id
|
||||
@@ -174,6 +158,7 @@
|
||||
GROUP BY pa_pd.warehouse_id
|
||||
) wd_prod ON pa.warehouse_id = wd_prod.warehouse_id
|
||||
WHERE pa.action_status IN (0, 1, 2)
|
||||
and pa.del_flag='0'
|
||||
AND pa.warehouse_id IS NOT NULL
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND c.enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
@@ -187,29 +172,30 @@
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND pa.create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
GROUP BY c.enter_coil_no
|
||||
) e ON aid.enter_coil_no = e.enter_coil_no
|
||||
GROUP BY pa.current_coil_no
|
||||
) e ON m.current_coil_no = e.current_coil_no
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
m.enter_coil_no,
|
||||
current_coil_no,
|
||||
SUM(CASE
|
||||
WHEN cs.unit_cost IS NULL THEN 0
|
||||
ELSE (
|
||||
CASE
|
||||
WHEN IFNULL(m.net_weight, 0) = 0 AND IFNULL(m.gross_weight, 0) > 0 THEN m.gross_weight
|
||||
ELSE IFNULL(m.net_weight, 0)
|
||||
WHEN IFNULL(net_weight, 0) = 0 AND IFNULL(gross_weight, 0) > 0 THEN gross_weight
|
||||
ELSE IFNULL(net_weight, 0)
|
||||
END
|
||||
) * cs.unit_cost
|
||||
END) AS stock_cost,
|
||||
SUM(IFNULL(m.net_weight, 0)) AS total_net_weight,
|
||||
SUM(IFNULL(m.gross_weight, 0)) AS total_gross_weight
|
||||
SUM(IFNULL(net_weight, 0)) AS total_net_weight,
|
||||
SUM(IFNULL(gross_weight, 0)) AS total_gross_weight
|
||||
FROM wms_material_coil m
|
||||
LEFT JOIN wms_cost_standard_config cs
|
||||
ON cs.status = 1
|
||||
AND DATE(m.create_time) >= cs.effective_date
|
||||
AND (cs.expire_date IS NULL OR DATE(m.create_time) <![CDATA[<=]]> cs.expire_date)
|
||||
WHERE m.data_type IN (0,1)
|
||||
WHERE m.data_type = 1
|
||||
AND m.del_flag = 0
|
||||
AND m.status = 0
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND m.enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
</if>
|
||||
@@ -222,11 +208,11 @@
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND m.create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
GROUP BY m.enter_coil_no
|
||||
) s ON aid.enter_coil_no = s.enter_coil_no
|
||||
GROUP BY current_coil_no
|
||||
) s ON m.current_coil_no = s.current_coil_no
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
dm.enter_coil_no,
|
||||
dm.current_coil_no,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN dm.total_minutes > 0
|
||||
@@ -244,7 +230,7 @@
|
||||
FROM (
|
||||
SELECT
|
||||
DATE(pa.create_time) AS day_key,
|
||||
c.enter_coil_no,
|
||||
pa.current_coil_no,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN pa.create_time < COALESCE(pa.complete_time, NOW())
|
||||
@@ -254,7 +240,7 @@
|
||||
) AS coil_minutes,
|
||||
td.total_minutes
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id AND c.data_type = 1 AND c.del_flag = 0 AND c.status = 0
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
DATE(pa_all.create_time) AS day_key,
|
||||
@@ -267,14 +253,28 @@
|
||||
) AS total_minutes
|
||||
FROM wms_coil_pending_action pa_all
|
||||
WHERE pa_all.action_status IN (0,1,2)
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND pa_all.create_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND pa_all.create_time <= CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
GROUP BY DATE(pa_all.create_time)
|
||||
) td ON td.day_key = DATE(pa.create_time)
|
||||
WHERE pa.action_status IN (0,1,2)
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND c.enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.currentCoilNo != null and bo.currentCoilNo != ''">
|
||||
AND pa.current_coil_no LIKE CONCAT('%', #{bo.currentCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND pa.create_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND pa.create_time <= CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
GROUP BY DATE(pa.create_time), c.enter_coil_no, td.total_minutes
|
||||
</if>
|
||||
GROUP BY DATE(pa.create_time), pa.current_coil_no, td.total_minutes
|
||||
) dm
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
@@ -283,8 +283,12 @@
|
||||
FROM eqp_auxiliary_material_change
|
||||
WHERE del_flag = '0'
|
||||
AND change_type = '减少'
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND change_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND change_time <= CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
GROUP BY DATE(change_time)
|
||||
) a ON dm.day_key = a.day_key
|
||||
LEFT JOIN (
|
||||
@@ -294,12 +298,17 @@
|
||||
FROM eqp_spare_parts_change
|
||||
WHERE del_flag = '0'
|
||||
AND change_type = '减少'
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND change_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND change_time <= CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
GROUP BY DATE(change_time)
|
||||
) p ON dm.day_key = p.day_key
|
||||
GROUP BY dm.enter_coil_no
|
||||
) x ON aid.enter_coil_no = x.enter_coil_no
|
||||
GROUP BY dm.current_coil_no
|
||||
) x ON m.current_coil_no = x.current_coil_no
|
||||
WHERE s.current_coil_no IS NOT NULL
|
||||
ORDER BY totalCost DESC
|
||||
LIMIT #{offset}, #{pageSize}
|
||||
</select>
|
||||
@@ -307,54 +316,42 @@
|
||||
<!-- 入场卷号维度能源+囤积成本汇总总数 -->
|
||||
<select id="selectCoilTotalMergedCount" parameterType="com.klp.ems.domain.bo.CoilTotalCostBo"
|
||||
resultType="long">
|
||||
SELECT COUNT(1) FROM (
|
||||
SELECT DISTINCT c.enter_coil_no
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id
|
||||
WHERE pa.action_status IN (0,1,2)
|
||||
AND pa.warehouse_id IS NOT NULL
|
||||
SELECT COUNT(1)
|
||||
FROM (
|
||||
SELECT
|
||||
current_coil_no,
|
||||
MAX(enter_coil_no) AS enter_coil_no,
|
||||
MIN(create_time) AS create_time
|
||||
FROM wms_material_coil
|
||||
WHERE data_type = 1
|
||||
AND del_flag = 0
|
||||
AND status = 0
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND c.enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
AND enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.currentCoilNo != null and bo.currentCoilNo != ''">
|
||||
AND pa.current_coil_no LIKE CONCAT('%', #{bo.currentCoilNo}, '%')
|
||||
AND current_coil_no LIKE CONCAT('%', #{bo.currentCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND pa.create_time <![CDATA[>=]]> CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
AND create_time <![CDATA[>=]]> CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND pa.create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
AND create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
UNION
|
||||
SELECT DISTINCT m.enter_coil_no
|
||||
FROM wms_material_coil m
|
||||
WHERE m.data_type IN (0,1)
|
||||
AND m.del_flag = 0
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND m.enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.currentCoilNo != null and bo.currentCoilNo != ''">
|
||||
AND m.current_coil_no LIKE CONCAT('%', #{bo.currentCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND m.create_time <![CDATA[>=]]> CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND m.create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
) tmp
|
||||
GROUP BY current_coil_no
|
||||
) m
|
||||
</select>
|
||||
|
||||
<!-- 入场卷号维度能源+囤积成本汇总(导出,全部) -->
|
||||
<select id="selectCoilTotalMergedExport" parameterType="com.klp.ems.domain.bo.CoilTotalCostBo"
|
||||
resultType="com.klp.ems.domain.vo.CoilTotalCostVo">
|
||||
SELECT
|
||||
aid.enter_coil_no AS enterCoilNo,
|
||||
e.current_coil_no AS currentCoilNo,
|
||||
e.coil_count AS coilCount,
|
||||
e.total_duration AS totalDuration,
|
||||
e.total_consumption AS totalConsumption,
|
||||
e.energy_cost AS totalEnergyCost,
|
||||
m.enter_coil_no AS enterCoilNo,
|
||||
m.current_coil_no AS currentCoilNo,
|
||||
IFNULL(e.coil_count, 0) AS coilCount,
|
||||
IFNULL(e.total_duration, 0) AS totalDuration,
|
||||
IFNULL(e.total_consumption, 0) AS totalConsumption,
|
||||
IFNULL(e.energy_cost, 0) AS totalEnergyCost,
|
||||
IFNULL(s.stock_cost, 0) AS stockCost,
|
||||
IFNULL(x.aux_cost, 0) AS auxCost,
|
||||
IFNULL(x.spare_cost, 0) AS spareCost,
|
||||
@@ -362,23 +359,31 @@
|
||||
IFNULL(s.total_gross_weight, 0) AS totalGrossWeight,
|
||||
(IFNULL(e.energy_cost, 0) + IFNULL(s.stock_cost, 0) + IFNULL(x.aux_cost, 0) + IFNULL(x.spare_cost, 0)) AS totalCost
|
||||
FROM (
|
||||
SELECT enter_coil_no FROM (
|
||||
SELECT DISTINCT c.enter_coil_no
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id
|
||||
WHERE pa.action_status IN (0,1,2)
|
||||
AND pa.warehouse_id IS NOT NULL
|
||||
) eids
|
||||
UNION
|
||||
SELECT DISTINCT m.enter_coil_no
|
||||
FROM wms_material_coil m
|
||||
WHERE m.data_type IN (0,1)
|
||||
AND m.del_flag = 0
|
||||
) aid
|
||||
SELECT
|
||||
MAX(enter_coil_no) AS enter_coil_no,
|
||||
current_coil_no,
|
||||
MIN(create_time) AS create_time
|
||||
FROM wms_material_coil
|
||||
WHERE data_type IN (0,1)
|
||||
AND del_flag = 0
|
||||
AND status = 0
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.currentCoilNo != null and bo.currentCoilNo != ''">
|
||||
AND current_coil_no LIKE CONCAT('%', #{bo.currentCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND create_time <![CDATA[>=]]> CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
GROUP BY current_coil_no
|
||||
) m
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
c.enter_coil_no,
|
||||
MIN(pa.current_coil_no) AS current_coil_no,
|
||||
pa.current_coil_no,
|
||||
COUNT(DISTINCT pa.coil_id) AS coil_count,
|
||||
SUM(
|
||||
CASE
|
||||
@@ -429,7 +434,7 @@
|
||||
END
|
||||
) AS energy_cost
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id AND c.status = 0
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseMeterTime"/>
|
||||
) wmt ON pa.warehouse_id = wmt.warehouse_id
|
||||
@@ -468,7 +473,7 @@
|
||||
WHERE pa.action_status IN (0, 1, 2)
|
||||
AND pa.warehouse_id IS NOT NULL
|
||||
GROUP BY c.enter_coil_no
|
||||
) e ON aid.enter_coil_no = e.enter_coil_no
|
||||
) e ON m.enter_coil_no = e.enter_coil_no
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
m.enter_coil_no,
|
||||
@@ -490,8 +495,9 @@
|
||||
AND (cs.expire_date IS NULL OR DATE(m.create_time) <![CDATA[<=]]> cs.expire_date)
|
||||
WHERE m.data_type IN (0,1)
|
||||
AND m.del_flag = 0
|
||||
AND m.status = 0
|
||||
GROUP BY m.enter_coil_no
|
||||
) s ON aid.enter_coil_no = s.enter_coil_no
|
||||
) s ON m.enter_coil_no = s.enter_coil_no
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
dm.enter_coil_no,
|
||||
@@ -522,7 +528,7 @@
|
||||
) AS coil_minutes,
|
||||
td.total_minutes
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id AND c.status = 0
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
DATE(pa_all.create_time) AS day_key,
|
||||
@@ -535,13 +541,21 @@
|
||||
) AS total_minutes
|
||||
FROM wms_coil_pending_action pa_all
|
||||
WHERE pa_all.action_status IN (0,1,2)
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND pa_all.create_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND pa_all.create_time <= CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
GROUP BY DATE(pa_all.create_time)
|
||||
) td ON td.day_key = DATE(pa.create_time)
|
||||
WHERE pa.action_status IN (0,1,2)
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND pa.create_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND pa.create_time <= CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
GROUP BY DATE(pa.create_time), c.enter_coil_no, td.total_minutes
|
||||
) dm
|
||||
LEFT JOIN (
|
||||
@@ -551,8 +565,12 @@
|
||||
FROM eqp_auxiliary_material_change
|
||||
WHERE del_flag = '0'
|
||||
AND change_type = '减少'
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND change_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND change_time <= CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
GROUP BY DATE(change_time)
|
||||
) a ON dm.day_key = a.day_key
|
||||
LEFT JOIN (
|
||||
@@ -562,12 +580,16 @@
|
||||
FROM eqp_spare_parts_change
|
||||
WHERE del_flag = '0'
|
||||
AND change_type = '减少'
|
||||
<if test="bo != null and bo.startDate != null and bo.startDate != ''">
|
||||
AND change_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
</if>
|
||||
<if test="bo != null and bo.endDate != null and bo.endDate != ''">
|
||||
AND change_time <= CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
</if>
|
||||
GROUP BY DATE(change_time)
|
||||
) p ON dm.day_key = p.day_key
|
||||
GROUP BY dm.enter_coil_no
|
||||
) x ON aid.enter_coil_no = x.enter_coil_no
|
||||
) x ON m.enter_coil_no = x.enter_coil_no
|
||||
ORDER BY totalCost DESC
|
||||
</select>
|
||||
|
||||
@@ -626,7 +648,7 @@
|
||||
END
|
||||
) AS totalEnergyCost
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id AND c.status = 0
|
||||
LEFT JOIN wms_warehouse w ON pa.warehouse_id = w.warehouse_id
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseMeterTime"/>
|
||||
@@ -741,7 +763,7 @@
|
||||
ELSE 0
|
||||
END AS totalCost
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id AND c.status = 0
|
||||
LEFT JOIN wms_warehouse w ON pa.warehouse_id = w.warehouse_id
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseMeterTime"/>
|
||||
@@ -776,9 +798,11 @@
|
||||
) wmt_pd ON pa_pd.warehouse_id = wmt_pd.warehouse_id
|
||||
WHERE pa_pd.action_status IN (0, 1)
|
||||
AND pa_pd.warehouse_id IS NOT NULL
|
||||
and pa_pd.del_flag=0
|
||||
GROUP BY pa_pd.warehouse_id
|
||||
) wd_prod ON pa.warehouse_id = wd_prod.warehouse_id
|
||||
WHERE pa.action_status IN (0, 1, 2)
|
||||
and pa.del_flag = 0
|
||||
AND pa.warehouse_id IS NOT NULL
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND c.enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
@@ -1019,7 +1043,7 @@
|
||||
ELSE 0
|
||||
END AS unitCost
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil mc ON pa.coil_id = mc.coil_id
|
||||
LEFT JOIN wms_material_coil mc ON pa.coil_id = mc.coil_id AND mc.status = 0
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseMeterTime"/>
|
||||
) wmt ON pa.warehouse_id = wmt.warehouse_id
|
||||
@@ -1135,7 +1159,7 @@
|
||||
ELSE 0
|
||||
END AS totalCost
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil mc ON pa.coil_id = mc.coil_id
|
||||
LEFT JOIN wms_material_coil mc ON pa.coil_id = mc.coil_id AND mc.status = 0
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseMeterTime"/>
|
||||
) wmt ON pa.warehouse_id = wmt.warehouse_id
|
||||
@@ -1379,7 +1403,7 @@
|
||||
ELSE 0
|
||||
END AS totalCost
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil mc ON pa.coil_id = mc.coil_id
|
||||
LEFT JOIN wms_material_coil mc ON pa.coil_id = mc.coil_id AND mc.status = 0
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseMeterTime"/>
|
||||
) wmt ON pa.warehouse_id = wmt.warehouse_id
|
||||
@@ -1719,7 +1743,7 @@
|
||||
wmt.warehouse_start_time AS latestMeterReadStartTime,
|
||||
wmt.warehouse_end_time AS latestMeterReadEndTime
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id AND c.status = 0
|
||||
LEFT JOIN wms_warehouse wh ON pa.warehouse_id = wh.warehouse_id
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseMeterTime"/>
|
||||
@@ -1773,9 +1797,184 @@
|
||||
) wd_count ON pa.warehouse_id = wd_count.warehouse_id
|
||||
WHERE pa.action_status IN (0, 1, 2)
|
||||
AND pa.warehouse_id IS NOT NULL
|
||||
<if test="bo != null and bo.coilId != null">
|
||||
AND pa.coil_id = #{bo.coilId}
|
||||
</if>
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND c.enter_coil_no LIKE CONCAT('%', #{bo.enterCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.currentCoilNo != null and bo.currentCoilNo != ''">
|
||||
AND pa.current_coil_no LIKE CONCAT('%', #{bo.currentCoilNo}, '%')
|
||||
</if>
|
||||
<if test="bo != null and bo.warehouseId != null">
|
||||
AND pa.warehouse_id = #{bo.warehouseId}
|
||||
</if>
|
||||
ORDER BY pa.warehouse_id, pa.create_time DESC
|
||||
</select>
|
||||
|
||||
<!-- 查询待操作钢卷的能源成本详情(单卷) -->
|
||||
<select id="selectPendingActionCoilCostDetail" resultType="com.klp.ems.domain.vo.WmsEnergyCoilDailyVo">
|
||||
SELECT
|
||||
pa.coil_id AS coilId,
|
||||
pa.current_coil_no AS currentCoilNo,
|
||||
c.enter_coil_no AS enterCoilNo,
|
||||
pa.warehouse_id AS warehouseId,
|
||||
wh.warehouse_name AS warehouseName,
|
||||
pa.create_time AS scanTime,
|
||||
-- 结束时间:优先使用库区绑定设备的最近一次抄表结束时间,其次使用钢卷自身的完成时间
|
||||
CASE
|
||||
WHEN pa.complete_time IS NOT NULL THEN pa.complete_time
|
||||
WHEN wmt.warehouse_end_time IS NOT NULL THEN LEAST(wmt.warehouse_end_time, NOW())
|
||||
ELSE NOW()
|
||||
END AS completeTime,
|
||||
-- 生产时长:
|
||||
-- 1) 若库区有抄表时间,则按 创建时间 ~ min(完成时间, 库区最近抄表结束时间)
|
||||
-- 2) 若库区无抄表时间,则仅在钢卷有完成时间时按 创建时间 ~ 完成时间
|
||||
CASE
|
||||
WHEN pa.create_time <![CDATA[<]]> (CASE
|
||||
WHEN pa.complete_time IS NOT NULL THEN pa.complete_time
|
||||
WHEN wmt.warehouse_end_time IS NOT NULL THEN LEAST(wmt.warehouse_end_time, NOW())
|
||||
ELSE NOW()
|
||||
END)
|
||||
THEN TIMESTAMPDIFF(MINUTE,
|
||||
pa.create_time,
|
||||
CASE
|
||||
WHEN pa.complete_time IS NOT NULL THEN pa.complete_time
|
||||
WHEN wmt.warehouse_end_time IS NOT NULL THEN LEAST(wmt.warehouse_end_time, NOW())
|
||||
ELSE NOW()
|
||||
END
|
||||
)
|
||||
ELSE 0
|
||||
END AS productionDuration,
|
||||
-- 分摊比率:按生产时长占库区总生产时长的比例
|
||||
CASE
|
||||
WHEN wd_prod.total_prod_minutes IS NOT NULL
|
||||
AND wd_prod.total_prod_minutes > 0
|
||||
AND pa.create_time <![CDATA[<]]> (CASE
|
||||
WHEN pa.complete_time IS NOT NULL THEN pa.complete_time
|
||||
WHEN wmt.warehouse_end_time IS NOT NULL THEN LEAST(wmt.warehouse_end_time, NOW())
|
||||
ELSE NOW()
|
||||
END)
|
||||
THEN CAST(
|
||||
CASE
|
||||
WHEN pa.create_time <![CDATA[<]]> (CASE
|
||||
WHEN pa.complete_time IS NOT NULL THEN pa.complete_time
|
||||
WHEN wmt.warehouse_end_time IS NOT NULL THEN LEAST(wmt.warehouse_end_time, NOW())
|
||||
ELSE NOW()
|
||||
END)
|
||||
THEN TIMESTAMPDIFF(MINUTE,
|
||||
pa.create_time,
|
||||
CASE
|
||||
WHEN pa.complete_time IS NOT NULL THEN pa.complete_time
|
||||
WHEN wmt.warehouse_end_time IS NOT NULL THEN LEAST(wmt.warehouse_end_time, NOW())
|
||||
ELSE NOW()
|
||||
END
|
||||
)
|
||||
ELSE 0
|
||||
END AS DECIMAL(20,6)
|
||||
) / wd_prod.total_prod_minutes
|
||||
ELSE 0
|
||||
END AS allocationFactor,
|
||||
-- 分摊能耗 = 总能耗 * 分摊比率
|
||||
CASE
|
||||
WHEN wd.total_warehouse_consumption IS NOT NULL
|
||||
AND wd_prod.total_prod_minutes IS NOT NULL
|
||||
AND wd_prod.total_prod_minutes > 0
|
||||
THEN wd.total_warehouse_consumption *
|
||||
(CAST(
|
||||
CASE
|
||||
WHEN pa.create_time <![CDATA[<]]> (CASE
|
||||
WHEN pa.complete_time IS NOT NULL THEN pa.complete_time
|
||||
WHEN wmt.warehouse_end_time IS NOT NULL THEN LEAST(wmt.warehouse_end_time, NOW())
|
||||
ELSE NOW()
|
||||
END)
|
||||
THEN TIMESTAMPDIFF(MINUTE,
|
||||
pa.create_time,
|
||||
CASE
|
||||
WHEN pa.complete_time IS NOT NULL THEN pa.complete_time
|
||||
WHEN wmt.warehouse_end_time IS NOT NULL THEN LEAST(wmt.warehouse_end_time, NOW())
|
||||
ELSE NOW()
|
||||
END
|
||||
)
|
||||
ELSE 0
|
||||
END AS DECIMAL(20,6)
|
||||
) / wd_prod.total_prod_minutes)
|
||||
ELSE 0
|
||||
END AS consumptionQty,
|
||||
-- 分摊成本 = 总成本 * 分摊比率
|
||||
CASE
|
||||
WHEN wd.total_warehouse_cost IS NOT NULL
|
||||
AND wd_prod.total_prod_minutes IS NOT NULL
|
||||
AND wd_prod.total_prod_minutes > 0
|
||||
THEN wd.total_warehouse_cost *
|
||||
(CAST(
|
||||
CASE
|
||||
WHEN pa.create_time <![CDATA[<]]> (CASE
|
||||
WHEN pa.complete_time IS NOT NULL THEN pa.complete_time
|
||||
WHEN wmt.warehouse_end_time IS NOT NULL THEN LEAST(wmt.warehouse_end_time, NOW())
|
||||
ELSE NOW()
|
||||
END)
|
||||
THEN TIMESTAMPDIFF(MINUTE,
|
||||
pa.create_time,
|
||||
CASE
|
||||
WHEN pa.complete_time IS NOT NULL THEN pa.complete_time
|
||||
WHEN wmt.warehouse_end_time IS NOT NULL THEN LEAST(wmt.warehouse_end_time, NOW())
|
||||
ELSE NOW()
|
||||
END
|
||||
)
|
||||
ELSE 0
|
||||
END AS DECIMAL(20,6)
|
||||
) / wd_prod.total_prod_minutes)
|
||||
ELSE 0
|
||||
END AS costAmount,
|
||||
wmt.warehouse_start_time AS latestMeterReadStartTime,
|
||||
wmt.warehouse_end_time AS latestMeterReadEndTime
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id AND c.status = 0
|
||||
LEFT JOIN wms_warehouse wh ON pa.warehouse_id = wh.warehouse_id
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseMeterTime"/>
|
||||
) wmt ON pa.warehouse_id = wmt.warehouse_id
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseCost"/>
|
||||
) wd ON pa.warehouse_id = wd.warehouse_id
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
pa_pd.warehouse_id,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN wmt_pd.warehouse_end_time IS NOT NULL
|
||||
AND pa_pd.create_time <![CDATA[<]]> COALESCE(pa_pd.complete_time, wmt_pd.warehouse_end_time)
|
||||
THEN TIMESTAMPDIFF(MINUTE,
|
||||
pa_pd.create_time,
|
||||
COALESCE(pa_pd.complete_time, wmt_pd.warehouse_end_time)
|
||||
)
|
||||
WHEN wmt_pd.warehouse_end_time IS NULL
|
||||
AND pa_pd.complete_time IS NOT NULL
|
||||
AND pa_pd.create_time <![CDATA[<]]> pa_pd.complete_time
|
||||
THEN TIMESTAMPDIFF(MINUTE,
|
||||
pa_pd.create_time,
|
||||
pa_pd.complete_time
|
||||
)
|
||||
ELSE 0
|
||||
END
|
||||
) AS total_prod_minutes
|
||||
FROM wms_coil_pending_action pa_pd
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseMeterTime"/>
|
||||
) wmt_pd ON pa_pd.warehouse_id = wmt_pd.warehouse_id
|
||||
WHERE pa_pd.action_status IN (0, 1)
|
||||
AND pa_pd.warehouse_id IS NOT NULL
|
||||
AND wmt_pd.warehouse_end_time IS NOT NULL
|
||||
GROUP BY pa_pd.warehouse_id
|
||||
) wd_prod ON pa.warehouse_id = wd_prod.warehouse_id
|
||||
WHERE pa.coil_id = #{coilId}
|
||||
AND pa.action_status IN (0, 1, 2)
|
||||
AND pa.warehouse_id IS NOT NULL
|
||||
AND pa.del_flag = 0
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<!-- 查询待操作钢卷的能源成本统计(按时间段分摊) -->
|
||||
<select id="selectPendingActionCoilCostStatistics" resultType="com.klp.ems.domain.vo.WmsEnergyCoilDailyStatisticsVo">
|
||||
SELECT
|
||||
@@ -1918,7 +2117,7 @@
|
||||
MIN(wmt.warehouse_start_time) AS latestMeterReadStartTime,
|
||||
MAX(wmt.warehouse_end_time) AS latestMeterReadEndTime
|
||||
FROM wms_coil_pending_action pa
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id
|
||||
LEFT JOIN wms_material_coil c ON pa.coil_id = c.coil_id AND c.status = 0
|
||||
LEFT JOIN wms_warehouse wh ON pa.warehouse_id = wh.warehouse_id
|
||||
LEFT JOIN (
|
||||
<include refid="WarehouseMeterTime"/>
|
||||
@@ -2034,4 +2233,181 @@
|
||||
ORDER BY c.calc_date DESC, c.energy_cost_id DESC
|
||||
</select>
|
||||
|
||||
<!-- 辅料分摊构成(按物料汇总,数量与金额按卷的日分摊系数分摊) -->
|
||||
<select id="selectAuxMaterialBreakdown" resultType="com.klp.ems.domain.vo.AuxMaterialBreakdownVo">
|
||||
SELECT
|
||||
CAST(t.auxiliary_id AS CHAR) AS itemCode,
|
||||
t.item_name AS itemName,
|
||||
t.spec AS spec,
|
||||
t.unit AS unit,
|
||||
SUM(t.total_qty) AS totalQty,
|
||||
SUM(t.total_amount) AS totalAmount,
|
||||
SUM(t.allocated_qty) AS allocatedQty,
|
||||
SUM(t.allocated_amount) AS allocatedAmount
|
||||
FROM (
|
||||
SELECT
|
||||
adc.day_key,
|
||||
adc.auxiliary_id,
|
||||
adc.item_name,
|
||||
adc.spec,
|
||||
adc.unit,
|
||||
adc.total_qty,
|
||||
adc.total_amount,
|
||||
CASE
|
||||
WHEN dtm.total_minutes > 0 AND cdm.coil_minutes IS NOT NULL AND cdm.coil_minutes > 0
|
||||
THEN adc.total_qty * (cdm.coil_minutes / dtm.total_minutes)
|
||||
ELSE 0
|
||||
END AS allocated_qty,
|
||||
CASE
|
||||
WHEN dtm.total_minutes > 0 AND cdm.coil_minutes IS NOT NULL AND cdm.coil_minutes > 0
|
||||
THEN adc.total_amount * (cdm.coil_minutes / dtm.total_minutes)
|
||||
ELSE 0
|
||||
END AS allocated_amount
|
||||
FROM (
|
||||
SELECT
|
||||
DATE(amc.change_time) AS day_key,
|
||||
am.auxiliary_id,
|
||||
am.auxiliary_name AS item_name,
|
||||
am.auxiliary_model AS spec,
|
||||
am.unit,
|
||||
SUM(ABS(amc.change_quantity)) AS total_qty,
|
||||
SUM(ABS(IFNULL(amc.amount, 0))) AS total_amount
|
||||
FROM eqp_auxiliary_material_change amc
|
||||
JOIN eqp_auxiliary_material am ON amc.auxiliary_id = am.auxiliary_id
|
||||
WHERE amc.del_flag = '0'
|
||||
AND amc.change_type = '减少'
|
||||
AND amc.change_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
AND amc.change_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
GROUP BY DATE(amc.change_time), am.auxiliary_id, am.auxiliary_name, am.auxiliary_model, am.unit
|
||||
) adc
|
||||
JOIN (
|
||||
SELECT
|
||||
DATE(pa_all.create_time) AS day_key,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN pa_all.create_time <![CDATA[<]]> COALESCE(pa_all.complete_time, NOW())
|
||||
THEN TIMESTAMPDIFF(MINUTE, pa_all.create_time, COALESCE(pa_all.complete_time, NOW()))
|
||||
ELSE 0
|
||||
END
|
||||
) AS total_minutes
|
||||
FROM wms_coil_pending_action pa_all
|
||||
WHERE pa_all.action_status IN (0,1,2)
|
||||
AND pa_all.create_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
AND pa_all.create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
GROUP BY DATE(pa_all.create_time)
|
||||
) dtm ON adc.day_key = dtm.day_key
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
c.enter_coil_no,
|
||||
DATE(pa.create_time) AS day_key,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN pa.create_time <![CDATA[<]]> COALESCE(pa.complete_time, NOW())
|
||||
THEN TIMESTAMPDIFF(MINUTE, pa.create_time, COALESCE(pa.complete_time, NOW()))
|
||||
ELSE 0
|
||||
END
|
||||
) AS coil_minutes
|
||||
FROM wms_coil_pending_action pa
|
||||
JOIN wms_material_coil c ON pa.coil_id = c.coil_id AND c.status = 0
|
||||
WHERE pa.action_status IN (0,1,2)
|
||||
AND pa.create_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
AND pa.create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND c.enter_coil_no = #{bo.enterCoilNo}
|
||||
</if>
|
||||
GROUP BY c.enter_coil_no, DATE(pa.create_time)
|
||||
) cdm ON adc.day_key = cdm.day_key
|
||||
) t
|
||||
GROUP BY t.auxiliary_id, t.item_name, t.spec, t.unit
|
||||
ORDER BY allocatedAmount DESC
|
||||
</select>
|
||||
|
||||
<!-- 备件分摊构成(按备件汇总,数量与金额按卷的日分摊系数分摊) -->
|
||||
<select id="selectSparePartBreakdown" resultType="com.klp.ems.domain.vo.SparePartBreakdownVo">
|
||||
SELECT
|
||||
CAST(t.part_id AS CHAR) AS itemCode,
|
||||
t.item_name AS itemName,
|
||||
t.spec AS spec,
|
||||
t.unit AS unit,
|
||||
SUM(t.total_qty) AS totalQty,
|
||||
SUM(t.total_amount) AS totalAmount,
|
||||
SUM(t.allocated_qty) AS allocatedQty,
|
||||
SUM(t.allocated_amount) AS allocatedAmount
|
||||
FROM (
|
||||
SELECT
|
||||
sdc.day_key,
|
||||
sdc.part_id,
|
||||
sdc.item_name,
|
||||
sdc.spec,
|
||||
sdc.unit,
|
||||
sdc.total_qty,
|
||||
sdc.total_amount,
|
||||
CASE
|
||||
WHEN dtm.total_minutes > 0 AND cdm.coil_minutes IS NOT NULL AND cdm.coil_minutes > 0
|
||||
THEN sdc.total_qty * (cdm.coil_minutes / dtm.total_minutes)
|
||||
ELSE 0
|
||||
END AS allocated_qty,
|
||||
CASE
|
||||
WHEN dtm.total_minutes > 0 AND cdm.coil_minutes IS NOT NULL AND cdm.coil_minutes > 0
|
||||
THEN sdc.total_amount * (cdm.coil_minutes / dtm.total_minutes)
|
||||
ELSE 0
|
||||
END AS allocated_amount
|
||||
FROM (
|
||||
SELECT
|
||||
DATE(spc.change_time) AS day_key,
|
||||
sp.part_id,
|
||||
sp.part_name AS item_name,
|
||||
sp.model AS spec,
|
||||
sp.unit,
|
||||
SUM(ABS(spc.change_quantity)) AS total_qty,
|
||||
SUM(ABS(IFNULL(spc.amount, 0))) AS total_amount
|
||||
FROM eqp_spare_parts_change spc
|
||||
JOIN eqp_spare_part sp ON spc.part_id = sp.part_id
|
||||
WHERE spc.del_flag = '0'
|
||||
AND spc.change_type = '减少'
|
||||
AND spc.change_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
AND spc.change_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
GROUP BY DATE(spc.change_time), sp.part_id, sp.part_name, sp.model, sp.unit
|
||||
) sdc
|
||||
JOIN (
|
||||
SELECT
|
||||
DATE(pa_all.create_time) AS day_key,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN pa_all.create_time <![CDATA[<]]> COALESCE(pa_all.complete_time, NOW())
|
||||
THEN TIMESTAMPDIFF(MINUTE, pa_all.create_time, COALESCE(pa_all.complete_time, NOW()))
|
||||
ELSE 0
|
||||
END
|
||||
) AS total_minutes
|
||||
FROM wms_coil_pending_action pa_all
|
||||
WHERE pa_all.action_status IN (0,1,2)
|
||||
AND pa_all.create_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
AND pa_all.create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
GROUP BY DATE(pa_all.create_time)
|
||||
) dtm ON sdc.day_key = dtm.day_key
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
c.enter_coil_no,
|
||||
DATE(pa.create_time) AS day_key,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN pa.create_time <![CDATA[<]]> COALESCE(pa.complete_time, NOW())
|
||||
THEN TIMESTAMPDIFF(MINUTE, pa.create_time, COALESCE(pa.complete_time, NOW()))
|
||||
ELSE 0
|
||||
END
|
||||
) AS coil_minutes
|
||||
FROM wms_coil_pending_action pa
|
||||
JOIN wms_material_coil c ON pa.coil_id = c.coil_id AND c.status = 0
|
||||
WHERE pa.action_status IN (0,1,2)
|
||||
AND pa.create_time >= CONCAT(#{bo.startDate}, ' 00:00:00')
|
||||
AND pa.create_time <![CDATA[<=]]> CONCAT(#{bo.endDate}, ' 23:59:59')
|
||||
<if test="bo != null and bo.enterCoilNo != null and bo.enterCoilNo != ''">
|
||||
AND c.enter_coil_no = #{bo.enterCoilNo}
|
||||
</if>
|
||||
GROUP BY c.enter_coil_no, DATE(pa.create_time)
|
||||
) cdm ON sdc.day_key = cdm.day_key
|
||||
) t
|
||||
GROUP BY t.part_id, t.item_name, t.spec, t.unit
|
||||
ORDER BY allocatedAmount DESC
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -60,3 +60,21 @@ export function exportCoilTotalMerged(query) {
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
// 辅料分摊构成(按物料汇总)
|
||||
export function fetchAuxMaterialBreakdown(query) {
|
||||
return request({
|
||||
url: '/ems/energy/report/material/aux/breakdown',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 备件分摊构成(按备件汇总)
|
||||
export function fetchSparePartBreakdown(query) {
|
||||
return request({
|
||||
url: '/ems/energy/report/material/spare/breakdown',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
496
klp-ui/src/views/ems/cost/auxAllocation.vue
Normal file
496
klp-ui/src/views/ems/cost/auxAllocation.vue
Normal file
@@ -0,0 +1,496 @@
|
||||
<template>
|
||||
<div class="material-allocation-page">
|
||||
<el-card class="search-card">
|
||||
<el-form :model="queryParams" inline label-width="100px" size="small">
|
||||
<el-form-item label="入场卷号" required>
|
||||
<el-input v-model="queryParams.enterCoilNo" placeholder="必填,支持模糊"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="当前卷号">
|
||||
<el-input v-model="queryParams.currentCoilNo" placeholder="支持模糊"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始日期">
|
||||
<el-date-picker v-model="queryParams.startDate" type="date" value-format="yyyy-MM-dd" placeholder="开始日期"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束日期">
|
||||
<el-date-picker v-model="queryParams.endDate" type="date" value-format="yyyy-MM-dd" placeholder="结束日期"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch">查询</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-row :gutter="16" class="stats-row">
|
||||
<el-col :xs="24" :sm="12" :md="6" :lg="5">
|
||||
<div class="stat-card">
|
||||
<div class="label">辅料分摊合计</div>
|
||||
<div class="value">¥ {{ formatNumber(auxSummary.totalAuxCost, 2) }}</div>
|
||||
<div class="desc">按日池 + 时长占比分摊</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6" :lg="5">
|
||||
<div class="stat-card">
|
||||
<div class="label">卷数</div>
|
||||
<div class="value">{{ mergedTotal }}</div>
|
||||
<div class="desc">当前查询条件下</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6" :lg="5">
|
||||
<div class="stat-card">
|
||||
<div class="label">种类数</div>
|
||||
<div class="value">{{ breakdownSummary.kinds }}</div>
|
||||
<div class="desc">按物料聚合</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6" :lg="5">
|
||||
<div class="stat-card">
|
||||
<div class="label">分摊数量合计</div>
|
||||
<div class="value">{{ formatNumber(breakdownSummary.totalAllocatedQty, 2) }}</div>
|
||||
<div class="desc">数量按分摊系数切分</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6" :lg="4">
|
||||
<div class="stat-card">
|
||||
<div class="label">分摊金额合计</div>
|
||||
<div class="value">¥ {{ formatNumber(breakdownSummary.totalAllocatedAmount, 2) }}</div>
|
||||
<div class="desc">金额按分摊系数切分</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="title">分摊数据</div>
|
||||
<div class="actions">
|
||||
<el-button size="mini" type="primary" icon="el-icon-download" @click="exportSummary">导出汇总</el-button>
|
||||
<el-button size="mini" icon="el-icon-document" @click="exportDetailCsv" :disabled="detailRows.length === 0">导出明细CSV</el-button>
|
||||
<el-button size="mini" icon="el-icon-document" @click="exportBreakdownCsv" :disabled="breakdownRows.length === 0">导出构成CSV</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sub-title">辅料消耗构成</div>
|
||||
<el-table :data="breakdownRows" border stripe v-loading="breakdownLoading">
|
||||
<el-table-column prop="itemCode" label="编码" width="140"></el-table-column>
|
||||
<el-table-column prop="itemName" label="名称" min-width="160"></el-table-column>
|
||||
<el-table-column prop="spec" label="规格" min-width="140"></el-table-column>
|
||||
<el-table-column prop="unit" label="单位" width="80"></el-table-column>
|
||||
<el-table-column prop="totalQty" label="全厂消耗数量" width="140" align="right">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.totalQty, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalAmount" label="全厂消耗金额(元)" width="160" align="right">
|
||||
<template slot-scope="scope">¥ {{ formatNumber(scope.row.totalAmount, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="allocatedQty" label="分摊数量" width="120" align="right">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.allocatedQty, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="allocatedAmount" label="分摊金额(元)" width="150" align="right">
|
||||
<template slot-scope="scope">¥ {{ formatNumber(scope.row.allocatedAmount, 2) }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="breakdownTotal > 0"
|
||||
:total="breakdownTotal"
|
||||
:page.sync="breakdownQuery.pageNum"
|
||||
:limit.sync="breakdownQuery.pageSize"
|
||||
@pagination="loadBreakdown"
|
||||
/>
|
||||
|
||||
<div class="sub-title" style="margin-top: 16px;">辅料成本分摊</div>
|
||||
<el-table :data="mergedRows" border stripe v-loading="loading">
|
||||
<el-table-column prop="enterCoilNo" label="入场卷号"></el-table-column>
|
||||
<el-table-column prop="currentCoilNo" label="当前卷号"></el-table-column>
|
||||
<el-table-column prop="auxCost" label="辅料成本">
|
||||
<template slot-scope="scope">¥ {{ formatNumber(scope.row.auxCost, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalNetWeight" label="净重">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.totalNetWeight, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalGrossWeight" label="毛重">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.totalGrossWeight, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="mini" @click="openDetail(scope.row)">分摊明细</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="mergedTotal > 0"
|
||||
:total="mergedTotal"
|
||||
:page.sync="mergedQuery.pageNum"
|
||||
:limit.sync="mergedQuery.pageSize"
|
||||
@pagination="loadMerged"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<el-dialog title="辅料分摊明细(按日)" :visible.sync="detailVisible" width="80%" :close-on-click-modal="false">
|
||||
<div class="detail-hint">入场卷号:{{ detailEnterCoilNo }}</div>
|
||||
<el-table :data="detailRows" stripe border max-height="420" v-loading="detailLoading">
|
||||
<el-table-column prop="day" label="日期" width="120"></el-table-column>
|
||||
<el-table-column prop="auxPoolAmount" label="当日辅料池(元)" width="140">
|
||||
<template slot-scope="scope">¥ {{ formatNumber(scope.row.auxPoolAmount, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalMinutes" label="全厂分钟" width="120">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.totalMinutes, 0) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="coilMinutes" label="卷分钟" width="120">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.coilMinutes, 0) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="factor" label="占比" width="100">
|
||||
<template slot-scope="scope">{{ toPercent(scope.row.factor) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="allocatedAuxCost" label="分摊辅料(元)" width="140">
|
||||
<template slot-scope="scope">¥ {{ formatNumber(scope.row.allocatedAuxCost, 2) }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="detailVisible = false">关 闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchCoilTotalMerged, exportCoilTotalMerged, fetchAuxMaterialBreakdown } from '@/api/ems/energyCostReport'
|
||||
|
||||
export default {
|
||||
name: 'AuxCostAllocation',
|
||||
data() {
|
||||
return {
|
||||
queryParams: {
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
startDate: undefined,
|
||||
endDate: undefined
|
||||
},
|
||||
mergedQuery: {
|
||||
pageNum: 1,
|
||||
pageSize: 50
|
||||
},
|
||||
loading: false,
|
||||
mergedRows: [],
|
||||
mergedTotal: 0,
|
||||
auxSummary: {
|
||||
totalAuxCost: 0
|
||||
},
|
||||
detailVisible: false,
|
||||
detailLoading: false,
|
||||
detailEnterCoilNo: '',
|
||||
detailRows: [],
|
||||
breakdownLoading: false,
|
||||
breakdownRows: [],
|
||||
breakdownTotal: 0,
|
||||
breakdownQuery: {
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
},
|
||||
breakdownSummary: {
|
||||
kinds: 0,
|
||||
totalAllocatedQty: 0,
|
||||
totalAllocatedAmount: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.handleSearch()
|
||||
},
|
||||
methods: {
|
||||
handleSearch() {
|
||||
this.mergedQuery.pageNum = 1
|
||||
this.breakdownQuery.pageNum = 1
|
||||
this.loadMerged()
|
||||
this.loadBreakdown()
|
||||
},
|
||||
handleReset() {
|
||||
this.queryParams = {
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
startDate: undefined,
|
||||
endDate: undefined
|
||||
}
|
||||
this.mergedQuery.pageNum = 1
|
||||
this.breakdownQuery.pageNum = 1
|
||||
this.mergedRows = []
|
||||
this.mergedTotal = 0
|
||||
this.auxSummary = { totalAuxCost: 0 }
|
||||
this.detailRows = []
|
||||
this.breakdownRows = []
|
||||
this.breakdownTotal = 0
|
||||
this.breakdownSummary = { kinds: 0, totalAllocatedQty: 0, totalAllocatedAmount: 0 }
|
||||
this.handleSearch()
|
||||
},
|
||||
loadMerged() {
|
||||
const params = {
|
||||
...this.queryParams,
|
||||
pageNum: this.mergedQuery.pageNum,
|
||||
pageSize: this.mergedQuery.pageSize
|
||||
}
|
||||
this.loading = true
|
||||
fetchCoilTotalMerged(params).then(res => {
|
||||
this.mergedRows = res.rows || []
|
||||
this.mergedTotal = res.total || 0
|
||||
const rows = this.mergedRows || []
|
||||
this.auxSummary = {
|
||||
totalAuxCost: rows.reduce((sum, r) => sum + (Number(r.auxCost) || 0), 0)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
loadBreakdown() {
|
||||
const params = {
|
||||
...this.queryParams,
|
||||
pageNum: this.breakdownQuery.pageNum,
|
||||
pageSize: this.breakdownQuery.pageSize
|
||||
}
|
||||
this.breakdownLoading = true
|
||||
fetchAuxMaterialBreakdown(params).then(res => {
|
||||
this.breakdownRows = res.rows || []
|
||||
this.breakdownTotal = res.total || 0
|
||||
const rows = this.breakdownRows || []
|
||||
this.breakdownSummary = {
|
||||
kinds: this.breakdownTotal || rows.length || 0,
|
||||
totalAllocatedQty: rows.reduce((sum, r) => sum + (Number(r.allocatedQty) || 0), 0),
|
||||
totalAllocatedAmount: rows.reduce((sum, r) => sum + (Number(r.allocatedAmount) || 0), 0)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.breakdownLoading = false
|
||||
})
|
||||
},
|
||||
exportBreakdownCsv() {
|
||||
const headers = ['编码', '名称', '规格', '单位', '全厂消耗数量', '全厂消耗金额(元)', '分摊数量', '分摊金额(元)']
|
||||
const lines = [headers.join(',')]
|
||||
;(this.breakdownRows || []).forEach(r => {
|
||||
const line = [
|
||||
this.csvCell(r.itemCode),
|
||||
this.csvCell(r.itemName),
|
||||
this.csvCell(r.spec),
|
||||
this.csvCell(r.unit),
|
||||
this.csvCell(r.totalQty),
|
||||
this.csvCell(r.totalAmount),
|
||||
this.csvCell(r.allocatedQty),
|
||||
this.csvCell(r.allocatedAmount)
|
||||
].join(',')
|
||||
lines.push(line)
|
||||
})
|
||||
const csv = lines.join('\n')
|
||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = `aux_allocation_breakdown_${this.queryParams.enterCoilNo || 'all'}.csv`
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
},
|
||||
openDetail(row) {
|
||||
if (!row || !row.enterCoilNo) return
|
||||
this.detailEnterCoilNo = row.enterCoilNo
|
||||
this.detailVisible = true
|
||||
this.buildDetailByDay(row.enterCoilNo)
|
||||
},
|
||||
buildDetailByDay(enterCoilNo) {
|
||||
// 明细口径:按天切分(A 方案),当日池金额 * (卷分钟/全厂分钟)
|
||||
// 当前后端 merged 接口仅返回汇总后的 auxCost/spareCost,不返回按日池/分钟细节。
|
||||
// 因此这里采用前端“可解释明细”的方式:
|
||||
// - 先拿同查询条件下的 merged 列表(分页内),并仅对选中卷号展示其 auxCost,总额按单行 auxCost 展示为 1 行。
|
||||
// 若后续补充后端明细接口,可在此替换为真实的按日明细。
|
||||
this.detailLoading = true
|
||||
const params = {
|
||||
...this.queryParams,
|
||||
enterCoilNo,
|
||||
pageNum: 1,
|
||||
pageSize: 1
|
||||
}
|
||||
fetchCoilTotalMerged(params).then(res => {
|
||||
const row = (res.rows || [])[0]
|
||||
const total = Number(row?.auxCost) || 0
|
||||
this.detailRows = [
|
||||
{
|
||||
day: this.queryParams.startDate && this.queryParams.endDate ? `${this.queryParams.startDate} ~ ${this.queryParams.endDate}` : '-',
|
||||
auxPoolAmount: null,
|
||||
totalMinutes: null,
|
||||
coilMinutes: null,
|
||||
factor: null,
|
||||
allocatedAuxCost: total
|
||||
}
|
||||
]
|
||||
}).finally(() => {
|
||||
this.detailLoading = false
|
||||
})
|
||||
},
|
||||
exportSummary() {
|
||||
const params = { ...this.queryParams }
|
||||
exportCoilTotalMerged(params).then(res => {
|
||||
const blob = new Blob([res], { type: 'application/vnd.ms-excel' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = 'aux_cost_allocation_summary.xlsx'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
})
|
||||
},
|
||||
exportDetailCsv() {
|
||||
// 仅导出当前弹窗可见的 detailRows
|
||||
const headers = ['日期', '当日辅料池(元)', '全厂分钟', '卷分钟', '占比', '分摊辅料(元)']
|
||||
const lines = [headers.join(',')]
|
||||
;(this.detailRows || []).forEach(r => {
|
||||
const line = [
|
||||
this.csvCell(r.day),
|
||||
this.csvCell(r.auxPoolAmount),
|
||||
this.csvCell(r.totalMinutes),
|
||||
this.csvCell(r.coilMinutes),
|
||||
this.csvCell(r.factor),
|
||||
this.csvCell(r.allocatedAuxCost)
|
||||
].join(',')
|
||||
lines.push(line)
|
||||
})
|
||||
const csv = lines.join('\n')
|
||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = `aux_cost_allocation_detail_${this.detailEnterCoilNo || ''}.csv`
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
},
|
||||
csvCell(val) {
|
||||
if (val === null || val === undefined) return ''
|
||||
const s = String(val)
|
||||
if (s.includes(',') || s.includes('"') || s.includes('\n')) {
|
||||
return '"' + s.replace(/"/g, '""') + '"'
|
||||
}
|
||||
return s
|
||||
},
|
||||
formatNumber(val, digits = 2) {
|
||||
if (val === null || val === undefined) return '-'
|
||||
const num = Number(val)
|
||||
if (Number.isNaN(num)) return String(val)
|
||||
return num.toFixed(digits)
|
||||
},
|
||||
toPercent(val) {
|
||||
if (val === null || val === undefined) return '-'
|
||||
const num = Number(val)
|
||||
if (Number.isNaN(num)) return String(val)
|
||||
return (num * 100).toFixed(2) + '%'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.material-allocation-page {
|
||||
padding: 16px 20px;
|
||||
|
||||
.search-card {
|
||||
margin-bottom: 16px;
|
||||
:deep(.el-card__body) {
|
||||
padding: 16px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.stats-row {
|
||||
margin-bottom: 24px;
|
||||
|
||||
.stat-card {
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
height: 100%;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s;
|
||||
border: 1px solid #ebeef5;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
line-height: 1.2;
|
||||
margin: 8px 0 4px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section {
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 16px 20px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
border: 1px solid #ebeef5;
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
margin: 16px 0 12px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table {
|
||||
margin-top: 8px;
|
||||
|
||||
th {
|
||||
background-color: #f5f7fa;
|
||||
color: #303133;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 16px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.detail-hint {
|
||||
margin-bottom: 12px;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
492
klp-ui/src/views/ems/cost/spareAllocation.vue
Normal file
492
klp-ui/src/views/ems/cost/spareAllocation.vue
Normal file
@@ -0,0 +1,492 @@
|
||||
<template>
|
||||
<div class="material-allocation-page">
|
||||
<el-card class="search-card">
|
||||
<el-form :model="queryParams" inline label-width="100px" size="small">
|
||||
<el-form-item label="入场卷号" required>
|
||||
<el-input v-model="queryParams.enterCoilNo" placeholder="必填,支持模糊"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="当前卷号">
|
||||
<el-input v-model="queryParams.currentCoilNo" placeholder="支持模糊"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始日期">
|
||||
<el-date-picker v-model="queryParams.startDate" type="date" value-format="yyyy-MM-dd" placeholder="开始日期"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束日期">
|
||||
<el-date-picker v-model="queryParams.endDate" type="date" value-format="yyyy-MM-dd" placeholder="结束日期"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch">查询</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-row :gutter="16" class="stats-row">
|
||||
<el-col :xs="24" :sm="12" :md="6" :lg="5">
|
||||
<div class="stat-card">
|
||||
<div class="label">备件分摊合计</div>
|
||||
<div class="value">¥ {{ formatNumber(spareSummary.totalSpareCost, 2) }}</div>
|
||||
<div class="desc">按日池 + 时长占比分摊</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6" :lg="5">
|
||||
<div class="stat-card">
|
||||
<div class="label">卷数</div>
|
||||
<div class="value">{{ mergedTotal }}</div>
|
||||
<div class="desc">当前查询条件下</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6" :lg="5">
|
||||
<div class="stat-card">
|
||||
<div class="label">种类数</div>
|
||||
<div class="value">{{ breakdownSummary.kinds }}</div>
|
||||
<div class="desc">按备件聚合</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6" :lg="5">
|
||||
<div class="stat-card">
|
||||
<div class="label">分摊数量合计</div>
|
||||
<div class="value">{{ formatNumber(breakdownSummary.totalAllocatedQty, 2) }}</div>
|
||||
<div class="desc">数量按分摊系数切分</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6" :lg="4">
|
||||
<div class="stat-card">
|
||||
<div class="label">分摊金额合计</div>
|
||||
<div class="value">¥ {{ formatNumber(breakdownSummary.totalAllocatedAmount, 2) }}</div>
|
||||
<div class="desc">金额按分摊系数切分</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="title">分摊数据</div>
|
||||
<div class="actions">
|
||||
<el-button size="mini" type="primary" icon="el-icon-download" @click="exportSummary">导出汇总</el-button>
|
||||
<el-button size="mini" icon="el-icon-document" @click="exportDetailCsv" :disabled="detailRows.length === 0">导出明细CSV</el-button>
|
||||
<el-button size="mini" icon="el-icon-document" @click="exportBreakdownCsv" :disabled="breakdownRows.length === 0">导出构成CSV</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sub-title">备件消耗构成</div>
|
||||
<el-table :data="breakdownRows" border stripe v-loading="breakdownLoading">
|
||||
<el-table-column prop="itemCode" label="编码" width="140"></el-table-column>
|
||||
<el-table-column prop="itemName" label="名称" min-width="160"></el-table-column>
|
||||
<el-table-column prop="spec" label="规格" min-width="140"></el-table-column>
|
||||
<el-table-column prop="unit" label="单位" width="80"></el-table-column>
|
||||
<el-table-column prop="totalQty" label="全厂消耗数量" width="140" align="right">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.totalQty, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalAmount" label="全厂消耗金额(元)" width="160" align="right">
|
||||
<template slot-scope="scope">¥ {{ formatNumber(scope.row.totalAmount, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="allocatedQty" label="分摊数量" width="120" align="right">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.allocatedQty, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="allocatedAmount" label="分摊金额(元)" width="150" align="right">
|
||||
<template slot-scope="scope">¥ {{ formatNumber(scope.row.allocatedAmount, 2) }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="breakdownTotal > 0"
|
||||
:total="breakdownTotal"
|
||||
:page.sync="breakdownQuery.pageNum"
|
||||
:limit.sync="breakdownQuery.pageSize"
|
||||
@pagination="loadBreakdown"
|
||||
/>
|
||||
|
||||
<div class="sub-title" style="margin-top: 16px;">备件成本分摊(按入场卷号)</div>
|
||||
<el-table :data="mergedRows" border stripe v-loading="loading">
|
||||
<el-table-column prop="enterCoilNo" label="入场卷号"></el-table-column>
|
||||
<el-table-column prop="currentCoilNo" label="当前卷号"></el-table-column>
|
||||
<el-table-column prop="spareCost" label="备件成本">
|
||||
<template slot-scope="scope">¥ {{ formatNumber(scope.row.spareCost, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalNetWeight" label="净重">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.totalNetWeight, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalGrossWeight" label="毛重">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.totalGrossWeight, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="mini" @click="openDetail(scope.row)">分摊明细</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="mergedTotal > 0"
|
||||
:total="mergedTotal"
|
||||
:page.sync="mergedQuery.pageNum"
|
||||
:limit.sync="mergedQuery.pageSize"
|
||||
@pagination="loadMerged"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<el-dialog title="备件分摊明细(按日)" :visible.sync="detailVisible" width="80%" :close-on-click-modal="false">
|
||||
<div class="detail-hint">入场卷号:{{ detailEnterCoilNo }}</div>
|
||||
<el-table :data="detailRows" stripe border max-height="420" v-loading="detailLoading">
|
||||
<el-table-column prop="day" label="日期" width="120"></el-table-column>
|
||||
<el-table-column prop="sparePoolAmount" label="当日备件池(元)" width="140">
|
||||
<template slot-scope="scope">¥ {{ formatNumber(scope.row.sparePoolAmount, 2) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalMinutes" label="全厂分钟" width="120">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.totalMinutes, 0) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="coilMinutes" label="卷分钟" width="120">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.coilMinutes, 0) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="factor" label="占比" width="100">
|
||||
<template slot-scope="scope">{{ toPercent(scope.row.factor) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="allocatedSpareCost" label="分摊备件(元)" width="140">
|
||||
<template slot-scope="scope">¥ {{ formatNumber(scope.row.allocatedSpareCost, 2) }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="detailVisible = false">关 闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchCoilTotalMerged, exportCoilTotalMerged, fetchSparePartBreakdown } from '@/api/ems/energyCostReport'
|
||||
|
||||
export default {
|
||||
name: 'SpareCostAllocation',
|
||||
data() {
|
||||
return {
|
||||
queryParams: {
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
startDate: undefined,
|
||||
endDate: undefined
|
||||
},
|
||||
mergedQuery: {
|
||||
pageNum: 1,
|
||||
pageSize: 50
|
||||
},
|
||||
loading: false,
|
||||
mergedRows: [],
|
||||
mergedTotal: 0,
|
||||
spareSummary: {
|
||||
totalSpareCost: 0
|
||||
},
|
||||
detailVisible: false,
|
||||
detailLoading: false,
|
||||
detailEnterCoilNo: '',
|
||||
detailRows: [],
|
||||
breakdownLoading: false,
|
||||
breakdownRows: [],
|
||||
breakdownTotal: 0,
|
||||
breakdownQuery: {
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
},
|
||||
breakdownSummary: {
|
||||
kinds: 0,
|
||||
totalAllocatedQty: 0,
|
||||
totalAllocatedAmount: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.handleSearch()
|
||||
},
|
||||
methods: {
|
||||
handleSearch() {
|
||||
this.mergedQuery.pageNum = 1
|
||||
this.breakdownQuery.pageNum = 1
|
||||
this.loadMerged()
|
||||
this.loadBreakdown()
|
||||
},
|
||||
handleReset() {
|
||||
this.queryParams = {
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
startDate: undefined,
|
||||
endDate: undefined
|
||||
}
|
||||
this.mergedQuery.pageNum = 1
|
||||
this.breakdownQuery.pageNum = 1
|
||||
this.mergedRows = []
|
||||
this.mergedTotal = 0
|
||||
this.spareSummary = { totalSpareCost: 0 }
|
||||
this.detailRows = []
|
||||
this.breakdownRows = []
|
||||
this.breakdownTotal = 0
|
||||
this.breakdownSummary = { kinds: 0, totalAllocatedQty: 0, totalAllocatedAmount: 0 }
|
||||
this.handleSearch()
|
||||
},
|
||||
loadMerged() {
|
||||
const params = {
|
||||
...this.queryParams,
|
||||
pageNum: this.mergedQuery.pageNum,
|
||||
pageSize: this.mergedQuery.pageSize
|
||||
}
|
||||
this.loading = true
|
||||
fetchCoilTotalMerged(params).then(res => {
|
||||
this.mergedRows = res.rows || []
|
||||
this.mergedTotal = res.total || 0
|
||||
const rows = this.mergedRows || []
|
||||
this.spareSummary = {
|
||||
totalSpareCost: rows.reduce((sum, r) => sum + (Number(r.spareCost) || 0), 0)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
loadBreakdown() {
|
||||
const params = {
|
||||
...this.queryParams,
|
||||
pageNum: this.breakdownQuery.pageNum,
|
||||
pageSize: this.breakdownQuery.pageSize
|
||||
}
|
||||
this.breakdownLoading = true
|
||||
fetchSparePartBreakdown(params).then(res => {
|
||||
this.breakdownRows = res.rows || []
|
||||
this.breakdownTotal = res.total || 0
|
||||
const rows = this.breakdownRows || []
|
||||
this.breakdownSummary = {
|
||||
kinds: this.breakdownTotal || rows.length || 0,
|
||||
totalAllocatedQty: rows.reduce((sum, r) => sum + (Number(r.allocatedQty) || 0), 0),
|
||||
totalAllocatedAmount: rows.reduce((sum, r) => sum + (Number(r.allocatedAmount) || 0), 0)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.breakdownLoading = false
|
||||
})
|
||||
},
|
||||
exportBreakdownCsv() {
|
||||
const headers = ['编码', '名称', '规格', '单位', '全厂消耗数量', '全厂消耗金额(元)', '分摊数量', '分摊金额(元)']
|
||||
const lines = [headers.join(',')]
|
||||
;(this.breakdownRows || []).forEach(r => {
|
||||
const line = [
|
||||
this.csvCell(r.itemCode),
|
||||
this.csvCell(r.itemName),
|
||||
this.csvCell(r.spec),
|
||||
this.csvCell(r.unit),
|
||||
this.csvCell(r.totalQty),
|
||||
this.csvCell(r.totalAmount),
|
||||
this.csvCell(r.allocatedQty),
|
||||
this.csvCell(r.allocatedAmount)
|
||||
].join(',')
|
||||
lines.push(line)
|
||||
})
|
||||
const csv = lines.join('\n')
|
||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = `spare_allocation_breakdown_${this.queryParams.enterCoilNo || 'all'}.csv`
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
},
|
||||
openDetail(row) {
|
||||
if (!row || !row.enterCoilNo) return
|
||||
this.detailEnterCoilNo = row.enterCoilNo
|
||||
this.detailVisible = true
|
||||
this.buildDetailByDay(row.enterCoilNo)
|
||||
},
|
||||
buildDetailByDay(enterCoilNo) {
|
||||
// 见 auxAllocation.vue 的说明:后端 merged 目前不返回按日池/分钟细节。
|
||||
// 这里先展示“可解释”的单行结果,后续若补充明细接口,可替换为真实按日明细。
|
||||
this.detailLoading = true
|
||||
const params = {
|
||||
...this.queryParams,
|
||||
enterCoilNo,
|
||||
pageNum: 1,
|
||||
pageSize: 1
|
||||
}
|
||||
fetchCoilTotalMerged(params).then(res => {
|
||||
const row = (res.rows || [])[0]
|
||||
const total = Number(row?.spareCost) || 0
|
||||
this.detailRows = [
|
||||
{
|
||||
day: this.queryParams.startDate && this.queryParams.endDate ? `${this.queryParams.startDate} ~ ${this.queryParams.endDate}` : '-',
|
||||
sparePoolAmount: null,
|
||||
totalMinutes: null,
|
||||
coilMinutes: null,
|
||||
factor: null,
|
||||
allocatedSpareCost: total
|
||||
}
|
||||
]
|
||||
}).finally(() => {
|
||||
this.detailLoading = false
|
||||
})
|
||||
},
|
||||
exportSummary() {
|
||||
const params = { ...this.queryParams }
|
||||
exportCoilTotalMerged(params).then(res => {
|
||||
const blob = new Blob([res], { type: 'application/vnd.ms-excel' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = 'spare_cost_allocation_summary.xlsx'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
})
|
||||
},
|
||||
exportDetailCsv() {
|
||||
const headers = ['日期', '当日备件池(元)', '全厂分钟', '卷分钟', '占比', '分摊备件(元)']
|
||||
const lines = [headers.join(',')]
|
||||
;(this.detailRows || []).forEach(r => {
|
||||
const line = [
|
||||
this.csvCell(r.day),
|
||||
this.csvCell(r.sparePoolAmount),
|
||||
this.csvCell(r.totalMinutes),
|
||||
this.csvCell(r.coilMinutes),
|
||||
this.csvCell(r.factor),
|
||||
this.csvCell(r.allocatedSpareCost)
|
||||
].join(',')
|
||||
lines.push(line)
|
||||
})
|
||||
const csv = lines.join('\n')
|
||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = `spare_cost_allocation_detail_${this.detailEnterCoilNo || ''}.csv`
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
},
|
||||
csvCell(val) {
|
||||
if (val === null || val === undefined) return ''
|
||||
const s = String(val)
|
||||
if (s.includes(',') || s.includes('"') || s.includes('\n')) {
|
||||
return '"' + s.replace(/"/g, '""') + '"'
|
||||
}
|
||||
return s
|
||||
},
|
||||
formatNumber(val, digits = 2) {
|
||||
if (val === null || val === undefined) return '-'
|
||||
const num = Number(val)
|
||||
if (Number.isNaN(num)) return String(val)
|
||||
return num.toFixed(digits)
|
||||
},
|
||||
toPercent(val) {
|
||||
if (val === null || val === undefined) return '-'
|
||||
const num = Number(val)
|
||||
if (Number.isNaN(num)) return String(val)
|
||||
return (num * 100).toFixed(2) + '%'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.material-allocation-page {
|
||||
padding: 16px 20px;
|
||||
|
||||
.search-card {
|
||||
margin-bottom: 16px;
|
||||
:deep(.el-card__body) {
|
||||
padding: 16px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.stats-row {
|
||||
margin-bottom: 24px;
|
||||
|
||||
.stat-card {
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
height: 100%;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s;
|
||||
border: 1px solid #ebeef5;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
line-height: 1.2;
|
||||
margin: 8px 0 4px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section {
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 16px 20px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
border: 1px solid #ebeef5;
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
margin: 16px 0 12px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table {
|
||||
margin-top: 8px;
|
||||
|
||||
th {
|
||||
background-color: #f5f7fa;
|
||||
color: #303133;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 16px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.detail-hint {
|
||||
margin-bottom: 12px;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -196,14 +196,11 @@
|
||||
<span class="info-value">{{ item.netWeight || '—' }}t</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <el-button style="position: absolute; bottom: 10px; right: 10px;" type="success" icon="el-icon-scissors"
|
||||
size="mini" @click="handleStartSplit(item)" :loading="buttonLoading" class="action-btn">分条</el-button> -->
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<el-button v-if="useSpecialSplit" type="success" icon="el-icon-scissors" size="mini"
|
||||
@click="handleStartSplit(item)" :loading="buttonLoading" class="action-btn">分条</el-button>
|
||||
@click="handleStartSplit(item)" :loading="buttonLoading" class="action-btn">加工</el-button>
|
||||
<el-button v-else type="primary" icon="el-icon-check" size="mini" @click="handlePickMaterial(item)"
|
||||
:loading="buttonLoading" class="action-btn">领料</el-button>
|
||||
<el-button type="danger" icon="el-icon-alarm-clock" :plain="item.abnormalCount == 0" size="mini"
|
||||
@@ -223,21 +220,77 @@
|
||||
|
||||
<!-- 右侧:待操作列表 -->
|
||||
<el-col :span="12">
|
||||
<div v-if="useSpecialSplit" style="margin-bottom: 20px;" v-loading="stepSpilt.loading">
|
||||
<div class="section-header">
|
||||
<div class="section-card action-section" v-if="useSpecialSplit" style="margin-bottom: 20px;"
|
||||
v-loading="stepSpilt.loading">
|
||||
<div class="section-header ">
|
||||
<h3 class="section-title">进行中的镀锌工序</h3>
|
||||
<el-button size="mini" icon="el-icon-refresh" @click="getStepSplitList">刷新</el-button>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
|
||||
<div v-for="item in stepSpilt.list" :key="item.coilId || index"
|
||||
style="text-align: center; padding: 10px; border: 2px solid #e4e7ed; border-radius: 4px;">
|
||||
<div class="step-item" style="font-size: 24px; font-weight: bold; ">
|
||||
<span class="step-value">{{ item.currentCoilNo }}</span>
|
||||
<div v-if="stepSpilt.list.length > 0" style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
|
||||
<div v-for="(item, index) in stepSpilt.list" :key="item.coilId || index" class="coil-card"
|
||||
style="border: 1px solid #e4e7ed; border-radius: 8px; padding: 16px; margin-bottom: 12px; background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); box-shadow: 0 2px 8px rgba(0,0,0,0.05);">
|
||||
|
||||
<!-- 主标题区域 - 突出显示currentCoilNo -->
|
||||
<div class="card-header" style="margin-bottom: 16px; text-align: center;">
|
||||
<div style="display: inline-block; position: relative;">
|
||||
<!-- <div style="font-size: 12px; color: #909399; margin-bottom: 4px;">卷号</div> -->
|
||||
<div class="coil-no" style="font-size: 28px; font-weight: 800; color: #409eff; letter-spacing: 1px;
|
||||
padding: 4px 16px; background: linear-gradient(135deg, #ecf5ff 0%, #d9ecff 100%);
|
||||
border-radius: 6px; display: inline-block; border: 2px solid #a0cfff;">
|
||||
{{ item.currentCoilNo || 'N/A' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 详细信息区域 -->
|
||||
<!-- <div class="card-content" style="margin-bottom: 16px;">
|
||||
|
||||
<div class="info-row" style="display: flex; justify-content: space-between; margin-bottom: 10px;">
|
||||
<div class="info-item" style="flex: 1; text-align: center;">
|
||||
<div style="font-size: 11px; color: #909399; margin-bottom: 2px;">仓库</div>
|
||||
<div style="font-size: 14px; font-weight: 600; color: #303133;">
|
||||
{{ item.warehouseName || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="width: 1px; background: #e4e7ed; margin: 0 8px;"></div>
|
||||
|
||||
<div class="info-item" style="flex: 1; text-align: center;">
|
||||
<div style="font-size: 11px; color: #909399; margin-bottom: 2px;">实际仓库</div>
|
||||
<div style="font-size: 14px; font-weight: 600; color: #303133;">
|
||||
{{ item.actualWarehouseName || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="weight-info" style="background: linear-gradient(135deg, #f0f9eb 0%, #e1f3d8 100%);
|
||||
border-radius: 6px; padding: 8px; margin-top: 8px; text-align: center;">
|
||||
<div style="display: inline-block;">
|
||||
<div style="font-size: 12px; color: #67c23a; margin-bottom: 2px;">净重</div>
|
||||
<div style="font-size: 18px; font-weight: 700; color: #67c23a;">
|
||||
{{ item.netWeight ? `${item.netWeight} kg` : '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="card-actions" style="text-align: center; border-top: 1px solid #ebeef5; padding-top: 12px;">
|
||||
<el-button type="primary" size="mini" @click="handleContinueSplit(item)"
|
||||
style="min-width: 80px; padding: 5px 15px;">
|
||||
查看
|
||||
</el-button>
|
||||
<el-button size="mini" @click="handleCancelSplit(item)"
|
||||
style="min-width: 80px; padding: 5px 15px; margin-left: 12px; border-color: #f56c6c; color: #f56c6c;"
|
||||
:plain="true">
|
||||
取消
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button type="primary" size="mini" @click="handleContinueSplit(item)">查看</el-button>
|
||||
<el-button size="mini" @click="handleCancelSplit(item)">取消操作</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-empty description="暂无进行中的镀锌工序" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-card action-section">
|
||||
@@ -267,7 +320,7 @@
|
||||
</el-form>
|
||||
|
||||
<!-- 待操作卡片列表 -->
|
||||
<div v-loading="actionLoading" class="card-grid-container">
|
||||
<div v-if="!useSpecialSplit" v-loading="actionLoading" class="card-grid-container">
|
||||
<div v-if="pendingActionList.length === 0" class="empty-state">
|
||||
<i class="el-icon-document"></i>
|
||||
<p>暂无待操作任务</p>
|
||||
@@ -290,11 +343,6 @@
|
||||
|
||||
<div class="card-body">
|
||||
<div class="info-list">
|
||||
<div class="info-item">
|
||||
<span class="info-label">类型:</span>
|
||||
<dict-tag :options="dict.type.action_type" :value="item.actionType"
|
||||
class="action-type-tag"></dict-tag>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">来源:</span>
|
||||
<span class="info-value">
|
||||
@@ -342,14 +390,29 @@
|
||||
@click="handleDeleteAction(item)" class="action-btn">删除</el-button>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="card-footer" v-else="!useSpecialSplit">
|
||||
<el-button :loading="buttonLoading" type="primary" icon="el-icon-edit" size="mini"
|
||||
@click="handleProcess(item)" class="action-btn">查看</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-table v-else :data="pendingActionList">
|
||||
<el-table-column label="钢卷号" prop="currentCoilNo"></el-table-column>
|
||||
<el-table-column label="操作状态" prop="actionStatus">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.actionStatus === 0" type="info" size="mini">待处理</el-tag>
|
||||
<el-tag v-else-if="scope.row.actionStatus === 1" type="warning" size="mini">处理中</el-tag>
|
||||
<el-tag v-else-if="scope.row.actionStatus === 2" type="success" size="mini">已完成</el-tag>
|
||||
<el-tag v-else-if="scope.row.actionStatus === 3" type="danger" size="mini">已取消</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建人" prop="createBy"></el-table-column>
|
||||
<el-table-column label="操作人" prop="operatorName"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-if="scope.row.actionStatus === 2" :loading="buttonLoading" icon="el-icon-delete"
|
||||
size="mini" @click="handleDeleteAction(scope.row)" class="action-btn">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-show="actionTotal > 0" :total="actionTotal" :page.sync="actionQueryParams.pageNum"
|
||||
:limit.sync="actionQueryParams.pageSize" @pagination="getPendingAction" />
|
||||
@@ -396,8 +459,8 @@
|
||||
<label-render :content="labelRender.data" :labelType="labelRender.type" />
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="分步分条" :visible.sync="stepSpilt.visible" width="1400px" append-to-body>
|
||||
<step-split @print="handlePrintLabel" @complete="stepSpilt.visible = false" :actionId="stepSpilt.actionId"
|
||||
<el-dialog title="分步加工" :visible.sync="stepSpilt.visible" width="1400px" append-to-body>
|
||||
<step-split @print="handlePrintLabel" @complete="handleComposeSplit" :actionId="stepSpilt.actionId"
|
||||
:coilId="stepSpilt.coilId" :actionStatus="stepSpilt.actionStatus" />
|
||||
</el-dialog>
|
||||
|
||||
@@ -833,7 +896,7 @@ export default {
|
||||
async handleStartSplit(row) {
|
||||
this.buttonLoading = true
|
||||
try {
|
||||
await this.$modal.confirm('是否确认领料开始分条操作?')
|
||||
await this.$modal.confirm('是否确认领料开始分步加工操作?')
|
||||
this.stepSpilt.loading = true
|
||||
await startSpecialSplit(row.coilId);
|
||||
// await addPendingAction({
|
||||
@@ -844,7 +907,7 @@ export default {
|
||||
// sourceType: 'manual',
|
||||
// priority: 0,
|
||||
// })
|
||||
this.$message.success('分条操作已创建')
|
||||
this.$message.success('加工操作已创建')
|
||||
|
||||
this.getPendingAction()
|
||||
// this.getMaterialCoil()
|
||||
|
||||
@@ -92,3 +92,135 @@ CREATE TABLE `eqp_spare_parts_change` (
|
||||
KEY `fk_change_part` (`part_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1980201774324969474 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='备品备件变动记录表';
|
||||
|
||||
create table wms_material_coil
|
||||
(
|
||||
coil_id bigint auto_increment comment '主键ID'
|
||||
primary key,
|
||||
enter_coil_no varchar(50) not null comment '入场钢卷号(年份后两位+月份+当月第几个,如25100001、25102422)',
|
||||
current_coil_no varchar(50) not null comment '当前钢卷号(入场钢卷号和当前钢卷号可能不同)',
|
||||
supplier_coil_no varchar(50) null comment '厂家原料卷号',
|
||||
data_type tinyint(1) default 1 not null comment '数据类型(0=历史,1=现存)',
|
||||
warehouse_id bigint null comment '所在库区ID',
|
||||
next_warehouse_id bigint null comment '下一库区ID',
|
||||
actual_warehouse_id bigint null comment '所在实际库区ID(关联wms_actual_warehouse表)',
|
||||
qrcode_record_id bigint null comment '关联二维码ID(wms_generate_record.record_id)',
|
||||
team varchar(50) null comment '班组',
|
||||
has_merge_split tinyint(1) default 0 not null comment '是否合卷/分卷(0=否,1=分卷,2=合卷)',
|
||||
parent_coil_nos varchar(500) null comment '父卷号(合卷或分卷时用,逗号分隔)',
|
||||
item_id bigint not null comment '物品ID(指向原材料或产品主键)',
|
||||
item_type varchar(20) not null comment '物品类型(raw_material/product)',
|
||||
material_type varchar(20) null comment '材料类型(废品,成品,原料)',
|
||||
quality_status varchar(20) null comment '质量状态(0=正常,1=待检,2=不合格)',
|
||||
status tinyint(1) default 0 null comment '状态(0=在库,1=已出库)',
|
||||
remark varchar(255) null comment '备注',
|
||||
export_time datetime null comment '发货时间',
|
||||
del_flag tinyint(1) default 0 not null comment '删除标志(0=正常,1=已删除)',
|
||||
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
|
||||
create_by varchar(50) null comment '创建人',
|
||||
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
|
||||
update_by varchar(50) null comment '更新人',
|
||||
gross_weight decimal(10, 3) null comment '毛重',
|
||||
net_weight decimal(10, 3) null comment '毛重',
|
||||
length decimal(10, 3) null comment '钢卷长度(单位:米)',
|
||||
trimming_requirement varchar(100) null comment '切边要求',
|
||||
packing_status varchar(20) null comment '打包状态(0=未打包,1=已打包)',
|
||||
packaging_requirement varchar(255) null comment '包装要求',
|
||||
sale_id bigint null comment '销售id',
|
||||
constraint fk_coil_next_warehouse
|
||||
foreign key (next_warehouse_id) references wms_warehouse (warehouse_id),
|
||||
constraint fk_coil_qrcode
|
||||
foreign key (qrcode_record_id) references wms_generate_record (record_id)
|
||||
)
|
||||
comment '钢卷物料表';
|
||||
|
||||
create index idx_coil_current_no
|
||||
on wms_material_coil (current_coil_no);
|
||||
|
||||
create index idx_coil_type
|
||||
on wms_material_coil (data_type);
|
||||
|
||||
create index idx_coil_warehouse
|
||||
on wms_material_coil (warehouse_id);
|
||||
|
||||
create index idx_mc_coil_id
|
||||
on wms_material_coil (coil_id);
|
||||
|
||||
create index idx_mc_core
|
||||
on wms_material_coil (del_flag, data_type, status, material_type, actual_warehouse_id, item_type, item_id);
|
||||
|
||||
create index idx_mc_data_type
|
||||
on wms_material_coil (data_type);
|
||||
|
||||
create index idx_mc_del_awh
|
||||
on wms_material_coil (del_flag, actual_warehouse_id);
|
||||
|
||||
create index idx_mc_del_create
|
||||
on wms_material_coil (del_flag, create_time);
|
||||
|
||||
create index idx_mc_del_item
|
||||
on wms_material_coil (del_flag, item_type, item_id);
|
||||
|
||||
create index idx_mc_del_status_sale
|
||||
on wms_material_coil (del_flag, status, sale_id);
|
||||
|
||||
create index idx_mc_del_update
|
||||
on wms_material_coil (del_flag, update_time);
|
||||
|
||||
create index idx_mc_del_wh
|
||||
on wms_material_coil (del_flag, warehouse_id);
|
||||
|
||||
create index idx_mc_enter_coil_no
|
||||
on wms_material_coil (enter_coil_no);
|
||||
|
||||
create index idx_mc_fixed_group
|
||||
on wms_material_coil (del_flag, data_type, status, item_type, actual_warehouse_id, item_id);
|
||||
|
||||
create index idx_mc_has_merge_split
|
||||
on wms_material_coil (has_merge_split);
|
||||
|
||||
create index idx_mc_team
|
||||
on wms_material_coil (team);
|
||||
|
||||
|
||||
|
||||
|
||||
create table wms_coil_pending_action
|
||||
(
|
||||
action_id bigint auto_increment comment '主键ID'
|
||||
primary key,
|
||||
coil_id bigint not null comment '关联的钢卷ID',
|
||||
current_coil_no varchar(50) not null comment '当前钢卷号',
|
||||
action_type int not null comment '操作类型(1=分卷,2=合卷,3=更新)',
|
||||
action_status tinyint(1) default 0 not null comment '操作状态(0=待处理,1=处理中,2=已完成,3=已取消)',
|
||||
scan_time datetime null comment '扫码时间',
|
||||
scan_device varchar(100) null comment '扫码设备(移动端设备信息)',
|
||||
priority tinyint(1) default 0 null comment '优先级(0=普通,1=重要,2=紧急)',
|
||||
source_type varchar(20) default 'scan' not null comment '来源类型(scan=扫码,manual=手动创建)',
|
||||
warehouse_id bigint null comment '所在库区ID',
|
||||
operator_id bigint null comment '操作人ID',
|
||||
operator_name varchar(50) null comment '操作人姓名',
|
||||
process_time datetime null comment '处理时间',
|
||||
complete_time datetime null comment '完成时间',
|
||||
remark varchar(500) null comment '备注',
|
||||
del_flag tinyint(1) default 0 not null comment '删除标志(0=正常,1=已删除)',
|
||||
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
|
||||
create_by varchar(50) null comment '创建人',
|
||||
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
|
||||
update_by varchar(50) null comment '更新人'
|
||||
)
|
||||
comment '钢卷待操作表';
|
||||
|
||||
create index idx_action_status
|
||||
on wms_coil_pending_action (action_status);
|
||||
|
||||
create index idx_action_type
|
||||
on wms_coil_pending_action (action_type);
|
||||
|
||||
create index idx_coil_id
|
||||
on wms_coil_pending_action (coil_id);
|
||||
|
||||
create index idx_scan_time
|
||||
on wms_coil_pending_action (scan_time);
|
||||
|
||||
create index idx_warehouse_id
|
||||
on wms_coil_pending_action (warehouse_id);
|
||||
|
||||
Reference in New Issue
Block a user