diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/pojo/param/RegulationParam.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/pojo/param/RegulationParam.java index 304e510..51ec8ca 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/pojo/param/RegulationParam.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/pojo/param/RegulationParam.java @@ -5,6 +5,8 @@ import lombok.Setter; import lombok.ToString; import lombok.experimental.Accessors; +import java.math.BigDecimal; + /** * 调账入参 */ @@ -27,7 +29,7 @@ public class RegulationParam { /** * 变动金额 */ - private String delta; + private BigDecimal delta; /** * 备注 diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/service/AccountRegulationService.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/service/AccountRegulationService.java index bc53f16..439c83d 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/service/AccountRegulationService.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/service/AccountRegulationService.java @@ -3,14 +3,24 @@ package com.njzscloud.supervisory.order.service; import cn.hutool.core.lang.Assert; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.njzscloud.common.core.ex.Exceptions; +import com.njzscloud.supervisory.expense.contant.ExpenseItemCategory; +import com.njzscloud.supervisory.money.contant.MoneyChangeCategory; +import com.njzscloud.supervisory.money.pojo.entity.MoneyAccountEntity; +import com.njzscloud.supervisory.money.pojo.entity.MoneyChangeDetailEntity; +import com.njzscloud.supervisory.money.service.MoneyAccountService; +import com.njzscloud.supervisory.money.service.MoneyChangeDetailService; +import com.njzscloud.supervisory.order.pojo.entity.OrderExpenseItemsEntity; import com.njzscloud.supervisory.order.pojo.entity.OrderInfoEntity; -import com.njzscloud.supervisory.order.pojo.param.ChangePriceParam; import com.njzscloud.supervisory.order.pojo.param.RegulationParam; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.YearMonth; + /** * 调账 */ @@ -21,13 +31,72 @@ public class AccountRegulationService { private final OrderInfoService orderInfoService; + private final MoneyAccountService moneyAccountService; + + private final MoneyChangeDetailService moneyChangeDetailService; + + private final OrderExpenseItemsService orderExpenseItemsService; + /** * 业务调账 */ @Transactional(rollbackFor = Exception.class) public void accountRegulation(RegulationParam param) { - OrderInfoEntity order = orderInfoService.getOne(Wrappers.lambdaQuery().eq(OrderInfoEntity::getSn, param.getSn())); - Assert.notNull(order, () -> Exceptions.clierr("订单不存在")); + OrderInfoEntity order = orderInfoService.getOne(Wrappers.lambdaQuery() + .eq(OrderInfoEntity::getSn, param.getSn()) + .eq(OrderInfoEntity::getTransCompanyId, param.getCompanyId())); + Assert.notNull(order, () -> Exceptions.clierr("当前客户不存在该笔订单,请检查订单号是否正确")); + + // 判断订单创建时间是否在当月 + LocalDateTime createTime = order.getCreateTime(); + if (createTime != null) { + YearMonth orderMonth = YearMonth.from(createTime); + YearMonth currentMonth = YearMonth.now(); + boolean isCurrentMonth = orderMonth.equals(currentMonth); + if (!isCurrentMonth) { + throw Exceptions.clierr("只能对当月订单调账"); + } + } + + // 新增一条付费项 + OrderExpenseItemsEntity productItem = new OrderExpenseItemsEntity() + .setExpenseItemCategory(ExpenseItemCategory.ChanPin.getVal()) + .setOrderId(order.getId()) + .setOriginExpenseItemId(202511081532L) + .setExpenseItemName("业务调账") + .setUnitPrice(new BigDecimal("0")) + .setUnit("Che") + .setMoneyStrategy("Che") + .setQuantity(1) + .setTotalMoney(param.getDelta()) + .setSettleMoney(param.getDelta()); + orderExpenseItemsService.save(productItem); + + // 查询账户 + MoneyAccountEntity accountEntity = moneyAccountService.getOne(Wrappers.lambdaQuery() + .eq(MoneyAccountEntity::getStationId, param.getCompanyId())); + if (null == accountEntity) { + throw Exceptions.clierr("资金账户不存在"); + } + BigDecimal newMoney = accountEntity.getMoney().add(param.getDelta()); + // 新增一条资金明细 + MoneyChangeDetailEntity changeDetail = new MoneyChangeDetailEntity() + .setCompanyId(param.getCompanyId()) + .setOrderId(order.getId()) + .setMoneyAccountId(accountEntity.getId()) + .setOldMoney(accountEntity.getMoney()) + .setDelta(param.getDelta()) + .setNewMoney(newMoney) + .setMoneyChangeCategory(MoneyChangeCategory.DingDanTiaoZhang) + .setMemo(param.getMemo()); + + moneyChangeDetailService.save(changeDetail); + + // 变更资金账户金额 + MoneyAccountEntity companyAccount = new MoneyAccountEntity() + .setId(accountEntity.getId()) + .setMoney(newMoney); + moneyAccountService.updateById(companyAccount); } diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/contant/WxApiConfig.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/contant/WxApiConfig.java index 01e9f1a..a70fac0 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/contant/WxApiConfig.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/contant/WxApiConfig.java @@ -19,5 +19,7 @@ public class WxApiConfig { public static final String SEND_TEMPLATE_MSG_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="; + public static final String TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="; + } diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/controller/WechatTemplateMessageController.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/controller/WechatTemplateMessageController.java index c67478e..c2b1d48 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/controller/WechatTemplateMessageController.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/controller/WechatTemplateMessageController.java @@ -23,11 +23,19 @@ public class WechatTemplateMessageController { * 绑定微信openid */ @GetMapping("/bind") - public R detail(@RequestParam String code) { + public R bind(@RequestParam String code) { wechatTemplateMessageService.bind(code); return R.success(); } + /** + * key + */ + @GetMapping("/key") + public R key() { + return R.success(wechatTemplateMessageService.key()); + } + @PostMapping("/send-order-notice") public String sendOrderNotice(@RequestBody TemplateMessageParam param) { try { diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/WechatTemplateMessageService.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/WechatTemplateMessageService.java index 8083850..875070e 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/WechatTemplateMessageService.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/WechatTemplateMessageService.java @@ -13,6 +13,8 @@ public interface WechatTemplateMessageService { void bind(String code); + Map key(); + /** * 发送消息 */ diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WechatTemplateMessageServiceImpl.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WechatTemplateMessageServiceImpl.java index c5b7f07..3d07583 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WechatTemplateMessageServiceImpl.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WechatTemplateMessageServiceImpl.java @@ -19,8 +19,12 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.UUID; /** * 微信消息推送服务实现类 @@ -69,12 +73,40 @@ public class WechatTemplateMessageServiceImpl implements WechatTemplateMessageSe } + @Override + public Map key() { + RestTemplate restTemplate = new RestTemplate(); + // 1. 获取Access Token + String accessToken = getAccessToken(); + String response = restTemplate.postForObject(WxApiConfig.TICKET_URL + accessToken + "&type=jsapi", "", String.class); + // 5. 处理响应 + JSONObject jsonResponse = JSONObject.parseObject(response); + if (null == jsonResponse) { + throw Exceptions.clierr("获取ticket失败,jsonResponse为null"); + } + if (jsonResponse.getIntValue("errcode") != 0) { + log.error("发送模板消息失败: " + jsonResponse.getString("errmsg")); + } + String jsapi_ticket = jsonResponse.getString("ticket"); + String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填,生成签名的时间戳 + String nonceStr = UUID.randomUUID().toString().replaceAll("-", ""); // 必填,生成签名的随机串 + // 注意这里参数名必须全部小写,且必须有序 + String signature = getSignature(jsapi_ticket, timestamp, nonceStr, WxApiConfig.REDIRECT_URI); + Map map = new HashMap<>(); + map.put("appId", WxApiConfig.APP_ID); + map.put("timestamp", timestamp); + map.put("nonceStr", nonceStr); + map.put("signature", signature); + + return map; + } + @Override public void sendTemplateMessage(TemplateMessageParam param) { // UserEntity userEntity = userService.getById(param.getUserId()); UserEntity userEntity = new UserEntity(); userEntity.setOpenid("owC-r2Bf1axK1C2MQ6nOaCDbKuHw"); - if (null != userEntity && !Strings.isNullOrEmpty(userEntity.getOpenid())) { + if (!Strings.isNullOrEmpty(userEntity.getOpenid())) { Map data; if (TempType.TRANS_COMPANY.getVal().equals(param.getTempType())) { // 通知清运公司指派司机 @@ -131,8 +163,8 @@ public class WechatTemplateMessageServiceImpl implements WechatTemplateMessageSe * 发送模板消息 */ public void sendMessage(String openId, String templateId, - Map data, - String url, String miniProgram) { + Map data, + String url, String miniProgram) { // 1. 获取Access Token String accessToken = getAccessToken(); if (Strings.isNullOrEmpty(accessToken)) { @@ -205,4 +237,57 @@ public class WechatTemplateMessageServiceImpl implements WechatTemplateMessageSe return jsonResponse.getString("access_token"); } + public static String getSignature(String jsapi_ticket, String timestamp, + String nonce, String js_url) { +// 对 jsapi_ticket、 timestamp 和 nonce 按字典排序 对所有待签名参数按照字段名的 ASCII +// 码从小到大排序(字典序)后,使用 URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串 +// string1。这里需要注意的是所有参数名均为小写字符。 接下来对 string1 作 sha1 加密,字段名和字段值都采用原始值,不进行 +// URL 转义。即 signature=sha1(string1)。 +// 如果没有按照生成的key1=value&key2=value拼接的话会报错 + String[] paramArr = new String[]{"jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp, "noncestr=" + nonce, + "url=" + js_url}; + Arrays.sort(paramArr); + // 将排序后的结果拼接成一个字符串 + String content = paramArr[0].concat("&" + paramArr[1]).concat("&" + paramArr[2]).concat("&" + paramArr[3]); + log.info("拼接之后的content为:" + content); + String genSignature = null; + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + // 对拼接后的字符串进行 sha1 加密 + byte[] digest = md.digest(content.getBytes()); + genSignature = byteToStr(digest); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + // 将 sha1 加密后的字符串与 signature 进行对比 + if (genSignature != null) { + return genSignature;// 返回signature + } else { + return "false"; + } + } + + /** + * 将字节数组转换为十六进制字符串 + */ + private static String byteToStr(byte[] byteArray) { + StringBuilder strDigest = new StringBuilder(); + for (byte b : byteArray) { + strDigest.append(byteToHexStr(b)); + } + return strDigest.toString(); + } + + /** + * 将字节转换为十六进制字符串 + */ + private static String byteToHexStr(byte mByte) { + char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', + 'B', 'C', 'D', 'E', 'F'}; + char[] tempArr = new char[2]; + tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; + tempArr[1] = Digit[mByte & 0X0F]; + return new String(tempArr); + } + } \ No newline at end of file diff --git a/njzscloud-svr/src/main/resources/application-dev.yml b/njzscloud-svr/src/main/resources/application-dev.yml index 95390bb..ccab5d2 100644 --- a/njzscloud-svr/src/main/resources/application-dev.yml +++ b/njzscloud-svr/src/main/resources/application-dev.yml @@ -28,7 +28,7 @@ spring: - /district/areaList - /biz_audit_config/copy - /order_info/gps_test - - /wechatTemplateMessage/bind + - /wechatTemplateMessage/key - /hsoa/push_order app: default-place: diff --git a/njzscloud-svr/src/main/resources/application-prod.yml b/njzscloud-svr/src/main/resources/application-prod.yml index 1043904..9891674 100644 --- a/njzscloud-svr/src/main/resources/application-prod.yml +++ b/njzscloud-svr/src/main/resources/application-prod.yml @@ -26,7 +26,7 @@ spring: - /payment/wechat/refundNotify - /district/areaList - /biz_audit_config/copy - - /wechatTemplateMessage/bind + - /wechatTemplateMessage/key - /hsoa/push_order app: