商城相关功能代码移植

This commit is contained in:
纪寒 2023-10-16 15:00:16 +08:00
parent fe9f8865eb
commit 8af9f2edf8
30 changed files with 912 additions and 955 deletions

View File

@ -36,6 +36,7 @@
<lombok.version>1.18.4</lombok.version>
<knife4j.version>3.0.3</knife4j.version>
<simple-xml.version>2.7.1</simple-xml.version>
<wechatpay-apiv3.version>0.4.4</wechatpay-apiv3.version>
</properties>
<!-- 依赖声明 -->
@ -235,6 +236,13 @@
<artifactId>simple-xml</artifactId>
<version>${simple-xml.version}</version>
</dependency>
<!-- 微信支付SDK -->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>${wechatpay-apiv3.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -274,21 +274,6 @@ applet-chat-config:
# 微信小程序事件回调消息加密密钥
encoding-aes-key: 5rbyhMBpdnxTEVT54zeHMNcXi3ccilQZ209QqGi89EW
# 护理员微信小程序参数配置信息
nurse-applet-chat-config:
# 微信小程序idwxa4f2b43d2ccb9908
applet-id: wxa4f2b43d2ccb9908
# 微信小程序密钥,
secret: faeba9fc043cfdcb088f43be1747e054
# 微信小程序返回国家语言
lang: zh_CN
# 微信小程序授权类型
grant-type: authorization_code
# 微信小程序事件回调令牌
token: Yw3vfW1ILpc34qAVDtTpB2hesAMCpvW0
# 微信小程序事件回调消息加密密钥
encoding-aes-key: Lr2uq0F3ds36ZA4AUv1h3Pki0JO1Ql0QeG0z1r4A3at
# 小程序首页路径
applet-page-config:
# 首页跳转路径
@ -303,3 +288,37 @@ applet-page-config:
integral-page-url: pages/integral/integral
# 护理结构详情页面跳转路径
nursestation-details-page-url: pages/nursestation/nursestation
# 新医路微信商户号配置参数
xyl-we-chat-config:
xyl-mch-id: 1633348407
xyl-mch-serial-no: 7C6A18FC8E1F0445901B1BE1C4DD1ACE284C3D79
xyl-private-key-path: xinyilu_apiclient_key.pem
xyl-payment-key: Xyl699003981qazVFR4xsw23edcASDFG
xyl-wechat-notify-url: https://1608.xinelu.cn
# 医路优品微信商户号配置参数
ylyp-we-chat-config:
ylyp-mch-id: 1633506981
ylyp-mch-serial-no: 7840E8CE4B9B1F0F19D5DD2AB7BC159E007F9D90
ylyp-private-key-path: yiluyoupin_apiclient_key.pem
ylyp-payment-key: Xyk699003981qazxsw23edcvfr4bgt56
ylyp-we-chat-notify-url: https://1608.xinelu.cn
# 微信支付接口地址包含小程序和App支付接口地址
we-chat-payment-url-config:
jsapi-palce-order-url: https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi
query-order-no-url: https://api.mch.weixin.qq.com/v3/pay/transactions/id/%s
query-mch-id-url: https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s
close-order-url: https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s/close
refund-apply-url: https://api.mch.weixin.qq.com/v3/refund/domestic/refunds
refund-query-order-url: https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/%s
trade-apply-bill-url: https://api.mch.weixin.qq.com/v3/bill/tradebill
capital-apply-bill-url: https://api.mch.weixin.qq.com/v3/bill/fundflowbill
app-place-order-url: https://api.mch.weixin.qq.com/v3/pay/transactions/app
# 快递鸟物流查询参数配置
logistics-config:
e-business-id: 1781371
api-key: 998b273d-c926-4659-a9d5-ae0613782d70
express-bird-url: https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDFgFmuT17PjBIN
B0wSGnchCCsB9ZRZZFpcpvBpO+VLspmTSM//zV621uTzZeWNONEBzwO4C7VCsbHW
gu7R5AQj9FYSzTKdycvs+097qQcQAvMr3VwrX0/dtH2U0iFX6zr3ztDKv2eQBegu
wEcZsoOEgEW1rsjs/t2MTJJLPYWfzDDUbDBJi2hKFzSGAPfpqeOz0+loKNUz/i7V
/dg5TXlbWfe0gdf4SI04sdrUkNsbQKabc7hWoPSVaRnX4ywfgzW8fHaIP+vuTzHr
p7h5dnFNUuA5CdobDnIl0sz+ekLfCFuX4pCYNE6uR/58uknmXW0jfrK/WPU5T+F7
sGDIsuJHAgMBAAECggEADIrkJx+/Q6r/kng+KoAnxJ9CK/OuoiavXmbzqZs2KqKD
AkmDfBlMxIvNKm/0Lg3HqDe/YrbLohqq0paqGAZFBQuFU9hYOJESNFCZcZ8AZdHq
I4UBT3fUGJ5Xw1W87Fpx+j7WH6ocJ5dYcW+glE8z7vw+cRVSiUp+Q2SxfbnAfK9c
anqJLWA8pxkGRcXzE/tcB4JAkPsluWslFPDeKVOZ5/NRs8oE5ppmQKxqx2KFK7rh
S0irhlJ/6t1jiI3t+syYXJILwbutJ9PUFaS1Uu3CErcvmBwWiLRZEkNa7xMlzEk+
R2dplVhT0W++Ku1cjtU4q7V+paea+/YZj3mtos45YQKBgQDsFc4KM8/Lm146dNJX
TOK1pDjZD5rfEpgtHCEm6dBRbueOYjb/D1Lo/JU4L6Yl2fGsJNtTX4a8i38nxTuI
6b+SEQoLinEyr8JQtBFMvU4vYOIiA5oCHaZIXn0WLLFbUBkOhq/dXC4xDT6MOyNd
2rDTSwvLqVE8K8sbupcvRP/RLwKBgQDWKVayVKGHz3cT+YyPhGTD19yBM0w6AGBR
MLNKdKek7/BnKXe009fxDg/gCtGUBmE+umFbEBLStg7zD31JXLm5/LyT2NBkJYRl
neO9UW8tWbnL6DOGgNvQTqDN650Od39R8rVoRSH4H4az6A/B1qrJReyrGw7xDXOz
0eAq9vnKaQKBgH1IDPDJEepAZr6qo7yEJoKxxSEa8NqT6YF2vfkCdvPf4K1kXT75
CMxuzVjloEvR3je1z1XtCXkgpbebKL69HFYNCMGbE/sL3hgplkyc4NKvnRDjzGR3
C3i3+7U6vltwo/tbahQUCMcq+hg8gcYaeV+HIZlQHrXJn5z1ZalF+mMtAoGAKVgZ
sJu+A2X96xFGHX7FpTlLDHZGxPvFnGb2de1HYAQiOQg8X+B108ePMQVlqFoC9AUv
PlFAEQWspSfcXAlWoZ01GqXEtVC42pU8nhPWjr6/q6nMKK8/wFstmBNgYqaXIc7l
TpfqEuijLKAkSpuSpQCmy/GRVN/v8ksWJ7U+S+ECgYB+e/GAdxHOdMGOFbrqZ3Dx
jmPshaFFj/3UEsBZ6lBBTbdlMI7wFrSsqxCe1KGh0yG2GnOXE2useggeJyDVuaEY
7/CNalD9w158WS9Zb7pPOm6QQpKUeIEXvpQbKi6FjKZKaFlUDk2auFT+d1lOga0T
QRowjmcym1p+moKlqdiXGw==
-----END PRIVATE KEY-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3rkr2Mp+Xb31y
xfTOJPSmjQkG5/Eko6cyJcb8e6fGrrtsPVM9kExpVIor61oWTS1gyKYLwCQ92xmh
qjKtazzd6KvqjKdxFknxxH9R1L+n7LnSEfK2KNaxIL17h2vdXOJatuinX0+7A9Ct
5ZnKb5O5HVctQH0xCca6C6yyuF0q11BFquKyGPVwhqVwQnt+qIeQ/VCKFD5AYf1r
ebkaHwKCg0rbzPFWeZfVI0z3j6M71DLxdIHV40xDn31ygQYlBeuTOUxFvKnri8m+
BalcSUhocS9VAIyuPyDXCAdujm3hKz/WgqVtvgB3OOiIeGVppbgDlW+JWgR7lizM
TzMYfhjPAgMBAAECggEBAJbB6SjVOAO1MEOpklo4Hs0saMJQUK3/3FTeiMnmPDho
ZdBbLR0UeILjLl0J2HEBe0M6rH5sf9J9KDZ2WQ3ZPKXuOFxUgYHiB2L2IoHpmjyb
oZB3xrwYHM5Yzuy6o5+Wgvptsdrd8bTPVtHD50wt9BM1r72mdppvKbq9pksx4tYr
apw4WXfjO2zbdOngY4T5pCk5NZgXrlBfY0/vXsP/3SR+52KXGre/lSt35A4SjNe6
voI1vZLDNlqzRaEZqBC0tLyvMH3NaYpRhwyEHtoABE9AQvVaQNt+fN1qhbhjtVdQ
lR64Dqdc6jjIhuUhs1umYswf2umA3duZox8RTLZo1UECgYEA4oM2gLsX7dVNiDI4
bZsMBdm8cb+N3/npiZBlDL9UL4tWCzLQP8sR/HJH3OZHQ1iLk+7QXi2g0YR5VtNx
tLvECK1+Cd3sGt2zyFcrSpeYAnvbsMqB9F/K3grCCnvzKKmHJS27c9EVGr+sRTbx
6hSqQyEAYTP1yRLnLVmWzkCBXh8CgYEAz5eqFmfou3U7B04tK739HTJGAaHTxVAR
C4u4x0HGUP+NhPKZzySc70vWHoNgyP/QBUgzf5gTEnGCJ7Rk6Y2YZxCLyPksEDFc
meW9ENSOQMwTWM1PAF+XLr4wXbyojMqlI7vWimTMOPK7WMVt4jYCoaN9lBS+McYj
e1ZpB5yEj1ECgYEAiSXLXVxq2604GYvW0L59JBm22OSTwZZuycUs+e/qyDLEcVld
8BJDnKeRTXX8lhFJydNiRHO6GMHuOh0ijrzVsC9jzhOZvpaYIWhuJObuuipGVZ/3
2YAatCCtZm2wR+GFm4Q6KKDi92QwqWPgS8whXy3fLfupCQsyACprfgxeiB8CgYBF
pfjm843d9wMK/GujVWbquMdMHONUO/y8BvDDyYmj+1mb1VlNaldM4gDA1AtQ5KMC
YqsEkB01/udQMvH4eg075w0/LHpgJG+RIsdAMlBX5SBIlvl+gpPSlvTbPkS+l+64
AnmEjTUHlkjNC9BGKSDQ4m1rlVoKkROuedtbNmQzQQKBgQCQdmmWy2Nr9NRmy5+r
3FKymUVGujww+R7IiFGnFiBBhec8hUPaBp1xG5d8XVIcLt6nleOX5ZunXBwTOmp6
XH6tQuup+hjFiNpRLmbVkTv8uQVy5sWEqiGp0i7Jhb+0QEOSEshOr8sQDDAFwWXl
FyCbC1amAeC1i1knzGrNOdppUw==
-----END PRIVATE KEY-----

View File

@ -0,0 +1,23 @@
package com.xinelu.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @Description 快递鸟物流接口配置参数类
* @Author 纪寒
* @Date 2022-11-01 13:30:47
* @Version 1.0
*/
@Data
@Component
@ConfigurationProperties(prefix = "logistics-config")
public class LogisticsConfig {
private String eBusinessId;
private String apiKey;
private String expressBirdUrl;
}

View File

@ -1,79 +0,0 @@
package com.xinelu.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 护理员小程序配置类
*
* @author ljh
* @version 1.0
* Create by 2023/3/29 15:40
*/
@Data
@Component
@ConfigurationProperties(prefix = "nurse-applet-chat-config")
public class NurseAppletChatConfig {
/**
* 小程序id
*/
private String appletId;
/**
* 小程序secret
*/
private String secret;
/**
* 返回国家地区语言版本zh_CN 简体zh_TW 繁体en 英语
*/
private String lang;
/**
* 授权类型
*/
private String grantType;
/**
* 微信小程序事件回调令牌
*/
private String token;
/**
* 微信小程序事件回调消息加密密钥
*/
private String encodingAesKey;
/**
* 护理站运营人员-服务派单通知-模板id
*/
private String serviceDispatchOperationsTemplateId;
/**
* 护理站运营人员-接单提醒-模板id
*/
private String receivingOrdersOperationsTemplateId;
/**
* 护理站运营人员-师傅拒绝接单通知-模板id
*/
private String refusalOrdersOperationsTemplateId;
/**
* 护理站运营人员和护理员-订单回池通知-模板id
*/
private String overtimeOrdersOperationsTemplateId;
/**
* 护理站运营人员-订单完成通知-模板id
*/
private String orderCompletionOperationsTemplateId;
/**
* 护理员-接单提醒-模板id
*/
private String receivingOrdersNurseTemplateId;
}

View File

@ -0,0 +1,35 @@
package com.xinelu.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @Description 微信支付接口地址
* @Author 纪寒
* @Date 2022-10-17 17:56:25
* @Version 1.0
*/
@Component
@Data
@ConfigurationProperties(prefix = "we-chat-payment-url-config")
public class WeChatPaymentUrlConfig {
private String jsapiPalceOrderUrl;
private String queryOrderNoUrl;
private String queryMchIdUrl;
private String closeOrderUrl;
private String refundApplyUrl;
private String refundQueryOrderUrl;
private String tradeApplyBillUrl;
private String capitalApplyBillUrl;
private String appPlaceOrderUrl;
}

View File

@ -0,0 +1,27 @@
package com.xinelu.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @Description 新医路商户号微信支付参数配置类
* @Author 纪寒
* @Date 2022-10-17 16:55:04
* @Version 1.0
*/
@Data
@Component
@ConfigurationProperties(prefix = "xyl-we-chat-config")
public class XylWeChatPaymentConfig {
private String xylMchId;
private String xylMchSerialNo;
private String xylPrivateKeyPath;
private String xylPaymentKey;
private String xylWeChatNotifyUrl;
}

View File

@ -0,0 +1,27 @@
package com.xinelu.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @Description 医路优品商户号微信支付参数配置类
* @Author 纪寒
* @Date 2022-10-17 16:55:04
* @Version 1.0
*/
@Data
@Component
@ConfigurationProperties(prefix = "ylyp-we-chat-config")
public class YlypWeChatPaymentConfig {
private String ylypMchId;
private String ylypMchSerialNo;
private String ylypPrivateKeyPath;
private String ylypPaymentKey;
private String ylypWeChatNotifyUrl;
}

View File

@ -1,7 +1,6 @@
package com.xinelu.familydoctor.applet.utils;
import com.xinelu.common.config.AppletChatConfig;
import com.xinelu.common.config.NurseAppletChatConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.entity.AppletAccessToken;
import com.xinelu.common.exception.ServiceException;
@ -27,8 +26,7 @@ public class AppletAccessTokenUtils {
private RedisTemplate<String, Object> redisTemplate;
@Resource
private AppletChatConfig appletChatConfig;
@Resource
private NurseAppletChatConfig nurseAppletChatConfig;
/**
* 返回成功状态码
*/
@ -65,34 +63,4 @@ public class AppletAccessTokenUtils {
return accessToken;
}
/**
* 护理员小程序获取小程序AccessToken方法
*
* @return 小程序的AccessToken
*/
public String getPersonAppletAccessToken() {
String accessToken;
String accessTokenKey = Constants.NURSE_STATION_PERSON_APPLET_ACCESS_TOKEN + "accessToken";
//从Redis中取出accessToken
Object object = redisTemplate.opsForValue().get(accessTokenKey);
if (Objects.isNull(object)) {
//没有获取accessToken
AppletAccessToken appletAccessToken = AppletChatUtil.getAppletAccessToken(nurseAppletChatConfig.getAppletId(), nurseAppletChatConfig.getSecret());
if (Objects.isNull(appletAccessToken)) {
throw new ServiceException("获取微信小程序accessToken信息失败");
}
if (Objects.nonNull(appletAccessToken.getErrcode()) && appletAccessToken.getErrcode() != SUCCESS_CODE) {
throw new ServiceException("获取微信小程序accessToken信息失败失败信息为" + appletAccessToken.getErrmsg(), 201);
}
if (StringUtils.isBlank(appletAccessToken.getAccessToken())) {
throw new ServiceException("accessToken信息为空");
}
//存入Redis中
redisTemplate.opsForValue().set(accessTokenKey, appletAccessToken.getAccessToken(), 3600, TimeUnit.SECONDS);
accessToken = appletAccessToken.getAccessToken();
} else {
accessToken = (String) object;
}
return accessToken;
}
}

View File

@ -78,6 +78,11 @@
<version>${knife4j.version}</version>
</dependency>
<!-- 微信支付SDK -->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -26,7 +26,6 @@ public class AsyncExecutorConfig {
*/
@Bean
public Executor asyncThreadServiceExecutor() {
log.info("异步线程池配置执行");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);

View File

@ -0,0 +1,97 @@
package com.xinelu.framework.config;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.xinelu.common.config.XylWeChatPaymentConfig;
import com.xinelu.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
/**
* @Description 新医路商户号微信支付核心配置类
* @Author 纪寒
* @Date 2022-10-17 18:56:22
* @Version 1.0
*/
@Configuration
@Slf4j
public class XylWeChatPaymentUtilConfig {
@Resource
private XylWeChatPaymentConfig xylWeChatPaymentConfig;
/**
* 获取新医路签名信息
*
* @return 签名信息
* @throws Exception 异常信息
*/
@Bean(name = "xylVerifier")
public Verifier getXylVerifier() throws Exception {
PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath());
PrivateKeySigner privateKeySigner = new PrivateKeySigner(xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey);
WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(xylWeChatPaymentConfig.getXylMchId(), privateKeySigner);
CertificatesManager certificatesManager = CertificatesManager.getInstance();
certificatesManager.putMerchant(xylWeChatPaymentConfig.getXylMchId(), wechatPay2Credentials, xylWeChatPaymentConfig.getXylPaymentKey().getBytes(StandardCharsets.UTF_8));
return certificatesManager.getVerifier(xylWeChatPaymentConfig.getXylMchId());
}
/**
* 获取新医路商户号带有签名的http请求对象
*
* @return CloseableHttpClient对象
*/
@Bean(name = "xinYiLuWeChatPayClient")
public CloseableHttpClient getXinYiLuWeChatPayClient(Verifier xylVerifier) {
PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath());
CloseableHttpClient closeableHttpClient = null;
try {
closeableHttpClient = WechatPayHttpClientBuilder.create()
.withMerchant(xylWeChatPaymentConfig.getXylMchId(), xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey)
.withValidator(new WechatPay2Validator(xylVerifier)).build();
} catch (Exception e) {
log.error("新医路验证签名信息失败,失败信息:{}", e.getMessage());
}
return closeableHttpClient;
}
/**
* 获取新医路商户号无签名的http请求对象
*
* @return CloseableHttpClient对象
*/
@Bean(name = "xinYiLuWeChatPayNoSignClient")
public CloseableHttpClient getXinYiLuWeChatPayNoSignClient() {
PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath());
return WechatPayHttpClientBuilder.create()
.withMerchant(xylWeChatPaymentConfig.getXylMchId(), xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey)
.withValidator((response) -> true).build();
}
/**
* 获取商户的私钥文件
*
* @param filename 获取商户的私钥文件
* @return 商户私钥
*/
private PrivateKey getPrivateKey(String filename) {
try {
return PemUtil.loadPrivateKey(new ClassPathResource(filename).getInputStream());
} catch (Exception e) {
log.error("新医路商户私钥文件不存在,错误原因:{}", e.getMessage());
throw new ServiceException("新医路商户私钥文件不存在,请联系管理员!");
}
}
}

View File

@ -0,0 +1,97 @@
package com.xinelu.framework.config;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.xinelu.common.config.YlypWeChatPaymentConfig;
import com.xinelu.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
/**
* @Description 医路优品微信支付核心配置类
* @Author 纪寒
* @Date 2022-10-17 18:56:22
* @Version 1.0
*/
@Configuration
@Slf4j
public class YlypWeChatPaymentUtilConfig {
@Resource
private YlypWeChatPaymentConfig ylypWeChatPaymentConfig;
/**
* 获取新医路签名信息
*
* @return 签名信息
* @throws Exception 异常信息
*/
@Bean(name = "ylypVerifier")
public Verifier getYlypVerifier() throws Exception {
PrivateKey privateKey = getPrivateKey(ylypWeChatPaymentConfig.getYlypPrivateKeyPath());
PrivateKeySigner privateKeySigner = new PrivateKeySigner(ylypWeChatPaymentConfig.getYlypMchSerialNo(), privateKey);
WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(ylypWeChatPaymentConfig.getYlypMchId(), privateKeySigner);
CertificatesManager certificatesManager = CertificatesManager.getInstance();
certificatesManager.putMerchant(ylypWeChatPaymentConfig.getYlypMchId(), wechatPay2Credentials, ylypWeChatPaymentConfig.getYlypPaymentKey().getBytes(StandardCharsets.UTF_8));
return certificatesManager.getVerifier(ylypWeChatPaymentConfig.getYlypMchId());
}
/**
* 获取医路优品商户带有签名信息的http请求对象
*
* @return CloseableHttpClient对象
*/
@Bean(name = "yiLuYouPinWeChatPayClient")
public CloseableHttpClient getYiLuYouPinWeChatPayClient(Verifier ylypVerifier) {
PrivateKey privateKey = getPrivateKey(ylypWeChatPaymentConfig.getYlypPrivateKeyPath());
CloseableHttpClient closeableHttpClient = null;
try {
closeableHttpClient = WechatPayHttpClientBuilder.create()
.withMerchant(ylypWeChatPaymentConfig.getYlypMchId(), ylypWeChatPaymentConfig.getYlypMchSerialNo(), privateKey)
.withValidator(new WechatPay2Validator(ylypVerifier)).build();
} catch (Exception e) {
log.error("医路优品验证签名信息失败,失败信息:{}", e.getMessage());
}
return closeableHttpClient;
}
/**
* 获取HttpClient无需进行应答签名验证跳过验签的流程
*
* @return CloseableHttpClient对象
*/
@Bean(name = "yiLuYouPinWeChatPayNoSignClient")
public CloseableHttpClient getYiLuYouPinWeChatPayNoSignClient() {
PrivateKey privateKey = getPrivateKey(ylypWeChatPaymentConfig.getYlypPrivateKeyPath());
return WechatPayHttpClientBuilder.create()
.withMerchant(ylypWeChatPaymentConfig.getYlypMchId(), ylypWeChatPaymentConfig.getYlypMchSerialNo(), privateKey)
.withValidator((response) -> true).build();
}
/**
* 获取商户的私钥文件
*
* @param filename 获取商户的私钥文件
* @return 商户私钥
*/
private PrivateKey getPrivateKey(String filename) {
try {
return PemUtil.loadPrivateKey(new ClassPathResource(filename).getInputStream());
} catch (Exception e) {
log.error("医路优品商户私钥文件不存在,错误原因:{}", e.getMessage());
throw new ServiceException("医路优品商户私钥文件不存在,请联系管理员!");
}
}
}

View File

@ -46,5 +46,11 @@
<groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId>
</dependency>
<!-- 微信支付SDK -->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,46 @@
package com.xinelu.applet.controller.logistics;
import com.xinelu.applet.service.logistics.LogisticsService;
import com.xinelu.common.annotation.MobileRequestAuthorization;
import com.xinelu.common.core.controller.BaseController;
import com.xinelu.common.core.domain.AjaxResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @Description 快递鸟物流查询接口控制器
* @Author 纪寒
* @Date 2022-11-01 13:33:31
* @Version 1.0
*/
@RestController
@RequestMapping("/nurseApp/logistics")
public class LogisticsController extends BaseController {
@Resource
private LogisticsService logisticsService;
/**
* 根据快递单号查询物流信息
*
* @param orderNo 订单单号
* @param expressNo 快递单号
* @return 物流信息
* @throws Exception 异常信息
*/
@MobileRequestAuthorization
@GetMapping("/queryLogisticsInfo")
public AjaxResult queryLogisticsInfo(String orderNo, String expressNo) throws Exception {
if (StringUtils.isBlank(orderNo)) {
return AjaxResult.error("请选择要查询的订单信息!");
}
if (StringUtils.isBlank(expressNo)) {
return AjaxResult.error("请选择要查询的快递单号!");
}
return logisticsService.queryLogisticsInfo(orderNo, expressNo);
}
}

View File

@ -1,45 +0,0 @@
package com.xinelu.applet.controller.personappletlogin;
import com.xinelu.applet.service.personappletlogin.PersonAppletLoginService;
import com.xinelu.common.core.controller.BaseController;
import com.xinelu.common.core.domain.AjaxResult;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @Description 护理员微信小程序登录注册控制器
* @Author zh
* @Date 2023-03-30
*/
@RestController
@RequestMapping("/nurseApplet/personLogin")
public class PersonAppletLoginController extends BaseController {
@Resource
private PersonAppletLoginService personAppletLoginService;
/**
* 护理员根据登录凭证获取用户的登录信息
*
* @param loginCode 登录凭证
* @param phoneCode 手机号凭证
* @return 微信用户登录信息
*/
@GetMapping("/getPersonWeChatUserInfo")
public AjaxResult appletLogin(@RequestParam("loginCode") String loginCode, @Param("phoneCode") String phoneCode) {
if (StringUtils.isBlank(loginCode)) {
return AjaxResult.error("登录凭证编码不能为空!");
}
if (StringUtils.isBlank(phoneCode)) {
return AjaxResult.error("获取手机号凭证不存在");
}
return personAppletLoginService.personAppletLogin(loginCode, phoneCode);
}
}

View File

@ -0,0 +1,22 @@
package com.xinelu.applet.service.logistics;
import com.xinelu.common.core.domain.AjaxResult;
/**
* @Description 快递鸟物流查询接口业务层
* @Author 纪寒
* @Date 2022-11-01 13:35:04
* @Version 1.0
*/
public interface LogisticsService {
/**
* 根据快递快递单号查询物流信息
*
* @param orderNo 订单单号
* @param expressNo 快递单号
* @return 物流信息结果
* @throws Exception 异常信息
*/
AjaxResult queryLogisticsInfo(String orderNo, String expressNo) throws Exception;
}

View File

@ -0,0 +1,172 @@
package com.xinelu.applet.service.logistics.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.xinelu.applet.service.logistics.LogisticsService;
import com.xinelu.applet.utils.LogisticsUtil;
import com.xinelu.applet.vo.logistics.DistinguishResultVO;
import com.xinelu.applet.vo.logistics.SearchMonitorResultVO;
import com.xinelu.common.config.LogisticsConfig;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.manage.domain.goodsOrder.GoodsOrder;
import com.xinelu.manage.mapper.goodsOrder.GoodsOrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Description 快递鸟物流查询接口业务层实现类
* @Author 纪寒
* @Date 2022-11-01 13:35:38
* @Version 1.0
*/
@Slf4j
@Service
public class LogisticsServiceImpl implements LogisticsService {
@Resource
private LogisticsConfig logisticsConfig;
@Resource
private GoodsOrderMapper goodsOrderMapper;
/**
* 编码格式
*/
private static final String CHARSET = "UTF-8";
/**
* 识别单号接口指令
*/
private static final String DISTINGUISH_REQUEST_TYPE = "2002";
/**
* DataType=2请求返回数据类型均为JSON格式
*/
private static final String DATA_TYPE = "2";
/**
* 即时查询接口指令
*/
private static final String SEARCH_MONITOR_REQUEST_TYPE = "8001";
/**
* 顺丰快递编码
*/
private static final String SF_SHIPPER_CODE_TYPE = "SF";
/**
* 根据快递快递单号查询物流信息
*
* @param orderNo 订单单号
* @param expressNo 快递单号
* @return 物流信息结果
* @throws Exception 异常信息
*/
@Override
public AjaxResult queryLogisticsInfo(String orderNo, String expressNo) throws Exception {
GoodsOrder goodsOrder = goodsOrderMapper.getGoodsOrderByOrderNo(orderNo);
if (Objects.isNull(goodsOrder) || StringUtils.isBlank(goodsOrder.getPhone())) {
return AjaxResult.error("当前订单信息不存在!");
}
if (StringUtils.isBlank(goodsOrder.getExpressNo())) {
return AjaxResult.error("当前订单未发货,暂无订物流信息!");
}
//用户idAPI KEY正式地址等参数信息
String eBusinessId = logisticsConfig.getEBusinessId();
String apiKey = logisticsConfig.getApiKey();
String expressBirdUrl = logisticsConfig.getExpressBirdUrl();
Map<String, String> distinguishParam = buildDistinguishParam(expressNo, eBusinessId, apiKey);
String distinguishResult = LogisticsUtil.sendPost(expressBirdUrl, distinguishParam);
if (StringUtils.isBlank(distinguishResult)) {
log.info("调用快递鸟识别单号返回结果为空,请求参数 ====> {}", distinguishParam.toString());
return AjaxResult.error("当前订单暂无物流信息!");
}
DistinguishResultVO vo = JSONObject.parseObject(distinguishResult, DistinguishResultVO.class);
if (Objects.isNull(vo) || BooleanUtils.isFalse(vo.getSuccess())) {
log.info("调用快递鸟识别单号返回结果为空,请求参数 ====> {}", distinguishParam.toString());
return AjaxResult.error("当前订单暂无物流信息!");
}
List<String> shipperCodeList = vo.getShippers().stream().filter(item -> StringUtils.isNotBlank(item.getShipperCode())).map(DistinguishResultVO.ShippersDTO::getShipperCode).distinct().collect(Collectors.toList());
//循环查询快递信息
SearchMonitorResultVO monitorResultVO = null;
for (String shipperCode : shipperCodeList) {
if (StringUtils.isBlank(shipperCode)) {
continue;
}
//构建在途查询中即时查询接口参数信息
Map<String, String> searchMonitorParam = buildSearchMonitorParam(expressNo, eBusinessId, apiKey, shipperCode, goodsOrder.getPhone());
String searchMonitorResult = LogisticsUtil.sendPost(expressBirdUrl, searchMonitorParam);
monitorResultVO = JSONObject.parseObject(searchMonitorResult, SearchMonitorResultVO.class);
if (Objects.nonNull(monitorResultVO) && BooleanUtils.isTrue(monitorResultVO.getSuccess())) {
List<SearchMonitorResultVO.TracesDTO> sortTraces = monitorResultVO.getTraces().stream()
.filter(item -> Objects.nonNull(item.getAcceptTime()))
.sorted(Comparator.comparing(SearchMonitorResultVO.TracesDTO::getAcceptTime).reversed()).collect(Collectors.toList());
monitorResultVO.setTraces(sortTraces);
monitorResultVO.setShipperName(vo.getShippers().stream().filter(item -> StringUtils.isNotBlank(item.getShipperName()))
.filter(item -> shipperCode.equals(item.getShipperCode())).map(DistinguishResultVO.ShippersDTO::getShipperName).findFirst().orElse(""));
break;
}
}
return AjaxResult.success(monitorResultVO);
}
/**
* 构建识别单号参数信息
*
* @param expressNo 快递单号
* @param eBusinessId 用户id
* @param apiKey API key
* @return 参数信息
* @throws Exception 异常信息
*/
private Map<String, String> buildDistinguishParam(String expressNo, String eBusinessId,
String apiKey) throws Exception {
String requestData = "{'LogisticCode': '" + expressNo + "'}";
Map<String, String> params = new LinkedHashMap<>();
params.put("RequestData", LogisticsUtil.urlEncoder(requestData, CHARSET));
params.put("EBusinessID", eBusinessId);
params.put("RequestType", DISTINGUISH_REQUEST_TYPE);
String dataSign = LogisticsUtil.encrypt(requestData, apiKey, CHARSET);
params.put("DataSign", LogisticsUtil.urlEncoder(dataSign, CHARSET));
params.put("DataType", DATA_TYPE);
return params;
}
/**
* 构建即时查询物流单号信息
*
* @param expressNo 快递单号
* @param eBusinessId 用户id
* @param apiKey API key
* @param shipperCode 快递公司编码
* @param phone 联系电话
* @return 参数信息
* @throws Exception 异常信息
*/
private Map<String, String> buildSearchMonitorParam(String expressNo, String eBusinessId, String apiKey,
String shipperCode, String phone) throws Exception {
Map<String, String> sysParamMap = new LinkedHashMap<>();
sysParamMap.put("OrderCode", "");
if (SF_SHIPPER_CODE_TYPE.equals(shipperCode)) {
sysParamMap.put("CustomerName", phone.substring(7, 11));
} else {
sysParamMap.put("CustomerName", "");
}
sysParamMap.put("ShipperCode", shipperCode);
sysParamMap.put("LogisticCode", expressNo);
String requestData = JSON.toJSONString(sysParamMap);
Map<String, String> params = new LinkedHashMap<>();
params.put("RequestData", LogisticsUtil.urlEncoder(requestData, CHARSET));
params.put("EBusinessID", eBusinessId);
params.put("RequestType", SEARCH_MONITOR_REQUEST_TYPE);
String dataSign = LogisticsUtil.encrypt(requestData, apiKey, CHARSET);
params.put("DataSign", LogisticsUtil.urlEncoder(dataSign, CHARSET));
params.put("DataType", DATA_TYPE);
return params;
}
}

View File

@ -8,7 +8,6 @@ import com.xinelu.common.enums.OrderStatusEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.manage.mapper.appointmentorder.AppointmentOrderMapper;
import com.xinelu.manage.mapper.appointmentorderdetails.AppointmentOrderDetailsMapper;
import com.xinelu.manage.service.stationmessagepush.StationMessagePushService;
import com.xinelu.manage.vo.appointmentorder.AppointmentReceivingOrderVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -29,8 +28,6 @@ public class NurseAppletPersonWorkOrderServiceImpl implements NurseAppletPersonW
@Resource
private AppointmentOrderMapper appointmentOrderMapper;
@Resource
private StationMessagePushService stationMessagePushService;
@Resource
private AppointmentOrderDetailsMapper appointmentOrderDetailsMapper;
/**
@ -50,8 +47,6 @@ public class NurseAppletPersonWorkOrderServiceImpl implements NurseAppletPersonW
if (update < 0) {
throw new ServiceException("接单失败,请联系管理员!");
}
//异步发送消息
stationMessagePushService.receivingOrdersOperationsPush(appointmentReceivingOrder);
return AjaxResult.success();
}
}

View File

@ -23,7 +23,6 @@ import com.xinelu.manage.mapper.nursestation.NurseStationMapper;
import com.xinelu.manage.mapper.nursestationperson.NurseStationPersonMapper;
import com.xinelu.manage.mapper.nursestationpersonrevenue.NurseStationPersonRevenueMapper;
import com.xinelu.manage.mapper.patientdiseaseinfo.PatientDiseaseInfoMapper;
import com.xinelu.manage.service.stationmessagepush.StationMessagePushService;
import com.xinelu.manage.vo.appointmentorder.AppointmentOrderRecordVO;
import com.xinelu.manage.vo.appointmentorder.AppointmentReceivingOrderVO;
import com.xinelu.manage.vo.nursestation.NurseStationSysUserVO;
@ -71,8 +70,6 @@ public class NursePersonAppLoginServiceImpl implements INursePersonAppLoginServi
private NurseStationPersonRevenueMapper nurseStationPersonRevenueMapper;
@Resource
private PatientDiseaseInfoMapper patientDiseaseInfoMapper;
@Resource
private StationMessagePushService stationMessagePushService;
/**
* 工单首页查询已完成以及未完成数量
@ -168,8 +165,6 @@ public class NursePersonAppLoginServiceImpl implements INursePersonAppLoginServi
if (update <= 0) {
throw new ServiceException("任务退回失败,请联系管理员!");
}
//异步发送信息
stationMessagePushService.refusalOrdersOperationsPush(appointmentReceivingOrder);
return AjaxResult.success();
}
@ -213,8 +208,6 @@ public class NursePersonAppLoginServiceImpl implements INursePersonAppLoginServi
Long nurseStationPersonId = Objects.isNull(orderDetails.getNurseStationPersonId()) ? 0 : orderDetails.getNurseStationPersonId();
BigDecimal orderCommissionAmount = Objects.isNull(orderDetails.getOrderCommissionAmount()) ? BigDecimal.ZERO : orderDetails.getOrderCommissionAmount();
nurseStationPersonMapper.updateTotalRevenueAmountById(nurseStationPersonId, orderCommissionAmount);
//异步发送信息
stationMessagePushService.orderCompletionOperationsPush(orderDetails);
return AjaxResult.success();
}

View File

@ -1,231 +0,0 @@
package com.xinelu.applet.service.personappletlogin.Impl;
import com.xinelu.applet.mapper.nursemanagepersonwechatinfo.NurseManagePersonWechatInfoMapper;
import com.xinelu.applet.mapper.personappletlogin.PersonAppletLoginMapper;
import com.xinelu.applet.service.personappletlogin.PersonAppletLoginService;
import com.xinelu.applet.utils.AppletAccessTokenUtil;
import com.xinelu.applet.vo.personappletlogin.PersonAppletVO;
import com.xinelu.applet.vo.personappletlogin.UserAndRole;
import com.xinelu.common.config.NurseAppletChatConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.entity.AppletLoginVO;
import com.xinelu.common.entity.AppletPhoneVO;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.AppletChatUtil;
import com.xinelu.manage.domain.nursemanagepersonwechatinfo.NurseManagePersonWechatInfo;
import com.xinelu.manage.mapper.nursestationperson.NurseStationPersonMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @Description 护理员微信小程序登录注册业务层实现类
* @Author zh
* @Date 2023-03-30
* @Version 1.0
*/
@Slf4j
@Service
public class PersonAppletLoginServiceImpl implements PersonAppletLoginService {
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private NurseAppletChatConfig nurseAppletChatConfig;
@Resource
private AppletAccessTokenUtil appletAccessTokenUtil;
@Resource
private NurseStationPersonMapper nurseStationPersonMapper;
@Resource
private PersonAppletLoginMapper personAppletLoginMapper;
@Resource
private NurseManagePersonWechatInfoMapper nurseManagePersonWechatInfoMapper;
/**
* 返回成功状态码
*/
private static final int SUCCESS_CODE = 0;
/**
* 获取微信小程序access_token错误码
*/
private static final int ERROR_ACCESS_CODE = 40001;
/**
* 返回成功状态码
*/
private static final String OK = "ok";
/**
* 根据登录凭证获取用户的登录信息
*
* @param loginCode 登录凭证
* @return 微信用户登录信息
*/
@Transactional(rollbackFor = Exception.class)
@Override
public AjaxResult personAppletLogin(String loginCode, String phoneCode) {
//根据code获取用户的微信unionId以及openId等信息
AppletLoginVO appletLoginInfo = AppletChatUtil.getAppletLoginInfo(nurseAppletChatConfig.getAppletId(), nurseAppletChatConfig.getSecret(), loginCode, nurseAppletChatConfig.getGrantType());
if (Objects.isNull(appletLoginInfo)) {
return AjaxResult.error("获取微信小程序用户信息失败");
}
if (Objects.nonNull(appletLoginInfo.getErrcode()) && appletLoginInfo.getErrcode() != SUCCESS_CODE) {
return AjaxResult.error("获取微信小程序用户信息失败,失败信息为:" + appletLoginInfo.getErrmsg());
}
//获取微信accessToken,从Redis中取出accessToken
String accessToken;
String accessTokenKey = Constants.NURSE_STATION_PERSON_APPLET_ACCESS_TOKEN + "accessToken";
Object object = redisTemplate.opsForValue().get(accessTokenKey);
if (Objects.isNull(object)) {
accessToken = appletAccessTokenUtil.getPersonAppletAccessToken();
} else {
accessToken = (String) object;
}
//获取用户手机号
AppletPhoneVO appletPhoneInfo = AppletChatUtil.getAppletPhoneInfo(phoneCode, accessToken);
if (Objects.isNull(appletPhoneInfo)) {
return AjaxResult.error("获取用户手机号失败");
}
if (Objects.nonNull(appletPhoneInfo.getErrcode()) && appletPhoneInfo.getErrcode() == ERROR_ACCESS_CODE) {
//当前Redis缓存中的access_token无效直接删除
if (Objects.nonNull(object)) {
redisTemplate.delete(accessTokenKey);
accessToken = appletAccessTokenUtil.getPersonAppletAccessToken();
appletPhoneInfo = AppletChatUtil.getAppletPhoneInfo(phoneCode, accessToken);
if (Objects.isNull(appletPhoneInfo)) {
return AjaxResult.error("获取用户手机号失败");
}
if (Objects.nonNull(appletPhoneInfo.getErrcode()) && appletPhoneInfo.getErrcode() == ERROR_ACCESS_CODE) {
return AjaxResult.error("登录失败!");
}
}
}
if (StringUtils.isNotBlank(appletPhoneInfo.getErrmsg()) && !OK.equals(appletPhoneInfo.getErrmsg())) {
return AjaxResult.error("获取用户手机号失败,失败信息为:" + appletPhoneInfo.getErrmsg());
}
PersonAppletVO personAppletVO = getPersonApplet(appletPhoneInfo, appletLoginInfo);
return AjaxResult.success(personAppletVO);
}
/**
* 护理站管理人员微信个人信息对象
*
* @param phone 护理员手机号
* @param openid 用户的信息
* @param sysUser 管理员信息
*/
private void getNurseManagePersonWechat(String phone, String openid, List<UserAndRole> sysUser) {
//护理站管理人员微信个人信息对象
NurseManagePersonWechatInfo nurseManagePersonWechat = nurseManagePersonWechatInfoMapper.selectNurseManagePersonWechatInfoByPhone(phone);
NurseManagePersonWechatInfo nurseManagePersonWechatInfo = new NurseManagePersonWechatInfo();
if (Objects.isNull(nurseManagePersonWechat)) {
nurseManagePersonWechatInfo.setOpenid(openid);
nurseManagePersonWechatInfo.setPhone(phone);
nurseManagePersonWechatInfo.setNurseStationId(StringUtils.isBlank(sysUser.get(0).getNurseStationIds()) ? "" : sysUser.get(0).getNurseStationIds());
nurseManagePersonWechatInfo.setUserId(Objects.isNull(sysUser.get(0).getUserId()) ? null : sysUser.get(0).getUserId());
nurseManagePersonWechatInfo.setCreateTime(LocalDateTime.now());
int count = nurseManagePersonWechatInfoMapper.insertNurseManagePersonWechatInfo(nurseManagePersonWechatInfo);
if (count <= 0) {
throw new ServiceException("新增护理站管理人员微信个人信息失败,请联系管理员!");
}
}
if (Objects.nonNull(nurseManagePersonWechat)) {
nurseManagePersonWechatInfo.setId(Objects.isNull(nurseManagePersonWechat.getId()) ? null : nurseManagePersonWechat.getId());
nurseManagePersonWechatInfo.setOpenid(openid);
nurseManagePersonWechatInfo.setPhone(phone);
nurseManagePersonWechatInfo.setNurseStationId(StringUtils.isBlank(sysUser.get(0).getNurseStationIds()) ? "" : sysUser.get(0).getNurseStationIds());
nurseManagePersonWechatInfo.setUserId(Objects.isNull(sysUser.get(0).getUserId()) ? null : sysUser.get(0).getUserId());
int update = nurseManagePersonWechatInfoMapper.updateNurseManagePersonWechatInfo(nurseManagePersonWechatInfo);
if (update <= 0) {
throw new ServiceException("新增护理站管理人员微信个人信息失败,请联系管理员!");
}
}
}
/**
* 护理员登录接口方法抽取
*
* @param appletPhoneInfo 微信用户信息
* @param appletLoginInfo 手机号信息
* @return 登录标识
*/
private PersonAppletVO getPersonApplet(AppletPhoneVO appletPhoneInfo, AppletLoginVO appletLoginInfo) {
PersonAppletVO appletParent = new PersonAppletVO();
String phone = StringUtils.isBlank(appletPhoneInfo.getPhoneInfo().getPhoneNumber()) ? "" : appletPhoneInfo.getPhoneInfo().getPhoneNumber();
String openid = StringUtils.isBlank(appletLoginInfo.getOpenid()) ? "" : appletLoginInfo.getOpenid();
PersonAppletVO nurseStationPerson = personAppletLoginMapper.getNurseStationPersonByPhone(phone);
List<UserAndRole> sysUser = personAppletLoginMapper.selectSysUser(phone);
//说明当前用户角色即是护理员又是护理站运营人员
if (Objects.nonNull(nurseStationPerson) && CollectionUtils.isNotEmpty(sysUser)) {
//更新用户的openid等微信标识信息
this.updateNurseStationPerson(appletParent, nurseStationPerson, openid);
appletParent.setPersonRoleLoginFlag(Constants.PERSON_ROLE_NAME);
//护理站管理人员微信个人信息对象
List<String> roleKeyList = sysUser.stream().filter(Objects::nonNull).map(UserAndRole::getRoleKey).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(roleKeyList) && (String.join((","), roleKeyList).contains(Constants.STATION_ROLE_NAME))) {
this.getNurseManagePersonWechat(phone, openid, sysUser);
appletParent.setPersonRoleLoginFlag(Constants.STATION_AND_PERSON_ROLE_NAME);
}
}
//说明当前用户角色即是护理员
if (Objects.nonNull(nurseStationPerson) && Objects.isNull(sysUser)) {
//更新用户的openid等微信标识信息
this.updateNurseStationPerson(appletParent, nurseStationPerson, openid);
appletParent.setPersonRoleLoginFlag(Constants.PERSON_ROLE_NAME);
}
//说明当前用户角色即是护理站运营人员
if (Objects.isNull(nurseStationPerson) && Objects.nonNull(sysUser)) {
List<String> roleKeyList = sysUser.stream().filter(Objects::nonNull).map(UserAndRole::getRoleKey).collect(Collectors.toList());
appletParent.setPersonRoleLoginFlag(Constants.NOT_ROLE_NAME);
if (CollectionUtils.isNotEmpty(roleKeyList) && (String.join((","), roleKeyList).contains(Constants.STATION_ROLE_NAME))) {
this.getNurseManagePersonWechat(phone, openid, sysUser);
appletParent.setPersonRoleLoginFlag(Constants.STATION_ROLE_NAME);
}
appletParent.setPhone(phone);
}
//说明当前用户角色即是即不是护理员又是不是护理站运营人员
if (Objects.isNull(nurseStationPerson) && Objects.isNull(sysUser)) {
appletParent.setPhone(phone);
appletParent.setPersonRoleLoginFlag(Constants.NOT_ROLE_NAME);
}
//当前用户角色只要包含护理员那么将护理员的信息返回给前端
if (Objects.nonNull(nurseStationPerson)) {
appletParent.setNurseStationId(Objects.isNull(nurseStationPerson.getNurseStationId()) ? null : nurseStationPerson.getNurseStationId());
appletParent.setNurseStationPersonId(Objects.isNull(nurseStationPerson.getNurseStationPersonId()) ? null : nurseStationPerson.getNurseStationPersonId());
appletParent.setNursePersonName(StringUtils.isBlank(nurseStationPerson.getNursePersonName()) ? "" : nurseStationPerson.getNursePersonName());
}
return appletParent;
}
/**
* 修改护理人员信息
*
* @param appletParent 护理员信息
* @param nurseStationPerson 护理员信息
* @param openid 护理员信息
*/
private void updateNurseStationPerson(PersonAppletVO appletParent, PersonAppletVO nurseStationPerson, String openid) {
appletParent.setId(nurseStationPerson.getNurseStationPersonId());
appletParent.setNurseStationPersonId(nurseStationPerson.getNurseStationPersonId());
appletParent.setOpenid(openid);
appletParent.setPhone(StringUtils.isBlank(nurseStationPerson.getPhone()) ? "" : nurseStationPerson.getPhone());
appletParent.setUpdateTime(LocalDateTime.now());
int updateCount = nurseStationPersonMapper.updateNurseStationPerson(appletParent);
if (updateCount <= 0) {
throw new ServiceException("修改护理人员信息失败,请联系管理员!");
}
}
}

