From 35d3dc45fbdc65eb23d5cc754134fbf240419f86 Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期四, 06 八月 2026 17:09:35 +0800
Subject: [PATCH] feat: 收藏降价推送改为计费策略审批通过时触发

---
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/TAppUserSiteFavoriteFallbackFactory.java    |   32 +++++
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/TAppUserSiteFavoriteClient.java         |   27 ++++
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/vo/SitePriceDropNotifyVO.java                       |   24 ++++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/TAppUserSiteFavoriteService.java                |    9 +
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserSiteFavoriteController.java          |    8 +
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java |   99 ++++++++++++++++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserSiteFavoriteServiceImpl.java       |  111 ++++++++++++++++++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/task/FavoritePriceDropTask.java                         |    3 
 8 files changed, 312 insertions(+), 1 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/TAppUserSiteFavoriteFallbackFactory.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/TAppUserSiteFavoriteFallbackFactory.java
new file mode 100644
index 0000000..5bbdbbe
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/TAppUserSiteFavoriteFallbackFactory.java
@@ -0,0 +1,32 @@
+package com.ruoyi.account.api.factory;
+
+import com.ruoyi.account.api.feignClient.TAppUserSiteFavoriteClient;
+import com.ruoyi.account.api.vo.SitePriceDropNotifyVO;
+import com.ruoyi.common.core.domain.R;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 收藏站点服务降级处理
+ */
+@Component
+public class TAppUserSiteFavoriteFallbackFactory implements FallbackFactory<TAppUserSiteFavoriteClient> {
+
+    private static final Logger log = LoggerFactory.getLogger(TAppUserSiteFavoriteFallbackFactory.class);
+
+    @Override
+    public TAppUserSiteFavoriteClient create(Throwable throwable) {
+        log.error("收藏站点服务调用失败:{}", throwable.getMessage());
+        return new TAppUserSiteFavoriteClient() {
+
+            @Override
+            public R<Void> notifyPriceDrop(List<SitePriceDropNotifyVO> drops) {
+                return R.fail("收藏站点降价推送失败:" + throwable.getMessage());
+            }
+        };
+    }
+}
diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/TAppUserSiteFavoriteClient.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/TAppUserSiteFavoriteClient.java
new file mode 100644
index 0000000..06e528d
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/TAppUserSiteFavoriteClient.java
@@ -0,0 +1,27 @@
+package com.ruoyi.account.api.feignClient;
+
+import com.ruoyi.account.api.factory.TAppUserSiteFavoriteFallbackFactory;
+import com.ruoyi.account.api.vo.SitePriceDropNotifyVO;
+import com.ruoyi.common.core.constant.ServiceNameConstants;
+import com.ruoyi.common.core.domain.R;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+/**
+ * 用户收藏站点服务(内部接口)
+ */
+@FeignClient(contextId = "TAppUserSiteFavoriteClient", value = ServiceNameConstants.ACCOUNT_SERVICE, fallbackFactory = TAppUserSiteFavoriteFallbackFactory.class)
+public interface TAppUserSiteFavoriteClient {
+
+    /**
+     * 计费策略审批通过且存在降价时段时,通知收藏用户
+     *
+     * @param drops 降价站点列表(站点ID、名称、降价后新价格)
+     * @return
+     */
+    @PostMapping(value = "/site-favorite/inner/notifyPriceDrop")
+    R<Void> notifyPriceDrop(@RequestBody List<SitePriceDropNotifyVO> drops);
+}
diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/vo/SitePriceDropNotifyVO.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/vo/SitePriceDropNotifyVO.java
new file mode 100644
index 0000000..3dbe9c4
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/vo/SitePriceDropNotifyVO.java
@@ -0,0 +1,24 @@
+package com.ruoyi.account.api.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 站点降价推送通知(计费策略审批通过后触发)
+ */
+@Data
+@ApiModel(value = "SitePriceDropNotifyVO", description = "站点降价推送通知")
+public class SitePriceDropNotifyVO {
+
+    @ApiModelProperty(value = "站点ID")
+    private Integer siteId;
+
+    @ApiModelProperty(value = "站点名称")
+    private String siteName;
+
+    @ApiModelProperty(value = "降价后新价格(新策略时段最低价)")
+    private BigDecimal price;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserSiteFavoriteController.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserSiteFavoriteController.java
index ce99718..daf5adf 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserSiteFavoriteController.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserSiteFavoriteController.java
@@ -2,6 +2,7 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ruoyi.account.api.model.TAppUserSiteFavorite;
+import com.ruoyi.account.api.vo.SitePriceDropNotifyVO;
 import com.ruoyi.account.dto.FavoriteSiteRequest;
 import com.ruoyi.account.service.TAppUserSiteFavoriteService;
 import com.ruoyi.chargingPile.api.feignClient.SiteClient;
@@ -97,4 +98,11 @@
     public AjaxResult<String> template() {
         return AjaxResult.success(priceDropTemplateId);
     }
+
+    @PostMapping("/inner/notifyPriceDrop")
+    @ApiOperation(value = "计费策略审批通过降价后通知收藏用户(内部接口)", tags = {"内部接口-收藏"})
+    public R<Void> notifyPriceDrop(@RequestBody List<SitePriceDropNotifyVO> drops) {
+        favoriteService.notifyPriceDrop(drops);
+        return R.ok();
+    }
 }
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/TAppUserSiteFavoriteService.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/TAppUserSiteFavoriteService.java
index 62abf2b..9f4e747 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/TAppUserSiteFavoriteService.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/TAppUserSiteFavoriteService.java
@@ -2,10 +2,19 @@
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.account.api.model.TAppUserSiteFavorite;
+import com.ruoyi.account.api.vo.SitePriceDropNotifyVO;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 public interface TAppUserSiteFavoriteService extends IService<TAppUserSiteFavorite> {
 
     void saveOrRestore(Long appUserId, Integer siteId, BigDecimal favoritePrice, Boolean notifyEnabled);
+
+    /**
+     * 计费策略审批通过且存在降价时段时,向开启降价提醒的收藏用户推送微信订阅消息
+     *
+     * @param drops 降价站点列表(站点ID、名称、降价后新价格)
+     */
+    void notifyPriceDrop(List<SitePriceDropNotifyVO> drops);
 }
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserSiteFavoriteServiceImpl.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserSiteFavoriteServiceImpl.java
index 14281ca..1abef3d 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserSiteFavoriteServiceImpl.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserSiteFavoriteServiceImpl.java
@@ -1,20 +1,131 @@
 package com.ruoyi.account.service.impl;
 
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.account.api.model.TAppUser;
 import com.ruoyi.account.api.model.TAppUserSiteFavorite;
+import com.ruoyi.account.api.vo.SitePriceDropNotifyVO;
 import com.ruoyi.account.mapper.TAppUserSiteFavoriteMapper;
+import com.ruoyi.account.service.TAppUserService;
 import com.ruoyi.account.service.TAppUserSiteFavoriteService;
+import com.ruoyi.account.wx.model.WeixinProperties;
+import com.ruoyi.account.wx.tools.WxAppletTools;
+import com.ruoyi.common.core.utils.HttpUtils;
+import com.ruoyi.common.redis.service.RedisService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.RestTemplate;
 
+import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
+@Slf4j
 @Service
 public class TAppUserSiteFavoriteServiceImpl
         extends ServiceImpl<TAppUserSiteFavoriteMapper, TAppUserSiteFavorite>
         implements TAppUserSiteFavoriteService {
 
+    private static final String SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";
+
+    @Resource
+    private TAppUserService appUserService;
+    @Resource
+    private RestTemplate wxRestTemplate;
+    @Resource
+    private WeixinProperties wxConfig;
+    @Resource
+    private RedisService redisService;
+
+    @Value("${wx.applet.price-drop-template-id:7nCycRUZxQ2jxAb2UaYazjp2sPZy3qYyeLqVytyhHhY}")
+    private String templateId;
+
+    @Value("${wx.applet.price-drop-page:pagesMine/favoriteSite/favoriteSite}")
+    private String page;
+
     @Override
     public void saveOrRestore(Long appUserId, Integer siteId, BigDecimal favoritePrice, Boolean notifyEnabled) {
         baseMapper.upsert(appUserId, siteId, favoritePrice, Boolean.TRUE.equals(notifyEnabled));
     }
+
+    @Override
+    public void notifyPriceDrop(List<SitePriceDropNotifyVO> drops) {
+        if (drops == null || drops.isEmpty() || !StringUtils.hasText(templateId)) {
+            return;
+        }
+        List<Integer> siteIds = drops.stream().map(SitePriceDropNotifyVO::getSiteId)
+                .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        if (siteIds.isEmpty()) {
+            return;
+        }
+        Map<Integer, SitePriceDropNotifyVO> priceMap = drops.stream()
+                .collect(Collectors.toMap(SitePriceDropNotifyVO::getSiteId, Function.identity(), (a, b) -> a));
+        List<TAppUserSiteFavorite> favorites = lambdaQuery()
+                .eq(TAppUserSiteFavorite::getNotifyEnabled, true)
+                .in(TAppUserSiteFavorite::getSiteId, siteIds)
+                .list();
+        for (TAppUserSiteFavorite favorite : favorites) {
+            SitePriceDropNotifyVO drop = priceMap.get(favorite.getSiteId());
+            if (drop == null || drop.getPrice() == null) {
+                continue;
+            }
+            TAppUser user = appUserService.getById(favorite.getAppUserId());
+            if (user == null || !StringUtils.hasText(user.getWxOpenid())) {
+                log.info("收藏站点降价提醒未发送,用户openid为空,userId={}, siteId={}",
+                        favorite.getAppUserId(), favorite.getSiteId());
+                continue;
+            }
+            if (sendSubscribeMessage(user.getWxOpenid(), favorite, drop)) {
+                favorite.setNotifyEnabled(false);
+                favorite.setLastNotifiedPrice(drop.getPrice());
+                updateById(favorite);
+                log.info("收藏站点降价提醒发送成功,userId={}, siteId={}, price={}",
+                        favorite.getAppUserId(), favorite.getSiteId(), drop.getPrice());
+            }
+        }
+    }
+
+    private boolean sendSubscribeMessage(String openId, TAppUserSiteFavorite favorite, SitePriceDropNotifyVO drop) {
+        JSONObject body = new JSONObject();
+        body.put("touser", openId);
+        body.put("template_id", templateId);
+        body.put("page", page + "?siteId=" + favorite.getSiteId());
+        JSONObject data = new JSONObject();
+        data.put("thing1", value(limit(drop.getSiteName(), 20)));
+        data.put("amount4", value(formatAmount(drop.getPrice())));
+        body.put("data", data);
+        String accessToken = new WxAppletTools(wxRestTemplate, wxConfig, redisService).getAccessToken("");
+        String result = HttpUtils.post(SEND_URL + accessToken, body.toJSONString());
+        JSONObject response = JSON.parseObject(result);
+        boolean success = response != null && response.getIntValue("errcode") == 0;
+        if (!success) {
+            log.warn("发送收藏站点降价提醒失败,userId={}, siteId={}, response={}",
+                    favorite.getAppUserId(), favorite.getSiteId(), result);
+        }
+        return success;
+    }
+
+    private JSONObject value(String value) {
+        JSONObject item = new JSONObject();
+        item.put("value", value);
+        return item;
+    }
+
+    private String formatAmount(BigDecimal amount) {
+        return amount.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "元";
+    }
+
+    private String limit(String value, int length) {
+        if (!StringUtils.hasText(value) || value.length() <= length) {
+            return value;
+        }
+        return value.substring(0, length);
+    }
 }
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/task/FavoritePriceDropTask.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/task/FavoritePriceDropTask.java
index ea0af40..e2d7fea 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/task/FavoritePriceDropTask.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/task/FavoritePriceDropTask.java
@@ -59,7 +59,8 @@
     @Value("${wx.applet.price-drop-page:pagesMine/favoriteSite/favoriteSite}")
     private String page;
 
-    @Scheduled(fixedDelay = 30 * 60 * 1000L, initialDelay = 2 * 60 * 1000L)
+    // 降价推送已改为计费策略审批通过时触发(TAccountingStrategyController.authPass → TAppUserSiteFavoriteClient),此轮询任务暂停(如需回退恢复 @Scheduled 即可)
+    // @Scheduled(fixedDelay = 30 * 60 * 1000L, initialDelay = 2 * 60 * 1000L)
     public void notifyPriceDrop() {
         if (!StringUtils.hasText(templateId)) {
             return;
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java
index 3f5c578..53524f4 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java
@@ -4,7 +4,9 @@
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ruoyi.account.api.feignClient.TAppUserSiteFavoriteClient;
 import com.ruoyi.account.api.model.TAppUser;
+import com.ruoyi.account.api.vo.SitePriceDropNotifyVO;
 import com.ruoyi.chargingPile.api.dto.TAccountingStrategyDTO;
 import com.ruoyi.chargingPile.api.model.*;
 import com.ruoyi.chargingPile.api.query.BatchSetAccountingStrategy;
@@ -35,6 +37,8 @@
 import com.ruoyi.system.api.domain.SysUser;
 import com.ruoyi.system.api.feignClient.SysUserClient;
 import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -46,6 +50,7 @@
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.format.DateTimeParseException;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
@@ -65,6 +70,8 @@
 @RestController
 @RequestMapping("/t-accounting-strategy")
 public class TAccountingStrategyController {
+
+    private static final Logger log = LoggerFactory.getLogger(TAccountingStrategyController.class);
 
     private final TAccountingStrategyService accountingStrategyService;
     private final TAccountingStrategyDetailService accountingStrategyDetailService;
@@ -88,6 +95,9 @@
 
     @Resource
     private ChengDuJianGuanClient chengDuJianGuanClient;
+
+    @Resource
+    private TAppUserSiteFavoriteClient siteFavoriteClient;
     @Autowired
     private TokenService tokenService;
 
@@ -507,6 +517,8 @@
                             if(!siteIds.isEmpty()){
                                 tcecClient.notificationStationChange(siteIds);
                             }
+                            // 审批通过且新旧策略对比存在收费降低的时段时,向开启降价提醒的收藏用户推送降价消息
+                            notifySubscribersOnPriceDrop(one, byId, list);
                         }
                         chargingGunService.update(Wrappers.<TChargingGun>lambdaUpdate()
                                 .set(TChargingGun::getAccountingStrategyId, byId.getId())
@@ -547,6 +559,93 @@
     }
 
 
+    /**
+     * 新旧计费策略时段对比,存在收费降低的时段时向受影响站点的降价提醒订阅用户推送微信消息。
+     * 推送为旁路操作,失败不影响审批主流程。
+     */
+    private void notifySubscribersOnPriceDrop(TAccountingStrategy oldStrategy, TAccountingStrategy newStrategy, List<Site> sites) {
+        try {
+            if (oldStrategy == null || newStrategy == null || sites == null || sites.isEmpty()) {
+                return;
+            }
+            // 旧策略详情须在旧策略删除前查询
+            List<TAccountingStrategyDetail> oldDetails = accountingStrategyDetailService.list(new LambdaQueryWrapper<TAccountingStrategyDetail>()
+                    .eq(TAccountingStrategyDetail::getAccountingStrategyId, oldStrategy.getId())
+                    .eq(TAccountingStrategyDetail::getDelFlag, 0));
+            List<TAccountingStrategyDetail> newDetails = accountingStrategyDetailService.list(new LambdaQueryWrapper<TAccountingStrategyDetail>()
+                    .eq(TAccountingStrategyDetail::getAccountingStrategyId, newStrategy.getId())
+                    .eq(TAccountingStrategyDetail::getDelFlag, 0));
+            if (!hasPriceDrop(oldDetails, newDetails)) {
+                return;
+            }
+            BigDecimal minPrice = newDetails.stream()
+                    .map(this::periodTotalPrice)
+                    .filter(Objects::nonNull)
+                    .min(BigDecimal::compareTo)
+                    .orElse(null);
+            if (minPrice == null) {
+                return;
+            }
+            List<SitePriceDropNotifyVO> drops = sites.stream().map(site -> {
+                SitePriceDropNotifyVO vo = new SitePriceDropNotifyVO();
+                vo.setSiteId(site.getId());
+                vo.setSiteName(site.getName());
+                vo.setPrice(minPrice);
+                return vo;
+            }).collect(Collectors.toList());
+            siteFavoriteClient.notifyPriceDrop(drops);
+        } catch (Exception e) {
+            log.error("计费策略审批通过后降价推送失败,oldStrategyId={}, newStrategyId={}",
+                    oldStrategy == null ? null : oldStrategy.getId(), newStrategy == null ? null : newStrategy.getId(), e);
+        }
+    }
+
+    /** 新旧时段按时间区间重叠对比,任一重叠时段新价低于旧价即视为降价(价格为 电价+服务费)。 */
+    private boolean hasPriceDrop(List<TAccountingStrategyDetail> oldDetails, List<TAccountingStrategyDetail> newDetails) {
+        for (TAccountingStrategyDetail oldDetail : oldDetails) {
+            BigDecimal oldPrice = periodTotalPrice(oldDetail);
+            LocalTime oldStart = parsePeriodTime(oldDetail.getStartTime(), false);
+            LocalTime oldEnd = parsePeriodTime(oldDetail.getEndTime(), true);
+            if (oldPrice == null || oldStart == null || oldEnd == null) {
+                continue;
+            }
+            for (TAccountingStrategyDetail newDetail : newDetails) {
+                BigDecimal newPrice = periodTotalPrice(newDetail);
+                LocalTime newStart = parsePeriodTime(newDetail.getStartTime(), false);
+                LocalTime newEnd = parsePeriodTime(newDetail.getEndTime(), true);
+                if (newPrice == null || newStart == null || newEnd == null) {
+                    continue;
+                }
+                if (oldStart.isBefore(newEnd) && newStart.isBefore(oldEnd) && newPrice.compareTo(oldPrice) < 0) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private BigDecimal periodTotalPrice(TAccountingStrategyDetail detail) {
+        if (detail.getElectrovalence() == null || detail.getServiceCharge() == null) {
+            return null;
+        }
+        return detail.getElectrovalence().add(detail.getServiceCharge()).setScale(4, BigDecimal.ROUND_HALF_UP);
+    }
+
+    /** 时段时间解析,endTime 为 "00:00" 时视为 23:59:59(与 SiteController.parsePriceTime 语义一致)。 */
+    private LocalTime parsePeriodTime(String value, boolean endTime) {
+        if (value == null || value.isEmpty()) {
+            return null;
+        }
+        if (endTime && "00:00".equals(value)) {
+            return LocalTime.of(23, 59, 59);
+        }
+        try {
+            return LocalTime.parse(value.length() == 5 ? value + ":00" : value);
+        } catch (DateTimeParseException e) {
+            return null;
+        }
+    }
+
     @ApiOperation(tags = {"后台-申请表单-计费模板审核"},value = "删除")
     @DeleteMapping(value = "/delete")
     @Log(title = "【计费模板审核】删除计费模板审核", businessType = BusinessType.DELETE)

--
Gitblit v1.7.1