Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
da8e224fae
@ -9,7 +9,7 @@ spring:
|
||||
time-zone: GMT+8
|
||||
cloud:
|
||||
nacos:
|
||||
server-addr: 192.168.2.226:8848 # nacos
|
||||
server-addr: 127.0.0.1:8848 # nacos
|
||||
username: nacos
|
||||
password: nacos
|
||||
kafka:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cdzy.ebikemaintenance.model.pojo;
|
||||
package com.cdzy.ebikemaintenance.model.dto.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@ -16,7 +16,6 @@ import com.cdzy.ebikemaintenance.model.dto.response.*;
|
||||
import com.cdzy.ebikemaintenance.model.pojo.*;
|
||||
import com.cdzy.ebikemaintenance.service.EbikeBikeInfoService;
|
||||
import com.cdzy.ebikemaintenance.service.EbikeBikeOrderService;
|
||||
import com.cdzy.ebikemaintenance.service.EbikeScheduleWorkOrderExtensionService;
|
||||
import com.cdzy.ebikemaintenance.utils.GeoCodingUtil;
|
||||
import com.cdzy.ebikemaintenance.utils.MinioUtil;
|
||||
import com.cdzy.ebikemaintenance.utils.RedisUtil;
|
||||
@ -35,7 +34,6 @@ import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.kafka.common.errors.ResourceNotFoundException;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
@ -124,6 +122,8 @@ public class EbikeBikeInfoServiceImpl extends ServiceImpl<EbikeBikeInfoMapper, E
|
||||
private EbikeDispatchRecordsMapper ebikeDispatchRecordsMapper;
|
||||
@Resource
|
||||
private EbikeScheduleWorkOrderExtensionMapper ebikeScheduleWorkOrderExtensionMapper;
|
||||
@Autowired
|
||||
private EbikeVehicleDispatchFileMapper ebikeVehicleDispatchFileMapper;
|
||||
|
||||
@Override
|
||||
public EbikeBikeInfo getByBikeCode(String bikeCode) {
|
||||
@ -1347,6 +1347,29 @@ public class EbikeBikeInfoServiceImpl extends ServiceImpl<EbikeBikeInfoMapper, E
|
||||
public JsonResult<?> completeDeployment(Map<String,Object> param) {
|
||||
|
||||
String orderId = MapUtil.getStr(param, "orderId");
|
||||
List<Map<String,Object>> fileLists = (List<Map<String,Object>>) param.get("fileLists");
|
||||
//设置一个关联ID
|
||||
if(fileLists!=null && fileLists.size()>0){
|
||||
String after_dispatch_photo=UUID.randomUUID().toString();
|
||||
EbikeScheduleWorkOrderExtension ebikeScheduleWorkOrderExtension = new EbikeScheduleWorkOrderExtension();
|
||||
ebikeScheduleWorkOrderExtension.setAfterDispatchPhoto(after_dispatch_photo);
|
||||
ebikeScheduleWorkOrderExtension.setId(orderId);
|
||||
ebikeScheduleWorkOrderExtensionMapper.update(ebikeScheduleWorkOrderExtension);
|
||||
|
||||
for (Map<String,Object> fileList : fileLists) {
|
||||
EbikeVehicleDispatchFile ebikeVehicleDispatchFile = new EbikeVehicleDispatchFile();
|
||||
ebikeVehicleDispatchFile.setFileName(fileList.get("fileName") != null ? fileList.get("fileName").toString() : "");
|
||||
ebikeVehicleDispatchFile.setFileSize(fileList.get("fileSize") != null ? fileList.get("fileSize").toString() : "");
|
||||
ebikeVehicleDispatchFile.setFileType(fileList.get("fileType") != null ? fileList.get("fileType").toString() : "");
|
||||
ebikeVehicleDispatchFile.setFileBucket(fileList.get("fileBucket") != null ? fileList.get("fileBucket").toString() : "");
|
||||
ebikeVehicleDispatchFile.setFileUniqueKey(fileList.get("fileUniqueKey") != null ? fileList.get("fileUniqueKey").toString() : "");
|
||||
ebikeVehicleDispatchFile.setCreatedAt(LocalDateTime.now());
|
||||
ebikeVehicleDispatchFile.setUpdatedAt(LocalDateTime.now());
|
||||
ebikeVehicleDispatchFile.setReportId(after_dispatch_photo);
|
||||
ebikeVehicleDispatchFileMapper.insert(ebikeVehicleDispatchFile);
|
||||
}
|
||||
}
|
||||
|
||||
//根据orderId 完成订单
|
||||
EbikeBikeOrder ebikeBikeOrder = new EbikeBikeOrder();
|
||||
ebikeBikeOrder.setOrderId(orderId);
|
||||
|
||||
@ -15,6 +15,7 @@ import com.cdzy.ebikeoperate.model.pojo.EbikeSysRcostsetWeek;
|
||||
import com.cdzy.ebikeoperate.service.EbikeSysRcostsetService;
|
||||
import com.cdzy.ebikeoperate.service.EbikeSysRcostsetTimePeriodService;
|
||||
import com.cdzy.ebikeoperate.service.EbikeSysRcostsetWeekService;
|
||||
import com.mybatisflex.core.keygen.impl.SnowFlakeIDKeyGenerator;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@ -210,4 +211,17 @@ public class EbikeSysRcostsetController {
|
||||
return JsonResult.failed("更新失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成一个雪花id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("createSnowflakeId")
|
||||
public JsonResult<Object> createSnowflakeId() {
|
||||
|
||||
SnowFlakeIDKeyGenerator snowFlakeIDKeyGenerator = new SnowFlakeIDKeyGenerator();
|
||||
long dataCenterId = snowFlakeIDKeyGenerator.nextId();
|
||||
return JsonResult.success(dataCenterId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.cdzy.ebikeoperate.controller;
|
||||
|
||||
import com.cdzy.common.model.JsonResult;
|
||||
import com.cdzy.ebikeoperate.model.dto.request.ReqEbikeSysRoperatesetsDto;
|
||||
import com.cdzy.ebikeoperate.model.dto.response.ResEbikeSysRoperatesetsDto;
|
||||
import com.cdzy.ebikeoperate.model.pojo.EbikeSysRoperateset;
|
||||
@ -27,8 +28,9 @@ public class EbikeSysRoperatesetController {
|
||||
* @return {@code true} 添加成功,{@code false} 添加失败
|
||||
*/
|
||||
@PostMapping("save")
|
||||
public boolean save(@RequestBody ReqEbikeSysRoperatesetsDto reqEbikeSysRoperatesetsDto) {
|
||||
return ebikeSysRoperatesetService.save(reqEbikeSysRoperatesetsDto);
|
||||
public JsonResult<?> save(@RequestBody ReqEbikeSysRoperatesetsDto reqEbikeSysRoperatesetsDto) {
|
||||
Boolean save = ebikeSysRoperatesetService.save(reqEbikeSysRoperatesetsDto);
|
||||
return save ? JsonResult.success(true) : JsonResult.failed("");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,9 +45,9 @@ public class EbikeSysRoperatesetController {
|
||||
}
|
||||
|
||||
@RequestMapping("getRegionConfigById")
|
||||
public ResEbikeSysRoperatesetsDto getRegionConfigById(@RequestParam(value = "regionId")
|
||||
String regionId) {
|
||||
public JsonResult<?> getRegionConfigById(@RequestParam(value = "regionId")
|
||||
String regionId) {
|
||||
ResEbikeSysRoperatesetsDto resEbikeSysRoperatesetsDto = new ResEbikeSysRoperatesetsDto();
|
||||
return resEbikeSysRoperatesetsDto;
|
||||
return JsonResult.success(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,9 @@ import java.util.List;
|
||||
@Data
|
||||
public class ReqEbikeSysRcostsetDto implements Serializable {
|
||||
|
||||
|
||||
private String costConfigId;
|
||||
|
||||
/**
|
||||
* 区域id
|
||||
*/
|
||||
|
||||
@ -4,6 +4,7 @@ import com.cdzy.ebikeoperate.mapper.EbikeSysLinktelMapper;
|
||||
import com.cdzy.ebikeoperate.mapper.EbikeSysOperateSetMapper;
|
||||
import com.cdzy.ebikeoperate.model.dto.request.ReqEbikeSysRoperatesetDto;
|
||||
import com.cdzy.ebikeoperate.model.dto.request.ReqEbikeSysRoperatesetsDto;
|
||||
import com.cdzy.ebikeoperate.model.pojo.EbikeSysRcostset;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import com.cdzy.ebikeoperate.model.pojo.EbikeSysRoperateset;
|
||||
@ -11,6 +12,7 @@ import com.cdzy.ebikeoperate.mapper.EbikeSysRoperatesetMapper;
|
||||
import com.cdzy.ebikeoperate.service.EbikeSysRoperatesetService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -63,7 +65,8 @@ public class EbikeSysRoperatesetServiceImpl extends ServiceImpl<EbikeSysRoperate
|
||||
public Boolean save(ReqEbikeSysRoperatesetsDto reqEbikeSysRoperatesetsDto) {
|
||||
|
||||
ReqEbikeSysRoperatesetDto reqEbikeSysRoperatesetDto = reqEbikeSysRoperatesetsDto.getReqEbikeSysRoperatesetDto();
|
||||
|
||||
return null;
|
||||
EbikeSysRoperateset ebikeSysRoperateset = new EbikeSysRoperateset();
|
||||
BeanUtils.copyProperties(reqEbikeSysRoperatesetDto,ebikeSysRoperateset);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,8 +86,8 @@ sa-token:
|
||||
is-log: true
|
||||
wechat:
|
||||
url: https://api.weixin.qq.com/sns/jscode2session
|
||||
appid: wx399ab8cf933bf77f
|
||||
app-secret: 94947f6a23e456c89e47bb5f6eb32186
|
||||
appid: wx327d788d7bd6eddf
|
||||
app-secret: 9adf2539a6c26499c67b5a3829f2e05e3
|
||||
minio:
|
||||
endpoint: http://192.168.2.226:9000 # MinIO服务器地址
|
||||
access-key: eQtGmQBEsGxNHrTd7AkJ # 访问密钥
|
||||
|
||||
@ -110,6 +110,12 @@
|
||||
<version>${mysql.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- for test only -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@ -8,7 +8,6 @@ import com.wechat.pay.java.service.payments.jsapi.JsapiService;
|
||||
import com.wechat.pay.java.service.refund.RefundService;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -57,12 +56,11 @@ public class WxPayConfig {
|
||||
private String refundNotifyUrl;
|
||||
/**
|
||||
* 支付、退款过期时间(分钟)
|
||||
* 默认30分钟,超过30分钟订单会自动关闭
|
||||
* 默认5分钟,超过5分钟订单会自动关闭
|
||||
*/
|
||||
private Integer expireMinute = 30;
|
||||
private Integer expireMinute = 5;
|
||||
|
||||
@Bean("certConfig")
|
||||
private Config certificateConfig() {
|
||||
public Config certificateConfig() {
|
||||
return new RSAAutoCertificateConfig.Builder()
|
||||
.merchantId(merchantId)
|
||||
// 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
||||
@ -73,12 +71,12 @@ public class WxPayConfig {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JsapiService wxJsapiService(@Qualifier("certConfig") Config certificateConfig) {
|
||||
public JsapiService wxJsapiService(Config certificateConfig) {
|
||||
return new JsapiService.Builder().config(certificateConfig).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RefundService wxRefundService(@Qualifier("certConfig") Config certificateConfig) {
|
||||
public RefundService wxRefundService(Config certificateConfig) {
|
||||
return new RefundService.Builder().config(certificateConfig).build();
|
||||
}
|
||||
|
||||
@ -87,4 +85,5 @@ public class WxPayConfig {
|
||||
PrivateKey privateKey = PemUtil.loadPrivateKeyFromPath(privateKeyPath);
|
||||
return new RSASigner(merchantSerialNumber, privateKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -4,10 +4,12 @@ import com.alibaba.fastjson2.JSONObject;
|
||||
import com.cdzy.common.model.JsonResult;
|
||||
import com.cdzy.payment.model.dto.EbikePaymentDto;
|
||||
import com.cdzy.payment.model.dto.EbikeRefundDto;
|
||||
import com.cdzy.payment.model.dto.HandleNotifyResult;
|
||||
import com.cdzy.payment.service.WxPayService;
|
||||
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||
import com.wechat.pay.java.service.refund.model.Refund;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -15,12 +17,16 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 用户订单微信支付 控制层。
|
||||
*
|
||||
* @author dingchao
|
||||
* @since 2025-04-24
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/wxPayment")
|
||||
public class EbikeWxPaymentController {
|
||||
@ -87,4 +93,54 @@ public class EbikeWxPaymentController {
|
||||
Refund r = wxPayService.queryRefundByOutNo(outRefundNo);
|
||||
return r == null?JsonResult.failed(String.format("退款单号{%s}查询退款失败", outRefundNo)):JsonResult.success(r);
|
||||
}
|
||||
|
||||
// ================通知回调接口===============
|
||||
// TODO 通知接口不能鉴权
|
||||
/**
|
||||
* 支付回调通知
|
||||
*
|
||||
* @param request 支付回调请求
|
||||
* @param response 支付回调响应
|
||||
* @return 支付回调响应
|
||||
*/
|
||||
@PostMapping("/pay/notify")
|
||||
public String payNotify(HttpServletRequest request, HttpServletResponse response) {
|
||||
HandleNotifyResult r = wxPayService.handlePayNotify(request);
|
||||
if(!r.isSuccess()) {
|
||||
response.setStatus(500);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("code", "SYSTEM_ERROR");
|
||||
jsonObject.put("message", r.getMessage());
|
||||
return jsonObject.toJSONString();
|
||||
}
|
||||
response.setStatus(200);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("code", "SUCCESS");
|
||||
jsonObject.put("message", "OK");
|
||||
return jsonObject.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款回调通知
|
||||
*
|
||||
* @param request 退款回调请求
|
||||
* @param response 退款回调响应
|
||||
* @return 退款回调响应
|
||||
*/
|
||||
@PostMapping("/refund/notify")
|
||||
public String refundNotify(HttpServletRequest request, HttpServletResponse response) {
|
||||
HandleNotifyResult r = wxPayService.handleRefundNotify(request);
|
||||
if(!r.isSuccess()) {
|
||||
response.setStatus(500);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("code", "SYSTEM_ERROR");
|
||||
jsonObject.put("message", r.getMessage());
|
||||
return jsonObject.toJSONString();
|
||||
}
|
||||
response.setStatus(200);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("code", "SUCCESS");
|
||||
jsonObject.put("message", "OK");
|
||||
return jsonObject.toJSONString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
package com.cdzy.payment.model.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 回调通知结果
|
||||
*
|
||||
* @author dingchao
|
||||
* @date 2025/4/28
|
||||
* @modified by:
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class HandleNotifyResult {
|
||||
/**
|
||||
* 解析是否成功
|
||||
*/
|
||||
private boolean success = false;
|
||||
/**
|
||||
* 解析错误消息
|
||||
*/
|
||||
private String message;
|
||||
}
|
||||
@ -37,7 +37,6 @@ public class EbikePayment implements Serializable {
|
||||
/**
|
||||
* 骑行订单号
|
||||
*/
|
||||
@Id
|
||||
private String orderId;
|
||||
|
||||
/**
|
||||
|
||||
@ -14,19 +14,27 @@ import java.util.List;
|
||||
*/
|
||||
public interface EbikePaymentService extends IService<EbikePayment> {
|
||||
/**
|
||||
* 查询未支付订单
|
||||
* 查询未支付订单, 未超时的
|
||||
*
|
||||
* @param duration 订单创建时间超过duration分钟,单位分钟
|
||||
* @return 未支付订单列表
|
||||
*/
|
||||
List<EbikePayment> getNoPayOrderByDuration(int duration);
|
||||
|
||||
/**
|
||||
* 查询未支付订单, 超时的
|
||||
*
|
||||
* @param duration 订单创建时间超过duration分钟,单位分钟
|
||||
* @return 未支付订单列表
|
||||
*/
|
||||
List<EbikePayment> getExpireOrderByDuration(int duration);
|
||||
|
||||
/**
|
||||
* 更新支付状态
|
||||
*
|
||||
* @param recordId 记录ID
|
||||
* @param transaction 支付结果
|
||||
* @return 更新成功返回true,否则返回false
|
||||
*/
|
||||
Boolean updatePaymentStatus(String recordId, Transaction transaction);
|
||||
Boolean updatePaymentStatus(Transaction transaction);
|
||||
|
||||
}
|
||||
|
||||
@ -33,9 +33,8 @@ public interface EbikeRefundService extends IService<EbikeRefund> {
|
||||
/**
|
||||
* 更新退款状态
|
||||
*
|
||||
* @param refundId 退款ID
|
||||
* @param refund 退款结果
|
||||
* @return 更新成功返回true,否则返回false
|
||||
*/
|
||||
Boolean updateRefundStatus(String refundId, Refund refund);
|
||||
Boolean updateRefundStatus(Refund refund);
|
||||
}
|
||||
|
||||
@ -5,9 +5,12 @@ import com.alibaba.fastjson2.JSONObject;
|
||||
import com.cdzy.payment.model.dto.AmountDto;
|
||||
import com.cdzy.payment.model.dto.AmountRefundDto;
|
||||
import com.cdzy.payment.model.dto.DetailDto;
|
||||
import com.cdzy.payment.model.dto.HandleNotifyResult;
|
||||
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||
import com.wechat.pay.java.service.refund.model.Refund;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 微信支付服务类(JSAPI支付),小程序
|
||||
*
|
||||
@ -50,6 +53,15 @@ public interface WxPayService {
|
||||
* @return 支付订单信息
|
||||
*/
|
||||
Transaction queryOrderByOutTradeNo(String outTradeNo);
|
||||
|
||||
/**
|
||||
* 处理支付回调
|
||||
*
|
||||
* @param request 回调请求
|
||||
* @return 支付订单信息
|
||||
*/
|
||||
HandleNotifyResult handlePayNotify(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 退款申请
|
||||
*
|
||||
@ -70,4 +82,12 @@ public interface WxPayService {
|
||||
*/
|
||||
Refund queryRefundByOutNo(String outRefundNo);
|
||||
|
||||
/**
|
||||
* 处理支退款回调
|
||||
*
|
||||
* @param request 回调请求
|
||||
* @return 退款订单信息
|
||||
*/
|
||||
HandleNotifyResult handleRefundNotify(HttpServletRequest request);
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.cdzy.payment.service.impl;
|
||||
|
||||
import com.cdzy.payment.model.enums.PayMethod;
|
||||
import com.cdzy.payment.utils.StringUtils;
|
||||
import com.ebike.feign.clients.OrdersFeignClient;
|
||||
import com.ebike.feign.model.res.ResFeignOrderPaymentDto;
|
||||
import com.mybatisflex.core.query.QueryColumn;
|
||||
@ -14,7 +15,6 @@ import com.wechat.pay.java.service.payments.model.Transaction;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static com.cdzy.payment.model.entity.table.EbikePaymentTableDef.EBIKE_PAYMENT;
|
||||
@ -33,24 +33,35 @@ public class EbikePaymentServiceImpl extends ServiceImpl<EbikePaymentMapper, Ebi
|
||||
|
||||
@Override
|
||||
public List<EbikePayment> getNoPayOrderByDuration(int duration) {
|
||||
QueryColumn time = QueryMethods.secToTime(String.valueOf(duration * 60));
|
||||
// trade_state 等于 NOTPAY未支付的, 并且创建时间未超过duration分钟的订单
|
||||
QueryWrapper query = QueryWrapper.create()
|
||||
.where(EBIKE_PAYMENT.TRADE_STATE.eq(Transaction.TradeStateEnum.USERPAYING.ordinal()))
|
||||
.and(QueryMethods.addTime(EBIKE_PAYMENT.CREATE_TIME, time).lt(QueryMethods.now()));
|
||||
return list(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EbikePayment> getExpireOrderByDuration(int duration) {
|
||||
QueryColumn time = QueryMethods.secToTime(String.valueOf(duration * 60));
|
||||
// trade_state 等于 NOTPAY未支付的, 并且创建时间超过duration分钟的订单
|
||||
QueryWrapper query = QueryWrapper.create()
|
||||
.where(EBIKE_PAYMENT.TRADE_STATE.eq(Transaction.TradeStateEnum.NOTPAY.ordinal()))
|
||||
.where(EBIKE_PAYMENT.TRADE_STATE.eq(Transaction.TradeStateEnum.USERPAYING.ordinal()))
|
||||
.and(QueryMethods.addTime(EBIKE_PAYMENT.CREATE_TIME, time).ge(QueryMethods.now()));
|
||||
return list(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updatePaymentStatus(String recordId, Transaction transaction) {
|
||||
public Boolean updatePaymentStatus(Transaction transaction) {
|
||||
EbikePayment ebikePayment = new EbikePayment();
|
||||
ebikePayment.setRecordId(recordId);
|
||||
//ebikePayment.setRecordId(recordId);
|
||||
ebikePayment.setTradeState(String.valueOf(transaction.getTradeState().ordinal()));
|
||||
if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) {
|
||||
// 支付成功, 更新订单状态
|
||||
double v = transaction.getAmount().getTotal().doubleValue() / 100.0;
|
||||
ebikePayment.setTotal(v);
|
||||
ebikePayment.setPaymentTime(LocalDateTime.now());
|
||||
String paymentTime = transaction.getSuccessTime();
|
||||
ebikePayment.setPaymentTime(StringUtils.toLocalDatetime(paymentTime));
|
||||
// 同步支付状态
|
||||
ResFeignOrderPaymentDto paymentParam = new ResFeignOrderPaymentDto();
|
||||
paymentParam.setOrderId(Long.valueOf(transaction.getOutTradeNo()));
|
||||
@ -58,6 +69,8 @@ public class EbikePaymentServiceImpl extends ServiceImpl<EbikePaymentMapper, Ebi
|
||||
paymentParam.setPaymentMethod(PayMethod.wechat.name());
|
||||
ordersFeignClient.payment(paymentParam);
|
||||
}
|
||||
return updateById(ebikePayment);
|
||||
QueryWrapper query = QueryWrapper.create()
|
||||
.where(EBIKE_PAYMENT.PAYMENT_ID.eq(transaction.getTransactionId()));
|
||||
return update(ebikePayment, query);
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,19 +41,21 @@ public class EbikeRefundServiceImpl extends ServiceImpl<EbikeRefundMapper, Ebike
|
||||
public List<EbikeRefund> getNoSuccessRefundOrderByDuration(int duration) {
|
||||
// trade_state 不等于 SUCCESS退款成功的, 并且创建时间超过duration分钟的订单
|
||||
QueryWrapper query = QueryWrapper.create()
|
||||
.where(EBIKE_REFUND.STATUS.ne(Status.SUCCESS.ordinal()))
|
||||
.where(EBIKE_REFUND.STATUS.eq(Status.PROCESSING.ordinal()))
|
||||
.and(QueryMethods.addTime(EBIKE_REFUND.CREATE_TIME, QueryMethods.secToTime(String.valueOf(duration * 60))).ge(QueryMethods.now()));
|
||||
return list(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateRefundStatus(String refundId, Refund refund) {
|
||||
public Boolean updateRefundStatus(Refund refund) {
|
||||
EbikeRefund ebikeRefund = new EbikeRefund();
|
||||
ebikeRefund.setRefundId(refundId);
|
||||
ebikeRefund.setRefundId(refund.getOutRefundNo());
|
||||
ebikeRefund.setStatus(String.valueOf(refund.getStatus().ordinal()));
|
||||
if (Status.SUCCESS.equals(refund.getStatus())) {
|
||||
ebikeRefund.setRefundTime(LocalDateTime.now());
|
||||
ebikeRefund.setRefund(refund.getAmount().getRefund().doubleValue() / 100.0);
|
||||
// 退款成功, 更新订单状态
|
||||
ordersFeignClient.doneRefund(Long.valueOf(refund.getOutTradeNo()));
|
||||
}
|
||||
return updateById(ebikeRefund);
|
||||
}
|
||||
|
||||
@ -3,21 +3,24 @@ package com.cdzy.payment.service.impl;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.cdzy.payment.config.WxPayConfig;
|
||||
import com.cdzy.payment.model.dto.AmountDto;
|
||||
import com.cdzy.payment.model.dto.AmountRefundDto;
|
||||
import com.cdzy.payment.model.dto.DetailDto;
|
||||
import com.cdzy.payment.model.dto.WxJsapiPromptDto;
|
||||
import com.cdzy.payment.model.dto.*;
|
||||
import com.cdzy.payment.model.entity.EbikePayment;
|
||||
import com.cdzy.payment.model.entity.EbikeRefund;
|
||||
import com.cdzy.payment.model.enums.PayMethod;
|
||||
import com.cdzy.payment.service.EbikePaymentService;
|
||||
import com.cdzy.payment.service.EbikeRefundService;
|
||||
import com.cdzy.payment.service.WxPayService;
|
||||
import com.cdzy.payment.utils.StringUtil;
|
||||
import com.cdzy.payment.utils.HttpServletUtils;
|
||||
import com.cdzy.payment.utils.StringUtils;
|
||||
import com.wechat.pay.java.core.Config;
|
||||
import com.wechat.pay.java.core.cipher.RSASigner;
|
||||
import com.wechat.pay.java.core.exception.HttpException;
|
||||
import com.wechat.pay.java.core.exception.MalformedMessageException;
|
||||
import com.wechat.pay.java.core.exception.ServiceException;
|
||||
import com.wechat.pay.java.core.exception.ValidationException;
|
||||
import com.wechat.pay.java.core.notification.NotificationConfig;
|
||||
import com.wechat.pay.java.core.notification.NotificationParser;
|
||||
import com.wechat.pay.java.core.notification.RequestParam;
|
||||
import com.wechat.pay.java.service.payments.jsapi.model.*;
|
||||
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
|
||||
import com.wechat.pay.java.service.payments.jsapi.model.GoodsDetail;
|
||||
@ -29,12 +32,12 @@ import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.*;
|
||||
|
||||
import static com.wechat.pay.java.core.http.Constant.*;
|
||||
import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_SERIAL;
|
||||
|
||||
/**
|
||||
* 微信支付服务类(JSAPI支付),小程序
|
||||
@ -56,6 +59,8 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
@Resource
|
||||
private RSASigner wxRsaSigner;
|
||||
@Resource
|
||||
private Config certificateConfig;
|
||||
@Resource
|
||||
private EbikePaymentService ebikePaymentService;
|
||||
@Resource
|
||||
private EbikeRefundService ebikeRefundService;
|
||||
@ -68,7 +73,7 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
request.setOutTradeNo(outTradeNo);
|
||||
wxJsapiService.closeOrder(request);
|
||||
log.info("关闭订单成功,订单号:{}", outTradeNo);
|
||||
//ebikePaymentService.updatePaymentStatus(outTradeNo, 2);
|
||||
// ebikePaymentService.updatePaymentStatus(outTradeNo, 2);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
logError("关闭订单closeOrder", e);
|
||||
@ -86,7 +91,7 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
request.setOutTradeNo(outTradeNo);
|
||||
request.setNotifyUrl(wxPayConfig.getPayNotifyUrl());
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(wxPayConfig.getExpireMinute());
|
||||
request.setTimeExpire(StringUtil.formatLocalDatetime(expireTime));
|
||||
request.setTimeExpire(StringUtils.formatLocalDatetime(expireTime));
|
||||
request.setGoodsTag(goodsTag);
|
||||
Amount amountReq = new Amount();
|
||||
amountReq.setTotal(BigDecimal.valueOf(amount.getTotal() * 100.0).intValue());
|
||||
@ -121,7 +126,7 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
ebikePayment.setCreateTime(LocalDateTime.now());
|
||||
ebikePayment.setPaymentMethod(PayMethod.wechat.name());
|
||||
ebikePayment.setCostPrice(amount.getTotal());
|
||||
int state = Transaction.TradeStateEnum.NOTPAY.ordinal();
|
||||
int state = Transaction.TradeStateEnum.USERPAYING.ordinal();
|
||||
ebikePayment.setTradeState(String.valueOf(state));
|
||||
ebikePaymentService.save(ebikePayment);
|
||||
// 返回给小程序的参数(调起微信支付)
|
||||
@ -164,11 +169,48 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandleNotifyResult handlePayNotify(HttpServletRequest request) {
|
||||
HandleNotifyResult result = new HandleNotifyResult();
|
||||
// 1. 提取请求头参数
|
||||
String requestId = request.getHeader(REQUEST_ID);
|
||||
String nonce = request.getHeader(WECHAT_PAY_NONCE);
|
||||
String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
|
||||
String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
|
||||
String signatureType = request.getHeader(WECHAT_PAY_SIGNATURE+"-Type");
|
||||
String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
|
||||
|
||||
try {
|
||||
RequestParam requestParam = new RequestParam.Builder()
|
||||
.serialNumber(serialNo)
|
||||
.signature(signature)
|
||||
.signType(signatureType)
|
||||
.timestamp(timestamp)
|
||||
.body(HttpServletUtils.getRequestBody(request))
|
||||
.nonce(nonce)
|
||||
.build();
|
||||
// 验签并解析通知
|
||||
NotificationParser parser = new NotificationParser((NotificationConfig)certificateConfig);
|
||||
// 解析解密后的通知
|
||||
Transaction transaction = parser.parse(requestParam, Transaction.class);
|
||||
// 更新状态
|
||||
ebikePaymentService.updatePaymentStatus(transaction);
|
||||
// 处理成功
|
||||
result.setSuccess(true);
|
||||
result.setMessage("success");
|
||||
return result;
|
||||
}catch (Exception e) {
|
||||
result.setMessage(String.format("verify failed, request-id=[%s]", requestId));
|
||||
logError("支付通知回调handlePayNotify", e);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String refund(String transactionId, String outTradeNo, String reason, AmountRefundDto amount) {
|
||||
try {
|
||||
// 雪花算法生成退款单号
|
||||
String outRefundNo = StringUtil.generateSnowflakeId("refundId");
|
||||
String outRefundNo = StringUtils.generateSnowflakeId("refundId");
|
||||
EbikeRefund ebikeRefund = new EbikeRefund();
|
||||
ebikeRefund.setCreateTime(LocalDateTime.now());
|
||||
// 发起退款
|
||||
@ -193,7 +235,6 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
ebikeRefund.setReason(reason);
|
||||
ebikeRefund.setStatus(String.valueOf(result.getStatus().ordinal()));
|
||||
ebikeRefund.setCurrency(amount.getCurrency());
|
||||
ebikeRefundService.saveRefundResult(ebikeRefund);
|
||||
if(Status.SUCCESS.equals(result.getStatus())){
|
||||
ebikeRefund.setRefund(result.getAmount().getRefund().doubleValue() / 100.0);
|
||||
ebikeRefund.setRefundTime(LocalDateTime.now());
|
||||
@ -221,6 +262,43 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandleNotifyResult handleRefundNotify(HttpServletRequest request) {
|
||||
HandleNotifyResult result = new HandleNotifyResult();
|
||||
// 1. 提取请求头参数
|
||||
String requestId = request.getHeader(REQUEST_ID);
|
||||
String nonce = request.getHeader(WECHAT_PAY_NONCE);
|
||||
String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
|
||||
String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
|
||||
String signatureType = request.getHeader(WECHAT_PAY_SIGNATURE+"-Type");
|
||||
String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
|
||||
|
||||
try {
|
||||
RequestParam requestParam = new RequestParam.Builder()
|
||||
.serialNumber(serialNo)
|
||||
.signature(signature)
|
||||
.signType(signatureType)
|
||||
.timestamp(timestamp)
|
||||
.body(HttpServletUtils.getRequestBody(request))
|
||||
.nonce(nonce)
|
||||
.build();
|
||||
// 验签并解析通知
|
||||
NotificationParser parser = new NotificationParser((NotificationConfig)certificateConfig);
|
||||
// 解析解密后的通知
|
||||
Refund refund = parser.parse(requestParam, Refund.class);
|
||||
// 更新状态
|
||||
ebikeRefundService.updateRefundStatus(refund);
|
||||
// 处理成功
|
||||
result.setSuccess(true);
|
||||
result.setMessage("success");
|
||||
return result;
|
||||
}catch (Exception e) {
|
||||
result.setMessage(String.format("verify failed, request-id=[%s]", requestId));
|
||||
logError("退款通知回调handleRefundNotify", e);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印日志
|
||||
*
|
||||
@ -237,6 +315,9 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
else if (e instanceof MalformedMessageException malformedMessageException) {
|
||||
log.error("{} 返回体类型不合法或者解析返回体失败, {}", desc, malformedMessageException.getMessage());
|
||||
}
|
||||
else if (e instanceof ValidationException validationException) {
|
||||
log.error("{} 验签失败,验证签名失败,{}", desc, validationException.getMessage());
|
||||
}
|
||||
else {
|
||||
log.error("{} 执行异常, {}", desc, e.getMessage());
|
||||
}
|
||||
|
||||
@ -36,31 +36,55 @@ public class WsPayTask {
|
||||
@Resource
|
||||
private EbikeRefundService ebikeRefundService;
|
||||
|
||||
// TODO @Scheduled任务线程默认串行执行,需要考虑并发问题
|
||||
/**
|
||||
* 从第0秒开始每隔30秒执行1次,查询创建超过5分钟,并且未支付的订单
|
||||
* 每隔30秒执行1次,查询创建未超过5分钟,并且未支付的订单
|
||||
*/
|
||||
@Scheduled(cron = "0/30 * * * * ?")
|
||||
public void orderConfirm() throws Exception {
|
||||
log.info("orderConfirm 执行......");
|
||||
public void checkOrderStatus() throws Exception {
|
||||
log.info("checkOrderStatus 执行......");
|
||||
// 1. 查询未支付的订单
|
||||
List<EbikePayment> ebikePaymentList = ebikePaymentService.getNoPayOrderByDuration(wxPayConfig.getExpireMinute());
|
||||
// 2. 遍历订单,查询支付状态
|
||||
for (EbikePayment ebikePayment : ebikePaymentList) {
|
||||
log.warn("超时未支付的订单号 ===> {}", ebikePayment.getOrderId());
|
||||
log.warn("未支付的订单号 ===> {}", ebikePayment.getOrderId());
|
||||
// 调用微信支付查询接口,查询支付状态
|
||||
Transaction transaction = wxPayService.queryOrderByOutTradeNo(ebikePayment.getOrderId());
|
||||
// 3. 更新订单状态
|
||||
if (transaction != null)
|
||||
ebikePaymentService.updatePaymentStatus(ebikePayment.getRecordId(), transaction);
|
||||
ebikePaymentService.updatePaymentStatus(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从第0秒开始每隔30秒执行1次,查询创建超过5分钟,并且未成功的退款单
|
||||
* 每隔30秒执行1次,查询创建超过5分钟,并且未支付的订单
|
||||
*/
|
||||
@Scheduled(cron = "0/30 * * * * ?")
|
||||
public void refundConfirm() throws Exception {
|
||||
log.info("refundConfirm 执行......");
|
||||
public void closeOrder() throws Exception {
|
||||
log.info("closeOrder 执行......");
|
||||
// 1. 查询未支付的超时订单
|
||||
List<EbikePayment> ebikePaymentList = ebikePaymentService.getExpireOrderByDuration(wxPayConfig.getExpireMinute());
|
||||
// 2. 遍历订单,关闭订单
|
||||
for (EbikePayment ebikePayment : ebikePaymentList) {
|
||||
log.warn("超时未支付的订单号 ===> {}", ebikePayment.getOrderId());
|
||||
// 调用微信支付关闭接口,关闭订单
|
||||
boolean close = wxPayService.closeOrder(ebikePayment.getOrderId());
|
||||
if (close) {
|
||||
// 3. 更新订单状态
|
||||
Transaction transaction = new Transaction();
|
||||
transaction.setTradeState(Transaction.TradeStateEnum.CLOSED);
|
||||
transaction.setTradeStateDesc("订单关闭");
|
||||
ebikePaymentService.updatePaymentStatus(transaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 每隔30秒执行1次,查询创建未超过5分钟,并且未成功的退款单
|
||||
*/
|
||||
@Scheduled(cron = "0/30 * * * * ?")
|
||||
public void checkRefundStatus() throws Exception {
|
||||
log.info("checkRefundStatus 执行......");
|
||||
|
||||
// 1. 查询未成功的退款单
|
||||
List<EbikeRefund> ebikeRefundList = ebikeRefundService.getNoSuccessRefundOrderByDuration(wxPayConfig.getExpireMinute());
|
||||
@ -69,9 +93,9 @@ public class WsPayTask {
|
||||
log.warn("超时未退款的退款单号 ===> {}", ebikeRefund.getRefundId());
|
||||
// 调用微信退款查询接口,查询退款状态
|
||||
Refund refund = wxPayService.queryRefundByOutNo(ebikeRefund.getRefundId());
|
||||
if (refund!= null&& Status.SUCCESS.equals(refund.getStatus())){
|
||||
if (refund!= null){
|
||||
// 3. 更新退款单状态
|
||||
//ebikeRefundService.updateRefundStatus(ebikeRefund.getRefundId(), 2);
|
||||
ebikeRefundService.updateRefundStatus(refund);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
package com.cdzy.payment.utils;
|
||||
|
||||
import jakarta.servlet.ServletInputStream;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* HttpServletRequest 获取请求体工具类
|
||||
*
|
||||
* @author dingchao
|
||||
* @date 2025/4/29
|
||||
* @modified by:
|
||||
*/
|
||||
public class HttpServletUtils {
|
||||
|
||||
/**
|
||||
* 获取请求体
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @return 请求体
|
||||
* @throws IOException 读取返回支付接口数据流出现异常!
|
||||
*/
|
||||
public static String getRequestBody(HttpServletRequest request) throws IOException {
|
||||
ServletInputStream stream = null;
|
||||
BufferedReader reader = null;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
try {
|
||||
stream = request.getInputStream();
|
||||
// 获取响应
|
||||
reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IOException("读取返回支付接口数据流出现异常!");
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,6 +2,7 @@ package com.cdzy.payment.utils;
|
||||
|
||||
import com.mybatisflex.core.keygen.IKeyGenerator;
|
||||
import com.mybatisflex.core.keygen.KeyGeneratorFactory;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
@ -14,12 +15,13 @@ import java.time.format.DateTimeFormatter;
|
||||
* @date 2025/4/27
|
||||
* @modified by:
|
||||
*/
|
||||
public class StringUtil {
|
||||
public class StringUtils {
|
||||
|
||||
private final static String WXPAY_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
* 格式:yyyy-MM-dd'T'HH:mm:ss.SSSX
|
||||
* 格式:yyyy-MM-dd'T'HH:mm:ssXXX
|
||||
* 示例:2025-04-25T10:10:10.100+08:00
|
||||
* 注意:时区为+8
|
||||
*
|
||||
@ -28,10 +30,32 @@ public class StringUtil {
|
||||
*/
|
||||
public static String formatLocalDatetime(LocalDateTime localDateTime) {
|
||||
ZonedDateTime localZoned = localDateTime.atZone(ZoneId.of("+8"));
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(WXPAY_DATE_FORMAT);
|
||||
return localZoned.format(formatter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
* 格式:yyyy-MM-dd'T'HH:mm:ssXXX
|
||||
* 示例:2025-04-25T10:10:10.100+08:00
|
||||
* 注意:时区为+8
|
||||
*
|
||||
* @param formatTime 时间字符串
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime toLocalDatetime(String formatTime) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(WXPAY_DATE_FORMAT);
|
||||
ZonedDateTime localZoned = ZonedDateTime.parse(formatTime, formatter);
|
||||
return localZoned.toLocalDateTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成雪花算法ID
|
||||
*
|
||||
* @param idFieldName 字段名
|
||||
* @return
|
||||
*/
|
||||
public static String generateSnowflakeId(String idFieldName) {
|
||||
// 获取名为 "snowFlakeId" 的生成器
|
||||
IKeyGenerator generator = KeyGeneratorFactory.getKeyGenerator("snowFlakeId");
|
||||
@ -39,8 +63,12 @@ public class StringUtil {
|
||||
return String.valueOf(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//public static void main(String[] args) {
|
||||
// System.out.println(formatLocalDatetime(LocalDateTime.now()));
|
||||
// System.out.println(generateSnowflakeId("refundId"));
|
||||
// LocalDateTime localDateTime = toLocalDatetime("2025-04-25T10:10:10+08:00");
|
||||
// System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
//}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user