1. 完善首页接口,增加订单环比、同比数据
2. 公众号模板消息结构调整,增加订单待支付消息 3. 微信支付附加信息添加描述 4. 交易信息中添加微信支付API类型字段 5. 微信支付 添加native支付功能 6. 云平台对于公司订单,添加多条扫码支付功能 7. 优化代码结构
This commit is contained in:
parent
4cb6391f42
commit
151220705c
@ -0,0 +1,17 @@
|
||||
package com.evotech.hd.common.core.dao.cloud;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStationCdStrategy;
|
||||
|
||||
/**
|
||||
* @author zrb
|
||||
* @since 2025-02-10
|
||||
*/
|
||||
public interface BatteryStationCdStrategyDao extends BaseMapper<BatteryStationCdStrategy> {
|
||||
|
||||
List<BatteryStationCdStrategy> listCdStrategy(@Param("stationCode") String stationCode, @Param("status") Integer status);
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.evotech.hd.common.core.dao.cloud;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStationCdStrategyDetail;
|
||||
|
||||
/**
|
||||
* @author zrb
|
||||
* @since 2025-02-10
|
||||
*/
|
||||
public interface BatteryStationCdStrategyDetailDao extends BaseMapper<BatteryStationCdStrategyDetail> {
|
||||
|
||||
List<BatteryStationCdStrategyDetail> getDetailById(Integer id);
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package com.evotech.hd.cloud.dao;
|
||||
package com.evotech.hd.common.core.dao.cloud;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
@ -23,7 +23,7 @@ import lombok.Data;
|
||||
* @since 2024-10-15
|
||||
*/
|
||||
@Data
|
||||
@TableName("yt_t_battery_station")
|
||||
@TableName("hd_cloud_manage.yt_t_battery_station")
|
||||
@Schema(name = "BatteryStation", description = "换电站")
|
||||
public class BatteryStation implements Serializable {
|
||||
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
package com.evotech.hd.common.core.entity.cloud;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author zrb
|
||||
* @since 2025-02-10
|
||||
*/
|
||||
@Data
|
||||
@TableName("hd_cloud_manage.yt_t_battery_station_cd_strategy")
|
||||
@Schema(name = "电站-充电策略")
|
||||
public class BatteryStationCdStrategy implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "pk_id", type = IdType.AUTO)
|
||||
@Schema(hidden = true)
|
||||
private Integer pkId;
|
||||
|
||||
@Schema(description = "策略名称", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String name;
|
||||
|
||||
@Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String stationCode;
|
||||
|
||||
@Schema(description = "换电站名称", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String stationName;
|
||||
|
||||
@Schema(description = "最低数量", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotNull
|
||||
@Min(1)
|
||||
private Integer miniLimit;
|
||||
|
||||
@Schema(description = "状态:0-未启用,1-启用")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建人")
|
||||
private String creater;
|
||||
|
||||
@Schema(description = "创建时间", hidden = true)
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||
private Date ctime;
|
||||
|
||||
@Schema(description = "更新人", hidden = true)
|
||||
private String updater;
|
||||
|
||||
@Schema(description = "更新时间", hidden = true)
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||
private Date uptime;
|
||||
|
||||
@Schema(description = "详情", hidden = true)
|
||||
private List<BatteryStationCdStrategyDetail> detailList;
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
package com.evotech.hd.common.core.entity.cloud;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author zrb
|
||||
* @since 2025-02-10
|
||||
*/
|
||||
@Data
|
||||
@TableName("hd_cloud_manage.yt_t_battery_station_cd_strategy_detail")
|
||||
@Schema(name = "电站-充电策略详情")
|
||||
public class BatteryStationCdStrategyDetail implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "pk_id", type = IdType.AUTO)
|
||||
@Schema(hidden = true)
|
||||
private Integer pkId;
|
||||
|
||||
@Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String stationCode;
|
||||
|
||||
@Schema(description = "换电站名称", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String stationName;
|
||||
|
||||
@Schema(description = "策略ID", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotNull
|
||||
private Integer strategyId;
|
||||
|
||||
@Schema(description = "开始时间", requiredMode = RequiredMode.REQUIRED, example = "20:01:32")
|
||||
@NotBlank
|
||||
private String beginTime;
|
||||
|
||||
@Schema(description = "结束时间", requiredMode = RequiredMode.REQUIRED, example = "23:05:41")
|
||||
@NotBlank
|
||||
private String endTime;
|
||||
|
||||
@Schema(description = "充电功率")
|
||||
private Double chargingPower;
|
||||
|
||||
@Schema(description = "创建人")
|
||||
private String creater;
|
||||
|
||||
@Schema(description = "创建时间", hidden = true)
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||
private Date ctime;
|
||||
|
||||
@Schema(description = "更新人", hidden = true)
|
||||
private String updater;
|
||||
|
||||
@Schema(description = "更新时间", hidden = true)
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||
private Date uptime;
|
||||
}
|
||||
@ -23,7 +23,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("yt_t_battery_station_dc")
|
||||
@TableName("hd_cloud_manage.yt_t_battery_station_dc")
|
||||
@Schema(name = "电站-电池")
|
||||
public class BatteryStationDc implements Serializable {
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("yt_t_battery_station_dcc")
|
||||
@TableName("hd_cloud_manage.yt_t_battery_station_dcc")
|
||||
@Schema(name = "电站-电池仓")
|
||||
public class BatteryStationDcc implements Serializable {
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("yt_t_battery_station_dj")
|
||||
@TableName("hd_cloud_manage.yt_t_battery_station_dj")
|
||||
@Schema(name = "电站-电机")
|
||||
public class BatteryStationDj implements Serializable {
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("yt_t_battery_station_hd_fee_standard")
|
||||
@TableName("hd_cloud_manage.yt_t_battery_station_hd_fee_standard")
|
||||
@Schema(name = "电站-换电费用标准")
|
||||
public class BatteryStationHdFeeStandard implements Serializable {
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("yt_t_battery_station_hd_fee_standard_detail")
|
||||
@TableName("hd_cloud_manage.yt_t_battery_station_hd_fee_standard_detail")
|
||||
@Schema(name = "电站-换电费用标准细节")
|
||||
public class BatteryStationHdFeeStandardDetail implements Serializable {
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("yt_t_battery_station_robot")
|
||||
@TableName("hd_cloud_manage.yt_t_battery_station_robot")
|
||||
@Schema(name = "电站-机器人")
|
||||
public class BatteryStationRobot implements Serializable {
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import lombok.Data;
|
||||
* @since 2024-12-06
|
||||
*/
|
||||
@Data
|
||||
@TableName("yt_t_battery_trace")
|
||||
@TableName("hd_cloud_manage.yt_t_battery_trace")
|
||||
@Schema(name = "电池追溯表")
|
||||
public class BatteryTrace implements Serializable {
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("yt_t_company")
|
||||
@TableName("hd_cloud_manage.yt_t_company")
|
||||
@Schema(name = "公司客户信息表")
|
||||
public class Company implements Serializable {
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("yt_t_order_recharge")
|
||||
@TableName("hd_cloud_manage.yt_t_order_recharge")
|
||||
@Schema(name = "充值订单")
|
||||
public class OrderRecharge implements Serializable {
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ import lombok.Data;
|
||||
* @since 2024-11-22
|
||||
*/
|
||||
@Data
|
||||
@TableName("yt_t_order_swap_battery")
|
||||
@TableName("hd_cloud_manage.yt_t_order_swap_battery")
|
||||
@Schema(name = "换电订单信息表")
|
||||
public class OrderSwapBattery implements Serializable {
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import lombok.Data;
|
||||
* @since 2024-12-04
|
||||
*/
|
||||
@Data
|
||||
@TableName("yt_t_order_swap_battery_pre")
|
||||
@TableName("hd_cloud_manage.yt_t_order_swap_battery_pre")
|
||||
@Schema(name = "换电预约订单")
|
||||
public class OrderSwapBatteryPre implements Serializable {
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ import lombok.Data;
|
||||
* @since 2024-12-11
|
||||
*/
|
||||
@Data
|
||||
@TableName("yt_t_order_swap_battery_step")
|
||||
@TableName("hd_cloud_manage.yt_t_order_swap_battery_step")
|
||||
@Schema(name = "换电步骤记录")
|
||||
public class OrderSwapBatteryStep implements Serializable {
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ import lombok.Data;
|
||||
* @since 2024-11-22
|
||||
*/
|
||||
@Data
|
||||
@TableName("yt_t_trade_detail")
|
||||
@TableName("hd_cloud_manage.yt_t_trade_detail")
|
||||
@Schema(name = "交易信息表")
|
||||
public class TradeDetail implements Serializable {
|
||||
|
||||
@ -51,6 +51,12 @@ public class TradeDetail implements Serializable {
|
||||
|
||||
@Schema(description = "收款商户号")
|
||||
private String mchid;
|
||||
|
||||
@Schema(description = "微信支付API类型")
|
||||
private String wechatPayApiType;
|
||||
|
||||
@Schema(description = "订单总描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "交易编码")
|
||||
private String outTradeNo;
|
||||
|
||||
@ -22,7 +22,7 @@ import lombok.Data;
|
||||
* @since 2024-11-22
|
||||
*/
|
||||
@Data
|
||||
@TableName("yt_t_vehicle_info")
|
||||
@TableName("hd_cloud_manage.yt_t_vehicle_info")
|
||||
@Schema(name = "车辆信息表")
|
||||
public class VehicleInfo implements Serializable {
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import lombok.Data;
|
||||
* @since 2024-11-22
|
||||
*/
|
||||
@Data
|
||||
@TableName("yt_t_vehicle_wechat_user_relation")
|
||||
@TableName("hd_cloud_manage.yt_t_vehicle_wechat_user_relation")
|
||||
@Schema(name = "车辆和用户关系")
|
||||
public class VehicleWechatUserRelation implements Serializable {
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import lombok.Data;
|
||||
* @since 2024-11-22
|
||||
*/
|
||||
@Data
|
||||
@TableName("yt_t_wallet_account")
|
||||
@TableName("hd_cloud_manage.yt_t_wallet_account")
|
||||
@Schema(name = "资金钱包账户表")
|
||||
public class WalletAccount implements Serializable {
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import lombok.Data;
|
||||
* @since 2024-11-22
|
||||
*/
|
||||
@Data
|
||||
@TableName("yt_t_wallet_account_detail")
|
||||
@TableName("hd_cloud_manage.yt_t_wallet_account_detail")
|
||||
@Schema(name = "资金账户明细")
|
||||
public class WalletAccountDetail implements Serializable {
|
||||
|
||||
|
||||
@ -26,4 +26,7 @@ public class WechatPayAttach {
|
||||
|
||||
@Schema(description = "钱包编码")
|
||||
private String walletCode;
|
||||
|
||||
@Schema(description = "订单总描述")
|
||||
private String description;
|
||||
}
|
||||
|
||||
@ -40,6 +40,9 @@ public class WechatPayPreOrder implements Serializable {
|
||||
|
||||
@Schema(description = "商户号")
|
||||
private String mchid;
|
||||
|
||||
@Schema(description = "类型")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "商户订单号")
|
||||
private String outTradeNo;
|
||||
|
||||
@ -4,7 +4,7 @@ public enum OrderStatusEnums {
|
||||
|
||||
CREATE(1, "已创建"),
|
||||
|
||||
SWAP(2, "换电中"),
|
||||
SWAP(2, "换电开始"),
|
||||
|
||||
SWAPOVER(3, "换电完成"),
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ public enum TradeTypeEnums {
|
||||
|
||||
PAYORDER(2, "支付订单"),
|
||||
|
||||
CASHOUT(9, "提现");
|
||||
REFUND(9, "提现");
|
||||
|
||||
|
||||
Integer code;
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
package com.evotech.hd.common.core.enums;
|
||||
|
||||
public enum WechatPayApiTypeEnums {
|
||||
|
||||
|
||||
JSAPI("JSAPI", "微信支付"),
|
||||
|
||||
NATIVE("NATIVE", "微信扫码支付"),
|
||||
|
||||
APP("APP", "微信APP支付"),
|
||||
|
||||
MICROPAY("MICROPAY", "小程序内嵌H5支付"),
|
||||
|
||||
MWEB("MWEB", "微信H5支付"),
|
||||
|
||||
FACEPAY("FACEPAY", "刷脸支付");
|
||||
|
||||
|
||||
String code;
|
||||
|
||||
String name;
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
WechatPayApiTypeEnums(String code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
@ -7,12 +7,14 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
|
||||
@EnableDiscoveryClient
|
||||
@ComponentScan("com.evotech.hd.**")
|
||||
@MapperScan({"com.evotech.hd.cloud.dao.**", "com.evotech.hd.common.core.dao.**"})
|
||||
@EnableFeignClients
|
||||
@EnableScheduling
|
||||
public class CloudManageServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
package com.evotech.hd.cloud.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.evotech.hd.cloud.service.BatteryStationCdStrategyService;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStationCdStrategy;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStationCdStrategyDetail;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
@Tag(name = "充电策略")
|
||||
@ApiSupport(order = 48)
|
||||
@RestController
|
||||
@RequestMapping("/batterystation/cd/strategy")
|
||||
public class BatteryStationCdStrategyController {
|
||||
|
||||
@Resource
|
||||
private BatteryStationCdStrategyService strategyService;
|
||||
|
||||
@Operation(summary = "增加")
|
||||
@PostMapping("/add")
|
||||
@ApiOperationSupport(order = 1)
|
||||
public Result<Integer> add(@Valid @ParameterObject BatteryStationCdStrategy bscs) {
|
||||
return strategyService.add(bscs);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除")
|
||||
@PostMapping("/del")
|
||||
@ApiOperationSupport(order = 2)
|
||||
public Result<Integer> delete(Integer id) {
|
||||
return strategyService.delete(id);
|
||||
}
|
||||
|
||||
@Operation(summary = "修改")
|
||||
@PostMapping({"/update"})
|
||||
@ApiOperationSupport(order = 3)
|
||||
public Result<Integer> update(@ParameterObject BatteryStationCdStrategy bscs) {
|
||||
return strategyService.update(bscs);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询")
|
||||
@GetMapping("/list")
|
||||
@ApiOperationSupport(order = 4)
|
||||
public Result<List<BatteryStationCdStrategy>> list(String stationCode, Integer status) {
|
||||
return strategyService.list(stationCode, status);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "详情增加")
|
||||
@PostMapping("/detail/add")
|
||||
@ApiOperationSupport(order = 5)
|
||||
public Result<Integer> addDetail(@Valid @ParameterObject BatteryStationCdStrategyDetail bscsd) {
|
||||
return strategyService.addDetail(bscsd);
|
||||
}
|
||||
|
||||
@Operation(summary = "详情删除")
|
||||
@PostMapping("/detail/del")
|
||||
@ApiOperationSupport(order = 6)
|
||||
public Result<Integer> deleteDetail(Integer id) {
|
||||
return strategyService.deleteDetail(id);
|
||||
}
|
||||
|
||||
@Operation(summary = "详情修改")
|
||||
@PostMapping({"/detail/update"})
|
||||
@ApiOperationSupport(order = 7)
|
||||
public Result<Integer> updateDetail(@ParameterObject BatteryStationCdStrategyDetail bscsd) {
|
||||
return strategyService.updateDetail(bscsd);
|
||||
}
|
||||
|
||||
@Operation(summary = "详情查询")
|
||||
@GetMapping("/detail/list")
|
||||
@ApiOperationSupport(order = 8)
|
||||
public Result<List<BatteryStationCdStrategyDetail>> listDetail(Integer strategyId) {
|
||||
return strategyService.listDetail(strategyId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -13,6 +13,8 @@ import com.evotech.hd.cloud.entity.vo.HomeData2;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData3;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData4;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData5;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData6;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData7;
|
||||
import com.evotech.hd.cloud.service.HomeService;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
@ -66,5 +68,20 @@ public class HomeController {
|
||||
public Result<List<HomeData5>> homeData5(@ParameterObject HomeDataRequest hd) {
|
||||
return homeService.homeData5(hd);
|
||||
}
|
||||
|
||||
@Operation(summary = "数据6-近6个月交易统计")
|
||||
@GetMapping("/data6")
|
||||
@ApiOperationSupport(order = 6)
|
||||
public Result<List<HomeData6>> homeData6(@ParameterObject HomeDataRequest hd) {
|
||||
return homeService.homeData6(hd);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "数据7-同比、环比")
|
||||
@GetMapping("/data7")
|
||||
@ApiOperationSupport(order = 7)
|
||||
public Result<HomeData7> homeData7(Integer type) {
|
||||
return homeService.homeData7(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(name = "首页请求超参数")
|
||||
@Schema(name = "首页请求参数")
|
||||
@Data
|
||||
public class HomeDataRequest {
|
||||
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
package com.evotech.hd.cloud.entity.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* copy微信的,这没有引那个包
|
||||
*/
|
||||
@Data
|
||||
public class GoodsDetail {
|
||||
|
||||
/** 商户侧商品编码 说明:由半角的大小写字母、数字、中划线、下划线中的一种或几种组成。 */
|
||||
private String merchantGoodsId;
|
||||
|
||||
/** 微信侧商品编码 说明:微信支付定义的统一商品编号(没有可不传)。 */
|
||||
private String wechatpayGoodsId;
|
||||
|
||||
/** 商品名称 说明:商品的实际名称。 */
|
||||
private String goodsName;
|
||||
|
||||
/** 商品数量 说明:用户购买的数量。 */
|
||||
private Integer quantity;
|
||||
|
||||
/** 商品单价 说明:商品单价,单位为分。 */
|
||||
private Integer unitPrice;
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.evotech.hd.cloud.entity.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(name = "同比、环比")
|
||||
public class HomeData7 {
|
||||
|
||||
@Schema(description = "年月")
|
||||
private String month;
|
||||
|
||||
@Schema(description = "订单数量")
|
||||
private Integer totalOrder;
|
||||
|
||||
@Schema(description = "同比订单数量")
|
||||
private Integer lastMonthTotalOrder;
|
||||
|
||||
@Schema(description = "环比订单数量")
|
||||
private Integer lastYearTotalOrder;
|
||||
|
||||
@Schema(description = "交易数量")
|
||||
private Integer totalTrade;
|
||||
|
||||
@Schema(description = "同比交易数量")
|
||||
private Integer lastMonthTotalTrade;
|
||||
|
||||
@Schema(description = "环比交易数量")
|
||||
private Integer lastYearTotalTrade;
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.evotech.hd.cloud.entity.vo;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(name = "Native下单参数")
|
||||
public class NativePayVO {
|
||||
|
||||
@Schema(description = "用户编码", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String wuid;
|
||||
|
||||
@Schema(description = "订单总描述", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String description;
|
||||
|
||||
@Schema(description = "支付金额,单位:分", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotNull
|
||||
@Min(1)
|
||||
@Max(100000000)
|
||||
private Integer total;
|
||||
|
||||
@Schema(description = "支付结束时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||
private Date timeExp;
|
||||
|
||||
@Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED)
|
||||
private String StationCode;
|
||||
|
||||
@Schema(description = "订单附加信息")
|
||||
private String attach;
|
||||
|
||||
@Schema(description = "使用的优惠活动编码", hidden = true)
|
||||
private String goodsTag;
|
||||
|
||||
@Schema(description = "商家小票ID", hidden = true)
|
||||
private String invoiceId;
|
||||
|
||||
@Schema(description = "商家小票金额", hidden = true)
|
||||
private Integer costPrice;
|
||||
|
||||
@Schema(description = "商品详情")
|
||||
private List<GoodsDetail> goodsDetail;
|
||||
|
||||
@Schema(description = "用户IP", requiredMode = RequiredMode.REQUIRED)
|
||||
private String payerClientIp;
|
||||
|
||||
@Schema(description = "用户设备型号")
|
||||
private String deviceId;
|
||||
|
||||
}
|
||||
@ -20,17 +20,19 @@ public class EventMessageService {
|
||||
*/
|
||||
public void event(MessageTopic topic, MqttMessageHeader header, JSONObject dataBody) {
|
||||
switch (EventFunctionTypesEnum.getFunctionType(header.getFunction())) {
|
||||
case FUN_CHARGE_RECORD:
|
||||
// TODO 写充电记录表
|
||||
// TODO 回复 confirm 消息
|
||||
// TODO 订单结算
|
||||
|
||||
break;
|
||||
case FUN_SWAP_RECORD:
|
||||
// TODO 写换电记录表
|
||||
// TODO 回复 confirm 消息
|
||||
// TODO 更新订单
|
||||
break;
|
||||
// // 这个事件不用了
|
||||
// case FUN_CHARGE_RECORD:
|
||||
// // TODO 写充电记录表
|
||||
// // TODO 回复 confirm 消息
|
||||
// // TODO 订单结算
|
||||
//
|
||||
// break;
|
||||
// // 这个事件不用了
|
||||
// case FUN_SWAP_RECORD:
|
||||
// // TODO 写换电记录表
|
||||
// // TODO 回复 confirm 消息
|
||||
// // TODO 更新订单
|
||||
// break;
|
||||
case FUN_WARN_RECORD:
|
||||
// TODO 写预警记录表
|
||||
// TODO 回复 confirm 消息
|
||||
|
||||
@ -12,7 +12,6 @@ import org.springframework.util.StringUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.evotech.hd.cloud.dao.BatteryStationDcDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao;
|
||||
import com.evotech.hd.cloud.dao.VehicleWechatUserRelationDao;
|
||||
import com.evotech.hd.cloud.mqtt.enums.MqttMessageTypeEnum;
|
||||
@ -29,6 +28,7 @@ import com.evotech.hd.cloud.mqtt.message.dto.newer.req.order.OrderData;
|
||||
import com.evotech.hd.cloud.service.OrderSwapBatteryService;
|
||||
import com.evotech.hd.cloud.utils.CommonUtil;
|
||||
import com.evotech.hd.cloud.utils.components.SwapOrderBasicFeeComponent;
|
||||
import com.evotech.hd.common.core.dao.cloud.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStationDc;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
|
||||
|
||||
@ -7,7 +7,6 @@ import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryStepDao;
|
||||
import com.evotech.hd.cloud.mqtt.enums.StateFunctionTypesEnum;
|
||||
@ -18,11 +17,11 @@ import com.evotech.hd.cloud.mqtt.message.dto.newer.state.OrderStatusData;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.state.SwapStep;
|
||||
import com.evotech.hd.cloud.service.BatteryStationDcService;
|
||||
import com.evotech.hd.cloud.utils.components.HDStepDictComponent;
|
||||
import com.evotech.hd.common.core.dao.cloud.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryTrace;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package com.evotech.hd.cloud.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStationCdStrategy;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStationCdStrategyDetail;
|
||||
|
||||
public interface BatteryStationCdStrategyService {
|
||||
|
||||
public Result<Integer> add(BatteryStationCdStrategy bscs);
|
||||
|
||||
public Result<Integer> delete(Integer id);
|
||||
|
||||
public Result<Integer> update(BatteryStationCdStrategy bscs);
|
||||
|
||||
public Result<List<BatteryStationCdStrategy>> list(String stationCode, Integer status);
|
||||
|
||||
public Result<Integer> addDetail(BatteryStationCdStrategyDetail bscsd);
|
||||
|
||||
public Result<Integer> deleteDetail(Integer id);
|
||||
|
||||
public Result<Integer> updateDetail(BatteryStationCdStrategyDetail bscsd);
|
||||
|
||||
public Result<List<BatteryStationCdStrategyDetail>> listDetail(Integer strategyId);
|
||||
|
||||
}
|
||||
@ -8,6 +8,8 @@ import com.evotech.hd.cloud.entity.vo.HomeData2;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData3;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData4;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData5;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData6;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData7;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
|
||||
public interface HomeService {
|
||||
@ -21,5 +23,9 @@ public interface HomeService {
|
||||
public Result<HomeData4> homeData4(HomeDataRequest hd);
|
||||
|
||||
public Result<List<HomeData5>> homeData5(HomeDataRequest hd);
|
||||
|
||||
public Result<List<HomeData6>> homeData6(HomeDataRequest hd);
|
||||
|
||||
public Result<HomeData7> homeData7(Integer type);
|
||||
|
||||
}
|
||||
|
||||
@ -28,6 +28,8 @@ public interface OrderSwapBatteryService {
|
||||
|
||||
public Result<String> calculateCost(String orderNo);
|
||||
|
||||
public Result<String> calculateCost(OrderSwapBattery osb);
|
||||
|
||||
public Result<String> walletPay(String orderNo, String wuid, String uname);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,109 @@
|
||||
package com.evotech.hd.cloud.service.impl;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.cloud.service.BatteryStationCdStrategyService;
|
||||
import com.evotech.hd.common.core.dao.cloud.BatteryStationCdStrategyDao;
|
||||
import com.evotech.hd.common.core.dao.cloud.BatteryStationCdStrategyDetailDao;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStationCdStrategy;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStationCdStrategyDetail;
|
||||
import com.evotech.hd.common.core.enums.CodeMsg;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
|
||||
@Service
|
||||
public class BatteryStationCdStrategyServiceImpl implements BatteryStationCdStrategyService {
|
||||
|
||||
@Resource
|
||||
private BatteryStationCdStrategyDao strategyDao;
|
||||
@Resource
|
||||
private BatteryStationCdStrategyDetailDao strategyDetailDao;
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Result<Integer> add(BatteryStationCdStrategy bscs) {
|
||||
bscs.setCtime(new Date());
|
||||
int n = strategyDao.insert(bscs);
|
||||
if (n == 1) {
|
||||
return new Result<Integer>().success(n);
|
||||
}
|
||||
return new Result<Integer>().error("添加充电策略出错!");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<Integer> delete(Integer id) {
|
||||
int n = strategyDao.deleteById(id);
|
||||
if (n == 1) {
|
||||
strategyDetailDao.delete(new QueryWrapper<BatteryStationCdStrategyDetail>().eq("strategy_id", id));
|
||||
return new Result<Integer>().success(n);
|
||||
}
|
||||
return new Result<Integer>().error("删除充电策略出错!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Integer> update(BatteryStationCdStrategy bscs) {
|
||||
int n = strategyDao.updateById(bscs);
|
||||
if (n == 1) {
|
||||
return new Result<Integer>().success(n);
|
||||
}
|
||||
return new Result<Integer>().error("更新充电策略失败!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<BatteryStationCdStrategy>> list(String stationCode, Integer status) {
|
||||
List<BatteryStationCdStrategy> list = strategyDao.listCdStrategy(stationCode, status);
|
||||
if (list.isEmpty()) {
|
||||
return new Result<List<BatteryStationCdStrategy>>().error(CodeMsg.DATABASE_RESULT_NULL);
|
||||
}
|
||||
return new Result<List<BatteryStationCdStrategy>>().success(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Integer> addDetail(BatteryStationCdStrategyDetail bscsd) {
|
||||
bscsd.setCtime(new Date());
|
||||
int n = strategyDetailDao.insert(bscsd);
|
||||
if (n == 1) {
|
||||
return new Result<Integer>().success(n);
|
||||
}
|
||||
return new Result<Integer>().error("添加充电策略详情出错!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Integer> deleteDetail(Integer id) {
|
||||
int n = strategyDetailDao.deleteById(id);
|
||||
if (n == 1) {
|
||||
return new Result<Integer>().success(n);
|
||||
}
|
||||
return new Result<Integer>().error("删除充电策略详情出错!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Integer> updateDetail(BatteryStationCdStrategyDetail bscsd) {
|
||||
int n = strategyDetailDao.updateById(bscsd);
|
||||
if (n == 1) {
|
||||
return new Result<Integer>().success(n);
|
||||
}
|
||||
return new Result<Integer>().error("更新充电策略详情失败!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<BatteryStationCdStrategyDetail>> listDetail(Integer strategyId) {
|
||||
List<BatteryStationCdStrategyDetail> list = strategyDetailDao.selectList(new QueryWrapper<BatteryStationCdStrategyDetail>()
|
||||
.eq(strategyId != null, "strategy_id", strategyId));
|
||||
if (list.isEmpty()) {
|
||||
return new Result<List<BatteryStationCdStrategyDetail>>().error(CodeMsg.DATABASE_RESULT_NULL);
|
||||
}
|
||||
return new Result<List<BatteryStationCdStrategyDetail>>().success(list);
|
||||
}
|
||||
|
||||
}
|
||||
@ -14,7 +14,6 @@ import com.evotech.hd.cloud.dao.BatteryStationDao;
|
||||
import com.evotech.hd.cloud.dao.BatteryStationDcDao;
|
||||
import com.evotech.hd.cloud.dao.BatteryStationRobotDao;
|
||||
import com.evotech.hd.cloud.dao.CompanyDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.cloud.dao.TradeDetailDao;
|
||||
import com.evotech.hd.cloud.dao.VehicleInfoDao;
|
||||
import com.evotech.hd.cloud.entity.request.HomeDataRequest;
|
||||
@ -23,7 +22,10 @@ import com.evotech.hd.cloud.entity.vo.HomeData2;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData3;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData4;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData5;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData6;
|
||||
import com.evotech.hd.cloud.entity.vo.HomeData7;
|
||||
import com.evotech.hd.cloud.service.HomeService;
|
||||
import com.evotech.hd.common.core.dao.cloud.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.common.core.dao.resource.ProxyOperaterDao;
|
||||
import com.evotech.hd.common.core.dao.wechat.WechatUserDao;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
@ -36,7 +38,10 @@ import com.evotech.hd.common.core.entity.cloud.TradeDetail;
|
||||
import com.evotech.hd.common.core.entity.cloud.VehicleInfo;
|
||||
import com.evotech.hd.common.core.entity.resource.ProxyOperater;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
import com.evotech.hd.common.core.enums.OrderStatusEnums;
|
||||
import com.evotech.hd.common.core.enums.PayTypeEnums;
|
||||
import com.evotech.hd.common.core.enums.TradeResultEnums;
|
||||
import com.evotech.hd.common.core.enums.TradeTypeEnums;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
@ -205,4 +210,90 @@ public class HomeServiceImpl implements HomeService {
|
||||
return new Result<List<HomeData5>>().success(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<HomeData6>> homeData6(HomeDataRequest hd) {
|
||||
List<HomeData6> list = new ArrayList<HomeData6>();
|
||||
// 1. 找出6个月
|
||||
String[] monthArr = new String[7];
|
||||
Date d = new Date();
|
||||
monthArr[0] = DateUtil.format(d, DatePattern.SIMPLE_MONTH_FORMATTER);
|
||||
for (int i = 1; i < monthArr.length; i++) {
|
||||
monthArr[i] = DateUtil.format(DateUtil.offsetMonth(d, -i), DatePattern.SIMPLE_MONTH_FORMATTER);
|
||||
}
|
||||
|
||||
Date beginTime = DateUtil.beginOfMonth(DateUtil.offsetMonth(d, -6));
|
||||
List<TradeDetail> tradeList = tradeDetailDao.selectList(new QueryWrapper<TradeDetail>()
|
||||
.eq("del_flag", 0)
|
||||
.ge("pay_time", beginTime));
|
||||
// 成功交易
|
||||
List<TradeDetail> successList = tradeList.stream().filter(i -> TradeResultEnums.SUCCESS.getName().equals(i.getPayResult())).toList();
|
||||
// 收入
|
||||
Map<Object, Integer> map1 = successList.parallelStream().filter(i -> i.getTradeType() == TradeTypeEnums.RECHARGE.getCode()
|
||||
||
|
||||
(i.getTradeType() == TradeTypeEnums.PAYORDER.getCode() && i.getPayType() != PayTypeEnums.WALLET.getCode())
|
||||
)
|
||||
.collect(Collectors.groupingBy(i -> DateUtil.format(i.getPayTime(), DatePattern.SIMPLE_MONTH_FORMATTER),
|
||||
Collectors.reducing(0, TradeDetail::getTradeAmount, Integer::sum)));
|
||||
// 退款
|
||||
Map<Object, Integer> map2 = successList.parallelStream().filter(i -> i.getTradeType() == TradeTypeEnums.REFUND.getCode())
|
||||
.collect(Collectors.groupingBy(i -> DateUtil.format(i.getPayTime(), DatePattern.SIMPLE_MONTH_FORMATTER),
|
||||
Collectors.reducing(0, TradeDetail::getTradeAmount, Integer::sum)));
|
||||
for (int i = 0; i < monthArr.length; i++) {
|
||||
HomeData6 data = new HomeData6();
|
||||
data.setMonth(monthArr[i]);
|
||||
data.setTotalMoney(map1.get(monthArr[i]) == null ? 0 : map1.get(monthArr[i]));
|
||||
data.setTotalRefund(map2.get(monthArr[i]) == null ? 0 : map2.get(monthArr[i]));
|
||||
list.add(data);
|
||||
}
|
||||
|
||||
return new Result<List<HomeData6>>().success(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<HomeData7> homeData7(Integer type) {
|
||||
HomeData7 data = new HomeData7();
|
||||
Date d = new Date();
|
||||
// 按月
|
||||
if (type == 1) {
|
||||
Date beginOfMonth = DateUtil.beginOfMonth(d);
|
||||
Date lastBeginOfMonth = DateUtil.offsetMonth(beginOfMonth, -1);
|
||||
data.setMonth(DateUtil.format(lastBeginOfMonth, DatePattern.SIMPLE_MONTH_FORMATTER));
|
||||
Date last2BeginOfMonth = DateUtil.offsetMonth(lastBeginOfMonth, -1);
|
||||
// 订单
|
||||
Long monthCount = orderSwapBatteryDao.selectCount(new QueryWrapper<OrderSwapBattery>()
|
||||
.ne("status", OrderStatusEnums.CANCLE.getCode())
|
||||
.ge("order_time", lastBeginOfMonth)
|
||||
.lt("order_time", beginOfMonth));
|
||||
Long lastMonthCount = orderSwapBatteryDao.selectCount(new QueryWrapper<OrderSwapBattery>()
|
||||
.ne("status", OrderStatusEnums.CANCLE.getCode())
|
||||
.ge("order_time", last2BeginOfMonth)
|
||||
.lt("order_time", lastBeginOfMonth));
|
||||
Long lastYearCount = orderSwapBatteryDao.selectCount(new QueryWrapper<OrderSwapBattery>()
|
||||
.ne("status", OrderStatusEnums.CANCLE.getCode())
|
||||
.ge("order_time", DateUtil.offsetYear(lastBeginOfMonth, -1))
|
||||
.lt("order_time", DateUtil.offsetYear(beginOfMonth, -1)));
|
||||
data.setTotalOrder(monthCount.intValue());
|
||||
data.setLastMonthTotalOrder(lastMonthCount.intValue());
|
||||
data.setLastYearTotalOrder(lastYearCount.intValue());
|
||||
|
||||
return new Result<HomeData7>().success(data);
|
||||
}
|
||||
// 按年
|
||||
Date beginOfYear = DateUtil.beginOfYear(d);
|
||||
Date lastBeginOfYear = DateUtil.offsetYear(beginOfYear, -1);
|
||||
data.setMonth(DateUtil.year(lastBeginOfYear) + "");
|
||||
Date last2BeginOfYear = DateUtil.offsetYear(lastBeginOfYear, -1);
|
||||
Long yearCount = orderSwapBatteryDao.selectCount(new QueryWrapper<OrderSwapBattery>()
|
||||
.ne("status", OrderStatusEnums.CANCLE.getCode())
|
||||
.ge("order_time", lastBeginOfYear)
|
||||
.lt("order_time", beginOfYear));
|
||||
Long lastYearCount = orderSwapBatteryDao.selectCount(new QueryWrapper<OrderSwapBattery>()
|
||||
.ne("status", OrderStatusEnums.CANCLE.getCode())
|
||||
.ge("order_time", last2BeginOfYear)
|
||||
.lt("order_time", lastBeginOfYear));
|
||||
data.setTotalOrder(yearCount.intValue());
|
||||
data.setLastYearTotalOrder(lastYearCount.intValue());
|
||||
return new Result<HomeData7>().success(data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryStepDao;
|
||||
import com.evotech.hd.cloud.dao.VehicleInfoDao;
|
||||
@ -23,6 +22,7 @@ import com.evotech.hd.cloud.service.TradeService;
|
||||
import com.evotech.hd.cloud.service.WalletAccountService;
|
||||
import com.evotech.hd.cloud.service.newthread.GZHTemplateMessageService;
|
||||
import com.evotech.hd.cloud.utils.components.SwapOrderBasicFeeComponent;
|
||||
import com.evotech.hd.common.core.dao.cloud.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.common.core.dao.wechat.WechatUserDao;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
@ -108,6 +108,7 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
OrderSwapBatteryPre osbp = new OrderSwapBatteryPre();
|
||||
osbp.setPkId(id);
|
||||
osbp.setStatus(status != null? status : 3);
|
||||
osbp.setUptime(null);
|
||||
int n = orderSwapBatteryPreDao.updateById(osbp);
|
||||
if (n == 1) {
|
||||
return new Result<Integer>().success(n);
|
||||
@ -153,6 +154,7 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
|
||||
@Override
|
||||
public Result<Integer> update(OrderSwapBattery osb) {
|
||||
osb.setUptime(null);
|
||||
int n = orderSwapBatteryDao.updateById(osb);
|
||||
if (n == 1) {
|
||||
return new Result<Integer>().success(n);
|
||||
@ -212,6 +214,30 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
if (order.getStatus() != 5) {
|
||||
return new Result<String>().error("订单状态异常!");
|
||||
}
|
||||
return calculateCost(order);
|
||||
// // 2. 检查数据
|
||||
// if (order.getBasicFee() == null || order.getServiceFee() == null) {
|
||||
// order = orderBasicFeeComponent.orderBasicFee(order);
|
||||
// if (order.getBasicFee() == null || order.getServiceFee() == null) {
|
||||
// return new Result<String>().error("订单费用标准异常!");
|
||||
// }
|
||||
// }
|
||||
// // 3. 选择费用计算方式 计算费用
|
||||
// // 先按电量计算
|
||||
// if (order.getElectAmount() == null) {
|
||||
// return new Result<String>().error("充电订单 充电量 异常!");
|
||||
// }
|
||||
// BigDecimal fee = order.getServiceFee().add(order.getBasicFee().multiply(order.getElectAmount())).setScale(0, RoundingMode.HALF_UP);
|
||||
// // 4. 修改订单
|
||||
// order.setAmount(fee.intValue());
|
||||
// order.setStatus(6);
|
||||
// orderSwapBatteryDao.updateById(order);
|
||||
// return new Result<String>().success(fee);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result<String> calculateCost(OrderSwapBattery order) {
|
||||
// 2. 检查数据
|
||||
if (order.getBasicFee() == null || order.getServiceFee() == null) {
|
||||
order = orderBasicFeeComponent.orderBasicFee(order);
|
||||
@ -228,10 +254,12 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
// 4. 修改订单
|
||||
order.setAmount(fee.intValue());
|
||||
order.setStatus(6);
|
||||
order.setUptime(null);
|
||||
orderSwapBatteryDao.updateById(order);
|
||||
return new Result<String>().success(fee);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<String> walletPay(String orderNo, String wuid, String uname) {
|
||||
@ -292,11 +320,13 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
// 改余额
|
||||
wallet.setTotalAmount(wad.getAfterTotalAmount());
|
||||
wallet.setRechargeAmount(wad.getAfterRechargeAmount());
|
||||
wallet.setUptime(null);
|
||||
walletAccountDao.updateById(wallet);
|
||||
|
||||
// 修改订单状态
|
||||
order.setStatus(OrderStatusEnums.FINISH.getCode());
|
||||
order.setTradeNo(trade.getOutTradeNo());
|
||||
order.setUptime(null);
|
||||
orderSwapBatteryDao.updateById(order);
|
||||
return new Result<String>().success("OK");
|
||||
}
|
||||
|
||||
@ -9,21 +9,13 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.cloud.dao.TradeDetailDao;
|
||||
import com.evotech.hd.cloud.dao.WalletAccountDao;
|
||||
import com.evotech.hd.cloud.dao.WalletAccountDetailDao;
|
||||
import com.evotech.hd.cloud.entity.request.PageListTradeRequest;
|
||||
import com.evotech.hd.cloud.service.TradeService;
|
||||
import com.evotech.hd.cloud.service.newthread.GZHTemplateMessageService;
|
||||
import com.evotech.hd.cloud.service.newthread.WechatPayNotifyHandleService;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.entity.cloud.TradeDetail;
|
||||
import com.evotech.hd.common.core.entity.cloud.WalletAccount;
|
||||
import com.evotech.hd.common.core.entity.cloud.WalletAccountDetail;
|
||||
import com.evotech.hd.common.core.enums.CodeMsg;
|
||||
import com.evotech.hd.common.core.enums.OrderStatusEnums;
|
||||
import com.evotech.hd.common.core.enums.TradeResultEnums;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -34,13 +26,8 @@ public class TradeServiceImpl implements TradeService {
|
||||
@Resource
|
||||
private TradeDetailDao tradeDetailDao;
|
||||
@Resource
|
||||
private OrderSwapBatteryDao orderSwapBatteryDao;
|
||||
@Resource
|
||||
private GZHTemplateMessageService templateMessageService;
|
||||
@Resource
|
||||
private WalletAccountDao walletAccountDao;
|
||||
@Resource
|
||||
private WalletAccountDetailDao walletAccountDetailDao;
|
||||
private WechatPayNotifyHandleService payNotifyHandleService;
|
||||
|
||||
|
||||
@Override
|
||||
public Result<Integer> add(TradeDetail td) {
|
||||
@ -105,65 +92,13 @@ public class TradeServiceImpl implements TradeService {
|
||||
}
|
||||
// 添加交易
|
||||
add(tradeDetail);
|
||||
// 2. 业务类型
|
||||
if (tradeDetail.getTradeType() == 1) {
|
||||
// 充值
|
||||
WalletAccount wallet = walletAccountDao.selectOne(new QueryWrapper<WalletAccount>().eq("code", tradeDetail.getWallet()));
|
||||
if (wallet == null) {
|
||||
return null;
|
||||
}
|
||||
// 添加明细
|
||||
WalletAccountDetail wad = new WalletAccountDetail();
|
||||
// TODO 写一个算法,计算充值的减多少,赠送的减多少,总金额减多少
|
||||
wad.setTradeRechargeAmount(tradeDetail.getTradeAmount());
|
||||
wad.setTradeGiftAmount(0);
|
||||
wad.setTradeTotalAmount(wad.getTradeRechargeAmount() + wad.getTradeGiftAmount());
|
||||
|
||||
wad.setPreTotalAmount(wallet.getTotalAmount());
|
||||
wad.setPreRechargeAmount(wallet.getRechargeAmount());
|
||||
wad.setPreGiftAmount(wallet.getGiftAmount());
|
||||
|
||||
wad.setAfterRechargeAmount(wad.getPreRechargeAmount() + Math.abs(wad.getTradeRechargeAmount()));
|
||||
wad.setAfterTotalAmount(wad.getPreTotalAmount() + Math.abs(wad.getTradeTotalAmount()));
|
||||
wad.setAfterGiftAmount(wad.getPreGiftAmount() + Math.abs(wad.getTradeGiftAmount()));
|
||||
|
||||
wad.setTradeGiftAmount(0);
|
||||
wad.setCode(tradeDetail.getWallet());
|
||||
wad.setTradeType(tradeDetail.getTradeType());
|
||||
wad.setTradeNo(tradeDetail.getOutTradeNo());
|
||||
|
||||
walletAccountDetailDao.insert(wad);
|
||||
// 改余额
|
||||
wallet.setTotalAmount(wad.getAfterTotalAmount());
|
||||
wallet.setRechargeAmount(wad.getAfterRechargeAmount());
|
||||
wallet.setGiftAmount(wad.getAfterGiftAmount());
|
||||
walletAccountDao.updateById(wallet);
|
||||
|
||||
// 发送公众号消息
|
||||
templateMessageService.rechargeMessageSend(tradeDetail, wallet.getTotalAmount());
|
||||
|
||||
} else if (tradeDetail.getTradeType() == 2) {
|
||||
// 支付订单
|
||||
OrderSwapBattery one = orderSwapBatteryDao.selectOne(new QueryWrapper<OrderSwapBattery>().eq("order_no", tradeDetail.getOrderNo()));
|
||||
if (one.getStatus() == 6) {
|
||||
if (TradeResultEnums.SUCCESS.getName().equals(tradeDetail.getPayResult())) {
|
||||
// 支付成功,修改订单
|
||||
OrderSwapBattery osb = new OrderSwapBattery();
|
||||
osb.setStatus(OrderStatusEnums.FINISH.getCode());
|
||||
osb.setTradeNo(tradeDetail.getOutTradeNo());
|
||||
orderSwapBatteryDao.update(osb, new QueryWrapper<OrderSwapBattery>().eq("order_no", tradeDetail.getOrderNo()));
|
||||
// 发送公众号消息
|
||||
templateMessageService.orderMessageSend(one, 3);
|
||||
}
|
||||
} else {
|
||||
log.info("\r\n===>>>支付订单存在问题:" + tradeDetail);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
// 2. 业务类型处理
|
||||
payNotifyHandleService.payNotifyBussinessHandle(tradeDetail);
|
||||
|
||||
return new Result<String>().success("OK");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -27,6 +27,11 @@ public class GZHTemplateMessageService {
|
||||
wechatService.orderMessage(osb, type);
|
||||
}
|
||||
|
||||
@Async("taskExecutor")
|
||||
public void orderMessageSend2(Integer id, Integer type) {
|
||||
wechatService.orderMessage2(id, type);
|
||||
}
|
||||
|
||||
@Async("taskExecutor")
|
||||
public void rechargeMessageSend(TradeDetail trade, Integer money) {
|
||||
wechatService.rechargeMessage(trade, money);
|
||||
|
||||
@ -0,0 +1,147 @@
|
||||
package com.evotech.hd.cloud.service.newthread;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.evotech.hd.cloud.dao.WalletAccountDao;
|
||||
import com.evotech.hd.cloud.dao.WalletAccountDetailDao;
|
||||
import com.evotech.hd.common.core.dao.cloud.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.entity.cloud.TradeDetail;
|
||||
import com.evotech.hd.common.core.entity.cloud.WalletAccount;
|
||||
import com.evotech.hd.common.core.entity.cloud.WalletAccountDetail;
|
||||
import com.evotech.hd.common.core.enums.OrderStatusEnums;
|
||||
import com.evotech.hd.common.core.enums.TradeResultEnums;
|
||||
import com.evotech.hd.common.core.enums.WechatPayApiTypeEnums;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class WechatPayNotifyHandleService {
|
||||
|
||||
@Resource
|
||||
private WalletAccountDao walletAccountDao;
|
||||
@Resource
|
||||
private WalletAccountDetailDao walletAccountDetailDao;
|
||||
@Resource
|
||||
private GZHTemplateMessageService templateMessageService;
|
||||
@Resource
|
||||
private OrderSwapBatteryDao orderSwapBatteryDao;
|
||||
|
||||
|
||||
// @Async("taskExecutor")
|
||||
public void payNotifyBussinessHandle(TradeDetail tradeDetail) {
|
||||
if (tradeDetail.getTradeType() == 1) {
|
||||
// 充值
|
||||
WalletAccount wallet = walletAccountDao.selectOne(new QueryWrapper<WalletAccount>().eq("code", tradeDetail.getWallet()));
|
||||
if (wallet == null) {
|
||||
return;
|
||||
}
|
||||
// 添加明细
|
||||
WalletAccountDetail wad = new WalletAccountDetail();
|
||||
// TODO 写一个算法,计算充值的减多少,赠送的减多少,总金额减多少
|
||||
wad.setTradeRechargeAmount(tradeDetail.getTradeAmount());
|
||||
wad.setTradeGiftAmount(0);
|
||||
wad.setTradeTotalAmount(wad.getTradeRechargeAmount() + wad.getTradeGiftAmount());
|
||||
|
||||
wad.setPreTotalAmount(wallet.getTotalAmount());
|
||||
wad.setPreRechargeAmount(wallet.getRechargeAmount());
|
||||
wad.setPreGiftAmount(wallet.getGiftAmount());
|
||||
|
||||
wad.setAfterRechargeAmount(wad.getPreRechargeAmount() + Math.abs(wad.getTradeRechargeAmount()));
|
||||
wad.setAfterTotalAmount(wad.getPreTotalAmount() + Math.abs(wad.getTradeTotalAmount()));
|
||||
wad.setAfterGiftAmount(wad.getPreGiftAmount() + Math.abs(wad.getTradeGiftAmount()));
|
||||
|
||||
wad.setTradeGiftAmount(0);
|
||||
wad.setCode(tradeDetail.getWallet());
|
||||
wad.setTradeType(tradeDetail.getTradeType());
|
||||
wad.setTradeNo(tradeDetail.getOutTradeNo());
|
||||
|
||||
walletAccountDetailDao.insert(wad);
|
||||
// 改余额
|
||||
wallet.setTotalAmount(wad.getAfterTotalAmount());
|
||||
wallet.setRechargeAmount(wad.getAfterRechargeAmount());
|
||||
wallet.setGiftAmount(wad.getAfterGiftAmount());
|
||||
walletAccountDao.updateById(wallet);
|
||||
|
||||
// 发送公众号消息
|
||||
templateMessageService.rechargeMessageSend(tradeDetail, wallet.getTotalAmount());
|
||||
|
||||
} else if (tradeDetail.getTradeType() == 2) {
|
||||
// 支付订单
|
||||
if (WechatPayApiTypeEnums.JSAPI.getCode().equals(tradeDetail.getWechatPayApiType())) {
|
||||
// jsapi支付
|
||||
jsapiPayHandle(tradeDetail);
|
||||
}
|
||||
if (WechatPayApiTypeEnums.NATIVE.getCode().equals(tradeDetail.getWechatPayApiType())) {
|
||||
// native支付,企业
|
||||
nativePayHandle(tradeDetail);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 一般个人单条付款
|
||||
* @param tradeDetail
|
||||
*/
|
||||
private void jsapiPayHandle(TradeDetail tradeDetail) {
|
||||
OrderSwapBattery one = orderSwapBatteryDao.selectOne(new QueryWrapper<OrderSwapBattery>().eq("order_no", tradeDetail.getOrderNo()));
|
||||
if (one.getStatus() == 6) {
|
||||
if (TradeResultEnums.SUCCESS.getName().equals(tradeDetail.getPayResult())) {
|
||||
// 支付成功,修改订单
|
||||
afterPayAlterOrder(tradeDetail, one);
|
||||
// 发送公众号消息
|
||||
templateMessageService.orderMessageSend(one, 3);
|
||||
}
|
||||
} else {
|
||||
log.info("\r\n===>>>支付订单存在问题:" + tradeDetail);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 一般企业多条付款
|
||||
* @param tradeDetail
|
||||
*/
|
||||
private void nativePayHandle(TradeDetail tradeDetail) {
|
||||
List<String> orderNoList = Arrays.asList(tradeDetail.getOrderNo().split(","));
|
||||
List<OrderSwapBattery> orderList = orderSwapBatteryDao.selectList(new QueryWrapper<OrderSwapBattery>()
|
||||
.eq("status", 6).in("order_no", orderNoList));
|
||||
if (orderList.size() != orderNoList.size()) {
|
||||
log.info("\r\n **********");
|
||||
log.error("\r\n===>>>交易订单存在问题:" + tradeDetail);
|
||||
log.info("\r\n **********");
|
||||
}
|
||||
List<Integer> idList = orderList.stream().map(i -> i.getPkId()).toList();
|
||||
orderSwapBatteryDao.update(new UpdateWrapper<OrderSwapBattery>().in("pk_id", idList)
|
||||
.set("status", OrderStatusEnums.FINISH.getCode())
|
||||
.set("trade_no", tradeDetail.getOutTradeNo()));
|
||||
|
||||
// 发送公众号消息,发给企业绑定的微信号
|
||||
// templateMessageService.orderMessageSend(one, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付成功后,修改订单状态
|
||||
* @param tradeDetail
|
||||
* @param one
|
||||
*/
|
||||
private void afterPayAlterOrder(TradeDetail tradeDetail, OrderSwapBattery one) {
|
||||
OrderSwapBattery osb = new OrderSwapBattery();
|
||||
osb.setPkId(one.getPkId());
|
||||
osb.setStatus(OrderStatusEnums.FINISH.getCode());
|
||||
osb.setTradeNo(tradeDetail.getOutTradeNo());
|
||||
orderSwapBatteryDao.updateById(osb);
|
||||
}
|
||||
|
||||
}
|
||||
@ -32,6 +32,10 @@ public interface WechatService {
|
||||
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
|
||||
public Result<String> orderMessage(@ParameterObject OrderSwapBattery osb, @RequestParam Integer templateType);
|
||||
|
||||
@PostMapping(value = "/wechat/gzh/msg/send/order2",
|
||||
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
|
||||
public Result<String> orderMessage2(@RequestParam Integer id, @RequestParam Integer templateType);
|
||||
|
||||
@PostMapping(value = "/wechat/gzh/msg/send/recharge",
|
||||
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
|
||||
public Result<String> rechargeMessage(@ParameterObject TradeDetail trade, @RequestParam Integer money);
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
package com.evotech.hd.cloud.task;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.cloud.service.OrderSwapBatteryService;
|
||||
import com.evotech.hd.cloud.service.newthread.GZHTemplateMessageService;
|
||||
import com.evotech.hd.common.core.dao.cloud.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.enums.CodeMsg;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class OrderCostCalculateTask {
|
||||
|
||||
@Resource
|
||||
private OrderSwapBatteryDao orderSwapBatteryDao;
|
||||
@Resource
|
||||
private OrderSwapBatteryService orderSwapBatteryService;
|
||||
@Resource
|
||||
private GZHTemplateMessageService gzhTemplateMessageService;
|
||||
|
||||
|
||||
|
||||
@Scheduled(cron ="0 0 11,14,16,18,20 * * ?")
|
||||
public void calculateOrder() {
|
||||
log.info("\r\n===>>>开始查找订单计算费用");
|
||||
// 查询状态为5的订单
|
||||
Boolean flag = true;
|
||||
int n = 0;
|
||||
while (flag) {
|
||||
List<OrderSwapBattery> list = orderSwapBatteryDao.selectList(new QueryWrapper<OrderSwapBattery>()
|
||||
.eq("status", 5).ne("del_flag", 1).last("limit 20"));
|
||||
if (!list.isEmpty()) {
|
||||
n = orderCalculate(n, list);
|
||||
} else {
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
log.info("\r\n===>>>订单计算费用完成:{} 条数据", n);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private int orderCalculate(int n, List<OrderSwapBattery> list) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Result<String> res = orderSwapBatteryService.calculateCost(list.get(i));
|
||||
if ( CodeMsg.SUCCESS.getCode().equals(res.getCode())) {
|
||||
n += 1;
|
||||
// 发送微信消息
|
||||
gzhTemplateMessageService.orderMessageSend2(list.get(i).getPkId(), 2);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.evotech.hd.common.core.dao.cloud.BatteryStationCdStrategyDetailDao">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="com.evotech.hd.common.core.entity.cloud.BatteryStationCdStrategyDetail">
|
||||
<id column="pk_id" property="pkId" />
|
||||
<result column="station_code" property="stationCode" />
|
||||
<result column="station_name" property="stationName" />
|
||||
<result column="strategy_id" property="strategyId" />
|
||||
<result column="begin_time" property="beginTime" />
|
||||
<result column="end_time" property="endTime" />
|
||||
<result column="charging_power" property="chargingPower" />
|
||||
<result column="ctime" property="ctime" />
|
||||
<result column="creater" property="creater" />
|
||||
<result column="uptime" property="uptime" />
|
||||
<result column="updater" property="updater" />
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
pk_id, station_code, station_name, strategy_id, begin_time, end_time, charging_power, ctime, creater, uptime, updater
|
||||
</sql>
|
||||
|
||||
<select id="getDetailById" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
yt_t_battery_station_cd_strategy_detail
|
||||
WHERE
|
||||
strategy_id = #{id}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.evotech.hd.common.core.dao.cloud.BatteryStationCdStrategyDao">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="com.evotech.hd.common.core.entity.cloud.BatteryStationCdStrategy">
|
||||
<id column="pk_id" property="pkId" />
|
||||
<result column="station_code" property="stationCode" />
|
||||
<result column="station_name" property="stationName" />
|
||||
<result column="mini_limit" property="miniLimit" />
|
||||
<result column="status" property="status" />
|
||||
<result column="ctime" property="ctime" />
|
||||
<result column="creater" property="creater" />
|
||||
<result column="uptime" property="uptime" />
|
||||
<result column="updater" property="updater" />
|
||||
<collection property="detailList"
|
||||
select="com.evotech.hd.common.core.dao.cloud.BatteryStationCdStrategyDetailDao.getDetailById"
|
||||
column="pk_id">
|
||||
</collection>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
pk_id, station_code, station_name, mini_limit, status, ctime, creater, uptime, updater
|
||||
</sql>
|
||||
|
||||
<select id="listCdStrategy" resultMap="BaseResultMap">
|
||||
select
|
||||
a.*
|
||||
From
|
||||
yt_t_battery_station_cd_strategy a
|
||||
where
|
||||
1 = 1
|
||||
<if test="stationCode != null and stationCode != '' ">
|
||||
and a.station_code = #{stationCode}
|
||||
</if>
|
||||
<if test="status != null and status != '' ">
|
||||
and a.status = #{status}
|
||||
</if>
|
||||
order by a.pk_id desc
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@ -55,13 +55,13 @@ public class AuthorizationManager implements ReactiveAuthorizationManager<Author
|
||||
return Mono.just(new AuthorizationDecision(true));
|
||||
}
|
||||
ServerHttpRequest request = authorizationContext.getExchange().getRequest();
|
||||
String uri = request.getURI().toString();
|
||||
System.out.println("&&&&&&>" + uri);
|
||||
|
||||
// 1. 对应跨域的预检请求直接放行
|
||||
if (request.getMethod() == HttpMethod.OPTIONS) {
|
||||
return Mono.just(new AuthorizationDecision(true));
|
||||
}
|
||||
|
||||
String uri = request.getURI().toString();
|
||||
System.out.println("===>>>" + uri);
|
||||
// 2. 微信服务token验证
|
||||
if (uri.contains("/gateway/wechat/")) {
|
||||
// 提到另一个类了,应该走不到这了
|
||||
@ -146,7 +146,6 @@ public class AuthorizationManager implements ReactiveAuthorizationManager<Author
|
||||
*/
|
||||
private boolean checkAuthorities(String token, ServerHttpRequest request, Authentication auth) {
|
||||
String uri = request.getURI().toString();
|
||||
|
||||
// 0. Redis中含有JTI才可用
|
||||
String jti = TokenUtil.getJti(token);
|
||||
if (!redisUtil.hasKey(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":token") ) {
|
||||
|
||||
@ -26,6 +26,8 @@ public class XcxProperties {
|
||||
|
||||
private String notifyUrl;
|
||||
|
||||
private String nativeNotifyUrl;
|
||||
|
||||
private String refundNotifyUrl;
|
||||
|
||||
private String publicKeyId;
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
package com.evotech.hd.wechat.controller;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.wechat.entity.NativePayVO;
|
||||
import com.evotech.hd.wechat.service.WechatNativePayService;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
@Tag(name = "微信Native支付")
|
||||
@RestController
|
||||
@RequestMapping("/wechatpay/native")
|
||||
@ApiSupport(order = 18)
|
||||
public class WechatNativePayController {
|
||||
|
||||
|
||||
@Resource
|
||||
private WechatNativePayService nativePayService;
|
||||
|
||||
|
||||
@Operation(summary = "Native预支付订单")
|
||||
@PostMapping("/prepay")
|
||||
@ApiOperationSupport(order = 1)
|
||||
public Result<String> nativePrepay(@RequestBody NativePayVO prePay) {
|
||||
return nativePayService.nativePrepay(prePay);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "支付回调地址")
|
||||
@PostMapping("/nativeback/msg")
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Hidden
|
||||
public ResponseEntity<String> nativeBack(HttpServletRequest request) {
|
||||
return nativePayService.nativeBack(request);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "支付订单查询状态")
|
||||
@GetMapping("/order/query")
|
||||
@ApiOperationSupport(order = 3)
|
||||
public Result<String> orderQuery(Integer type, @RequestParam(required = false)String transactionId, @RequestParam(required = false)String outTradeNo) {
|
||||
return nativePayService.orderQuery(type, transactionId, outTradeNo);
|
||||
}
|
||||
|
||||
|
||||
// @Operation(summary = "退款")
|
||||
// @PostMapping("/refunds")
|
||||
// @ApiOperationSupport(order = 4)
|
||||
// public Result<String> refunds(String outTradeNo, String transactionId, String reason, Integer money, Integer total) {
|
||||
// return wechatPayService.refunds(outTradeNo, transactionId, reason, money, total);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Operation(summary = "退款回调地址")
|
||||
// @PostMapping("/refundsback/msg")
|
||||
// @ApiOperationSupport(order = 5)
|
||||
// @Hidden
|
||||
// public ResponseEntity<String> refundsBack(HttpServletRequest request) {
|
||||
// return wechatPayService.refundsBack(request);
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Operation(summary = "单笔退款查询")
|
||||
// @GetMapping("/refunds/query")
|
||||
// @ApiOperationSupport(order = 6)
|
||||
// public Result<String> refundsQuery(String outRefundNo) {
|
||||
// return wechatPayService.refundsQuery(outRefundNo);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Operation(summary = "单日交易账单,进3月内")
|
||||
// @PostMapping("/daytradebill")
|
||||
// @ApiOperationSupport(order = 7)
|
||||
// public Result<String> dayTradebill(@RequestParam @NotBlank String day) {
|
||||
// return wechatPayService.dayTradebill(day);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
@ -51,7 +51,7 @@ public class WechatPayController {
|
||||
@Operation(summary = "支付订单查询状态")
|
||||
@GetMapping("/order/query")
|
||||
@ApiOperationSupport(order = 3)
|
||||
public Result<String> orderQuery(Integer type, String transactionId, String outTradeNo) {
|
||||
public Result<String> orderQuery(Integer type, @RequestParam(required = false) String transactionId, @RequestParam(required = false)String outTradeNo) {
|
||||
return wechatPayService.orderQuery(type, transactionId, outTradeNo);
|
||||
}
|
||||
|
||||
|
||||
@ -45,6 +45,13 @@ public class GZHMessageSendController {
|
||||
return gzhMessageTemplateService.sendTemplateMessageOrder(osb, templateType);
|
||||
}
|
||||
|
||||
@Operation(summary = "推送公众号订单消息2")
|
||||
@PostMapping("/order2")
|
||||
@Hidden
|
||||
public Result<String> orderMessage2(@RequestParam Integer id, @RequestParam Integer templateType) {
|
||||
return gzhMessageTemplateService.sendTemplateMessageOrder2(id, templateType);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "预约发送公众号消息2")
|
||||
@PostMapping("/preorder2")
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
package com.evotech.hd.wechat.entity;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.GoodsDetail;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(name = "Native下单参数")
|
||||
public class NativePayVO {
|
||||
|
||||
@Schema(description = "用户编码", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String wuid;
|
||||
|
||||
@Schema(description = "订单总描述", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String description;
|
||||
|
||||
@Schema(description = "支付金额,单位:分", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotNull
|
||||
@Min(1)
|
||||
@Max(100000000)
|
||||
private Integer total;
|
||||
|
||||
@Schema(description = "支付结束时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||
private Date timeExp;
|
||||
|
||||
@Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED)
|
||||
private String StationCode;
|
||||
|
||||
@Schema(description = "订单附加信息")
|
||||
private String attach;
|
||||
|
||||
@Schema(description = "使用的优惠活动编码", hidden = true)
|
||||
private String goodsTag;
|
||||
|
||||
@Schema(description = "商家小票ID", hidden = true)
|
||||
private String invoiceId;
|
||||
|
||||
@Schema(description = "商家小票金额", hidden = true)
|
||||
private Integer costPrice;
|
||||
|
||||
@Schema(description = "商品详情")
|
||||
private List<GoodsDetail> goodsDetail;
|
||||
|
||||
@Schema(description = "用户IP", requiredMode = RequiredMode.REQUIRED)
|
||||
private String payerClientIp;
|
||||
|
||||
@Schema(description = "用户设备型号")
|
||||
private String deviceId;
|
||||
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.evotech.hd.wechat.service;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.wechat.entity.NativePayVO;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
public interface WechatNativePayService {
|
||||
|
||||
public Result<String> nativePrepay(NativePayVO prePay);
|
||||
|
||||
public ResponseEntity<String> nativeBack(HttpServletRequest request);
|
||||
|
||||
public Result<String> orderQuery(Integer type, String transactionId, String outTradeNo);
|
||||
|
||||
}
|
||||
@ -40,7 +40,6 @@ public class GZHMessageReceiveService {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
System.out.println("++++++++");
|
||||
String res = HttpUtil.getString(request.getInputStream(), Charset.defaultCharset(), false);
|
||||
Map<String, Object> map = XmlUtil.xmlToMap(res);
|
||||
if ("event".equals(map.get("MsgType").toString())) {
|
||||
|
||||
@ -4,6 +4,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.common.core.dao.cloud.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.common.core.dao.wechat.WechatUserDao;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
@ -47,6 +48,8 @@ public class GZHMessageTemplateService {
|
||||
private XcxProperties xcxProperties;
|
||||
@Resource
|
||||
private WechatUserDao wechatUserDao;
|
||||
@Resource
|
||||
private OrderSwapBatteryDao orderSwapBatteryDao;
|
||||
|
||||
|
||||
|
||||
@ -106,7 +109,6 @@ public class GZHMessageTemplateService {
|
||||
if (!StringUtils.hasText(wuser.getGzhOpenid())) {
|
||||
return new Result<String>().error("未关注公众号!");
|
||||
}
|
||||
|
||||
MessageTemplateSendData sendData = new MessageTemplateSendData();
|
||||
sendData.setTouser(wuser.getGzhOpenid());
|
||||
String templateId = "";
|
||||
@ -126,7 +128,7 @@ public class GZHMessageTemplateService {
|
||||
break;
|
||||
// 充电完成,待结算
|
||||
case 2:
|
||||
templateId = gzhProperties.getOrderEndTemplateId();
|
||||
templateId = gzhProperties.getOrderToPayTemplateId();
|
||||
miniprogram.setPath(orderPage);
|
||||
ChargeTemplateData chargeData = new ChargeTemplateData();
|
||||
chargeData.setCharacter_string14(osb.getOrderNo());
|
||||
@ -164,6 +166,11 @@ public class GZHMessageTemplateService {
|
||||
}
|
||||
|
||||
|
||||
public Result<String> sendTemplateMessageOrder2(Integer id, Integer templateType) {
|
||||
OrderSwapBattery order = orderSwapBatteryDao.selectById(id);
|
||||
return sendTemplateMessageOrder(order, templateType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 充值成功推送公众号消息
|
||||
* @param osb
|
||||
|
||||
@ -0,0 +1,154 @@
|
||||
package com.evotech.hd.wechat.service.impl;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.common.core.dao.wechat.WechatUserDao;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatPayPreOrder;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
import com.evotech.hd.common.core.utils.XCXUtil;
|
||||
import com.evotech.hd.wechat.config.XcxProperties;
|
||||
import com.evotech.hd.wechat.entity.NativePayVO;
|
||||
import com.evotech.hd.wechat.service.WechatNativePayService;
|
||||
import com.evotech.hd.wechat.utils.wechatpay.WechatPayComponent;
|
||||
import com.evotech.hd.wechat.utils.wechatpay.NativePayUtil;
|
||||
import com.evotech.hd.wechat.utils.wechatpay.WechatPayUtil;
|
||||
import com.wechat.pay.java.core.RSAPublicKeyConfig;
|
||||
import com.wechat.pay.java.core.notification.RSAPublicKeyNotificationConfig;
|
||||
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
|
||||
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.Detail;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.GoodsDetail;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.QueryOrderByIdRequest;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.QueryOrderByOutTradeNoRequest;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.SceneInfo;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
@Service
|
||||
public class WechatNativePayServiceImpl implements WechatNativePayService {
|
||||
|
||||
@Resource
|
||||
private RSAPublicKeyConfig config;
|
||||
@Resource
|
||||
private RSAPublicKeyNotificationConfig notificationConfig;
|
||||
@Resource
|
||||
private XcxProperties xcxProperties;
|
||||
@Resource
|
||||
private WechatUserDao wechatUserDao;
|
||||
@Resource
|
||||
private WechatPayComponent wechatPayComponent;
|
||||
|
||||
@Override
|
||||
public Result<String> nativePrepay(NativePayVO prePay) {
|
||||
// 校验用户
|
||||
WechatUser wuser = wechatUserDao.selectOne(new QueryWrapper<WechatUser>().eq("wuid", prePay.getWuid()));
|
||||
if (wuser == null || !StringUtils.hasText(wuser.getOpenid())) {
|
||||
return new Result<String>().error("用户信息错误");
|
||||
}
|
||||
WechatPayPreOrder preOrder = new WechatPayPreOrder();
|
||||
// 组装数据
|
||||
PrepayRequest request = new PrepayRequest();
|
||||
// 基础信息
|
||||
request.setTimeExpire(prePay.getTimeExp() == null
|
||||
? DateUtil.format(DateUtil.offsetMinute(new Date(), 30), DatePattern.UTC_PATTERN)
|
||||
: DateUtil.format(prePay.getTimeExp(), DatePattern.UTC_PATTERN));
|
||||
request.setAttach(prePay.getAttach());
|
||||
request.setAppid(xcxProperties.getAppid());
|
||||
request.setMchid(xcxProperties.getMchid());
|
||||
request.setDescription(prePay.getDescription());
|
||||
request.setNotifyUrl(xcxProperties.getNativeNotifyUrl());
|
||||
request.setOutTradeNo(XCXUtil.payOutTradeNo(prePay.getStationCode()));
|
||||
// 金额
|
||||
Amount amount = new Amount();
|
||||
// amount.setTotal(prePay.getMoney());
|
||||
amount.setTotal(1);
|
||||
request.setAmount(amount);
|
||||
preOrder.setTotal(amount.getTotal());
|
||||
// 付款人 不需要
|
||||
|
||||
// 商品信息
|
||||
Detail detail = new Detail();
|
||||
detail.setCostPrice(prePay.getCostPrice());
|
||||
detail.setInvoiceId(prePay.getInvoiceId());
|
||||
List<GoodsDetail> goodsDetail = prePay.getGoodsDetail();
|
||||
if (goodsDetail != null && !goodsDetail.isEmpty()) {
|
||||
detail.setGoodsDetail(goodsDetail);
|
||||
preOrder.setGoodsDetail(JSONUtil.toJsonStr(goodsDetail));
|
||||
request.setDetail(detail);
|
||||
}
|
||||
|
||||
// 场景信息
|
||||
if (StringUtils.hasText(prePay.getPayerClientIp())) {
|
||||
SceneInfo si = new SceneInfo();
|
||||
si.setPayerClientIp(prePay.getPayerClientIp());
|
||||
si.setDeviceId(prePay.getDeviceId());
|
||||
request.setSceneInfo(si);
|
||||
preOrder.setPayerClientIp(prePay.getPayerClientIp());
|
||||
preOrder.setDeviceId(prePay.getDeviceId());
|
||||
}
|
||||
PrepayResponse response = NativePayUtil.nativePrepay(config, request);
|
||||
// System.out.println("\r\n=====response>>>>>" + response);
|
||||
// 写表
|
||||
BeanUtils.copyProperties(request, preOrder);
|
||||
wechatPayComponent.wechatPrePayLog(prePay.getWuid(), prePay.getCostPrice(), preOrder, JSONUtil.toJsonStr(response));
|
||||
|
||||
return new Result<String>().success(response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public ResponseEntity<String> nativeBack(HttpServletRequest request) {
|
||||
// 1. 验签解密
|
||||
Transaction transaction;
|
||||
try {
|
||||
transaction = WechatPayUtil.decryptWechatPayNotify(request, notificationConfig);
|
||||
} catch (Exception e) {
|
||||
JSONObject jo = new JSONObject();
|
||||
jo.set("code", "FAIL");
|
||||
jo.set("message", "解析body异常");
|
||||
return new ResponseEntity<String>(jo.toJSONString(0), HttpStatus.FAILED_DEPENDENCY);
|
||||
}
|
||||
// 2. 业务处理逻辑
|
||||
wechatPayComponent.wechatPayBussinessHandle(transaction);
|
||||
|
||||
// 3. 回复微信
|
||||
return new ResponseEntity<String>("", HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> orderQuery(Integer type, String transactionId, String outTradeNo) {
|
||||
NativePayService nativeService = new NativePayService.Builder().config(config).build();
|
||||
Transaction transaction;
|
||||
if (type == 1) {
|
||||
QueryOrderByIdRequest request = new QueryOrderByIdRequest();
|
||||
request.setTransactionId(transactionId);
|
||||
request.setMchid(xcxProperties.getMchid());
|
||||
transaction = nativeService.queryOrderById(request);
|
||||
} else {
|
||||
QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
|
||||
request.setMchid(xcxProperties.getMchid());
|
||||
request.setOutTradeNo(outTradeNo);
|
||||
transaction = nativeService.queryOrderByOutTradeNo(request);
|
||||
}
|
||||
return new Result<String>().success(transaction);
|
||||
}
|
||||
|
||||
}
|
||||
@ -14,15 +14,13 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.common.core.dao.wechat.WechatPayPreOrderDao;
|
||||
import com.evotech.hd.common.core.dao.wechat.WechatUserDao;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.TradeDetail;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatPayAttach;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatPayPreOrder;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
import com.evotech.hd.common.core.utils.XCXUtil;
|
||||
import com.evotech.hd.wechat.config.XcxProperties;
|
||||
import com.evotech.hd.wechat.entity.PrePayVO;
|
||||
import com.evotech.hd.wechat.service.WechatPayService;
|
||||
import com.evotech.hd.wechat.service.rpc.CloudService;
|
||||
import com.evotech.hd.wechat.utils.wechatpay.WechatPayComponent;
|
||||
import com.evotech.hd.wechat.utils.wechatpay.WechatPayUtil;
|
||||
import com.wechat.pay.java.core.RSAPublicKeyConfig;
|
||||
import com.wechat.pay.java.core.notification.NotificationParser;
|
||||
@ -43,7 +41,6 @@ import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByIdRequest;
|
||||
import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest;
|
||||
import com.wechat.pay.java.service.payments.jsapi.model.SceneInfo;
|
||||
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||
import com.wechat.pay.java.service.payments.model.Transaction.TradeTypeEnum;
|
||||
import com.wechat.pay.java.service.refund.RefundService;
|
||||
import com.wechat.pay.java.service.refund.model.AmountReq;
|
||||
import com.wechat.pay.java.service.refund.model.CreateRequest;
|
||||
@ -75,7 +72,7 @@ public class WechatPayServiceImpl implements WechatPayService {
|
||||
@Resource
|
||||
private WechatPayPreOrderDao preOrderDao;
|
||||
@Resource
|
||||
private CloudService cloudService;
|
||||
private WechatPayComponent wechatPayComponent;
|
||||
|
||||
|
||||
@Override
|
||||
@ -101,6 +98,7 @@ public class WechatPayServiceImpl implements WechatPayService {
|
||||
// amount.setTotal(prePay.getMoney());
|
||||
amount.setTotal(1);
|
||||
request.setAmount(amount);
|
||||
preOrder.setTotal(amount.getTotal());
|
||||
// 付款人
|
||||
Payer payer = new Payer();
|
||||
payer.setOpenid(wuser.getOpenid());
|
||||
@ -128,14 +126,8 @@ public class WechatPayServiceImpl implements WechatPayService {
|
||||
PrepayWithRequestPaymentResponse response = WechatPayUtil.jsapiPrepay(config, request);
|
||||
// System.out.println("\r\n=====response>>>>>" + response);
|
||||
// 写表
|
||||
BeanUtils.copyProperties(request, preOrder);
|
||||
preOrder.setPrePayResponse(JSONUtil.toJsonStr(response));
|
||||
preOrder.setWuid(prePay.getWuid());
|
||||
preOrder.setTotal(amount.getTotal());
|
||||
preOrder.setOpenid(payer.getOpenid());
|
||||
preOrder.setCostPrice(prePay.getCostPrice());
|
||||
preOrder.setCtime(new Date());
|
||||
preOrderDao.insert(preOrder);
|
||||
BeanUtils.copyProperties(request, preOrder);
|
||||
wechatPayComponent.wechatPrePayLog(prePay.getWuid(), prePay.getCostPrice(), preOrder, JSONUtil.toJsonStr(response));
|
||||
|
||||
return new Result<String>().success(response);
|
||||
}
|
||||
@ -148,7 +140,7 @@ public class WechatPayServiceImpl implements WechatPayService {
|
||||
// 1. 验签解密
|
||||
Transaction transaction;
|
||||
try {
|
||||
transaction = decryptWechatPayNotify(request);
|
||||
transaction = WechatPayUtil.decryptWechatPayNotify(request, notificationConfig);
|
||||
} catch (Exception e) {
|
||||
JSONObject jo = new JSONObject();
|
||||
jo.set("code", "FAIL");
|
||||
@ -156,98 +148,14 @@ public class WechatPayServiceImpl implements WechatPayService {
|
||||
return new ResponseEntity<String>(jo.toJSONString(0), HttpStatus.FAILED_DEPENDENCY);
|
||||
}
|
||||
// 2. 业务处理逻辑
|
||||
wechatPayBussinessHandle(transaction);
|
||||
wechatPayComponent.wechatPayBussinessHandle(transaction);
|
||||
|
||||
// 3. 回复微信
|
||||
return new ResponseEntity<String>("", HttpStatus.OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付回调 解密
|
||||
* @param request
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private Transaction decryptWechatPayNotify(HttpServletRequest request) throws IOException {
|
||||
String body = "";
|
||||
try {
|
||||
ServletInputStream inputStream = request.getInputStream();
|
||||
body = IOUtil.toString(inputStream);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
// 1. 初始化解析器
|
||||
NotificationParser parser = new NotificationParser(notificationConfig);
|
||||
// 2. 构造解析器所需参数
|
||||
RequestParam param = new RequestParam.Builder()
|
||||
// 序列号
|
||||
.serialNumber(request.getHeader("Wechatpay-Serial"))
|
||||
// 随机数
|
||||
.nonce(request.getHeader("Wechatpay-Nonce"))
|
||||
// 签名
|
||||
.signature(request.getHeader("Wechatpay-Signature"))
|
||||
// 时间戳
|
||||
.timestamp(request.getHeader("Wechatpay-Timestamp"))
|
||||
// 默认值为 WECHATPAY2-SHA256-RSA2048
|
||||
.signType(request.getHeader("Wechatpay-Signature-Type"))
|
||||
.body(body)
|
||||
.build();
|
||||
// 3. 验签、解密,parse方法中包含2个方法,一个验签,一个解密
|
||||
Transaction transaction;
|
||||
try {
|
||||
transaction = parser.parse(param, Transaction.class);
|
||||
log.info("\r\n===>>>支付回调信息:" + JSONUtil.toJsonStr(transaction));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付回调业务处理
|
||||
* @param transaction
|
||||
*/
|
||||
private void wechatPayBussinessHandle(Transaction transaction) {
|
||||
// 1. 生成交易信息
|
||||
TradeDetail tradeDetail = new TradeDetail();
|
||||
BeanUtils.copyProperties(transaction, tradeDetail);
|
||||
|
||||
WechatUser wuser = wechatUserDao.selectOne(new QueryWrapper<WechatUser>().eq("openid", transaction.getPayer().getOpenid()));
|
||||
if (wuser != null) {
|
||||
tradeDetail.setPayer(wuser.getWuid());
|
||||
} else {
|
||||
tradeDetail.setPayer(transaction.getPayer().getOpenid());
|
||||
}
|
||||
// 附加信息处理
|
||||
WechatPayAttach payAttach = JSONUtil.toBean(transaction.getAttach(), WechatPayAttach.class);
|
||||
tradeDetail.setTradeType(payAttach.getType());
|
||||
tradeDetail.setTrader(payAttach.getTrader());
|
||||
tradeDetail.setTraderCode(payAttach.getTraderCode());
|
||||
tradeDetail.setWallet(payAttach.getWalletCode());
|
||||
if (payAttach.getType() == 2) {
|
||||
tradeDetail.setOrderNo(payAttach.getOrderNo());
|
||||
tradeDetail.setOrderCount(payAttach.getOrderNo().split(",").length);
|
||||
}
|
||||
|
||||
tradeDetail.setTradeAmount(transaction.getAmount().getPayerTotal());
|
||||
|
||||
TradeTypeEnum tradePayType = transaction.getTradeType();
|
||||
if (tradePayType.equals(Transaction.TradeTypeEnum.JSAPI)) {
|
||||
tradeDetail.setPayType(21);
|
||||
}
|
||||
if (tradePayType.equals(Transaction.TradeTypeEnum.NATIVE)) {
|
||||
tradeDetail.setPayType(22);
|
||||
}
|
||||
|
||||
tradeDetail.setPayResult(transaction.getTradeState().name());
|
||||
tradeDetail.setPayMsg(transaction.getTradeStateDesc());
|
||||
tradeDetail.setPayTime(DateUtil.parseUTC(transaction.getSuccessTime()));
|
||||
|
||||
// 2. 处理订单,看要不要异步
|
||||
cloudService.wechatPayNotifyHandle(tradeDetail);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result<String> orderQuery(Integer type, String transactionId, String outTradeNo) {
|
||||
|
||||
@ -84,7 +84,7 @@ public class WechatUserServiceImpl implements WechatUserService {
|
||||
|
||||
@Override
|
||||
public Result<List<WalletAccount>> listWallet(String wuid, HttpServletRequest request) {
|
||||
if (!wuid.equals(request.getHeader(HDConstant.WECHAT_SERVER_AUTHORIZATION_KEY))) {
|
||||
if (wuid == null || !wuid.equals(request.getHeader(HDConstant.WECHAT_SERVER_AUTHORIZATION_KEY))) {
|
||||
return new Result<List<WalletAccount>>().error("账号错误");
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
package com.evotech.hd.wechat.utils.wechatpay;
|
||||
|
||||
import com.wechat.pay.java.core.Config;
|
||||
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
|
||||
|
||||
/**
|
||||
* 微信支付工具类2
|
||||
*/
|
||||
public class NativePayUtil {
|
||||
|
||||
/**
|
||||
* Native下单
|
||||
* @param config
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static PrepayResponse nativePrepay(Config config, PrepayRequest request) {
|
||||
NativePayService nativeService = new NativePayService.Builder().config(config).build();
|
||||
PrepayResponse response = nativeService.prepay(request);
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
package com.evotech.hd.wechat.utils.wechatpay;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.common.core.dao.wechat.WechatPayPreOrderDao;
|
||||
import com.evotech.hd.common.core.dao.wechat.WechatUserDao;
|
||||
import com.evotech.hd.common.core.entity.cloud.TradeDetail;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatPayAttach;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatPayPreOrder;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
import com.evotech.hd.common.core.enums.PayTypeEnums;
|
||||
import com.evotech.hd.common.core.enums.TradeTypeEnums;
|
||||
import com.evotech.hd.common.core.enums.WechatPayApiTypeEnums;
|
||||
import com.evotech.hd.wechat.service.rpc.CloudService;
|
||||
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||
import com.wechat.pay.java.service.payments.model.Transaction.TradeTypeEnum;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Component
|
||||
public class WechatPayComponent {
|
||||
|
||||
@Resource
|
||||
private WechatPayPreOrderDao preOrderDao;
|
||||
@Resource
|
||||
private WechatUserDao wechatUserDao;
|
||||
@Resource
|
||||
private CloudService cloudService;
|
||||
|
||||
/**
|
||||
* 记录预支付订单信息
|
||||
* @param wuid
|
||||
* @param costPrice
|
||||
* @param preOrder
|
||||
* @param jsonStrResponse
|
||||
*/
|
||||
public void wechatPrePayLog(String wuid, Integer costPrice, WechatPayPreOrder preOrder,
|
||||
String jsonStrResponse) {
|
||||
preOrder.setPrePayResponse(jsonStrResponse);
|
||||
preOrder.setType(Transaction.TradeTypeEnum.NATIVE.name());
|
||||
preOrder.setWuid(wuid);
|
||||
preOrder.setCostPrice(costPrice);
|
||||
preOrder.setCtime(new Date());
|
||||
preOrderDao.insert(preOrder);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 微信支付回调业务处理
|
||||
* @param transaction
|
||||
*/
|
||||
public void wechatPayBussinessHandle(Transaction transaction) {
|
||||
// 1. 生成交易信息
|
||||
TradeDetail tradeDetail = new TradeDetail();
|
||||
BeanUtils.copyProperties(transaction, tradeDetail);
|
||||
|
||||
WechatUser wuser = wechatUserDao.selectOne(new QueryWrapper<WechatUser>().eq("openid", transaction.getPayer().getOpenid()));
|
||||
if (wuser != null) {
|
||||
tradeDetail.setPayer(wuser.getWuid());
|
||||
} else {
|
||||
tradeDetail.setPayer(transaction.getPayer().getOpenid());
|
||||
}
|
||||
// 附加信息处理
|
||||
WechatPayAttach payAttach = JSONUtil.toBean(transaction.getAttach(), WechatPayAttach.class);
|
||||
tradeDetail.setTradeType(payAttach.getType());
|
||||
tradeDetail.setTrader(payAttach.getTrader());
|
||||
tradeDetail.setTraderCode(payAttach.getTraderCode());
|
||||
tradeDetail.setWallet(payAttach.getWalletCode());
|
||||
tradeDetail.setDescription(payAttach.getDescription());
|
||||
if (payAttach.getType() == TradeTypeEnums.PAYORDER.getCode()) {
|
||||
tradeDetail.setOrderNo(payAttach.getOrderNo());
|
||||
tradeDetail.setOrderCount(payAttach.getOrderNo().split(",").length);
|
||||
}
|
||||
|
||||
tradeDetail.setTradeAmount(transaction.getAmount().getPayerTotal());
|
||||
tradeDetail.setPayType(PayTypeEnums.WECHAT.getCode());
|
||||
|
||||
TradeTypeEnum tradePayType = transaction.getTradeType();
|
||||
if (tradePayType.equals(Transaction.TradeTypeEnum.JSAPI)) {
|
||||
tradeDetail.setWechatPayApiType(WechatPayApiTypeEnums.JSAPI.getCode());
|
||||
}
|
||||
if (tradePayType.equals(Transaction.TradeTypeEnum.NATIVE)) {
|
||||
tradeDetail.setWechatPayApiType(WechatPayApiTypeEnums.NATIVE.getCode());
|
||||
}
|
||||
|
||||
tradeDetail.setPayResult(transaction.getTradeState().name());
|
||||
tradeDetail.setPayMsg(transaction.getTradeStateDesc());
|
||||
tradeDetail.setPayTime(DateUtil.parseUTC(transaction.getSuccessTime()));
|
||||
|
||||
// 2. 处理订单,看要不要异步
|
||||
cloudService.wechatPayNotifyHandle(tradeDetail);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,13 +1,27 @@
|
||||
package com.evotech.hd.wechat.utils.wechatpay;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.wechat.pay.java.core.Config;
|
||||
import com.wechat.pay.java.core.notification.NotificationParser;
|
||||
import com.wechat.pay.java.core.notification.RSAPublicKeyNotificationConfig;
|
||||
import com.wechat.pay.java.core.notification.RequestParam;
|
||||
import com.wechat.pay.java.core.util.IOUtil;
|
||||
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
|
||||
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
|
||||
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import jakarta.servlet.ServletInputStream;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
|
||||
|
||||
/**
|
||||
* 微信支付工具类
|
||||
*/
|
||||
@Slf4j
|
||||
public class WechatPayUtil {
|
||||
|
||||
/**
|
||||
@ -21,8 +35,47 @@ public class WechatPayUtil {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 微信支付回调 解密
|
||||
* @param request
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static Transaction decryptWechatPayNotify(HttpServletRequest request, RSAPublicKeyNotificationConfig notificationConfig) throws IOException {
|
||||
String body = "";
|
||||
try {
|
||||
ServletInputStream inputStream = request.getInputStream();
|
||||
body = IOUtil.toString(inputStream);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
// 1. 初始化解析器
|
||||
NotificationParser parser = new NotificationParser(notificationConfig);
|
||||
// 2. 构造解析器所需参数
|
||||
RequestParam param = new RequestParam.Builder()
|
||||
// 序列号
|
||||
.serialNumber(request.getHeader("Wechatpay-Serial"))
|
||||
// 随机数
|
||||
.nonce(request.getHeader("Wechatpay-Nonce"))
|
||||
// 签名
|
||||
.signature(request.getHeader("Wechatpay-Signature"))
|
||||
// 时间戳
|
||||
.timestamp(request.getHeader("Wechatpay-Timestamp"))
|
||||
// 默认值为 WECHATPAY2-SHA256-RSA2048
|
||||
.signType(request.getHeader("Wechatpay-Signature-Type"))
|
||||
.body(body)
|
||||
.build();
|
||||
// 3. 验签、解密,parse方法中包含2个方法,一个验签,一个解密
|
||||
Transaction transaction;
|
||||
try {
|
||||
transaction = parser.parse(param, Transaction.class);
|
||||
log.info("\r\n===>>>支付回调信息:" + JSONUtil.toJsonStr(transaction));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -60,6 +60,8 @@ hbyt:
|
||||
public_key_path: src/main/resources/static/key/pub_key.pem
|
||||
# 支付回调地址
|
||||
notify_url: https://api.evo-techina.com/wechat/wechatpay/prepayback/msg
|
||||
# Native支付回调地址
|
||||
native_notify_url: https://api.evo-techina.com/wechat/wechatpay/native/nativeback/msg
|
||||
# 退款回调地址
|
||||
refund_notify_url: https://api.evo-techina.com/wechat/wechatpay/refundsback/msg
|
||||
# token缓存时效:小时
|
||||
|
||||
Loading…
Reference in New Issue
Block a user