Compare commits
No commits in common. "0a8cfe078bb6b055bb870259c58fd607d111dff3" and "4d768ea54e6d7eaa2fe8e8ec505d025a19596266" have entirely different histories.
0a8cfe078b
...
4d768ea54e
|
|
@ -12,12 +12,7 @@ ruoyi:
|
||||||
addressEnabled: false
|
addressEnabled: false
|
||||||
# 验证码类型 math 数字计算 char 字符验证
|
# 验证码类型 math 数字计算 char 字符验证
|
||||||
captchaType: math
|
captchaType: math
|
||||||
wechat:
|
|
||||||
pay:
|
|
||||||
app-id: wx73d0202b3c8a6d68
|
|
||||||
mch-id: 1672571923
|
|
||||||
api-key: sssssssssssssssssssssssssssssssS
|
|
||||||
cert-path: wechat/apiclient_cert.p12
|
|
||||||
# 七牛云配置
|
# 七牛云配置
|
||||||
qiniu:
|
qiniu:
|
||||||
# 是否启用七牛云上传 true-启用七牛云 false-使用本地上传
|
# 是否启用七牛云上传 true-启用七牛云 false-使用本地上传
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,25 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIELjCCAxagAwIBAgIUSSFh2nX1a5drX17lBR7WCwwoi7kwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
|
||||||
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
|
||||||
Q0EwHhcNMjQwNDAzMDEzNTM5WhcNMjkwNDAyMDEzNTM5WjCBhzETMBEGA1UEAwwK
|
|
||||||
MTY3MjU3MTkyMzEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTMwMQYDVQQL
|
|
||||||
DCropb/lronljY7lupzkurrlrrboo4XppbDlt6XnqIvmnInpmZDlhazlj7gxCzAJ
|
|
||||||
BgNVBAYTAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQAD
|
|
||||||
ggEPADCCAQoCggEBANvnZX1T6o0xR1yOkQy17upOeNsGGE8pn5istcvc5/UTtcg8
|
|
||||||
5aH39oAZ0wXruE41wR9bEM6c3FB27w5FcnQonUYgBZvU/jHlIrbogZK1UhvoQMqX
|
|
||||||
SnKbiQx2oqLxiFXzZjWBz5g8E9Mss4xErRT8XmuE5alWnIc5ljGGYAUNt9qi5bpc
|
|
||||||
wawSqoBYR1nJM1WtGwHWNUTCi2XYL2H7olPnJw/vv0dpQC3kNF/0bNALzM9ulyf3
|
|
||||||
sESbFu6wOJhYqZRseiUQHyXRFGQOQ665rho7YJ4j6y51kfbUAIUp2U4yMf8009pQ
|
|
||||||
du9XYId9TxjRt/tNxwkRVEIVukAgv90mZwALvyMCAwEAAaOBuTCBtjAJBgNVHRME
|
|
||||||
AjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDov
|
|
||||||
L2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUw
|
|
||||||
REJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJF
|
|
||||||
MTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IB
|
|
||||||
AQASunlG7V6cH05d3z4pthRixzU4Rn5xSW8d09gshq1XA6BBCu6I7glqiEKotrai
|
|
||||||
oLWrwHDKddCRSRuV3KKC0//fAwS/8j0pkFDI/Aad5TKS361uA38HaHda0bJQnKoB
|
|
||||||
m1WinL+GsfsLr+SL17ZGZAJqPBeP/Vz/c41cUX2gMAXjkem7DGbtytQiVkyXxocL
|
|
||||||
/qhlF3Hy3eiMI186ki5ctKkp6WISCRKHWjc1du8ri/T6fvnNv/Rls/GAtpxVBm7V
|
|
||||||
uFem8oe5heDDe4/RlqPv7sY2Oybkq/9iUfFwYvUNv/yQfb7TiGBQkasAt+PVgI5g
|
|
||||||
djd8S7m1zDTFWl4LeNBIYaS2
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDb52V9U+qNMUdc
|
|
||||||
jpEMte7qTnjbBhhPKZ+YrLXL3Of1E7XIPOWh9/aAGdMF67hONcEfWxDOnNxQdu8O
|
|
||||||
RXJ0KJ1GIAWb1P4x5SK26IGStVIb6EDKl0pym4kMdqKi8YhV82Y1gc+YPBPTLLOM
|
|
||||||
RK0U/F5rhOWpVpyHOZYxhmAFDbfaouW6XMGsEqqAWEdZyTNVrRsB1jVEwotl2C9h
|
|
||||||
+6JT5ycP779HaUAt5DRf9GzQC8zPbpcn97BEmxbusDiYWKmUbHolEB8l0RRkDkOu
|
|
||||||
ua4aO2CeI+sudZH21ACFKdlOMjH/NNPaUHbvV2CHfU8Y0bf7TccJEVRCFbpAIL/d
|
|
||||||
JmcAC78jAgMBAAECggEAQBF82jTWw2g2GFtZG1DuWMmgIH/4GShRXVQEa27jDd4+
|
|
||||||
Oiaz6Kqr4MqlVrZErlSu/Ym0rd25up/MKmZFYF5s4/90YuB9ZuARayT2i13UnFjg
|
|
||||||
d6X4hMeX+E+gNsUUKaaOgsxdRUdLp10Aur9Phiu4/q5rkxiu5h77CVbTJuXGSSZe
|
|
||||||
VEtlUfXsyl5nLqnViqOam0cbD3vM0tKnAtHHootIcz3Bn5a9QGfBA7JKHqWpQIZp
|
|
||||||
zkd0XcfbZdOLwk+I+HAenFQYK8mOpg999iNVOFOI0egsj9tES9cxkDMezUrYjr/W
|
|
||||||
+I5KkggwigF0tjgvqcklqNdGIIlLak+jBDfWA2vwgQKBgQD3Sx6C/YafiEv30Phw
|
|
||||||
K+kmWMT5X+bTJBF8uie62Rlzz6PQs9p7K7iHcWLPtAO93JR6O25/tWIeYWGVyWOF
|
|
||||||
PyJLNoch+3aDw2e7K9gn14xMb9/rlAMEtKsM1g+W78TJfzGaeH4gGTkzBQYxaoV1
|
|
||||||
Zi9LXGEXurpgIRgCYA+2mxIeAwKBgQDjpWmcAXEA6NQBfUWCxlI3xAv5R0G4Adtf
|
|
||||||
ziKnJZnTxTbe7OZBMugAwxWtuNjJESg4RAPwUlmkaWO+pN4yu6dZsfphsgNUs6kG
|
|
||||||
1x2LXB72E0bVo0xyMANkeYtgh6Vz9JIfm54CNHEbpf6udTKFAL4QmoW43v68FKSK
|
|
||||||
6wR6j3ogYQKBgFBwqP4nBdGC/mMgIJAsWGzW10ve/DCWPPH7g8ztra/UTQ8oUdta
|
|
||||||
/21fXqr9fXIW/F0+U9VK5R3Iw3t7xNmlDby1ggN1zrlRqL5jpq5fGQ4MHiR9QvYW
|
|
||||||
5sUIJI4OdE6vBy2eIDjEu6xy5+7PHZZwpNW4uQSFAvceDLdJFBNsIdqNAoGAPRmK
|
|
||||||
jPq+D9ZuALBU1dLRAnK2HAQKGY82CDLVjjNDZFmMbqz66Aj3yCyURvpUBTN7rg5j
|
|
||||||
WD9iHATFZsftc4R2WFays0IKLtPBzDo0jdD95mIqIvEfdY55eqA8zn3Z5JOCHMWx
|
|
||||||
1TmqGhelkcGW+6fFW8N9nK8NhAGuYDLQEu0rhEECgYAdsN/WQcG+IcHv/90AajQi
|
|
||||||
a4gnybw1tuC7PlBDTtrSYbd3YuEZ3ocLTKINvADqh9/rgTaOHs6n4wS8av02XWw+
|
|
||||||
AOUF2N2Qvb1nk5FDV87wBjeWDWR1wy8o5njBU45+mnMdelubpKHemkrqkMd0sd7B
|
|
||||||
Pcd6BtcwZjvzB4UisErFqA==
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIEFDCCAvygAwIBAgIUSfMroWK5C2gDN/vbxA/Igoszko0wDQYJKoZIhvcNAQEL
|
|
||||||
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
|
||||||
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
|
||||||
Q0EwHhcNMjQwNDAzMDEzNTM4WhcNMjkwNDAyMDEzNTM4WjBuMRgwFgYDVQQDDA9U
|
|
||||||
ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl
|
|
||||||
bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGEwJDTjERMA8GA1UEBwwIU2hlblpo
|
|
||||||
ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCu+HNPatzFYBeTBflC
|
|
||||||
fsbpLAz/5RgxMriwVxUsy7i2IdlcCX60ZM9W0a4ZpaR0o61njR0s67dTGDW17Kd5
|
|
||||||
bQ8rJBParLSVh4sBn7kRcJFyBzcnjGWECDR5kUpuvV2MW7HzlogGZxWqD55/5ZHz
|
|
||||||
n4QPi35axPRv/ZCx9KDz2iK86FBad9+CZeYBJ0KvDZDDDq4Y3N9b4e0LNNw5Pq4l
|
|
||||||
IpuHU1Q8LPytf84UhRdyLh7ofgQmulIwISeqPy+IXB01brIYwh76affri90w8UyS
|
|
||||||
cDraOC8cgjgWsMc5ZJiRjiPmmWTa2jFbUeh2mHoC4ik3CBGxHNOXtg7fEbYtxVCn
|
|
||||||
qdQLAgMBAAGjgbkwgbYwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwgZsGA1UdHwSB
|
|
||||||
kzCBkDCBjaCBiqCBh4aBhGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMv
|
|
||||||
aXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4
|
|
||||||
RUJEMiZzZz1IQUNDNDcxQjY1NDIyRTEyQjI3QTlEMzNBODdBRDFDREY1OTI2RTE0
|
|
||||||
MDM3MTANBgkqhkiG9w0BAQsFAAOCAQEAB1Dw7Gr+bmGtvL++lNY7KEeIywSTuHz2
|
|
||||||
264LhBxFEX5fKaKdq/cy7Kw6n9c7Jbcu1aIbNb08eZ0h1veJGp8oJzDxpIE8m/g2
|
|
||||||
AQHRfkOJidHEed+UvLb6dKD20nh/vVfdOKoV1NEvQZw6n3YuRjH+YzaZAeKA6T2E
|
|
||||||
CxBF7apLC/FQ06hBZruZDr8GgaxzubkAZu8CHdbCDk4K3OuEOJjJT9fxgbiVhih5
|
|
||||||
wtlupVbpnGKpXm+xqeti90EKUGh/rFv/3pz+mD4n5xioYcQrvOxNUYEGEAcNSEmK
|
|
||||||
mEc2D13rJf7pBRm+nhjVee3qckW5cdQfj1hxgB2CQOY05Xt5Zba8KA==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
|
|
@ -1895,9 +1895,9 @@ public class AppletController extends BaseController {
|
||||||
if (!(Boolean) userValidation.get("valid")) {
|
if (!(Boolean) userValidation.get("valid")) {
|
||||||
return error("用户未登录或token无效");
|
return error("用户未登录或token无效");
|
||||||
}
|
}
|
||||||
WechatPayUtil wechatPayUtil = new WechatPayUtil();
|
|
||||||
// 2. 调用微信支付统一下单
|
// 2. 调用微信支付统一下单
|
||||||
Map<String, Object> payResult = wechatPayUtil.unifiedOrder((String) params.get("openid"), (String) params.get("orderNo"), (int) params.get("totalFee"), (String) params.get("body"), (String) params.get("notifyUrl"), (String) params.get("attach"));
|
Map<String, Object> payResult = WechatPayUtil.unifiedOrder(params);
|
||||||
|
|
||||||
// 3. 返回结果
|
// 3. 返回结果
|
||||||
boolean success = (Boolean) payResult.get("success");
|
boolean success = (Boolean) payResult.get("success");
|
||||||
|
|
@ -1928,9 +1928,9 @@ public class AppletController extends BaseController {
|
||||||
if (!(Boolean) userValidation.get("valid")) {
|
if (!(Boolean) userValidation.get("valid")) {
|
||||||
return error("用户未登录或token无效");
|
return error("用户未登录或token无效");
|
||||||
}
|
}
|
||||||
WechatPayUtil wechatPayUtil = new WechatPayUtil();
|
|
||||||
// 2. 查询订单状态
|
// 2. 查询订单状态
|
||||||
Map<String, Object> queryResult = wechatPayUtil.queryOrder(orderNo, null);
|
Map<String, Object> queryResult = WechatPayUtil.queryOrder(orderNo, null);
|
||||||
|
|
||||||
// 3. 返回结果
|
// 3. 返回结果
|
||||||
boolean success = (Boolean) queryResult.get("success");
|
boolean success = (Boolean) queryResult.get("success");
|
||||||
|
|
@ -1972,9 +1972,9 @@ public class AppletController extends BaseController {
|
||||||
if (!(Boolean) userValidation.get("valid")) {
|
if (!(Boolean) userValidation.get("valid")) {
|
||||||
return error("用户未登录或token无效");
|
return error("用户未登录或token无效");
|
||||||
}
|
}
|
||||||
WechatPayUtil wechatPayUtil = new WechatPayUtil();
|
|
||||||
// 2. 创建代付订单
|
// 2. 创建代付订单
|
||||||
Map<String, Object> payForResult = wechatPayUtil.unifiedOrder(params.get("payerOpenid").toString(), params.get("orderNo").toString(),Integer.valueOf(params.get("totalFee").toString()), params.get("body").toString(), params.get("notifyUrl").toString(), params.get("remark").toString());
|
Map<String, Object> payForResult = WechatPayUtil.createPayForOrder(params);
|
||||||
|
|
||||||
// 3. 返回结果
|
// 3. 返回结果
|
||||||
boolean success = (Boolean) payForResult.get("success");
|
boolean success = (Boolean) payForResult.get("success");
|
||||||
|
|
@ -2001,9 +2001,8 @@ public class AppletController extends BaseController {
|
||||||
@PostMapping(value = "/api/pay/notify")
|
@PostMapping(value = "/api/pay/notify")
|
||||||
public String handlePayNotify(HttpServletRequest request) {
|
public String handlePayNotify(HttpServletRequest request) {
|
||||||
try {
|
try {
|
||||||
WechatPayUtil wechatPayUtil = new WechatPayUtil();
|
|
||||||
// 1. 处理支付回调
|
// 1. 处理支付回调
|
||||||
Map<String, Object> notifyResult = wechatPayUtil.handlePayNotify(request);
|
Map<String, Object> notifyResult = WechatPayUtil.handlePayNotify(request);
|
||||||
|
|
||||||
// 2. 获取支付信息
|
// 2. 获取支付信息
|
||||||
boolean success = (Boolean) notifyResult.get("success");
|
boolean success = (Boolean) notifyResult.get("success");
|
||||||
|
|
@ -2053,9 +2052,9 @@ public class AppletController extends BaseController {
|
||||||
if (!(Boolean) userValidation.get("valid")) {
|
if (!(Boolean) userValidation.get("valid")) {
|
||||||
return error("用户未登录或token无效");
|
return error("用户未登录或token无效");
|
||||||
}
|
}
|
||||||
WechatPayUtil wechatPayUtil = new WechatPayUtil();
|
|
||||||
// 2. 申请退款
|
// 2. 申请退款
|
||||||
Map<String, Object> refundResult = wechatPayUtil.refund(params);
|
Map<String, Object> refundResult = WechatPayUtil.refund(params);
|
||||||
|
|
||||||
// 3. 返回结果
|
// 3. 返回结果
|
||||||
boolean success = (Boolean) refundResult.get("success");
|
boolean success = (Boolean) refundResult.get("success");
|
||||||
|
|
@ -2094,9 +2093,9 @@ public class AppletController extends BaseController {
|
||||||
if (!(Boolean) userValidation.get("valid")) {
|
if (!(Boolean) userValidation.get("valid")) {
|
||||||
return error("用户未登录或token无效");
|
return error("用户未登录或token无效");
|
||||||
}
|
}
|
||||||
WechatPayUtil wechatPayUtil = new WechatPayUtil();
|
|
||||||
// 2. 企业付款
|
// 2. 企业付款
|
||||||
Map<String, Object> transferResult = wechatPayUtil.transferToUser(params);
|
Map<String, Object> transferResult = WechatPayUtil.transferToUser(params);
|
||||||
|
|
||||||
// 3. 返回结果
|
// 3. 返回结果
|
||||||
boolean success = (Boolean) transferResult.get("success");
|
boolean success = (Boolean) transferResult.get("success");
|
||||||
|
|
@ -3071,36 +3070,6 @@ public class AppletController extends BaseController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 小程序下单时用户订阅消息推送接口(前端不传值,后端返回固定结构)
|
|
||||||
* @return 订阅消息推送ID分类结果
|
|
||||||
*/
|
|
||||||
@GetMapping("/api/public/massge/notice")
|
|
||||||
public Map<String, Object> subscribeMessageNotice() {
|
|
||||||
Map<String, Object> data = new HashMap<>();
|
|
||||||
data.put("make_success", Arrays.asList(
|
|
||||||
"YKnuTCAD-oEEhNGoI3LUVkAqNsykOMTcyrf71S9vev8",
|
|
||||||
"5lA-snytEPl25fBS7rf6rQi8Y0i5HOSdG0JMVdUnMcU"
|
|
||||||
));
|
|
||||||
data.put("pay_success", Arrays.asList(
|
|
||||||
"pv3cba-wPoinUbBZSskp0KpDNnJwrHqS0rvGBfDNQ1M"
|
|
||||||
));
|
|
||||||
data.put("integral", Arrays.asList(
|
|
||||||
"pv3cba-wPoinUbBZSskp0KpDNnJwrHqS0rvGBfDNQ1M"
|
|
||||||
));
|
|
||||||
data.put("worker", Arrays.asList(
|
|
||||||
"5lA-snytEPl25fBS7rf6rQi8Y0i5HOSdG0JMVdUnMcU"
|
|
||||||
));
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
result.put("code", 200);
|
|
||||||
result.put("msg", "OK");
|
|
||||||
result.put("data", data);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 积分商品兑换接口
|
* 积分商品兑换接口
|
||||||
*
|
*
|
||||||
|
|
@ -4385,7 +4354,7 @@ public class AppletController extends BaseController {
|
||||||
Long productId = Long.valueOf(orderParams.get("product_id").toString());
|
Long productId = Long.valueOf(orderParams.get("product_id").toString());
|
||||||
Long addressId = Long.valueOf(orderParams.get("address_id").toString());
|
Long addressId = Long.valueOf(orderParams.get("address_id").toString());
|
||||||
String makeTime = orderParams.get("make_time").toString();
|
String makeTime = orderParams.get("make_time").toString();
|
||||||
|
Long num = Long.valueOf(orderParams.get("num").toString());
|
||||||
String sku = orderParams.get("sku") != null ? orderParams.get("sku").toString() : "";
|
String sku = orderParams.get("sku") != null ? orderParams.get("sku").toString() : "";
|
||||||
|
|
||||||
// 5. 查询商品信息
|
// 5. 查询商品信息
|
||||||
|
|
@ -4399,9 +4368,7 @@ public class AppletController extends BaseController {
|
||||||
if (userAddress == null) {
|
if (userAddress == null) {
|
||||||
return error("地址不存在");
|
return error("地址不存在");
|
||||||
}
|
}
|
||||||
//判断如果是商品就添加商品订单,如果是服务就添加服务订单
|
|
||||||
if(serviceGoods.getType()==2){
|
if(serviceGoods.getType()==2){
|
||||||
Long num = Long.valueOf(orderParams.get("num").toString());
|
|
||||||
GoodsOrder goodsOrder = new GoodsOrder();
|
GoodsOrder goodsOrder = new GoodsOrder();
|
||||||
goodsOrder.setType(2);
|
goodsOrder.setType(2);
|
||||||
goodsOrder.setMainOrderId("WX" + System.currentTimeMillis());
|
goodsOrder.setMainOrderId("WX" + System.currentTimeMillis());
|
||||||
|
|
@ -4436,7 +4403,6 @@ public class AppletController extends BaseController {
|
||||||
order.setAddressId(addressId);
|
order.setAddressId(addressId);
|
||||||
order.setSku(sku);
|
order.setSku(sku);
|
||||||
|
|
||||||
|
|
||||||
// 解析预约时间
|
// 解析预约时间
|
||||||
String[] makeTimeArr = makeTime.split(" ");
|
String[] makeTimeArr = makeTime.split(" ");
|
||||||
if (makeTimeArr.length != 2) {
|
if (makeTimeArr.length != 2) {
|
||||||
|
|
@ -4452,7 +4418,7 @@ public class AppletController extends BaseController {
|
||||||
return error("预约时间格式错误");
|
return error("预约时间格式错误");
|
||||||
}
|
}
|
||||||
|
|
||||||
order.setNum(1l); // 默认数量为1
|
order.setNum(num); // 默认数量为1
|
||||||
order.setTotalPrice(serviceGoods.getPrice()); // 总价等于商品价格
|
order.setTotalPrice(serviceGoods.getPrice()); // 总价等于商品价格
|
||||||
order.setGoodPrice(serviceGoods.getPrice()); // 商品金额
|
order.setGoodPrice(serviceGoods.getPrice()); // 商品金额
|
||||||
order.setServicePrice(BigDecimal.ZERO); // 服务金额默认为0
|
order.setServicePrice(BigDecimal.ZERO); // 服务金额默认为0
|
||||||
|
|
@ -4462,7 +4428,6 @@ public class AppletController extends BaseController {
|
||||||
order.setIsAccept(0); // 0:未接单
|
order.setIsAccept(0); // 0:未接单
|
||||||
order.setIsComment(0); // 0:未评价
|
order.setIsComment(0); // 0:未评价
|
||||||
order.setIsPause(1); // 0:未暂停
|
order.setIsPause(1); // 0:未暂停
|
||||||
order.setDeduction(new BigDecimal(0));
|
|
||||||
// 8. 生成订单号
|
// 8. 生成订单号
|
||||||
String orderId = generateOrderId();
|
String orderId = generateOrderId();
|
||||||
order.setOrderId(orderId);
|
order.setOrderId(orderId);
|
||||||
|
|
@ -4480,46 +4445,6 @@ 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());
|
|
||||||
String wxsendmsg=WXsendMsgUtil.sendMsgForUserInfo(user.getOpenid(), orderNewData, serviceGoods);
|
|
||||||
//第二步系统派单
|
|
||||||
Users worker = AppletControllerUtil.creatWorkerForOrder(orderNewData);
|
|
||||||
//第三步向师傅发送订阅消息
|
|
||||||
if(worker!=null){
|
|
||||||
//确定派单之后,更新订单状态为已派单,并添加订单日志记录
|
|
||||||
//修改订单状态为派单开始-------------------------------------------
|
|
||||||
orderNewData.setWorkerId(worker.getId());
|
|
||||||
orderNewData.setStatus(2l);
|
|
||||||
orderNewData.setIsPause(1);
|
|
||||||
orderNewData.setReceiveTime(new Date());
|
|
||||||
orderNewData.setReceiveType(3l);
|
|
||||||
orderNewData.setLogStatus(9);
|
|
||||||
JSONObject jSONObject =new JSONObject();
|
|
||||||
jSONObject.put("type",9);
|
|
||||||
orderNewData.setLogJson(jSONObject.toJSONString());
|
|
||||||
orderService.updateOrder(orderNewData);
|
|
||||||
OrderLog orderLognew = new OrderLog();
|
|
||||||
orderLognew.setOid(orderNewData.getId());
|
|
||||||
orderLognew.setOrderId(orderNewData.getOrderId());
|
|
||||||
orderLognew.setTitle("平台派单");
|
|
||||||
orderLognew.setType(new BigDecimal(1.1));
|
|
||||||
JSONObject jSONObject1 =new JSONObject();
|
|
||||||
jSONObject1.put("name","师傅收到派单信息");
|
|
||||||
orderLognew.setContent(jSONObject1.toJSONString());
|
|
||||||
orderLognew.setWorkerId(worker.getId());
|
|
||||||
orderLognew.setWorkerLogId(worker.getId());
|
|
||||||
orderLogService.insertOrderLog(orderLognew);
|
|
||||||
//修改订单状态为派单结束-------------------------------------------
|
|
||||||
//给师傅发送微信订阅消息进行通知需要他进行接单
|
|
||||||
WXsendMsgUtil.sendMsgForWorkerInfo(worker.getOpenid(), orderNewData, serviceGoods);
|
|
||||||
//第四步给师傅进行电话通知
|
|
||||||
YunXinPhoneUtilAPI.httpsAxbTransfer(worker.getPhone(), "404168");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
System.out.println("wxsendmsg:" + wxsendmsg);
|
|
||||||
return success("预约成功");
|
return success("预约成功");
|
||||||
} else {
|
} else {
|
||||||
return error("预约失败,请稍后重试");
|
return error("预约失败,请稍后重试");
|
||||||
|
|
@ -4652,32 +4577,9 @@ public class AppletController extends BaseController {
|
||||||
order.setReceiveTime(new Date());
|
order.setReceiveTime(new Date());
|
||||||
order.setIsAccept(1); // 1:已接单
|
order.setIsAccept(1); // 1:已接单
|
||||||
order.setJsonStatus(2); // 服务进度:2=接单
|
order.setJsonStatus(2); // 服务进度:2=接单
|
||||||
order.setStatus(2l);
|
|
||||||
order.setLogStatus(9);
|
|
||||||
JSONObject json=new JSONObject();
|
|
||||||
json.put("type",1);
|
|
||||||
order.setLogJson(json.toJSONString());
|
|
||||||
orderService.updateOrder(order);
|
|
||||||
|
|
||||||
// 5. 写入日志
|
// 5. 写入日志
|
||||||
OrderLog orderLog=new OrderLog();
|
OrderUtil orderUtil = new OrderUtil();
|
||||||
orderLog.setOid(order.getId());
|
orderUtil.SaveOrderLog(order);
|
||||||
orderLog.setOrderId(order.getOrderId());
|
|
||||||
orderLog.setTitle("师傅接单");
|
|
||||||
orderLog.setType(new BigDecimal(2.0));
|
|
||||||
JSONObject js=new JSONObject();
|
|
||||||
js.put("type", 1);
|
|
||||||
orderLog.setContent(js.toJSONString());
|
|
||||||
orderLog.setWorkerId(order.getWorkerId());
|
|
||||||
orderLog.setWorkerLogId(order.getWorkerId());
|
|
||||||
orderLogService.insertOrderLog(orderLog);
|
|
||||||
// OrderUtil orderUtil = new OrderUtil();
|
|
||||||
// orderUtil.SaveOrderLog(order);
|
|
||||||
//绑定号码
|
|
||||||
Map<String, Object> bindmap= OrderBindWorkerUtil.getOrderBindWorker(order.getId());
|
|
||||||
//发送微信推送通知客户师傅已接单
|
|
||||||
|
|
||||||
|
|
||||||
// 6. 返回成功
|
// 6. 返回成功
|
||||||
return AjaxResult.success("接单成功");
|
return AjaxResult.success("接单成功");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
@ -5001,7 +4903,7 @@ public class AppletController extends BaseController {
|
||||||
data.put("name", order.getName());
|
data.put("name", order.getName());
|
||||||
data.put("phone", order.getPhone());
|
data.put("phone", order.getPhone());
|
||||||
data.put("address", address);
|
data.put("address", address);
|
||||||
data.put("make_time", AppletControllerUtil.timeStamp2Date(order));
|
data.put("make_time", order.getMakeTime());
|
||||||
data.put("make_hour", order.getMakeHour());
|
data.put("make_hour", order.getMakeHour());
|
||||||
data.put("num", order.getNum());
|
data.put("num", order.getNum());
|
||||||
data.put("total_price", order.getTotalPrice());
|
data.put("total_price", order.getTotalPrice());
|
||||||
|
|
@ -6310,63 +6212,4 @@ public class AppletController extends BaseController {
|
||||||
return AppletControllerUtil.appletError("操作失败");
|
return AppletControllerUtil.appletError("操作失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 云信交互式语音通知呼叫结果推送回调接口
|
|
||||||
* 用于接收云信平台推送的交互式语音通知呼叫结果。
|
|
||||||
* @param requestBody 云信平台推送的JSON字符串
|
|
||||||
* @return 必须返回{"resultCode":"200"},否则云信认为推送失败
|
|
||||||
*/
|
|
||||||
@PostMapping("/api/voice/interactNotify/resultCallback")
|
|
||||||
public Map<String, Object> voiceInteractNotifyResultCallback(@RequestBody String requestBody) {
|
|
||||||
// 解析请求体(可根据业务需要保存或处理字段)
|
|
||||||
try {
|
|
||||||
JSONObject json = JSONObject.parseObject(requestBody);
|
|
||||||
// 可提取字段:accountId、callId、calleeNumber、startCallTime、endTime、duration等
|
|
||||||
// String accountId = json.getString("accountId");
|
|
||||||
// String callId = json.getString("callId");
|
|
||||||
// ... 其他字段
|
|
||||||
// 这里可以根据业务需求进行日志记录、数据库保存等操作
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 解析异常可记录日志
|
|
||||||
}
|
|
||||||
// 必须返回{"resultCode":"200"},否则云信会认为推送失败
|
|
||||||
Map<String, Object> resp = new java.util.HashMap<>();
|
|
||||||
resp.put("resultCode", "200");
|
|
||||||
return resp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 云信交互式小号呼叫结果推送结果推送回调接口
|
|
||||||
* 用于接收云信平台推送的交互式语音通知呼叫结果。
|
|
||||||
* @param requestBody 云信平台推送的JSON字符串
|
|
||||||
* @return 必须返回{"resultCode":"200"},否则云信认为推送失败
|
|
||||||
*/
|
|
||||||
@PostMapping("/api/voice/middleNumberAXB/resultCallback")
|
|
||||||
public Map<String, Object> voiceInteractmiddleNumberAXBCallback(@RequestBody String requestBody) {
|
|
||||||
// 解析请求体(可根据业务需要保存或处理字段)
|
|
||||||
try {
|
|
||||||
JSONObject json = JSONObject.parseObject(requestBody);
|
|
||||||
// 可提取字段:accountId、callId、calleeNumber、startCallTime、endTime、duration等
|
|
||||||
// String accountId = json.getString("accountId");
|
|
||||||
// String callId = json.getString("callId");
|
|
||||||
// ... 其他字段
|
|
||||||
// 这里可以根据业务需求进行日志记录、数据库保存等操作
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 解析异常可记录日志
|
|
||||||
}
|
|
||||||
// 必须返回{"resultCode":"200"},否则云信会认为推送失败
|
|
||||||
Map<String, Object> resp = new java.util.HashMap<>();
|
|
||||||
resp.put("resultCode", "200");
|
|
||||||
return resp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,17 @@ 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.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.system.domain.ServiceCate;
|
||||||
import com.ruoyi.system.domain.*;
|
import com.ruoyi.system.domain.ServiceGoods;
|
||||||
|
import com.ruoyi.system.domain.Users;
|
||||||
import com.ruoyi.system.service.IServiceGoodsService;
|
import com.ruoyi.system.service.IServiceGoodsService;
|
||||||
import com.ruoyi.system.service.IUserAddressService;
|
|
||||||
import com.ruoyi.system.service.IUsersService;
|
import com.ruoyi.system.service.IUsersService;
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.util.ArrayList;
|
||||||
import java.util.*;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小程序控制器工具类
|
* 小程序控制器工具类
|
||||||
|
|
@ -29,10 +31,6 @@ import java.util.*;
|
||||||
*/
|
*/
|
||||||
public class AppletControllerUtil {
|
public class AppletControllerUtil {
|
||||||
|
|
||||||
|
|
||||||
private static final IUsersService usersService= SpringUtils.getBean(IUsersService.class);
|
|
||||||
private static final IUserAddressService userAddressService= SpringUtils.getBean(IUserAddressService.class);
|
|
||||||
|
|
||||||
// ============================== 统一响应处理方法 ==============================
|
// ============================== 统一响应处理方法 ==============================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2116,7 +2114,7 @@ public class AppletControllerUtil {
|
||||||
orderDetail.put("name", order.getName());
|
orderDetail.put("name", order.getName());
|
||||||
orderDetail.put("phone", order.getPhone());
|
orderDetail.put("phone", order.getPhone());
|
||||||
orderDetail.put("address", order.getAddress());
|
orderDetail.put("address", order.getAddress());
|
||||||
orderDetail.put("make_time", AppletControllerUtil.timeStamp2Date(order));
|
orderDetail.put("make_time", order.getMakeTime());
|
||||||
orderDetail.put("make_hour", order.getMakeHour());
|
orderDetail.put("make_hour", order.getMakeHour());
|
||||||
orderDetail.put("num", order.getNum());
|
orderDetail.put("num", order.getNum());
|
||||||
|
|
||||||
|
|
@ -2360,28 +2358,6 @@ public class AppletControllerUtil {
|
||||||
return timeSlotList;
|
return timeSlotList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单生成给师傅派单
|
|
||||||
*
|
|
||||||
* @param order 订单主键
|
|
||||||
* @return 是否可用
|
|
||||||
*/
|
|
||||||
public static Users creatWorkerForOrder(Order order) {
|
|
||||||
GaoDeMapUtil gaoDeMapUtil = new GaoDeMapUtil();
|
|
||||||
UserAddress userAddress = userAddressService.selectUserAddressById(order.getAddressId());
|
|
||||||
// if (userAddress != null){
|
|
||||||
// String city = gaoDeMapUtil.getCityByLocation(userAddress.getLongitude(), userAddress.getLatitude());
|
|
||||||
// if (city != null){
|
|
||||||
//
|
|
||||||
// }else{
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
Users worker = usersService.selectUsersById(2l);
|
|
||||||
return worker;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断时间段是否可用
|
* 判断时间段是否可用
|
||||||
*
|
*
|
||||||
|
|
@ -2720,117 +2696,4 @@ public class AppletControllerUtil {
|
||||||
dataPage.put("total", pageInfo.getTotal());
|
dataPage.put("total", pageInfo.getTotal());
|
||||||
return dataPage;
|
return dataPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 云信交互式语音通知回调接口
|
|
||||||
* <p>
|
|
||||||
* 用于接收云信平台推送的语音通知结果,解析callId、result、message等字段。
|
|
||||||
* 该方法可直接作为Controller层的回调接口方法使用。
|
|
||||||
* </p>
|
|
||||||
* @param requestBody 云信平台推送的JSON字符串
|
|
||||||
* @return 标准响应结果
|
|
||||||
*/
|
|
||||||
public static Map<String, Object> voiceInteractNotifyCallback(String requestBody) {
|
|
||||||
Map<String, Object> resultMap = new HashMap<>();
|
|
||||||
try {
|
|
||||||
// 解析JSON请求体
|
|
||||||
com.alibaba.fastjson2.JSONObject json = com.alibaba.fastjson2.JSONObject.parseObject(requestBody);
|
|
||||||
String callId = json.getString("callId");
|
|
||||||
String result = json.getString("result");
|
|
||||||
String message = json.getString("message");
|
|
||||||
|
|
||||||
// 业务处理:可根据callId、result、message进行自定义逻辑
|
|
||||||
// 例如:记录日志、更新数据库、通知业务系统等
|
|
||||||
|
|
||||||
// 返回标准响应
|
|
||||||
resultMap.put("code", 200);
|
|
||||||
resultMap.put("msg", "回调接收成功");
|
|
||||||
resultMap.put("callId", callId);
|
|
||||||
resultMap.put("result", result);
|
|
||||||
resultMap.put("message", message);
|
|
||||||
} catch (Exception e) {
|
|
||||||
resultMap.put("code", 500);
|
|
||||||
resultMap.put("msg", "回调处理异常: " + e.getMessage());
|
|
||||||
}
|
|
||||||
return resultMap;
|
|
||||||
}
|
|
||||||
//完成订单的初步创建之后开始进行派单和发送订阅,以及预约师傅的操作
|
|
||||||
public static Map<String, Object> creatOrderTheNext(String imageUrl) {
|
|
||||||
Map<String, Object> imageData = new HashMap<>();
|
|
||||||
|
|
||||||
//第一步给客户发送订阅消息,告诉客户预约成功
|
|
||||||
|
|
||||||
imageData.put("url", imageUrl);
|
|
||||||
imageData.put("thumb", imageUrl);
|
|
||||||
return imageData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送微信小程序订阅消息(自动获取accessToken)
|
|
||||||
* @param touser 接收者(用户)的openid
|
|
||||||
* @param templateId 订阅消息模板ID
|
|
||||||
* @param page 跳转页面路径(可选,可为null)
|
|
||||||
* @param data 模板内容(如{"thing1":{"value":"内容"}})
|
|
||||||
* @return 微信接口响应字符串(JSON格式)
|
|
||||||
* @throws Exception 异常信息
|
|
||||||
*
|
|
||||||
* 使用示例:
|
|
||||||
* Map<String, Object> data = new HashMap<>();
|
|
||||||
* Map<String, String> thing1 = new HashMap<>();
|
|
||||||
* thing1.put("value", "测试内容");
|
|
||||||
* data.put("thing1", thing1);
|
|
||||||
* String result = AppletControllerUtil.WXSendMsgUtil(openid, templateId, "pages/index/index", data);
|
|
||||||
*/
|
|
||||||
public static String WXSendMsgUtil(String touser, String templateId, String page, Map<String, Object> data) throws Exception {
|
|
||||||
// 1. 获取accessToken
|
|
||||||
String accessToken = com.ruoyi.system.ControllerUtil.WechatApiUtil.getAccessToken().get("access_token").toString();
|
|
||||||
// 2. 微信订阅消息接口地址
|
|
||||||
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
|
|
||||||
// 3. 组装请求参数
|
|
||||||
Map<String, Object> param = new HashMap<>();
|
|
||||||
param.put("touser", touser);
|
|
||||||
param.put("template_id", templateId);
|
|
||||||
if (page != null && !page.isEmpty()) {
|
|
||||||
param.put("page", page);
|
|
||||||
}
|
|
||||||
param.put("data", data);
|
|
||||||
String body = com.alibaba.fastjson2.JSON.toJSONString(param);
|
|
||||||
// 4. 发送POST请求
|
|
||||||
java.net.HttpURLConnection conn = (java.net.HttpURLConnection) new java.net.URL(url).openConnection();
|
|
||||||
conn.setRequestMethod("POST");
|
|
||||||
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
|
|
||||||
conn.setDoOutput(true);
|
|
||||||
try (java.io.OutputStream os = conn.getOutputStream()) {
|
|
||||||
os.write(body.getBytes(java.nio.charset.StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
// 5. 读取响应
|
|
||||||
java.io.InputStream is = conn.getInputStream();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
int len;
|
|
||||||
while ((len = is.read(buf)) != -1) {
|
|
||||||
sb.append(new String(buf, 0, len, java.nio.charset.StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
is.close();
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//时间转化,将int的时间戳转换为时间,这个方法用于订单详情里面的预约时间
|
|
||||||
public static String timeStamp2Date(Order order) {
|
|
||||||
// 定义日期格式化模式
|
|
||||||
String formattedDate="";
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");// 注意:Java的Date构
|
|
||||||
if(order!=null){
|
|
||||||
if (order.getMakeTime() != null){
|
|
||||||
// 将时间戳转换为Date对象
|
|
||||||
Date date = new Date((long) order.getMakeTime() * 1000);
|
|
||||||
formattedDate = sdf.format(date);
|
|
||||||
if (order.getMakeHour() != null){
|
|
||||||
formattedDate += " " + order.getMakeHour();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return formattedDate.replace("-", "~");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,113 +0,0 @@
|
||||||
package com.ruoyi.system.ControllerUtil;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 高德地图工具类
|
|
||||||
* 提供常用的地图相关功能,如根据经纬度获取城市、逆地理编码等
|
|
||||||
* 需要在高德开放平台注册并获取Web服务Key
|
|
||||||
*/
|
|
||||||
public class GaoDeMapUtil {
|
|
||||||
|
|
||||||
// 请替换为你自己的高德Web服务Key
|
|
||||||
private static final String GAODE_KEY = "308ad08f306d74daddffba44f5537767";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据经纬度获取所在城市名称
|
|
||||||
* @param longitude 经度
|
|
||||||
* @param latitude 纬度
|
|
||||||
* @return 城市名称(如"上海市"),失败返回null
|
|
||||||
*/
|
|
||||||
public static String getCityByLocation(double longitude, double latitude) {
|
|
||||||
try {
|
|
||||||
String url = String.format(
|
|
||||||
"https://restapi.amap.com/v3/geocode/regeo?location=%f,%f&key=%s&extensions=base",
|
|
||||||
longitude, latitude, GAODE_KEY
|
|
||||||
);
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
|
||||||
conn.setRequestMethod("GET");
|
|
||||||
conn.setDoInput(true);
|
|
||||||
InputStream is = conn.getInputStream();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
int len;
|
|
||||||
while ((len = is.read(buf)) != -1) {
|
|
||||||
sb.append(new String(buf, 0, len, StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
is.close();
|
|
||||||
JSONObject json = JSONObject.parseObject(sb.toString());
|
|
||||||
if (json.getIntValue("status") == 1) {
|
|
||||||
JSONObject regeocode = json.getJSONObject("regeocode");
|
|
||||||
if (regeocode != null) {
|
|
||||||
JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
|
|
||||||
if (addressComponent != null) {
|
|
||||||
return addressComponent.getString("city");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 经纬度逆地理编码,获取详细地址
|
|
||||||
* @param longitude 经度
|
|
||||||
* @param latitude 纬度
|
|
||||||
* @return 详细地址字符串,失败返回null
|
|
||||||
*/
|
|
||||||
public static String getAddressByLocation(double longitude, double latitude) {
|
|
||||||
try {
|
|
||||||
String url = String.format(
|
|
||||||
"https://restapi.amap.com/v3/geocode/regeo?location=%f,%f&key=%s&extensions=base",
|
|
||||||
longitude, latitude, GAODE_KEY
|
|
||||||
);
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
|
||||||
conn.setRequestMethod("GET");
|
|
||||||
conn.setDoInput(true);
|
|
||||||
InputStream is = conn.getInputStream();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
int len;
|
|
||||||
while ((len = is.read(buf)) != -1) {
|
|
||||||
sb.append(new String(buf, 0, len, StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
is.close();
|
|
||||||
JSONObject json = JSONObject.parseObject(sb.toString());
|
|
||||||
if (json.getIntValue("status") == 1) {
|
|
||||||
JSONObject regeocode = json.getJSONObject("regeocode");
|
|
||||||
if (regeocode != null) {
|
|
||||||
return regeocode.getString("formatted_address");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算两个经纬度点之间的直线距离(单位:米)
|
|
||||||
* @param lng1 第一个点经度
|
|
||||||
* @param lat1 第一个点纬度
|
|
||||||
* @param lng2 第二个点经度
|
|
||||||
* @param lat2 第二个点纬度
|
|
||||||
* @return 距离(米)
|
|
||||||
*/
|
|
||||||
public static double getDistance(double lng1, double lat1, double lng2, double lat2) {
|
|
||||||
double radLat1 = Math.toRadians(lat1);
|
|
||||||
double radLat2 = Math.toRadians(lat2);
|
|
||||||
double a = radLat1 - radLat2;
|
|
||||||
double b = Math.toRadians(lng1) - Math.toRadians(lng2);
|
|
||||||
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
|
|
||||||
+ Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
|
|
||||||
s = s * 6378137.0; // 地球半径(米)
|
|
||||||
s = Math.round(s * 10000d) / 10000d;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
||||||
package com.ruoyi.system.ControllerUtil;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
|
||||||
import com.ruoyi.system.domain.Area;
|
|
||||||
import com.ruoyi.system.domain.MobileMiddle;
|
|
||||||
import com.ruoyi.system.domain.Order;
|
|
||||||
import com.ruoyi.system.domain.UserAddress;
|
|
||||||
import com.ruoyi.system.domain.Users;
|
|
||||||
import com.ruoyi.system.service.IAreaService;
|
|
||||||
import com.ruoyi.system.service.IMobileMiddleService;
|
|
||||||
import com.ruoyi.system.service.IOrderService;
|
|
||||||
import com.ruoyi.system.service.IUserAddressService;
|
|
||||||
import com.ruoyi.system.service.IUsersService;
|
|
||||||
import com.winnerlook.model.VoiceResponseResult;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 师傅绑定订单的电话号码操作
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author Mr. Zhang Pan
|
|
||||||
* @date 2025-01-03
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public class OrderBindWorkerUtil {
|
|
||||||
|
|
||||||
private static final IUsersService usersService= SpringUtils.getBean(IUsersService.class);
|
|
||||||
private static final IUserAddressService userAddressService= SpringUtils.getBean(IUserAddressService.class);
|
|
||||||
private static final IMobileMiddleService mobileMiddleService= SpringUtils.getBean(IMobileMiddleService.class);
|
|
||||||
private static final IOrderService orderService= SpringUtils.getBean(IOrderService.class);
|
|
||||||
private static final IAreaService areaService= SpringUtils.getBean(IAreaService.class);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单绑定师傅电话号码操作
|
|
||||||
* @param orderId 订单ID
|
|
||||||
* @return 绑定结果Map,包含code和msg
|
|
||||||
*/
|
|
||||||
public static Map<String, Object> getOrderBindWorker(long orderId) {
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
try {
|
|
||||||
// 1. 查询订单
|
|
||||||
Order order = orderService.selectOrderById(orderId);
|
|
||||||
if (order == null) {
|
|
||||||
result.put("code", 404);
|
|
||||||
result.put("msg", "订单不存在");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// 2. 查询师傅信息
|
|
||||||
Users workerUser = usersService.selectUsersById(order.getWorkerId());
|
|
||||||
if (workerUser == null) {
|
|
||||||
result.put("code", 404);
|
|
||||||
result.put("msg", "师傅信息不存在");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// 3. 查询订单地址
|
|
||||||
UserAddress userAddress = userAddressService.selectUserAddressById(order.getAddressId());
|
|
||||||
if (userAddress == null) {
|
|
||||||
result.put("code", 404);
|
|
||||||
result.put("msg", "订单地址不存在");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// 4. 经纬度转城市
|
|
||||||
double lng = Double.parseDouble(userAddress.getLongitude());
|
|
||||||
double lat = Double.parseDouble(userAddress.getLatitude());
|
|
||||||
String city = GaoDeMapUtil.getCityByLocation(lng, lat);
|
|
||||||
if (city == null || city.isEmpty()) {
|
|
||||||
result.put("code", 500);
|
|
||||||
result.put("msg", "无法根据经纬度获取城市信息");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// 5. 查询城市编码
|
|
||||||
Area area = new Area();
|
|
||||||
area.setTitle(city);
|
|
||||||
List<Area> areaList = areaService.selectAreaList(area);
|
|
||||||
if (areaList == null || areaList.isEmpty()) {
|
|
||||||
result.put("code", 404);
|
|
||||||
result.put("msg", "未找到城市编码");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
Long cityCode = areaList.get(0).getId();
|
|
||||||
// 6. 查询可用中间号
|
|
||||||
MobileMiddle mobileMiddleQuery = new MobileMiddle();
|
|
||||||
mobileMiddleQuery.setCityId(cityCode);
|
|
||||||
List<MobileMiddle> mobileMiddleList = mobileMiddleService.selectMobileMiddleList(mobileMiddleQuery);
|
|
||||||
if (mobileMiddleList == null || mobileMiddleList.isEmpty()) {
|
|
||||||
result.put("code", 404);
|
|
||||||
result.put("msg", "该城市暂无可用中间号");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// 7. 获取用户和师傅手机号
|
|
||||||
String userPhone = userAddress.getPhone();
|
|
||||||
String workerPhone = workerUser.getPhone();
|
|
||||||
if (userPhone == null || workerPhone == null) {
|
|
||||||
result.put("code", 400);
|
|
||||||
result.put("msg", "用户或师傅手机号为空");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// 8. 绑定中间号,直到成功
|
|
||||||
for (MobileMiddle middle : mobileMiddleList) {
|
|
||||||
VoiceResponseResult bindResult = YunXinPhoneUtilAPI.httpsPrivacyBindAxb(middle.getPhone(), userPhone, workerPhone);
|
|
||||||
if ("000000".equals(bindResult.getResult())) {
|
|
||||||
// 绑定成功,更新订单
|
|
||||||
order.setMiddlePhone(middle.getPhone());
|
|
||||||
order.setUserPhone(userPhone);
|
|
||||||
order.setWorkerPhone(workerPhone);
|
|
||||||
orderService.updateOrder(order);
|
|
||||||
result.put("code", 200);
|
|
||||||
result.put("msg", "绑定成功");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 9. 所有中间号都绑定失败
|
|
||||||
result.put("code", 500);
|
|
||||||
result.put("msg", "所有中间号均绑定失败");
|
|
||||||
} catch (Exception e) {
|
|
||||||
result.put("code", 500);
|
|
||||||
result.put("msg", "绑定异常: " + e.getMessage());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,20 +5,11 @@ import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
|
||||||
import com.ruoyi.system.domain.AppleDoMain.TemplateData;
|
|
||||||
import com.ruoyi.system.domain.AppleDoMain.WxMssVo;
|
|
||||||
import com.ruoyi.system.domain.Order;
|
|
||||||
import com.ruoyi.system.domain.ServiceGoods;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信小程序通知消息推送工具类
|
* 微信小程序通知消息推送工具类
|
||||||
|
|
@ -28,12 +19,8 @@ import org.springframework.web.client.RestTemplate;
|
||||||
public class WXsendMsgUtil {
|
public class WXsendMsgUtil {
|
||||||
|
|
||||||
// 微信小程序的AppID和AppSecret(请替换为你自己的)
|
// 微信小程序的AppID和AppSecret(请替换为你自己的)
|
||||||
private static final String APPID = "wx73d0202b3c8a6d68";
|
private static final String APPID = "YOUR_APPID";
|
||||||
private static final String APPSECRET = "c0871da0ca140930420c695147f3694b";
|
private static final String APPSECRET = "YOUR_APPSECRET";
|
||||||
|
|
||||||
private static final String PAY_SUCCESS="YKnuTCAD-oEEhNGoI3LUVkAqNsykOMTcyrf71S9vev8"; //下单成功通知
|
|
||||||
private static final String ORDER_STATUS="5lA-snytEPl25fBS7rf6rQi8Y0i5HOSdG0JMVdUnMcU"; // ##订单状态通知
|
|
||||||
private static final String PAY_GOODS="pv3cba-wPoinUbBZSskp0KpDNnJwrHqS0rvGBfDNQ1M"; //##商品支付通知
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取微信小程序全局唯一后台接口调用凭据 access_token
|
* 获取微信小程序全局唯一后台接口调用凭据 access_token
|
||||||
|
|
@ -57,117 +44,57 @@ public class WXsendMsgUtil {
|
||||||
return json.getString("access_token");
|
return json.getString("access_token");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送微信小程序订阅消息
|
||||||
//公共推送
|
* @param accessToken access_token
|
||||||
public static String PublicPush(WxMssVo wxMssVo) throws Exception {
|
* @param touser 接收者openid
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
* @param templateId 模板ID
|
||||||
// String accessToken = getAccessToken();
|
* @param page 跳转页面(可选)
|
||||||
//这里简单起见我们每次都获取最新的access_token
|
* @param data 模板内容(Map<String, Object>,如{"thing1":{"value":"内容"}})
|
||||||
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + getAccessToken();
|
* @return 微信接口响应
|
||||||
ResponseEntity<String> responseEntity =
|
* @throws Exception 异常
|
||||||
restTemplate.postForEntity(url, wxMssVo, String.class);
|
*/
|
||||||
return responseEntity.getBody();
|
public static String sendSubscribeMsg(String accessToken, String touser, String templateId, String page, Map<String, Object> data) throws Exception {
|
||||||
}
|
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put("touser", touser);
|
||||||
|
param.put("template_id", templateId);
|
||||||
|
if (page != null && !page.isEmpty()) {
|
||||||
// /**
|
param.put("page", page);
|
||||||
// * 发送微信小程序订阅消息
|
|
||||||
// * @param accessToken access_token
|
|
||||||
// * @param touser 接收者openid
|
|
||||||
// * @param templateId 模板ID
|
|
||||||
// * @param page 跳转页面(可选)
|
|
||||||
// * @param data 模板内容(Map<String, Object>,如{"thing1":{"value":"内容"}})
|
|
||||||
// * @return 微信接口响应
|
|
||||||
// * @throws Exception 异常
|
|
||||||
// */
|
|
||||||
// public static String sendSubscribeMsg(String accessToken, String touser, String templateId, String page, Map<String, Object> data) throws Exception {
|
|
||||||
// System.out.println("0001access_token:" + accessToken);
|
|
||||||
// String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
|
|
||||||
// Map<String, Object> param = new HashMap<>();
|
|
||||||
// param.put("touser", touser);
|
|
||||||
// param.put("template_id", templateId);
|
|
||||||
// if (page != null && !page.isEmpty()) {
|
|
||||||
// param.put("page", page);
|
|
||||||
// }
|
|
||||||
// param.put("data", data);
|
|
||||||
// String body = JSON.toJSONString(param);
|
|
||||||
// HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
|
||||||
// conn.setRequestMethod("POST");
|
|
||||||
// conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
|
|
||||||
// conn.setDoOutput(true);
|
|
||||||
// try (OutputStream os = conn.getOutputStream()) {
|
|
||||||
// os.write(body.getBytes(StandardCharsets.UTF_8));
|
|
||||||
// }
|
|
||||||
// InputStream is = conn.getInputStream();
|
|
||||||
// StringBuilder sb = new StringBuilder();
|
|
||||||
// System.out.println("0001sb.toString():" + sb.toString());
|
|
||||||
// byte[] buf = new byte[1024];
|
|
||||||
// int len;
|
|
||||||
// while ((len = is.read(buf)) != -1) {
|
|
||||||
// sb.append(new String(buf, 0, len, StandardCharsets.UTF_8));
|
|
||||||
// }
|
|
||||||
// is.close();
|
|
||||||
// return sb.toString();
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
//微信推送第一步,通知用户预约成功
|
|
||||||
public static String sendMsgForUserInfo(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(PAY_SUCCESS);//订阅消息模板id
|
|
||||||
wxMssVo.setPage("/pages/mine/serveOrder/index");
|
|
||||||
String mark = order.getMark();
|
|
||||||
if (StringUtils.isEmpty( mark)){
|
|
||||||
mark="暂无备注";
|
|
||||||
}
|
}
|
||||||
|
param.put("data", data);
|
||||||
Map<String, TemplateData> m = new HashMap<>(3);
|
String body = JSON.toJSONString(param);
|
||||||
m.put("thing44", new TemplateData(serviceGoods.getTitle()));
|
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||||
m.put("character_string22", new TemplateData(order.getOrderId()));
|
conn.setRequestMethod("POST");
|
||||||
m.put("time1", new TemplateData(AppletControllerUtil.timeStamp2Date(order)));
|
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
|
||||||
m.put("thing27", new TemplateData(mark));
|
conn.setDoOutput(true);
|
||||||
m.put("time10", new TemplateData(sdf.format(new Date())));
|
try (OutputStream os = conn.getOutputStream()) {
|
||||||
System.out.println("thing44"+ serviceGoods.getTitle());
|
os.write(body.getBytes(StandardCharsets.UTF_8));
|
||||||
System.out.println("character_string22"+ order.getOrderId());
|
|
||||||
System.out.println("time1"+ AppletControllerUtil.timeStamp2Date(order));
|
|
||||||
System.out.println("thing27"+ order.getMark());
|
|
||||||
System.out.println("time10"+sdf.format(new Date()));
|
|
||||||
|
|
||||||
System.out.println("0002订单号:" + m.toString());
|
|
||||||
wxMssVo.setData(m);
|
|
||||||
return PublicPush(wxMssVo);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//微信推送第er步,给师傅通知派单情况
|
|
||||||
public static String sendMsgForWorkerInfo(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/tab/serve/index");
|
|
||||||
String mark = order.getMark();
|
|
||||||
if (StringUtils.isEmpty( mark)){
|
|
||||||
mark="暂无备注";
|
|
||||||
}
|
}
|
||||||
Map<String, TemplateData> m = new HashMap<>(3);
|
InputStream is = conn.getInputStream();
|
||||||
m.put("thing15", new TemplateData(serviceGoods.getTitle()));
|
StringBuilder sb = new StringBuilder();
|
||||||
m.put("character_string5", new TemplateData(order.getOrderId()));
|
byte[] buf = new byte[1024];
|
||||||
m.put("date3", new TemplateData(AppletControllerUtil.timeStamp2Date(order)));
|
int len;
|
||||||
m.put("thing1", new TemplateData(order.getAddress()));
|
while ((len = is.read(buf)) != -1) {
|
||||||
m.put("thing9", new TemplateData(sdf.format(new Date())));
|
sb.append(new String(buf, 0, len, StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
System.out.println("0002订单号:" + m.toString());
|
is.close();
|
||||||
wxMssVo.setData(m);
|
return sb.toString();
|
||||||
return PublicPush(wxMssVo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 示例:如何推送微信小程序订阅消息
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
// 1. 获取access_token
|
||||||
|
String accessToken = getAccessToken();
|
||||||
|
// 2. 组装消息内容
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
Map<String, String> thing1 = new HashMap<>();
|
||||||
|
thing1.put("value", "测试内容");
|
||||||
|
data.put("thing1", thing1);
|
||||||
|
// 3. 发送消息
|
||||||
|
String result = sendSubscribeMsg(accessToken, "OPENID", "TEMPLATE_ID", "pages/index/index", data);
|
||||||
|
System.out.println("推送结果:" + result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,8 +6,6 @@ import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
@ -37,35 +35,22 @@ import java.util.*;
|
||||||
* @date 2025-01-03
|
* @date 2025-01-03
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
@Component
|
|
||||||
public class WechatPayUtil {
|
public class WechatPayUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付配置(通过Spring配置注入)
|
* 微信支付配置常量
|
||||||
* 仅支持小程序支付(JSAPI)
|
* 注意:实际使用时需要在配置文件中配置这些值
|
||||||
* 建议在application.yml或application.properties中配置如下:
|
|
||||||
* wechat.pay.app-id=xxx
|
|
||||||
* wechat.pay.mch-id=xxx
|
|
||||||
* wechat.pay.api-key=xxx
|
|
||||||
* wechat.pay.cert-path=xxx
|
|
||||||
*/
|
*/
|
||||||
@Value("${wechat.pay.app-id}")
|
private static final String WECHAT_APP_ID = "your_wechat_appid";
|
||||||
private String wechatAppId;
|
private static final String WECHAT_MCH_ID = "your_merchant_id";
|
||||||
|
private static final String WECHAT_API_KEY = "your_api_key";
|
||||||
@Value("${wechat.pay.mch-id}")
|
private static final String WECHAT_CERT_PATH = "/path/to/cert.p12"; // 微信支付证书路径
|
||||||
private String wechatMchId;
|
|
||||||
|
|
||||||
@Value("${wechat.pay.api-key}")
|
|
||||||
private String wechatApiKey;
|
|
||||||
|
|
||||||
@Value("${wechat.pay.cert-path}")
|
|
||||||
private String wechatCertPath;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付API地址(仅保留小程序相关接口)
|
* 微信支付API地址
|
||||||
*/
|
*/
|
||||||
private static final String WECHAT_PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; // 统一下单
|
private static final String WECHAT_PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
||||||
private static final String WECHAT_QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery"; // 订单查询
|
private static final String WECHAT_QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
|
||||||
private static final String WECHAT_REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
|
private static final String WECHAT_REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
|
||||||
private static final String WECHAT_TRANSFER_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 企业付款
|
private static final String WECHAT_TRANSFER_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 企业付款
|
||||||
|
|
||||||
|
|
@ -82,104 +67,110 @@ public class WechatPayUtil {
|
||||||
*/
|
*/
|
||||||
private static final RestTemplate restTemplate = new RestTemplate();
|
private static final RestTemplate restTemplate = new RestTemplate();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小程序统一下单(JSAPI)
|
* 统一下单 - 微信小程序支付
|
||||||
* @param openid 用户openid
|
*
|
||||||
* @param orderNo 商户订单号(唯一)
|
* @param orderInfo 订单信息
|
||||||
* @param totalFee 支付金额(单位:分,整型)
|
* @return 支付参数Map
|
||||||
* @param body 商品描述
|
|
||||||
* @param notifyUrl 支付回调通知地址
|
|
||||||
* @param attach 附加数据(可选)
|
|
||||||
* @return 统一下单结果,包含小程序端调起支付的参数
|
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> unifiedOrder(String openid, String orderNo, int totalFee, String body, String notifyUrl, String attach) {
|
public static Map<String, Object> unifiedOrder(Map<String, Object> orderInfo) {
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 1. 参数校验
|
// 1. 参数验证
|
||||||
if (openid == null || openid.trim().isEmpty()) {
|
String validationError = validateOrderParams(orderInfo);
|
||||||
return failResult("用户openid不能为空");
|
if (validationError != null) {
|
||||||
}
|
result.put("success", false);
|
||||||
if (orderNo == null || orderNo.trim().isEmpty()) {
|
result.put("message", validationError);
|
||||||
return failResult("订单号不能为空");
|
return result;
|
||||||
}
|
|
||||||
if (totalFee <= 0) {
|
|
||||||
return failResult("支付金额必须大于0");
|
|
||||||
}
|
|
||||||
if (body == null || body.trim().isEmpty()) {
|
|
||||||
return failResult("商品描述不能为空");
|
|
||||||
}
|
|
||||||
if (notifyUrl == null || notifyUrl.trim().isEmpty()) {
|
|
||||||
return failResult("回调通知地址不能为空");
|
|
||||||
}
|
|
||||||
// 2. 构建参数
|
|
||||||
Map<String, String> params = new HashMap<>();
|
|
||||||
params.put("appid", wechatAppId);
|
|
||||||
params.put("mch_id", wechatMchId);
|
|
||||||
params.put("nonce_str", generateNonceStr());
|
|
||||||
params.put("body", body);
|
|
||||||
params.put("out_trade_no", orderNo);
|
|
||||||
params.put("total_fee", String.valueOf(totalFee)); // 单位:分
|
|
||||||
params.put("spbill_create_ip", "127.0.0.1");
|
|
||||||
params.put("notify_url", notifyUrl);
|
|
||||||
params.put("trade_type", TRADE_TYPE_JSAPI);
|
|
||||||
params.put("openid", openid);
|
|
||||||
if (attach != null && !attach.trim().isEmpty()) {
|
|
||||||
params.put("attach", attach);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. 构建统一下单参数
|
||||||
|
Map<String, String> params = buildUnifiedOrderParams(orderInfo);
|
||||||
|
|
||||||
// 3. 生成签名
|
// 3. 生成签名
|
||||||
String sign = generateSign(params, wechatApiKey);
|
String sign = generateSign(params, WECHAT_API_KEY);
|
||||||
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);
|
ResponseEntity<String> response = restTemplate.postForEntity(WECHAT_PAY_URL, xmlRequest, 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"))) {
|
if (SUCCESS_CODE.equals(responseMap.get("return_code")) &&
|
||||||
// 6. 构建小程序端调起支付参数
|
SUCCESS_CODE.equals(responseMap.get("result_code"))) {
|
||||||
|
|
||||||
|
// 6. 构建小程序支付参数
|
||||||
Map<String, Object> payParams = buildMiniProgramPayParams(responseMap.get("prepay_id"));
|
Map<String, Object> payParams = buildMiniProgramPayParams(responseMap.get("prepay_id"));
|
||||||
|
|
||||||
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", responseMap.get("prepay_id"));
|
||||||
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")));
|
result.put("success", false);
|
||||||
|
result.put("message", "统一下单失败:" +
|
||||||
|
(responseMap.get("err_code_des") != null ? responseMap.get("err_code_des") :
|
||||||
|
responseMap.get("return_msg")));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
result = failResult("统一下单异常:" + e.getMessage());
|
result.put("success", false);
|
||||||
|
result.put("message", "统一下单异常:" + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询订单状态(小程序支付)
|
* 查询订单状态
|
||||||
* @param orderNo 商户订单号
|
*
|
||||||
* @param transactionId 微信订单号(可选)
|
* @param orderNo 订单号
|
||||||
* @return 查询结果,包含订单状态等信息
|
* @param transactionId 微信订单号(可选,与orderNo二选一)
|
||||||
|
* @return 查询结果
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> queryOrder(String orderNo, String transactionId) {
|
public static Map<String, Object> queryOrder(String orderNo, String transactionId) {
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((orderNo == null || orderNo.trim().isEmpty()) && (transactionId == null || transactionId.trim().isEmpty())) {
|
// 1. 参数验证
|
||||||
return failResult("订单号和微信订单号不能同时为空");
|
if ((orderNo == null || orderNo.trim().isEmpty()) &&
|
||||||
|
(transactionId == null || transactionId.trim().isEmpty())) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "订单号和微信订单号不能同时为空");
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. 构建查询参数
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put("appid", wechatAppId);
|
params.put("appid", WECHAT_APP_ID);
|
||||||
params.put("mch_id", wechatMchId);
|
params.put("mch_id", WECHAT_MCH_ID);
|
||||||
params.put("nonce_str", generateNonceStr());
|
params.put("nonce_str", generateNonceStr());
|
||||||
|
|
||||||
if (orderNo != null && !orderNo.trim().isEmpty()) {
|
if (orderNo != null && !orderNo.trim().isEmpty()) {
|
||||||
params.put("out_trade_no", orderNo.trim());
|
params.put("out_trade_no", orderNo.trim());
|
||||||
}
|
}
|
||||||
if (transactionId != null && !transactionId.trim().isEmpty()) {
|
if (transactionId != null && !transactionId.trim().isEmpty()) {
|
||||||
params.put("transaction_id", transactionId.trim());
|
params.put("transaction_id", transactionId.trim());
|
||||||
}
|
}
|
||||||
String sign = generateSign(params, wechatApiKey);
|
|
||||||
|
// 3. 生成签名
|
||||||
|
String sign = generateSign(params, WECHAT_API_KEY);
|
||||||
params.put("sign", sign);
|
params.put("sign", sign);
|
||||||
|
|
||||||
|
// 4. 发送请求
|
||||||
String xmlRequest = mapToXml(params);
|
String xmlRequest = mapToXml(params);
|
||||||
ResponseEntity<String> response = restTemplate.postForEntity(WECHAT_QUERY_URL, xmlRequest, String.class);
|
ResponseEntity<String> response = restTemplate.postForEntity(WECHAT_QUERY_URL, xmlRequest, String.class);
|
||||||
|
|
||||||
|
// 5. 解析响应
|
||||||
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<>();
|
||||||
orderInfo.put("tradeState", responseMap.get("trade_state"));
|
orderInfo.put("tradeState", responseMap.get("trade_state"));
|
||||||
orderInfo.put("tradeStateDesc", responseMap.get("trade_state_desc"));
|
orderInfo.put("tradeStateDesc", responseMap.get("trade_state_desc"));
|
||||||
|
|
@ -188,44 +179,125 @@ public class WechatPayUtil {
|
||||||
orderInfo.put("totalFee", responseMap.get("total_fee"));
|
orderInfo.put("totalFee", responseMap.get("total_fee"));
|
||||||
orderInfo.put("cashFee", responseMap.get("cash_fee"));
|
orderInfo.put("cashFee", responseMap.get("cash_fee"));
|
||||||
orderInfo.put("timeEnd", responseMap.get("time_end"));
|
orderInfo.put("timeEnd", responseMap.get("time_end"));
|
||||||
|
|
||||||
result.put("success", true);
|
result.put("success", true);
|
||||||
result.put("orderInfo", orderInfo);
|
result.put("orderInfo", orderInfo);
|
||||||
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")));
|
result.put("success", false);
|
||||||
|
result.put("message", "查询订单失败:" +
|
||||||
|
(responseMap.get("err_code_des") != null ? responseMap.get("err_code_des") :
|
||||||
|
responseMap.get("return_msg")));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
result = failResult("查询订单异常:" + e.getMessage());
|
result.put("success", false);
|
||||||
|
result.put("message", "查询订单异常:" + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付回调通知处理(小程序支付)
|
* 找朋友代付功能 - 生成代付订单
|
||||||
* @param request HttpServletRequest
|
*
|
||||||
* @return 处理结果,包含是否成功、支付信息等
|
* @param payForInfo 代付信息
|
||||||
|
* @return 代付订单结果
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> handlePayNotify(HttpServletRequest request) {
|
public static Map<String, Object> createPayForOrder(Map<String, Object> payForInfo) {
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 参数验证
|
||||||
|
String validationError = validatePayForParams(payForInfo);
|
||||||
|
if (validationError != null) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", validationError);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 生成代付订单号
|
||||||
|
String payForOrderNo = generatePayForOrderNo((String) payForInfo.get("orderNo"));
|
||||||
|
|
||||||
|
// 3. 构建代付订单信息
|
||||||
|
Map<String, Object> payForOrderInfo = new HashMap<>();
|
||||||
|
payForOrderInfo.put("orderNo", payForOrderNo);
|
||||||
|
payForOrderInfo.put("openid", payForInfo.get("payerOpenid"));
|
||||||
|
payForOrderInfo.put("totalFee", payForInfo.get("totalFee"));
|
||||||
|
payForOrderInfo.put("body", "代付-" + payForInfo.get("body"));
|
||||||
|
payForOrderInfo.put("notifyUrl", payForInfo.get("notifyUrl"));
|
||||||
|
payForOrderInfo.put("attach", buildPayForAttach(payForInfo));
|
||||||
|
|
||||||
|
// 4. 设置30分钟过期时间
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.add(Calendar.MINUTE, 30);
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||||
|
payForOrderInfo.put("timeExpire", sdf.format(calendar.getTime()));
|
||||||
|
|
||||||
|
// 5. 调用统一下单
|
||||||
|
Map<String, Object> unifiedResult = unifiedOrder(payForOrderInfo);
|
||||||
|
|
||||||
|
if ((Boolean) unifiedResult.get("success")) {
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("payForOrderNo", payForOrderNo);
|
||||||
|
result.put("payParams", unifiedResult.get("payParams"));
|
||||||
|
result.put("prepayId", unifiedResult.get("prepayId"));
|
||||||
|
result.put("expireTime", payForOrderInfo.get("timeExpire"));
|
||||||
|
result.put("message", "代付订单创建成功");
|
||||||
|
} else {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "代付订单创建失败:" + unifiedResult.get("message"));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "创建代付订单异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付结果通知回调处理
|
||||||
|
*
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return 处理结果
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> handlePayNotify(HttpServletRequest request) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 1. 读取请求数据
|
// 1. 读取请求数据
|
||||||
StringBuilder xmlData = new StringBuilder();
|
StringBuilder xmlData = new StringBuilder();
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
|
BufferedReader reader = new BufferedReader(
|
||||||
|
new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
xmlData.append(line);
|
xmlData.append(line);
|
||||||
}
|
}
|
||||||
reader.close();
|
reader.close();
|
||||||
|
|
||||||
// 2. 解析XML数据
|
// 2. 解析XML数据
|
||||||
Map<String, String> notifyData = xmlToMap(xmlData.toString());
|
Map<String, String> notifyData = xmlToMap(xmlData.toString());
|
||||||
|
|
||||||
// 3. 验证签名
|
// 3. 验证签名
|
||||||
if (!verifySign(notifyData, wechatApiKey)) {
|
if (!verifySign(notifyData, WECHAT_API_KEY)) {
|
||||||
return failResult("签名验证失败");
|
result.put("success", false);
|
||||||
|
result.put("responseXml", buildNotifyResponse(FAIL_CODE, "签名验证失败"));
|
||||||
|
result.put("message", "签名验证失败");
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 检查支付结果
|
// 4. 检查支付结果
|
||||||
if (!SUCCESS_CODE.equals(notifyData.get("return_code")) || !SUCCESS_CODE.equals(notifyData.get("result_code"))) {
|
if (!SUCCESS_CODE.equals(notifyData.get("return_code")) ||
|
||||||
return failResult("支付失败:" + notifyData.get("err_code_des"));
|
!SUCCESS_CODE.equals(notifyData.get("result_code"))) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("responseXml", buildNotifyResponse(FAIL_CODE, "支付失败"));
|
||||||
|
result.put("message", "支付失败:" + notifyData.get("err_code_des"));
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 构建支付信息
|
// 5. 构建支付信息
|
||||||
Map<String, Object> paymentInfo = new HashMap<>();
|
Map<String, Object> paymentInfo = new HashMap<>();
|
||||||
paymentInfo.put("transactionId", notifyData.get("transaction_id"));
|
paymentInfo.put("transactionId", notifyData.get("transaction_id"));
|
||||||
|
|
@ -235,12 +307,23 @@ public class WechatPayUtil {
|
||||||
paymentInfo.put("timeEnd", notifyData.get("time_end"));
|
paymentInfo.put("timeEnd", notifyData.get("time_end"));
|
||||||
paymentInfo.put("attach", notifyData.get("attach"));
|
paymentInfo.put("attach", notifyData.get("attach"));
|
||||||
paymentInfo.put("openid", notifyData.get("openid"));
|
paymentInfo.put("openid", notifyData.get("openid"));
|
||||||
|
|
||||||
|
// 6. 判断是否为代付订单
|
||||||
|
String orderNo = notifyData.get("out_trade_no");
|
||||||
|
boolean isPayFor = isPayForOrder(orderNo);
|
||||||
|
|
||||||
result.put("success", true);
|
result.put("success", true);
|
||||||
|
result.put("responseXml", buildNotifyResponse(SUCCESS_CODE, "OK"));
|
||||||
result.put("paymentInfo", paymentInfo);
|
result.put("paymentInfo", paymentInfo);
|
||||||
|
result.put("isPayFor", isPayFor);
|
||||||
result.put("message", "支付通知处理成功");
|
result.put("message", "支付通知处理成功");
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
result = failResult("处理支付通知异常:" + e.getMessage());
|
result.put("success", false);
|
||||||
|
result.put("responseXml", buildNotifyResponse(FAIL_CODE, "处理异常"));
|
||||||
|
result.put("message", "处理支付通知异常:" + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,7 +333,7 @@ public class WechatPayUtil {
|
||||||
* @param refundInfo 退款信息
|
* @param refundInfo 退款信息
|
||||||
* @return 退款结果
|
* @return 退款结果
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> refund(Map<String, Object> refundInfo) {
|
public static Map<String, Object> refund(Map<String, Object> refundInfo) {
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -266,7 +349,7 @@ public class WechatPayUtil {
|
||||||
Map<String, String> params = buildRefundParams(refundInfo);
|
Map<String, String> params = buildRefundParams(refundInfo);
|
||||||
|
|
||||||
// 3. 生成签名
|
// 3. 生成签名
|
||||||
String sign = generateSign(params, wechatApiKey);
|
String sign = generateSign(params, WECHAT_API_KEY);
|
||||||
params.put("sign", sign);
|
params.put("sign", sign);
|
||||||
|
|
||||||
// 4. 发送请求(需要证书)
|
// 4. 发送请求(需要证书)
|
||||||
|
|
@ -311,7 +394,7 @@ public class WechatPayUtil {
|
||||||
* @param transferInfo 付款信息
|
* @param transferInfo 付款信息
|
||||||
* @return 付款结果
|
* @return 付款结果
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> transferToUser(Map<String, Object> transferInfo) {
|
public static Map<String, Object> transferToUser(Map<String, Object> transferInfo) {
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -327,7 +410,7 @@ public class WechatPayUtil {
|
||||||
Map<String, String> params = buildTransferParams(transferInfo);
|
Map<String, String> params = buildTransferParams(transferInfo);
|
||||||
|
|
||||||
// 3. 生成签名
|
// 3. 生成签名
|
||||||
String sign = generateSign(params, wechatApiKey);
|
String sign = generateSign(params, WECHAT_API_KEY);
|
||||||
params.put("sign", sign);
|
params.put("sign", sign);
|
||||||
|
|
||||||
// 4. 发送请求(需要证书)
|
// 4. 发送请求(需要证书)
|
||||||
|
|
@ -365,149 +448,35 @@ public class WechatPayUtil {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===================== 工具方法和签名相关 =====================
|
// ========== 私有工具方法 ==========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建小程序端调起支付参数
|
* 验证统一下单参数
|
||||||
* @param prepayId 预支付交易会话标识
|
|
||||||
* @return 小程序端调起支付参数Map
|
|
||||||
*/
|
*/
|
||||||
private Map<String, Object> buildMiniProgramPayParams(String prepayId) {
|
private static String validateOrderParams(Map<String, Object> orderInfo) {
|
||||||
Map<String, Object> payParams = new HashMap<>();
|
if (orderInfo == null) return "订单信息不能为空";
|
||||||
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
|
if (orderInfo.get("orderNo") == null || orderInfo.get("orderNo").toString().trim().isEmpty()) {
|
||||||
String nonceStr = generateNonceStr();
|
return "订单号不能为空";
|
||||||
String packageStr = "prepay_id=" + prepayId;
|
|
||||||
String signType = "MD5";
|
|
||||||
// 构建签名参数
|
|
||||||
Map<String, String> signParams = new HashMap<>();
|
|
||||||
signParams.put("appId", wechatAppId);
|
|
||||||
signParams.put("timeStamp", timeStamp);
|
|
||||||
signParams.put("nonceStr", nonceStr);
|
|
||||||
signParams.put("package", packageStr);
|
|
||||||
signParams.put("signType", signType);
|
|
||||||
String paySign = generateSign(signParams, wechatApiKey);
|
|
||||||
payParams.put("timeStamp", timeStamp);
|
|
||||||
payParams.put("nonceStr", nonceStr);
|
|
||||||
payParams.put("package", packageStr);
|
|
||||||
payParams.put("signType", signType);
|
|
||||||
payParams.put("paySign", paySign);
|
|
||||||
return payParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成签名
|
|
||||||
* @param params 参数Map
|
|
||||||
* @param key API密钥
|
|
||||||
* @return 签名字符串
|
|
||||||
*/
|
|
||||||
private String generateSign(Map<String, String> params, String key) {
|
|
||||||
try {
|
|
||||||
Map<String, String> sortedParams = new TreeMap<>(params);
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
|
|
||||||
if (entry.getValue() != null && !entry.getValue().isEmpty() && !"sign".equals(entry.getKey())) {
|
|
||||||
stringBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stringBuilder.append("key=").append(key);
|
|
||||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
|
||||||
byte[] digest = md5.digest(stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
for (byte b : digest) {
|
|
||||||
result.append(String.format("%02X", b));
|
|
||||||
}
|
|
||||||
return result.toString();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("生成签名失败", e);
|
|
||||||
}
|
}
|
||||||
}
|
if (orderInfo.get("openid") == null || orderInfo.get("openid").toString().trim().isEmpty()) {
|
||||||
|
return "用户openid不能为空";
|
||||||
/**
|
|
||||||
* 验证签名
|
|
||||||
* @param params 参数Map
|
|
||||||
* @param key API密钥
|
|
||||||
* @return 是否验证通过
|
|
||||||
*/
|
|
||||||
private boolean verifySign(Map<String, String> params, String key) {
|
|
||||||
String sign = params.get("sign");
|
|
||||||
if (sign == null || sign.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
Map<String, String> paramsWithoutSign = new HashMap<>(params);
|
if (orderInfo.get("totalFee") == null) {
|
||||||
paramsWithoutSign.remove("sign");
|
return "支付金额不能为空";
|
||||||
String generatedSign = generateSign(paramsWithoutSign, key);
|
|
||||||
return sign.equals(generatedSign);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map转XML
|
|
||||||
* @param params 参数Map
|
|
||||||
* @return XML字符串
|
|
||||||
*/
|
|
||||||
private String mapToXml(Map<String, String> params) {
|
|
||||||
StringBuilder xml = new StringBuilder();
|
|
||||||
xml.append("<xml>");
|
|
||||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
|
||||||
xml.append("<").append(entry.getKey()).append("><![CDATA[")
|
|
||||||
.append(entry.getValue()).append("]]></").append(entry.getKey()).append(">");
|
|
||||||
}
|
}
|
||||||
xml.append("</xml>");
|
if (orderInfo.get("body") == null || orderInfo.get("body").toString().trim().isEmpty()) {
|
||||||
return xml.toString();
|
return "商品描述不能为空";
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* XML转Map(简化实现)
|
|
||||||
* @param xml XML字符串
|
|
||||||
* @return Map
|
|
||||||
*/
|
|
||||||
private Map<String, String> xmlToMap(String xml) {
|
|
||||||
Map<String, String> map = new HashMap<>();
|
|
||||||
try {
|
|
||||||
xml = xml.replaceAll("<xml>", "").replaceAll("</xml>", "");
|
|
||||||
String[] elements = xml.split("</\\w+>");
|
|
||||||
for (String element : elements) {
|
|
||||||
if (element.trim().isEmpty()) continue;
|
|
||||||
int startTag = element.indexOf("<");
|
|
||||||
int endTag = element.indexOf(">");
|
|
||||||
if (startTag >= 0 && endTag > startTag) {
|
|
||||||
String key = element.substring(startTag + 1, endTag);
|
|
||||||
String value = element.substring(endTag + 1);
|
|
||||||
if (value.startsWith("<![CDATA[") && value.endsWith("]]>")) {
|
|
||||||
value = value.substring(9, value.length() - 3);
|
|
||||||
}
|
|
||||||
map.put(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("XML解析失败", e);
|
|
||||||
}
|
}
|
||||||
return map;
|
if (orderInfo.get("notifyUrl") == null || orderInfo.get("notifyUrl").toString().trim().isEmpty()) {
|
||||||
}
|
return "回调地址不能为空";
|
||||||
|
}
|
||||||
/**
|
return null;
|
||||||
* 生成随机字符串
|
|
||||||
* @return 随机字符串
|
|
||||||
*/
|
|
||||||
private String generateNonceStr() {
|
|
||||||
return UUID.randomUUID().toString().replace("-", "").substring(0, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 统一失败返回结构
|
|
||||||
* @param msg 失败信息
|
|
||||||
* @return 标准失败结构
|
|
||||||
*/
|
|
||||||
private Map<String, Object> failResult(String msg) {
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
result.put("success", false);
|
|
||||||
result.put("message", msg);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证代付参数
|
* 验证代付参数
|
||||||
*/
|
*/
|
||||||
private String validatePayForParams(Map<String, Object> payForInfo) {
|
private static String validatePayForParams(Map<String, Object> payForInfo) {
|
||||||
if (payForInfo == null) return "代付信息不能为空";
|
if (payForInfo == null) return "代付信息不能为空";
|
||||||
if (payForInfo.get("orderNo") == null || payForInfo.get("orderNo").toString().trim().isEmpty()) {
|
if (payForInfo.get("orderNo") == null || payForInfo.get("orderNo").toString().trim().isEmpty()) {
|
||||||
return "原订单号不能为空";
|
return "原订单号不能为空";
|
||||||
|
|
@ -533,7 +502,7 @@ public class WechatPayUtil {
|
||||||
/**
|
/**
|
||||||
* 验证退款参数
|
* 验证退款参数
|
||||||
*/
|
*/
|
||||||
private String validateRefundParams(Map<String, Object> refundInfo) {
|
private static String validateRefundParams(Map<String, Object> refundInfo) {
|
||||||
if (refundInfo == null) return "退款信息不能为空";
|
if (refundInfo == null) return "退款信息不能为空";
|
||||||
if (refundInfo.get("orderNo") == null || refundInfo.get("orderNo").toString().trim().isEmpty()) {
|
if (refundInfo.get("orderNo") == null || refundInfo.get("orderNo").toString().trim().isEmpty()) {
|
||||||
return "订单号不能为空";
|
return "订单号不能为空";
|
||||||
|
|
@ -553,7 +522,7 @@ public class WechatPayUtil {
|
||||||
/**
|
/**
|
||||||
* 验证企业付款参数
|
* 验证企业付款参数
|
||||||
*/
|
*/
|
||||||
private String validateTransferParams(Map<String, Object> transferInfo) {
|
private static String validateTransferParams(Map<String, Object> transferInfo) {
|
||||||
if (transferInfo == null) return "付款信息不能为空";
|
if (transferInfo == null) return "付款信息不能为空";
|
||||||
if (transferInfo.get("partnerTradeNo") == null || transferInfo.get("partnerTradeNo").toString().trim().isEmpty()) {
|
if (transferInfo.get("partnerTradeNo") == null || transferInfo.get("partnerTradeNo").toString().trim().isEmpty()) {
|
||||||
return "商户订单号不能为空";
|
return "商户订单号不能为空";
|
||||||
|
|
@ -571,53 +540,38 @@ public class WechatPayUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建代付附加数据
|
* 构建统一下单参数
|
||||||
*/
|
*/
|
||||||
private String buildPayForAttach(Map<String, Object> payForInfo) {
|
private static Map<String, String> buildUnifiedOrderParams(Map<String, Object> orderInfo) {
|
||||||
JSONObject attach = new JSONObject();
|
Map<String, String> params = new HashMap<>();
|
||||||
attach.put("type", "payfor");
|
params.put("appid", WECHAT_APP_ID);
|
||||||
attach.put("originalOrderNo", payForInfo.get("orderNo"));
|
params.put("mch_id", WECHAT_MCH_ID);
|
||||||
attach.put("payerOpenid", payForInfo.get("payerOpenid"));
|
params.put("nonce_str", generateNonceStr());
|
||||||
attach.put("payeeOpenid", payForInfo.get("payeeOpenid"));
|
params.put("body", orderInfo.get("body").toString());
|
||||||
if (payForInfo.get("remark") != null) {
|
params.put("out_trade_no", orderInfo.get("orderNo").toString());
|
||||||
attach.put("remark", payForInfo.get("remark"));
|
params.put("total_fee", orderInfo.get("totalFee").toString());
|
||||||
|
params.put("spbill_create_ip", "127.0.0.1");
|
||||||
|
params.put("notify_url", orderInfo.get("notifyUrl").toString());
|
||||||
|
params.put("trade_type", TRADE_TYPE_JSAPI);
|
||||||
|
params.put("openid", orderInfo.get("openid").toString());
|
||||||
|
|
||||||
|
if (orderInfo.get("attach") != null) {
|
||||||
|
params.put("attach", orderInfo.get("attach").toString());
|
||||||
|
}
|
||||||
|
if (orderInfo.get("timeExpire") != null) {
|
||||||
|
params.put("time_expire", orderInfo.get("timeExpire").toString());
|
||||||
}
|
}
|
||||||
return attach.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
return params;
|
||||||
* 生成代付订单号
|
|
||||||
*/
|
|
||||||
private String generatePayForOrderNo(String originalOrderNo) {
|
|
||||||
return "PF" + originalOrderNo + System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否为代付订单
|
|
||||||
*/
|
|
||||||
private boolean isPayForOrder(String orderNo) {
|
|
||||||
return orderNo != null && orderNo.startsWith("PF");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建通知响应XML
|
|
||||||
*/
|
|
||||||
private String buildNotifyResponse(String returnCode, String returnMsg) {
|
|
||||||
StringBuilder xml = new StringBuilder();
|
|
||||||
xml.append("<xml>");
|
|
||||||
xml.append("<return_code><![CDATA[").append(returnCode).append("]]></return_code>");
|
|
||||||
xml.append("<return_msg><![CDATA[").append(returnMsg).append("]]></return_msg>");
|
|
||||||
xml.append("</xml>");
|
|
||||||
return xml.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建退款参数
|
* 构建退款参数
|
||||||
*/
|
*/
|
||||||
private Map<String, String> buildRefundParams(Map<String, Object> refundInfo) {
|
private static Map<String, String> buildRefundParams(Map<String, Object> refundInfo) {
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put("appid", wechatAppId);
|
params.put("appid", WECHAT_APP_ID);
|
||||||
params.put("mch_id", wechatMchId);
|
params.put("mch_id", WECHAT_MCH_ID);
|
||||||
params.put("nonce_str", generateNonceStr());
|
params.put("nonce_str", generateNonceStr());
|
||||||
params.put("out_trade_no", refundInfo.get("orderNo").toString());
|
params.put("out_trade_no", refundInfo.get("orderNo").toString());
|
||||||
params.put("out_refund_no", refundInfo.get("refundNo").toString());
|
params.put("out_refund_no", refundInfo.get("refundNo").toString());
|
||||||
|
|
@ -637,10 +591,10 @@ public class WechatPayUtil {
|
||||||
/**
|
/**
|
||||||
* 构建企业付款参数
|
* 构建企业付款参数
|
||||||
*/
|
*/
|
||||||
private Map<String, String> buildTransferParams(Map<String, Object> transferInfo) {
|
private static Map<String, String> buildTransferParams(Map<String, Object> transferInfo) {
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put("mch_appid", wechatAppId);
|
params.put("mch_appid", WECHAT_APP_ID);
|
||||||
params.put("mchid", wechatMchId);
|
params.put("mchid", WECHAT_MCH_ID);
|
||||||
params.put("nonce_str", generateNonceStr());
|
params.put("nonce_str", generateNonceStr());
|
||||||
params.put("partner_trade_no", transferInfo.get("partnerTradeNo").toString());
|
params.put("partner_trade_no", transferInfo.get("partnerTradeNo").toString());
|
||||||
params.put("openid", transferInfo.get("openid").toString());
|
params.put("openid", transferInfo.get("openid").toString());
|
||||||
|
|
@ -656,4 +610,178 @@ public class WechatPayUtil {
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建小程序支付参数
|
||||||
|
*/
|
||||||
|
private static Map<String, Object> buildMiniProgramPayParams(String prepayId) {
|
||||||
|
Map<String, Object> payParams = new HashMap<>();
|
||||||
|
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
|
||||||
|
String nonceStr = generateNonceStr();
|
||||||
|
String packageStr = "prepay_id=" + prepayId;
|
||||||
|
String signType = "MD5";
|
||||||
|
|
||||||
|
// 构建签名参数
|
||||||
|
Map<String, String> signParams = new HashMap<>();
|
||||||
|
signParams.put("appId", WECHAT_APP_ID);
|
||||||
|
signParams.put("timeStamp", timeStamp);
|
||||||
|
signParams.put("nonceStr", nonceStr);
|
||||||
|
signParams.put("package", packageStr);
|
||||||
|
signParams.put("signType", signType);
|
||||||
|
|
||||||
|
String paySign = generateSign(signParams, WECHAT_API_KEY);
|
||||||
|
|
||||||
|
payParams.put("timeStamp", timeStamp);
|
||||||
|
payParams.put("nonceStr", nonceStr);
|
||||||
|
payParams.put("package", packageStr);
|
||||||
|
payParams.put("signType", signType);
|
||||||
|
payParams.put("paySign", paySign);
|
||||||
|
|
||||||
|
return payParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建代付附加数据
|
||||||
|
*/
|
||||||
|
private static String buildPayForAttach(Map<String, Object> payForInfo) {
|
||||||
|
JSONObject attach = new JSONObject();
|
||||||
|
attach.put("type", "payfor");
|
||||||
|
attach.put("originalOrderNo", payForInfo.get("orderNo"));
|
||||||
|
attach.put("payerOpenid", payForInfo.get("payerOpenid"));
|
||||||
|
attach.put("payeeOpenid", payForInfo.get("payeeOpenid"));
|
||||||
|
if (payForInfo.get("remark") != null) {
|
||||||
|
attach.put("remark", payForInfo.get("remark"));
|
||||||
|
}
|
||||||
|
return attach.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成代付订单号
|
||||||
|
*/
|
||||||
|
private static String generatePayForOrderNo(String originalOrderNo) {
|
||||||
|
return "PF" + originalOrderNo + System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为代付订单
|
||||||
|
*/
|
||||||
|
private static boolean isPayForOrder(String orderNo) {
|
||||||
|
return orderNo != null && orderNo.startsWith("PF");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建通知响应XML
|
||||||
|
*/
|
||||||
|
private static String buildNotifyResponse(String returnCode, String returnMsg) {
|
||||||
|
StringBuilder xml = new StringBuilder();
|
||||||
|
xml.append("<xml>");
|
||||||
|
xml.append("<return_code><![CDATA[").append(returnCode).append("]]></return_code>");
|
||||||
|
xml.append("<return_msg><![CDATA[").append(returnMsg).append("]]></return_msg>");
|
||||||
|
xml.append("</xml>");
|
||||||
|
return xml.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成随机字符串
|
||||||
|
*/
|
||||||
|
private static String generateNonceStr() {
|
||||||
|
return UUID.randomUUID().toString().replace("-", "").substring(0, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成签名
|
||||||
|
*/
|
||||||
|
private static String generateSign(Map<String, String> params, String key) {
|
||||||
|
try {
|
||||||
|
// 1. 排序参数
|
||||||
|
Map<String, String> sortedParams = new TreeMap<>(params);
|
||||||
|
|
||||||
|
// 2. 拼接参数
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
|
||||||
|
if (entry.getValue() != null && !entry.getValue().isEmpty() && !"sign".equals(entry.getKey())) {
|
||||||
|
stringBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stringBuilder.append("key=").append(key);
|
||||||
|
|
||||||
|
// 3. MD5加密
|
||||||
|
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] digest = md5.digest(stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
// 4. 转换为大写16进制字符串
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
for (byte b : digest) {
|
||||||
|
result.append(String.format("%02X", b));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toString();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("生成签名失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证签名
|
||||||
|
*/
|
||||||
|
private static boolean verifySign(Map<String, String> params, String key) {
|
||||||
|
String sign = params.get("sign");
|
||||||
|
if (sign == null || sign.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> paramsWithoutSign = new HashMap<>(params);
|
||||||
|
paramsWithoutSign.remove("sign");
|
||||||
|
|
||||||
|
String generatedSign = generateSign(paramsWithoutSign, key);
|
||||||
|
return sign.equals(generatedSign);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map转XML
|
||||||
|
*/
|
||||||
|
private static String mapToXml(Map<String, String> params) {
|
||||||
|
StringBuilder xml = new StringBuilder();
|
||||||
|
xml.append("<xml>");
|
||||||
|
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||||
|
xml.append("<").append(entry.getKey()).append("><![CDATA[")
|
||||||
|
.append(entry.getValue()).append("]]></").append(entry.getKey()).append(">");
|
||||||
|
}
|
||||||
|
xml.append("</xml>");
|
||||||
|
return xml.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML转Map(简化实现)
|
||||||
|
*/
|
||||||
|
private static Map<String, String> xmlToMap(String xml) {
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
try {
|
||||||
|
// 简化的XML解析实现
|
||||||
|
xml = xml.replaceAll("<xml>", "").replaceAll("</xml>", "");
|
||||||
|
String[] elements = xml.split("</\\w+>");
|
||||||
|
|
||||||
|
for (String element : elements) {
|
||||||
|
if (element.trim().isEmpty()) continue;
|
||||||
|
|
||||||
|
int startTag = element.indexOf("<");
|
||||||
|
int endTag = element.indexOf(">");
|
||||||
|
if (startTag >= 0 && endTag > startTag) {
|
||||||
|
String key = element.substring(startTag + 1, endTag);
|
||||||
|
String value = element.substring(endTag + 1);
|
||||||
|
|
||||||
|
// 处理CDATA
|
||||||
|
if (value.startsWith("<![CDATA[") && value.endsWith("]]>")) {
|
||||||
|
value = value.substring(9, value.length() - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("XML解析失败", e);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package com.ruoyi.system.domain.AppleDoMain;
|
|
||||||
|
|
||||||
|
|
||||||
public class TemplateData {
|
|
||||||
|
|
||||||
private String value;//
|
|
||||||
|
|
||||||
public TemplateData(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
package com.ruoyi.system.domain.AppleDoMain;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class WxMssVo {
|
|
||||||
private String touser;//用户openid
|
|
||||||
private String template_id;//订阅消息模版id
|
|
||||||
private String page = "pages/index/index";//默认跳到小程序首页
|
|
||||||
private Map<String, TemplateData> data;//推送文字
|
|
||||||
|
|
||||||
public String getTouser() {
|
|
||||||
return touser;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTouser(String touser) {
|
|
||||||
this.touser = touser;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTemplate_id() {
|
|
||||||
return template_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTemplate_id(String template_id) {
|
|
||||||
this.template_id = template_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPage() {
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPage(String page) {
|
|
||||||
this.page = page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, TemplateData> getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(Map<String, TemplateData> data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -19,13 +19,7 @@ public interface OrderLogMapper
|
||||||
*/
|
*/
|
||||||
public OrderLog selectOrderLogById(Long id);
|
public OrderLog selectOrderLogById(Long id);
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询最新一条日志记录
|
|
||||||
*
|
|
||||||
* @param oid 订单服务记录主键
|
|
||||||
* @return 订单服务记录
|
|
||||||
*/
|
|
||||||
public OrderLog selectDataTheFirstNew(Long oid);
|
|
||||||
public int selectCountOrderLogByOrderId(String orderId);
|
public int selectCountOrderLogByOrderId(String orderId);
|
||||||
|
|
||||||
public List<OrderLog> selectOrderLogByOrderId(String orderId);
|
public List<OrderLog> selectOrderLogByOrderId(String orderId);
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,6 @@ public interface IOrderLogService
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询最新一条日志记录
|
|
||||||
*
|
|
||||||
* @param oid 订单服务记录主键
|
|
||||||
* @return 订单服务记录
|
|
||||||
*/
|
|
||||||
public OrderLog selectDataTheFirstNew(Long oid);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询订单服务记录数量
|
* 查询订单服务记录数量
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -32,18 +32,6 @@ public class OrderLogServiceImpl implements IOrderLogService
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询最新一条日志记录
|
|
||||||
*
|
|
||||||
* @param oid 订单服务记录主键
|
|
||||||
* @return 订单服务记录
|
|
||||||
*/
|
|
||||||
public OrderLog selectDataTheFirstNew(Long oid) {
|
|
||||||
return orderLogMapper.selectDataTheFirstNew(oid);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询订单服务记录数量
|
* 查询订单服务记录数量
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -81,12 +81,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<select id="selectDataTheFirstNew" parameterType="Long" resultMap="OrderLogResult">
|
|
||||||
<include refid="selectOrderLogVo"/>
|
|
||||||
where oid = #{oid}
|
|
||||||
ORDER BY created_at DESC LIMIT 1;
|
|
||||||
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<select id="selectOrderLogByOrderId" parameterType="String" resultMap="OrderLogResult">
|
<select id="selectOrderLogByOrderId" parameterType="String" resultMap="OrderLogResult">
|
||||||
select * from order_log where order_id = #{orderId} order by id DESC
|
select * from order_log where order_id = #{orderId} order by id DESC
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
v-model="loginForm.username"
|
v-model="loginForm.username"
|
||||||
type="text"
|
type="text"
|
||||||
auto-complete="off"
|
auto-complete="off"
|
||||||
size="medium"
|
|
||||||
placeholder="账号"
|
placeholder="账号"
|
||||||
>
|
>
|
||||||
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
|
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
|
||||||
|
|
@ -19,7 +18,6 @@
|
||||||
type="password"
|
type="password"
|
||||||
auto-complete="off"
|
auto-complete="off"
|
||||||
placeholder="密码"
|
placeholder="密码"
|
||||||
size="medium"
|
|
||||||
@keyup.enter.native="handleLogin"
|
@keyup.enter.native="handleLogin"
|
||||||
>
|
>
|
||||||
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
|
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
|
||||||
|
|
@ -46,7 +44,6 @@
|
||||||
size="medium"
|
size="medium"
|
||||||
type="primary"
|
type="primary"
|
||||||
style="width:100%;"
|
style="width:100%;"
|
||||||
class="submit"
|
|
||||||
@click.native.prevent="handleLogin"
|
@click.native.prevent="handleLogin"
|
||||||
>
|
>
|
||||||
<span v-if="!loading">登 录</span>
|
<span v-if="!loading">登 录</span>
|
||||||
|
|
@ -59,7 +56,7 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
<!-- 底部 -->
|
<!-- 底部 -->
|
||||||
<div class="el-login-footer">
|
<div class="el-login-footer">
|
||||||
|
<span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -159,7 +156,7 @@ export default {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style rel="stylesheet/scss" lang="scss">
|
||||||
.login {
|
.login {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
@ -180,19 +177,16 @@ export default {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
padding: 25px 25px 5px 25px;
|
padding: 25px 25px 5px 25px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
.el-input {
|
||||||
|
height: 38px;
|
||||||
|
input {
|
||||||
|
height: 38px;
|
||||||
|
}
|
||||||
|
}
|
||||||
.input-icon {
|
.input-icon {
|
||||||
height: 46px;
|
height: 39px;
|
||||||
width: 14px;
|
width: 14px;
|
||||||
margin-left: 10px;
|
margin-left: 2px;
|
||||||
}
|
|
||||||
.submit{
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
::v-deep .el-input__inner {
|
|
||||||
line-height: 46px !important;
|
|
||||||
height: 46px !important;
|
|
||||||
padding-left: 40px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.login-tip {
|
.login-tip {
|
||||||
|
|
@ -202,7 +196,7 @@ export default {
|
||||||
}
|
}
|
||||||
.login-code {
|
.login-code {
|
||||||
width: 33%;
|
width: 33%;
|
||||||
height: 46px;
|
height: 38px;
|
||||||
float: right;
|
float: right;
|
||||||
img {
|
img {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
@ -222,6 +216,6 @@ export default {
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
.login-code-img {
|
.login-code-img {
|
||||||
height: 46px;
|
height: 38px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue