202506201451
This commit is contained in:
parent
984791f7bd
commit
266742ca2d
|
|
@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.text.DateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
@ -977,7 +978,12 @@ public class AppletController extends BaseController {
|
||||||
orderData.put("status_text", getOrderStatusText(order.getStatus())); // 状态文本
|
orderData.put("status_text", getOrderStatusText(order.getStatus())); // 状态文本
|
||||||
orderData.put("total_price", order.getTotalPrice() != null ? order.getTotalPrice().toString() : "0.00");
|
orderData.put("total_price", order.getTotalPrice() != null ? order.getTotalPrice().toString() : "0.00");
|
||||||
orderData.put("num", order.getNum());
|
orderData.put("num", order.getNum());
|
||||||
|
if (order.getSku()!=null) {
|
||||||
orderData.put("sku", order.getSku());
|
orderData.put("sku", order.getSku());
|
||||||
|
} else {
|
||||||
|
orderData.put("sku", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 时间字段格式化
|
// 时间字段格式化
|
||||||
if (order.getPayTime() != null) {
|
if (order.getPayTime() != null) {
|
||||||
|
|
@ -1472,7 +1478,8 @@ public class AppletController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 其他业务字段
|
// 其他业务字段
|
||||||
userInfo.put("commission", user.getCommission().toString() != null ? user.getCommission().toString() : "0.00");
|
userInfo.put("commission","0.00");
|
||||||
|
//userInfo.put("commission", user.getCommission().toString() != null ? user.getCommission().toString() : "0.00");
|
||||||
userInfo.put("integral", user.getIntegral() != null ? user.getIntegral() : 0);
|
userInfo.put("integral", user.getIntegral() != null ? user.getIntegral() : 0);
|
||||||
userInfo.put("is_stop", user.getIsStop() != null ? user.getIsStop() : 1);
|
userInfo.put("is_stop", user.getIsStop() != null ? user.getIsStop() : 1);
|
||||||
userInfo.put("job_number", user.getJobNumber());
|
userInfo.put("job_number", user.getJobNumber());
|
||||||
|
|
@ -1487,7 +1494,8 @@ public class AppletController extends BaseController {
|
||||||
userInfo.put("remember_token", user.getRememberToken());
|
userInfo.put("remember_token", user.getRememberToken());
|
||||||
userInfo.put("status", user.getStatus() != null ? user.getStatus() : 1);
|
userInfo.put("status", user.getStatus() != null ? user.getStatus() : 1);
|
||||||
userInfo.put("tpd", 0); // 默认值
|
userInfo.put("tpd", 0); // 默认值
|
||||||
userInfo.put("total_comm", user.getTotalComm().toString() != null ? user.getTotalComm().toString() : "0.00");
|
userInfo.put("total_comm","0.00");
|
||||||
|
// userInfo.put("total_comm", user.getTotalComm().toString() != null ? user.getTotalComm().toString() : "0.00");
|
||||||
userInfo.put("total_integral", user.getTotalIntegral() != null ? user.getTotalIntegral() : 100);
|
userInfo.put("total_integral", user.getTotalIntegral() != null ? user.getTotalIntegral() : 100);
|
||||||
userInfo.put("type", user.getType() != null ? user.getType().toString() : "1");
|
userInfo.put("type", user.getType() != null ? user.getType().toString() : "1");
|
||||||
userInfo.put("worker_time", user.getWorkerTime());
|
userInfo.put("worker_time", user.getWorkerTime());
|
||||||
|
|
@ -3667,8 +3675,25 @@ public class AppletController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 获取商品规格参数
|
// 4. 获取商品规格参数
|
||||||
String sku = params.get("sku") != null ? params.get("sku").toString().trim() : "";
|
// String sku = params.get("sku") != null ? params.get("sku").toString().trim() : "";
|
||||||
|
String sku = null;
|
||||||
|
if (params.get("sku") != null) {
|
||||||
|
Object skuParam = params.get("sku");
|
||||||
|
if (skuParam instanceof Map) {
|
||||||
|
// 如果前端传递的是Map对象,转换为JSON字符串
|
||||||
|
try {
|
||||||
|
sku = com.alibaba.fastjson2.JSON.toJSONString(skuParam);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("SKU转换JSON失败:" + e.getMessage());
|
||||||
|
sku = skuParam.toString();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果前端传递的是字符串,直接使用
|
||||||
|
sku = skuParam.toString().trim();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
sku = null;
|
||||||
|
}
|
||||||
// 5. 查询商品信息并验证
|
// 5. 查询商品信息并验证
|
||||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodId);
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodId);
|
||||||
if (serviceGoods == null) {
|
if (serviceGoods == null) {
|
||||||
|
|
@ -3803,7 +3828,12 @@ public class AppletController extends BaseController {
|
||||||
cartData.put("uid", cart.getUid());
|
cartData.put("uid", cart.getUid());
|
||||||
cartData.put("good_id", cart.getGoodId());
|
cartData.put("good_id", cart.getGoodId());
|
||||||
cartData.put("good_num", cart.getGoodNum());
|
cartData.put("good_num", cart.getGoodNum());
|
||||||
cartData.put("sku", cart.getSku());
|
if (cart.getSku() != null||cart.getSku() != "") {
|
||||||
|
cartData.put("sku", JSONObject.parseObject(cart.getSku()));
|
||||||
|
}else{
|
||||||
|
cartData.put("sku", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 格式化时间字段
|
// 格式化时间字段
|
||||||
cartData.put("created_at", cart.getCreatedAt() != null ?
|
cartData.put("created_at", cart.getCreatedAt() != null ?
|
||||||
|
|
@ -4399,10 +4429,11 @@ public class AppletController extends BaseController {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建服务订单
|
* 创建服务订单(支持多商品批量下单)
|
||||||
*
|
*
|
||||||
* @param params 请求参数,包含商品信息、地址信息和预约时间
|
* @param params 请求参数,包含多个商品信息、地址信息和预约时间
|
||||||
* @param request HTTP请求对象
|
* @param request HTTP请求对象
|
||||||
* @return 返回创建结果
|
* @return 返回创建结果
|
||||||
*/
|
*/
|
||||||
|
|
@ -4422,129 +4453,95 @@ public class AppletController extends BaseController {
|
||||||
return error("用户信息获取失败");
|
return error("用户信息获取失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 解析订单参数
|
// 3. 验证订单参数
|
||||||
if (params == null || params.get("0") == null) {
|
if (params == null || params.isEmpty()) {
|
||||||
return error("订单参数不能为空");
|
return error("订单参数不能为空");
|
||||||
}
|
}
|
||||||
Map<String, Object> orderParams = (Map<String, Object>) params.get("0");
|
|
||||||
|
|
||||||
// 4. 验证必要参数
|
// 4. 生成主订单号
|
||||||
Long productId = Long.valueOf(orderParams.get("product_id").toString());
|
String mainOrderId =GenerateCustomCode.generCreateOrder("WXB");
|
||||||
Long addressId = Long.valueOf(orderParams.get("address_id").toString());
|
|
||||||
|
|
||||||
|
// 5. 存储所有订单信息
|
||||||
|
List<Map<String, Object>> orderList = new ArrayList<>();
|
||||||
|
BigDecimal totalAmount = BigDecimal.ZERO; // 总金额
|
||||||
|
|
||||||
String sku = orderParams.get("sku") != null ? orderParams.get("sku").toString() : "";
|
// 6. 遍历所有订单项
|
||||||
|
for (String key : params.keySet()) {
|
||||||
// 5. 查询商品信息
|
// 跳过非数字键
|
||||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId);
|
if (!key.matches("\\d+")) {
|
||||||
if (serviceGoods == null) {
|
continue;
|
||||||
return error("商品不存在");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. 查询地址信息
|
Map<String, Object> orderParams = (Map<String, Object>) params.get(key);
|
||||||
|
|
||||||
|
// 验证必要参数
|
||||||
|
if (orderParams.get("product_id") == null || orderParams.get("address_id") == null) {
|
||||||
|
return error("商品ID或地址ID不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
Long productId = Long.valueOf(orderParams.get("product_id").toString());
|
||||||
|
Long addressId = Long.valueOf(orderParams.get("address_id").toString());
|
||||||
|
Long num = orderParams.get("num") != null ? Long.valueOf(orderParams.get("num").toString()) : 1L;
|
||||||
|
|
||||||
|
// 处理SKU参数
|
||||||
|
String sku = AppletControllerUtil.processSkuParam(orderParams.get("sku"));
|
||||||
|
|
||||||
|
// 查询商品信息
|
||||||
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId);
|
||||||
|
if (serviceGoods == null) {
|
||||||
|
return error("商品ID " + productId + " 不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询地址信息(只需要查询一次,假设所有订单使用相同地址)
|
||||||
UserAddress userAddress = userAddressService.selectUserAddressById(addressId);
|
UserAddress userAddress = userAddressService.selectUserAddressById(addressId);
|
||||||
if (userAddress == null) {
|
if (userAddress == null) {
|
||||||
return error("地址不存在");
|
return error("地址不存在");
|
||||||
}
|
}
|
||||||
//判断如果是商品就添加商品订单,如果是服务就添加服务订单
|
|
||||||
if(serviceGoods.getType()==2){
|
|
||||||
Long num = Long.valueOf(orderParams.get("num").toString());
|
|
||||||
|
|
||||||
|
// 计算单个订单金额
|
||||||
|
BigDecimal itemPrice = serviceGoods.getPrice().multiply(BigDecimal.valueOf(num));
|
||||||
|
totalAmount = totalAmount.add(itemPrice);
|
||||||
|
|
||||||
|
// 判断商品类型并创建相应订单
|
||||||
|
if (serviceGoods.getType() == 2) {
|
||||||
// 创建商品订单
|
// 创建商品订单
|
||||||
GoodsOrder goodsOrder = new GoodsOrder();
|
GoodsOrder goodsOrder = new GoodsOrder();
|
||||||
goodsOrder.setType(2);
|
goodsOrder.setType(2);
|
||||||
String mainOrderId = "WX" + System.currentTimeMillis();
|
|
||||||
String orderId = "B" + System.currentTimeMillis();
|
|
||||||
goodsOrder.setMainOrderId(mainOrderId);
|
goodsOrder.setMainOrderId(mainOrderId);
|
||||||
goodsOrder.setOrderId(orderId);
|
goodsOrder.setOrderId(GenerateCustomCode.generCreateOrder("B")); // 独立订单号
|
||||||
goodsOrder.setUid(user.getId());
|
goodsOrder.setUid(user.getId());
|
||||||
goodsOrder.setProductId(productId);
|
goodsOrder.setProductId(productId);
|
||||||
goodsOrder.setName(userAddress.getName());
|
goodsOrder.setName(userAddress.getName());
|
||||||
goodsOrder.setPhone(userAddress.getPhone());
|
goodsOrder.setPhone(userAddress.getPhone());
|
||||||
goodsOrder.setAddress(userAddress.getAddressName());
|
goodsOrder.setAddress(userAddress.getAddressName());
|
||||||
goodsOrder.setNum(num);
|
goodsOrder.setNum(num);
|
||||||
|
goodsOrder.setTotalPrice(itemPrice);
|
||||||
// 计算订单金额
|
|
||||||
BigDecimal totalPrice = serviceGoods.getPrice().multiply(BigDecimal.valueOf(num));
|
|
||||||
goodsOrder.setTotalPrice(totalPrice);
|
|
||||||
goodsOrder.setGoodPrice(serviceGoods.getPrice());
|
goodsOrder.setGoodPrice(serviceGoods.getPrice());
|
||||||
goodsOrder.setPayPrice(totalPrice); // 实际支付金额
|
goodsOrder.setPayPrice(itemPrice);
|
||||||
goodsOrder.setDeduction(new BigDecimal(0));
|
goodsOrder.setDeduction(new BigDecimal(0));
|
||||||
goodsOrder.setStatus(1L); // 待支付状态
|
goodsOrder.setStatus(1L); // 待支付状态
|
||||||
goodsOrder.setAddressId(addressId);
|
goodsOrder.setAddressId(addressId);
|
||||||
goodsOrder.setSku(sku);
|
goodsOrder.setSku(sku);
|
||||||
|
|
||||||
// 保存订单到数据库
|
// 保存商品订单
|
||||||
int insertResult = goodsOrderService.insertGoodsOrder(goodsOrder);
|
int insertResult = goodsOrderService.insertGoodsOrder(goodsOrder);
|
||||||
if (insertResult <= 0) {
|
if (insertResult <= 0) {
|
||||||
return error("订单创建失败,请稍后重试");
|
return error("商品订单创建失败,请稍后重试");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用微信支付统一下单
|
// 添加到订单列表
|
||||||
try {
|
Map<String, Object> orderInfo = new HashMap<>();
|
||||||
// 准备支付参数
|
orderInfo.put("type", "goods");
|
||||||
String openid = user.getOpenid();
|
orderInfo.put("orderId", goodsOrder.getId());
|
||||||
if (openid == null || openid.trim().isEmpty()) {
|
orderInfo.put("orderNo", goodsOrder.getOrderId());
|
||||||
return error("用户openid为空,无法发起支付");
|
orderInfo.put("productName", serviceGoods.getTitle());
|
||||||
}
|
orderInfo.put("price", itemPrice.toString());
|
||||||
|
orderList.add(orderInfo);
|
||||||
|
|
||||||
// 金额转换为分(微信支付要求)
|
|
||||||
int totalFeeInCents = totalPrice.multiply(new BigDecimal(100)).intValue();
|
|
||||||
String body = "商品订单-" + serviceGoods.getTitle();
|
|
||||||
String notifyUrl = "https://4d983d7f.r3.cpolar.top/api/wechat/pay/notify"; // TODO: 预留回调地址,需要根据实际部署环境配置
|
|
||||||
String attach = "goods_order:" + goodsOrder.getId(); // 附加数据,用于回调时识别订单类型
|
|
||||||
|
|
||||||
// 调用微信支付工具类
|
|
||||||
Map<String, Object> payResult = wechatPayUtil.unifiedOrder(
|
|
||||||
openid,
|
|
||||||
orderId,
|
|
||||||
totalFeeInCents,
|
|
||||||
body,
|
|
||||||
notifyUrl,
|
|
||||||
attach
|
|
||||||
);
|
|
||||||
|
|
||||||
if (payResult != null && (Boolean) payResult.get("success")) {
|
|
||||||
// 支付下单成功,返回支付参数给前端
|
|
||||||
Map<String, Object> payParams = (Map<String, Object>) payResult.get("payParams");
|
|
||||||
Map<String, Object> responseData = new HashMap<>();
|
|
||||||
responseData.put("orderId", goodsOrder.getId());
|
|
||||||
responseData.put("orderNo", orderId);
|
|
||||||
responseData.put("totalPrice", totalPrice.toString());
|
|
||||||
responseData.put("prepayId", payResult.get("prepayId"));
|
|
||||||
|
|
||||||
// 添加微信支付所需的参数(根据图片显示的格式)
|
|
||||||
if (payParams != null) {
|
|
||||||
responseData.put("appId", payParams.get("appId"));
|
|
||||||
responseData.put("timeStamp", payParams.get("timeStamp"));
|
|
||||||
responseData.put("nonceStr", payParams.get("nonceStr"));
|
|
||||||
responseData.put("package", payParams.get("package"));
|
|
||||||
responseData.put("signType", payParams.get("signType"));
|
|
||||||
responseData.put("paySign", payParams.get("paySign"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return AppletControllerUtil.appletSuccess(responseData);
|
|
||||||
} else {
|
} else {
|
||||||
// 支付下单失败,删除已创建的订单或标记为失败
|
// 创建服务订单
|
||||||
goodsOrder.setStatus(0L); // 标记为失败状态
|
String makeTime = orderParams.get("make_time") != null ? orderParams.get("make_time").toString() : "";
|
||||||
goodsOrderService.updateGoodsOrder(goodsOrder);
|
|
||||||
|
|
||||||
String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败";
|
|
||||||
return error("支付下单失败:" + errorMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 支付异常,删除已创建的订单或标记为失败
|
|
||||||
goodsOrder.setStatus(0L); // 标记为失败状态
|
|
||||||
goodsOrderService.updateGoodsOrder(goodsOrder);
|
|
||||||
|
|
||||||
logger.error("微信支付下单异常:", e);
|
|
||||||
return error("支付下单异常:" + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
}else{
|
|
||||||
String makeTime = orderParams.get("make_time").toString();
|
|
||||||
// 7. 创建订单对象
|
|
||||||
Order order = new Order();
|
Order order = new Order();
|
||||||
order.setType(1); // 1:服务项目
|
order.setType(1); // 1:服务项目
|
||||||
order.setCreateType(1); // 1:用户自主下单
|
order.setCreateType(1); // 1:用户自主下单
|
||||||
|
|
@ -4557,42 +4554,43 @@ public class AppletController extends BaseController {
|
||||||
order.setAddress(userAddress.getAddressInfo());
|
order.setAddress(userAddress.getAddressInfo());
|
||||||
order.setAddressId(addressId);
|
order.setAddressId(addressId);
|
||||||
order.setSku(sku);
|
order.setSku(sku);
|
||||||
|
order.setMainOrderId(mainOrderId);
|
||||||
|
order.setOrderId(GenerateCustomCode.generCreateOrder("B")); // 独立订单号
|
||||||
|
|
||||||
|
// 处理预约时间
|
||||||
// 解析预约时间
|
if (makeTime != null && !makeTime.isEmpty()) {
|
||||||
String[] makeTimeArr = makeTime.split(" ");
|
String[] makeTimeArr = makeTime.split(" ");
|
||||||
if (makeTimeArr.length != 2) {
|
if (makeTimeArr.length == 2) {
|
||||||
return error("预约时间格式错误");
|
|
||||||
}
|
|
||||||
// 将日期字符串转换为时间戳
|
|
||||||
try {
|
try {
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
Date date = sdf.parse(makeTimeArr[0]);
|
Date date = sdf.parse(makeTimeArr[0]);
|
||||||
order.setMakeTime(date.getTime() / 1000); // 转换为秒级时间戳
|
order.setMakeTime(date.getTime() / 1000);
|
||||||
order.setMakeHour(makeTimeArr[1]); // 设置预约时间段
|
order.setMakeHour(makeTimeArr[1]);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return error("预约时间格式错误");
|
logger.warn("预约时间格式错误: " + makeTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
order.setNum(1l); // 默认数量为1
|
order.setNum(num);
|
||||||
order.setTotalPrice(serviceGoods.getPrice()); // 总价等于商品价格
|
order.setTotalPrice(itemPrice);
|
||||||
order.setGoodPrice(serviceGoods.getPrice()); // 商品金额
|
order.setGoodPrice(serviceGoods.getPrice());
|
||||||
order.setServicePrice(BigDecimal.ZERO); // 服务金额默认为0
|
order.setServicePrice(BigDecimal.ZERO);
|
||||||
order.setPayPrice(serviceGoods.getPrice()); // 支付金额等于总价
|
order.setPayPrice(itemPrice);
|
||||||
order.setStatus(1L); // 1:待接单
|
order.setStatus(1L); // 1:待接单
|
||||||
order.setReceiveType(1L); // 1:自由抢单
|
order.setReceiveType(1L); // 1:自由抢单
|
||||||
order.setIsAccept(0); // 0:未接单
|
order.setIsAccept(0);
|
||||||
order.setIsComment(0); // 0:未评价
|
order.setIsComment(0);
|
||||||
order.setIsPause(1); // 0:未暂停
|
order.setIsPause(1);
|
||||||
order.setDeduction(new BigDecimal(0));
|
order.setDeduction(new BigDecimal(0));
|
||||||
// 8. 生成订单号
|
|
||||||
String orderId = generateOrderId();
|
// 保存服务订单
|
||||||
order.setOrderId(orderId);
|
|
||||||
order.setMainOrderId(orderId);
|
|
||||||
// 9. 保存订单
|
|
||||||
int result = orderService.insertOrder(order);
|
int result = orderService.insertOrder(order);
|
||||||
if (result > 0) {
|
if (result <= 0) {
|
||||||
//10预约后添加到订单记录中
|
return error("服务订单创建失败,请稍后重试");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加订单日志
|
||||||
OrderLog orderLog = new OrderLog();
|
OrderLog orderLog = new OrderLog();
|
||||||
orderLog.setOid(order.getId());
|
orderLog.setOid(order.getId());
|
||||||
orderLog.setOrderId(order.getOrderId());
|
orderLog.setOrderId(order.getOrderId());
|
||||||
|
|
@ -4602,58 +4600,319 @@ public class AppletController extends BaseController {
|
||||||
orderLog.setType(new BigDecimal(1.0));
|
orderLog.setType(new BigDecimal(1.0));
|
||||||
orderLog.setContent(jsonObject.toString());
|
orderLog.setContent(jsonObject.toString());
|
||||||
orderLogService.insertOrderLog(orderLog);
|
orderLogService.insertOrderLog(orderLog);
|
||||||
//完成订单的初步创建之后开始进行派单和发送订阅,以及预约师傅的操作
|
|
||||||
//完成订单后的第一步,向用户发送订阅消息
|
// 系统派单和消息通知逻辑
|
||||||
Order orderNewData= orderService.selectOrderById(order.getId());
|
Order orderNewData = orderService.selectOrderById(order.getId());
|
||||||
String wxsendmsg=WXsendMsgUtil.sendMsgForUserInfo(user.getOpenid(), orderNewData, serviceGoods);
|
String wxsendmsg = WXsendMsgUtil.sendMsgForUserInfo(user.getOpenid(), orderNewData, serviceGoods);
|
||||||
//第二步系统派单
|
|
||||||
Users worker = AppletControllerUtil.creatWorkerForOrder(orderNewData);
|
Users worker = AppletControllerUtil.creatWorkerForOrder(orderNewData);
|
||||||
//第三步向师傅发送订阅消息
|
|
||||||
if(worker!=null){
|
if (worker != null) {
|
||||||
//确定派单之后,更新订单状态为已派单,并添加订单日志记录
|
// 更新订单状态为已派单
|
||||||
//修改订单状态为派单开始-------------------------------------------
|
|
||||||
orderNewData.setWorkerId(worker.getId());
|
orderNewData.setWorkerId(worker.getId());
|
||||||
orderNewData.setStatus(2l);
|
orderNewData.setStatus(2l);
|
||||||
orderNewData.setIsPause(1);
|
orderNewData.setIsPause(1);
|
||||||
orderNewData.setReceiveTime(new Date());
|
orderNewData.setReceiveTime(new Date());
|
||||||
orderNewData.setReceiveType(3l);
|
orderNewData.setReceiveType(3l);
|
||||||
orderNewData.setLogStatus(9);
|
orderNewData.setLogStatus(9);
|
||||||
JSONObject jSONObject =new JSONObject();
|
JSONObject jSONObject = new JSONObject();
|
||||||
jSONObject.put("type",9);
|
jSONObject.put("type", 9);
|
||||||
orderNewData.setLogJson(jSONObject.toJSONString());
|
orderNewData.setLogJson(jSONObject.toJSONString());
|
||||||
orderService.updateOrder(orderNewData);
|
orderService.updateOrder(orderNewData);
|
||||||
|
|
||||||
|
// 添加派单日志
|
||||||
OrderLog orderLognew = new OrderLog();
|
OrderLog orderLognew = new OrderLog();
|
||||||
orderLognew.setOid(orderNewData.getId());
|
orderLognew.setOid(orderNewData.getId());
|
||||||
orderLognew.setOrderId(orderNewData.getOrderId());
|
orderLognew.setOrderId(orderNewData.getOrderId());
|
||||||
orderLognew.setTitle("平台派单");
|
orderLognew.setTitle("平台派单");
|
||||||
orderLognew.setType(new BigDecimal(1.1));
|
orderLognew.setType(new BigDecimal(1.1));
|
||||||
JSONObject jSONObject1 =new JSONObject();
|
JSONObject jSONObject1 = new JSONObject();
|
||||||
jSONObject1.put("name","师傅收到派单信息");
|
jSONObject1.put("name", "师傅收到派单信息");
|
||||||
orderLognew.setContent(jSONObject1.toJSONString());
|
orderLognew.setContent(jSONObject1.toJSONString());
|
||||||
orderLognew.setWorkerId(worker.getId());
|
orderLognew.setWorkerId(worker.getId());
|
||||||
orderLognew.setWorkerLogId(worker.getId());
|
orderLognew.setWorkerLogId(worker.getId());
|
||||||
orderLogService.insertOrderLog(orderLognew);
|
orderLogService.insertOrderLog(orderLognew);
|
||||||
//修改订单状态为派单结束-------------------------------------------
|
|
||||||
//给师傅发送微信订阅消息进行通知需要他进行接单
|
// 发送通知
|
||||||
WXsendMsgUtil.sendMsgForWorkerInfo(worker.getOpenid(), orderNewData, serviceGoods);
|
WXsendMsgUtil.sendMsgForWorkerInfo(worker.getOpenid(), orderNewData, serviceGoods);
|
||||||
//第四步给师傅进行电话通知
|
|
||||||
YunXinPhoneUtilAPI.httpsAxbTransfer(worker.getPhone());
|
YunXinPhoneUtilAPI.httpsAxbTransfer(worker.getPhone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加到订单列表
|
||||||
|
Map<String, Object> orderInfo = new HashMap<>();
|
||||||
|
orderInfo.put("type", "service");
|
||||||
|
orderInfo.put("orderId", order.getId());
|
||||||
|
orderInfo.put("orderNo", order.getOrderId());
|
||||||
|
orderInfo.put("productName", serviceGoods.getTitle());
|
||||||
|
orderInfo.put("price", itemPrice.toString());
|
||||||
|
orderList.add(orderInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println("wxsendmsg:" + wxsendmsg);
|
// 7. 如果有商品订单,需要发起微信支付
|
||||||
return success("预约成功");
|
boolean hasGoodsOrder = orderList.stream().anyMatch(order -> "goods".equals(order.get("type")));
|
||||||
|
|
||||||
|
if (hasGoodsOrder && totalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
// 使用工具类简化微信支付参数组装
|
||||||
|
Map<String, Object> payResult = wechatPayUtil.createBatchOrderAndPay(user.getOpenid(), mainOrderId, new BigDecimal(0.01), orderList.size(),"https://4d983d7f.r3.cpolar.top/api/goods/pay/notify");
|
||||||
|
//Map<String, Object> payResult = wechatPayUtil.createBatchOrderAndPay(user.getOpenid(), mainOrderId, totalAmount, orderList.size());
|
||||||
|
if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) {
|
||||||
|
Map<String, Object> responseData = new HashMap<>();
|
||||||
|
responseData.put("mainOrderId", mainOrderId);
|
||||||
|
responseData.put("orderList", orderList);
|
||||||
|
responseData.put("totalAmount", totalAmount.toString());
|
||||||
|
responseData.put("prepayId", payResult.get("prepayId"));
|
||||||
|
// 直接合并所有支付参数
|
||||||
|
responseData.putAll(payResult);
|
||||||
|
return AppletControllerUtil.appletSuccess(responseData);
|
||||||
} else {
|
} else {
|
||||||
return error("预约失败,请稍后重试");
|
String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败";
|
||||||
|
return error("支付下单失败:" + errorMsg);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// 没有商品订单,只有服务订单,直接返回成功
|
||||||
|
Map<String, Object> responseData = new HashMap<>();
|
||||||
|
responseData.put("mainOrderId", mainOrderId);
|
||||||
|
responseData.put("orderList", orderList);
|
||||||
|
responseData.put("totalAmount", totalAmount.toString());
|
||||||
|
return AppletControllerUtil.appletSuccess(responseData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return error("预约失败:" + e.getMessage());
|
logger.error("创建订单异常:", e);
|
||||||
|
return error("创建订单失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 尾款结算
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@PostMapping("api/service/order/pay/total/price")
|
||||||
|
public AjaxResult apiServiceOrderPayTotalPprice(@RequestBody Map<String, Object> params, HttpServletRequest request) {
|
||||||
|
// 1. 验证用户登录状态
|
||||||
|
String token = request.getHeader("token");
|
||||||
|
Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
|
||||||
|
if (!(Boolean) userValidation.get("valid")) {
|
||||||
|
return error("用户未登录或token无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取用户信息
|
||||||
|
Users user = (Users) userValidation.get("user");
|
||||||
|
if (user == null) {
|
||||||
|
return error("用户信息获取失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 验证必要参数
|
||||||
|
if (params == null || params.get("id") == null ) {
|
||||||
|
return error("参数不能为空");
|
||||||
|
}
|
||||||
|
Long worker_id = Long.valueOf(params.get("worker_id").toString());
|
||||||
|
String order_id = params.get("order_id").toString();
|
||||||
|
Order order = orderService.selectOrderByOrderId(order_id);
|
||||||
|
// 2. 查询订单日志(取type=5评估报价,或最新一条)
|
||||||
|
List<OrderLog> logList = orderLogService.selectOrderLogByOrderId(order.getOrderId());
|
||||||
|
OrderLog log = null;
|
||||||
|
for (OrderLog l : logList) {
|
||||||
|
if (l.getType() != null && l.getType().intValue() == 5) {
|
||||||
|
log = l;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (log == null && !logList.isEmpty()) {
|
||||||
|
log = logList.get(0);
|
||||||
|
}
|
||||||
|
if (log == null) {
|
||||||
|
return error("未找到订单日志");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> payResult = wechatPayUtil.createBatchOrderAndPay(
|
||||||
|
user.getOpenid(),
|
||||||
|
String.valueOf(order_id),
|
||||||
|
new BigDecimal(0.01),
|
||||||
|
1,
|
||||||
|
"https://4d983d7f.r3.cpolar.top/api/order/amount/pay/notify");
|
||||||
|
if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) {
|
||||||
|
Map<String, Object> responseData = new HashMap<>();
|
||||||
|
responseData.put("mainOrderId", order_id);
|
||||||
|
//responseData.put("orderList", orderList);
|
||||||
|
responseData.put("totalAmount",log.getPrice());
|
||||||
|
responseData.put("prepayId", payResult.get("prepayId"));
|
||||||
|
// 直接合并所有支付参数
|
||||||
|
responseData.putAll(payResult);
|
||||||
|
return AppletControllerUtil.appletSuccess(responseData);
|
||||||
|
} else {
|
||||||
|
String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败";
|
||||||
|
return error("支付下单失败:" + errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 上门费支付接口
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
@PostMapping("api/service/order/pay_fee")
|
||||||
|
public AjaxResult apiServiceOrderPayFee(@RequestBody Map<String, Object> params, HttpServletRequest request) {
|
||||||
|
// 1. 验证用户登录状态
|
||||||
|
String token = request.getHeader("token");
|
||||||
|
Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
|
||||||
|
if (!(Boolean) userValidation.get("valid")) {
|
||||||
|
return error("用户未登录或token无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取用户信息
|
||||||
|
Users user = (Users) userValidation.get("user");
|
||||||
|
if (user == null) {
|
||||||
|
return error("用户信息获取失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 验证必要参数
|
||||||
|
if (params == null || params.get("id") == null ) {
|
||||||
|
return error("参数不能为空");
|
||||||
|
}
|
||||||
|
Long orderId = Long.valueOf(params.get("id").toString());
|
||||||
|
OrderLog orderLog = orderLogService.selectOrderLogById(orderId);
|
||||||
|
if (orderLog != null) {
|
||||||
|
|
||||||
|
Map<String, Object> payResult = wechatPayUtil.createBatchOrderAndPay(
|
||||||
|
user.getOpenid(),
|
||||||
|
String.valueOf(orderLog.getId()),
|
||||||
|
new BigDecimal(0.01),
|
||||||
|
1,
|
||||||
|
"https://4d983d7f.r3.cpolar.top/api/door/fee/pay/notify");
|
||||||
|
if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) {
|
||||||
|
Map<String, Object> responseData = new HashMap<>();
|
||||||
|
responseData.put("mainOrderId", String.valueOf(orderLog.getId()));
|
||||||
|
//responseData.put("orderList", orderList);
|
||||||
|
responseData.put("totalAmount",orderLog.getPrice());
|
||||||
|
responseData.put("prepayId", payResult.get("prepayId"));
|
||||||
|
// 直接合并所有支付参数
|
||||||
|
responseData.putAll(payResult);
|
||||||
|
return AppletControllerUtil.appletSuccess(responseData);
|
||||||
|
} else {
|
||||||
|
String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败";
|
||||||
|
return error("支付下单失败:" + errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return error("支付失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定金支付接口
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
@PostMapping("/api/service/order/pay/deposit")
|
||||||
|
public AjaxResult apiServiceOrderPaydeposit(@RequestBody Map<String, Object> params, HttpServletRequest request) {
|
||||||
|
// 1. 验证用户登录状态
|
||||||
|
String token = request.getHeader("token");
|
||||||
|
Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
|
||||||
|
if (!(Boolean) userValidation.get("valid")) {
|
||||||
|
return error("用户未登录或token无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取用户信息
|
||||||
|
Users user = (Users) userValidation.get("user");
|
||||||
|
if (user == null) {
|
||||||
|
return error("用户信息获取失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 验证必要参数
|
||||||
|
if (params == null || params.get("id") == null ) {
|
||||||
|
return error("参数不能为空");
|
||||||
|
}
|
||||||
|
Long orderId = Long.valueOf(params.get("id").toString());
|
||||||
|
OrderLog orderLog = orderLogService.selectOrderLogById(orderId);
|
||||||
|
if (orderLog != null) {
|
||||||
|
|
||||||
|
Map<String, Object> payResult = wechatPayUtil.createBatchOrderAndPay(
|
||||||
|
user.getOpenid(),
|
||||||
|
String.valueOf(orderLog.getId()),
|
||||||
|
new BigDecimal(0.01),
|
||||||
|
1,
|
||||||
|
"https://4d983d7f.r3.cpolar.top/api/deposit/pay/notify");
|
||||||
|
if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) {
|
||||||
|
Map<String, Object> responseData = new HashMap<>();
|
||||||
|
responseData.put("mainOrderId", String.valueOf(orderLog.getId()));
|
||||||
|
//responseData.put("orderList", orderList);
|
||||||
|
responseData.put("totalAmount",orderLog.getPrice());
|
||||||
|
responseData.put("prepayId", payResult.get("prepayId"));
|
||||||
|
// 直接合并所有支付参数
|
||||||
|
responseData.putAll(payResult);
|
||||||
|
return AppletControllerUtil.appletSuccess(responseData);
|
||||||
|
} else {
|
||||||
|
String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败";
|
||||||
|
return error("支付下单失败:" + errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return error("支付失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个商品支付
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@PostMapping("api/goods/order/once_pay")
|
||||||
|
public AjaxResult apiGoodsOrderOncePay(@RequestBody Map<String, Object> params, HttpServletRequest request) {
|
||||||
|
// 1. 验证用户登录状态
|
||||||
|
String token = request.getHeader("token");
|
||||||
|
Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
|
||||||
|
if (!(Boolean) userValidation.get("valid")) {
|
||||||
|
return error("用户未登录或token无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取用户信息
|
||||||
|
Users user = (Users) userValidation.get("user");
|
||||||
|
if (user == null) {
|
||||||
|
return error("用户信息获取失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 验证必要参数
|
||||||
|
if (params == null || params.get("id") == null ) {
|
||||||
|
return error("参数不能为空");
|
||||||
|
}
|
||||||
|
Long orderId = Long.valueOf(params.get("id").toString());
|
||||||
|
GoodsOrder goodsOrder= goodsOrderService.selectGoodsOrderById(orderId);
|
||||||
|
logger.info("orderId:{}",orderId);
|
||||||
|
logger.info("goodsOrder:{}",goodsOrder);
|
||||||
|
if (goodsOrder != null) {
|
||||||
|
goodsOrder.setMainOrderId(GenerateCustomCode.generCreateOrder("WXB"));
|
||||||
|
int flg=goodsOrderService.updateGoodsOrder(goodsOrder);
|
||||||
|
//修改成功就开始走支付功能
|
||||||
|
if(flg>0){
|
||||||
|
goodsOrder.setMainOrderId(goodsOrder.getMainOrderId());
|
||||||
|
Map<String, Object> payResult = wechatPayUtil.createBatchOrderAndPay(user.getOpenid(), goodsOrder.getMainOrderId(), new BigDecimal(0.01), 1, "https://4d983d7f.r3.cpolar.top/api/goods/pay/notify");
|
||||||
|
if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) {
|
||||||
|
Map<String, Object> responseData = new HashMap<>();
|
||||||
|
responseData.put("mainOrderId", goodsOrder.getMainOrderId());
|
||||||
|
//responseData.put("orderList", orderList);
|
||||||
|
responseData.put("totalAmount", goodsOrder.getTotalPrice());
|
||||||
|
responseData.put("prepayId", payResult.get("prepayId"));
|
||||||
|
// 直接合并所有支付参数
|
||||||
|
responseData.putAll(payResult);
|
||||||
|
return AppletControllerUtil.appletSuccess(responseData);
|
||||||
|
} else {
|
||||||
|
String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败";
|
||||||
|
return error("支付下单失败:" + errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return error("支付失败");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成订单号
|
* 生成订单号
|
||||||
|
|
@ -4788,7 +5047,7 @@ public class AppletController extends BaseController {
|
||||||
orderLog.setTitle("师傅接单");
|
orderLog.setTitle("师傅接单");
|
||||||
orderLog.setType(new BigDecimal(2.0));
|
orderLog.setType(new BigDecimal(2.0));
|
||||||
JSONObject js=new JSONObject();
|
JSONObject js=new JSONObject();
|
||||||
js.put("type", 1);
|
js.put("name", "同意系统配单");
|
||||||
orderLog.setContent(js.toJSONString());
|
orderLog.setContent(js.toJSONString());
|
||||||
orderLog.setWorkerId(order.getWorkerId());
|
orderLog.setWorkerId(order.getWorkerId());
|
||||||
orderLog.setWorkerLogId(order.getWorkerId());
|
orderLog.setWorkerLogId(order.getWorkerId());
|
||||||
|
|
@ -5031,6 +5290,9 @@ public class AppletController extends BaseController {
|
||||||
@GetMapping("/api/worker/order/info/{id}")
|
@GetMapping("/api/worker/order/info/{id}")
|
||||||
public AjaxResult getWorkerOrderInfo(@PathVariable("id") Long id, HttpServletRequest request) {
|
public AjaxResult getWorkerOrderInfo(@PathVariable("id") Long id, HttpServletRequest request) {
|
||||||
try {
|
try {
|
||||||
|
// 4. 处理时间字段
|
||||||
|
java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
// DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
// 1. 校验token并获取师傅信息
|
// 1. 校验token并获取师傅信息
|
||||||
String token = request.getHeader("token");
|
String token = request.getHeader("token");
|
||||||
Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
|
Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
|
||||||
|
|
@ -5104,8 +5366,8 @@ public class AppletController extends BaseController {
|
||||||
logMap.put("coupon_id", log.getCouponId());
|
logMap.put("coupon_id", log.getCouponId());
|
||||||
logMap.put("deduction", log.getDeduction());
|
logMap.put("deduction", log.getDeduction());
|
||||||
logMap.put("worker_log_id", log.getWorkerLogId());
|
logMap.put("worker_log_id", log.getWorkerLogId());
|
||||||
logMap.put("created_at", log.getCreatedAt());
|
logMap.put("created_at", log.getCreatedAt() != null ? dateFormat.format(log.getCreatedAt()) : null);
|
||||||
logMap.put("updated_at", log.getUpdatedAt());
|
logMap.put("updated_at", log.getUpdatedAt() != null ? dateFormat.format(log.getUpdatedAt()) : null);
|
||||||
logMap.put("deleted_at", log.getDeletedAt());
|
logMap.put("deleted_at", log.getDeletedAt());
|
||||||
logArr.add(logMap);
|
logArr.add(logMap);
|
||||||
}
|
}
|
||||||
|
|
@ -5140,7 +5402,7 @@ public class AppletController extends BaseController {
|
||||||
data.put("sku", order.getSku());
|
data.put("sku", order.getSku());
|
||||||
data.put("worker_id", order.getWorkerId());
|
data.put("worker_id", order.getWorkerId());
|
||||||
data.put("first_worker_id", order.getFirstWorkerId());
|
data.put("first_worker_id", order.getFirstWorkerId());
|
||||||
data.put("receive_time", order.getReceiveTime());
|
data.put("receive_time",order.getReceiveTime() != null ? dateFormat.format(order.getReceiveTime()) : null);
|
||||||
data.put("is_comment", order.getIsComment());
|
data.put("is_comment", order.getIsComment());
|
||||||
data.put("receive_type", order.getReceiveType());
|
data.put("receive_type", order.getReceiveType());
|
||||||
data.put("is_accept", order.getIsAccept());
|
data.put("is_accept", order.getIsAccept());
|
||||||
|
|
@ -5154,9 +5416,9 @@ public class AppletController extends BaseController {
|
||||||
data.put("log_json", order.getLogJson());
|
data.put("log_json", order.getLogJson());
|
||||||
data.put("json_status", order.getJsonStatus());
|
data.put("json_status", order.getJsonStatus());
|
||||||
data.put("log_images", order.getLogImages());
|
data.put("log_images", order.getLogImages());
|
||||||
data.put("created_at", order.getCreatedAt());
|
data.put("created_at",order.getCreatedAt() != null ? dateFormat.format(order.getCreatedAt()) : null);
|
||||||
data.put("updated_at", order.getUpdatedAt());
|
data.put("updated_at",order.getUpdatedAt() != null ? dateFormat.format(order.getUpdatedAt()) : null);
|
||||||
data.put("deleted_at", order.getDeletedAt());
|
data.put("deleted_at",order.getDeletedAt() != null ? dateFormat.format(order.getDeletedAt()) : null);
|
||||||
data.put("phone_xx", order.getPhone()); // 可脱敏处理
|
data.put("phone_xx", order.getPhone()); // 可脱敏处理
|
||||||
data.put("user", user);
|
data.put("user", user);
|
||||||
data.put("product", product);
|
data.put("product", product);
|
||||||
|
|
@ -5167,6 +5429,89 @@ public class AppletController extends BaseController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付尾款回调到页面的数据
|
||||||
|
* 返回结构见json.txt
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/service/order/pay/total/price/info")
|
||||||
|
public AjaxResult getOrderPayLastInfo(@RequestBody Map<String, Object> params) {
|
||||||
|
try {
|
||||||
|
String orderId = (String) params.get("order_id");
|
||||||
|
if (StringUtils.isEmpty(orderId)) {
|
||||||
|
return error("订单号不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 查询订单
|
||||||
|
Order order = orderService.selectOrderByOrderId(orderId);
|
||||||
|
if (order == null) {
|
||||||
|
return error("订单不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 查询订单日志(取type=5评估报价,或最新一条)
|
||||||
|
List<OrderLog> logList = orderLogService.selectOrderLogByOrderId(orderId);
|
||||||
|
OrderLog log = null;
|
||||||
|
for (OrderLog l : logList) {
|
||||||
|
if (l.getType() != null && l.getType().intValue() == 5) {
|
||||||
|
log = l;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (log == null && !logList.isEmpty()) {
|
||||||
|
log = logList.get(0);
|
||||||
|
}
|
||||||
|
if (log == null) {
|
||||||
|
return error("未找到订单日志");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 组装content字段
|
||||||
|
JSONObject contentJson;
|
||||||
|
try {
|
||||||
|
contentJson = JSONObject.parseObject(log.getContent());
|
||||||
|
} catch (Exception e) {
|
||||||
|
contentJson = new JSONObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 组装返回数据
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("id", log.getId());
|
||||||
|
data.put("oid", log.getOid());
|
||||||
|
data.put("order_id", log.getOrderId());
|
||||||
|
data.put("log_order_id", log.getLogOrderId());
|
||||||
|
data.put("title", log.getTitle());
|
||||||
|
data.put("type", log.getType() != null ? log.getType().intValue() : null);
|
||||||
|
data.put("content", contentJson);
|
||||||
|
data.put("deposit", log.getDeposit() != null ? log.getDeposit().toString() : "0.00");
|
||||||
|
data.put("dep_paid", log.getDepPaid());
|
||||||
|
data.put("dep_pay_time", log.getDepPayTime());
|
||||||
|
data.put("dep_log_id", log.getDepLogId());
|
||||||
|
data.put("price", log.getPrice() != null ? log.getPrice().toString() : "0.00");
|
||||||
|
data.put("paid", log.getPaid());
|
||||||
|
data.put("pay_time", log.getPayTime() != null ? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(log.getPayTime() * 1000)) : null);
|
||||||
|
data.put("log_id", log.getLogId());
|
||||||
|
data.put("worker_id", log.getWorkerId());
|
||||||
|
data.put("first_worker_id", log.getFirstWorkerId());
|
||||||
|
data.put("give_up", log.getGiveUp());
|
||||||
|
data.put("worker_cost", log.getWorkerCost());
|
||||||
|
data.put("reduction_price", log.getReductionPrice() != null ? log.getReductionPrice().toString() : "0.00");
|
||||||
|
data.put("is_pause", log.getIsPause());
|
||||||
|
data.put("coupon_id", log.getCouponId());
|
||||||
|
data.put("deduction", log.getDeduction());
|
||||||
|
data.put("worker_log_id", log.getWorkerLogId());
|
||||||
|
data.put("created_at", log.getCreatedAt() != null ? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(log.getCreatedAt()) : null);
|
||||||
|
data.put("updated_at", log.getUpdatedAt() != null ? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(log.getUpdatedAt()) : null);
|
||||||
|
data.put("deleted_at", log.getDeletedAt());
|
||||||
|
|
||||||
|
return success(data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return error("查询失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 师傅列表接口
|
* 师傅列表接口
|
||||||
* 返回结构见json.txt
|
* 返回结构见json.txt
|
||||||
|
|
@ -5903,6 +6248,8 @@ public class AppletController extends BaseController {
|
||||||
}
|
}
|
||||||
// 查询最新订单日志
|
// 查询最新订单日志
|
||||||
OrderLog neworderLog = orderLogService.selectDataTheFirstNew(order.getId());
|
OrderLog neworderLog = orderLogService.selectDataTheFirstNew(order.getId());
|
||||||
|
System.out.println("######################"+order.getId());
|
||||||
|
System.out.println("^^^^^^^^^^^^^^^^^^^^^^"+neworderLog.getId());
|
||||||
if (neworderLog!=null){
|
if (neworderLog!=null){
|
||||||
//修改订单日志添加费用
|
//修改订单日志添加费用
|
||||||
neworderLog.setPrice(price);
|
neworderLog.setPrice(price);
|
||||||
|
|
@ -5914,11 +6261,13 @@ public class AppletController extends BaseController {
|
||||||
JSONObject jsonObject3 = new JSONObject();
|
JSONObject jsonObject3 = new JSONObject();
|
||||||
jsonObject3.put("type", 2);
|
jsonObject3.put("type", 2);
|
||||||
order.setLogJson(jsonObject3.toJSONString());
|
order.setLogJson(jsonObject3.toJSONString());
|
||||||
|
orderLogService.updateOrderLog(neworderLog);
|
||||||
orderService.updateOrder(order);
|
orderService.updateOrder(order);
|
||||||
Users userinfo = usersService.selectUsersById(order.getUid());
|
Users userinfo = usersService.selectUsersById(order.getUid());
|
||||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId());
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId());
|
||||||
//给用户发送微信推送消息
|
//给用户发送微信推送消息
|
||||||
WXsendMsgUtil.sendMsgForUserDoorMoney(userinfo.getOpenid(),order,serviceGoods); }
|
WXsendMsgUtil.sendMsgForUserDoorMoney(userinfo.getOpenid(),order,serviceGoods);
|
||||||
|
}
|
||||||
// List<OrderLog> logList = orderLogService.selectOrderLogByOrderId(order.getOrderId());
|
// List<OrderLog> logList = orderLogService.selectOrderLogByOrderId(order.getOrderId());
|
||||||
// if (logList == null || logList.isEmpty()) {
|
// if (logList == null || logList.isEmpty()) {
|
||||||
// return AppletControllerUtil.appletWarning("订单日志不存在");
|
// return AppletControllerUtil.appletWarning("订单日志不存在");
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package com.ruoyi.system.controller;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.system.ControllerUtil.AppletControllerUtil;
|
import com.ruoyi.system.ControllerUtil.AppletControllerUtil;
|
||||||
import com.ruoyi.system.ControllerUtil.WechatPayUtil;
|
|
||||||
import com.ruoyi.system.domain.ServiceGoods;
|
import com.ruoyi.system.domain.ServiceGoods;
|
||||||
import com.ruoyi.system.domain.GoodsOrderCursor;
|
import com.ruoyi.system.domain.GoodsOrderCursor;
|
||||||
import com.ruoyi.system.service.IServiceGoodsService;
|
import com.ruoyi.system.service.IServiceGoodsService;
|
||||||
|
|
@ -12,9 +11,11 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -33,9 +34,6 @@ public class CoursorUtil extends BaseController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IGoodsOrderCursorService goodsOrderCursorService;
|
private IGoodsOrderCursorService goodsOrderCursorService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WechatPayUtil wechatPayUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取服务商品详细信息
|
* 获取服务商品详细信息
|
||||||
*
|
*
|
||||||
|
|
@ -45,8 +43,8 @@ public class CoursorUtil extends BaseController {
|
||||||
* <p>
|
* <p>
|
||||||
* 接口说明:
|
* 接口说明:
|
||||||
* - 根据商品ID获取详细信息
|
* - 根据商品ID获取详细信息
|
||||||
* - type=1时返回ServiceGoodsResponse格式
|
* - type=1时返回服务商品格式
|
||||||
* - type=2时返回json.txt中的商品格式
|
* - type=2时返回普通商品格式
|
||||||
* - 包含图片、基础信息等数组数据
|
* - 包含图片、基础信息等数组数据
|
||||||
*/
|
*/
|
||||||
@GetMapping(value = "/api/service/infoData/id/{id}")
|
@GetMapping(value = "/api/service/infoData/id/{id}")
|
||||||
|
|
@ -63,143 +61,170 @@ public class CoursorUtil extends BaseController {
|
||||||
return AppletControllerUtil.appletError("商品不存在或已下架");
|
return AppletControllerUtil.appletError("商品不存在或已下架");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据商品类型返回不同格式的数据
|
// 构建返回数据
|
||||||
if (serviceGoodsData.getType() != null && serviceGoodsData.getType().intValue() == 2) {
|
Map<String, Object> goodsData = buildServiceGoodsResponse(serviceGoodsData);
|
||||||
// type=2时返回json.txt格式
|
|
||||||
Map<String, Object> goodsData = AppletControllerUtil.buildType2ServiceGoodsResponse(serviceGoodsData);
|
|
||||||
return AppletControllerUtil.appletSuccess(goodsData);
|
return AppletControllerUtil.appletSuccess(goodsData);
|
||||||
} else {
|
|
||||||
// type=1时返回ServiceGoodsResponse格式
|
|
||||||
AppletControllerUtil.ServiceGoodsResponse response = new AppletControllerUtil.ServiceGoodsResponse(serviceGoodsData);
|
|
||||||
return AppletControllerUtil.appletSuccess(response);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return AppletControllerUtil.appletError("查询商品详情失败:" + e.getMessage());
|
return AppletControllerUtil.appletError("查询商品详情失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付回调通知接口
|
* 获取订单游标信息
|
||||||
*
|
*
|
||||||
|
* @param id 游标ID
|
||||||
* @param request HTTP请求对象
|
* @param request HTTP请求对象
|
||||||
* @return XML格式的响应给微信服务器
|
* @return 游标详细信息
|
||||||
* <p>
|
|
||||||
* 接口说明:
|
|
||||||
* - 接收微信支付成功后的异步通知
|
|
||||||
* - 验证签名确保数据安全性
|
|
||||||
* - 处理支付成功后的业务逻辑
|
|
||||||
* - 返回XML格式响应告知微信处理结果
|
|
||||||
* <p>
|
|
||||||
* 微信支付回调特点:
|
|
||||||
* - 微信会POST XML数据到此接口
|
|
||||||
* - 必须返回XML格式的成功/失败响应
|
|
||||||
* - 如果返回失败,微信会重复发送通知
|
|
||||||
* - 建议做幂等性处理,避免重复处理同一笔订单
|
|
||||||
*/
|
*/
|
||||||
@PostMapping(value = "/api/wechatdata/pay/notify")
|
@GetMapping(value = "/api/cursor/order/info/{id}")
|
||||||
public String handleWechatPayNotify(HttpServletRequest request) {
|
public AjaxResult getOrderCursorInfo(@PathVariable("id") long id, HttpServletRequest request) {
|
||||||
try {
|
try {
|
||||||
// 记录回调日志(可选)
|
// 参数验证
|
||||||
logger.info("收到微信支付回调通知,开始处理...");
|
if (id <= 0) {
|
||||||
|
return AppletControllerUtil.appletError("游标ID无效");
|
||||||
// 1. 使用WechatPayUtil处理支付回调
|
|
||||||
Map<String, Object> notifyResult = wechatPayUtil.handlePayNotify(request);
|
|
||||||
|
|
||||||
// 2. 检查处理结果
|
|
||||||
boolean success = (Boolean) notifyResult.get("success");
|
|
||||||
String message = (String) notifyResult.get("message");
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
// 3. 获取支付信息
|
|
||||||
Map<String, Object> paymentInfo = (Map<String, Object>) notifyResult.get("paymentInfo");
|
|
||||||
|
|
||||||
// 4. 处理支付成功的业务逻辑
|
|
||||||
handlePaymentSuccessLogic(paymentInfo);
|
|
||||||
|
|
||||||
// 5. 记录成功日志
|
|
||||||
logger.info("微信支付回调处理成功:订单号={}, 微信交易号={}",
|
|
||||||
paymentInfo.get("outTradeNo"), paymentInfo.get("transactionId"));
|
|
||||||
|
|
||||||
// 6. 返回成功响应给微信
|
|
||||||
return buildSuccessResponse();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// 7. 处理失败情况
|
|
||||||
logger.error("微信支付回调处理失败:{}", message);
|
|
||||||
|
|
||||||
// 8. 返回失败响应给微信
|
|
||||||
return buildFailResponse(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
// 查询游标信息
|
||||||
// 9. 异常处理
|
GoodsOrderCursor cursor = goodsOrderCursorService.selectGoodsOrderCursorById(id);
|
||||||
logger.error("微信支付回调处理异常:", e);
|
if (cursor == null) {
|
||||||
|
return AppletControllerUtil.appletError("游标信息不存在");
|
||||||
|
}
|
||||||
|
|
||||||
// 10. 返回异常响应给微信
|
// 构建返回数据
|
||||||
return buildFailResponse("处理异常:" + e.getMessage());
|
Map<String, Object> cursorData = buildCursorResponse(cursor);
|
||||||
|
return AppletControllerUtil.appletSuccess(cursorData);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AppletControllerUtil.appletError("查询游标信息失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理支付成功后的业务逻辑
|
* 创建订单游标
|
||||||
*
|
*
|
||||||
* @param paymentInfo 支付信息
|
* @param params 游标参数
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return 创建结果
|
||||||
*/
|
*/
|
||||||
private void handlePaymentSuccessLogic(Map<String, Object> paymentInfo) {
|
@PostMapping(value = "/api/cursor/order/create")
|
||||||
|
public AjaxResult createOrderCursor(@RequestBody Map<String, Object> params, HttpServletRequest request) {
|
||||||
try {
|
try {
|
||||||
String outTradeNo = (String) paymentInfo.get("outTradeNo");
|
// 参数验证
|
||||||
String transactionId = (String) paymentInfo.get("transactionId");
|
if (params == null || params.isEmpty()) {
|
||||||
String totalFee = (String) paymentInfo.get("totalFee");
|
return AppletControllerUtil.appletError("参数不能为空");
|
||||||
String timeEnd = (String) paymentInfo.get("timeEnd");
|
|
||||||
String attach = (String) paymentInfo.get("attach");
|
|
||||||
String openid = (String) paymentInfo.get("openid");
|
|
||||||
|
|
||||||
logger.info("开始处理支付成功业务逻辑:订单号={}, 金额={}", outTradeNo, totalFee);
|
|
||||||
|
|
||||||
// TODO: 根据实际业务需求实现以下逻辑
|
|
||||||
// 1. 更新订单状态为已支付
|
|
||||||
// 2. 记录支付流水
|
|
||||||
// 3. 发送支付成功通知给用户
|
|
||||||
// 4. 触发后续业务流程(如发货、服务安排等)
|
|
||||||
// 5. 更新库存(如果是商品订单)
|
|
||||||
|
|
||||||
// 示例:如果是商品订单临时表的支付
|
|
||||||
if (attach != null && attach.startsWith("cursor_order:")) {
|
|
||||||
String cursorOrderId = attach.replace("cursor_order:", "");
|
|
||||||
// 可以在这里处理商品订单临时表的状态更新
|
|
||||||
logger.info("处理商品订单临时表支付:ID={}", cursorOrderId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用AppletControllerUtil的通用支付成功处理方法
|
// 创建游标对象
|
||||||
AppletControllerUtil.handlePaymentSuccess(paymentInfo, false);
|
GoodsOrderCursor cursor = new GoodsOrderCursor();
|
||||||
|
|
||||||
logger.info("支付成功业务逻辑处理完成:订单号={}", outTradeNo);
|
// 设置基本信息
|
||||||
|
if (params.get("productId") != null) {
|
||||||
|
cursor.setProductId(Long.valueOf(params.get("productId").toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.get("sku") != null) {
|
||||||
|
cursor.setSku(params.get("sku").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.get("type") != null) {
|
||||||
|
cursor.setType(Long.valueOf(params.get("type").toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.get("num") != null) {
|
||||||
|
cursor.setNum(Long.valueOf(params.get("num").toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.get("totalPrice") != null) {
|
||||||
|
cursor.setTotalPrice(new BigDecimal(params.get("totalPrice").toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存游标
|
||||||
|
int result = goodsOrderCursorService.insertGoodsOrderCursor(cursor);
|
||||||
|
if (result > 0) {
|
||||||
|
Map<String, Object> responseData = new HashMap<>();
|
||||||
|
responseData.put("cursorId", cursor.getId());
|
||||||
|
return AppletControllerUtil.appletSuccess(responseData);
|
||||||
|
} else {
|
||||||
|
return AppletControllerUtil.appletError("创建游标失败");
|
||||||
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("处理支付成功业务逻辑异常:", e);
|
return AppletControllerUtil.appletError("创建游标失败:" + e.getMessage());
|
||||||
// 注意:即使业务逻辑处理失败,也应该向微信返回成功响应
|
|
||||||
// 避免微信重复发送通知,可以通过日志或其他方式处理业务异常
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建成功响应XML
|
* 构建服务商品响应数据
|
||||||
|
*
|
||||||
|
* @param serviceGoods 服务商品对象
|
||||||
|
* @return 响应数据
|
||||||
*/
|
*/
|
||||||
private String buildSuccessResponse() {
|
private Map<String, Object> buildServiceGoodsResponse(ServiceGoods serviceGoods) {
|
||||||
return "<xml>" +
|
Map<String, Object> goodsData = new HashMap<>();
|
||||||
"<return_code><![CDATA[SUCCESS]]></return_code>" +
|
|
||||||
"<return_msg><![CDATA[OK]]></return_msg>" +
|
// 基础信息
|
||||||
"</xml>";
|
goodsData.put("id", serviceGoods.getId());
|
||||||
|
goodsData.put("title", serviceGoods.getTitle());
|
||||||
|
goodsData.put("sub_title", serviceGoods.getSubTitle());
|
||||||
|
goodsData.put("price", serviceGoods.getPrice());
|
||||||
|
goodsData.put("type", serviceGoods.getType());
|
||||||
|
goodsData.put("status", serviceGoods.getStatus());
|
||||||
|
|
||||||
|
// 图片信息
|
||||||
|
goodsData.put("icon", AppletControllerUtil.buildImageUrl(serviceGoods.getIcon()));
|
||||||
|
|
||||||
|
// 详细信息
|
||||||
|
if (serviceGoods.getDescription() != null) {
|
||||||
|
goodsData.put("description", serviceGoods.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 简介信息
|
||||||
|
if (serviceGoods.getInfo() != null) {
|
||||||
|
goodsData.put("info", serviceGoods.getInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分类信息
|
||||||
|
if (serviceGoods.getCateId() != null) {
|
||||||
|
goodsData.put("cate_id", serviceGoods.getCateId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据商品类型添加特定字段
|
||||||
|
if (serviceGoods.getType() != null && serviceGoods.getType().intValue() == 2) {
|
||||||
|
// 普通商品特有字段
|
||||||
|
goodsData.put("stock", serviceGoods.getStock() != null ? serviceGoods.getStock() : 0);
|
||||||
|
goodsData.put("sales", serviceGoods.getSales() != null ? serviceGoods.getSales() : 0);
|
||||||
|
goodsData.put("postage", serviceGoods.getPostage() != null ? serviceGoods.getPostage() : BigDecimal.ZERO);
|
||||||
|
} else {
|
||||||
|
// 服务商品特有字段
|
||||||
|
goodsData.put("service_type", "service");
|
||||||
|
goodsData.put("project", serviceGoods.getProject() != null ? serviceGoods.getProject() : "");
|
||||||
|
goodsData.put("basic", serviceGoods.getBasic() != null ? serviceGoods.getBasic() : "");
|
||||||
|
goodsData.put("material", serviceGoods.getMaterial() != null ? serviceGoods.getMaterial() : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return goodsData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建失败响应XML
|
* 构建游标响应数据
|
||||||
|
*
|
||||||
|
* @param cursor 游标对象
|
||||||
|
* @return 响应数据
|
||||||
*/
|
*/
|
||||||
private String buildFailResponse(String message) {
|
private Map<String, Object> buildCursorResponse(GoodsOrderCursor cursor) {
|
||||||
return "<xml>" +
|
Map<String, Object> cursorData = new HashMap<>();
|
||||||
"<return_code><![CDATA[FAIL]]></return_code>" +
|
|
||||||
"<return_msg><![CDATA[" + message + "]]></return_msg>" +
|
|
||||||
"</xml>";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
cursorData.put("id", cursor.getId());
|
||||||
|
cursorData.put("productId", cursor.getProductId());
|
||||||
|
cursorData.put("sku", cursor.getSku());
|
||||||
|
cursorData.put("type", cursor.getType());
|
||||||
|
cursorData.put("num", cursor.getNum());
|
||||||
|
cursorData.put("totalPrice", cursor.getTotalPrice());
|
||||||
|
cursorData.put("postage", cursor.getPostage());
|
||||||
|
cursorData.put("createdAt", cursor.getCreatedAt());
|
||||||
|
cursorData.put("updatedAt", cursor.getUpdatedAt());
|
||||||
|
|
||||||
|
return cursorData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,949 @@
|
||||||
|
package com.ruoyi.system.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.system.ControllerUtil.GenerateCustomCode;
|
||||||
|
import com.ruoyi.system.ControllerUtil.WXsendMsgUtil;
|
||||||
|
import com.ruoyi.system.ControllerUtil.WechatPayUtil;
|
||||||
|
import com.ruoyi.system.domain.*;
|
||||||
|
import com.ruoyi.system.service.*;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付回调控制器
|
||||||
|
*
|
||||||
|
* 处理各种支付场景的微信支付回调通知
|
||||||
|
* 所有回调接口都以api开头,符合项目规范
|
||||||
|
*
|
||||||
|
* @author Mr. Zhang Pan
|
||||||
|
* @date 2025-06-16
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class PayNotifyController extends BaseController {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PayNotifyController.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WechatPayUtil wechatPayUtil;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IGoodsOrderService goodsOrderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IOrderService orderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IOrderLogService orderLogService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IUsersService usersService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IServiceGoodsService serviceGoodsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISiteConfigService siteConfigService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IIntegralLogService integralLogService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IPayMoneyLogService payMoneyLogService;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IWorkerLevelService workerLevelService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IWorkerMarginLogService workerMarginLogService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品支付回调接口
|
||||||
|
*
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return XML格式响应给微信服务器
|
||||||
|
*
|
||||||
|
* 处理商品订单的支付成功回调:
|
||||||
|
* 1. 验证支付签名
|
||||||
|
* 2. 更新商品订单支付状态
|
||||||
|
* 3. 更新订单支付时间和交易号
|
||||||
|
* 4. 处理库存扣减等业务逻辑
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/api/goods/pay/notify")
|
||||||
|
public String apiGoodsPayNotify(HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
logger.info("收到商品支付回调通知,开始处理...");
|
||||||
|
|
||||||
|
// 1. 使用WechatPayUtil处理支付回调
|
||||||
|
Map<String, Object> notifyResult = wechatPayUtil.handlePayNotify(request);
|
||||||
|
|
||||||
|
// 2. 检查处理结果
|
||||||
|
boolean success = (Boolean) notifyResult.get("success");
|
||||||
|
String message = (String) notifyResult.get("message");
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
logger.error("商品支付回调处理失败:{}", message);
|
||||||
|
return buildFailResponse("商品支付回调处理失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 获取支付信息
|
||||||
|
Map<String, Object> paymentInfo = (Map<String, Object>) notifyResult.get("paymentInfo");
|
||||||
|
String outTradeNo = (String) paymentInfo.get("outTradeNo");
|
||||||
|
String transactionId = (String) paymentInfo.get("transactionId");
|
||||||
|
String totalFee = (String) paymentInfo.get("totalFee");
|
||||||
|
|
||||||
|
// 4. 查询对应的商品订单
|
||||||
|
GoodsOrder goodsOrder = new GoodsOrder();
|
||||||
|
goodsOrder.setMainOrderId(outTradeNo);
|
||||||
|
List<GoodsOrder> goodsOrderslist = goodsOrderService.selectGoodsOrderList(goodsOrder);
|
||||||
|
|
||||||
|
// if (!goodsOrderslist.isEmpty()) {
|
||||||
|
// logger.error("商品订单不存在,订单号:{}", outTradeNo);
|
||||||
|
// return buildFailResponse("商品订单不存在");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 5. 检查订单状态,避免重复处理
|
||||||
|
// if (goodsOrder.getStatus() != null && goodsOrder.getStatus() == 2L) {
|
||||||
|
// logger.info("商品订单已支付,订单号:{}", outTradeNo);
|
||||||
|
// return buildSuccessResponse();
|
||||||
|
// }
|
||||||
|
long uid = Long.parseLong("0");
|
||||||
|
// 6. 更新商品订单状态
|
||||||
|
for (GoodsOrder goodsOrderData : goodsOrderslist){
|
||||||
|
uid= goodsOrderData.getUid();
|
||||||
|
goodsOrderData.setStatus(2L); // 2:已支付
|
||||||
|
goodsOrderData.setPayTime(new Date());
|
||||||
|
goodsOrderData.setTransactionId(transactionId);
|
||||||
|
int updateResult = goodsOrderService.updateGoodsOrder(goodsOrderData);
|
||||||
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodsOrderData.getProductId());
|
||||||
|
Users userinfo = usersService.selectUsersById(goodsOrderData.getUid());
|
||||||
|
WXsendMsgUtil.sendUserForMoneySuccess(userinfo.getOpenid(),goodsOrder,serviceGoods);
|
||||||
|
}
|
||||||
|
// if (updateResult <= 0) {
|
||||||
|
// logger.error("更新商品订单状态失败,订单号:{}", outTradeNo);
|
||||||
|
// return buildFailResponse("更新订单状态失败");
|
||||||
|
// }
|
||||||
|
Users users =usersService.selectUsersById(uid);
|
||||||
|
|
||||||
|
// 7. 处理商品订单支付成功后的业务逻辑
|
||||||
|
handleGoodsPaymentSuccess(users,outTradeNo, paymentInfo);
|
||||||
|
//8向客户推送微信消息
|
||||||
|
|
||||||
|
//sendWechatMessage(users,outTradeNo);
|
||||||
|
logger.info("商品支付回调处理成功,订单号:{}", outTradeNo);
|
||||||
|
return buildSuccessResponse();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("商品支付回调处理异常:", e);
|
||||||
|
return buildFailResponse("商品支付回调处理异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上门费支付回调接口
|
||||||
|
*
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return XML格式响应给微信服务器
|
||||||
|
*
|
||||||
|
* 处理上门费的支付成功回调:
|
||||||
|
* 1. 验证支付签名
|
||||||
|
* 2. 更新订单日志中的上门费支付状态
|
||||||
|
* 3. 更新订单状态为已支付上门费
|
||||||
|
* 4. 通知师傅可以开始上门服务
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/api/door/fee/pay/notify")
|
||||||
|
public String apiDoorFeePayNotify(HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
logger.info("收到上门费支付回调通知,开始处理...");
|
||||||
|
|
||||||
|
// 1. 使用WechatPayUtil处理支付回调
|
||||||
|
Map<String, Object> notifyResult = wechatPayUtil.handlePayNotify(request);
|
||||||
|
|
||||||
|
// 2. 检查处理结果
|
||||||
|
boolean success = (Boolean) notifyResult.get("success");
|
||||||
|
String message = (String) notifyResult.get("message");
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
logger.error("上门费支付回调处理失败:{}", message);
|
||||||
|
return buildFailResponse("上门费支付回调处理失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 获取支付信息
|
||||||
|
Map<String, Object> paymentInfo = (Map<String, Object>) notifyResult.get("paymentInfo");
|
||||||
|
String outTradeNo = (String) paymentInfo.get("outTradeNo");
|
||||||
|
String transactionId = (String) paymentInfo.get("transactionId");
|
||||||
|
String totalFee = (String) paymentInfo.get("totalFee");
|
||||||
|
|
||||||
|
// 4. 查询对应的订单日志(上门费记录)
|
||||||
|
OrderLog orderLog = orderLogService.selectOrderLogById(Long.parseLong(outTradeNo));
|
||||||
|
if (orderLog == null) {
|
||||||
|
logger.error("上门费订单记录不存在,订单号:{}", outTradeNo);
|
||||||
|
return buildFailResponse("上门费订单记录不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 检查支付状态,避免重复处理
|
||||||
|
if (orderLog.getPaid() != null && orderLog.getPaid() == 2L) {
|
||||||
|
logger.info("上门费已支付,订单号:{}", outTradeNo);
|
||||||
|
return buildSuccessResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 更新上门费支付状态
|
||||||
|
orderLog.setPaid(2L); // 1:已支付
|
||||||
|
orderLog.setWorkerCost(new BigDecimal(totalFee));
|
||||||
|
orderLog.setPayTime(System.currentTimeMillis()/1000);
|
||||||
|
//orderLog.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
int updateResult = orderLogService.updateOrderLog(orderLog);
|
||||||
|
logger.error("更新上门费支付状态失败,订单号:{}", outTradeNo);
|
||||||
|
if (updateResult <= 0) {
|
||||||
|
logger.error("更新上门费支付状态失败,订单号:{}", outTradeNo);
|
||||||
|
return buildFailResponse("更新上门费支付状态失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// // 7. 更新主订单状态
|
||||||
|
Order mainOrder = orderService.selectOrderByOrderId(orderLog.getOrderId());
|
||||||
|
Users users = usersService.selectUsersById(mainOrder.getUid());
|
||||||
|
// if (mainOrder != null) {
|
||||||
|
// // 更新订单状态,表示上门费已支付
|
||||||
|
// JSONObject logJson = new JSONObject();
|
||||||
|
// logJson.put("type", 3);
|
||||||
|
// logJson.put("doorFeePaid", true);
|
||||||
|
// mainOrder.setLogJson(logJson.toJSONString());
|
||||||
|
// mainOrder.setJsonStatus(4); // 4:已支付上门费,可以出发上门
|
||||||
|
// orderService.updateOrder(mainOrder);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 8. 处理上门费支付成功后的业务逻辑
|
||||||
|
handleDoorFeePaymentSuccess(orderLog, paymentInfo);
|
||||||
|
|
||||||
|
// 2. 处理积分奖励
|
||||||
|
handleIntegralReward(users, paymentInfo, "付款赠送积分");
|
||||||
|
//微信推送给师傅用户已支付上门费String openid, Order order, ServiceGoods serviceGoods
|
||||||
|
Users worker=usersService.selectUsersById(mainOrder.getWorkerId());
|
||||||
|
if (worker != null){
|
||||||
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(mainOrder.getProductId());
|
||||||
|
if (serviceGoods != null){
|
||||||
|
WXsendMsgUtil.sendUserPayDoorMoneyForWorker(worker.getOpenid(),mainOrder,serviceGoods);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("上门费支付回调处理成功,订单号:{}", outTradeNo);
|
||||||
|
return buildSuccessResponse();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("上门费支付回调处理异常:", e);
|
||||||
|
return buildFailResponse("上门费支付回调处理异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定金支付回调接口
|
||||||
|
*
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return XML格式响应给微信服务器
|
||||||
|
*
|
||||||
|
* 处理定金的支付成功回调:
|
||||||
|
* 1. 验证支付签名
|
||||||
|
* 2. 更新订单日志中的定金支付状态
|
||||||
|
* 3. 更新订单状态为已支付定金
|
||||||
|
* 4. 记录定金支付时间和交易号
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/api/deposit/pay/notify")
|
||||||
|
public String apiDepositPayNotify(HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
logger.info("收到定金支付回调通知,开始处理...");
|
||||||
|
|
||||||
|
// 1. 使用WechatPayUtil处理支付回调
|
||||||
|
Map<String, Object> notifyResult = wechatPayUtil.handlePayNotify(request);
|
||||||
|
|
||||||
|
// 2. 检查处理结果
|
||||||
|
boolean success = (Boolean) notifyResult.get("success");
|
||||||
|
String message = (String) notifyResult.get("message");
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
logger.error("定金支付回调处理失败:{}", message);
|
||||||
|
return buildFailResponse("定金支付回调处理失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 获取支付信息
|
||||||
|
Map<String, Object> paymentInfo = (Map<String, Object>) notifyResult.get("paymentInfo");
|
||||||
|
String outTradeNo = (String) paymentInfo.get("outTradeNo");
|
||||||
|
String transactionId = (String) paymentInfo.get("transactionId");
|
||||||
|
String totalFee = (String) paymentInfo.get("totalFee");
|
||||||
|
|
||||||
|
// 4. 查询对应的订单日志(定金记录)
|
||||||
|
OrderLog orderLog = orderLogService.selectOrderLogById(Long.parseLong(outTradeNo));
|
||||||
|
if (orderLog == null) {
|
||||||
|
logger.error("定金订单记录不存在,订单号:{}", outTradeNo);
|
||||||
|
return buildFailResponse("定金订单记录不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 检查定金支付状态,避免重复处理
|
||||||
|
if (orderLog.getDepPaid() != null && orderLog.getDepPaid() == 2) {
|
||||||
|
logger.info("定金已支付,订单号:{}", outTradeNo);
|
||||||
|
return buildSuccessResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 更新定金支付状态
|
||||||
|
orderLog.setDepPaid(2); // 1:已支付
|
||||||
|
orderLog.setDepPayTime(System.currentTimeMillis()/1000);
|
||||||
|
// orderLog.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
int updateResult = orderLogService.updateOrderLog(orderLog);
|
||||||
|
if (updateResult <= 0) {
|
||||||
|
logger.error("更新定金支付状态失败,订单号:{}", outTradeNo);
|
||||||
|
return buildFailResponse("更新定金支付状态失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// // 7. 更新主订单状态
|
||||||
|
Order mainOrder = orderService.selectOrderByOrderId(orderLog.getOrderId());
|
||||||
|
// if (mainOrder != null) {
|
||||||
|
// // 更新订单状态,表示定金已支付
|
||||||
|
// JSONObject logJson = new JSONObject();
|
||||||
|
// logJson.put("type", 4);
|
||||||
|
// logJson.put("depositPaid", true);
|
||||||
|
// mainOrder.setLogJson(logJson.toJSONString());
|
||||||
|
// orderService.updateOrder(mainOrder);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 8. 处理定金支付成功后的业务逻辑
|
||||||
|
Users users = usersService.selectUsersById(mainOrder.getUid());
|
||||||
|
handleDepositPaymentSuccess(users,orderLog, paymentInfo);
|
||||||
|
|
||||||
|
logger.info("定金支付回调处理成功,订单号:{}", outTradeNo);
|
||||||
|
return buildSuccessResponse();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("定金支付回调处理异常:", e);
|
||||||
|
return buildFailResponse("定金支付回调处理异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单金额支付回调接口
|
||||||
|
*
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return XML格式响应给微信服务器
|
||||||
|
*
|
||||||
|
* 处理订单总金额的支付成功回调:
|
||||||
|
* 1. 验证支付签名
|
||||||
|
* 2. 更新服务订单支付状态
|
||||||
|
* 3. 更新订单支付时间和交易号
|
||||||
|
* 4. 处理订单支付完成后的业务逻辑
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/api/order/amount/pay/notify")
|
||||||
|
public String apiOrderAmountPayNotify(HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
logger.info("收到订单金额支付回调通知,开始处理...");
|
||||||
|
|
||||||
|
// 1. 使用WechatPayUtil处理支付回调
|
||||||
|
Map<String, Object> notifyResult = wechatPayUtil.handlePayNotify(request);
|
||||||
|
|
||||||
|
// 2. 检查处理结果
|
||||||
|
boolean success = (Boolean) notifyResult.get("success");
|
||||||
|
String message = (String) notifyResult.get("message");
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
logger.error("订单金额支付回调处理失败:{}", message);
|
||||||
|
return buildFailResponse("订单金额支付回调处理失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 获取支付信息
|
||||||
|
Map<String, Object> paymentInfo = (Map<String, Object>) notifyResult.get("paymentInfo");
|
||||||
|
String outTradeNo = (String) paymentInfo.get("outTradeNo");
|
||||||
|
String transactionId = (String) paymentInfo.get("transactionId");
|
||||||
|
String totalFee = (String) paymentInfo.get("totalFee");
|
||||||
|
|
||||||
|
// 4. 查询对应的服务订单
|
||||||
|
Order order = orderService.selectOrderByOrderId(outTradeNo);
|
||||||
|
|
||||||
|
if (order == null) {
|
||||||
|
logger.error("服务订单不存在,订单号:{}", outTradeNo);
|
||||||
|
return buildFailResponse("服务订单不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 检查订单支付状态,避免重复处理
|
||||||
|
if (order.getStatus() != null && order.getStatus() == 2L) {
|
||||||
|
logger.info("订单已支付,订单号:{}", outTradeNo);
|
||||||
|
return buildSuccessResponse();
|
||||||
|
}
|
||||||
|
//更新最新的一条日志信息
|
||||||
|
OrderLog orderLog = orderLogService.selectDataTheFirstNew(order.getId());
|
||||||
|
orderLog.setPayTime(System.currentTimeMillis()/1000);
|
||||||
|
orderLog.setPaid(2L);
|
||||||
|
orderLogService.updateOrderLog(orderLog);
|
||||||
|
|
||||||
|
// 6. 更新订单支付状态
|
||||||
|
order.setStatus(4L); // 2:已支付
|
||||||
|
order.setTransactionId(transactionId);
|
||||||
|
order.setPayTime(new Date());
|
||||||
|
//order.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
// 计算实际支付金额(分转换为元)
|
||||||
|
BigDecimal paidAmount = new BigDecimal(totalFee).divide(new BigDecimal(100));
|
||||||
|
order.setPayPrice(paidAmount);
|
||||||
|
|
||||||
|
int updateResult = orderService.updateOrder(order);
|
||||||
|
if (updateResult <= 0) {
|
||||||
|
logger.error("更新订单支付状态失败,订单号:{}", outTradeNo);
|
||||||
|
return buildFailResponse("更新订单支付状态失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. 处理订单支付成功后的业务逻辑
|
||||||
|
handleOrderAmountPaymentSuccess(order, paymentInfo);
|
||||||
|
calculateCommissionMoney(order.getOrderId(), order.getUid(),order.getWorkerId());
|
||||||
|
logger.info("订单金额支付回调处理成功,订单号:{}", outTradeNo);
|
||||||
|
return buildSuccessResponse();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("订单金额支付回调处理异常:", e);
|
||||||
|
return buildFailResponse("订单金额支付回调处理异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理商品支付成功后的业务逻辑
|
||||||
|
*/
|
||||||
|
private void handleGoodsPaymentSuccess(Users users,String outTradeNo, Map<String, Object> paymentInfo) {
|
||||||
|
try {
|
||||||
|
// 1. 记录支付成功日志
|
||||||
|
logger.info("商品订单支付成功,订单号:{},支付金额:{}",
|
||||||
|
outTradeNo, paymentInfo.get("totalFee"));
|
||||||
|
|
||||||
|
// 2. 处理积分奖励
|
||||||
|
handleIntegralReward(users, paymentInfo, "下单赠送积分");
|
||||||
|
|
||||||
|
// 3. 记录支付记录
|
||||||
|
recordPaymentLog(outTradeNo, paymentInfo,"支付订单金额");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("处理商品支付成功业务逻辑异常:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理上门费支付成功后的业务逻辑
|
||||||
|
*/
|
||||||
|
private void handleDoorFeePaymentSuccess(OrderLog orderLog, Map<String, Object> paymentInfo) {
|
||||||
|
try {
|
||||||
|
// 1. 记录支付成功日志
|
||||||
|
logger.info("上门费支付成功,订单号:{},支付金额:{}",
|
||||||
|
orderLog.getLogOrderId(), paymentInfo.get("totalFee"));
|
||||||
|
|
||||||
|
// 2. 获取主订单信息以获取用户信息
|
||||||
|
Order mainOrder = orderService.selectOrderByOrderId(orderLog.getOrderId());
|
||||||
|
if (mainOrder != null) {
|
||||||
|
// 3. 上门费支付不赠送积分(按照PHP逻辑)
|
||||||
|
logger.info("上门费支付不赠送积分");
|
||||||
|
|
||||||
|
recordPaymentLogones(orderLog.getOid(), orderLog.getLogOrderId(),mainOrder.getUid(),mainOrder.getUname(), paymentInfo, "支付上门费");
|
||||||
|
|
||||||
|
|
||||||
|
//// // 4. 记录支付记录
|
||||||
|
// recordPaymentLog(orderLog.getOid(), orderLog.getLogOrderId(),
|
||||||
|
// mainOrder.getUid(), mainOrder.getUname(), paymentInfo, "支付" + mainOrder.getProductName() + "上门费");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("处理上门费支付成功业务逻辑异常:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理定金支付成功后的业务逻辑
|
||||||
|
*/
|
||||||
|
private void handleDepositPaymentSuccess(Users users,OrderLog orderLog, Map<String, Object> paymentInfo) {
|
||||||
|
try {
|
||||||
|
// 1. 记录支付成功日志
|
||||||
|
logger.info("定金支付成功,订单号:{},支付金额:{}",
|
||||||
|
orderLog.getDepLogId(), paymentInfo.get("totalFee"));
|
||||||
|
|
||||||
|
// 2. 获取主订单信息以获取用户信息
|
||||||
|
Order mainOrder = orderService.selectOrderByOrderId(orderLog.getOrderId());
|
||||||
|
if (mainOrder != null) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 2. 处理积分奖励
|
||||||
|
handleIntegralReward(users, paymentInfo, "支付赠送积分");
|
||||||
|
// long oid,String orderid,long uid,String uname,Map<String, Object> paymentInfo, String description
|
||||||
|
// 3. 记录支付记录
|
||||||
|
recordPaymentLogones(orderLog.getOid(), orderLog.getOrderId(),users.getId(),users.getName(), paymentInfo,"支付定金金额");
|
||||||
|
|
||||||
|
// // 3. 处理积分奖励
|
||||||
|
// handleIntegralReward(orderLog.getDepLogId(), mainOrder.getUid(),
|
||||||
|
// mainOrder.getUname(), paymentInfo, "支付定金赠送积分");
|
||||||
|
|
||||||
|
// 4. 记录支付记录
|
||||||
|
// recordPaymentLog(orderLog.getOid(), orderLog.getDepLogId(),
|
||||||
|
// mainOrder.getUid(), mainOrder.getUname(), paymentInfo, "支付" + mainOrder.getProductName() + "服务定金");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("处理定金支付成功业务逻辑异常:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理订单金额支付成功后的业务逻辑
|
||||||
|
*/
|
||||||
|
private void handleOrderAmountPaymentSuccess(Order order, Map<String, Object> paymentInfo) {
|
||||||
|
try {
|
||||||
|
// 1. 记录支付成功日志
|
||||||
|
logger.info("订单金额支付成功,订单号:{},支付金额:{}",
|
||||||
|
order.getOrderId(), paymentInfo.get("totalFee"));
|
||||||
|
|
||||||
|
// 2. 更新订单状态为已完成
|
||||||
|
order.setStatus(4L); // 4:已结束
|
||||||
|
orderService.updateOrder(order);
|
||||||
|
|
||||||
|
// 3. 处理积分奖励(复杂逻辑:考虑定金支付情况)
|
||||||
|
handleOrderAmountIntegralReward(order, paymentInfo);
|
||||||
|
|
||||||
|
// 4. 记录支付记录
|
||||||
|
// recordPaymentLog(order.getId(), order.getOrderId(),
|
||||||
|
// order.getUid(), order.getUname(), paymentInfo, "支付" + order.getProductName() + "服务尾款");
|
||||||
|
recordPaymentLogones(order.getId(),order.getOrderId(),order.getUid(),order.getUname(), paymentInfo, "订单尾款支付");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("处理订单金额支付成功业务逻辑异常:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建成功响应XML
|
||||||
|
*/
|
||||||
|
private String buildSuccessResponse() {
|
||||||
|
return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建失败响应XML
|
||||||
|
*/
|
||||||
|
private String buildFailResponse(String message) {
|
||||||
|
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[" + message + "]]></return_msg></xml>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据订单号查找商品订单
|
||||||
|
*/
|
||||||
|
private GoodsOrder findGoodsOrderByOrderId(String orderId) {
|
||||||
|
GoodsOrder queryOrder = new GoodsOrder();
|
||||||
|
queryOrder.setOrderId(orderId);
|
||||||
|
List<GoodsOrder> orderList = goodsOrderService.selectGoodsOrderList(queryOrder);
|
||||||
|
return orderList.isEmpty() ? null : orderList.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据日志订单号查找订单日志
|
||||||
|
*/
|
||||||
|
private OrderLog findOrderLogByLogId(String logId) {
|
||||||
|
OrderLog queryLog = new OrderLog();
|
||||||
|
queryLog.setLogId(logId);
|
||||||
|
List<OrderLog> logList = orderLogService.selectOrderLogList(queryLog);
|
||||||
|
return logList.isEmpty() ? null : logList.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据定金订单号查找订单日志
|
||||||
|
*/
|
||||||
|
private OrderLog findOrderLogByDepLogId(String depLogId) {
|
||||||
|
OrderLog queryLog = new OrderLog();
|
||||||
|
queryLog.setDepLogId(depLogId);
|
||||||
|
List<OrderLog> logList = orderLogService.selectOrderLogList(queryLog);
|
||||||
|
return logList.isEmpty() ? null : logList.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理积分奖励
|
||||||
|
*
|
||||||
|
* @param paymentInfo 支付信息
|
||||||
|
* @param description 描述
|
||||||
|
*/
|
||||||
|
private void handleIntegralReward(Users users,Map<String, Object> paymentInfo, String description) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 查询系统配置 config_one
|
||||||
|
SiteConfig siteConfigQuery = new SiteConfig();
|
||||||
|
siteConfigQuery.setName("config_one");
|
||||||
|
List<SiteConfig> configList = siteConfigService.selectSiteConfigList(siteConfigQuery);
|
||||||
|
|
||||||
|
if (configList.isEmpty()) {
|
||||||
|
logger.warn("未找到config_one配置,跳过积分奖励");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SiteConfig config = configList.get(0);
|
||||||
|
String configValue = config.getValue();
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(configValue)) {
|
||||||
|
logger.warn("config_one配置值为空,跳过积分奖励");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 解析JSON获取integral值(积分配置)
|
||||||
|
Integer integral = null;
|
||||||
|
try {
|
||||||
|
JSONObject configJson = JSONObject.parseObject(configValue);
|
||||||
|
integral = configJson.getInteger("integral");
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("解析config_one配置失败:", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (integral == null || integral <= 0) {
|
||||||
|
logger.warn("integral配置无效,跳过积分奖励");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 计算积分
|
||||||
|
String totalFeeStr = (String) paymentInfo.get("totalFee");
|
||||||
|
if (StringUtils.isEmpty(totalFeeStr)) {
|
||||||
|
logger.warn("支付金额为空,跳过积分奖励");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支付金额单位为分,转换为元
|
||||||
|
BigDecimal payAmount = new BigDecimal(totalFeeStr).divide(new BigDecimal(100));
|
||||||
|
|
||||||
|
// 计算积分:实际支付金额除以integral,向下取整
|
||||||
|
long integralReward = payAmount.divide(new BigDecimal(integral), 0, BigDecimal.ROUND_DOWN).longValue();
|
||||||
|
|
||||||
|
// 4. 如果积分大于1,则添加积分记录
|
||||||
|
if (integralReward >= 1) {
|
||||||
|
IntegralLog integralLog = new IntegralLog();
|
||||||
|
integralLog.setOrderId(GenerateCustomCode.generCreateOrder("ESTB"));
|
||||||
|
integralLog.setTitle("支付获得积分");
|
||||||
|
integralLog.setMark(description + "获得积分奖励");
|
||||||
|
integralLog.setUid(users.getId());
|
||||||
|
integralLog.setUname(users.getName());
|
||||||
|
integralLog.setType(1L); // 1:增加
|
||||||
|
integralLog.setNum(integralReward);
|
||||||
|
integralLog.setCreatedAt(new Date());
|
||||||
|
integralLog.setUpdatedAt(new Date());
|
||||||
|
|
||||||
|
int result = integralLogService.insertIntegralLog(integralLog);
|
||||||
|
if (result > 0) {
|
||||||
|
logger.info("用户{}通过{}获得{}积分", users.getName(), description, integralReward);
|
||||||
|
} else {
|
||||||
|
logger.error("添加积分记录失败,订单号:{}", integralLog.getOrderId());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.info("订单{}积分奖励小于1,不予奖励","");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("处理积分奖励异常,订单号:{},异常信息:", "", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 记录支付记录单条
|
||||||
|
*
|
||||||
|
* @param paymentInfo 支付信息
|
||||||
|
* @param description 描述
|
||||||
|
*/
|
||||||
|
private void recordPaymentLogones(long oid,String orderid,long uid,String uname,Map<String, Object> paymentInfo, String description) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
String totalFeeStr = (String) paymentInfo.get("totalFee");
|
||||||
|
if (StringUtils.isEmpty(totalFeeStr)) {
|
||||||
|
logger.warn("支付金额为空,跳过支付记录");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PayMoneyLog payMoneyLog = new PayMoneyLog();
|
||||||
|
payMoneyLog.setOid(oid);
|
||||||
|
payMoneyLog.setOrderId(orderid);
|
||||||
|
payMoneyLog.setUid(uid);
|
||||||
|
payMoneyLog.setUname(uname);
|
||||||
|
payMoneyLog.setPrice(new BigDecimal(totalFeeStr));
|
||||||
|
payMoneyLog.setMark(description);
|
||||||
|
payMoneyLog.setPayTime(new Date());
|
||||||
|
payMoneyLogService.insertPayMoneyLog(payMoneyLog);
|
||||||
|
logger.info("用户{}的{}支付记录已保存,金额:{}元", uname, description, totalFeeStr);
|
||||||
|
|
||||||
|
// 支付金额单位为分,转换为元
|
||||||
|
// BigDecimal payAmount = new BigDecimal(totalFeeStr).divide(new BigDecimal(100));
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("记录支付记录异常,订单号:{},异常信息:", oid, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 记录支付记录多条
|
||||||
|
*
|
||||||
|
* @param paymentInfo 支付信息
|
||||||
|
* @param description 描述
|
||||||
|
*/
|
||||||
|
private void recordPaymentLog(String outTradeNo,Map<String, Object> paymentInfo, String description) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
String totalFeeStr = (String) paymentInfo.get("totalFee");
|
||||||
|
if (StringUtils.isEmpty(totalFeeStr)) {
|
||||||
|
logger.warn("支付金额为空,跳过支付记录");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 查询对应的商品订单
|
||||||
|
GoodsOrder goodsOrder = new GoodsOrder();
|
||||||
|
goodsOrder.setMainOrderId(outTradeNo);
|
||||||
|
List<GoodsOrder> goodsOrderslist = goodsOrderService.selectGoodsOrderList(goodsOrder);
|
||||||
|
if (!goodsOrderslist.isEmpty()) {
|
||||||
|
for (GoodsOrder goodsOrderdata : goodsOrderslist){
|
||||||
|
PayMoneyLog payMoneyLog = new PayMoneyLog();
|
||||||
|
payMoneyLog.setOid(goodsOrderdata.getId());
|
||||||
|
payMoneyLog.setOrderId(goodsOrderdata.getOrderId());
|
||||||
|
payMoneyLog.setUid(goodsOrderdata.getUid());
|
||||||
|
payMoneyLog.setUname(goodsOrderdata.getUname());
|
||||||
|
payMoneyLog.setPrice(goodsOrderdata.getTotalPrice());
|
||||||
|
payMoneyLog.setMark(description);
|
||||||
|
payMoneyLog.setPayTime(new Date());
|
||||||
|
payMoneyLogService.insertPayMoneyLog(payMoneyLog);
|
||||||
|
logger.info("用户{}的{}支付记录已保存,金额:{}元", goodsOrderdata.getUname(), description, goodsOrderdata.getTotalPrice());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支付金额单位为分,转换为元
|
||||||
|
// BigDecimal payAmount = new BigDecimal(totalFeeStr).divide(new BigDecimal(100));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("记录支付记录异常,订单号:{},异常信息:", outTradeNo, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理订单总金额的积分奖励(考虑定金情况)
|
||||||
|
*
|
||||||
|
* @param order 订单信息
|
||||||
|
* @param paymentInfo 支付信息
|
||||||
|
*/
|
||||||
|
private void handleOrderAmountIntegralReward(Order order, Map<String, Object> paymentInfo) {
|
||||||
|
try {
|
||||||
|
// 1. 查询系统配置 config_one
|
||||||
|
SiteConfig siteConfigQuery = new SiteConfig();
|
||||||
|
siteConfigQuery.setName("config_one");
|
||||||
|
List<SiteConfig> configList = siteConfigService.selectSiteConfigList(siteConfigQuery);
|
||||||
|
|
||||||
|
if (configList.isEmpty()) {
|
||||||
|
logger.warn("未找到config_one配置,跳过积分奖励");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SiteConfig config = configList.get(0);
|
||||||
|
String configValue = config.getValue();
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(configValue)) {
|
||||||
|
logger.warn("config_one配置值为空,跳过积分奖励");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 解析JSON获取integral值
|
||||||
|
Integer integral = null;
|
||||||
|
try {
|
||||||
|
JSONObject configJson = JSONObject.parseObject(configValue);
|
||||||
|
integral = configJson.getInteger("integral");
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("解析config_one配置失败:", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (integral == null || integral <= 0) {
|
||||||
|
logger.warn("integral配置无效,跳过积分奖励");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 查询是否有定金记录
|
||||||
|
OrderLog orderLogQuery = new OrderLog();
|
||||||
|
orderLogQuery.setOrderId(order.getOrderId());
|
||||||
|
List<OrderLog> orderLogList = orderLogService.selectOrderLogList(orderLogQuery);
|
||||||
|
|
||||||
|
BigDecimal totalPrice = BigDecimal.ZERO;
|
||||||
|
OrderLog depositLog = null;
|
||||||
|
|
||||||
|
// 查找定金记录
|
||||||
|
for (OrderLog log : orderLogList) {
|
||||||
|
if (log.getDeposit() != null && log.getDeposit().compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
depositLog = log;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 根据定金情况计算积分基数
|
||||||
|
if (depositLog != null && depositLog.getDepPaid() != null) {
|
||||||
|
if (depositLog.getDepPaid() == 1) {
|
||||||
|
// 定金未支付/没有定金,直接支付总金额
|
||||||
|
totalPrice = depositLog.getPrice();
|
||||||
|
} else if (depositLog.getDepPaid() == 2) {
|
||||||
|
// 定金已支付,计算尾款
|
||||||
|
totalPrice = depositLog.getPrice().subtract(depositLog.getDeposit());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 没有定金,使用订单总金额
|
||||||
|
totalPrice = order.getPayPrice();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 计算积分
|
||||||
|
long integralReward = totalPrice.divide(new BigDecimal(integral), 0, BigDecimal.ROUND_DOWN).longValue();
|
||||||
|
|
||||||
|
// 6. 如果积分大于0,则添加积分记录
|
||||||
|
if (integralReward > 0) {
|
||||||
|
IntegralLog integralLog = new IntegralLog();
|
||||||
|
integralLog.setOrderId(order.getOrderId());
|
||||||
|
integralLog.setTitle("支付服务费用赠送积分");
|
||||||
|
integralLog.setMark(order.getProductName() + "服务费用");
|
||||||
|
integralLog.setUid(order.getUid());
|
||||||
|
integralLog.setUname(order.getUname());
|
||||||
|
integralLog.setType(1L); // 1:增加
|
||||||
|
integralLog.setNum(integralReward);
|
||||||
|
integralLog.setCreatedAt(new Date());
|
||||||
|
integralLog.setUpdatedAt(new Date());
|
||||||
|
|
||||||
|
int result = integralLogService.insertIntegralLog(integralLog);
|
||||||
|
if (result > 0) {
|
||||||
|
logger.info("用户{}通过服务费用支付获得{}积分", order.getUname(), integralReward);
|
||||||
|
} else {
|
||||||
|
logger.error("添加积分记录失败,订单号:{}", order.getOrderId());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.info("订单{}服务费用积分奖励为0,不予奖励", order.getOrderId());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("处理订单总金额积分奖励异常,订单号:{},异常信息:", order.getOrderId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分佣
|
||||||
|
*
|
||||||
|
|
||||||
|
* @return 商品标题
|
||||||
|
*/
|
||||||
|
public Map<String, Object> calculateCommissionMoney(String orderId,long oid, Long workerId
|
||||||
|
) {
|
||||||
|
// 结果
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
BigDecimal totalPrice = BigDecimal.ZERO;
|
||||||
|
BigDecimal margin = BigDecimal.ZERO;
|
||||||
|
BigDecimal reduction = BigDecimal.ZERO;
|
||||||
|
BigDecimal servicePrice = BigDecimal.ZERO;
|
||||||
|
BigDecimal doorPrice = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
// 1. 查询订单日志
|
||||||
|
OrderLog orderLogQuery = new OrderLog();
|
||||||
|
orderLogQuery.setOrderId(orderId);
|
||||||
|
List<OrderLog> orderLogList = orderLogService.selectOrderLogList(orderLogQuery);
|
||||||
|
//List<OrderLog> orderLogList = orderLogService.selectOrderLogListByWorker(orderId, workerId);
|
||||||
|
|
||||||
|
// 2. 查询订单和商品
|
||||||
|
Order order = orderService.selectOrderById(oid);
|
||||||
|
ServiceGoods product = null;
|
||||||
|
if (order != null && order.getProductId() != null) {
|
||||||
|
product = serviceGoodsService.selectServiceGoodsById(order.getProductId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 查询师傅信息
|
||||||
|
Users worker = usersService.selectUsersById(workerId);
|
||||||
|
|
||||||
|
// 4. 计算佣金、上门费、优惠金额
|
||||||
|
for (OrderLog log : orderLogList) {
|
||||||
|
if (log.getType() != null && log.getType().intValue() == 5) {
|
||||||
|
// type=5 评估报价
|
||||||
|
WorkerLevel levelInfo = workerLevelService.selectWorkerLevelByLevel(Long.valueOf(worker.getLevel()));
|
||||||
|
BigDecimal cr = (levelInfo != null && levelInfo.getCr() != null) ? new BigDecimal(levelInfo.getCr()).divide(new BigDecimal(100)) : BigDecimal.ZERO;
|
||||||
|
totalPrice = totalPrice.add(log.getWorkerCost().multiply(cr).setScale(2, BigDecimal.ROUND_HALF_UP));
|
||||||
|
servicePrice = log.getWorkerCost().add(log.getReductionPrice() != null ? log.getReductionPrice() : BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
if (log.getType() != null && log.getType().intValue() == 2) {
|
||||||
|
// type=2 上门费
|
||||||
|
totalPrice = totalPrice.add(log.getWorkerCost());
|
||||||
|
doorPrice = log.getWorkerCost();
|
||||||
|
}
|
||||||
|
if (log.getReductionPrice() != null) {
|
||||||
|
reduction = reduction.add(log.getReductionPrice());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 判断是否需要扣除质保金
|
||||||
|
if (product != null && product.getMargin() != null && worker != null && worker.getMargin() != null
|
||||||
|
&& product.getMargin().compareTo(worker.getMargin()) > 0) {
|
||||||
|
// 查系统配置
|
||||||
|
SiteConfig config = siteConfigService.selectSiteConfigByName("config_one");
|
||||||
|
BigDecimal marginPercent = BigDecimal.ZERO;
|
||||||
|
if (config != null && config.getValue() != null) {
|
||||||
|
try {
|
||||||
|
JSONObject json = JSONObject.parseObject(config.getValue());
|
||||||
|
if (json.containsKey("margin")) {
|
||||||
|
marginPercent = new BigDecimal(json.getString("margin")).divide(new BigDecimal(100));
|
||||||
|
}
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
margin = totalPrice.multiply(marginPercent).setScale(2, BigDecimal.ROUND_HALF_UP);
|
||||||
|
// 超过质保金,则扣少点
|
||||||
|
if (worker.getMargin().add(margin).compareTo(product.getMargin()) > 0) {
|
||||||
|
margin = product.getMargin().subtract(worker.getMargin());
|
||||||
|
}
|
||||||
|
// 插入质保金明细
|
||||||
|
WorkerMarginLog marginLog = new WorkerMarginLog();
|
||||||
|
marginLog.setOid(order.getId());
|
||||||
|
marginLog.setUid(workerId);
|
||||||
|
marginLog.setOrderId(order != null ? order.getOrderId() : null);
|
||||||
|
marginLog.setPrice(margin);
|
||||||
|
// marginLog.setCreatedAt(new Date());
|
||||||
|
// marginLog.setUpdatedAt(new Date());
|
||||||
|
workerMarginLogService.insertWorkerMarginLog(marginLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 返回
|
||||||
|
result.put("commission", totalPrice);
|
||||||
|
result.put("margin", margin);
|
||||||
|
result.put("reduction", reduction);
|
||||||
|
result.put("service_price", servicePrice);
|
||||||
|
result.put("door_price", doorPrice);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取商品标题
|
||||||
|
*
|
||||||
|
* @param goodsOrder 商品订单
|
||||||
|
* @return 商品标题
|
||||||
|
*/
|
||||||
|
private String getGoodsTitle(GoodsOrder goodsOrder) {
|
||||||
|
try {
|
||||||
|
// 这里应该查询商品信息,简化处理返回商品名称或默认值
|
||||||
|
if (goodsOrder.getProductName() != null) {
|
||||||
|
return goodsOrder.getProductName();
|
||||||
|
}
|
||||||
|
return "商品";
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("获取商品标题异常:", e);
|
||||||
|
return "商品";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,8 +2,11 @@ package com.ruoyi.system.ControllerUtil;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
import com.ruoyi.system.domain.*;
|
import com.ruoyi.system.domain.*;
|
||||||
|
import com.ruoyi.system.service.IGoodsCartService;
|
||||||
import com.ruoyi.system.service.IServiceGoodsService;
|
import com.ruoyi.system.service.IServiceGoodsService;
|
||||||
import com.ruoyi.system.service.IUserAddressService;
|
import com.ruoyi.system.service.IUserAddressService;
|
||||||
import com.ruoyi.system.service.IUsersService;
|
import com.ruoyi.system.service.IUsersService;
|
||||||
|
|
@ -2573,11 +2576,11 @@ public class AppletControllerUtil {
|
||||||
* @param goodsCartService 购物车服务
|
* @param goodsCartService 购物车服务
|
||||||
* @return 添加结果
|
* @return 添加结果
|
||||||
*/
|
*/
|
||||||
public static com.ruoyi.common.core.domain.AjaxResult addNewCartItem(
|
public static AjaxResult addNewCartItem(
|
||||||
com.ruoyi.system.domain.Users user,
|
Users user,
|
||||||
com.ruoyi.system.domain.ServiceGoods serviceGoods,
|
ServiceGoods serviceGoods,
|
||||||
String sku,
|
String sku,
|
||||||
com.ruoyi.system.service.IGoodsCartService goodsCartService) {
|
IGoodsCartService goodsCartService) {
|
||||||
try {
|
try {
|
||||||
// 构建购物车记录
|
// 构建购物车记录
|
||||||
com.ruoyi.system.domain.GoodsCart newCartItem = new com.ruoyi.system.domain.GoodsCart();
|
com.ruoyi.system.domain.GoodsCart newCartItem = new com.ruoyi.system.domain.GoodsCart();
|
||||||
|
|
@ -2618,7 +2621,7 @@ public class AppletControllerUtil {
|
||||||
if (serviceGoods != null) {
|
if (serviceGoods != null) {
|
||||||
goodInfo.put("id", serviceGoods.getId());
|
goodInfo.put("id", serviceGoods.getId());
|
||||||
goodInfo.put("title", serviceGoods.getTitle());
|
goodInfo.put("title", serviceGoods.getTitle());
|
||||||
goodInfo.put("price", serviceGoods.getPriceZn());
|
goodInfo.put("price", serviceGoods.getPrice());
|
||||||
goodInfo.put("price_zn", serviceGoods.getPriceZn());
|
goodInfo.put("price_zn", serviceGoods.getPriceZn());
|
||||||
goodInfo.put("icon", buildImageUrl(serviceGoods.getIcon()));
|
goodInfo.put("icon", buildImageUrl(serviceGoods.getIcon()));
|
||||||
goodInfo.put("stock", serviceGoods.getStock());
|
goodInfo.put("stock", serviceGoods.getStock());
|
||||||
|
|
@ -2996,7 +2999,7 @@ public class AppletControllerUtil {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 尝试解析为JSON对象
|
// 尝试解析为JSON对象
|
||||||
com.alibaba.fastjson2.JSONObject skuJson = com.alibaba.fastjson2.JSONObject.parseObject(sku);
|
JSONObject skuJson = JSONObject.parseObject(sku);
|
||||||
return skuJson.toJavaObject(Map.class);
|
return skuJson.toJavaObject(Map.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// 解析失败,返回null
|
// 解析失败,返回null
|
||||||
|
|
@ -3004,6 +3007,76 @@ public class AppletControllerUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串转换为JSON对象(通用工具方法)
|
||||||
|
*
|
||||||
|
* 支持将JSON字符串转换为Map<String, Object>对象
|
||||||
|
* 如果字符串为空或解析失败,返回null
|
||||||
|
*
|
||||||
|
* @param jsonString JSON字符串
|
||||||
|
* @return JSON对象,解析失败返回null
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> parseStringToJson(String jsonString) {
|
||||||
|
if (jsonString == null || jsonString.trim().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 预处理字符串,移除可能的特殊字符
|
||||||
|
String cleanJsonString = cleanJsonString(jsonString);
|
||||||
|
|
||||||
|
// 尝试解析为JSON对象
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(cleanJsonString);
|
||||||
|
return jsonObject.toJavaObject(Map.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 解析失败,打印详细错误信息并返回null
|
||||||
|
System.err.println("JSON解析失败,原始字符串: [" + jsonString + "], 错误: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理JSON字符串,移除可能导致解析失败的字符
|
||||||
|
*
|
||||||
|
* @param jsonString 原始JSON字符串
|
||||||
|
* @return 清理后的JSON字符串
|
||||||
|
*/
|
||||||
|
private static String cleanJsonString(String jsonString) {
|
||||||
|
if (jsonString == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除BOM字符
|
||||||
|
if (jsonString.startsWith("\uFEFF")) {
|
||||||
|
jsonString = jsonString.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除首尾空白字符
|
||||||
|
jsonString = jsonString.trim();
|
||||||
|
|
||||||
|
// 如果不是以{或[开头,可能不是有效的JSON
|
||||||
|
if (!jsonString.startsWith("{") && !jsonString.startsWith("[")) {
|
||||||
|
return "{}"; // 返回空对象
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串转换为JSON对象(带默认值)
|
||||||
|
*
|
||||||
|
* 支持将JSON字符串转换为Map<String, Object>对象
|
||||||
|
* 如果字符串为空或解析失败,返回提供的默认值
|
||||||
|
*
|
||||||
|
* @param jsonString JSON字符串
|
||||||
|
* @param defaultValue 解析失败时的默认值
|
||||||
|
* @return JSON对象,解析失败返回默认值
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> parseStringToJson(String jsonString, Map<String, Object> defaultValue) {
|
||||||
|
Map<String, Object> result = parseStringToJson(jsonString);
|
||||||
|
return result != null ? result : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化日期为字符串
|
* 格式化日期为字符串
|
||||||
*
|
*
|
||||||
|
|
@ -3017,4 +3090,28 @@ public class AppletControllerUtil {
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
return sdf.format(date);
|
return sdf.format(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理SKU参数,确保以JSON字符串格式存储
|
||||||
|
* @param skuParam 前端传递的SKU参数
|
||||||
|
* @return JSON字符串格式的SKU
|
||||||
|
*/
|
||||||
|
public static String processSkuParam(Object skuParam) {
|
||||||
|
if (skuParam == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skuParam instanceof Map) {
|
||||||
|
// 如果是Map对象,转换为JSON字符串
|
||||||
|
try {
|
||||||
|
return com.alibaba.fastjson2.JSON.toJSONString(skuParam);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("SKU转换JSON失败:" + e.getMessage());
|
||||||
|
return skuParam.toString();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果是字符串,直接使用
|
||||||
|
return skuParam.toString().trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,7 @@ public class OrderBindWorkerUtil {
|
||||||
// 8. 绑定中间号,直到成功
|
// 8. 绑定中间号,直到成功
|
||||||
for (MobileMiddle middle : mobileMiddleList) {
|
for (MobileMiddle middle : mobileMiddleList) {
|
||||||
VoiceResponseResult bindResult = YunXinPhoneUtilAPI.httpsPrivacyBindAxb(middle.getPhone(), userPhone, workerPhone);
|
VoiceResponseResult bindResult = YunXinPhoneUtilAPI.httpsPrivacyBindAxb(middle.getPhone(), userPhone, workerPhone);
|
||||||
|
System.out.println(middle.getPhone()+"__________"+userPhone+"__________"+workerPhone);
|
||||||
if ("000000".equals(bindResult.getResult())) {
|
if ("000000".equals(bindResult.getResult())) {
|
||||||
// 绑定成功,更新订单
|
// 绑定成功,更新订单
|
||||||
order.setMiddlePhone(middle.getPhone());
|
order.setMiddlePhone(middle.getPhone());
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.system.domain.AppleDoMain.TemplateData;
|
import com.ruoyi.system.domain.AppleDoMain.TemplateData;
|
||||||
import com.ruoyi.system.domain.AppleDoMain.WxMssVo;
|
import com.ruoyi.system.domain.AppleDoMain.WxMssVo;
|
||||||
|
import com.ruoyi.system.domain.GoodsOrder;
|
||||||
import com.ruoyi.system.domain.Order;
|
import com.ruoyi.system.domain.Order;
|
||||||
import com.ruoyi.system.domain.ServiceGoods;
|
import com.ruoyi.system.domain.ServiceGoods;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
@ -291,5 +292,52 @@ public class WXsendMsgUtil {
|
||||||
wxMssVo.setData(m);
|
wxMssVo.setData(m);
|
||||||
return PublicPush(wxMssVo);
|
return PublicPush(wxMssVo);
|
||||||
}
|
}
|
||||||
|
//用户支付上门费后向师傅进行推送
|
||||||
|
public static String sendUserPayDoorMoneyForWorker(String openid, Order order, ServiceGoods serviceGoods) throws Exception {
|
||||||
|
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
//拼接推送的模版
|
||||||
|
WxMssVo wxMssVo = new WxMssVo();
|
||||||
|
wxMssVo.setTouser(openid);//用户的openid(要发送给那个用户,通常这里应该动态传进来的)
|
||||||
|
wxMssVo.setTemplate_id(ORDER_STATUS);//订阅消息模板id
|
||||||
|
wxMssVo.setPage("/pages/serveSF/home/details?id="+order.getId());
|
||||||
|
// String mark = order.getMark();
|
||||||
|
// if (StringUtils.isEmpty( mark)){
|
||||||
|
// mark="暂无备注";
|
||||||
|
// }
|
||||||
|
Map<String, TemplateData> m = new HashMap<>(3);
|
||||||
|
m.put("thing15", new TemplateData(serviceGoods.getTitle()));
|
||||||
|
m.put("character_string5", new TemplateData(order.getOrderId()));
|
||||||
|
m.put("date3", new TemplateData(AppletControllerUtil.timeStamp2Date(order)));
|
||||||
|
m.put("thing1", new TemplateData(order.getAddress()));
|
||||||
|
m.put("thing9", new TemplateData("用户已支付上门费"));
|
||||||
|
|
||||||
|
System.out.println("师傅设置上门费的时候的推送:" + m.toString());
|
||||||
|
wxMssVo.setData(m);
|
||||||
|
return PublicPush(wxMssVo);
|
||||||
|
}
|
||||||
|
|
||||||
|
//客户支付成功的消息推送
|
||||||
|
public static String sendUserForMoneySuccess(String openid, GoodsOrder order, ServiceGoods serviceGoods) throws Exception {
|
||||||
|
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
//拼接推送的模版
|
||||||
|
WxMssVo wxMssVo = new WxMssVo();
|
||||||
|
wxMssVo.setTouser(openid);//用户的openid(要发送给那个用户,通常这里应该动态传进来的)
|
||||||
|
wxMssVo.setTemplate_id(PAY_GOODS);//订阅消息模板id
|
||||||
|
wxMssVo.setPage("/pages/mine/shopOrder/index");
|
||||||
|
String mark = order.getMark();
|
||||||
|
if (StringUtils.isEmpty( mark)){
|
||||||
|
mark="暂无备注";
|
||||||
|
}
|
||||||
|
Map<String, TemplateData> m = new HashMap<>(3);
|
||||||
|
m.put("thing11", new TemplateData(serviceGoods.getTitle()));
|
||||||
|
m.put("character_string3", new TemplateData(order.getOrderId()));
|
||||||
|
m.put("amount27",new TemplateData(String.valueOf(order.getTotalPrice())));
|
||||||
|
m.put("thing1", new TemplateData(order.getAddress()));
|
||||||
|
m.put("thing9", new TemplateData("师傅已经已经接单"));
|
||||||
|
|
||||||
|
System.out.println("师傅设置上门费的时候的推送:" + m.toString());
|
||||||
|
wxMssVo.setData(m);
|
||||||
|
return PublicPush(wxMssVo);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -78,9 +78,24 @@ public class WechatPayUtil {
|
||||||
private static final String FAIL_CODE = "FAIL";
|
private static final String FAIL_CODE = "FAIL";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RestTemplate实例
|
* RestTemplate实例(配置UTF-8编码)
|
||||||
*/
|
*/
|
||||||
private static final RestTemplate restTemplate = new RestTemplate();
|
private static final RestTemplate restTemplate = createRestTemplate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建配置了UTF-8编码的RestTemplate实例
|
||||||
|
*/
|
||||||
|
private static RestTemplate createRestTemplate() {
|
||||||
|
RestTemplate template = new RestTemplate();
|
||||||
|
// 设置字符编码为UTF-8,解决中文乱码问题
|
||||||
|
template.getMessageConverters().forEach(converter -> {
|
||||||
|
if (converter instanceof org.springframework.http.converter.StringHttpMessageConverter) {
|
||||||
|
((org.springframework.http.converter.StringHttpMessageConverter) converter)
|
||||||
|
.setDefaultCharset(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -113,11 +128,13 @@ public class WechatPayUtil {
|
||||||
if (notifyUrl == null || notifyUrl.trim().isEmpty()) {
|
if (notifyUrl == null || notifyUrl.trim().isEmpty()) {
|
||||||
return failResult("回调通知地址不能为空");
|
return failResult("回调通知地址不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 构建参数
|
// 2. 构建参数
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put("appid", wechatAppId);
|
params.put("appid", wechatAppId);
|
||||||
params.put("mch_id", wechatMchId);
|
params.put("mch_id", wechatMchId);
|
||||||
params.put("nonce_str", generateNonceStr());
|
String nonceStr = generateNonceStr();
|
||||||
|
params.put("nonce_str", nonceStr);
|
||||||
params.put("body", body);
|
params.put("body", body);
|
||||||
params.put("out_trade_no", orderNo);
|
params.put("out_trade_no", orderNo);
|
||||||
params.put("total_fee", String.valueOf(totalFee)); // 单位:分
|
params.put("total_fee", String.valueOf(totalFee)); // 单位:分
|
||||||
|
|
@ -128,27 +145,52 @@ public class WechatPayUtil {
|
||||||
if (attach != null && !attach.trim().isEmpty()) {
|
if (attach != null && !attach.trim().isEmpty()) {
|
||||||
params.put("attach", attach);
|
params.put("attach", attach);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 生成签名
|
// 3. 生成签名
|
||||||
String sign = generateSign(params, wechatApiKey);
|
String sign = generateSign(params, wechatApiKey);
|
||||||
params.put("sign", sign);
|
params.put("sign", sign);
|
||||||
|
|
||||||
// 4. 发送请求
|
// 4. 发送请求
|
||||||
String xmlRequest = mapToXml(params);
|
String xmlRequest = mapToXml(params);
|
||||||
ResponseEntity<String> response = restTemplate.postForEntity(WECHAT_PAY_URL, xmlRequest, String.class);
|
|
||||||
|
// 设置请求头,指定字符编码为UTF-8
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.set("Content-Type", "application/xml;charset=UTF-8");
|
||||||
|
headers.set("Accept", "application/xml;charset=UTF-8");
|
||||||
|
headers.set("User-Agent", "Mozilla/5.0");
|
||||||
|
|
||||||
|
HttpEntity<String> requestEntity = new HttpEntity<>(xmlRequest, headers);
|
||||||
|
ResponseEntity<String> response = restTemplate.exchange(WECHAT_PAY_URL, HttpMethod.POST, requestEntity, String.class);
|
||||||
|
|
||||||
|
// 5. 解析响应
|
||||||
Map<String, String> responseMap = xmlToMap(response.getBody());
|
Map<String, String> responseMap = xmlToMap(response.getBody());
|
||||||
// 5. 处理响应
|
|
||||||
if (SUCCESS_CODE.equals(responseMap.get("return_code")) && SUCCESS_CODE.equals(responseMap.get("result_code"))) {
|
// 6. 处理响应
|
||||||
// 6. 构建小程序端调起支付参数
|
String returnCode = responseMap.get("return_code");
|
||||||
Map<String, Object> payParams = buildMiniProgramPayParams(responseMap.get("prepay_id"));
|
String resultCode = responseMap.get("result_code");
|
||||||
|
|
||||||
|
if (SUCCESS_CODE.equals(returnCode) && SUCCESS_CODE.equals(resultCode)) {
|
||||||
|
String prepayId = responseMap.get("prepay_id");
|
||||||
|
|
||||||
|
// 7. 构建小程序端调起支付参数
|
||||||
|
Map<String, Object> payParams = buildMiniProgramPayParams(prepayId);
|
||||||
|
|
||||||
result.put("success", true);
|
result.put("success", true);
|
||||||
result.put("payParams", payParams);
|
result.put("payParams", payParams);
|
||||||
result.put("prepayId", responseMap.get("prepay_id"));
|
result.put("prepayId", prepayId);
|
||||||
result.put("message", "统一下单成功");
|
result.put("message", "统一下单成功");
|
||||||
} else {
|
} else {
|
||||||
result = failResult("统一下单失败:" + (responseMap.get("err_code_des") != null ? responseMap.get("err_code_des") : responseMap.get("return_msg")));
|
String errorCode = responseMap.get("err_code");
|
||||||
|
String errorCodeDes = responseMap.get("err_code_des");
|
||||||
|
String returnMsg = responseMap.get("return_msg");
|
||||||
|
|
||||||
|
String errorMessage = "统一下单失败:" + (errorCodeDes != null ? errorCodeDes : returnMsg);
|
||||||
|
result = failResult(errorMessage);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
result = failResult("统一下单异常:" + e.getMessage());
|
result = failResult("统一下单异常:" + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,7 +219,15 @@ public class WechatPayUtil {
|
||||||
String sign = generateSign(params, wechatApiKey);
|
String sign = generateSign(params, wechatApiKey);
|
||||||
params.put("sign", sign);
|
params.put("sign", sign);
|
||||||
String xmlRequest = mapToXml(params);
|
String xmlRequest = mapToXml(params);
|
||||||
ResponseEntity<String> response = restTemplate.postForEntity(WECHAT_QUERY_URL, xmlRequest, String.class);
|
|
||||||
|
// 设置请求头,指定字符编码为UTF-8解决中文乱码
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.set("Content-Type", "application/xml;charset=UTF-8");
|
||||||
|
headers.set("Accept", "application/xml;charset=UTF-8");
|
||||||
|
headers.set("User-Agent", "Mozilla/5.0");
|
||||||
|
|
||||||
|
HttpEntity<String> requestEntity = new HttpEntity<>(xmlRequest, headers);
|
||||||
|
ResponseEntity<String> response = restTemplate.exchange(WECHAT_QUERY_URL, HttpMethod.POST, requestEntity, String.class);
|
||||||
Map<String, String> responseMap = xmlToMap(response.getBody());
|
Map<String, String> responseMap = xmlToMap(response.getBody());
|
||||||
if (SUCCESS_CODE.equals(responseMap.get("return_code")) && SUCCESS_CODE.equals(responseMap.get("result_code"))) {
|
if (SUCCESS_CODE.equals(responseMap.get("return_code")) && SUCCESS_CODE.equals(responseMap.get("result_code"))) {
|
||||||
Map<String, Object> orderInfo = new HashMap<>();
|
Map<String, Object> orderInfo = new HashMap<>();
|
||||||
|
|
@ -365,6 +415,58 @@ public class WechatPayUtil {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量订单统一下单并返回前端支付参数(用于多商品批量下单场景)
|
||||||
|
* @param openid 用户openid
|
||||||
|
* @param mainOrderId 主订单号
|
||||||
|
* @param totalAmount 总金额(单位:元)
|
||||||
|
* @param orderCount 订单数量
|
||||||
|
* @return Map,包含支付参数和下单结果
|
||||||
|
*/
|
||||||
|
public Map<String, Object> createBatchOrderAndPay(String openid, String mainOrderId, BigDecimal totalAmount, int orderCount,String notifyUrl) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
try {
|
||||||
|
if (openid == null || openid.trim().isEmpty()) {
|
||||||
|
return failResult("用户openid为空,无法发起支付");
|
||||||
|
}
|
||||||
|
if (mainOrderId == null || mainOrderId.trim().isEmpty()) {
|
||||||
|
return failResult("主订单号不能为空");
|
||||||
|
}
|
||||||
|
if (totalAmount == null || totalAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
return failResult("支付金额必须大于0");
|
||||||
|
}
|
||||||
|
// 金额转换为分
|
||||||
|
int totalFeeInCents = totalAmount.multiply(new BigDecimal(100)).intValue();
|
||||||
|
String body = "批量订单-" + orderCount + "个商品";
|
||||||
|
//String notifyUrl =notifyUrl;
|
||||||
|
//String notifyUrl = "https://4d983d7f.r3.cpolar.top/api/goods/pay/notify";
|
||||||
|
String attach = "batch_order:" + mainOrderId;
|
||||||
|
|
||||||
|
Map<String, Object> payResult = unifiedOrder(
|
||||||
|
openid,
|
||||||
|
mainOrderId,
|
||||||
|
totalFeeInCents,
|
||||||
|
body,
|
||||||
|
notifyUrl,
|
||||||
|
attach
|
||||||
|
);
|
||||||
|
if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) {
|
||||||
|
Map<String, Object> payParams = (Map<String, Object>) payResult.get("payParams");
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("prepayId", payResult.get("prepayId"));
|
||||||
|
if (payParams != null) {
|
||||||
|
result.putAll(payParams);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败";
|
||||||
|
return failResult(errorMsg);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return failResult("批量订单微信支付异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// ===================== 工具方法和签名相关 =====================
|
// ===================== 工具方法和签名相关 =====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -378,6 +480,7 @@ public class WechatPayUtil {
|
||||||
String nonceStr = generateNonceStr();
|
String nonceStr = generateNonceStr();
|
||||||
String packageStr = "prepay_id=" + prepayId;
|
String packageStr = "prepay_id=" + prepayId;
|
||||||
String signType = "MD5";
|
String signType = "MD5";
|
||||||
|
|
||||||
// 构建签名参数
|
// 构建签名参数
|
||||||
Map<String, String> signParams = new HashMap<>();
|
Map<String, String> signParams = new HashMap<>();
|
||||||
signParams.put("appId", wechatAppId);
|
signParams.put("appId", wechatAppId);
|
||||||
|
|
@ -385,12 +488,15 @@ public class WechatPayUtil {
|
||||||
signParams.put("nonceStr", nonceStr);
|
signParams.put("nonceStr", nonceStr);
|
||||||
signParams.put("package", packageStr);
|
signParams.put("package", packageStr);
|
||||||
signParams.put("signType", signType);
|
signParams.put("signType", signType);
|
||||||
|
|
||||||
String paySign = generateSign(signParams, wechatApiKey);
|
String paySign = generateSign(signParams, wechatApiKey);
|
||||||
|
|
||||||
payParams.put("timeStamp", timeStamp);
|
payParams.put("timeStamp", timeStamp);
|
||||||
payParams.put("nonceStr", nonceStr);
|
payParams.put("nonceStr", nonceStr);
|
||||||
payParams.put("package", packageStr);
|
payParams.put("package", packageStr);
|
||||||
payParams.put("signType", signType);
|
payParams.put("signType", signType);
|
||||||
payParams.put("paySign", paySign);
|
payParams.put("paySign", paySign);
|
||||||
|
|
||||||
return payParams;
|
return payParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -410,12 +516,15 @@ public class WechatPayUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stringBuilder.append("key=").append(key);
|
stringBuilder.append("key=").append(key);
|
||||||
|
|
||||||
|
String signString = stringBuilder.toString();
|
||||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||||
byte[] digest = md5.digest(stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
|
byte[] digest = md5.digest(signString.getBytes(StandardCharsets.UTF_8));
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
for (byte b : digest) {
|
for (byte b : digest) {
|
||||||
result.append(String.format("%02X", b));
|
result.append(String.format("%02X", b));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.toString();
|
return result.toString();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("生成签名失败", e);
|
throw new RuntimeException("生成签名失败", e);
|
||||||
|
|
@ -446,6 +555,8 @@ public class WechatPayUtil {
|
||||||
*/
|
*/
|
||||||
private String mapToXml(Map<String, String> params) {
|
private String mapToXml(Map<String, String> params) {
|
||||||
StringBuilder xml = new StringBuilder();
|
StringBuilder xml = new StringBuilder();
|
||||||
|
// 添加XML声明,指定UTF-8编码
|
||||||
|
xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||||
xml.append("<xml>");
|
xml.append("<xml>");
|
||||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||||
xml.append("<").append(entry.getKey()).append("><![CDATA[")
|
xml.append("<").append(entry.getKey()).append("><![CDATA[")
|
||||||
|
|
@ -463,21 +574,32 @@ public class WechatPayUtil {
|
||||||
private Map<String, String> xmlToMap(String xml) {
|
private Map<String, String> xmlToMap(String xml) {
|
||||||
Map<String, String> map = new HashMap<>();
|
Map<String, String> map = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
xml = xml.replaceAll("<xml>", "").replaceAll("</xml>", "");
|
// 移除XML声明和根标签
|
||||||
String[] elements = xml.split("</\\w+>");
|
String processedXml = xml.replaceAll("<\\?xml[^>]*\\?>", "")
|
||||||
|
.replaceAll("<xml>", "")
|
||||||
|
.replaceAll("</xml>", "");
|
||||||
|
|
||||||
|
String[] elements = processedXml.split("</\\w+>");
|
||||||
|
|
||||||
for (String element : elements) {
|
for (String element : elements) {
|
||||||
if (element.trim().isEmpty()) continue;
|
if (element.trim().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int startTag = element.indexOf("<");
|
int startTag = element.indexOf("<");
|
||||||
int endTag = element.indexOf(">");
|
int endTag = element.indexOf(">");
|
||||||
if (startTag >= 0 && endTag > startTag) {
|
if (startTag >= 0 && endTag > startTag) {
|
||||||
String key = element.substring(startTag + 1, endTag);
|
String key = element.substring(startTag + 1, endTag);
|
||||||
String value = element.substring(endTag + 1);
|
String value = element.substring(endTag + 1);
|
||||||
|
|
||||||
if (value.startsWith("<![CDATA[") && value.endsWith("]]>")) {
|
if (value.startsWith("<![CDATA[") && value.endsWith("]]>")) {
|
||||||
value = value.substring(9, value.length() - 3);
|
value = value.substring(9, value.length() - 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
map.put(key, value);
|
map.put(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("XML解析失败", e);
|
throw new RuntimeException("XML解析失败", e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,8 +143,8 @@ public class Order extends BaseEntity
|
||||||
private Long firstWorkerId;
|
private Long firstWorkerId;
|
||||||
|
|
||||||
/** 接单时间 */
|
/** 接单时间 */
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
@Excel(name = "接单时间", width = 30, dateFormat = "yyyy-MM-dd")
|
@Excel(name = "接单时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||||
private Date receiveTime;
|
private Date receiveTime;
|
||||||
|
|
||||||
/** 1:已评价 0:未评价 */
|
/** 1:已评价 0:未评价 */
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ public interface SiteConfigMapper
|
||||||
*/
|
*/
|
||||||
public SiteConfig selectSiteConfigById(Integer id);
|
public SiteConfig selectSiteConfigById(Integer id);
|
||||||
|
|
||||||
|
public SiteConfig selectSiteConfigByName(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询系统配置列表
|
* 查询系统配置列表
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ public interface WorkerLevelMapper
|
||||||
*/
|
*/
|
||||||
public WorkerLevel selectWorkerLevelById(Long id);
|
public WorkerLevel selectWorkerLevelById(Long id);
|
||||||
|
|
||||||
|
public WorkerLevel selectWorkerLevelByLevel(Long level);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询师傅等级配置列表
|
* 查询师傅等级配置列表
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ public interface ISiteConfigService
|
||||||
* @return 系统配置
|
* @return 系统配置
|
||||||
*/
|
*/
|
||||||
public SiteConfig selectSiteConfigById(Integer id);
|
public SiteConfig selectSiteConfigById(Integer id);
|
||||||
|
public SiteConfig selectSiteConfigByName(String name);
|
||||||
/**
|
/**
|
||||||
* 查询系统配置列表
|
* 查询系统配置列表
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ public interface IWorkerLevelService
|
||||||
* @return 师傅等级配置
|
* @return 师傅等级配置
|
||||||
*/
|
*/
|
||||||
public WorkerLevel selectWorkerLevelById(Long id);
|
public WorkerLevel selectWorkerLevelById(Long id);
|
||||||
|
public WorkerLevel selectWorkerLevelByLevel(Long level);
|
||||||
/**
|
/**
|
||||||
* 查询师傅等级配置列表
|
* 查询师傅等级配置列表
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,11 @@ public class SiteConfigServiceImpl implements ISiteConfigService
|
||||||
return siteConfigMapper.selectSiteConfigById(id);
|
return siteConfigMapper.selectSiteConfigById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public SiteConfig selectSiteConfigByName(String name) {
|
||||||
|
return siteConfigMapper.selectSiteConfigByName(name);
|
||||||
|
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 查询系统配置列表
|
* 查询系统配置列表
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,11 @@ public class WorkerLevelServiceImpl implements IWorkerLevelService
|
||||||
@Autowired
|
@Autowired
|
||||||
private WorkerLevelMapper workerLevelMapper;
|
private WorkerLevelMapper workerLevelMapper;
|
||||||
|
|
||||||
|
|
||||||
|
public WorkerLevel selectWorkerLevelByLevel(Long level) {
|
||||||
|
|
||||||
|
return workerLevelMapper.selectWorkerLevelByLevel(level);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 查询师傅等级配置
|
* 查询师傅等级配置
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<select id="selectDataTheFirstNew" parameterType="Long" resultMap="OrderLogResult">
|
<select id="selectDataTheFirstNew" parameterType="Long" resultMap="OrderLogResult">
|
||||||
<include refid="selectOrderLogVo"/>
|
<include refid="selectOrderLogVo"/>
|
||||||
where oid = #{oid}
|
where oid = #{oid}
|
||||||
ORDER BY created_at DESC LIMIT 1;
|
ORDER BY updated_at DESC LIMIT 1;
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<include refid="selectSiteConfigVo"/>
|
<include refid="selectSiteConfigVo"/>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</select>
|
</select>
|
||||||
|
<select id="selectSiteConfigByName" parameterType="String" resultMap="SiteConfigResult">
|
||||||
|
<include refid="selectSiteConfigVo"/>
|
||||||
|
where name = #{name} limit 1
|
||||||
|
</select>
|
||||||
|
|
||||||
<insert id="insertSiteConfig" parameterType="SiteConfig" useGeneratedKeys="true" keyProperty="id">
|
<insert id="insertSiteConfig" parameterType="SiteConfig" useGeneratedKeys="true" keyProperty="id">
|
||||||
insert into site_config
|
insert into site_config
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<include refid="selectWorkerLevelVo"/>
|
<include refid="selectWorkerLevelVo"/>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</select>
|
</select>
|
||||||
|
<select id="selectWorkerLevelByLevel" parameterType="Long" resultMap="WorkerLevelResult">
|
||||||
|
<include refid="selectWorkerLevelVo"/>
|
||||||
|
where level = #{level} limit 1
|
||||||
|
</select>
|
||||||
|
|
||||||
<insert id="insertWorkerLevel" parameterType="WorkerLevel" useGeneratedKeys="true" keyProperty="id">
|
<insert id="insertWorkerLevel" parameterType="WorkerLevel" useGeneratedKeys="true" keyProperty="id">
|
||||||
insert into worker_level
|
insert into worker_level
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue