master
parent
ca40e8260f
commit
d6cbc62e5c
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
|
|
|
|||
|
|
@ -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.<OrderInfoEntity>lambdaQuery().eq(OrderInfoEntity::getSn, param.getSn()));
|
||||
Assert.notNull(order, () -> Exceptions.clierr("订单不存在"));
|
||||
OrderInfoEntity order = orderInfoService.getOne(Wrappers.<OrderInfoEntity>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.<MoneyAccountEntity>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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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=";
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ public interface WechatTemplateMessageService {
|
|||
|
||||
void bind(String code);
|
||||
|
||||
Map<String, Object> key();
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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<String, Object> 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<String, Object> 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<String, TemplateData> data;
|
||||
if (TempType.TRANS_COMPANY.getVal().equals(param.getTempType())) {
|
||||
// 通知清运公司指派司机
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ spring:
|
|||
- /payment/wechat/refundNotify
|
||||
- /district/areaList
|
||||
- /biz_audit_config/copy
|
||||
- /wechatTemplateMessage/bind
|
||||
- /wechatTemplateMessage/key
|
||||
- /hsoa/push_order
|
||||
|
||||
app:
|
||||
|
|
|
|||
Loading…
Reference in New Issue