Browse Source

能源价格计算

wukai 2 months ago
parent
commit
120fb2678e

+ 38 - 0
jjt-admin/src/test/java/com/jjt/data/ElecTest.java

@@ -0,0 +1,38 @@
+package com.jjt.data;
+
+import com.jjt.JjtApplication;
+import com.jjt.common.utils.StringUtils;
+import com.jjt.elec.domain.ElecPeriod;
+import com.jjt.elec.domain.ElecPrice;
+import com.jjt.elec.service.IElecPeriodService;
+import com.jjt.elec.service.IElecPriceService;
+import com.jjt.ws.service.ITwinWorkshopCalcService;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.util.*;
+
+/**
+ * 印花机
+ */
+@SpringBootTest(classes = JjtApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class ElecTest {
+    @Resource
+    private ITwinWorkshopCalcService calcService;
+    @Resource
+    private IElecPeriodService periodService;
+    @Resource
+    private IElecPriceService priceService;
+
+    @Test
+    void test() {
+        String st = "2025-03-07";
+        LocalDate localDate = LocalDate.parse(st);
+        Map<Integer, BigDecimal> result=priceService.getPrice(localDate);
+        System.err.println(result);
+    }
+
+}

+ 3 - 3
jjt-admin/src/test/java/com/jjt/data/EnergyTest.java

@@ -53,9 +53,9 @@ public class EnergyTest {
     @Test
     void test() {
         iotService.setToken();
-        String st = "2025-03-04";
+        String st = "2025-03-16";
         LocalDate localDate = LocalDate.parse(st);
-        LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(1);
+        LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(2);
         LocalDateTime end = start.plusHours(1);
         LocalDateTime stop = Tools.currWholeTime();
         while (!end.isAfter(stop)) {
@@ -72,7 +72,7 @@ public class EnergyTest {
 
     @Test
     void day() {
-        String st = "2025-03-07";
+        String st = "2025-03-09";
         LocalDate localDate = LocalDate.parse(st);
         calcService.calc(localDate);
     }

+ 14 - 0
jjt-biz/src/main/java/com/jjt/calc/domain/TwinCalcHourEnergy.java

@@ -57,11 +57,25 @@ public class TwinCalcHourEnergy extends BaseEntity {
     @ApiModelProperty("统计数据")
     @Excel(name = "统计数据")
     private BigDecimal dataValue;
+    @ApiModelProperty("价格")
+    private BigDecimal price;
     @ApiModelProperty("班组")
     private String team;
     @ApiModelProperty("车间ID")
     private Long wsId;
 
+    /**
+     * 计算价格
+     *
+     * @param unit 单价
+     */
+    public void calcPrice(BigDecimal unit) {
+        this.price = dataValue.multiply(unit);
+    }
+
+    /**
+     * 设置班组
+     */
     public void setTeam() {
         if (this.hour >= 7 && this.hour < 19) {
             //A班

+ 5 - 5
jjt-biz/src/main/java/com/jjt/calc/service/impl/TwinCalcHourEnergyServiceImpl.java

@@ -178,10 +178,10 @@ public class TwinCalcHourEnergyServiceImpl implements ITwinCalcHourEnergyService
      */
     @Override
     public void calcLastEnergy() {
-        LocalDateTime ldt = Tools.currWholeTime();
-        LocalDateTime start = ldt;
-        LocalDateTime end = ldt.plusHours(1);
-        calcEnergy(start, end);
+        LocalDateTime curr = Tools.currWholeTime();
+        //上一个小时
+        LocalDateTime start = curr.minusHours(1);
+        calcEnergy(start, curr);
     }
 
     /**
@@ -235,6 +235,6 @@ public class TwinCalcHourEnergyServiceImpl implements ITwinCalcHourEnergyService
      * @return 结果
      */
     private TwinCalcHourEnergy lastRecord() {
-       return twinCalcHourEnergyMapper.lastRecord();
+        return twinCalcHourEnergyMapper.lastRecord();
     }
 }

+ 3 - 3
jjt-biz/src/main/java/com/jjt/elec/service/IElecPriceService.java

@@ -5,6 +5,7 @@ import com.jjt.elec.domain.ElecPrice;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 电费价格配置Service接口
@@ -62,11 +63,10 @@ public interface IElecPriceService {
     public int deleteElecPriceByPriceId(Long priceId);
 
     /**
-     * 根据月份和时段获取价格
+     * 根据时间获取时段价格列表
      *
      * @param localDate 时间,只取月份
-     * @param hour      小时
      * @return 电价
      */
-    BigDecimal getPrice(LocalDate localDate, int hour);
+    Map<Integer, BigDecimal> getPrice(LocalDate localDate);
 }

+ 72 - 45
jjt-biz/src/main/java/com/jjt/elec/service/impl/ElecPriceServiceImpl.java

@@ -1,5 +1,6 @@
 package com.jjt.elec.service.impl;
 
+import com.jjt.common.utils.StringUtils;
 import com.jjt.elec.domain.ElecPeriod;
 import com.jjt.elec.domain.ElecPrice;
 import com.jjt.elec.mapper.ElecPriceMapper;
@@ -10,9 +11,10 @@ import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.time.LocalDate;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
 
 /**
  * 电费价格配置Service业务层处理
@@ -94,74 +96,80 @@ public class ElecPriceServiceImpl implements IElecPriceService {
     }
 
     /**
-     * 根据月份和时段获取价格
+     * 根据时间获取时段价格列表
      *
      * @param localDate 时间,只取月份
-     * @param hour      小时
      * @return 电价
      */
     @Override
-    public BigDecimal getPrice(LocalDate localDate, int hour) {
+    public Map<Integer, BigDecimal> getPrice(LocalDate localDate) {
         ElecPeriod period = periodService.selectElecPeriodByPeriodId(1L);
         int year = localDate.getYear();
         int month = localDate.getMonthValue();
         ElecPrice priceObj = selectElecPriceByMonth(year, month);
 
         // 判断月份是春秋还是夏冬
-        boolean isSummerAutumn = getNumbers(period.getSaMonths(), true).contains(month);
+        boolean isSummerAutumn = getNumbers(period.getSaMonths(), PeriodType.MONTH).contains(month);
 
         // 根据月份和时段获取价格
+        Map<Integer, BigDecimal> result;
+        // 根据月份和时段获取价格
         if (isSummerAutumn) {
-            return getPriceByPeriod(period.getSaPeak(), period.getSaFlat(), period.getSaValley(), period.getSaSuperPeak(), hour, priceObj);
+            result = getPriceByPeriod(period.getSaPeak(), period.getSaFlat(), period.getSaValley(), period.getSaSuperPeak(), priceObj);
         } else {
-            return getPriceByPeriod(period.getSwPeak(), period.getSwFlat(), period.getSwValley(), period.getSwSuperPeak(), hour, priceObj);
+            result = getPriceByPeriod(period.getSwPeak(), period.getSwFlat(), period.getSwValley(), period.getSwSuperPeak(), priceObj);
         }
+        return result;
+
     }
 
     /**
      * 根据时段获取价格
      */
-    private BigDecimal getPriceByPeriod(String peakPeriod, String flatPeriod, String valleyPeriod, String superPeakPeriod, int hour, ElecPrice priceObj) {
-        if (getNumbers(peakPeriod, false).contains(hour)) {
-            return priceObj.getPricePeak();
-        } else if (getNumbers(flatPeriod, false).contains(hour)) {
-            return priceObj.getPriceFlat();
-        } else if (getNumbers(valleyPeriod, false).contains(hour)) {
-            return priceObj.getPriceValley();
-        } else if (getNumbers(superPeakPeriod, false).contains(hour)) {
-            return priceObj.getPriceSuperPeak();
-        }
-        return BigDecimal.ZERO;
+    private Map<Integer, BigDecimal> getPriceByPeriod(String peakPeriod, String flatPeriod, String valleyPeriod, String superPeakPeriod, ElecPrice priceObj) {
+        Map<Integer, BigDecimal> map = new HashMap<>();
+        addPricesToMap(map, peakPeriod, priceObj.getPricePeak(), PeriodType.HOUR);
+        addPricesToMap(map, flatPeriod, priceObj.getPriceFlat(), PeriodType.HOUR);
+        addPricesToMap(map, valleyPeriod, priceObj.getPriceValley(), PeriodType.HOUR);
+        addPricesToMap(map, superPeakPeriod, priceObj.getPriceSuperPeak(), PeriodType.HOUR);
+        return map;
+    }
+
+    /**
+     * 将指定时段的价格添加到Map中
+     */
+    private void addPricesToMap(Map<Integer, BigDecimal> map, String period, BigDecimal price, PeriodType periodType) {
+        getNumbers(period, periodType).forEach(hour -> map.put(hour, price));
     }
 
     /**
      * 解析 1-8,9-11这种数据
      * 如果是月份,则包含头尾,如果是小时,则不包含尾部
      *
-     * @param d    字符串
-     * @param flag 是否月份
-     * @return
+     * @param data 字符串
+     * @param type 时段类型
+     * @return 时段集合
      */
-    private Set<Long> getNumbers(String d, boolean flag) {
-        String[] temp = d.split(",");
-        Set<Long> list = new HashSet();
-        for (String s : temp) {
-            String[] ss = s.split("-");
-            if (ss.length > 1) {
-                long st = Long.parseLong(ss[0]);
-                long ed = Long.parseLong(ss[1]);
-
-                if (!flag) {
-                    ed = ed - 1;
-                }
-                for (long i = st; i <= ed; i++) {
-                    list.add(i);
-                }
-            } else {
-                list.add(Long.parseLong(s));
-            }
+    private Set<Integer> getNumbers(String data, PeriodType type) {
+        if (StringUtils.isEmpty(data)) {
+            return Collections.emptySet();
         }
-        return list;
+
+        return Arrays.stream(data.split(","))
+                .flatMap(s -> {
+                    String[] range = s.split("-");
+                    if (range.length > 1) {
+                        int start = Integer.parseInt(range[0]);
+                        int end = Integer.parseInt(range[1]);
+                        if (type == PeriodType.HOUR) {
+                            end = end - 1;
+                        }
+                        return IntStream.rangeClosed(start, end).boxed();
+                    } else {
+                        return Stream.of(Integer.parseInt(range[0]));
+                    }
+                })
+                .collect(Collectors.toSet());
     }
 
     private ElecPrice selectElecPriceByMonth(int year, int month) {
@@ -169,9 +177,28 @@ public class ElecPriceServiceImpl implements IElecPriceService {
         ElecPrice search = new ElecPrice();
         search.setPriceMonth(monthStr);
         List<ElecPrice> list = selectElecPriceList(search);
-        if (list.size() != 0) {
-            return list.get(0);
+        ElecPrice elecPrice;
+        if (list.size() == 0) {
+            //如果未找到,则取最后一条记录
+            list = selectElecPriceList(new ElecPrice());
+            elecPrice = list.get(0);
+            elecPrice.setPriceMonth(monthStr);
+            elecPrice.setPriceId(null);
+            insertElecPrice(elecPrice);
+        } else {
+            elecPrice = list.get(0);
         }
-        return null;
+        return elecPrice;
+    }
+
+    enum PeriodType {
+        /**
+         * 月份
+         */
+        MONTH,
+        /**
+         * 小时
+         */
+        HOUR
     }
 }

+ 31 - 1
jjt-biz/src/main/java/com/jjt/ws/domain/TwinWorkshopCalc.java

@@ -15,7 +15,7 @@ import java.util.Date;
  * 能源统计对象 TWIN_WORKSHOP_CALC
  *
  * @author wukai
- * @date 2025-01-17
+ * @date 2025-03-16
  */
 @ApiModel(value = "TwinWorkshopCalc", description = "能源统计")
 @Data
@@ -44,9 +44,34 @@ public class TwinWorkshopCalc extends BaseEntity {
     @Excel(name = "车间ID")
     private Long wsId;
 
+    /**
+     * 总价格
+     */
+    @ApiModelProperty("总价格")
+    @Excel(name = "总价格")
+    private BigDecimal totalPrice;
+
+    /**
+     * A班价格
+     */
+    @ApiModelProperty("A班价格")
+    @Excel(name = "A班价格")
+    private BigDecimal aPrice;
+
+    /**
+     * B班价格
+     */
+    @ApiModelProperty("B班价格")
+    @Excel(name = "B班价格")
+    private BigDecimal bPrice;
+
+    /**
+     * 总计
+     */
     @ApiModelProperty("总计")
     @Excel(name = "总计")
     private BigDecimal totalValue;
+
     /**
      * A班统计
      */
@@ -67,4 +92,9 @@ public class TwinWorkshopCalc extends BaseEntity {
         this.totalValue = this.aValue.add(this.bValue);
     }
 
+    public void setPrice(BigDecimal aPrice, BigDecimal bPrice) {
+        this.aPrice = aPrice == null ? BigDecimal.ZERO : aPrice;
+        this.bPrice = bPrice == null ? BigDecimal.ZERO : bPrice;
+        this.totalPrice = this.aPrice.add(this.bPrice);
+    }
 }

+ 38 - 6
jjt-biz/src/main/java/com/jjt/ws/service/impl/TwinWorkshopCalcServiceImpl.java

@@ -3,6 +3,7 @@ package com.jjt.ws.service.impl;
 import com.jjt.calc.domain.TwinCalcHourEnergy;
 import com.jjt.calc.service.ITwinCalcHourEnergyService;
 import com.jjt.common.utils.DateUtils;
+import com.jjt.elec.service.IElecPriceService;
 import com.jjt.ws.domain.TwinWorkshop;
 import com.jjt.ws.domain.TwinWorkshopCalc;
 import com.jjt.ws.domain.TwinWorkshopEnergy;
@@ -36,6 +37,8 @@ public class TwinWorkshopCalcServiceImpl implements ITwinWorkshopCalcService {
     private SqlSessionFactory factory;
     @Resource
     private ITwinWorkshopService wsService;
+    @Resource
+    private IElecPriceService elecPriceService;
 
     /**
      * 查询能源统计
@@ -117,26 +120,55 @@ public class TwinWorkshopCalcServiceImpl implements ITwinWorkshopCalcService {
         List<TwinWorkshopCalc> calcList = new ArrayList<>();
         List<TwinWorkshop> wsList = wsService.selectTwinWorkshopList(new TwinWorkshop());
         //存储能源ID和车间ID关系
-        Map<Long, Long> wsMap = new HashMap<>(16);
+        Map<Long, TwinWorkshopEnergy> wsMap = new HashMap<>(16);
         wsList.forEach(ws -> {
             List<TwinWorkshopEnergy> list = wsService.selectTwinWorkshopByWsId(ws.getWsId()).getTwinWorkshopEnergyList();
-            list.forEach(o -> wsMap.put(o.getEnergyId(), ws.getWsId()));
+            list.forEach(o -> wsMap.put(o.getEnergyId(), o));
         });
         //获取统计数据
         List<TwinCalcHourEnergy> energyList = energyService.selectTwinEmpCalcListByDate(date);
+        Map<Integer, BigDecimal> elecPrice = elecPriceService.getPrice(localDate);
         energyList.forEach(obj -> {
             obj.setTeam();
-            obj.setWsId(wsMap.get(obj.getEnergyId()));
+            TwinWorkshopEnergy energy = wsMap.get(obj.getEnergyId());
+            obj.setWsId(energy.getWsId());
+            switch (energy.getEnergyType()) {
+                case "1"://水
+                    obj.calcPrice(BigDecimal.valueOf(4.7));
+                    break;
+                case "2"://电
+                    obj.calcPrice(elecPrice.get(obj.getHour()));
+                    break;
+                case "3"://油
+                    // break;
+                case "4"://汽
+                    obj.calcPrice(BigDecimal.valueOf(257));
+                    break;
+                default:
+            }
         });
         //先按ID分组
         Map<Long, List<TwinCalcHourEnergy>> calcMap = energyList.stream().collect(Collectors.groupingBy(TwinCalcHourEnergy::getWsId, LinkedHashMap::new, Collectors.toList()));
         for (Long wsId : calcMap.keySet()) {
-            //按班组统计
-            Map<String, BigDecimal> resultMap = calcMap.get(wsId).stream().collect(Collectors.groupingBy(TwinCalcHourEnergy::getTeam, Collectors.reducing(BigDecimal.ZERO, TwinCalcHourEnergy::getDataValue, BigDecimal::add)));
+            //按班组统计用量和价格
+            Map<String, TwinWorkshopCalc> resultMap = calcMap.get(wsId).stream().collect(Collectors.groupingBy(TwinCalcHourEnergy::getTeam,
+                    Collectors.collectingAndThen(
+                            Collectors.toList(),
+                            list -> {
+                                BigDecimal v = list.stream().map(TwinCalcHourEnergy::getDataValue).reduce(BigDecimal.ZERO, BigDecimal::add);
+                                BigDecimal p = list.stream().map(TwinCalcHourEnergy::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
+                                TwinWorkshopCalc c = new TwinWorkshopCalc();
+                                c.setTotalPrice(p);
+                                c.setTotalValue(v);
+                                return c;
+                            }
+                    )));
+
             TwinWorkshopCalc calc = new TwinWorkshopCalc();
             calc.setWsId(wsId);
             calc.setDataDate(date);
-            calc.setValue(resultMap.get("A"), resultMap.get("B"));
+            calc.setValue(resultMap.get("A").getTotalValue(), resultMap.get("B").getTotalValue());
+            calc.setPrice(resultMap.get("A").getTotalPrice(), resultMap.get("B").getTotalPrice());
             calcList.add(calc);
 
         }

+ 28 - 13
jjt-biz/src/main/resources/mapper/ws/TwinWorkshopCalcMapper.xml

@@ -5,26 +5,32 @@
 <mapper namespace="com.jjt.ws.mapper.TwinWorkshopCalcMapper">
 
     <resultMap type="TwinWorkshopCalc" id="TwinWorkshopCalcResult">
-        <result property="calcId" column="CALC_ID"/>
-        <result property="dataDate" column="DATA_DATE"/>
-        <result property="wsId" column="WS_ID"/>
-        <result property="totalValue" column="TOTAL_VALUE"/>
-        <result property="aValue" column="A_VALUE"/>
-        <result property="bValue" column="B_VALUE"/>
+        <result property="calcId"    column="CALC_ID"    />
+        <result property="dataDate"    column="DATA_DATE"    />
+        <result property="wsId"    column="WS_ID"    />
+        <result property="totalPrice"    column="TOTAL_PRICE"    />
+        <result property="aPrice"    column="A_PRICE"    />
+        <result property="bPrice"    column="B_PRICE"    />
+        <result property="totalValue"    column="TOTAL_VALUE"    />
+        <result property="aValue"    column="A_VALUE"    />
+        <result property="bValue"    column="B_VALUE"    />
     </resultMap>
 
     <sql id="selectTwinWorkshopCalcVo">
-        select CALC_ID, DATA_DATE, WS_ID, TOTAL_VALUE, A_VALUE, B_VALUE
-        from TWIN_WORKSHOP_CALC
+        select CALC_ID, DATA_DATE, WS_ID, TOTAL_PRICE, A_PRICE, B_PRICE, TOTAL_VALUE, A_VALUE, B_VALUE from TWIN_WORKSHOP_CALC
     </sql>
 
     <select id="selectTwinWorkshopCalcList" parameterType="TwinWorkshopCalc" resultMap="TwinWorkshopCalcResult">
         <include refid="selectTwinWorkshopCalcVo"/>
         <where>
-            <if test="dataDate != null ">and DATA_DATE = #{dataDate}</if>
-            <if test="wsId != null ">and WS_ID = #{wsId}</if>
-            <if test="aValue != null ">and A_VALUE = #{aValue}</if>
-            <if test="bValue != null ">and B_VALUE = #{bValue}</if>
+            <if test="dataDate != null "> and DATA_DATE = #{dataDate}</if>
+            <if test="wsId != null "> and WS_ID = #{wsId}</if>
+            <if test="totalPrice != null "> and TOTAL_PRICE = #{totalPrice}</if>
+            <if test="aPrice != null "> and A_PRICE = #{aPrice}</if>
+            <if test="bPrice != null "> and B_PRICE = #{bPrice}</if>
+            <if test="totalValue != null "> and TOTAL_VALUE = #{totalValue}</if>
+            <if test="aValue != null "> and A_VALUE = #{aValue}</if>
+            <if test="bValue != null "> and B_VALUE = #{bValue}</if>
         </where>
     </select>
 
@@ -43,6 +49,9 @@
         <trim prefix="(" suffix=")" suffixOverrides=",">
             <if test="dataDate != null">DATA_DATE,</if>
             <if test="wsId != null">WS_ID,</if>
+            <if test="totalPrice != null">TOTAL_PRICE,</if>
+            <if test="aPrice != null">A_PRICE,</if>
+            <if test="bPrice != null">B_PRICE,</if>
             <if test="totalValue != null">TOTAL_VALUE,</if>
             <if test="aValue != null">A_VALUE,</if>
             <if test="bValue != null">B_VALUE,</if>
@@ -50,6 +59,9 @@
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="dataDate != null">#{dataDate},</if>
             <if test="wsId != null">#{wsId},</if>
+            <if test="totalPrice != null">#{totalPrice},</if>
+            <if test="aPrice != null">#{aPrice},</if>
+            <if test="bPrice != null">#{bPrice},</if>
             <if test="totalValue != null">#{totalValue},</if>
             <if test="aValue != null">#{aValue},</if>
             <if test="bValue != null">#{bValue},</if>
@@ -61,7 +73,10 @@
         <trim prefix="SET" suffixOverrides=",">
             <if test="dataDate != null">DATA_DATE = #{dataDate},</if>
             <if test="wsId != null">WS_ID = #{wsId},</if>
-            <if test="totalValue != null">TOTAL_VALUE=#{totalValue},</if>
+            <if test="totalPrice != null">TOTAL_PRICE = #{totalPrice},</if>
+            <if test="aPrice != null">A_PRICE = #{aPrice},</if>
+            <if test="bPrice != null">B_PRICE = #{bPrice},</if>
+            <if test="totalValue != null">TOTAL_VALUE = #{totalValue},</if>
             <if test="aValue != null">A_VALUE = #{aValue},</if>
             <if test="bValue != null">B_VALUE = #{bValue},</if>
         </trim>