View File

@ -1,21 +0,0 @@
package com.xinelu.applet.service.personappletlogin;
import com.xinelu.common.core.domain.AjaxResult;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @Description 护理员微信小程序登录注册业务层
* @Author zh
* @Date 2023-03-30
*/
public interface PersonAppletLoginService {
/**
* 护理员根据登录凭证获取用户的登录信息
*
* @param loginCode 登录凭证
* @param phoneCode 手机号凭证
* @return 微信用户登录信息
*/
AjaxResult personAppletLogin(@RequestParam("loginCode") String loginCode, String phoneCode);
}

View File

@ -1,7 +1,6 @@
package com.xinelu.applet.utils;
import com.xinelu.common.config.AppletChatConfig;
import com.xinelu.common.config.NurseAppletChatConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.entity.AppletAccessToken;
import com.xinelu.common.exception.ServiceException;
@ -27,8 +26,7 @@ public class AppletAccessTokenUtil {
private RedisTemplate<String, Object> redisTemplate;
@Resource
private AppletChatConfig appletChatConfig;
@Resource
private NurseAppletChatConfig nurseAppletChatConfig;
/**
* 返回成功状态码
*/
@ -65,34 +63,4 @@ public class AppletAccessTokenUtil {
return accessToken;
}
/**
* 护理员小程序获取小程序AccessToken方法
*
* @return 小程序的AccessToken
*/
public String getPersonAppletAccessToken() {
String accessToken;
String accessTokenKey = Constants.NURSE_STATION_PERSON_APPLET_ACCESS_TOKEN + "accessToken";
//从Redis中取出accessToken
Object object = redisTemplate.opsForValue().get(accessTokenKey);
if (Objects.isNull(object)) {
//没有获取accessToken
AppletAccessToken appletAccessToken = AppletChatUtil.getAppletAccessToken(nurseAppletChatConfig.getAppletId(), nurseAppletChatConfig.getSecret());
if (Objects.isNull(appletAccessToken)) {
throw new ServiceException("获取微信小程序accessToken信息失败");
}
if (Objects.nonNull(appletAccessToken.getErrcode()) && appletAccessToken.getErrcode() != SUCCESS_CODE) {
throw new ServiceException("获取微信小程序accessToken信息失败失败信息为" + appletAccessToken.getErrmsg(), 201);
}
if (StringUtils.isBlank(appletAccessToken.getAccessToken())) {
throw new ServiceException("accessToken信息为空");
}
//存入Redis中
redisTemplate.opsForValue().set(accessTokenKey, appletAccessToken.getAccessToken(), 3600, TimeUnit.SECONDS);
accessToken = appletAccessToken.getAccessToken();
} else {
accessToken = (String) object;
}
return accessToken;
}
}

View File

@ -0,0 +1,145 @@
package com.xinelu.applet.utils;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import com.xinelu.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Map;
/**
* @Description 快递鸟物流查询工具类
* @Author 纪寒
* @Date 2022-11-01 13:43:03
* @Version 1.0
*/
@Slf4j
public class LogisticsUtil {
/**
* 发送POST请求
*
* @param url 请求地址
* @param params 请求参数
* @return 返回结果信息
* @throws Exception 异常信息
*/
public static String sendPost(String url, Map<String, String> params) throws Exception {
OutputStreamWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
try {
URL realUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
//发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
//设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.connect();
//获取URLConnection对象对应的输出流
out = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
StringBuilder param = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (param.length() > 0) {
param.append("&");
}
param.append(entry.getKey());
param.append("=");
param.append(entry.getValue());
}
out.write(param.toString());
out.flush();
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
log.error("调用快递鸟识别单号异常,异常信息:{}", e.getMessage());
throw new ServiceException("查询物流信息出错,请联系管理员!");
} finally {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
}
return result.toString();
}
/**
* sign签名生成
*
* @param content 内容
* @param keyValue ApiKey
* @param charset 编码方式
* @return 签名信息
* @throws Exception 异常信息
*/
public static String encrypt(String content, String keyValue, String charset) throws Exception {
if (keyValue != null) {
return base64(logisticsMd5(content + keyValue, charset), charset);
}
return base64(logisticsMd5(content, charset), charset);
}
/**
* 编码格式信息
*
* @param content 内容
* @param charset 字符集
* @return 编码结果信息
* @throws Exception 异常信息
*/
public static String urlEncoder(String content, String charset) throws Exception {
return URLEncoder.encode(content, charset);
}
/**
* base64编码
*
* @param content 内容
* @param charset 编码方式
* @return 编码结果信息
* @throws Exception 异常信息
*/
public static String base64(String content, String charset) throws Exception {
return Base64.encode(content.getBytes(charset));
}
/**
* MD5加密
*
* @param content 内容
* @param charset 编码方式
* @return 结果
* @throws Exception 异常信息
*/
public static String logisticsMd5(String content, String charset) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(content.getBytes(charset));
byte[] result = md.digest();
StringBuilder sb = new StringBuilder(32);
for (byte b : result) {
int val = b & 0xff;
if (val <= 0xf) {
sb.append("0");
}
sb.append(Integer.toHexString(val));
}
return sb.toString().toLowerCase();
}
}

View File

@ -0,0 +1,44 @@
package com.xinelu.applet.vo.logistics;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* @Description 快递鸟单号识别接口返回值实体类
* @Author 纪寒
* @Date 2022-11-01 14:44:06
* @Version 1.0
*/
@NoArgsConstructor
@Data
public class DistinguishResultVO implements Serializable {
private static final long serialVersionUID = 5858502009039750987L;
@JsonProperty("EBusinessID")
private String eBusinessID;
@JsonProperty("Success")
private Boolean success;
@JsonProperty("LogisticCode")
private String logisticCode;
@JsonProperty("Shippers")
private List<ShippersDTO> shippers;
@NoArgsConstructor
@Data
public static class ShippersDTO {
@JsonProperty("ShipperCode")
private String shipperCode;
@JsonProperty("ShipperName")
private String shipperName;
}
}

View File

@ -0,0 +1,66 @@
package com.xinelu.applet.vo.logistics;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
/**
* @Description 快递鸟即时查询接口返回值实体类
* @Author 纪寒
* @Date 2022-11-01 15:21:32
* @Version 1.0
*/
@NoArgsConstructor
@Data
public class SearchMonitorResultVO implements Serializable {
private static final long serialVersionUID = -3109050110048632561L;
@JsonProperty("EBusinessID")
private String eBusinessID;
@JsonProperty("ShipperCode")
private String shipperCode;
private String shipperName;
@JsonProperty("Success")
private Boolean success;
@JsonProperty("LogisticCode")
private String logisticCode;
@JsonProperty("State")
private String state;
@JsonProperty("StateEx")
private String stateEx;
@JsonProperty("Location")
private String location;
@JsonProperty("Traces")
private List<TracesDTO> traces;
@NoArgsConstructor
@Data
public static class TracesDTO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonProperty("AcceptTime")
private LocalDateTime acceptTime;
@JsonProperty("AcceptStation")
private String acceptStation;
@JsonProperty("Location")
private String location;
@JsonProperty("Action")
private String action;
}
}

View File

@ -13,7 +13,6 @@ import com.xinelu.manage.mapper.appointmentorder.AppointmentOrderMapper;
import com.xinelu.manage.mapper.appointmentorderconsumable.AppointmentOrderConsumableMapper;
import com.xinelu.manage.mapper.appointmentorderdetails.AppointmentOrderDetailsMapper;
import com.xinelu.manage.service.appointmentorder.IAppointmentOrderService;
import com.xinelu.manage.service.stationmessagepush.StationMessagePushService;
import com.xinelu.manage.vo.appointmentorder.AppointmentOrderVO;
import com.xinelu.manage.vo.appointmentorder.PersonAndDepartmentVO;
import lombok.extern.slf4j.Slf4j;
@ -42,8 +41,6 @@ public class AppointmentOrderServiceImpl implements IAppointmentOrderService {
private AppointmentOrderDetailsMapper appointmentOrderDetailsMapper;
@Resource
private AppointmentOrderConsumableMapper appointmentOrderConsumableMapper;
@Resource
private StationMessagePushService stationMessagePushService;
/**
* 查询预约订单信息
@ -178,7 +175,6 @@ public class AppointmentOrderServiceImpl implements IAppointmentOrderService {
if (updateAppointmentOrderStatus <= 0) {
throw new ServiceException("派单失败,请联系管理员!");
}
stationMessagePushService.waitReceiveMessagePush(appointmentOrder);
return AjaxResult.success();
}

View File

@ -1,408 +0,0 @@
package com.xinelu.manage.service.stationmessagepush.Impl;
import com.alibaba.fastjson2.JSON;
import com.xinelu.common.config.NurseAppletChatConfig;
import com.xinelu.common.config.NurseAppletPageConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.entity.AppletAccessToken;
import com.xinelu.common.entity.MessageValueEntity;
import com.xinelu.common.enums.AppletSubscriptionMessageEnum;
import com.xinelu.common.enums.SubscribeStatusEnum;
import com.xinelu.common.utils.AppletChatUtil;
import com.xinelu.common.utils.http.HttpUtils;
import com.xinelu.manage.domain.appointmentorder.AppointmentOrder;
import com.xinelu.manage.domain.personsubscribemessage.PersonSubscribeMessage;
import com.xinelu.manage.mapper.appointmentorder.AppointmentOrderMapper;
import com.xinelu.manage.mapper.personsubscribemessage.PersonSubscribeMessageMapper;
import com.xinelu.manage.service.stationmessagepush.StationMessagePushService;
import com.xinelu.manage.vo.appointmentorder.AppointmentOrderInfoVO;
import com.xinelu.manage.vo.appointmentorder.AppointmentOrderRecordVO;
import com.xinelu.manage.vo.appointmentorder.AppointmentReceivingOrderVO;
import com.xinelu.manage.vo.personsubscribemessage.PersonSubscribeMessageVO;
import com.xinelu.manage.vo.stationmessagepush.WaitReceiveMessagePushVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
* 派单消息推送业务层
*
* @author zh
*/
@Slf4j
@Service
public class StationMessagePushServiceImpl implements StationMessagePushService {
@Resource
private NurseAppletChatConfig nurseAppletChatConfig;
@Resource
private PersonSubscribeMessageMapper personSubscribeMessageMapper;
@Resource
private AppointmentOrderMapper appointmentOrderMapper;
@Resource
private NurseAppletPageConfig nurseAppletPageConfig;
/**
* 微信消息推送url
*/
private static final String MESSAGE_PUSH_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";
/**
* 派单后提醒护理员接单消息推送
*
* @param appointmentOrder 订单信息
*/
@Override
@Async("asyncThreadServiceExecutor")
public void waitReceiveMessagePush(AppointmentOrder appointmentOrder) {
log.info("待接单消息提醒,订单参数:{}", appointmentOrder);
//获取AppletAccessToken的值
AppletAccessToken appletAccessToken = AppletChatUtil.getAppletAccessToken(nurseAppletChatConfig.getAppletId(), nurseAppletChatConfig.getSecret());
if (Objects.isNull(appletAccessToken)) {
log.error("获取微信小程序accessToken信息失败");
return;
}
if (Objects.nonNull(appletAccessToken.getErrcode()) && appletAccessToken.getErrcode() != AppletSubscriptionMessageEnum.SUCCESS_ERRCODE.getValue()) {
log.error("获取微信小程序accessToken信息失败失败信息为" + appletAccessToken.getErrmsg(), 201);
return;
}
if (StringUtils.isBlank(appletAccessToken.getAccessToken())) {
log.error("accessToken信息为空");
return;
}
//获取用户信息订阅消息记录规则信息
PersonSubscribeMessage personSubscribeMessage = personSubscribeMessageMapper
.selectPersonSubscribeMessageByPatientId(appointmentOrder.getNurseStationPersonId(), null, nurseAppletChatConfig.getReceivingOrdersNurseTemplateId());
if (Objects.isNull(personSubscribeMessage) || StringUtils.isBlank(personSubscribeMessage.getOpenid()) || StringUtils.isBlank(personSubscribeMessage.getSubscribeStatus()) || !SubscribeStatusEnum.ACCEPT.getInfo().equals(personSubscribeMessage.getSubscribeStatus())) {
return;
}
WaitReceiveMessagePushVO waitReceiveOrderDetails = appointmentOrderMapper.selectOrderDetailsAndPatientBy(appointmentOrder.getOrderNo());
if (Objects.isNull(waitReceiveOrderDetails)) {
return;
}
this.waitReceiveMessage(waitReceiveOrderDetails, personSubscribeMessage, appletAccessToken);
}
/**
* 待接单消息推送
*
* @param appletAccessToken 令牌
* @param dispatchOrderDetails 订单信息
* @param personSubscribeMessage 订阅消息记录
*/
@Override
public void waitReceiveMessage(WaitReceiveMessagePushVO dispatchOrderDetails, PersonSubscribeMessage personSubscribeMessage, AppletAccessToken appletAccessToken) {
//模板参数用户openid推送消息模板id
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("touser", personSubscribeMessage.getOpenid());
paramsMap.put("template_id", nurseAppletChatConfig.getReceivingOrdersNurseTemplateId());
paramsMap.put("page", nurseAppletPageConfig.getWorkPageUrl());
String serviceDate = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(Objects.isNull(dispatchOrderDetails.getServiceDate()) ? LocalDate.now() : dispatchOrderDetails.getServiceDate());
LocalTime serviceStartTime = Objects.isNull(dispatchOrderDetails.getServiceStartTime()) ? LocalTime.now() : dispatchOrderDetails.getServiceStartTime();
//模板内容
Map<String, MessageValueEntity> messageValueEntityMap = new LinkedHashMap<>();
messageValueEntityMap.put("thing2", new MessageValueEntity(StringUtils.isBlank(dispatchOrderDetails.getNurseItemName()) ? "" : dispatchOrderDetails.getNurseItemName()));
String serviceAddress = StringUtils.isBlank(dispatchOrderDetails.getServiceAddress()) ? "" : dispatchOrderDetails.getServiceAddress();
if (StringUtils.isNotBlank(serviceAddress) && dispatchOrderDetails.getServiceAddress().length() > 20) {
serviceAddress = dispatchOrderDetails.getServiceAddress().substring(0, 19);
}
messageValueEntityMap.put("thing6", new MessageValueEntity(serviceAddress));
messageValueEntityMap.put("time16", new MessageValueEntity(serviceDate + " " + serviceStartTime));
messageValueEntityMap.put("thing7", new MessageValueEntity(StringUtils.isBlank(dispatchOrderDetails.getPatientName()) ? "" : dispatchOrderDetails.getPatientName()));
messageValueEntityMap.put("phone_number8", new MessageValueEntity(StringUtils.isBlank(dispatchOrderDetails.getPhone()) ? "" : dispatchOrderDetails.getPhone()));
paramsMap.put("data", messageValueEntityMap);
this.sendPosts(appletAccessToken, paramsMap);
}
/**
* 服务派单通知运营人员
*
* @param appointmentOrderInfo 订单信息表
**/
@Override
@Async("asyncThreadServiceExecutor")
public void serviceDispatchOperationsPush(AppointmentOrderInfoVO appointmentOrderInfo) {
log.info("预定订单下单派单消息提醒,订单参数:{}", appointmentOrderInfo);
//根据护理人员id去查询护理人员角色是否是护理站管理人员
List<PersonSubscribeMessageVO> personSubscribe = personSubscribeMessageMapper.selectPersonSubscribeMessageByPersonWechatId(appointmentOrderInfo.getNurseStationId(), null, null, nurseAppletChatConfig.getServiceDispatchOperationsTemplateId());
if (CollectionUtils.isEmpty(personSubscribe)) {
return;
}
//循环发送
AppletAccessToken appletAccessToken = getAppletAccessToken();
for (PersonSubscribeMessageVO personSubscribeMessage : personSubscribe) {
boolean subscribeMessage = Objects.nonNull(personSubscribeMessage)
&& StringUtils.isNotBlank(personSubscribeMessage.getSubscribeStatus())
&& SubscribeStatusEnum.ACCEPT.getInfo().equals(personSubscribeMessage.getSubscribeStatus());
if (BooleanUtils.isTrue(subscribeMessage)) {
//构建微信小程序消息推送参数
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("template_id", StringUtils.isBlank(personSubscribeMessage.getTemplateId()) ? "" : personSubscribeMessage.getTemplateId());
paramsMap.put("page", nurseAppletPageConfig.getNursePageUrl());
paramsMap.put("touser", StringUtils.isBlank(personSubscribeMessage.getOpenid()) ? "" : personSubscribeMessage.getOpenid());
paramsMap.put("lang", "zh_CN");
//构建微信小程序消息推送内容参数
Map<String, MessageValueEntity> amountParamMap = new HashMap<>();
//服务项目
amountParamMap.put("thing2", new MessageValueEntity(StringUtils.isBlank(appointmentOrderInfo.getNurseItemName()) ? "" : appointmentOrderInfo.getNurseItemName()));
//服务信息
amountParamMap.put("thing3", new MessageValueEntity(StringUtils.isBlank(appointmentOrderInfo.getItemServeDurationUnit()) ? "" : appointmentOrderInfo.getItemServeDurationUnit()));
//订单编号
amountParamMap.put("character_string13", new MessageValueEntity(StringUtils.isBlank(appointmentOrderInfo.getOrderNo()) ? "" : appointmentOrderInfo.getOrderNo()));
//上门时间
String serviceDate = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(Objects.isNull(appointmentOrderInfo.getServiceDate()) ? LocalDate.now() : appointmentOrderInfo.getServiceDate());
LocalTime serviceStartTime = Objects.isNull(appointmentOrderInfo.getServiceStartTime()) ? LocalTime.now() : appointmentOrderInfo.getServiceStartTime();
amountParamMap.put("time24", new MessageValueEntity(serviceDate + " " + serviceStartTime));
//上门地址
String serviceAddress = StringUtils.isBlank(appointmentOrderInfo.getServiceAddress()) ? "" : appointmentOrderInfo.getServiceAddress();
if (StringUtils.isNotBlank(serviceAddress) && appointmentOrderInfo.getServiceAddress().length() > 20) {
serviceAddress = appointmentOrderInfo.getServiceAddress().substring(0, 19);
}
amountParamMap.put("thing25", new MessageValueEntity(serviceAddress));
paramsMap.put("data", amountParamMap);
//发送
this.sendPosts(appletAccessToken, paramsMap);
}
}
}
/**
* 接单提醒通知运营人员
*
* @param appointmentReceivingOrder 订单信息表
**/
@Override
@Async("asyncThreadServiceExecutor")
public void receivingOrdersOperationsPush(AppointmentReceivingOrderVO appointmentReceivingOrder) {
//根据护理人员id去查询护理人员角色是否是护理站管理人员
log.info("预约订单接单消息提醒,订单参数:{}", appointmentReceivingOrder);
List<PersonSubscribeMessageVO> personSubscribe = personSubscribeMessageMapper.selectPersonSubscribeMessageByPersonWechatId(appointmentReceivingOrder.getNurseStationId(), null, null, nurseAppletChatConfig.getReceivingOrdersOperationsTemplateId());
if (CollectionUtils.isEmpty(personSubscribe)) {
return;
}
//循环发送
AppletAccessToken appletAccessToken = getAppletAccessToken();
for (PersonSubscribeMessageVO personSubscribeMessage : personSubscribe) {
boolean subscribeMessage = Objects.nonNull(personSubscribeMessage)
&& StringUtils.isNotBlank(personSubscribeMessage.getSubscribeStatus())
&& SubscribeStatusEnum.ACCEPT.getInfo().equals(personSubscribeMessage.getSubscribeStatus());
if (BooleanUtils.isTrue(subscribeMessage)) {
//构建微信小程序消息推送参数
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("template_id", StringUtils.isBlank(personSubscribeMessage.getTemplateId()) ? "" : personSubscribeMessage.getTemplateId());
paramsMap.put("page", nurseAppletPageConfig.getNursePageUrl());
paramsMap.put("touser", StringUtils.isBlank(personSubscribeMessage.getOpenid()) ? "" : personSubscribeMessage.getOpenid());
paramsMap.put("lang", "zh_CN");
//构建微信小程序消息推送内容参数
Map<String, MessageValueEntity> amountParamMap = new HashMap<>();
//服务师傅
amountParamMap.put("thing15", new MessageValueEntity(StringUtils.isBlank(appointmentReceivingOrder.getNursePersonName()) ? "" : appointmentReceivingOrder.getNursePersonName()));
//预约时间
String serviceDate = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(Objects.isNull(appointmentReceivingOrder.getServiceDate()) ? LocalDate.now() : appointmentReceivingOrder.getServiceDate());
LocalTime serviceStartTime = Objects.isNull(appointmentReceivingOrder.getServiceStartTime()) ? LocalTime.now() : appointmentReceivingOrder.getServiceStartTime();
amountParamMap.put("time11", new MessageValueEntity(serviceDate + " " + serviceStartTime));
//地点
String serviceAddress = StringUtils.isBlank(appointmentReceivingOrder.getServiceAddress()) ? "" : appointmentReceivingOrder.getServiceAddress();
if (StringUtils.isNotBlank(serviceAddress) && appointmentReceivingOrder.getServiceAddress().length() > 20) {
serviceAddress = appointmentReceivingOrder.getServiceAddress().substring(0, 19);
}
amountParamMap.put("thing9", new MessageValueEntity(serviceAddress));
//电话
amountParamMap.put("phone_number8", new MessageValueEntity(StringUtils.isBlank(appointmentReceivingOrder.getPhone()) ? "" : appointmentReceivingOrder.getPhone()));
//业主
amountParamMap.put("thing7", new MessageValueEntity(StringUtils.isBlank(appointmentReceivingOrder.getPatientName()) ? "" : appointmentReceivingOrder.getPatientName()));
paramsMap.put("data", amountParamMap);
//发送
this.sendPosts(appletAccessToken, paramsMap);
}
}
}
/**
* 拒单通知运营人员
*
* @param appointmentReceivingOrder 订单信息表
**/
@Override
@Async("asyncThreadServiceExecutor")
public void refusalOrdersOperationsPush(AppointmentReceivingOrderVO appointmentReceivingOrder) {
//根据护理人员id去查询护理人员角色是否是护理站管理人员
log.info("预约订单拒单消息提醒,订单参数:{}", appointmentReceivingOrder);
List<PersonSubscribeMessageVO> personSubscribe = personSubscribeMessageMapper.selectPersonSubscribeMessageByPersonWechatId(appointmentReceivingOrder.getNurseStationId(), null, null, nurseAppletChatConfig.getRefusalOrdersOperationsTemplateId());
if (CollectionUtils.isEmpty(personSubscribe)) {
return;
}
//循环发送
AppletAccessToken appletAccessToken = getAppletAccessToken();
for (PersonSubscribeMessageVO personSubscribeMessage : personSubscribe) {
boolean subscribeMessage = Objects.nonNull(personSubscribeMessage)
&& StringUtils.isNotBlank(personSubscribeMessage.getSubscribeStatus())
&& SubscribeStatusEnum.ACCEPT.getInfo().equals(personSubscribeMessage.getSubscribeStatus());
if (BooleanUtils.isTrue(subscribeMessage)) {
//构建微信小程序消息推送参数
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("template_id", StringUtils.isBlank(personSubscribeMessage.getTemplateId()) ? "" : personSubscribeMessage.getTemplateId());
paramsMap.put("page", nurseAppletPageConfig.getNursePageUrl());
paramsMap.put("touser", StringUtils.isBlank(personSubscribeMessage.getOpenid()) ? "" : personSubscribeMessage.getOpenid());
paramsMap.put("lang", "zh_CN");
//构建微信小程序消息推送内容参数
Map<String, MessageValueEntity> amountParamMap = new HashMap<>();
//订单编号
amountParamMap.put("character_string3", new MessageValueEntity(StringUtils.isBlank(appointmentReceivingOrder.getOrderNo()) ? "" : appointmentReceivingOrder.getOrderNo()));
//服务内容
amountParamMap.put("thing1", new MessageValueEntity(StringUtils.isBlank(appointmentReceivingOrder.getNurseItemName()) ? "" : appointmentReceivingOrder.getNurseItemName()));
//服务时间
String serviceDate = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(Objects.isNull(appointmentReceivingOrder.getServiceDate()) ? LocalDate.now() : appointmentReceivingOrder.getServiceDate());
LocalTime serviceStartTime = Objects.isNull(appointmentReceivingOrder.getServiceStartTime()) ? LocalTime.now() : appointmentReceivingOrder.getServiceStartTime();
amountParamMap.put("time4", new MessageValueEntity(serviceDate + " " + serviceStartTime));
//服务地点
String serviceAddress = StringUtils.isBlank(appointmentReceivingOrder.getServiceAddress()) ? "" : appointmentReceivingOrder.getServiceAddress();
if (StringUtils.isNotBlank(serviceAddress) && appointmentReceivingOrder.getServiceAddress().length() > 20) {
serviceAddress = appointmentReceivingOrder.getServiceAddress().substring(0, 19);
}
amountParamMap.put("thing5", new MessageValueEntity(serviceAddress));
//拒单理由
String taskReturnReason = StringUtils.isBlank(appointmentReceivingOrder.getTaskReturnReason()) ? "" : appointmentReceivingOrder.getTaskReturnReason();
String[] split = StringUtils.split(taskReturnReason, ";");
if (split.length > 0) {
taskReturnReason = split[0];
if (StringUtils.isNotBlank(taskReturnReason) && taskReturnReason.length() > 20) {
taskReturnReason = taskReturnReason.substring(0, 19);
}
}
amountParamMap.put("thing6", new MessageValueEntity(taskReturnReason));
paramsMap.put("data", amountParamMap);
//发送
this.sendPosts(appletAccessToken, paramsMap);
}
}
}
/**
* 订单完成通知运营人员
*
* @param appointmentOrderRecordVO 订单信息表
**/
@Override
@Async("asyncThreadServiceExecutor")
public void orderCompletionOperationsPush(AppointmentOrderRecordVO appointmentOrderRecordVO) {
//根据护理人员id去查询护理人员角色是否是护理站管理人员
log.info("预约订单完成消息提醒,订单参数:{}", appointmentOrderRecordVO);
List<PersonSubscribeMessageVO> personSubscribe = personSubscribeMessageMapper.selectPersonSubscribeMessageByPersonWechatId(appointmentOrderRecordVO.getNurseStationId(), null, null, nurseAppletChatConfig.getOrderCompletionOperationsTemplateId());
if (CollectionUtils.isEmpty(personSubscribe)) {
return;
}
//循环发送
AppletAccessToken appletAccessToken = getAppletAccessToken();
for (PersonSubscribeMessageVO personSubscribeMessage : personSubscribe) {
boolean subscribeMessage = Objects.nonNull(personSubscribeMessage)
&& StringUtils.isNotBlank(personSubscribeMessage.getSubscribeStatus())
&& SubscribeStatusEnum.ACCEPT.getInfo().equals(personSubscribeMessage.getSubscribeStatus());
if (BooleanUtils.isTrue(subscribeMessage)) {
//构建微信小程序消息推送参数
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("template_id", StringUtils.isBlank(personSubscribeMessage.getTemplateId()) ? "" : personSubscribeMessage.getTemplateId());
paramsMap.put("page", nurseAppletPageConfig.getNursePageUrl());
paramsMap.put("touser", StringUtils.isBlank(personSubscribeMessage.getOpenid()) ? "" : personSubscribeMessage.getOpenid());
paramsMap.put("lang", "zh_CN");
//构建微信小程序消息推送内容参数
Map<String, MessageValueEntity> amountParamMap = new HashMap<>();
//订单编号
amountParamMap.put("character_string5", new MessageValueEntity(StringUtils.isBlank(appointmentOrderRecordVO.getOrderNo()) ? "" : appointmentOrderRecordVO.getOrderNo()));
//服务内容
amountParamMap.put("thing6", new MessageValueEntity(StringUtils.isBlank(appointmentOrderRecordVO.getNurseItemName()) ? "" : appointmentOrderRecordVO.getNurseItemName()));
//服务金额
BigDecimal totalPrice = Objects.isNull(appointmentOrderRecordVO.getTotalPrice()) ? BigDecimal.ZERO : appointmentOrderRecordVO.getTotalPrice();
amountParamMap.put("amount8", new MessageValueEntity(totalPrice + ""));
//骑手和电话
amountParamMap.put("thing21", new MessageValueEntity((StringUtils.isBlank(appointmentOrderRecordVO.getNursePersonName()) ? "" : appointmentOrderRecordVO.getNursePersonName()) + " " + (StringUtils.isBlank(appointmentOrderRecordVO.getPhone()) ? "" : appointmentOrderRecordVO.getPhone())));
//订单地址
String serviceAddress = StringUtils.isBlank(appointmentOrderRecordVO.getServiceAddress()) ? "" : appointmentOrderRecordVO.getServiceAddress();
if (StringUtils.isNotBlank(serviceAddress) && appointmentOrderRecordVO.getServiceAddress().length() > 20) {
serviceAddress = appointmentOrderRecordVO.getServiceAddress().substring(0, 19);
}
amountParamMap.put("thing1", new MessageValueEntity(serviceAddress));
paramsMap.put("data", amountParamMap);
//发送
this.sendPosts(appletAccessToken, paramsMap);
}
}
}
/**
* 获取appletAccessToken
*
* @return com.xinyilu.common.entity.AppletAccessToken
**/
private AppletAccessToken getAppletAccessToken() {
//获取AppletAccessToken的值
AppletAccessToken appletAccessToken = AppletChatUtil.getAppletAccessToken(nurseAppletChatConfig.getAppletId(), nurseAppletChatConfig.getSecret());
if (Objects.isNull(appletAccessToken)) {
log.error("获取微信小程序accessToken信息失败");
}
if (Objects.nonNull(appletAccessToken.getErrcode()) && appletAccessToken.getErrcode() != AppletSubscriptionMessageEnum.SUCCESS_ERRCODE.getValue()) {
log.error("获取微信小程序accessToken信息失败失败信息为" + appletAccessToken.getErrmsg(), 201);
}
if (StringUtils.isBlank(appletAccessToken.getAccessToken())) {
log.error("accessToken信息为空");
}
return appletAccessToken;
}
/**
* 发送
*
* @param appletAccessToken 令牌
* @param paramsMap 模板
**/
@Override
public void sendPosts(AppletAccessToken appletAccessToken, Map<String, Object> paramsMap) {
//拼接请求地址并发送
String messageUrl = MESSAGE_PUSH_URL + appletAccessToken.getAccessToken();
String param = JSON.toJSONString(paramsMap);
String result = HttpUtils.sendPostJson(messageUrl, param);
//返回参数映射
AppletAccessToken errCode = JSON.parseObject(result, AppletAccessToken.class);
if (Objects.nonNull(errCode) && Objects.nonNull(errCode.getErrcode())) {
switch (errCode.getErrcode()) {
case Constants.SUCCESS_ERRCODE:
log.info("发送消息成功!");
break;
case Constants.INVALID_CREDENTIAL_ACCESS_TOKEN_ISINVALID_OR_NOT_LATEST:
log.error("取 access_token 时 AppSecret 错误,或者 access_token 无效!");
break;
case Constants.INVALID_OPENID:
log.error("不合法的 OpenId");
break;
case Constants.INVALID_ACCESS_TOKEN:
log.error("合法的 access_token");
break;
case Constants.INVALID_TEMPLATE_ID:
log.error("不合法的 template_id");
break;
case Constants.ARGUMENT_INVALID:
log.error("参数无效!");
break;
case Constants.DENY_SUBSCRIPTION:
log.error("用户拒接订阅!");
break;
default:
break;
}
}
}
}

View File

@ -1,73 +0,0 @@
package com.xinelu.manage.service.stationmessagepush;
import com.xinelu.common.entity.AppletAccessToken;
import com.xinelu.manage.domain.appointmentorder.AppointmentOrder;
import com.xinelu.manage.domain.personsubscribemessage.PersonSubscribeMessage;
import com.xinelu.manage.vo.appointmentorder.AppointmentOrderInfoVO;
import com.xinelu.manage.vo.appointmentorder.AppointmentOrderRecordVO;
import com.xinelu.manage.vo.appointmentorder.AppointmentReceivingOrderVO;
import com.xinelu.manage.vo.stationmessagepush.WaitReceiveMessagePushVO;
import java.util.Map;
/**
* 派单消息推送Service接口
*
* @author zh
* @date 2023-04-03
*/
public interface StationMessagePushService {
/**
* 派单后提醒护理员接单提醒
*
* @param appointmentOrder 订单信息
*/
void waitReceiveMessagePush(AppointmentOrder appointmentOrder);
/**
* 服务代派单通知运营人员
*
* @param appointmentOrderInfo 订单信息表
**/
void serviceDispatchOperationsPush(AppointmentOrderInfoVO appointmentOrderInfo);
/**
* 接单提醒通知运营人员
*
* @param appointmentReceivingOrder 订单信息表
**/
void receivingOrdersOperationsPush(AppointmentReceivingOrderVO appointmentReceivingOrder);
/**
* 拒单通知运营人员
*
* @param appointmentReceivingOrder 订单信息表
**/
void refusalOrdersOperationsPush(AppointmentReceivingOrderVO appointmentReceivingOrder);
/**
* 订单完成通知运营人员
*
* @param appointmentOrderRecordVO 订单信息表
**/
void orderCompletionOperationsPush(AppointmentOrderRecordVO appointmentOrderRecordVO);
/**
* 发送
*
* @param appletAccessToken 令牌
* @param paramsMap 模板
**/
void sendPosts(AppletAccessToken appletAccessToken, Map<String, Object> paramsMap);
/**
* 待接单消息推送
*
* @param appletAccessToken 令牌
* @param dispatchOrderDetails 订单信息
* @param personSubscribeMessage 订阅消息记录
*/
void waitReceiveMessage(WaitReceiveMessagePushVO dispatchOrderDetails, PersonSubscribeMessage personSubscribeMessage, AppletAccessToken appletAccessToken);
}