From 6539b325b5ce95d1fafa864c75a32279c954167f Mon Sep 17 00:00:00 2001 From: KKSU <15274802129@163.com> Date: Fri, 07 Feb 2025 11:03:31 +0800 Subject: [PATCH] refactor(mall): 重构订单退款流程 --- src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java | 24 +-- src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java | 67 +--------- src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java | 25 +-- src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java | 116 +++++++++++++++++++ src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java | 2 src/main/java/cc/mrbird/febs/pay/util/FiuuRefundUtil.java | 83 +++++++++++++ src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java | 2 src/main/java/cc/mrbird/febs/pay/model/RefundStatus.java | 13 ++ src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java | 2 src/main/java/cc/mrbird/febs/pay/util/HashUtils.java | 18 +++ 10 files changed, 260 insertions(+), 92 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java b/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java index 96ce4ef..90674f2 100644 --- a/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java +++ b/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java @@ -33,7 +33,7 @@ registration.excludePathPatterns("/api/xcxPay/wxpayCallback"); registration.excludePathPatterns("/api/xcxPay/rechargeCallBack"); registration.excludePathPatterns("/api/xcxPay/fapiaoCallBack"); -// registration.excludePathPatterns("/api/fuPay/callback"); + registration.excludePathPatterns("/api/fuPay/callback"); registration.excludePathPatterns("/api/fuPay/notify"); // 添加Swagger UI相关路径 diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java b/src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java index dae67f7..7858ec4 100644 --- a/src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java +++ b/src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java @@ -21,7 +21,7 @@ private Long orderId; //退款订单详情ID private Long itemId; - //退款方式 1:微信 2:支付宝 3:其他 + //退款方式 1:FIUU 2:支付宝 3:其他 private Integer type; //退款状态 1:成功 2:失败 3:退款中 private Integer state; diff --git a/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java b/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java index 0ca11c7..eb3e796 100644 --- a/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java +++ b/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java @@ -1,8 +1,13 @@ package cc.mrbird.febs.mall.quartz; +import cc.mrbird.febs.common.enumerates.FlowTypeEnum; +import cc.mrbird.febs.common.enumerates.MoneyFlowTypeEnum; import cc.mrbird.febs.common.enumerates.YesOrNoOrIngEnum; -import cc.mrbird.febs.mall.entity.MallActivity; -import cc.mrbird.febs.mall.mapper.MallActivityMapper; +import cc.mrbird.febs.mall.entity.*; +import cc.mrbird.febs.mall.mapper.*; +import cc.mrbird.febs.mall.service.IMallMoneyFlowService; +import cc.mrbird.febs.pay.model.RefundStatus; +import cc.mrbird.febs.pay.util.FiuuRefundUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; @@ -26,6 +31,27 @@ @Autowired private MallActivityMapper mallActivityMapper; + + @Autowired + private MallRefundMapper mallRefundMapper; + + @Autowired + private MallOrderInfoMapper mallOrderInfoMapper; + + @Autowired + private MallOrderItemMapper mallOrderItemMapper; + + @Autowired + private MallGoodsSkuMapper mallGoodsSkuMapper; + + @Autowired + private MallGoodsMapper mallGoodsMapper; + + @Autowired + private FiuuRefundUtil fiuuRefundUtil; + + @Autowired + private IMallMoneyFlowService mallMoneyFlowService; /** * 一分钟运行一次 @@ -74,4 +100,90 @@ }); } + + + /** + * 一分钟运行一次 + * 查询退款记录,去验证是否已经退款成功 + */ + @Scheduled(cron = "0 0/1 * * * ? ") + public void refundJob() { + LambdaQueryWrapper<MallRefundEntity> mallOrderRefundLambdaQueryWrapper = new LambdaQueryWrapper<>(); + mallOrderRefundLambdaQueryWrapper.eq(MallRefundEntity::getStatus, 3); + mallOrderRefundLambdaQueryWrapper.eq(MallRefundEntity::getType, 1); + List<MallRefundEntity> mallRefundEntities = mallRefundMapper.selectList(mallOrderRefundLambdaQueryWrapper); + if(CollUtil.isEmpty(mallRefundEntities)){ + return; + } + mallRefundEntities.forEach(mallRefundEntity -> { + processRefund(mallRefundEntity); + }); + } + + private void processRefund(MallRefundEntity mallRefundEntity) { + try { + MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(mallRefundEntity.getOrderId()); + MallOrderItem mallOrderItem = mallOrderItemMapper.selectById(mallRefundEntity.getItemId()); + MallGoodsSku mallGoodsSku = mallGoodsSkuMapper.selectById(mallOrderItem.getSkuId()); + + String txnId = mallOrderInfo.getPayOrderNo(); + RefundStatus status = fiuuRefundUtil.pollRefundStatus(txnId); + + switch (status.getStatus()) { + case "success": + updateOnSuccess(mallRefundEntity, mallOrderInfo, mallOrderItem, mallGoodsSku); + break; + case "rejected": + updateOnRejected(mallRefundEntity, mallOrderItem); + break; + default: + log.warn("未知状态:{}", status.getStatus()); + } + } catch (Exception e) { + log.error("处理退款失败: {}", e.getMessage(), e); + } + } + + private void updateOnSuccess(MallRefundEntity mallRefundEntity, MallOrderInfo mallOrderInfo, MallOrderItem mallOrderItem, MallGoodsSku mallGoodsSku) { + mallOrderItem.setState(3); + mallOrderItemMapper.updateById(mallOrderItem); + + MallGoods mallGoods = mallGoodsMapper.selectById(mallOrderItem.getGoodsId()); + mallGoods.setStock(mallGoods.getStock() + mallOrderItem.getCnt()); + mallGoods.setVolume(mallGoods.getVolume() - mallOrderItem.getCnt()); + mallGoodsMapper.updateById(mallGoods); + + mallGoodsSku.setStock(mallGoodsSku.getStock() + mallOrderItem.getCnt()); + mallGoodsSku.setSkuVolume(mallGoodsSku.getSkuVolume() - mallOrderItem.getCnt()); + mallGoodsSkuMapper.updateById(mallGoodsSku); + + mallRefundEntity.setState(1); + mallRefundEntity.setUpdatedTime(DateUtil.date()); + mallRefundMapper.updateById(mallRefundEntity); + + mallMoneyFlowService.addMoneyFlow( + mallOrderInfo.getMemberId(), + mallRefundEntity.getAmount(), + MoneyFlowTypeEnum.WECHAT_REFUND.getValue(), + mallOrderInfo.getOrderNo(), + FlowTypeEnum.WECHAT.getValue(), + "FIUU退款", + 2); + + List<MallOrderItem> mallOrderItemList = mallOrderItemMapper.selectListByNotInStateAndOrderId(3, mallRefundEntity.getOrderId()); + if (CollUtil.isEmpty(mallOrderItemList)) { + MallOrderInfo mallOrderRefund = mallOrderInfoMapper.selectById(mallRefundEntity.getOrderId()); + mallOrderRefund.setStatus(6); + mallOrderInfoMapper.updateById(mallOrderRefund); + } + } + + private void updateOnRejected(MallRefundEntity mallRefundEntity, MallOrderItem mallOrderItem) { + mallOrderItem.setState(1); + mallOrderItemMapper.updateById(mallOrderItem); + + mallRefundEntity.setState(2); + mallRefundMapper.updateById(mallRefundEntity); + } + } diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java index 534d61d..c1e9602 100644 --- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java @@ -900,23 +900,16 @@ @Transactional public FebsResponse refundOrder(Long id) { MallMember member = LoginUserUtil.getLoginUser(); - MallOrderInfo mallOrderInfo = this.baseMapper.selectById(id); - if(ObjectUtil.isEmpty(mallOrderInfo)){ - return new FebsResponse().fail().message("订单不存在"); - } + MallOrderInfo mallOrderInfo = ValidateEntityUtils + .ensureColumnReturnEntity(id, MallOrderInfo::getId, this.baseMapper::selectOne, "订单不存在"); Integer status = mallOrderInfo.getStatus(); - if(OrderStatusEnum.WAIT_SHIPPING.getValue() != status){ - return new FebsResponse().fail().message("订单不是待发货状态"); - } Integer deliveryState = mallOrderInfo.getDeliveryState(); - if(1 != deliveryState){ - return new FebsResponse().fail().message("订单不是待配送状态"); - } + + ValidateEntityUtils.ensureEqual(OrderStatusEnum.WAIT_SHIPPING.getValue(),status,"订单不是待发货状态"); + ValidateEntityUtils.ensureEqual(1,deliveryState,"订单不是待配送状态"); //根据子订单生成退款记录 - List<MallOrderItem> mallOrderItemList = mallOrderItemMapper.selectListByOrderId(id); - if(CollUtil.isEmpty(mallOrderItemList)){ - return new FebsResponse().fail().message("订单不存在"); - } + List<MallOrderItem> mallOrderItemList = ValidateEntityUtils + .ensureColumnReturnEntityList(id, MallOrderItem::getOrderId, mallOrderItemMapper::selectList, "订单不存在"); for(MallOrderItem mallOrderItem : mallOrderItemList){ QueryWrapper<MallRefundEntity> objectQueryWrapper = new QueryWrapper<>(); objectQueryWrapper.eq("member_id",member.getId()); @@ -940,9 +933,7 @@ mallRefundEntity.setAmount(mallOrderItem.getAmount()); mallRefundMapper.insert(mallRefundEntity); }else{ - if(mallRefund.getState() == 1){ - return new FebsResponse().fail().message("订单已退款"); - } + ValidateEntityUtils.ensureNotEqual(1,mallRefund.getState(),"订单已退款"); if(mallRefund.getState() == 2 || mallRefund.getState() == 3){ mallRefundEntity.setId(mallRefund.getId()); mallRefundEntity.setRefundNo(mallRefund.getRefundNo()); diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java index d1257d8..c4ce447 100644 --- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java @@ -5,6 +5,7 @@ import cc.mrbird.febs.common.properties.XcxProperties; import cc.mrbird.febs.common.utils.LoginUserUtil; import cc.mrbird.febs.common.utils.SpringContextHolder; +import cc.mrbird.febs.common.utils.ValidateEntityUtils; import cc.mrbird.febs.mall.conversion.MallLeaderAchieveConversion; import cc.mrbird.febs.mall.conversion.MallOrderInfoConversion; import cc.mrbird.febs.mall.conversion.MallTeamLeaderConversion; @@ -395,13 +396,12 @@ if(!(1 == agreeType || 2 == agreeType)){ return new FebsResponse().fail().message("退款失败,请联系客服人员"); } - - MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(orderId); - MallOrderItem mallOrderItem = mallOrderItemMapper.selectById(itemId); - MallGoodsSku mallGoodsSku = mallGoodsSkuMapper.selectById(mallOrderItem.getSkuId()); - if(ObjectUtil.isEmpty(mallGoodsSku)){ - return new FebsResponse().fail().message("退款失败,请联系客服人员"); - } + MallOrderInfo mallOrderInfo = ValidateEntityUtils + .ensureColumnReturnEntity(orderId, MallOrderInfo::getId, mallOrderInfoMapper::selectOne, "订单不存在"); + MallOrderItem mallOrderItem = ValidateEntityUtils + .ensureColumnReturnEntity(itemId, MallOrderItem::getId, mallOrderItemMapper::selectOne, "订单不存在"); + MallGoodsSku mallGoodsSku = ValidateEntityUtils + .ensureColumnReturnEntity(mallOrderItem.getSkuId(), MallGoodsSku::getId, mallGoodsSkuMapper::selectOne, "订单不存在,退款失败,请联系客服人员"); List<MallRefundEntity> mallRefundEntities = mallRefundMapper.selectByItemIdAndOrderIdAndState(itemId, orderId, 3); if(CollUtil.isEmpty(mallRefundEntities)){ return new FebsResponse().fail().message("退款失败,请联系客服人员"); @@ -453,7 +453,6 @@ } } } -// refundAmount = refundAmount.add(mallOrderInfo.getCarriage()); BigDecimal bb = new BigDecimal(100); int refundMoney = refundAmount.multiply(bb).intValue(); @@ -486,55 +485,9 @@ return new FebsResponse().success().message("退款成功"); } - Boolean flag = false; - Boolean debug = xcxProperties.getDebug(); - if (debug) { - boolean b = fiuuUtil.comRefund(mallOrderInfo.getPayOrderNo(), refundNo, "1"); - flag = b; - } else { - log.info("开始调用退款接口。。。退款编号为{}", refundNo); - boolean b = fiuuUtil.comRefund(mallOrderInfo.getPayOrderNo(), refundNo, orderAmount.toString()); - flag = b; - } - - if(flag){ - //更新订单详情 - mallOrderItem.setState(3); - mallOrderItemMapper.updateById(mallOrderItem); - //更新库存信息 - MallGoods mallGoods = mallGoodsMapper.selectById(mallOrderItem.getGoodsId()); - mallGoods.setStock(mallGoods.getStock() + mallOrderItem.getCnt()); - mallGoods.setVolume(mallGoods.getVolume() - mallOrderItem.getCnt()); - mallGoodsMapper.updateById(mallGoods); - -// MallGoodsSku mallGoodsSku = mallGoodsSkuMapper.selectById(mallOrderItem.getSkuId()); - mallGoodsSku.setStock(mallGoodsSku.getStock() + mallOrderItem.getCnt()); - mallGoodsSku.setSkuVolume(mallGoodsSku.getSkuVolume() - mallOrderItem.getCnt()); - mallGoodsSkuMapper.updateById(mallGoodsSku); - - //更新退款订单 - mallRefundEntity.setState(1); - mallRefundEntity.setUpdatedTime(DateUtil.date()); - mallRefundMapper.updateById(mallRefundEntity); - mallMoneyFlowService.addMoneyFlow(mallOrderInfo.getMemberId(), refundAmount, MoneyFlowTypeEnum.WECHAT_REFUND.getValue(), mallOrderInfo.getOrderNo(), FlowTypeEnum.WECHAT.getValue(),"微信退款",2); - - List<MallOrderItem> mallOrderItemList = mallOrderItemMapper.selectListByNotInStateAndOrderId(3,orderId); - if(CollUtil.isEmpty(mallOrderItemList)){ - MallOrderInfo mallOrderRefund = mallOrderInfoMapper.selectById(orderId); - mallOrderRefund.setStatus(6); - mallOrderInfoMapper.updateById(mallOrderRefund); - } - }else{ - - //更新订单详情 - mallOrderItem.setState(1); - mallOrderItemMapper.updateById(mallOrderItem); - - mallRefundEntity.setState(2); - mallRefundMapper.updateById(mallRefundEntity); - return new FebsResponse().fail().message("退款失败,请联系客服人员"); - } - return new FebsResponse().success().message("退款成功"); + log.info("开始调用退款接口。。。退款编号为{}", refundNo); + fiuuUtil.comRefund(mallOrderInfo.getPayOrderNo(), refundNo, orderAmount.toString()); + return new FebsResponse().success().message("已申请退款"); } } diff --git a/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java b/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java index e419e3e..59620cb 100644 --- a/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java +++ b/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java @@ -64,7 +64,7 @@ params.put("bill_desc", productNames); params.put("currency", "MYR"); // 默认 MYR params.put("vcode", vcode); -// params.put("returnurl", returnUrl); + params.put("returnurl", returnUrl); return new FebsResponse().success().data(params); } catch (Exception e) { diff --git a/src/main/java/cc/mrbird/febs/pay/model/RefundStatus.java b/src/main/java/cc/mrbird/febs/pay/model/RefundStatus.java new file mode 100644 index 0000000..0e59e32 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/pay/model/RefundStatus.java @@ -0,0 +1,13 @@ +package cc.mrbird.febs.pay.model; + +import lombok.Data; + +@Data +public class RefundStatus { + private String TxnID; + private String RefID; + private String RefundID; + private String Status; + private String LastUpdate; + private String FPXTxnID; +} diff --git a/src/main/java/cc/mrbird/febs/pay/util/FiuuRefundUtil.java b/src/main/java/cc/mrbird/febs/pay/util/FiuuRefundUtil.java new file mode 100644 index 0000000..6071945 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/pay/util/FiuuRefundUtil.java @@ -0,0 +1,83 @@ +package cc.mrbird.febs.pay.util; + +import cc.mrbird.febs.pay.model.RefundStatus; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.stereotype.Service; + +import java.util.concurrent.*; + +@Service(value="FiuuRefundUtil") +public class FiuuRefundUtil { + + private static final String API_BASE_URL = "https://api.fiuu.com/RMS/API/refundAPI/"; + private static final String MERCHANT_ID = "e2umart01"; + private static final String VERIFY_KEY = "4e3a4ed58e62ddbfacf41f6d5ec56bf2"; + private static final int MAX_RETRIES = 3; + private static final int POLL_INTERVAL = 1000; // 5秒 + private static final int TIMEOUT = 60000; // 60秒超时 + + private final ObjectMapper objectMapper = new ObjectMapper(); + + // 退款状态查询(根据TxnID) + public RefundStatus queryByTxnId(String txnId) throws Exception { + String signature = HashUtils.md5(txnId + MERCHANT_ID + VERIFY_KEY); + String url = API_BASE_URL + "q_by_txn.php?TxnID=" + txnId + + "&MerchantID=" + MERCHANT_ID + + "&Signature=" + signature; + + return executeQuery(url); + } + + // 退款状态查询(根据RefID) + public RefundStatus queryByRefId(String refId) throws Exception { + String signature = HashUtils.md5(refId + MERCHANT_ID + VERIFY_KEY); + String url = API_BASE_URL + "q_by_refID.php?RefID=" + refId + + "&MerchantID=" + MERCHANT_ID + + "&Signature=" + signature; + + return executeQuery(url); + } + + private RefundStatus executeQuery(String url) throws Exception { + HttpGet request = new HttpGet(url); + try (CloseableHttpClient client = HttpClients.createDefault()) { + String response = EntityUtils.toString(client.execute(request).getEntity()); + return objectMapper.readValue(response, RefundStatus.class); + } + } + + // 异步轮询退款状态 + public RefundStatus pollRefundStatus(String txnId) throws Exception { + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future<RefundStatus> future = executor.submit(() -> { + int retryCount = 0; + while (retryCount < MAX_RETRIES) { + try { + RefundStatus status = queryByTxnId(txnId); + if (!"pending".equals(status.getStatus())) { + return status; + } + Thread.sleep(POLL_INTERVAL); + retryCount++; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Polling interrupted", e); + } + } + throw new TimeoutException("Max retries reached"); + }); + + try { + return future.get(TIMEOUT, TimeUnit.MILLISECONDS); + } catch (TimeoutException e) { + future.cancel(true); + throw new RuntimeException("Refund status check timeout"); + } finally { + executor.shutdown(); + } + } +} diff --git a/src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java b/src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java index 9b96b62..b7c1ede 100644 --- a/src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java +++ b/src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java @@ -1,7 +1,5 @@ package cc.mrbird.febs.pay.util; -import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; @@ -25,7 +23,7 @@ private static final String SECRET_KEY = "59c709fc18978a6a83b87f05d37cecbf"; @Transactional - public boolean comRefund(String outTradeNo, String outRefundNo,String amount){ + public void comRefund(String outTradeNo, String outRefundNo,String amount){ // 退款请求参数 Map<String, String> params = new LinkedHashMap<>(); params.put("RefundType", "P"); // P: Partial Refund, F: Full Refund @@ -52,14 +50,14 @@ } System.out.println("退款响应: " + response); - JSONObject jsonObject = JSONUtil.parseObj(response); - - String status = jsonObject.getStr("status"); - if ("00".equals(status)) { - return true; - }else{ - return false; - } +// JSONObject jsonObject = JSONUtil.parseObj(response); +// +// String status = jsonObject.getStr("status"); +// if ("00".equals(status)) { +// return true; +// }else{ +// return false; +// } } public static void main(String[] args) { @@ -68,8 +66,8 @@ Map<String, String> params = new LinkedHashMap<>(); params.put("RefundType", "P"); // P: Partial Refund, F: Full Refund params.put("MerchantID", MERCHANT_ID); - params.put("RefID", "2025020614313541756_RITEM426"); // 商户唯一退款ID - params.put("TxnID", "2685173864"); // Fiuu原始交易ID + params.put("RefID", "2025020611124868512_RITEM42432121"); // 商户唯一退款ID + params.put("TxnID", "2685352601"); // Fiuu原始交易ID params.put("Amount", "1.00"); // 退款金额 // 生成签名 diff --git a/src/main/java/cc/mrbird/febs/pay/util/HashUtils.java b/src/main/java/cc/mrbird/febs/pay/util/HashUtils.java new file mode 100644 index 0000000..db3a203 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/pay/util/HashUtils.java @@ -0,0 +1,18 @@ +package cc.mrbird.febs.pay.util; + +public class HashUtils { + + public static String md5(String input) { + try { + java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); + byte[] array = md.digest(input.getBytes()); + StringBuilder sb = new StringBuilder(); + for (byte b : array) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } catch (java.security.NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } +} -- Gitblit v1.9.1