master
parent
ca40e8260f
commit
d6cbc62e5c
|
|
@ -5,6 +5,8 @@ import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.experimental.Accessors;
|
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 cn.hutool.core.lang.Assert;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.njzscloud.common.core.ex.Exceptions;
|
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.entity.OrderInfoEntity;
|
||||||
import com.njzscloud.supervisory.order.pojo.param.ChangePriceParam;
|
|
||||||
import com.njzscloud.supervisory.order.pojo.param.RegulationParam;
|
import com.njzscloud.supervisory.order.pojo.param.RegulationParam;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
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 OrderInfoService orderInfoService;
|
||||||
|
|
||||||
|
private final MoneyAccountService moneyAccountService;
|
||||||
|
|
||||||
|
private final MoneyChangeDetailService moneyChangeDetailService;
|
||||||
|
|
||||||
|
private final OrderExpenseItemsService orderExpenseItemsService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 业务调账
|
* 业务调账
|
||||||
*/
|
*/
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void accountRegulation(RegulationParam param) {
|
public void accountRegulation(RegulationParam param) {
|
||||||
OrderInfoEntity order = orderInfoService.getOne(Wrappers.<OrderInfoEntity>lambdaQuery().eq(OrderInfoEntity::getSn, param.getSn()));
|
OrderInfoEntity order = orderInfoService.getOne(Wrappers.<OrderInfoEntity>lambdaQuery()
|
||||||
Assert.notNull(order, () -> Exceptions.clierr("订单不存在"));
|
.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 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
|
* 绑定微信openid
|
||||||
*/
|
*/
|
||||||
@GetMapping("/bind")
|
@GetMapping("/bind")
|
||||||
public R<?> detail(@RequestParam String code) {
|
public R<?> bind(@RequestParam String code) {
|
||||||
wechatTemplateMessageService.bind(code);
|
wechatTemplateMessageService.bind(code);
|
||||||
return R.success();
|
return R.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* key
|
||||||
|
*/
|
||||||
|
@GetMapping("/key")
|
||||||
|
public R<?> key() {
|
||||||
|
return R.success(wechatTemplateMessageService.key());
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/send-order-notice")
|
@PostMapping("/send-order-notice")
|
||||||
public String sendOrderNotice(@RequestBody TemplateMessageParam param) {
|
public String sendOrderNotice(@RequestBody TemplateMessageParam param) {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ public interface WechatTemplateMessageService {
|
||||||
|
|
||||||
void bind(String code);
|
void bind(String code);
|
||||||
|
|
||||||
|
Map<String, Object> key();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送消息
|
* 发送消息
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,12 @@ import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
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
|
@Override
|
||||||
public void sendTemplateMessage(TemplateMessageParam param) {
|
public void sendTemplateMessage(TemplateMessageParam param) {
|
||||||
// UserEntity userEntity = userService.getById(param.getUserId());
|
// UserEntity userEntity = userService.getById(param.getUserId());
|
||||||
UserEntity userEntity = new UserEntity();
|
UserEntity userEntity = new UserEntity();
|
||||||
userEntity.setOpenid("owC-r2Bf1axK1C2MQ6nOaCDbKuHw");
|
userEntity.setOpenid("owC-r2Bf1axK1C2MQ6nOaCDbKuHw");
|
||||||
if (null != userEntity && !Strings.isNullOrEmpty(userEntity.getOpenid())) {
|
if (!Strings.isNullOrEmpty(userEntity.getOpenid())) {
|
||||||
Map<String, TemplateData> data;
|
Map<String, TemplateData> data;
|
||||||
if (TempType.TRANS_COMPANY.getVal().equals(param.getTempType())) {
|
if (TempType.TRANS_COMPANY.getVal().equals(param.getTempType())) {
|
||||||
// 通知清运公司指派司机
|
// 通知清运公司指派司机
|
||||||
|
|
@ -131,8 +163,8 @@ public class WechatTemplateMessageServiceImpl implements WechatTemplateMessageSe
|
||||||
* 发送模板消息
|
* 发送模板消息
|
||||||
*/
|
*/
|
||||||
public void sendMessage(String openId, String templateId,
|
public void sendMessage(String openId, String templateId,
|
||||||
Map<String, TemplateData> data,
|
Map<String, TemplateData> data,
|
||||||
String url, String miniProgram) {
|
String url, String miniProgram) {
|
||||||
// 1. 获取Access Token
|
// 1. 获取Access Token
|
||||||
String accessToken = getAccessToken();
|
String accessToken = getAccessToken();
|
||||||
if (Strings.isNullOrEmpty(accessToken)) {
|
if (Strings.isNullOrEmpty(accessToken)) {
|
||||||
|
|
@ -205,4 +237,57 @@ public class WechatTemplateMessageServiceImpl implements WechatTemplateMessageSe
|
||||||
return jsonResponse.getString("access_token");
|
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
|
- /district/areaList
|
||||||
- /biz_audit_config/copy
|
- /biz_audit_config/copy
|
||||||
- /order_info/gps_test
|
- /order_info/gps_test
|
||||||
- /wechatTemplateMessage/bind
|
- /wechatTemplateMessage/key
|
||||||
- /hsoa/push_order
|
- /hsoa/push_order
|
||||||
app:
|
app:
|
||||||
default-place:
|
default-place:
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ spring:
|
||||||
- /payment/wechat/refundNotify
|
- /payment/wechat/refundNotify
|
||||||
- /district/areaList
|
- /district/areaList
|
||||||
- /biz_audit_config/copy
|
- /biz_audit_config/copy
|
||||||
- /wechatTemplateMessage/bind
|
- /wechatTemplateMessage/key
|
||||||
- /hsoa/push_order
|
- /hsoa/push_order
|
||||||
|
|
||||||
app:
|
app:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue