PC端-小程序商城模块移植,个人中心积分相关移植

This commit is contained in:
纪寒 2023-09-22 16:44:36 +08:00
parent 940599b2f8
commit 333431d14a
77 changed files with 8267 additions and 4 deletions

View File

@ -34,6 +34,7 @@
<velocity.version>2.3</velocity.version>
<jwt.version>0.9.1</jwt.version>
<lombok.version>1.18.4</lombok.version>
<simple-xml.version>2.7.1</simple-xml.version>
</properties>
<!-- 依赖声明 -->
@ -220,6 +221,13 @@
<artifactId>xinelu-nurse-applet</artifactId>
<version>${xinelu.version}</version>
</dependency>
<!-- xml文件序列化和反序列化 -->
<dependency>
<groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId>
<version>${simple-xml.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -151,24 +151,23 @@
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>1.12.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<!--糊涂工具 https://github.com/looly/hutool/-->
<dependency>
@ -176,10 +175,16 @@
<artifactId>hutool-all</artifactId>
<version>5.4.7</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-redis</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,39 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* @Description 购买来源枚举
* @Author 纪寒
* @Date 2022-10-19 16:46:39
* @Version 1.0
*/
@Getter
public enum BuySourceEnum {
/**
* 护理站
*/
NURSE_STATION("NURSE_STATION"),
/**
* 商城
*/
SHOPPING_MALL("SHOPPING_MALL"),
/**
* 健康咨询健康咨询订单使用
*/
HEALTH_CONSULTATION("HEALTH_CONSULTATION"),
/**
* 学习培训泉医助手学习培训订单使用
*/
TRAINING("TRAINING"),
;
final private String info;
BuySourceEnum(String info) {
this.info = info;
}
}

View File

@ -0,0 +1,28 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* @Description 积分兑换标识优惠券抵扣标识积分抵扣标识
* @Author zh
* @Date 2023-02-27
*/
@Getter
public enum CouponAndIntegralFlagEnum {
/**
* 可兑换抵扣
*/
CONVERTIBLE(1),
/**
* 不可兑换抵扣
*/
NOT_CONVERTIBLE(0),
;
final private Integer info;
CouponAndIntegralFlagEnum(Integer info) {
this.info = info;
}
}

View File

@ -0,0 +1,34 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* @Description 优惠券领取使用方式枚举
* @Author 纪寒
* @Date 2023-02-24 11:09:31
* @Version 1.0
*/
@Getter
public enum CouponReceiveTypeEnum {
/**
* 新人福利
*/
NEW_PEOPLE_WELFARE("NEW_PEOPLE_WELFARE"),
/**
* 活动赠送
*/
EVENT_GIFT("EVENT_GIFT"),
/**
* 消费返券
*/
CONSUME_REBATE("CONSUME_REBATE"),
;
final private String info;
CouponReceiveTypeEnum(String info) {
this.info = info;
}
}

View File

@ -0,0 +1,39 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* @Description 优惠券类型枚举
* @Author 纪寒
* @Date 2023-02-24 10:56:26
* @Version 1.0
*/
@Getter
public enum CouponTypeEnum {
/**
* 满减券
*/
FULL_REDUCTION_COUPON("FULL_REDUCTION_COUPON"),
/**
* 代金券
*/
CASH_COUPON("CASH_COUPON"),
/**
* 兑换券
*/
EXCHANGE_COUPON("EXCHANGE_COUPON"),
/**
* 折扣券
*/
DISCOUNT_COUPON("DISCOUNT_COUPON"),
;
final private String info;
CouponTypeEnum(String info) {
this.info = info;
}
}

View File

@ -0,0 +1,40 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* @Description 优惠券使用状态枚举
* @Author 纪寒
* @Date 2023-02-24 10:48:54
* @Version 1.0
*/
@Getter
public enum CouponUseStatusEnum {
/**
* 待领取
*/
WAIT_RECEIVE("WAIT_RECEIVE"),
/**
* 未使用
*/
NOT_USED("NOT_USED"),
/**
* 已使用
*/
USED("USED"),
/**
* 已过期
*/
EXPIRED("EXPIRED"),
;
final private String info;
CouponUseStatusEnum(String info) {
this.info = info;
}
}

View File

@ -0,0 +1,28 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* @Description 商品用途标识
* @Author zh
* @Date 2023-02-27
*/
@Getter
public enum GoodsPurposeEnum {
/**
* 买卖
*/
BUSINESS("BUSINESS"),
/**
* 租赁
*/
LEASE("LEASE"),
;
final private String info;
GoodsPurposeEnum(String info) {
this.info = info;
}
}

View File

@ -0,0 +1,39 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* @Description 积分变动类型枚举
* @Author 纪寒
* @Date 2023-02-27 14:22:22
* @Version 1.0
*/
@Getter
public enum IntegralChangeType {
/**
* 商品兑换
*/
COMMODITY_EXCHANGE("COMMODITY_EXCHANGE"),
/**
* 好友邀请
*/
FRIEND_INVITATION("FRIEND_INVITATION"),
/**
* 观看视频
*/
WATCH_VIDEO("WATCH_VIDEO"),
/**
* 会员签到
*/
SIGN_IN("SIGN_IN"),
;
final private String info;
IntegralChangeType(String info) {
this.info = info;
}
}

View File

@ -0,0 +1,34 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* @Description 订单类型枚举
* @Author ljh
* @Version 1.0
*/
@Getter
public enum OrderTypeEnum {
/**
* 积分兑换
*/
INTEGRAL_EXCHANGE("INTEGRAL_EXCHANGE"),
/**
* 直接购买
*/
DIRECT_BUY("DIRECT_BUY"),
/**
* 健康咨询
*/
HEALTH_CONSULTATION("HEALTH_CONSULTATION"),
;
final private String info;
OrderTypeEnum(String info) {
this.info = info;
}
}

View File

@ -0,0 +1,39 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* @Description 微信小程序订阅消息记录表 订阅消息类型枚举
* @Author LJH
* @Version 1.0
*/
@Getter
public enum SubscribeMessageTypeEnum {
/**
* 预约服务付款通知提醒
*/
APPOINT_ORDER_MESSAGE_PUSH("APPOINT_ORDER_MESSAGE_PUSH"),
/**
* 优惠券领取提醒
*/
COUPON_RECEIVE_MESSAGE_PUSH("COUPON_RECEIVE_MESSAGE_PUSH"),
/**
* 商品订单支付成功提醒
*/
GOODS_ORDER_MESSAGE_PUSH("GOODS_ORDER_MESSAGE_PUSH"),
/**
* 签到积分通知提醒
*/
SIGN_MESSAGE_PUSH("SIGN_MESSAGE_PUSH"),
;
final private String info;
SubscribeMessageTypeEnum(String info) {
this.info = info;
}
}

View File

@ -0,0 +1,32 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* @Description 是否上架枚举
* @Author 纪寒
* @Date 2022-12-23 14:11:44
* @Version 1.0
*/
@Getter
public enum WhetherShelfEnum {
/**
* 已上架
*/
SHEL(1),
/**
* 未上架
*/
NOT_SHEL(0),
;
final private Integer info;
WhetherShelfEnum(Integer info) {
this.info = info;
}
}

View File

@ -0,0 +1,92 @@
package com.xinelu.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
/**
* @Description Redis锁工具类
* @Author 纪寒
* @Date 2022-10-24 10:00:00
* @Version 1.0
*/
@SuppressWarnings("unused")
@Slf4j
@Component
public class RedisDistributedLockUtils {
/**
* 默认的有效时长
*/
private static final long DEFAULT_EXPIRE_UNUSED = 30000L;
@Resource
private RedisLockRegistry redisLockRegistry;
/**
* 加锁
*
* @param lockKey
*/
@SuppressWarnings("AlibabaLockShouldWithTryFinally")
public void lock(String lockKey) {
Lock lock = obtainLock(lockKey);
lock.lock();
}
/**
* 尝试获取锁
*
* @param lockKey
* @return 结果
*/
public boolean tryLock(String lockKey) {
Lock lock = obtainLock(lockKey);
return lock.tryLock();
}
/**
* 尝试获取锁带有时间单位
*
* @param lockKey
* @param seconds 时间单位秒
* @return 结果
*/
public boolean tryLock(String lockKey, long seconds) {
Lock lock = obtainLock(lockKey);
try {
return lock.tryLock(seconds, TimeUnit.SECONDS);
} catch (InterruptedException e) {
return false;
}
}
/**
* 释放锁
*
* @param lockKey
*/
public void unlock(String lockKey) {
try {
Lock lock = obtainLock(lockKey);
lock.unlock();
redisLockRegistry.expireUnusedOlderThan(DEFAULT_EXPIRE_UNUSED);
} catch (Exception e) {
log.warn("分布式锁 [{}] 释放异常", lockKey, e);
}
}
/**
* 释放锁
*
* @param lockKey
* @return 结果
*/
private Lock obtainLock(String lockKey) {
return redisLockRegistry.obtain(lockKey);
}
}

View File

@ -0,0 +1,55 @@
package com.xinelu.common.utils.aes;
/**
* @Description 微信AES解密异常信息类
* @Author WeChat
* @Date 2023-03-14 15:09:50
*/
@SuppressWarnings("serial")
public class AesException extends Exception {
public final static int OK = 0;
public final static int VALIDATE_SIGNATURE_ERROR = -40001;
public final static int PARSE_XML_ERROR = -40002;
public final static int COMPUTE_SIGNATURE_ERROR = -40003;
public final static int ILLEGAL_AES_KEY = -40004;
public final static int VALIDATE_APP_ID_ERROR = -40005;
public final static int ENCRYPT_AES_ERROR = -40006;
public final static int DECRYPT_AES_ERROR = -40007;
public final static int ILLEGAL_BUFFER = -40008;
private final int code;
private static String getMessage(int code) {
switch (code) {
case VALIDATE_SIGNATURE_ERROR:
return "签名验证错误";
case PARSE_XML_ERROR:
return "xml解析失败";
case COMPUTE_SIGNATURE_ERROR:
return "sha加密生成签名失败";
case ILLEGAL_AES_KEY:
return "SymmetricKey非法";
case VALIDATE_APP_ID_ERROR:
return "appid校验失败";
case ENCRYPT_AES_ERROR:
return "aes加密失败";
case DECRYPT_AES_ERROR:
return "aes解密失败";
case ILLEGAL_BUFFER:
return "解密后得到的buffer非法";
default:
return null;
}
}
public int getCode() {
return code;
}
AesException(int code) {
super(getMessage(code));
this.code = code;
}
}

View File

@ -0,0 +1,31 @@
package com.xinelu.common.utils.aes;
import java.util.ArrayList;
import java.util.List;
/**
* @Description 字节数组
* @Author WeChat
* @Date 2023-03-14 15:09:50
*/
class ByteGroup {
List<Byte> byteContainer = new ArrayList<>();
public byte[] toBytes() {
byte[] bytes = new byte[byteContainer.size()];
for (int i = 0; i < byteContainer.size(); i++) {
bytes[i] = byteContainer.get(i);
}
return bytes;
}
public void addBytes(byte[] bytes) {
for (byte b : bytes) {
byteContainer.add(b);
}
}
public int size() {
return byteContainer.size();
}
}

View File

@ -0,0 +1,62 @@
package com.xinelu.common.utils.aes;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
/**
* @Description 提供基于PKCS7算法的加解密接口
* @Author WeChat
* @Date 2023-03-14 15:09:50
*/
class PKCS7Encoder {
static Charset CHARSET = StandardCharsets.UTF_8;
static int BLOCK_SIZE = 32;
/**
* 获得对明文进行补位填充的字节.
*
* @param count 需要进行填充补位操作的明文字节个数
* @return 补齐用的字节数组
*/
static byte[] encode(int count) {
// 计算需要填充的位数
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
if (amountToPad == 0) {
amountToPad = BLOCK_SIZE;
}
// 获得补位所用的字符
char padChr = chr(amountToPad);
StringBuilder tmp = new StringBuilder();
for (int index = 0; index < amountToPad; index++) {
tmp.append(padChr);
}
return tmp.toString().getBytes(CHARSET);
}
/**
* 删除解密后明文的补位字符
*
* @param decrypted 解密后的明文
* @return 删除补位字符后的明文
*/
static byte[] decode(byte[] decrypted) {
int pad = decrypted[decrypted.length - 1];
if (pad < 1 || pad > 32) {
pad = 0;
}
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}
/**
* 将数字转化成ASCII码对应的字符用于对明文进行补码
*
* @param a 需要转化的数字
* @return 转化得到的字符
*/
static char chr(int a) {
byte target = (byte) (a & 0xFF);
return (char) target;
}
}

View File

@ -0,0 +1,94 @@
package com.xinelu.common.utils.aes;
import org.apache.commons.lang3.BooleanUtils;
import java.security.MessageDigest;
import java.util.Arrays;
/**
* SHA1 class
* <p>
*
* @Description 计算公众平台的消息签名接口
* @Author WeChat
* @Date 2023-03-14 15:09:50
*/
class SHA1 {
/**
* 用SHA1算法生成安全签名
*
* @param token 票据
* @param timestamp 时间戳
* @param nonce 随机字符串
* @param encrypt 密文
* @return 安全签名
* @throws AesException 异常信息
*/
public static String getShaOne(String token, String timestamp, String nonce, String encrypt) throws AesException {
return signatureByShaOne(token, timestamp, nonce, encrypt, true);
}
/**
* 用SHA1算法生成安全签名小程序回调设置验证URL时计算签名使用
*
* @param token 票据
* @param timestamp 时间戳
* @param nonce 随机字符串
* @return 安全签名
* @throws AesException 异常信息
*/
public static String getShaTwo(String token, String timestamp, String nonce) throws AesException {
return signatureByShaOne(token, timestamp, nonce, "", false);
}
/**
* 使用SHA-1计算签名公共方法
*
* @param token 令牌
* @param timestamp 时间粗
* @param nonce 随机字符串
* @param encrypt 密文
* @param encryptFlag 密文传入标识
* @return String 明文
* @throws AesException 异常信息
*/
private static String signatureByShaOne(String token, String timestamp, String nonce, String encrypt, boolean encryptFlag) throws AesException {
try {
String[] array;
int size;
if (BooleanUtils.isTrue(encryptFlag)) {
array = new String[]{token, timestamp, nonce, encrypt};
size = 4;
} else {
array = new String[]{token, timestamp, nonce};
size = 3;
}
StringBuilder sb = new StringBuilder();
// 字符串排序
Arrays.sort(array);
for (int i = 0; i < size; i++) {
sb.append(array[i]);
}
String str = sb.toString();
// SHA1签名生成
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuilder hexStr = new StringBuilder();
String shaHex;
for (byte b : digest) {
shaHex = Integer.toHexString(b & 0xFF);
if (shaHex.length() < 2) {
hexStr.append(0);
}
hexStr.append(shaHex);
}
return hexStr.toString();
} catch (Exception e) {
e.printStackTrace();
throw new AesException(AesException.COMPUTE_SIGNATURE_ERROR);
}
}
}

View File

@ -0,0 +1,234 @@
package com.xinelu.common.utils.aes;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Random;
/**
* @Description 提供接收和推送给公众平台消息的加解密接口(UTF8编码的字符串).
* @Author WeChat
* @Date 2023-03-14 15:09:50
*/
public class WXBizMsgCrypt {
static Charset CHARSET = StandardCharsets.UTF_8;
Base64 base64 = new Base64();
byte[] aesKey;
String token;
String appId;
/**
* 构造函数
*
* @param token 公众平台上开发者设置的token
* @param encodingAesKey 公众平台上开发者设置的EncodingAESKey
* @param appId 公众平台appid
* @throws AesException 执行失败请查看该异常的错误码和具体的错误信息
*/
public WXBizMsgCrypt(String token, String encodingAesKey, String appId) throws AesException {
int length = 43;
if (encodingAesKey.length() != length) {
throw new AesException(AesException.ILLEGAL_AES_KEY);
}
this.token = token;
this.appId = appId;
aesKey = Base64.decodeBase64(encodingAesKey + "=");
}
/**
* 生成4个字节的网络字节序
*
* @param sourceNumber 数值
* @return 字节数组
*/
byte[] getNetworkBytesOrder(int sourceNumber) {
byte[] orderBytes = new byte[4];
orderBytes[3] = (byte) (sourceNumber & 0xFF);
orderBytes[2] = (byte) (sourceNumber >> 8 & 0xFF);
orderBytes[1] = (byte) (sourceNumber >> 16 & 0xFF);
orderBytes[0] = (byte) (sourceNumber >> 24 & 0xFF);
return orderBytes;
}
/**
* 还原4个字节的网络字节序
*
* @param orderBytes 字节数组
* @return 数值
*/
int recoverNetworkBytesOrder(byte[] orderBytes) {
int sourceNumber = 0;
for (int i = 0; i < 4; i++) {
sourceNumber <<= 8;
sourceNumber |= orderBytes[i] & 0xff;
}
return sourceNumber;
}
/**
* 随机生成16位字符串
*
* @return 随机字符串
*/
String getRandomStr() {
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 16; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
/**
* 对明文进行加密.
*
* @param text 需要加密的明文
* @return 加密后base64编码的字符串
* @throws AesException aes加密失败
*/
String encrypt(String randomStr, String text) throws AesException {
ByteGroup byteCollector = new ByteGroup();
byte[] randomStrBytes = randomStr.getBytes(CHARSET);
byte[] textBytes = text.getBytes(CHARSET);
byte[] networkBytesOrder = getNetworkBytesOrder(textBytes.length);
byte[] appidBytes = appId.getBytes(CHARSET);
// randomStr + networkBytesOrder + text + appid
byteCollector.addBytes(randomStrBytes);
byteCollector.addBytes(networkBytesOrder);
byteCollector.addBytes(textBytes);
byteCollector.addBytes(appidBytes);
// ... + pad: 使用自定义的填充方式对明文进行补位填充
byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
byteCollector.addBytes(padBytes);
// 获得最终的字节流, 未加密
byte[] unencrypted = byteCollector.toBytes();
try {
// 设置加密模式为AES的CBC模式
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
// 加密
byte[] encrypted = cipher.doFinal(unencrypted);
// 使用BASE64对加密后的字符串进行编码
return base64.encodeToString(encrypted);
} catch (Exception e) {
e.printStackTrace();
throw new AesException(AesException.ENCRYPT_AES_ERROR);
}
}
/**
* 对密文进行解密.
*
* @param text 需要解密的密文
* @return 解密得到的明文
* @throws AesException aes解密失败
*/
String decrypt(String text) throws AesException {
byte[] original;
try {
// 设置解密模式为AES的CBC模式
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
// 使用BASE64对密文进行解码
byte[] encrypted = Base64.decodeBase64(text);
// 解密
original = cipher.doFinal(encrypted);
} catch (Exception e) {
e.printStackTrace();
throw new AesException(AesException.DECRYPT_AES_ERROR);
}
String xmlContent, fromAppid;
try {
// 去除补位字符
byte[] bytes = PKCS7Encoder.decode(original);
// 分离16位随机字符串,网络字节序和AppId
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
int xmlLength = recoverNetworkBytesOrder(networkOrder);
xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
fromAppid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length),
CHARSET);
} catch (Exception e) {
e.printStackTrace();
throw new AesException(AesException.ILLEGAL_BUFFER);
}
// appid不相同的情况
if (!fromAppid.equals(appId)) {
throw new AesException(AesException.VALIDATE_APP_ID_ERROR);
}
return xmlContent;
}
/**
* @param replyMsg 公众平台待回复用户的消息xml格式的字符串
* @param timeStamp 时间戳可以自己生成也可以用URL参数的timestamp
* @param nonce 随机串可以自己生成也可以用URL参数的nonce
* @return 加密后的可以直接回复用户的密文包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
* @throws AesException 执行失败请查看该异常的错误码和具体的错误信息
* @Description 将公众平台回复用户的消息加密打包.
*/
public String encryptMsg(String replyMsg, String timeStamp, String nonce) throws AesException {
// 加密
String encrypt = encrypt(getRandomStr(), replyMsg);
// 生成安全签名
if ("".equals(timeStamp)) {
timeStamp = Long.toString(System.currentTimeMillis());
}
String signature = SHA1.getShaOne(token, timeStamp, nonce, encrypt);
// 生成发送的xml
return XMLParse.generate(encrypt, signature, timeStamp, nonce);
}
/**
* @param msgSignature 签名串对应URL参数的msg_signature
* @param timeStamp 时间戳对应URL参数的timestamp
* @param nonce 随机串对应URL参数的nonce
* @param postData 密文对应POST请求的数据
* @return 解密后的原文
* @throws AesException 执行失败请查看该异常的错误码和具体的错误信息
* @Description 检验消息的真实性并且获取解密后的明文.
*/
public String decryptMsg(String msgSignature, String timeStamp, String nonce, String postData)
throws AesException {
// 密钥公众账号的app secret
// 提取密文
Object[] encrypt = XMLParse.extract(postData);
// 验证安全签名
String signature = SHA1.getShaTwo(token, timeStamp, nonce);
// 和URL中的签名比较是否相等
if (!signature.equals(msgSignature)) {
throw new AesException(AesException.VALIDATE_SIGNATURE_ERROR);
}
// 解密
return decrypt(encrypt[1].toString());
}
/**
* 验证URL
*
* @param msgSignature 签名串对应URL参数的msg_signature
* @param timeStamp 时间戳对应URL参数的timestamp
* @param nonce 随机串对应URL参数的nonce
* @param echoStr 随机串对应URL参数的echostr
* @return 原始的随机串echostr
* @throws AesException 执行失败请查看该异常的错误码和具体的错误信息
*/
public String verifyUrl(String msgSignature, String timeStamp, String nonce, String echoStr) throws AesException {
String signature = SHA1.getShaTwo(token, timeStamp, nonce);
if (!signature.equals(msgSignature)) {
throw new AesException(AesException.VALIDATE_SIGNATURE_ERROR);
}
return echoStr;
}
}

View File

@ -0,0 +1,68 @@
package com.xinelu.common.utils.aes;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
/**
* @Description 提供提取消息格式中的密文及生成回复消息格式的接口.
* @Author WeChat
* @Date 2023-03-14 15:09:50
*/
class XMLParse {
/**
* 提取出xml数据包中的加密消息
*
* @param xmltext 待提取的xml字符串
* @return 提取出的加密消息字符串
* @throws AesException 异常信息
*/
public static Object[] extract(String xmltext) throws AesException {
Object[] result = new Object[3];
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(xmltext);
InputSource is = new InputSource(sr);
Document document = db.parse(is);
Element root = document.getDocumentElement();
NodeList nodelist1 = root.getElementsByTagName("Encrypt");
NodeList nodelist2 = root.getElementsByTagName("ToUserName");
result[0] = 0;
result[1] = nodelist1.item(0).getTextContent();
result[2] = nodelist2.item(0).getTextContent();
return result;
} catch (Exception e) {
e.printStackTrace();
throw new AesException(AesException.PARSE_XML_ERROR);
}
}
/**
* 生成xml消息
*
* @param encrypt 加密后的消息密文
* @param signature 安全签名
* @param timestamp 时间戳
* @param nonce 随机字符串
* @return 生成的xml字符串
*/
public static String generate(String encrypt, String signature, String timestamp, String nonce) {
String format = "<xml>\n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>\n"
+ "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
+ "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n" + "</xml>";
return String.format(format, encrypt, signature, timestamp, nonce);
}
}

View File

@ -0,0 +1,86 @@
package com.xinelu.framework.aspectj;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.exception.ServiceException;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
/**
* @Description 移动端接口校验处理
* @Author 纪寒
* @Date 2022-12-09 10:55:53
* @Version 1.0
*/
@Slf4j
@Aspect
@Component
public class MobileRequestAuthorizationAspect {
/**
* 令牌秘钥标识
*/
@Value("${token.secret}")
private String secret;
/**
* 令牌自定义标识
*/
@Value("${token.header}")
private String header;
/**
* 移动端令牌前缀
*/
private static final String TOKEN_PREFIX = "Bearer ";
/**
* 移动端令牌前缀
*/
private static final Integer ERROR_CODE = 9999;
@Resource
private RedisTemplate<String, String> redisTemplate;
@Pointcut("execution(@com.xinelu.common.annotation.MobileRequestAuthorization * *(..))")
private void judgeTokenInfo() {
}
@Before("judgeTokenInfo()")
public void doJudgeTokenInfo() {
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
String requestHeader = request.getHeader(header);
if (StringUtils.isBlank(requestHeader)) {
log.warn("获取请求头中的Authorization令牌头部信息失败");
throw new ServiceException("验证签名错误,请重新登录!", ERROR_CODE);
}
try {
String token = request.getHeader(header).replaceAll(TOKEN_PREFIX, "");
if (StringUtils.isBlank(token)) {
log.warn("获取请求头中的Authorization令牌信息为空");
throw new ServiceException("验证签名错误,请重新登录!", ERROR_CODE);
}
String uuid = (String) Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().get(Constants.MOBILE_AUTHORIZATION_PREFIX);
String tokenString = redisTemplate.opsForValue().get(Constants.MOBILE_AUTHORIZATION_KEY + uuid);
if (StringUtils.isBlank(tokenString) || !StringUtils.equals(token, tokenString)) {
log.warn("Redis中的令牌信息已失效或者为空");
throw new ServiceException("验证签名错误,请重新登录!", ERROR_CODE);
}
} catch (Exception e) {
log.error("移动端验证签名异常,异常信息为=====>{}", e.getMessage());
throw new ServiceException("验证签名错误,请重新登录!", ERROR_CODE);
}
}
}

View File

@ -0,0 +1,39 @@
package com.xinelu.framework.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @Description 异步任务线程池配置类
* @Author 纪寒
* @Date 2023-03-17 09:55:36
* @Version 1.0
*/
@Slf4j
@Configuration
@EnableAsync
public class AsyncExecutorConfig {
/**
* 创建一个核心线程为10个最大线程为20等待队列为10拒绝策略为线程最大需求满就返回给调度线程执行
*
* @return 创建完的线程池
*/
@Bean
public Executor asyncThreadServiceExecutor() {
log.info("异步线程池配置执行");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(10);
executor.setThreadNamePrefix("async-thread-service-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
executor.initialize();
return executor;
}
}

View File

@ -0,0 +1,21 @@
package com.xinelu.framework.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.integration.redis.util.RedisLockRegistry;
/**
* @Description Redis分布式锁配置
* @Author 纪寒
* @Date 2022-10-26 15:27:41
* @Version 1.0
*/
@Configuration
public class RedisDistributedLockUtilsConfig {
@Bean
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
return new RedisLockRegistry(redisConnectionFactory, this.getClass().getName());
}
}

View File

@ -40,5 +40,11 @@
<artifactId>swagger-models</artifactId>
<version>1.6.2</version>
</dependency>
<!-- xml文件序列化和反序列化 -->
<dependency>
<groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,233 @@
package com.xinelu.applet.controller.nursingstationgoods;
import com.xinelu.applet.dto.nursingstationgoods.GoodsList;
import com.xinelu.applet.dto.nursingstationgoods.GoodsOrderPatient;
import com.xinelu.applet.dto.nursingstationgoods.GoodsOrderStationDTO;
import com.xinelu.applet.service.nursingstationgoods.INursingStationGoodsService;
import com.xinelu.applet.vo.nursingstationgoods.UpdateDefaultAddressVO;
import com.xinelu.common.annotation.MobileRequestAuthorization;
import com.xinelu.common.annotation.RepeatSubmit;
import com.xinelu.common.core.controller.BaseController;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.page.TableDataInfo;
import com.xinelu.common.custominterface.Insert;
import com.xinelu.common.custominterface.Update;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.manage.domain.goodsCategory.GoodsCategory;
import com.xinelu.manage.domain.receiveAddressInfo.ReceiveAddressInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
/**
* 商品信息页面控制器
*
* @author ljh
* @version 1.0
* Create by 2022/10/17 13:40
*/
@RestController
@RequestMapping("/nurseApplet/nursingStationGoods")
public class NursingStationGoodsController extends BaseController {
@Resource
private INursingStationGoodsService nursingStationGoodsService;
/**
* 查询商品分类信息列表
*/
@MobileRequestAuthorization
@GetMapping("/goodsCategoryList")
public TableDataInfo goodsCategoryList(GoodsCategory goodsCategory) {
startPage();
List<GoodsCategory> goodsCategoryList = nursingStationGoodsService.getGoodsCategoryList(goodsCategory);
return getDataTable(goodsCategoryList);
}
/**
* 查询商品二级分类信息列表
*/
@MobileRequestAuthorization
@GetMapping("/getGoodsCategoryNameList")
public AjaxResult getGoodsCategoryNameList(Long goodsCategoryId) {
if (Objects.isNull(goodsCategoryId)) {
return AjaxResult.error("商品分类信息id不能为空");
}
return nursingStationGoodsService.getGoodsCategoryNameList(goodsCategoryId);
}
/**
* 根据商品分类id查询商品信息
*
* @param goodsList 商品信息
* @return com.xinyilu.common.core.page.TableDataInfo
**/
@MobileRequestAuthorization
@GetMapping("/goodsList")
public TableDataInfo goodsList(GoodsList goodsList) {
return nursingStationGoodsService.getGoodsInfoList(goodsList);
}
/**
* 根据商品id查询商品详细信息
*
* @param goodsInfoId 商品详细id
* @param patientId 用户信息id
* @return com.xinyilu.nurseapplet.domain.nearbynursingstation.NearbyNursingStationVO
**/
@MobileRequestAuthorization
@GetMapping("/goodsDetails")
public AjaxResult goodsDetails(Long goodsInfoId, Long patientId) {
if (Objects.isNull(goodsInfoId)) {
return AjaxResult.error("商品id不能为空");
}
return AjaxResult.success(nursingStationGoodsService.getGoodsDetails(goodsInfoId, patientId));
}
/**
* 手机App和微信小程序商城确认订单方法
*
* @param goodsOrder 商品订单
* @return 结果
*/
@MobileRequestAuthorization
@RepeatSubmit
@PostMapping("/addStationGoodsOrder")
public AjaxResult addStationGoodsOrder(@Validated(Insert.class) @RequestBody GoodsOrderStationDTO goodsOrder, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new ServiceException(bindingResult.getAllErrors().get(0).getDefaultMessage());
}
if (Objects.nonNull(goodsOrder.getTotalPrice()) && goodsOrder.getTotalPrice().compareTo(BigDecimal.ZERO) <= 0) {
return AjaxResult.error("订单金额不正确,无法下单,请输入正确的订单金额!");
}
return nursingStationGoodsService.insertNurseStationGoodsOrder(goodsOrder);
}
/**
* 根据订单编号查询订单信息废弃暂时不用
*
* @param orderNo 订单信息编号
* @return com.xinyilu.nurseapplet.domain.nursingStationGoods.GoodsOrderPatient
**/
@GetMapping("/orderPatient")
public AjaxResult orderPatient(String orderNo) {
if (StringUtils.isBlank(orderNo)) {
return AjaxResult.error("订单编号不能为空!");
}
GoodsOrderPatient orderPatient = nursingStationGoodsService.selectGoodsOrderPatient(orderNo);
return AjaxResult.success(orderPatient);
}
/**
* 根据被护理人id查询基本信息
*
* @param patientId 被护理人id
* @return com.xinyilu.base.domain.patientinfo.PatientInfo
**/
@MobileRequestAuthorization
@GetMapping("/goodPatientInfo")
public AjaxResult goodPatientInfo(Long patientId) {
if (Objects.isNull(patientId)) {
return AjaxResult.error("会员信息不能为空!");
}
return nursingStationGoodsService.getReceiveAddressInfoList(patientId);
}
/**
* 获取收货人地址信息详细信息
*/
@MobileRequestAuthorization
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return AjaxResult.success(nursingStationGoodsService.selectReceiveAddressInfoById(id));
}
/**
* 新增收货人地址信息
*/
@MobileRequestAuthorization
@PostMapping("/add")
public AjaxResult add(@Validated(Insert.class) @RequestBody ReceiveAddressInfo receiveAddressInfo, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new ServiceException(bindingResult.getAllErrors().get(0).getDefaultMessage());
}
return toAjax(nursingStationGoodsService.insertReceiveAddressInfo(receiveAddressInfo));
}
/**
* 修改收货人地址信息
*/
@MobileRequestAuthorization
@PostMapping("/edit")
public AjaxResult edit(@Validated(Update.class) @RequestBody ReceiveAddressInfo receiveAddressInfo, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new ServiceException(bindingResult.getAllErrors().get(0).getDefaultMessage());
}
return toAjax(nursingStationGoodsService.updateReceiveAddressInfo(receiveAddressInfo));
}
/**
* 删除收货人地址信息
*/
@MobileRequestAuthorization
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(nursingStationGoodsService.deleteReceiveAddressInfoByIds(ids));
}
/**
* 获取区域详细信息
*/
@MobileRequestAuthorization
@GetMapping("/getSubordinateRegions")
public AjaxResult getSubordinateRegionsFindSuperiorRegions(@RequestParam("areaCode") String areaCode) {
if (StringUtils.isBlank(areaCode)) {
return AjaxResult.error("区域编码不能为空!");
}
return AjaxResult.success(nursingStationGoodsService.getSubordinateRegionsFindSuperiorRegions(areaCode));
}
/**
* App和微信小程序确认收货
*
* @param orderNo 订单编号
* @return 返回结果
*/
@MobileRequestAuthorization
@PostMapping("/confirmReceipt")
public AjaxResult confirmReceipt(String orderNo) {
if (StringUtils.isBlank(orderNo)) {
return AjaxResult.error("请选择订单信息!");
}
return nursingStationGoodsService.confirmReceipt(orderNo);
}
/**
* 微信小程序和会员App设置默认地址接口
*
* @param defaultAddressList 默认地址标识集合
* @return 结果
*/
@PostMapping("/updateDefaultAddress")
public AjaxResult updateDefaultAddress(@RequestBody @Validated(Update.class) List<UpdateDefaultAddressVO> defaultAddressList) {
if (CollectionUtils.isEmpty(defaultAddressList)) {
return AjaxResult.error("请选择要设置的收货地址信息!");
}
return nursingStationGoodsService.updateDefaultAddress(defaultAddressList);
}
}

View File

@ -0,0 +1,197 @@
package com.xinelu.applet.controller.patientcenter;
import com.xinelu.applet.dto.nursingstationgoods.GoodsList;
import com.xinelu.applet.dto.nursingstationgoods.GoodsOrderStationDTO;
import com.xinelu.applet.dto.patientcenter.PatientCenterCouponDTO;
import com.xinelu.applet.service.patientcenter.PatientCenterService;
import com.xinelu.applet.vo.coupon.CouponVO;
import com.xinelu.applet.vo.patientcenter.PatientCenterCouponVO;
import com.xinelu.common.annotation.MobileRequestAuthorization;
import com.xinelu.common.annotation.RepeatSubmit;
import com.xinelu.common.core.controller.BaseController;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.page.TableDataInfo;
import com.xinelu.common.custominterface.Insert;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.manage.dto.subscribemessagerecord.SubscribeMessageRecordDTO;
import com.xinelu.manage.service.patientinfo.IPatientInfoService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
/**
* 被护理人基本信息Controller
*
* @author zhangheng
* @date 2022-09-02
*/
@RestController
@RequestMapping("/nurseApplet/patientInfo")
public class PatientCenterController extends BaseController {
@Resource
private IPatientInfoService patientInfoService;
@Resource
private PatientCenterService patientCenterService;
/**
* 根据登录id查询个人信息
*
* @param id 被护理人id
* @return 护理人信息
*/
@GetMapping(value = "/id")
public AjaxResult getInfo(Long id) {
if (Objects.isNull(id)) {
return AjaxResult.error("被护理人编号不能为空!");
}
return AjaxResult.success(patientInfoService.selectPatientInfoById(id));
}
/**
* 会员app和微信小程序-签到方法
*
* @param patientId 会员用户id
* @param signInChannel 签到来源微信小程序会员APP
* @return 签到结果
*/
@MobileRequestAuthorization
@PostMapping("/signIn")
public AjaxResult patientSignIn(Long patientId, String signInChannel) {
if (Objects.isNull(patientId)) {
return AjaxResult.error("会员信息不能为空!");
}
if (StringUtils.isBlank(signInChannel)) {
return AjaxResult.error("签到方式不能为为空!");
}
return patientCenterService.patientSignIn(patientId, signInChannel);
}
/**
* 个人中心优惠券(共用)
*
* @param patientCenterCouponVO 用户信息及优惠券状态
* @return List<CouponVO>
*/
@MobileRequestAuthorization
@GetMapping("/selectCoupon")
public TableDataInfo selectCoupon(@Validated(Insert.class) PatientCenterCouponVO patientCenterCouponVO) {
startPage();
List<CouponVO> list = patientCenterService.selectCouponByUseStatus(patientCenterCouponVO);
return getDataTable(list);
}
/**
* 个人中心积分兑换-查询可以兑换的商品
*
* @return List<GoodInfoVO>
*/
@MobileRequestAuthorization
@GetMapping("selectExchangeGoods")
public TableDataInfo selectExchangeGoods() {
startPage();
List<GoodsList> list = patientCenterService.selectExchangeGoods();
return getDataTable(list);
}
/**
* 获取积分返回规则
*
* @param patientId 用户id
* @return com.xinyilu.nurseapplet.domain.vo.patientcenter.PatientSignInfoVO
**/
@MobileRequestAuthorization
@GetMapping("selectPatientSignIn")
public AjaxResult selectPatientSignIn(Long patientId) {
if (Objects.isNull(patientId)) {
return AjaxResult.error("会员信息不能为空!");
}
return AjaxResult.success(patientCenterService.selectPatientSignIn(patientId));
}
/**
* 微信小程序-邀请好友接口
*
* @param inviteId 邀请人id
* @return 邀请码图片地址
*/
@MobileRequestAuthorization
@PostMapping("/inviteFriends")
public AjaxResult inviteFriends(Long inviteId) {
if (Objects.isNull(inviteId)) {
return AjaxResult.error("邀请人信息不能为空!");
}
return patientCenterService.inviteFriends(inviteId);
}
/**
* 新人福利优惠券(共用)
*
* @param patientCenterCouponDTO 用户信息及优惠券状态
* @return List<CouponVO>
*/
@MobileRequestAuthorization
@GetMapping("/couponByUseStatus")
public TableDataInfo couponByUseStatus(PatientCenterCouponDTO patientCenterCouponDTO) {
return patientCenterService.getCouponByUseStatus(patientCenterCouponDTO);
}
/**
* 新人福利-优惠券领取
*
* @param patientId 用户id
* @param couponId 优惠券id
* @return AjaxResult
*/
@MobileRequestAuthorization
@PostMapping("/insertCouponReceive")
public AjaxResult insertCouponReceive(Long patientId, Long couponId) {
if (Objects.isNull(patientId) || Objects.isNull(couponId)) {
return AjaxResult.error("用户信息或优惠券信息不能为空!");
}
return patientCenterService.insertCouponReceive(patientId, couponId);
}
/**
* 手机App和微信小程序积分兑换订单方法
*
* @param goodsOrder 商品订单
* @return 结果
*/
@MobileRequestAuthorization
@RepeatSubmit
@PostMapping("/integralGoodsOrder")
public AjaxResult integralGoodsOrder(@Validated(Insert.class) @RequestBody GoodsOrderStationDTO goodsOrder, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new ServiceException(bindingResult.getAllErrors().get(0).getDefaultMessage());
}
if (Objects.isNull(goodsOrder.getIntegralExchangeSill()) || goodsOrder.getIntegralExchangeSill() <= 0) {
return AjaxResult.error("当前积分数值不足,无法兑换!");
}
if (Objects.isNull(goodsOrder.getIntegralExchangeCount()) || goodsOrder.getIntegralExchangeCount() <= 0) {
return AjaxResult.error("兑换商品数量不正确,无法兑换!");
}
return patientCenterService.insertIntegralGoodsOrder(goodsOrder);
}
/**
* 新增订阅微信小程序订阅消息记录暂时走微信回调事件未使用
*
* @param subscribeMessageRecord 订阅微信小程序订阅消息记录
* @return com.xinyilu.common.core.domain.AjaxResult
**/
@MobileRequestAuthorization
@PostMapping("/insertSubscribeMessageRecord")
public AjaxResult insertSubscribeMessageRecord(@RequestBody SubscribeMessageRecordDTO subscribeMessageRecord) {
if (CollectionUtils.isEmpty(subscribeMessageRecord.getSubscribeMessageRecordList())) {
return AjaxResult.error("订阅信息不能为空!");
}
return patientCenterService.insertSubscribeMessageRecord(subscribeMessageRecord.getSubscribeMessageRecordList());
}
}

View File

@ -0,0 +1,74 @@
package com.xinelu.applet.controller.wechatappletcallback;
import com.xinelu.applet.dto.appletcallback.MessageSignDTO;
import com.xinelu.applet.service.wechatappletcallback.WeChatAppletCallBackService;
import com.xinelu.applet.utils.XmlUtil;
import com.xinelu.applet.vo.messagepush.WeChatMessagePushVO;
import com.xinelu.common.config.AppletChatConfig;
import com.xinelu.common.utils.aes.AesException;
import com.xinelu.common.utils.aes.WXBizMsgCrypt;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Objects;
/**
* @Description 微信小程序事件回调控制器
* @Author 纪寒
* @Date 2023-03-14 15:09:50
* @Version 1.0
*/
@Slf4j
@RestController
@RequestMapping("/nurseApplet/weChatAppletCallBack")
public class WeChatAppletCallBackController {
@Resource
private AppletChatConfig appletChatConfig;
@Resource
private WeChatAppletCallBackService weChatAppletCallBackService;
/**
* 微信小程序回调验证方法
*
* @param messageSignDTO 微信输入参数
* @return 解密后的字符串
* @throws AesException 异常信息
*/
@GetMapping
public String getWeChatAppletCallBack(MessageSignDTO messageSignDTO) throws AesException {
WXBizMsgCrypt wxCpt = new WXBizMsgCrypt(appletChatConfig.getToken(), appletChatConfig.getEncodingAesKey(), appletChatConfig.getAppletId());
String verifyMessage = wxCpt.verifyUrl(messageSignDTO.getSignature(), messageSignDTO.getTimestamp(), messageSignDTO.getNonce(), messageSignDTO.getEchostr());
log.info("微信小程序回调设置验证URL成功验证信息verifyMessage = [{}]", verifyMessage);
return verifyMessage;
}
/**
* 微信小程序消息推送事件回调POST处理
*
* @param signature 签名
* @param timestamp 时间戳
* @param nonce 随机字符串
* @param postData 消息体xml格式
*/
@PostMapping
public void handleWeChatAppletCallBack(@RequestParam("signature") String signature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce,
@RequestBody String postData) throws AesException {
WXBizMsgCrypt wxCpt = new WXBizMsgCrypt(appletChatConfig.getToken(), appletChatConfig.getEncodingAesKey(), appletChatConfig.getAppletId());
String decryptMsg = wxCpt.decryptMsg(signature, timestamp, nonce, postData);
WeChatMessagePushVO weChatMessagePushVO = (WeChatMessagePushVO) XmlUtil.fromXml(decryptMsg, WeChatMessagePushVO.class);
if (Objects.isNull(weChatMessagePushVO)) {
log.error("xml数据转换失败请求信息为 [{}]", decryptMsg);
return;
}
if (StringUtils.isBlank(weChatMessagePushVO.getEvent()) || StringUtils.isBlank(weChatMessagePushVO.getMsgType())) {
return;
}
log.info("微信小程序消息推送回调执行,消息数据为: [{}]", weChatMessagePushVO);
weChatAppletCallBackService.handleWeChatAppletCallBack(weChatMessagePushVO);
}
}

View File

@ -0,0 +1,40 @@
package com.xinelu.applet.dto.appletcallback;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 消息验证实体类
* @Author 纪寒
* @Date 2023-03-14 15:53:01
* @Version 1.0
*/
@Data
public class MessageSignDTO implements Serializable {
private static final long serialVersionUID = -2514572635286835742L;
/**
* 微信小程序签名
*/
private String signature;
/**
* 时间戳
*/
private String timestamp;
/**
* 随机字符串
*/
private String nonce;
/**
* 加密的字符串
*/
private String echostr;
/**
* 回调数据包xml格式
*/
private String postData;
}

View File

@ -0,0 +1,41 @@
package com.xinelu.applet.dto.patientcenter;
import lombok.Data;
import java.io.Serializable;
/**
* @author ljh
* @version 1.0
* Create by 2023/3/2 10:43
*/
@Data
public class PatientCenterCouponDTO implements Serializable {
private static final long serialVersionUID = -3649311477999618876L;
/**
* 会员id
*/
private Long patientId;
/**
* 优惠券使用状态
*/
private String useStatus;
/**
* 领取方式新人福利NEW_PEOPLE_WELFARE活动赠送EVENT_GIFT消费返券CONSUME_REBATE
*/
private String receiveType;
/**
* 优惠券来源
*/
private String receiveSource;
/**
* 优惠券id
*/
private String couponId;
}

View File

@ -20,4 +20,12 @@ public interface NurseAppLoginMapper {
* @return PatientDiseaseInfo
*/
PatientAndDiseaseVO getPatientDiseaseByPatientId(@Param("patientId") Long patientId);
/**
* 查询信息完善标识符
*
* @param patientId 账号信息
* @return 数量
*/
Integer getLoginFlagByPatientId(@Param("patientId") Long patientId);
}

View File

@ -0,0 +1,152 @@
package com.xinelu.applet.mapper.nursingstationgoods;
import com.xinelu.applet.dto.nursingstationgoods.GoodDetails;
import com.xinelu.applet.dto.nursingstationgoods.GoodsList;
import com.xinelu.applet.dto.nursingstationgoods.GoodsOrderPatient;
import com.xinelu.applet.vo.coupon.CouponVO;
import com.xinelu.manage.domain.goodsAttributeDetails.GoodsAttributeDetails;
import com.xinelu.manage.domain.goodsCategory.GoodsCategory;
import com.xinelu.manage.domain.receiveAddressInfo.ReceiveAddressInfo;
import com.xinelu.manage.vo.goodsCategory.GoodsCategoryNameVO;
import com.xinelu.manage.vo.receiveAddressInfo.ReceiveAddressInfoVO;
import com.xinelu.manage.vo.sysarea.SysAreaVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author ljh
* @version 1.0
* Create by 2022/10/17 13:31
*/
public interface NursingStationGoodsMapper {
/**
* 查询商品分类信息列表
*
* @param goodsCategory 商品分类信息
* @return 商品分类信息集合
*/
List<GoodsCategory> getGoodsCategoryList(GoodsCategory goodsCategory);
/**
* 根据商品分类id查询商品信息
*
* @param goodsList 商品信息
* @return 商品基本信息集合
*/
List<GoodsList> getGoodsInfoList(GoodsList goodsList);
/**
* 查询商品二级分类信息列表
*
* @param goodsCategory 商品分类信息
* @return 商品分类信息集合
*/
List<GoodsCategoryNameVO> getGoodsCategoryNameList(GoodsCategoryNameVO goodsCategory);
/**
* 商品属性信息
*
* @param goodsInfoId 商品详细id
* @return java.util.List<com.xinyilu.nurseapplet.domain.nursingStationGoods.GoodDetailsList>
**/
GoodDetails getGoodsDetailsList(Long goodsInfoId);
/**
* 根据被护理人id查询基本信息
*
* @param patientId 被护理人id
* @return com.xinyilu.base.domain.patientinfo.PatientInfo
**/
List<ReceiveAddressInfoVO> getReceiveAddressInfoList(Long patientId);
/**
* 根据被护理人id查询基本信息集合
*
* @param patientId 被护理人id
* @return java.util.List<com.xinyilu.base.domain.receiveAddressInfo.ReceiveAddressInfo>
**/
List<ReceiveAddressInfo> selectReceiveAddressInfoByPatientId(Long patientId);
/**
* 查询收货人地址信息
*
* @param id 收货人地址信息主键
* @return 收货人地址信息
*/
ReceiveAddressInfo selectReceiveAddressInfoById(Long id);
/**
* 新增收货人地址信息
*
* @param receiveAddressInfo 收货人地址信息
* @return 结果
*/
int insertReceiveAddressInfo(ReceiveAddressInfo receiveAddressInfo);
/**
* 修改收货人地址信息
*
* @param receiveAddressInfo 收货人地址信息
* @return 结果
*/
int updateReceiveAddressInfo(ReceiveAddressInfo receiveAddressInfo);
/**
* 批量删除收货人地址信息
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
int deleteReceiveAddressInfoByIds(Long[] ids);
/**
* 下级区域寻找上级区域
*
* @param areaCode 区域编码
* @return com.xinyilu.base.domain.vo.sysarea.SysAreaVO
**/
SysAreaVO getSubordinateRegionsFindSuperiorRegions(@Param("areaCode") String areaCode);
/**
* 查询商品属性明细
*
* @param id 商品属性明细主键
* @return 商品属性明细
*/
GoodsAttributeDetails selectGoodsAttributeDetailsGoodsStockById(Long id);
/**
* 修改商品属性明细
*
* @param goodsAttributeDetails 商品属性明细
* @return 结果
*/
int updateGoodsAttributeDetails(GoodsAttributeDetails goodsAttributeDetails);
/**
* 根据订单编号查询订单信息
*
* @param orderNo 订单信息编号
* @return com.xinyilu.nurseapplet.domain.nursingStationGoods.GoodsOrderPatient
**/
GoodsOrderPatient selectGoodsOrderPatient(String orderNo);
/**
* 查询商品分类信息下的所有子id
*
* @param goodsCategoryId 当前商品分类id
* @return com.xinyilu.base.domain.goodsCategory.GoodsCategory
**/
String getChildrenCategoryIds(Long goodsCategoryId);
/**
* 商品详情查询用户优惠券信息
*
* @param patientId 用户信息
* @param useStatus 优惠券状态
* @return List<Coupon>
*/
List<CouponVO> selectCouponListByPatient(@Param("patientId") Long patientId, @Param("useStatus") String useStatus);
}

View File

@ -0,0 +1,116 @@
package com.xinelu.applet.mapper.patientcenter;
import com.xinelu.applet.dto.nursingstationgoods.GoodsList;
import com.xinelu.applet.dto.patientcenter.PatientCenterCouponDTO;
import com.xinelu.applet.vo.coupon.CouponVO;
import com.xinelu.applet.vo.patientcenter.PatientCenterCouponVO;
import com.xinelu.applet.vo.patientcenter.PatientSignInVO;
import com.xinelu.applet.vo.patientcenter.PatientSignInfoVO;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDate;
import java.util.List;
/**
* 个人中心Mapper接口
*
* @author zh
* @date 2023-02-24
*/
public interface PatientCenterMapper {
/**
* 根据优惠券状态查询优惠券信息
*
* @param patientCenterCouponVO 用户信息及优惠券状态
* @return List<CouponVO>
*/
List<CouponVO> selectCouponByUseStatus(PatientCenterCouponVO patientCenterCouponVO);
/**
* 积分兑换 - 查询积分兑换商品
*
* @param integralExchangeFlag 积分兑换标识
* @param whetherShelf 是否上架
* @param goodsPurpose 商品用途
* @return List<GoodsInfo>
*/
List<GoodsList> selectGoodsByExchangeFlag(@Param("integralExchangeFlag") Integer integralExchangeFlag, @Param("whetherShelf") Integer whetherShelf, @Param("goodsPurpose") String goodsPurpose);
/**
* 查询优惠券表所有id待领取优惠券
*
* @return List<Long>
*/
List<Long> selectCouponId();
/**
* 根据id查询用户签到信息
*
* @param patientId 用户id
* @param nowDate 当前日期
* @return 签到信息
*/
PatientSignInVO getPatientSignInInfo(@Param("patientId") Long patientId, @Param("nowDate") LocalDate nowDate);
/**
* 更新用户签到天数
*
* @param patientId 会员id
* @return 数量
*/
int updateTotalSignInDays(Long patientId);
/**
* 修改用户账户的积分
*
* @param patientId 会员id
* @param integral 积分值
* @return 数量
*/
int updatePatientIntegral(@Param("patientId") Long patientId, @Param("integral") Integer integral);
/**
* 更新用户签到天数
*
* @param patientId 会员id
* @return 数量
*/
int clearTotalSignInDays(Long patientId);
/**
* 获取积分返回规则
*
* @param patientId 用户id
* @param nowDate 今天日期
* @param ruleList 规则集合
* @return com.xinyilu.nurseapplet.domain.vo.patientcenter.PatientSignInfoVO
**/
List<PatientSignInfoVO> selectPatientSignIn(@Param("patientId") Long patientId,
@Param("nowDate") LocalDate nowDate,
@Param("ruleList") List<String> ruleList);
/**
* 新人福利查询优惠券
*
* @param receiveType 新人福利标识1/
* @return java.util.List<com.xinyilu.base.domain.coupon.Coupon>
**/
List<CouponVO> getCouponNewPeople(String receiveType);
/**
* 根据优惠券状态查询优惠券信息
*
* @param patientCenterCouponDTO 用户信息及优惠券状态
* @return List<CouponVO>
*/
List<CouponVO> getCouponByUseStatus(PatientCenterCouponDTO patientCenterCouponDTO);
/**
* 查询用户签到信息和积分信息
*
* @param patientId 会员id
* @param nowDate 当前时间
* @return 信息
*/
PatientSignInfoVO getPatientSignInfo(@Param("patientId") Long patientId, @Param("nowDate") LocalDate nowDate);
}

View File

@ -0,0 +1,221 @@
package com.xinelu.applet.service.messagepush.Impl;
import com.alibaba.fastjson2.JSON;
import com.xinelu.applet.service.messagepush.MessagePushService;
import com.xinelu.common.config.AppletChatConfig;
import com.xinelu.common.config.AppletPageConfig;
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.CouponTypeEnum;
import com.xinelu.common.enums.SettingsTypeEnum;
import com.xinelu.common.enums.SubscribeStatusEnum;
import com.xinelu.common.utils.AppletChatUtil;
import com.xinelu.common.utils.http.HttpUtils;
import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord;
import com.xinelu.manage.domain.systemsettingsinfo.SystemSettingsInfo;
import com.xinelu.manage.mapper.subscribemessagerecord.SubscribeMessageRecordMapper;
import com.xinelu.manage.mapper.systemsettingsinfo.SystemSettingsInfoMapper;
import com.xinelu.manage.vo.patientcouponreceive.PatientCouponReceiveInfoVO;
import lombok.extern.slf4j.Slf4j;
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.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
/**
* @Description 消息推送实现层
* @Author zh
* @Date 2023-03-17
*/
@Slf4j
@Service
public class MessagePushServiceImpl implements MessagePushService {
@Resource
private AppletChatConfig appletChatConfig;
@Resource
private SubscribeMessageRecordMapper subscribeMessageRecordMapper;
@Resource
private SystemSettingsInfoMapper systemSettingsInfoMapper;
@Resource
private AppletPageConfig appletPageConfig;
/**
* 微信消息推送url
*/
private static final String MESSAGE_PUSH_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";
/**
* 签到消息推送
*
* @param patientId 用户ID
* @param days 天数
*/
@Override
@Async("asyncThreadServiceExecutor")
public void integralMessage(Long patientId, Integer days) {
//获取AppletAccessToken的值
AppletAccessToken appletAccessToken = AppletChatUtil.getAppletAccessToken(appletChatConfig.getAppletId(), appletChatConfig.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;
}
//获取用户信息订阅消息记录规则信息
SubscribeMessageRecord subscribeMessageRecord = subscribeMessageRecordMapper.selectSubscribeMessageRecordByPatientId(patientId, null, appletChatConfig.getSignTemplateId());
if (Objects.isNull(subscribeMessageRecord) || StringUtils.isBlank(subscribeMessageRecord.getOpenid()) || StringUtils.isBlank(subscribeMessageRecord.getSubscribeStatus()) || !SubscribeStatusEnum.ACCEPT.getInfo().equals(subscribeMessageRecord.getSubscribeStatus())) {
return;
}
SystemSettingsInfo systemSettingsInfo = systemSettingsInfoMapper.getSystemSettingsInfoByType(SettingsTypeEnum.SIGN_IN_RULE.getInfo());
if (Objects.isNull(systemSettingsInfo) || Objects.isNull(systemSettingsInfo.getIntegralCount()) || Objects.isNull(systemSettingsInfo.getTotalSignInDays())) {
return;
}
this.sendIntegralMessage(appletAccessToken, systemSettingsInfo, subscribeMessageRecord, days);
}
/**
* 签到消息推送
*
* @param appletAccessToken 令牌
* @param systemSettingsInfo 规则信息
* @param subscribeMessageRecord 订阅消息记录
* @param days 天数
*/
public void sendIntegralMessage(AppletAccessToken appletAccessToken, SystemSettingsInfo systemSettingsInfo, SubscribeMessageRecord subscribeMessageRecord, Integer days) {
//模板参数用户openid推送消息模板id
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("touser", subscribeMessageRecord.getOpenid());
paramsMap.put("template_id", appletChatConfig.getSignTemplateId());
paramsMap.put("page", appletPageConfig.getIntegralPageUrl());
//模板内容
Map<String, MessageValueEntity> messageValueEntityMap = new LinkedHashMap<>();
messageValueEntityMap.put("thing1", new MessageValueEntity("每日签到"));
//如果签到天数满足规则
if (days.equals(systemSettingsInfo.getTotalSignInDays())) {
messageValueEntityMap.put("thing2", new MessageValueEntity("今日已签到,已领取" + systemSettingsInfo.getIntegralCount() + "积分"));
} else {
messageValueEntityMap.put("thing2", new MessageValueEntity(LocalDate.now().getYear() + "" + LocalDate.now().getMonthValue() + "" + LocalDate.now().getDayOfMonth() + "日签到成功"));
}
messageValueEntityMap.put("thing3", new MessageValueEntity("累计签到" + systemSettingsInfo.getTotalSignInDays() + "天,可获得" + systemSettingsInfo.getIntegralCount() + "积分"));
paramsMap.put("data", messageValueEntityMap);
//发送
this.sendPosts(appletAccessToken, paramsMap);
}
/**
* 完善信息优惠券领取与优惠券领取共用异步发送订阅信息
*
* @param subscribeMessageRecord 微信小程序订阅消息记录表
* @param couponReceive 用户优惠券
**/
@Override
@Async("asyncThreadServiceExecutor")
public void messageCouponReceiveThread(SubscribeMessageRecord subscribeMessageRecord, PatientCouponReceiveInfoVO couponReceive) {
if (StringUtils.equals(CouponTypeEnum.FULL_REDUCTION_COUPON.getInfo(), couponReceive.getCouponType())) {
couponReceive.setCouponType("满减券");
}
if (StringUtils.equals(CouponTypeEnum.CASH_COUPON.getInfo(), couponReceive.getCouponType())) {
couponReceive.setCouponType("代金券");
}
if (StringUtils.equals(CouponTypeEnum.EXCHANGE_COUPON.getInfo(), couponReceive.getCouponType())) {
couponReceive.setCouponType("兑换券");
}
if (StringUtils.equals(CouponTypeEnum.DISCOUNT_COUPON.getInfo(), couponReceive.getCouponType())) {
couponReceive.setCouponType("折扣卷");
}
//获取AppletAccessToken的值
AppletAccessToken appletAccessToken = AppletChatUtil.getAppletAccessToken(appletChatConfig.getAppletId(), appletChatConfig.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信息为空");
}
//构建微信小程序消息推送参数
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("template_id", StringUtils.isBlank(subscribeMessageRecord.getTemplateId()) ? "" : subscribeMessageRecord.getTemplateId());
paramsMap.put("page", appletPageConfig.getCouponPageUrl());
paramsMap.put("touser", StringUtils.isBlank(subscribeMessageRecord.getOpenid()) ? "" : subscribeMessageRecord.getOpenid());
paramsMap.put("lang", "zh_CN");
//构建微信小程序消息推送内容参数
Map<String, MessageValueEntity> amountParamMap = new HashMap<>();
//优惠券名称
amountParamMap.put("thing3", new MessageValueEntity(StringUtils.isBlank(couponReceive.getCouponTitle()) ? "" : couponReceive.getCouponTitle()));
//优惠券金额
BigDecimal couponPrice = Objects.isNull(couponReceive.getCouponPrice()) ? BigDecimal.ZERO : couponReceive.getCouponPrice();
amountParamMap.put("amount2", new MessageValueEntity(couponPrice + ""));
//优惠券类型
amountParamMap.put("thing4", new MessageValueEntity(StringUtils.isBlank(couponReceive.getCouponType()) ? "" : couponReceive.getCouponType()));
//发布时间
amountParamMap.put("time6", new MessageValueEntity(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(couponReceive.getReceiveTime())));
//温馨提示
amountParamMap.put("thing1", new MessageValueEntity("优惠券来啦,您可进入小程序进行使用"));
paramsMap.put("data", amountParamMap);
//发送
this.sendPosts(appletAccessToken, paramsMap);
}
/**
* 发送
*
* @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

@ -0,0 +1,41 @@
package com.xinelu.applet.service.messagepush;
import com.xinelu.common.entity.AppletAccessToken;
import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord;
import com.xinelu.manage.vo.patientcouponreceive.PatientCouponReceiveInfoVO;
import java.util.Map;
/**
* @Description 消息推送业务层
* @Author zh
* @Date 2023-03-17
*/
public interface MessagePushService {
/**
* 签到消息推送
*
* @param patientId 用户ID
* @param days 天数
*/
void integralMessage(Long patientId, Integer days);
/**
* 完善信息优惠券领取与优惠券领取共用异步发送订阅信息
*
* @param subscribeMessageRecord 微信小程序订阅消息记录表
* @param couponReceive 用户优惠券
**/
void messageCouponReceiveThread(SubscribeMessageRecord subscribeMessageRecord, PatientCouponReceiveInfoVO couponReceive);
/**
* 发送
*
* @param appletAccessToken 令牌
* @param paramsMap 模板
**/
void sendPosts(AppletAccessToken appletAccessToken, Map<String, Object> paramsMap);
}

View File

@ -0,0 +1,137 @@
package com.xinelu.applet.service.nursingstationgoods;
import com.xinelu.applet.dto.nursingstationgoods.GoodDetails;
import com.xinelu.applet.dto.nursingstationgoods.GoodsList;
import com.xinelu.applet.dto.nursingstationgoods.GoodsOrderPatient;
import com.xinelu.applet.dto.nursingstationgoods.GoodsOrderStationDTO;
import com.xinelu.applet.vo.nursingstationgoods.UpdateDefaultAddressVO;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.page.TableDataInfo;
import com.xinelu.manage.domain.goodsCategory.GoodsCategory;
import com.xinelu.manage.domain.receiveAddressInfo.ReceiveAddressInfo;
import com.xinelu.manage.vo.sysarea.SysAreaVO;
import java.util.List;
/**
* 商品信息
*
* @author zhangheng
* @date 2022-09-06
*/
public interface INursingStationGoodsService {
/**
* 查询商品分类信息列表
*
* @param goodsCategory 商品分类信息
* @return 商品分类信息集合
*/
List<GoodsCategory> getGoodsCategoryList(GoodsCategory goodsCategory);
/**
* 查询商品二级分类信息列表
*
* @param goodsCategoryId 商品分类信息
* @return 商品分类信息集合
*/
AjaxResult getGoodsCategoryNameList(Long goodsCategoryId);
/**
* 根据商品分类id查询商品信息
*
* @param goodsList 商品信息
* @return 商品基本信息集合
*/
TableDataInfo getGoodsInfoList(GoodsList goodsList);
/**
* 根据商品id查询商品详细信息
*
* @param goodsInfoId 商品详细id
* @param patientId 用户信息id
* @return com.xinyilu.nurseapplet.domain.nursingStationGoods.GoodDetails
**/
GoodDetails getGoodsDetails(Long goodsInfoId, Long patientId);
/**
* 根据被护理人id查询基本信息
*
* @param patientId 被护理人id
* @return com.xinyilu.base.domain.patientinfo.PatientInfo
**/
AjaxResult getReceiveAddressInfoList(Long patientId);
/**
* 查询收货人地址信息
*
* @param id 收货人地址信息主键
* @return 收货人地址信息
*/
ReceiveAddressInfo selectReceiveAddressInfoById(Long id);
/**
* 新增收货人地址信息
*
* @param receiveAddressInfo 收货人地址信息
* @return 结果
*/
int insertReceiveAddressInfo(ReceiveAddressInfo receiveAddressInfo);
/**
* 修改收货人地址信息
*
* @param receiveAddressInfo 收货人地址信息
* @return 结果
*/
int updateReceiveAddressInfo(ReceiveAddressInfo receiveAddressInfo);
/**
* 批量删除收货人地址信息
*
* @param ids 需要删除的收货人地址信息主键集合
* @return 结果
*/
int deleteReceiveAddressInfoByIds(Long[] ids);
/**
* 下级区域寻找上级区域
*
* @param areaCode 区域编码
* @return com.xinyilu.base.domain.vo.sysarea.SysAreaVO
**/
SysAreaVO getSubordinateRegionsFindSuperiorRegions(String areaCode);
/**
* 新增商品订单以及详细信息
*
* @param goodsOrder 商品订单
* @return 结果
*/
AjaxResult insertNurseStationGoodsOrder(GoodsOrderStationDTO goodsOrder);
/**
* 根据订单编号查询订单信息
*
* @param orderNo 订单信息编号
* @return com.xinyilu.nurseapplet.domain.nursingStationGoods.GoodsOrderPatient
**/
GoodsOrderPatient selectGoodsOrderPatient(String orderNo);
/**
* App和小程序确认收货
*
* @param orderNo 订单编号
* @return 结果
*/
AjaxResult confirmReceipt(String orderNo);
/**
* 微信小程序和会员App设置默认地址接口
*
* @param defaultAddressList 默认地址标识集合
* @return 结果
*/
AjaxResult updateDefaultAddress(List<UpdateDefaultAddressVO> defaultAddressList);
}

View File

@ -0,0 +1,562 @@
package com.xinelu.applet.service.nursingstationgoods.impl;
import com.xinelu.applet.dto.nursingstationgoods.*;
import com.xinelu.applet.mapper.nursingstationgoods.NursingStationGoodsMapper;
import com.xinelu.applet.service.nursingstationgoods.INursingStationGoodsService;
import com.xinelu.applet.vo.coupon.CouponVO;
import com.xinelu.applet.vo.nursingstationgoods.UpdateDefaultAddressVO;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.page.TableDataInfo;
import com.xinelu.common.enums.CouponUseStatusEnum;
import com.xinelu.common.enums.GooodsOrderStatusEnum;
import com.xinelu.common.enums.OrderTypeEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.PageServiceUtil;
import com.xinelu.common.utils.RedisDistributedLockUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.common.utils.regex.RegexUtil;
import com.xinelu.manage.domain.goodsAttributeDetails.GoodsAttributeDetails;
import com.xinelu.manage.domain.goodsCategory.GoodsCategory;
import com.xinelu.manage.domain.goodsOrder.GoodsOrder;
import com.xinelu.manage.domain.goodsOrderDetails.GoodsOrderDetails;
import com.xinelu.manage.domain.receiveAddressInfo.ReceiveAddressInfo;
import com.xinelu.manage.domain.sysarea.SysArea;
import com.xinelu.manage.mapper.goodsAttributeDetails.GoodsAttributeDetailsMapper;
import com.xinelu.manage.mapper.goodsOrder.GoodsOrderMapper;
import com.xinelu.manage.mapper.goodsOrderDetails.GoodsOrderDetailsMapper;
import com.xinelu.manage.mapper.patientcouponreceive.PatientCouponReceiveMapper;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.receiveAddressInfo.ReceiveAddressInfoMapper;
import com.xinelu.manage.mapper.sysarea.SysAreaMapper;
import com.xinelu.manage.vo.goodsCategory.GoodsCategoryNameVO;
import com.xinelu.manage.vo.patientcouponreceive.PatientCouponReceiveVO;
import com.xinelu.manage.vo.patientinfo.PatientInfoVO;
import com.xinelu.manage.vo.receiveAddressInfo.ReceiveAddressInfoVO;
import com.xinelu.manage.vo.sysarea.SysAreaVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* @author ljh
* @version 1.0
* Create by 2022/10/17 13:38
*/
@Slf4j
@Service
public class NursingStationGoodsServiceImpl implements INursingStationGoodsService {
@Resource
private NursingStationGoodsMapper nursingStationGoodsMapper;
@Resource
private RegexUtil regexUtil;
@Resource
private SysAreaMapper sysAreaMapper;
@Resource
private GoodsOrderMapper goodsOrderMapper;
@Resource
private RedisDistributedLockUtils redisDistributedLockUtils;
@Resource
private GoodsAttributeDetailsMapper goodsAttributeDetailsMapper;
@Resource
private PatientInfoMapper patientInfoMapper;
@Resource
private ReceiveAddressInfoMapper receiveAddressInfoMapper;
@Resource
private PageServiceUtil pageServiceUtil;
@Resource
private PatientCouponReceiveMapper patientCouponReceiveMapper;
@Resource
private GoodsOrderDetailsMapper goodsOrderDetailsMapper;
/**
* 所在省的级别
*/
private static final int PROVINCE_AREA_LEVEL = 1;
/**
* 所在市的级别
*/
private static final int CITY_AREA_LEVEL = 2;
/**
* 查询商城分类
*
* @param goodsCategory 商品分类信息表
* @return java.util.List<com.xinyilu.base.domain.goodsCategory.GoodsCategory>
**/
@Override
public List<GoodsCategory> getGoodsCategoryList(GoodsCategory goodsCategory) {
return nursingStationGoodsMapper.getGoodsCategoryList(goodsCategory);
}
/**
* 查询商品二级分类信息列表
*
* @param goodsCategoryId 商品分类信息
* @return 商品分类信息集合
*/
@Override
public AjaxResult getGoodsCategoryNameList(Long goodsCategoryId) {
//查询当前分类下属所有分类id集合
List<Integer> childCategoryIds = this.getChildCategoryIds(goodsCategoryId);
GoodsCategoryNameVO goodsCategoryNameVO = new GoodsCategoryNameVO();
goodsCategoryNameVO.setGoodsCategoryNameId(childCategoryIds);
goodsCategoryNameVO.setCategoryLevel(1);
return AjaxResult.success(nursingStationGoodsMapper.getGoodsCategoryNameList(goodsCategoryNameVO));
}
/**
* 根据商品分类id查询商品信息
*
* @param goodsList 商品信息
* @return java.util.List<com.xinyilu.base.domain.goodsInfo.GoodsInfo>
**/
@Override
public TableDataInfo getGoodsInfoList(GoodsList goodsList) {
if (Objects.nonNull(goodsList) && Objects.isNull(goodsList.getGoodsCategoryId())) {
throw new ServiceException("所选商品分类不能为空!");
}
//查询当前分类下属所有分类id集合
List<Integer> childCategoryIds = this.getChildCategoryIds(goodsList.getGoodsCategoryId());
goodsList.setGoodsCategoryIds(childCategoryIds);
pageServiceUtil.startPage();
List<GoodsList> goodsInfoList = nursingStationGoodsMapper.getGoodsInfoList(goodsList);
return pageServiceUtil.getDataTable(goodsInfoList);
}
/**
* 根据商品id查询商品详细信息
*
* @param goodsInfoId 商品详细id
* @param patientId 用户信息
* @return com.xinyilu.nurseapplet.domain.nursingStationGoods.GoodDetails
**/
@Transactional(rollbackFor = Exception.class)
@Override
public GoodDetails getGoodsDetails(Long goodsInfoId, Long patientId) {
GoodDetails goodsDetailsList = nursingStationGoodsMapper.getGoodsDetailsList(goodsInfoId);
//获取集合属性中的最小值
BigDecimal goodAttributeDetailsMin = goodsDetailsList.getGoodAttributeDetailsLists()
.stream()
.filter(Objects::nonNull)
.filter(good -> Objects.nonNull(good.getGoodsPrice()))
.map(GoodAttributeDetailsList::getGoodsPrice).min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
goodsDetailsList.setMinGoodsPrice(goodAttributeDetailsMin);
//查询用户未使用的优惠券信息
if (Objects.nonNull(patientId)) {
//数据库中查出的用户未使用的优惠券信息
List<CouponVO> couponVOList = nursingStationGoodsMapper.selectCouponListByPatient(patientId, CouponUseStatusEnum.NOT_USED.getInfo());
//用流筛选出用户未使用以及未过期的 优惠券信息
List<CouponVO> couponVO = couponVOList.stream()
.filter(cou -> (Objects.nonNull(cou.getExpirationEndTime()))).filter(coupon -> (coupon.getExpirationEndTime().isAfter(LocalDateTime.now()))).collect(Collectors.toList());
//未过期的优惠券塞入返回值中 返回
goodsDetailsList.setCouponList(couponVO);
//做差集取出用户未使用以及 过期的 优惠券信息
List<CouponVO> couponSubtractList = new ArrayList<>(CollectionUtils.subtract(couponVOList, couponVO));
if (CollectionUtils.isNotEmpty(couponSubtractList)) {
//取出会员用户优惠券领取记录表id集合
List<Long> couponIdList = couponSubtractList.stream()
.filter(coupon -> (Objects.nonNull(coupon.getPatientCouponReceiveId())))
.map(CouponVO::getPatientCouponReceiveId).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(couponIdList)) {
int receiveStatusList = patientCouponReceiveMapper.updateCouponReceiveStatusList(CouponUseStatusEnum.EXPIRED.getInfo(), couponIdList);
if (receiveStatusList < 0) {
throw new ServiceException("优惠券查询失败,请联系管理员!");
}
}
}
}
return goodsDetailsList;
}
/**
* 根据被护理人id查询基本信息
*
* @param patientId 被护理人id
* @return java.util.List<com.xinyilu.base.domain.receiveAddressInfo.ReceiveAddressInfo>
**/
@Override
public AjaxResult getReceiveAddressInfoList(Long patientId) {
//根据id查询所有的地址
List<ReceiveAddressInfoVO> receiveAddressInfoList = nursingStationGoodsMapper.getReceiveAddressInfoList(patientId);
//取出list集合中所有的AreaCode
List<String> areaCodeList = receiveAddressInfoList.stream().filter(item -> StringUtils.isNotBlank(item.getAreaCode())).map(ReceiveAddressInfoVO::getAreaCode).distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(areaCodeList)) {
return AjaxResult.success(receiveAddressInfoList);
}
//查询所在的街道的区域信息
Map<String, SysAreaVO> sysStreetAreaMap = sysAreaMapper.getNurseStationAreaByList(areaCodeList).stream().filter(item -> StringUtils.isNotBlank(item.getStreetCode())).collect(Collectors.toMap(SysAreaVO::getStreetCode, item -> item));
//所在区的编码集合
List<String> regionCodeList = new ArrayList<>();
for (ReceiveAddressInfoVO receiveAddressInfoVO : receiveAddressInfoList) {
SysAreaVO sysAreaVO = sysStreetAreaMap.getOrDefault(receiveAddressInfoVO.getAreaCode(), new SysAreaVO());
if (Objects.isNull(sysAreaVO.getStreetCode())) {
regionCodeList.add(receiveAddressInfoVO.getAreaCode());
continue;
}
//拼接省市区街道地址信息
String provinceName = StringUtils.isBlank(sysAreaVO.getProvinceName()) ? "" : sysAreaVO.getProvinceName();
String cityName = StringUtils.isBlank(sysAreaVO.getCityName()) ? "" : sysAreaVO.getCityName();
String regionName = StringUtils.isBlank(sysAreaVO.getRegionName()) ? "" : sysAreaVO.getRegionName();
String streetName = StringUtils.isBlank(sysAreaVO.getStreetName()) ? "" : sysAreaVO.getStreetName();
receiveAddressInfoVO.setAreaName(provinceName + cityName + regionName + streetName);
}
if (CollectionUtils.isNotEmpty(regionCodeList)) {
//查询所有区的各级信息
Map<String, SysAreaVO> sysRegionAreaMap = sysAreaMapper.getNurseStationGoodsAreaByList(regionCodeList).stream().filter(item -> StringUtils.isNotBlank(item.getRegionCode())).collect(Collectors.toMap(SysAreaVO::getRegionCode, item -> item));
for (ReceiveAddressInfoVO receiveAddressInfoVO : receiveAddressInfoList) {
SysAreaVO sysAreaVO = sysRegionAreaMap.getOrDefault(receiveAddressInfoVO.getAreaCode(), null);
if (Objects.nonNull(sysAreaVO)) {
String provinceName = StringUtils.isBlank(sysAreaVO.getProvinceName()) ? "" : sysAreaVO.getProvinceName();
String cityName = StringUtils.isBlank(sysAreaVO.getCityName()) ? "" : sysAreaVO.getCityName();
String regionName = StringUtils.isBlank(sysAreaVO.getRegionName()) ? "" : sysAreaVO.getRegionName();
receiveAddressInfoVO.setAreaName(provinceName + cityName + regionName);
}
}
}
return AjaxResult.success(receiveAddressInfoList);
}
/**
* 查询收货人地址信息
*
* @param id 收货人地址信息主键
* @return 收货人地址信息
*/
@Override
public ReceiveAddressInfo selectReceiveAddressInfoById(Long id) {
return nursingStationGoodsMapper.selectReceiveAddressInfoById(id);
}
/**
* 新增收货人地址信息
*
* @param receiveAddressInfo 收货人地址信息
* @return 结果
*/
@Override
public int insertReceiveAddressInfo(ReceiveAddressInfo receiveAddressInfo) {
//设置创建人以及创建时间
receiveAddressInfo.setCreateTime(LocalDateTime.now());
receiveAddressInfo.setPatientId(receiveAddressInfo.getPatientId());
if (StringUtils.isNotBlank(receiveAddressInfo.getReceivePhone())) {
// 校验手机号是否正确
boolean phone = regexUtil.regexPhone(receiveAddressInfo.getReceivePhone());
if (BooleanUtils.isFalse(phone)) {
throw new ServiceException("您输入的联系电话" + receiveAddressInfo.getReceivePhone() + "不正确,请重新输入!");
}
}
//根据区域areaCode查询区域级别
SysArea sysArea = sysAreaMapper.selectSysAreaById(null, receiveAddressInfo.getAreaCode());
List<Integer> areaLevelList = Arrays.asList(PROVINCE_AREA_LEVEL, CITY_AREA_LEVEL);
if (Objects.isNull(sysArea) || areaLevelList.contains(sysArea.getAreaLevel())) {
throw new ServiceException("所在地区必须选择到所在区或者街道,请重新选择!");
}
return nursingStationGoodsMapper.insertReceiveAddressInfo(receiveAddressInfo);
}
/**
* 修改收货人地址信息
*
* @param receiveAddressInfo 收货人地址信息
* @return 结果
*/
@Override
public int updateReceiveAddressInfo(ReceiveAddressInfo receiveAddressInfo) {
//设置修改人以及修改时间
receiveAddressInfo.setUpdateTime(LocalDateTime.now());
if (StringUtils.isNotBlank(receiveAddressInfo.getReceivePhone())) {
// 校验手机号是否正确
boolean phone = regexUtil.regexPhone(receiveAddressInfo.getReceivePhone());
if (BooleanUtils.isFalse(phone)) {
throw new ServiceException("您输入的联系电话" + receiveAddressInfo.getReceivePhone() + "不正确,请重新输入!");
}
}
//根据区域areaCode查询区域级别
SysArea sysArea = sysAreaMapper.selectSysAreaById(null, receiveAddressInfo.getAreaCode());
List<Integer> areaLevelList = Arrays.asList(PROVINCE_AREA_LEVEL, CITY_AREA_LEVEL);
if (Objects.isNull(sysArea) || areaLevelList.contains(sysArea.getAreaLevel())) {
throw new ServiceException("所在地区必须选择到所在区或者街道,请重新选择!");
}
return nursingStationGoodsMapper.updateReceiveAddressInfo(receiveAddressInfo);
}
/**
* 批量删除收货人地址信息
*
* @param ids 需要删除的收货人地址信息主键
* @return 结果
*/
@Override
public int deleteReceiveAddressInfoByIds(Long[] ids) {
return nursingStationGoodsMapper.deleteReceiveAddressInfoByIds(ids);
}
/**
* 下级区域寻找上级区域
*
* @param areaCode 区域编码
* @return com.xinyilu.base.domain.vo.sysarea.SysAreaVO
**/
@Override
public SysAreaVO getSubordinateRegionsFindSuperiorRegions(String areaCode) {
return nursingStationGoodsMapper.getSubordinateRegionsFindSuperiorRegions(areaCode);
}
/**
* 新增商品订单以及详细信息
*
* @param goodsOrder 商品订单
* @return 结果
*/
@Transactional(rollbackFor = Exception.class)
@Override
public AjaxResult insertNurseStationGoodsOrder(GoodsOrderStationDTO goodsOrder) {
//校验优惠券等相关信息
AjaxResult ajaxResult = checkAddGoodOrderParam(goodsOrder);
if (Objects.nonNull(ajaxResult)) {
return ajaxResult;
}
//判断库存是否充足
GoodsAttributeDetails goodsAttributeDetails = nursingStationGoodsMapper.selectGoodsAttributeDetailsGoodsStockById(goodsOrder.getGoodsAttributeDetailsId());
if (Objects.isNull(goodsAttributeDetails.getGoodsStock()) || goodsAttributeDetails.getGoodsStock() == 0) {
return AjaxResult.error("当前商品库存不足,无法购买!");
}
//库存数量
AtomicInteger goodsStock = new AtomicInteger(goodsAttributeDetails.getGoodsStock());
AtomicInteger goodsCount = new AtomicInteger(goodsOrder.getGoodsCount());
if (goodsStock.get() < goodsCount.get()) {
return AjaxResult.error("当前商品库存不足,无法购买!");
}
//生成订单信息
String goodOrderNo = com.xinelu.common.utils.StringUtils.fillZeroByPatientId(goodsOrder.getPatientId(), 5) + System.nanoTime();
this.insertGoodsOrder(goodsOrder, goodsCount, goodOrderNo);
return AjaxResult.success(goodsOrderMapper.getGoodsOrderByOrderNo(goodOrderNo));
}
/**
* 根据订单编号查询订单信息
*
* @param orderNo 订单信息编号
* @return com.xinyilu.nurseapplet.domain.nursingStationGoods.GoodsOrderPatient
**/
@Override
public GoodsOrderPatient selectGoodsOrderPatient(String orderNo) {
return nursingStationGoodsMapper.selectGoodsOrderPatient(orderNo);
}
/**
* App和小程序确认收货
*
* @param orderNo 订单编号
* @return 结果信息
*/
@Override
public AjaxResult confirmReceipt(String orderNo) {
GoodsOrder goodsOrderByOrderNo = goodsOrderMapper.getGoodsOrderByOrderNo(orderNo);
if (Objects.isNull(goodsOrderByOrderNo)) {
return AjaxResult.error("当前订单信息不存在,请重新选择!");
}
if (!GooodsOrderStatusEnum.WAIT_RECEIVED_GOODS.getInfo().equals(goodsOrderByOrderNo.getOrderStatus())) {
return AjaxResult.error("当前订单非待收货状态,无法确认收货!");
}
goodsOrderMapper.updateGoodsOrderStatus(GooodsOrderStatusEnum.RECEIVED_GOODS.getInfo(), orderNo);
return AjaxResult.success();
}
/**
* 微信小程序和会员App设置默认地址接口
*
* @param defaultAddressList 默认地址标识集合
* @return 结果
*/
@Transactional(rollbackFor = Exception.class)
@Override
public AjaxResult updateDefaultAddress(List<UpdateDefaultAddressVO> defaultAddressList) {
for (UpdateDefaultAddressVO updateDefaultAddressVO : defaultAddressList) {
ReceiveAddressInfo receiveAddressInfo = new ReceiveAddressInfo();
receiveAddressInfo.setId(updateDefaultAddressVO.getId());
receiveAddressInfo.setUpdateTime(LocalDateTime.now());
receiveAddressInfo.setDefaultAddressFlag(updateDefaultAddressVO.getDefaultAddressFlag());
int updateReceiveCount = receiveAddressInfoMapper.updateReceiveAddressInfo(receiveAddressInfo);
if (updateReceiveCount <= 0) {
throw new ServiceException("设置默认收货地址失败,请联系管理员!");
}
}
return AjaxResult.success();
}
/**
* 根据当前分类id查询其下属所有子分类id集合
*
* @param categoryId 当前分类id
* @return 子分类id集合
*/
private List<Integer> getChildCategoryIds(Long categoryId) {
//查询当前分类下属所有分类id集合
String childrenCategoryIds = nursingStationGoodsMapper.getChildrenCategoryIds(categoryId);
//分割 去除第一个 获取数据 转换类型
String[] split;
List<Integer> goodsCategoryIds = Lists.newArrayList();
if (childrenCategoryIds.length() > 0) {
split = StringUtils.split(childrenCategoryIds.substring(1), ",");
goodsCategoryIds = Arrays.stream(split).map(Integer::valueOf).collect(Collectors.toList());
}
return goodsCategoryIds;
}
/**
* 商品订单接口相关参数校验
*
* @param goodsOrder 商品订单信息
* @return 校验结果
*/
private AjaxResult checkAddGoodOrderParam(GoodsOrderStationDTO goodsOrder) {
//判断当前会员信息是否存在
PatientInfoVO patientInfo = patientInfoMapper.getPatientInfoById(goodsOrder.getPatientId());
if (Objects.isNull(patientInfo)) {
return AjaxResult.error("用户信息不存在,无法购买商品!");
}
if (Objects.nonNull(goodsOrder.getCouponId())) {
//当前商品订单使用了优惠券
PatientCouponReceiveVO patientCouponInfo = patientCouponReceiveMapper.getPatientCouponInfo(goodsOrder.getPatientId(), goodsOrder.getCouponId());
if (Objects.isNull(patientCouponInfo)) {
return AjaxResult.error("优惠券信息不存在,无法购买商品!");
}
//优惠券金额是否被篡改过
if (Objects.nonNull(goodsOrder.getDiscountPrice()) && Objects.nonNull(patientCouponInfo.getCouponPrice()) && goodsOrder.getDiscountPrice().compareTo(patientCouponInfo.getCouponPrice()) != 0) {
return AjaxResult.error("优惠券金额已被篡改过,无法使用'" + patientCouponInfo.getCouponTitle() + "'优惠券购买商品!");
}
//优惠券门槛是否被篡改过
if (Objects.nonNull(goodsOrder.getCouponConsumePrice()) && Objects.nonNull(patientCouponInfo.getCouponConsumePrice()) && goodsOrder.getCouponConsumePrice().compareTo(patientCouponInfo.getCouponConsumePrice()) != 0) {
return AjaxResult.error("优惠券使用门槛已被篡改过,无法使用'" + patientCouponInfo.getCouponTitle() + "'优惠券购买商品!");
}
//判断当前优惠券是否过期
if (StringUtils.isNotBlank(patientCouponInfo.getUseStatus()) && CouponUseStatusEnum.USED.getInfo().equals(patientCouponInfo.getUseStatus())) {
return AjaxResult.error("优惠券:'" + patientCouponInfo.getCouponTitle() + "'已使用,无法使用!");
}
boolean isUsedStatus = StringUtils.isNotBlank(patientCouponInfo.getUseStatus()) && CouponUseStatusEnum.EXPIRED.getInfo().equals(patientCouponInfo.getUseStatus());
boolean expireTime = Objects.nonNull(patientCouponInfo.getExpirationEndTime()) && LocalDateTime.now().isAfter(patientCouponInfo.getExpirationEndTime());
if (BooleanUtils.isTrue(isUsedStatus) || BooleanUtils.isTrue(expireTime)) {
return AjaxResult.error("优惠券:'" + patientCouponInfo.getCouponTitle() + "'已过期,无法使用!");
}
//判断商品总金额是否大于使用优惠券使用门槛
if (Objects.nonNull(goodsOrder.getGoodsCount()) && Objects.nonNull(goodsOrder.getGoodsPrice()) && Objects.nonNull(patientCouponInfo.getCouponConsumePrice())) {
BigDecimal originalPrice = BigDecimal.valueOf(goodsOrder.getGoodsCount()).multiply(goodsOrder.getGoodsPrice()).setScale(2, BigDecimal.ROUND_DOWN);
if (Objects.nonNull(goodsOrder.getOriginalTotalPrice()) && originalPrice.compareTo(goodsOrder.getOriginalTotalPrice()) != 0) {
return AjaxResult.error("订单金额被篡改过,原始金额为:" + originalPrice + ", 篡改后金额为:" + goodsOrder.getOriginalTotalPrice() + ",无法购买!");
}
if (BooleanUtils.isFalse(originalPrice.compareTo(patientCouponInfo.getCouponConsumePrice()) >= 0)) {
return AjaxResult.error("订单金额未达到优惠券使用门槛,'" + patientCouponInfo.getCouponTitle() + "'优惠券无法使用!");
}
}
//判断商品数量 * 商品单价 - 优惠券金额 = 应付总价格
if (Objects.nonNull(goodsOrder.getGoodsCount()) && Objects.nonNull(goodsOrder.getGoodsPrice()) && Objects.nonNull(goodsOrder.getDiscountPrice())) {
BigDecimal originalPrice = BigDecimal.valueOf(goodsOrder.getGoodsCount()).multiply(goodsOrder.getGoodsPrice()).setScale(2, BigDecimal.ROUND_DOWN);
if (Objects.nonNull(goodsOrder.getOriginalTotalPrice()) && originalPrice.compareTo(goodsOrder.getOriginalTotalPrice()) != 0) {
return AjaxResult.error("订单金额被篡改过,原始金额为:" + originalPrice + ", 篡改后金额为:" + goodsOrder.getOriginalTotalPrice() + ",无法购买!");
}
BigDecimal totalPrice = originalPrice.subtract(goodsOrder.getDiscountPrice()).setScale(2, BigDecimal.ROUND_DOWN);
if (totalPrice.compareTo(goodsOrder.getTotalPrice()) != 0) {
return AjaxResult.error("订单金额不正确,应付金额为:" + totalPrice + "元,支付金额为:" + goodsOrder.getTotalPrice() + ",无法购买!");
}
}
} else {
//未使用优惠券计算商品数量 * 商品单价 = 应付总价格
if (Objects.nonNull(goodsOrder.getGoodsCount()) && Objects.nonNull(goodsOrder.getGoodsPrice()) && Objects.nonNull(goodsOrder.getTotalPrice())) {
BigDecimal originalPrice = BigDecimal.valueOf(goodsOrder.getGoodsCount()).multiply(goodsOrder.getGoodsPrice()).setScale(2, BigDecimal.ROUND_DOWN);
if (Objects.nonNull(goodsOrder.getOriginalTotalPrice()) && originalPrice.compareTo(goodsOrder.getOriginalTotalPrice()) != 0) {
return AjaxResult.error("订单金额不正确,应付金额为:" + originalPrice + "元,支付金额为:" + goodsOrder.getOriginalTotalPrice() + ",无法购买!");
}
if (originalPrice.compareTo(goodsOrder.getTotalPrice()) != 0) {
return AjaxResult.error("订单金额不正确,应付金额为:" + originalPrice + "元,支付金额为:" + goodsOrder.getTotalPrice() + ",无法购买!");
}
}
}
return null;
}
/**
* 商品订单接口-生成订单表和订单明细表信息
*
* @param goodsOrder 输入参数
* @param goodsCount 库存原子数量
* @param goodOrderNo 订单编号
*/
private void insertGoodsOrder(GoodsOrderStationDTO goodsOrder, AtomicInteger goodsCount, String goodOrderNo) {
//新增商品订单主表信息
GoodsOrder good = new GoodsOrder();
BeanUtils.copyBeanProp(good, goodsOrder);
good.setPatientId(goodsOrder.getPatientId());
good.setOrderNo(goodOrderNo);
good.setOrderStatus(GooodsOrderStatusEnum.WAIT_PAY.getInfo());
good.setRemark(StringUtils.isBlank(goodsOrder.getRemark()) ? "" : goodsOrder.getRemark());
good.setOrderTime(LocalDateTime.now());
good.setDelFlag(0);
good.setOrderType(OrderTypeEnum.DIRECT_BUY.getInfo());
good.setCreateTime(LocalDateTime.now());
good.setOriginalTotalPrice(goodsOrder.getOriginalTotalPrice());
int stationGoodsOrder = goodsOrderMapper.insertGoodsOrder(good);
if (stationGoodsOrder <= 0) {
throw new ServiceException("商品订单新增信息失败,请联系管理员!");
}
//新增商品订单明细表信息
GoodsOrderDetails goodsOrderDetails = new GoodsOrderDetails();
BeanUtils.copyBeanProp(goodsOrderDetails, goodsOrder);
goodsOrderDetails.setGoodsOrderId(good.getId());
goodsOrderDetails.setOrderNo(goodOrderNo);
goodsOrderDetails.setDelFlag(0);
goodsOrderDetails.setCreateTime(LocalDateTime.now());
if (Objects.nonNull(goodsOrder.getCouponId())) {
goodsOrderDetails.setCouponId(goodsOrder.getCouponId());
}
if (StringUtils.isNotBlank(goodsOrder.getCouponTitle())) {
goodsOrderDetails.setCouponTitle(goodsOrderDetails.getCouponTitle());
}
if (Objects.nonNull(goodsOrderDetails.getDiscountPrice())) {
goodsOrderDetails.setDiscountPrice(goodsOrderDetails.getDiscountPrice());
}
int orderDetails = goodsOrderDetailsMapper.insertGoodsOrderDetails(goodsOrderDetails);
if (orderDetails <= 0) {
throw new ServiceException("商品订单明细新增信息失败,请联系管理员!");
}
//修改优惠券的状态
if (Objects.nonNull(goodsOrder.getCouponId())) {
patientCouponReceiveMapper.updatePatientCouponUseStatus(goodsOrder.getPatientId(), goodsOrder.getCouponId(), CouponUseStatusEnum.USED.getInfo());
}
//减少库存数量
String goodsStockKey = Constants.BUY_GOODS_REDUCE_STOCK_KEY + goodOrderNo + "_" + goodsOrderDetails.getId();
boolean tryLock = redisDistributedLockUtils.tryLock(goodsStockKey, 5);
if (!tryLock) {
log.info("商品订单获取Redis锁失败订单编号 =====> {}", goodOrderNo);
throw new ServiceException("减少库存信息失败,请联系管理员!");
}
try {
//减少库存数量
int updateCount = goodsAttributeDetailsMapper.reduceGoodsStockCount(goodsOrder.getGoodsAttributeDetailsId(), goodsCount.get());
if (updateCount < 1) {
log.info("减少库存数量失败,订单编号:{}商品属性明细id{},库存数量:{}", goodOrderNo, goodsOrder.getGoodsAttributeDetailsId(), goodsCount.get());
}
} catch (Exception e) {
log.error("减少库存信息失败,失败原因为 ====> {}", e.getMessage());
throw new ServiceException(e.getMessage());
} finally {
redisDistributedLockUtils.unlock(goodsStockKey);
}
}
}

View File

@ -0,0 +1,95 @@
package com.xinelu.applet.service.patientcenter;
import com.xinelu.applet.dto.nursingstationgoods.GoodsList;
import com.xinelu.applet.dto.nursingstationgoods.GoodsOrderStationDTO;
import com.xinelu.applet.dto.patientcenter.PatientCenterCouponDTO;
import com.xinelu.applet.vo.coupon.CouponVO;
import com.xinelu.applet.vo.patientcenter.PatientCenterCouponVO;
import com.xinelu.applet.vo.patientcenter.PatientSignInfoVO;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.page.TableDataInfo;
import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord;
import java.util.List;
/**
* @Description 会员APP和小程序个人中心业务层
* @Author 纪寒
* @Date 2023-02-24 14:45:11
* @Version 1.0
*/
public interface PatientCenterService {
/**
* 会员app和微信小程序-签到方法
*
* @param patientId 会员用户id
* @param signInChannel 签到来源微信小程序会员APP
* @return 签到结果
*/
AjaxResult patientSignIn(Long patientId, String signInChannel);
/**
* 个人中心优惠券
*
* @param patientCenterCouponVO 用户信息及优惠券状态
* @return List<CouponVO>
*/
List<CouponVO> selectCouponByUseStatus(PatientCenterCouponVO patientCenterCouponVO);
/**
* 个人中心积分兑换 - 查询积分兑换商品
*
* @return AjaxResult
*/
List<GoodsList> selectExchangeGoods();
/**
* 获取积分返回规则
*
* @param patientId 用户id
* @return com.xinyilu.nurseapplet.domain.vo.patientcenter.PatientSignInfoVO
**/
PatientSignInfoVO selectPatientSignIn(Long patientId);
/**
* 新人福利优惠券
*
* @param patientCenterCouponVO 用户信息及优惠券状态
* @return List<CouponVO>
*/
TableDataInfo getCouponByUseStatus(PatientCenterCouponDTO patientCenterCouponVO);
/**
* 新人福利-优惠券领取
*
* @param patientId 用户id
* @param couponId 优惠券id
* @return AjaxResult
*/
AjaxResult insertCouponReceive(Long patientId, Long couponId);
/**
* 微信小程序-邀请好友接口
*
* @param inviteId 邀请人id
* @return 邀请码图片地址
*/
AjaxResult inviteFriends(Long inviteId);
/**
* 新增积分兑换商品订单以及详细信息
*
* @param goodsOrder 商品订单
* @return 结果
*/
AjaxResult insertIntegralGoodsOrder(GoodsOrderStationDTO goodsOrder);
/**
* 新增订阅微信小程序订阅消息记录
*
* @param subscribeMessageRecord 订阅微信小程序订阅消息记录
* @return com.xinyilu.common.core.domain.AjaxResult
**/
AjaxResult insertSubscribeMessageRecord(List<SubscribeMessageRecord> subscribeMessageRecord);
}

View File

@ -0,0 +1,666 @@
package com.xinelu.applet.service.patientcenter.impl;
import com.xinelu.applet.dto.nursingstationgoods.GoodsList;
import com.xinelu.applet.dto.nursingstationgoods.GoodsOrderStationDTO;
import com.xinelu.applet.dto.patientcenter.PatientCenterCouponDTO;
import com.xinelu.applet.mapper.nurseapplogin.NurseAppLoginMapper;
import com.xinelu.applet.mapper.nursingstationgoods.NursingStationGoodsMapper;
import com.xinelu.applet.mapper.patientcenter.PatientCenterMapper;
import com.xinelu.applet.service.messagepush.MessagePushService;
import com.xinelu.applet.service.patientcenter.PatientCenterService;
import com.xinelu.applet.vo.coupon.CouponVO;
import com.xinelu.applet.vo.patientcenter.PatientCenterCouponVO;
import com.xinelu.applet.vo.patientcenter.PatientSignInVO;
import com.xinelu.applet.vo.patientcenter.PatientSignInfoVO;
import com.xinelu.common.config.AppletChatConfig;
import com.xinelu.common.config.AppletPageConfig;
import com.xinelu.common.config.XinELuConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.page.TableDataInfo;
import com.xinelu.common.enums.*;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.AppletChatUtil;
import com.xinelu.common.utils.PageServiceUtil;
import com.xinelu.common.utils.RedisDistributedLockUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.manage.domain.coupon.Coupon;
import com.xinelu.manage.domain.goodsAttributeDetails.GoodsAttributeDetails;
import com.xinelu.manage.domain.goodsOrder.GoodsOrder;
import com.xinelu.manage.domain.goodsOrderDetails.GoodsOrderDetails;
import com.xinelu.manage.domain.patientcouponreceive.PatientCouponReceive;
import com.xinelu.manage.domain.patientintegralchange.PatientIntegralChange;
import com.xinelu.manage.domain.patientsignininfo.PatientSignInInfo;
import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord;
import com.xinelu.manage.domain.systemsettingsinfo.SystemSettingsInfo;
import com.xinelu.manage.mapper.coupon.CouponMapper;
import com.xinelu.manage.mapper.goodsAttributeDetails.GoodsAttributeDetailsMapper;
import com.xinelu.manage.mapper.goodsOrder.GoodsOrderMapper;
import com.xinelu.manage.mapper.goodsOrderDetails.GoodsOrderDetailsMapper;
import com.xinelu.manage.mapper.patientcouponreceive.PatientCouponReceiveMapper;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.patientintegralchange.PatientIntegralChangeMapper;
import com.xinelu.manage.mapper.patientsignininfo.PatientSignInInfoMapper;
import com.xinelu.manage.mapper.subscribemessagerecord.SubscribeMessageRecordMapper;
import com.xinelu.manage.mapper.systemsettingsinfo.SystemSettingsInfoMapper;
import com.xinelu.manage.vo.patientcouponreceive.PatientCouponReceiveInfoVO;
import com.xinelu.manage.vo.patientinfo.PatientInfoVO;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* @Description 会员APP和小程序个人中心业务层实现类
* @Author 纪寒
* @Date 2023-02-24 14:45:35
* @Version 1.0
*/
@Slf4j
@Service
public class PatientCenterServiceImpl implements PatientCenterService {
@Resource
private PatientCenterMapper patientCenterMapper;
@Resource
private SystemSettingsInfoMapper systemSettingsInfoMapper;
@Resource
private PatientSignInInfoMapper patientSignInInfoMapper;
@Resource
private PatientIntegralChangeMapper patientIntegralChangeMapper;
@Resource
private PatientInfoMapper patientInfoMapper;
@Resource
private AppletPageConfig appletPageConfig;
@Resource
private XinELuConfig xinYiLuConfig;
@Resource
private NurseAppLoginMapper nurseAppLoginMapper;
@Resource
private PageServiceUtil pageServiceUtil;
@Resource
private PatientCouponReceiveMapper patientCouponReceiveMapper;
@Resource
private NursingStationGoodsMapper nursingStationGoodsMapper;
@Resource
private RedisDistributedLockUtils redisDistributedLockUtils;
@Resource
private GoodsAttributeDetailsMapper goodsAttributeDetailsMapper;
@Resource
private GoodsOrderMapper goodsOrderMapper;
@Resource
private GoodsOrderDetailsMapper goodsOrderDetailsMapper;
@Resource
private CouponMapper couponMapper;
@Resource
private AppletChatConfig appletChatConfig;
@Resource
private SubscribeMessageRecordMapper subscribeMessageRecordMapper;
@Resource
private MessagePushService messagePushService;
/**
* 用户第一次签到次数
*/
private static final int FIRST_SIGN_COUNT = 1;
/**
* 获取小程序二维码接口失败标识
*/
private static final String FAIL = "FAIL";
/**
* 会员app和微信小程序-签到方法
*
* @param patientId 会员用户id
* @param signInChannel 签到来源微信小程序会员APP
* @return 签到结果
*/
@Transactional(rollbackFor = Exception.class)
@Override
public AjaxResult patientSignIn(Long patientId, String signInChannel) {
//确认用户是否是第一次签到
PatientSignInVO patientSignInInfo = patientCenterMapper.getPatientSignInInfo(patientId, LocalDate.now());
if (Objects.isNull(patientSignInInfo)) {
return AjaxResult.error("当前用户信息不存在,无法进行签到,请联系管理员!");
}
if (Objects.nonNull(patientSignInInfo.getTotalSignInDays()) && patientSignInInfo.getTodaySignInCount() > 0) {
return AjaxResult.error("您今天已经签到!");
}
boolean isFirstSignIn = Objects.isNull(patientSignInInfo.getSignInCount()) || patientSignInInfo.getSignInCount() == 0;
if (Objects.isNull(patientSignInInfo.getTotalSignInDays()) && BooleanUtils.isTrue(isFirstSignIn)) {
//当前用户第一次签到记录签到信息
patientCenterMapper.updateTotalSignInDays(patientId);
this.setPatientSignInInfo(patientId, signInChannel);
//第一次签到送积分以及记录积分变更记录
this.insertGoodPatientIntegral(patientSignInInfo, FIRST_SIGN_COUNT, patientId, signInChannel);
messagePushService.integralMessage(patientId, FIRST_SIGN_COUNT);
return AjaxResult.success(FIRST_SIGN_COUNT);
}
//用户不是第一次签到判断当前用户是否到达签到天数并送积分
patientCenterMapper.updateTotalSignInDays(patientId);
this.setPatientSignInInfo(patientId, signInChannel);
AtomicInteger atomicInteger = new AtomicInteger(Objects.isNull(patientSignInInfo.getTotalSignInDays()) ? 0 : patientSignInInfo.getTotalSignInDays());
int increment = atomicInteger.incrementAndGet();
//新增账户积分以及记录积分变更记录
this.insertGoodPatientIntegral(patientSignInInfo, increment, patientId, signInChannel);
messagePushService.integralMessage(patientId, increment);
return AjaxResult.success(increment);
}
/**
* 个人中心优惠券
*
* @param patientCenterCouponVO 用户信息及优惠券状态
* @return List<CouponVO>
*/
@Transactional(rollbackFor = Exception.class)
@Override
public List<CouponVO> selectCouponByUseStatus(PatientCenterCouponVO patientCenterCouponVO) {
patientCenterCouponVO.setReceiveSource(CouponReceiveTypeEnum.NEW_PEOPLE_WELFARE.getInfo());
List<String> useStatusList = Arrays.asList(CouponUseStatusEnum.USED.getInfo(), CouponUseStatusEnum.NOT_USED.getInfo(), CouponUseStatusEnum.EXPIRED.getInfo());
patientCenterCouponVO.setUseStatusList(useStatusList);
List<CouponVO> couponList = patientCenterMapper.selectCouponByUseStatus(patientCenterCouponVO);
//筛查过期的优惠券
for (CouponVO couponVO : couponList) {
if (Objects.isNull(couponVO) || Objects.isNull(couponVO.getExpirationEndTime())) {
continue;
}
if (LocalDateTime.now().isAfter(couponVO.getExpirationEndTime())) {
PatientCouponReceive patientCouponReceive = new PatientCouponReceive();
patientCouponReceive.setId(Objects.isNull(couponVO.getPatientCouponReceiveId()) ? 0 : couponVO.getPatientCouponReceiveId());
patientCouponReceive.setUseStatus(CouponUseStatusEnum.EXPIRED.getInfo());
int couponReceive = patientCouponReceiveMapper.updatePatientCouponReceive(patientCouponReceive);
if (couponReceive < 0) {
throw new ServiceException("个人中心优惠券查询失败,请联系管理员!");
}
couponVO.setUseStatus(CouponUseStatusEnum.EXPIRED.getInfo());
}
}
return couponList;
}
/**
* 积分兑换 - 查询积分兑换商品
*
* @return AjaxResult
*/
@Override
public List<GoodsList> selectExchangeGoods() {
//传入积分兑换标识是否上架商品买卖
return patientCenterMapper.selectGoodsByExchangeFlag(CouponAndIntegralFlagEnum.CONVERTIBLE.getInfo(), WhetherShelfEnum.SHEL.getInfo(), GoodsPurposeEnum.BUSINESS.getInfo());
}
/**
* 获取积分返回规则
*
* @param patientId 用户id
* @return com.xinyilu.nurseapplet.domain.vo.patientcenter.PatientSignInfoVO
**/
@Override
public PatientSignInfoVO selectPatientSignIn(Long patientId) {
//查询积分签到规则和邀请好友规则
List<String> ruleList = Arrays.asList(SettingsTypeEnum.INVITE_FRIENDS.getInfo(), SettingsTypeEnum.SIGN_IN_RULE.getInfo());
Map<String, PatientSignInfoVO> ruleMap = patientCenterMapper.selectPatientSignIn(patientId, LocalDate.now(), ruleList).stream().filter(item -> StringUtils.isNotBlank(item.getSettingsType())).collect(Collectors.toMap(PatientSignInfoVO::getSettingsType, item -> item));
PatientSignInfoVO vo = new PatientSignInfoVO();
//获取累计签到规则信息
PatientSignInfoVO signInfoVO = ruleMap.getOrDefault(SettingsTypeEnum.SIGN_IN_RULE.getInfo(), new PatientSignInfoVO());
if (Objects.nonNull(signInfoVO) && Objects.nonNull(signInfoVO.getTotalSignInDays())) {
vo.setTotalSignInDays(signInfoVO.getTotalSignInDays());
} else {
vo.setTotalSignInDays(0);
}
if (Objects.nonNull(signInfoVO) && Objects.nonNull(signInfoVO.getIntegralCount())) {
vo.setSignInCount(signInfoVO.getIntegralCount());
} else {
vo.setSignInCount(0);
}
//获取邀请规则信息
PatientSignInfoVO inviteVO = ruleMap.getOrDefault(SettingsTypeEnum.INVITE_FRIENDS.getInfo(), new PatientSignInfoVO());
if (Objects.nonNull(inviteVO) && Objects.nonNull(inviteVO.getIntegralCount())) {
vo.setInviteFriends(inviteVO.getIntegralCount());
} else {
vo.setInviteFriends(0);
}
//查询用户签到天数和账户积分信息
PatientSignInfoVO patientSignInfo = patientCenterMapper.getPatientSignInfo(patientId, LocalDate.now());
if (Objects.isNull(patientSignInfo)) {
throw new ServiceException("当前用户信息不存在,获取积分信息失败!");
}
vo.setPatientSignInCount(Objects.isNull(patientSignInfo.getPatientSignInCount()) ? 0 : patientSignInfo.getPatientSignInCount());
vo.setIntegral(Objects.isNull(patientSignInfo.getIntegral()) ? 0 : patientSignInfo.getIntegral());
vo.setTodaySignInCount(Objects.isNull(patientSignInfo.getTodaySignInCount()) ? 0 : patientSignInfo.getTodaySignInCount());
return vo;
}
/**
* 微信小程序-邀请好友接口
*
* @param inviteId 邀请人id
* @return 邀请码图片地址
*/
@Override
public AjaxResult inviteFriends(Long inviteId) {
//获取微信小程序AccessToken的值
PatientInfoVO patientInfo = patientInfoMapper.getPatientInfoById(inviteId);
if (Objects.isNull(patientInfo)) {
return AjaxResult.error("当前用户信息不存在,请联系管理员!");
}
if (StringUtils.isBlank(patientInfo.getPersonalWechatCodeUrl())) {
String fileName = String.valueOf(System.nanoTime()) + inviteId + ".png";
//小程序跳转路径
String appletPageUrl = appletPageConfig.getPageUrl();
//邀请人二维码存放路径
String filePathWeChatCodeUrl = xinYiLuConfig.getPersonalWeChatCodeUrl();
String appletCodePicture = AppletChatUtil.createAppletCode(inviteId, false, fileName, appletPageUrl, filePathWeChatCodeUrl);
if (StringUtils.isNotBlank(appletCodePicture) && StringUtils.equals(FAIL, appletCodePicture)) {
//第一次调用获取小程序二维码信息失败重新递归调用一次第二次失败直接返回提示信息
appletCodePicture = AppletChatUtil.createAppletCode(inviteId, true, fileName, appletPageUrl, filePathWeChatCodeUrl);
if (StringUtils.isNotBlank(appletCodePicture) && StringUtils.equals(FAIL, appletCodePicture)) {
return AjaxResult.error("获取小程序二维码信息失败,请联系管理员!");
}
}
String pictureUrl = "";
if (StringUtils.isNotBlank(appletCodePicture)) {
pictureUrl = "/profile" + xinYiLuConfig.getPersonalWeChatCodeUrl() + "/" + inviteId + "/" + fileName;
int updateCount = patientInfoMapper.updatePersonalWeChatCodeUrl(inviteId, pictureUrl);
if (updateCount <= 0) {
throw new ServiceException("获取微信小程序二维码信息失败,请联系管理员!");
}
}
return AjaxResult.success(pictureUrl);
}
//直接返回二维码图片信息
return AjaxResult.success(patientInfo.getPersonalWechatCodeUrl());
}
/**
* 新增积分兑换商品订单以及详细信息
*
* @param goodsOrder 商品订单
* @return 结果
*/
@Transactional(rollbackFor = Exception.class)
@Override
public AjaxResult insertIntegralGoodsOrder(GoodsOrderStationDTO goodsOrder) {
//判断当前会员信息是否存在
PatientInfoVO patientInfo = patientInfoMapper.getPatientInfoById(goodsOrder.getPatientId());
if (Objects.isNull(patientInfo)) {
return AjaxResult.error("当前用户信息不存在,无法兑换!");
}
GoodsAttributeDetails goodsAttributeDetails = nursingStationGoodsMapper.selectGoodsAttributeDetailsGoodsStockById(goodsOrder.getGoodsAttributeDetailsId());
//判断当前商品是否可兑换商品
if (Objects.nonNull(goodsAttributeDetails) && CouponAndIntegralFlagEnum.NOT_CONVERTIBLE.getInfo().equals(goodsAttributeDetails.getIntegralExchangeFlag())) {
return AjaxResult.error("当前商品非积分兑换商品,无法兑换!");
}
//判断积分兑换数值是否正确
boolean integralExchangeSill = Objects.nonNull(goodsAttributeDetails) && Objects.isNull(goodsAttributeDetails.getIntegralExchangeSill());
boolean equalIntegralExchangeSill = Objects.nonNull(goodsAttributeDetails) && !goodsOrder.getIntegralExchangeSill().equals(goodsAttributeDetails.getIntegralExchangeSill());
if (BooleanUtils.isTrue(integralExchangeSill) || BooleanUtils.isTrue(equalIntegralExchangeSill)) {
return AjaxResult.error("当前商品兑换需要使用的积分数值不正确,无法兑换!");
}
//判断积分兑换商品数目是否正确
boolean integralExchangeCount = Objects.nonNull(goodsAttributeDetails) && Objects.isNull(goodsAttributeDetails.getIntegralExchangeCount());
boolean equalIntegralExchangeCount = Objects.nonNull(goodsAttributeDetails) && !goodsOrder.getIntegralExchangeCount().equals(goodsAttributeDetails.getIntegralExchangeCount());
if (BooleanUtils.isTrue(integralExchangeCount) || BooleanUtils.isTrue(equalIntegralExchangeCount)) {
return AjaxResult.error("当前积分兑换商品的数量不正确,无法兑换!");
}
//判断库存是否充足
if (Objects.isNull(goodsAttributeDetails.getGoodsStock()) || goodsAttributeDetails.getGoodsStock() == 0) {
return AjaxResult.error("当前商品库存不足,无法购买!");
}
//判读用户账户积分是否充足
AtomicInteger patientIntegral = new AtomicInteger(Objects.isNull(patientInfo.getIntegral()) ? 0 : patientInfo.getIntegral());
AtomicInteger exchangeIntegralSkill = new AtomicInteger(Objects.isNull(goodsOrder.getIntegralExchangeSill()) ? 0 : goodsOrder.getIntegralExchangeSill());
if (patientIntegral.get() < exchangeIntegralSkill.get()) {
return AjaxResult.error("当前用户的账户积分数值不足,无法兑换!");
}
//判断商品库存数量是否满足兑换数量
AtomicInteger goodsStock = new AtomicInteger(goodsAttributeDetails.getGoodsStock());
AtomicInteger exchangeGoodsCount = new AtomicInteger(goodsOrder.getIntegralExchangeCount());
if (goodsStock.get() < exchangeGoodsCount.get()) {
return AjaxResult.error("当前商品库存不足,无法兑换!");
}
//生成兑换商品订单信息
String goodOrderNo = com.xinelu.common.utils.StringUtils.fillZeroByPatientId(goodsOrder.getPatientId(), 5) + System.nanoTime();
this.addExchangeGoodsOrderInfo(goodsOrder, patientInfo, exchangeIntegralSkill, exchangeGoodsCount, goodOrderNo);
return AjaxResult.success(goodsOrderMapper.getGoodsOrderByOrderNo(goodOrderNo));
}
/**
* 新增订阅微信小程序订阅消息记录
*
* @param subscribeMessageRecord 订阅微信小程序订阅消息记录
* @return com.xinyilu.common.core.domain.AjaxResult
**/
@Transactional(rollbackFor = Exception.class)
@Override
public AjaxResult insertSubscribeMessageRecord(List<SubscribeMessageRecord> subscribeMessageRecord) {
SubscribeMessageRecord messageRecord = new SubscribeMessageRecord();
messageRecord.setPatientId(subscribeMessageRecord.get(0).getPatientId());
messageRecord.setOpenid(subscribeMessageRecord.get(0).getOpenid());
//查询数据库中的数据 并去重
List<SubscribeMessageRecord> subscribeMessageRecords = subscribeMessageRecordMapper.selectSubscribeMessageRecordList(messageRecord);
//前端穿过聊的数据并去重
List<SubscribeMessageRecord> subscribeRecordVO = subscribeMessageRecord.stream().distinct().collect(Collectors.toList());
//求出差集 要新增的
List<SubscribeMessageRecord> messageRecordSubtract = new ArrayList<>(CollectionUtils.subtract(subscribeRecordVO, subscribeMessageRecords));
//求出交集 要修改的
List<SubscribeMessageRecord> messageRecordRetainAll = new ArrayList<>(CollectionUtils.intersection(subscribeRecordVO, subscribeMessageRecords));
if (CollectionUtils.isNotEmpty(messageRecordRetainAll)) {
for (SubscribeMessageRecord record : messageRecordRetainAll) {
subscribeMessageRecordMapper.updateSubscribeMessageTemplateId(record.getOpenid(), record.getTemplateId(), record.getSubscribeStatus(), record.getPatientId());
}
}
if (CollectionUtils.isNotEmpty(messageRecordSubtract)) {
return AjaxResult.success();
}
//新增订阅消息表信息
for (SubscribeMessageRecord record : messageRecordSubtract) {
record.setAppletId(appletChatConfig.getAppletId());
record.setSubscribeCount(1);
record.setSubscribeTime(LocalDateTime.now());
record.setSubscribeStatus(record.getSubscribeStatus());
if (StringUtils.equals(appletChatConfig.getAppointOrderTemplateId(), record.getTemplateId())) {
record.setMessageType(SubscribeMessageTypeEnum.APPOINT_ORDER_MESSAGE_PUSH.getInfo());
}
if (StringUtils.equals(appletChatConfig.getCouponReceiveTemplateId(), record.getTemplateId())) {
record.setMessageType(SubscribeMessageTypeEnum.COUPON_RECEIVE_MESSAGE_PUSH.getInfo());
}
if (StringUtils.equals(appletChatConfig.getGoodsOrderTemplateId(), record.getTemplateId())) {
record.setMessageType(SubscribeMessageTypeEnum.GOODS_ORDER_MESSAGE_PUSH.getInfo());
}
}
int insertRecord = subscribeMessageRecordMapper.insertSubscribeMessageRecordList(messageRecordSubtract);
if (insertRecord <= 0) {
return AjaxResult.error("新增订阅消息失败,请联系管理员!");
}
return AjaxResult.success();
}
/**
* 新人福利优惠券
*
* @param patientCenterCouponDTO 用户信息及优惠券状态
* @return List<CouponVO>
*/
@Transactional(rollbackFor = Exception.class)
@Override
public TableDataInfo getCouponByUseStatus(PatientCenterCouponDTO patientCenterCouponDTO) {
//用户无登录情况下
if (Objects.isNull(patientCenterCouponDTO.getPatientId())) {
pageServiceUtil.startPage();
List<CouponVO> couponNewPeople = patientCenterMapper.getCouponNewPeople(CouponReceiveTypeEnum.NEW_PEOPLE_WELFARE.getInfo());
return pageServiceUtil.getDataTable(couponNewPeople);
}
// 根据传过来的人员id去查询会员表中的完善标识字段
Integer loginFlag = nurseAppLoginMapper.getLoginFlagByPatientId(patientCenterCouponDTO.getPatientId());
patientCenterCouponDTO.setReceiveType(CouponReceiveTypeEnum.NEW_PEOPLE_WELFARE.getInfo());
//去判断完善标识是否完善 如果没有完善就是新人 否则就是注册过的
if (Objects.isNull(loginFlag)) {
pageServiceUtil.startPage();
List<CouponVO> couponNewPeople = patientCenterMapper.getCouponNewPeople(CouponReceiveTypeEnum.NEW_PEOPLE_WELFARE.getInfo());
return pageServiceUtil.getDataTable(couponNewPeople);
}
pageServiceUtil.startPage();
List<CouponVO> couponList = patientCenterMapper.getCouponByUseStatus(patientCenterCouponDTO);
//筛查过期的优惠券
for (CouponVO couponVO : couponList) {
if (Objects.isNull(couponVO) || Objects.isNull(couponVO.getExpirationEndTime())) {
continue;
}
if (LocalDateTime.now().isAfter(couponVO.getExpirationEndTime())) {
PatientCouponReceive patientCouponReceive = new PatientCouponReceive();
patientCouponReceive.setId(Objects.isNull(couponVO.getPatientCouponReceiveId()) ? 0 : couponVO.getPatientCouponReceiveId());
patientCouponReceive.setUseStatus(CouponUseStatusEnum.EXPIRED.getInfo());
patientCouponReceiveMapper.updatePatientCouponReceive(patientCouponReceive);
couponVO.setUseStatus(CouponUseStatusEnum.EXPIRED.getInfo());
}
}
return pageServiceUtil.getDataTable(couponList);
}
/**
* 优惠券领取
*
* @param patientId 用户id
* @param couponId 优惠券id
* @return AjaxResult
*/
@Override
public AjaxResult insertCouponReceive(Long patientId, Long couponId) {
PatientInfoVO patientInfo = patientInfoMapper.getPatientInfoById(patientId);
if (Objects.isNull(patientInfo)) {
return AjaxResult.error("用户不存在,无法领取!");
}
PatientCouponReceiveInfoVO patientCouponReceive = patientCouponReceiveMapper.selectPatientCouponReceive(patientId, couponId);
//查询微信小程序订阅消息记录表该会员是否已订阅
SubscribeMessageRecord subscribeMessageRecord = subscribeMessageRecordMapper.selectSubscribeMessageRecordByPatientId(null, patientInfo.getOpenid(), appletChatConfig.getCouponReceiveTemplateId());
if (Objects.nonNull(patientCouponReceive)) {
if (StringUtils.isNotBlank(patientCouponReceive.getUseStatus()) && !CouponUseStatusEnum.WAIT_RECEIVE.getInfo().equals(patientCouponReceive.getUseStatus())) {
return AjaxResult.error("该优惠券已领取!");
}
patientCouponReceive.setExpirationStartTime(LocalDateTime.now());
patientCouponReceive.setExpirationEndTime(LocalDate.now().plusDays(patientCouponReceive.getCouponReductionDays()).atTime(23, 59, 59));
patientCouponReceive.setReceiveTime(LocalDateTime.now());
patientCouponReceive.setUseStatus(CouponUseStatusEnum.NOT_USED.getInfo());
patientCouponReceive.setUpdateTime(LocalDateTime.now());
patientCouponReceive.setCouponType(CouponTypeEnum.FULL_REDUCTION_COUPON.getInfo());
patientCouponReceiveMapper.updatePatientCouponReceive(patientCouponReceive);
boolean subscribeMessage = Objects.nonNull(subscribeMessageRecord)
&& StringUtils.isNotBlank(subscribeMessageRecord.getSubscribeStatus())
&& SubscribeStatusEnum.ACCEPT.getInfo().equals(subscribeMessageRecord.getSubscribeStatus());
if (BooleanUtils.isTrue(subscribeMessage)) {
//优惠券领取异步发送信息
messagePushService.messageCouponReceiveThread(subscribeMessageRecord, patientCouponReceive);
}
return AjaxResult.success();
}
//组装优惠券信息 并发送订阅消息
this.setCouponReceive(patientId, couponId, subscribeMessageRecord);
return AjaxResult.success();
}
/**
* 生成签到信息
*
* @param patientId 用户id
* @param signInChannel 签到渠道微信小程序手机APP
*/
private void setPatientSignInInfo(Long patientId, String signInChannel) {
PatientSignInInfo signInInfo = new PatientSignInInfo();
signInInfo.setPatientId(patientId);
signInInfo.setSignInChannel(signInChannel);
signInInfo.setSignInTime(LocalDate.now());
signInInfo.setCreateTime(LocalDateTime.now());
int insertCount = patientSignInInfoMapper.insertPatientSignInInfo(signInInfo);
if (insertCount <= 0) {
log.error("生成签到记录表信息失败,签到信息:{}", signInInfo);
throw new ServiceException("签到失败,请联系管理员!");
}
}
/**
* 生成签到信息
*
* @param patientId 用户id
* @param signInChannel 签到渠道微信小程序手机APP
* @param originalIntegral 原始账户积分
* @param changeIntegral 赠送变更积分
*/
private void setPatientIntegral(Long patientId, String signInChannel, int originalIntegral, int changeIntegral) {
PatientIntegralChange integralChange = new PatientIntegralChange();
integralChange.setPatientId(patientId);
integralChange.setOriginalIntegral(originalIntegral);
integralChange.setChangeIntegral(changeIntegral);
integralChange.setChangeTime(LocalDateTime.now());
integralChange.setChangeType(IntegralChangeType.SIGN_IN.getInfo());
integralChange.setChangeRemark("签到赠送积分");
integralChange.setChangeIntegralChannel(signInChannel);
integralChange.setCreateTime(LocalDateTime.now());
int insertCount = patientIntegralChangeMapper.insertPatientIntegralChange(integralChange);
if (insertCount <= 0) {
log.error("用户签到-生成积分变更记录表信息失败,积分变更信息:{}", integralChange);
throw new ServiceException("签到失败,请联系管理员!");
}
}
/**
* 新增商品订单主表信息减积分数与库存
*
* @param goodsOrder 前端穿过来的订单数据
* @param patientInfo 数据库查出的会员信息
* @param exchangeIntegralSkill 前端传的商品兑换数值
* @param exchangeGoodsCount 前端传的兑换商品积分数量
*/
private void addExchangeGoodsOrderInfo(GoodsOrderStationDTO goodsOrder, PatientInfoVO patientInfo, AtomicInteger exchangeIntegralSkill, AtomicInteger exchangeGoodsCount, String goodOrderNo) {
GoodsOrder good = new GoodsOrder();
BeanUtils.copyBeanProp(good, goodsOrder);
good.setPatientId(goodsOrder.getPatientId());
good.setOrderNo(goodOrderNo);
good.setOrderStatus(GooodsOrderStatusEnum.WAIT_RECEIVED_GOODS.getInfo());
good.setRemark(com.xinelu.common.utils.StringUtils.isBlank(goodsOrder.getRemark()) ? "" : goodsOrder.getRemark());
good.setOrderTime(LocalDateTime.now());
good.setDelFlag(0);
good.setTotalPrice(BigDecimal.ZERO);
good.setOrderType(OrderTypeEnum.INTEGRAL_EXCHANGE.getInfo());
good.setCreateTime(LocalDateTime.now());
good.setNurseStationId(Objects.isNull(goodsOrder.getNurseStationId()) ? null : goodsOrder.getNurseStationId());
good.setBuySource(Objects.nonNull(good.getNurseStationId()) ? BuySourceEnum.NURSE_STATION.getInfo() : BuySourceEnum.SHOPPING_MALL.getInfo());
good.setOriginalTotalPrice(BigDecimal.ZERO);
int stationGoodsOrder = goodsOrderMapper.insertGoodsOrder(good);
if (stationGoodsOrder <= 0) {
throw new ServiceException("商品订单新增信息失败,请联系管理员!");
}
//新增商品订单明细表信息
GoodsOrderDetails goodsOrderDetails = new GoodsOrderDetails();
BeanUtils.copyBeanProp(goodsOrderDetails, goodsOrder);
goodsOrderDetails.setGoodsOrderId(good.getId());
goodsOrderDetails.setOrderNo(goodOrderNo);
goodsOrderDetails.setDelFlag(0);
goodsOrderDetails.setTotalPrice(BigDecimal.ZERO);
goodsOrderDetails.setCreateTime(LocalDateTime.now());
goodsOrderDetails.setIntegralExchangeSill(goodsOrder.getIntegralExchangeSill());
goodsOrderDetails.setIntegralExchangeCount(goodsOrder.getIntegralExchangeCount());
int orderDetails = goodsOrderDetailsMapper.insertGoodsOrderDetails(goodsOrderDetails);
if (orderDetails <= 0) {
throw new ServiceException("商品订单明细新增信息失败,请联系管理员!");
}
//减少库存数量
String goodsStockKey = Constants.BUY_GOODS_REDUCE_STOCK_KEY + goodOrderNo + "_" + goodsOrderDetails.getId();
boolean tryLock = redisDistributedLockUtils.tryLock(goodsStockKey, 5);
if (!tryLock) {
log.info("商品订单获取Redis锁失败订单编号 =====> {}", goodOrderNo);
throw new ServiceException("减少库存信息失败,请联系管理员!");
}
try {
//减少会员账户积分数
patientInfoMapper.reducePatientIntegralCount(patientInfo.getId(), exchangeIntegralSkill.get());
//减少库存数量
goodsAttributeDetailsMapper.reduceGoodsStockCount(goodsOrder.getGoodsAttributeDetailsId(), exchangeGoodsCount.get());
//会员积分变更记录
this.setGoodPatientIntegral(patientInfo, exchangeIntegralSkill, good);
} catch (Exception e) {
log.error("减少库存与会员积分信息失败,失败原因为 ====> {}", e.getMessage());
throw new ServiceException(e.getMessage());
} finally {
redisDistributedLockUtils.unlock(goodsStockKey);
}
}
/**
* 记录商品兑换积分变更信息
*
* @param patientInfo 会员信息
* @param exchangeIntegralSkill 前端传的购买商品积分数量
* @param good 商品信息
**/
private void setGoodPatientIntegral(PatientInfoVO patientInfo, AtomicInteger exchangeIntegralSkill, GoodsOrder good) {
PatientIntegralChange patientIntegralChange = new PatientIntegralChange();
patientIntegralChange.setPatientId(patientInfo.getId());
patientIntegralChange.setOriginalIntegral(patientInfo.getIntegral());
patientIntegralChange.setChangeIntegral(exchangeIntegralSkill.get());
patientIntegralChange.setChangeTime(LocalDateTime.now());
patientIntegralChange.setChangeType(IntegralChangeType.COMMODITY_EXCHANGE.getInfo());
patientIntegralChange.setChangeRemark("商品兑换扣减积分");
patientIntegralChange.setChangeIntegralChannel(good.getOrderChannel());
patientIntegralChange.setCreateTime(LocalDateTime.now());
int integralChange = patientIntegralChangeMapper.insertPatientIntegralChange(patientIntegralChange);
if (integralChange <= 0) {
log.error("积分兑换商品-生成积分变更记录表信息失败,积分变更信息:{}", integralChange);
throw new ServiceException("兑换商品失败,请联系管理员!");
}
}
/**
* 签到送积分-记录积分信息
*
* @param patientSignInInfo 会员
* @param increment 签到天数
* @param patientId 会员id
* @param signInChannel 亲到方式
*/
private void insertGoodPatientIntegral(PatientSignInVO patientSignInInfo, int increment, Long patientId, String signInChannel) {
SystemSettingsInfo settingsInfo = systemSettingsInfoMapper.getSystemSettingsInfoByType(SettingsTypeEnum.SIGN_IN_RULE.getInfo());
if (Objects.nonNull(settingsInfo) && Objects.nonNull(settingsInfo.getTotalSignInDays()) && increment >= settingsInfo.getTotalSignInDays()) {
//赠送积分
int originalIntegral = Objects.isNull(patientSignInInfo.getIntegral()) ? 0 : patientSignInInfo.getIntegral();
int changeIntegral = Objects.isNull(settingsInfo.getIntegralCount()) ? 0 : settingsInfo.getIntegralCount();
patientCenterMapper.updatePatientIntegral(patientId, changeIntegral);
this.setPatientIntegral(patientId, signInChannel, originalIntegral, changeIntegral);
//将用户表的签到天数清零
patientCenterMapper.clearTotalSignInDays(patientId);
}
}
/**
* 组装优惠券信息 并发送订阅消息
*
* @param patientId 会员id
* @param couponId 优惠券id
* @param subscribeMessageRecord 微信小程序订阅消息记录信息
**/
private void setCouponReceive(Long patientId, Long couponId, SubscribeMessageRecord subscribeMessageRecord) {
//组装优惠券信息
Coupon couponInfo = couponMapper.selectCouponById(couponId);
PatientCouponReceive couponReceive = new PatientCouponReceive();
couponReceive.setPatientId(patientId);
couponReceive.setCouponId(couponId);
couponReceive.setReceiveSource(CouponReceiveTypeEnum.NEW_PEOPLE_WELFARE.getInfo());
couponReceive.setExpirationStartTime(LocalDateTime.now());
couponReceive.setExpirationEndTime(LocalDate.now().plusDays(couponInfo.getCouponReductionDays()).atTime(23, 59, 59));
couponReceive.setReceiveTime(LocalDateTime.now());
couponReceive.setCreateTime(LocalDateTime.now());
couponReceive.setCouponTitle(com.xinelu.common.utils.StringUtils.isBlank(couponInfo.getCouponTitle()) ? "" : couponInfo.getCouponTitle());
couponReceive.setCouponPrice(Objects.isNull(couponInfo.getCouponPrice()) ? BigDecimal.ZERO : couponInfo.getCouponPrice());
couponReceive.setCouponConsumePrice(Objects.isNull(couponInfo.getCouponConsumePrice()) ? BigDecimal.ZERO : couponInfo.getCouponConsumePrice());
couponReceive.setCouponDescription(com.xinelu.common.utils.StringUtils.isBlank(couponInfo.getCouponDescription()) ? "" : couponInfo.getCouponDescription());
couponReceive.setUseStatus(CouponUseStatusEnum.NOT_USED.getInfo());
patientCouponReceiveMapper.insertPatientCouponReceive(couponReceive);
//新建对象并复制
PatientCouponReceiveInfoVO couponReceiveInfoVO = new PatientCouponReceiveInfoVO();
BeanUtils.copyProperties(couponReceive, couponReceiveInfoVO);
couponReceiveInfoVO.setCouponType(CouponTypeEnum.FULL_REDUCTION_COUPON.getInfo());
boolean subscribeMessage = Objects.nonNull(subscribeMessageRecord)
&& StringUtils.isNotBlank(subscribeMessageRecord.getSubscribeStatus())
&& SubscribeStatusEnum.ACCEPT.getInfo().equals(subscribeMessageRecord.getSubscribeStatus());
if (BooleanUtils.isTrue(subscribeMessage)) {
//异步发送信息
messagePushService.messageCouponReceiveThread(subscribeMessageRecord, couponReceiveInfoVO);
}
}
}

View File

@ -0,0 +1,19 @@
package com.xinelu.applet.service.wechatappletcallback;
import com.xinelu.applet.vo.messagepush.WeChatMessagePushVO;
/**
* @Description 微信小程序事件回调业务层
* @Author 纪寒
* @Date 2023-03-15 13:49:50
* @Version 1.0
*/
public interface WeChatAppletCallBackService {
/**
* 微信小程序消息推送事件回调POST处理
*
* @param weChatMessagePushVO 请求参数
*/
void handleWeChatAppletCallBack(WeChatMessagePushVO weChatMessagePushVO);
}

View File

@ -0,0 +1,276 @@
package com.xinelu.applet.service.wechatappletcallback.impl;
import com.xinelu.applet.mapper.appletlogin.AppletLoginMapper;
import com.xinelu.applet.service.wechatappletcallback.WeChatAppletCallBackService;
import com.xinelu.applet.vo.messagepush.WeChatMessagePushVO;
import com.xinelu.common.config.AppletChatConfig;
import com.xinelu.common.enums.SubscribeMessageTypeEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.DateUtils;
import com.xinelu.manage.domain.patientinfo.PatientInfo;
import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord;
import com.xinelu.manage.domain.subscribemessagesendrecord.SubscribeMessageSendRecord;
import com.xinelu.manage.mapper.subscribemessagerecord.SubscribeMessageRecordMapper;
import com.xinelu.manage.mapper.subscribemessagesendrecord.SubscribeMessageSendRecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @Description 微信小程序事件回调业务层实现类
* @Author 纪寒
* @Date 2023-03-15 13:50:06
* @Version 1.0
*/
@Service
@Slf4j
public class WeChatAppletCallBackServiceImpl implements WeChatAppletCallBackService {
@Resource
private SubscribeMessageRecordMapper subscribeMessageRecordMapper;
@Resource
private AppletChatConfig appletChatConfig;
@Resource
private AppletLoginMapper appletLoginMapper;
@Resource
private SubscribeMessageSendRecordMapper subscribeMessageSendRecordMapper;
/**
* 微信消息推送变更事件标识
*/
private static final String SUBSCRIBE_MSG_CHANGE_EVENT = "subscribe_msg_change_event";
/**
* 微信消息推送订阅事件标识
*/
private static final String SUBSCRIBE_MSG_POPUP_EVENT = "subscribe_msg_popup_event";
/**
* 微信消息推送发送结果事件标识
*/
private static final String SUBSCRIBE_MSG__SENT_EVENT = "subscribe_msg_sent_event";
/**
* 微信小程序消息推送事件回调POST处理
*
* @param weChatMessagePushVO 请求参数
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void handleWeChatAppletCallBack(WeChatMessagePushVO weChatMessagePushVO) {
if (weChatMessagePushVO.getEvent().equals(SUBSCRIBE_MSG_POPUP_EVENT)) {
//处理用户订阅授权事件
this.handleSubscribeMsgPopupEvent(weChatMessagePushVO);
}
if (weChatMessagePushVO.getEvent().equals(SUBSCRIBE_MSG_CHANGE_EVENT)) {
//处理订阅消息变更事件
this.handleSubscribeMsgChangeEvent(weChatMessagePushVO);
}
if (weChatMessagePushVO.getEvent().equals(SUBSCRIBE_MSG__SENT_EVENT)) {
//处理订阅消息发送结果事件
this.handleSubscribeMsgSentEvent(weChatMessagePushVO);
}
}
/**
* 处理用户订阅授权事件
*
* @param weChatMessagePushVO 参数信息
*/
private void handleSubscribeMsgPopupEvent(WeChatMessagePushVO weChatMessagePushVO) {
//处理订阅消息授权事件
if (Objects.isNull(weChatMessagePushVO.getSubscribeMsgPopupEvent()) || CollectionUtils.isEmpty(weChatMessagePushVO.getSubscribeMsgPopupEvent().getSubscribeMsgPopupEventList())) {
return;
}
//查询用户信息表
PatientInfo patientInfo = appletLoginMapper.getPatientInfoByOpenId(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
//组装数据
List<SubscribeMessageRecord> subscribeMessageRecordList = createSubscribeMessageRecordList(patientInfo, weChatMessagePushVO, SUBSCRIBE_MSG_POPUP_EVENT);
if (CollectionUtils.isEmpty(subscribeMessageRecordList)) {
return;
}
//根据openid查询数据库原有的订阅消息记录
SubscribeMessageRecord subscribeMessageRecord = new SubscribeMessageRecord();
subscribeMessageRecord.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
List<SubscribeMessageRecord> existMessageRecordList = subscribeMessageRecordMapper.selectSubscribeMessageRecordList(subscribeMessageRecord);
List<SubscribeMessageRecord> subtractSubscribeList = new ArrayList<>(CollectionUtils.subtract(subscribeMessageRecordList, existMessageRecordList));
if (CollectionUtils.isNotEmpty(subtractSubscribeList)) {
//新增订阅记录信息
int insertCount = subscribeMessageRecordMapper.insertSubscribeMessageRecordList(subtractSubscribeList);
if (insertCount <= 0) {
log.error("微信订阅消息回调,新增用户订阅消息记录失败,记录信息为:[{}]", subtractSubscribeList);
throw new ServiceException("微信订阅消息回调,新增用户订阅消息记录失败!");
}
}
List<SubscribeMessageRecord> intersectionSubscribeList = new ArrayList<>(CollectionUtils.intersection(subscribeMessageRecordList, existMessageRecordList));
if (CollectionUtils.isNotEmpty(intersectionSubscribeList)) {
//修改订阅信息状态
for (SubscribeMessageRecord messageRecord : intersectionSubscribeList) {
Long patientId = null;
if (Objects.nonNull(patientInfo) && Objects.nonNull(patientInfo.getId())) {
patientId = patientInfo.getId();
}
String openId = StringUtils.isBlank(messageRecord.getOpenid()) ? "" : messageRecord.getOpenid();
String templateId = StringUtils.isBlank(messageRecord.getTemplateId()) ? "" : messageRecord.getTemplateId();
String subscribeStatus = StringUtils.isBlank(messageRecord.getSubscribeStatus()) ? "" : messageRecord.getSubscribeStatus();
subscribeMessageRecordMapper.updateSubscribeMessageTemplateId(openId, templateId, subscribeStatus, patientId);
}
}
}
/**
* 处理订阅消息变更事件
*
* @param weChatMessagePushVO 信息
*/
private void handleSubscribeMsgChangeEvent(WeChatMessagePushVO weChatMessagePushVO) {
if (Objects.isNull(weChatMessagePushVO.getSubscribeMsgChangeEvent()) || CollectionUtils.isEmpty(weChatMessagePushVO.getSubscribeMsgChangeEvent().getSubscribeMsgPopupEventList())) {
return;
}
//查询用户信息表
PatientInfo patientInfo = appletLoginMapper.getPatientInfoByOpenId(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
//组装数据
List<SubscribeMessageRecord> subscribeMessageRecordList = createSubscribeMessageRecordList(patientInfo, weChatMessagePushVO, SUBSCRIBE_MSG_CHANGE_EVENT);
if (CollectionUtils.isEmpty(subscribeMessageRecordList)) {
return;
}
//根据openid查询数据库原有的订阅消息记录
SubscribeMessageRecord subscribeMessageRecord = new SubscribeMessageRecord();
subscribeMessageRecord.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
List<SubscribeMessageRecord> existMessageRecordList = subscribeMessageRecordMapper.selectSubscribeMessageRecordList(subscribeMessageRecord);
List<SubscribeMessageRecord> intersectionSubscribeList = new ArrayList<>(CollectionUtils.intersection(subscribeMessageRecordList, existMessageRecordList));
if (CollectionUtils.isNotEmpty(intersectionSubscribeList)) {
//修改订阅信息状态
for (SubscribeMessageRecord messageRecord : intersectionSubscribeList) {
Long patientId = null;
if (Objects.nonNull(patientInfo) && Objects.nonNull(patientInfo.getId())) {
patientId = patientInfo.getId();
}
String openId = StringUtils.isBlank(messageRecord.getOpenid()) ? "" : messageRecord.getOpenid();
String templateId = StringUtils.isBlank(messageRecord.getTemplateId()) ? "" : messageRecord.getTemplateId();
String subscribeStatus = StringUtils.isBlank(messageRecord.getSubscribeStatus()) ? "" : messageRecord.getSubscribeStatus();
subscribeMessageRecordMapper.updateSubscribeMessageTemplateId(openId, templateId, subscribeStatus, patientId);
}
}
}
/**
* 处理订阅消息发送结果事件
*
* @param weChatMessagePushVO 信息
*/
private void handleSubscribeMsgSentEvent(WeChatMessagePushVO weChatMessagePushVO) {
if (Objects.isNull(weChatMessagePushVO.getSubscribeMsgSentEvent()) || CollectionUtils.isEmpty(weChatMessagePushVO.getSubscribeMsgSentEvent().getSubscribeMsgSentEventList())) {
return;
}
//组装数据
List<SubscribeMessageSendRecord> subscribeMessageSendRecordList = createSubscribeMessageSendRecordList(weChatMessagePushVO);
if (CollectionUtils.isNotEmpty(subscribeMessageSendRecordList)) {
int insertCount = subscribeMessageSendRecordMapper.insertSubscribeMessageSendRecordList(subscribeMessageSendRecordList);
if (insertCount <= 0) {
log.error("微信订阅消息回调,新增用户订阅消息发送记录失败,记录信息为:[{}]", subscribeMessageSendRecordList);
throw new ServiceException("微信订阅消息回调,新增用户订阅消息发送记录失败!");
}
}
}
/**
* 组装订阅消息数据
*
* @param patientInfo 会员用户信息
* @param weChatMessagePushVO 微信请求参数信息
* @param eventType 事件类型
* @return List<SubscribeMessageRecord>
*/
private List<SubscribeMessageRecord> createSubscribeMessageRecordList(PatientInfo patientInfo, WeChatMessagePushVO weChatMessagePushVO, String eventType) {
List<SubscribeMessageRecord> subscribeMessageRecordList = Lists.newArrayList();
if (SUBSCRIBE_MSG_POPUP_EVENT.equals(eventType)) {
subscribeMessageRecordList = weChatMessagePushVO.getSubscribeMsgPopupEvent().getSubscribeMsgPopupEventList().stream().filter(Objects::nonNull).map(item -> {
SubscribeMessageRecord subscribe = new SubscribeMessageRecord();
if (Objects.nonNull(patientInfo) && Objects.nonNull(patientInfo.getId())) {
subscribe.setPatientId(patientInfo.getId());
}
subscribe.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
subscribe.setAppletId(StringUtils.isBlank(weChatMessagePushVO.getToUserName()) ? "" : weChatMessagePushVO.getToUserName());
subscribe.setTemplateId(StringUtils.isBlank(item.getTemplateId()) ? "" : item.getTemplateId());
if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getCouponReceiveTemplateId().equals(item.getTemplateId())) {
subscribe.setMessageType(SubscribeMessageTypeEnum.COUPON_RECEIVE_MESSAGE_PUSH.getInfo());
}
if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getAppointOrderTemplateId().equals(item.getTemplateId())) {
subscribe.setMessageType(SubscribeMessageTypeEnum.APPOINT_ORDER_MESSAGE_PUSH.getInfo());
}
if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getGoodsOrderTemplateId().equals(item.getTemplateId())) {
subscribe.setMessageType(SubscribeMessageTypeEnum.GOODS_ORDER_MESSAGE_PUSH.getInfo());
}
if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getSignTemplateId().equals(item.getTemplateId())) {
subscribe.setMessageType(SubscribeMessageTypeEnum.SIGN_MESSAGE_PUSH.getInfo());
}
subscribe.setSubscribeCount(1);
subscribe.setSubscribeTime(StringUtils.isBlank(weChatMessagePushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(weChatMessagePushVO.getCreateTime()) * 1000L));
subscribe.setCreateTime(LocalDateTime.now());
subscribe.setSubscribeStatus(StringUtils.isBlank(item.getSubscribeStatusString()) ? "" : item.getSubscribeStatusString());
return subscribe;
}).collect(Collectors.toList());
}
if (SUBSCRIBE_MSG_CHANGE_EVENT.equals(eventType)) {
subscribeMessageRecordList = weChatMessagePushVO.getSubscribeMsgChangeEvent().getSubscribeMsgPopupEventList().stream().filter(Objects::nonNull).map(item -> {
SubscribeMessageRecord subscribe = new SubscribeMessageRecord();
if (Objects.nonNull(patientInfo) && Objects.nonNull(patientInfo.getId())) {
subscribe.setPatientId(patientInfo.getId());
}
subscribe.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
subscribe.setAppletId(StringUtils.isBlank(weChatMessagePushVO.getToUserName()) ? "" : weChatMessagePushVO.getToUserName());
subscribe.setTemplateId(StringUtils.isBlank(item.getTemplateId()) ? "" : item.getTemplateId());
if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getCouponReceiveTemplateId().equals(item.getTemplateId())) {
subscribe.setMessageType(SubscribeMessageTypeEnum.COUPON_RECEIVE_MESSAGE_PUSH.getInfo());
}
if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getAppointOrderTemplateId().equals(item.getTemplateId())) {
subscribe.setMessageType(SubscribeMessageTypeEnum.APPOINT_ORDER_MESSAGE_PUSH.getInfo());
}
if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getGoodsOrderTemplateId().equals(item.getTemplateId())) {
subscribe.setMessageType(SubscribeMessageTypeEnum.GOODS_ORDER_MESSAGE_PUSH.getInfo());
}
if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getSignTemplateId().equals(item.getTemplateId())) {
subscribe.setMessageType(SubscribeMessageTypeEnum.SIGN_MESSAGE_PUSH.getInfo());
}
subscribe.setSubscribeCount(1);
subscribe.setSubscribeTime(StringUtils.isBlank(weChatMessagePushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(weChatMessagePushVO.getCreateTime()) * 1000L));
subscribe.setCreateTime(LocalDateTime.now());
subscribe.setSubscribeStatus(StringUtils.isBlank(item.getSubscribeStatusString()) ? "" : item.getSubscribeStatusString());
return subscribe;
}).collect(Collectors.toList());
}
return subscribeMessageRecordList;
}
/**
* 组装订阅消息发送结果数据
*
* @param weChatMessagePushVO 微信请求参数信息
* @return List<SubscribeMessageSendRecord>
*/
private List<SubscribeMessageSendRecord> createSubscribeMessageSendRecordList(WeChatMessagePushVO weChatMessagePushVO) {
return weChatMessagePushVO.getSubscribeMsgSentEvent().getSubscribeMsgSentEventList().stream().map(item -> {
SubscribeMessageSendRecord sendRecord = new SubscribeMessageSendRecord();
sendRecord.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
sendRecord.setAppletId(StringUtils.isBlank(weChatMessagePushVO.getToUserName()) ? "" : weChatMessagePushVO.getToUserName());
sendRecord.setTemplateId(StringUtils.isBlank(item.getTemplateId()) ? "" : item.getTemplateId());
sendRecord.setMessageType(StringUtils.isBlank(weChatMessagePushVO.getMsgType()) ? "" : weChatMessagePushVO.getMsgType());
sendRecord.setMsgId(StringUtils.isBlank(item.getMsgId()) ? "" : item.getMsgId());
sendRecord.setSubscribeTime(StringUtils.isBlank(weChatMessagePushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(weChatMessagePushVO.getCreateTime()) * 1000L));
sendRecord.setCreateTime(LocalDateTime.now());
sendRecord.setErrorStatus(StringUtils.isBlank(item.getErrorStatus()) ? "" : item.getErrorStatus());
sendRecord.setErrorCode(StringUtils.isBlank(item.getErrorCode()) ? null : Integer.parseInt(item.getErrorCode()));
return sendRecord;
}).collect(Collectors.toList());
}
}

View File

@ -0,0 +1,29 @@
package com.xinelu.applet.utils;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
/**
* @Description Xml格式数据工具类
* @Author 纪寒
* @Date 2023-03-15 13:37:34
* @Version 1.0
*/
public class XmlUtil {
/**
* Xml数据转换
*
* @param xml 数据格式
* @param objClass 要转换的类
* @return 返回结果
*/
public static Object fromXml(String xml, Class objClass) {
Serializer serializer = new Persister();
try {
return serializer.read(objClass, xml);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,25 @@
package com.xinelu.applet.vo.messagepush;
import lombok.Data;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;
import java.io.Serializable;
import java.util.List;
/**
* @Description 当用户在手机端服务通知里消息卡片右上角...管理消息实体类
* @Author 纪寒
* @Date 2023-03-15 10:19:23
* @Version 1.0
*/
@Root(name = "SubscribeMsgChangeEvent", strict = false)
@Data
public class SubscribeMsgChangeEventVO implements Serializable {
private static final long serialVersionUID = -6682105837610124794L;
/**
* 信息集合
*/
@ElementList(inline = true, required = false)
private List<SubscribeMsgPopupEventListVO> subscribeMsgPopupEventList;
}

View File

@ -0,0 +1,36 @@
package com.xinelu.applet.vo.messagepush;
import lombok.Data;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
import java.io.Serializable;
/**
* @Description 模板信息集合
* @Author 纪寒
* @Date 2023-03-15 10:28:02
* @Version 1.0
*/
@Root(name = "List", strict = false)
@Data
public class SubscribeMsgPopupEventListVO implements Serializable {
private static final long serialVersionUID = 548605591615555467L;
/**
* 模板id
*/
@Element(name = "TemplateId", required = false)
private String templateId;
/**
* 订阅结果accept接收reject拒收
*/
@Element(name = "SubscribeStatusString", required = false)
private String subscribeStatusString;
/**
* 弹框场景0代表在小程序页面内
*/
@Element(name = "PopupScene", required = false)
private String popupScene;
}

View File

@ -0,0 +1,25 @@
package com.xinelu.applet.vo.messagepush;
import lombok.Data;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;
import java.io.Serializable;
import java.util.List;
/**
* @Description 当用户触发订阅消息弹框后信息实体类
* @Author 纪寒
* @Date 2023-03-15 10:19:23
* @Version 1.0
*/
@Root(name = "SubscribeMsgPopupEvent", strict = false)
@Data
public class SubscribeMsgPopupEventVO implements Serializable {
private static final long serialVersionUID = -6682105837610124794L;
/**
* 信息集合
*/
@ElementList(inline = true, required = false)
private List<SubscribeMsgPopupEventListVO> subscribeMsgPopupEventList;
}

View File

@ -0,0 +1,42 @@
package com.xinelu.applet.vo.messagepush;
import lombok.Data;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
import java.io.Serializable;
/**
* @Description 调用订阅消息接口发送消息给用户的最终结果信息集合实体类
* @Author 纪寒
* @Date 2023-03-15 11:20:38
* @Version 1.0
*/
@Root(name = "List", strict = false)
@Data
public class SubscribeMsgSentEventListVO implements Serializable {
private static final long serialVersionUID = 3771741965224817805L;
/**
* 模板id
*/
@Element(name = "TemplateId", required = false)
private String templateId;
/**
* 消息id调用接口时也会返回
*/
@Element(name = "MsgID", required = false)
private String msgId;
/**
* 推送结果状态码0表示成功
*/
@Element(name = "ErrorCode", required = false)
private String errorCode;
/**
* 推送结果状态码对应的含义
*/
@Element(name = "ErrorStatus", required = false)
private String errorStatus;
}

View File

@ -0,0 +1,25 @@
package com.xinelu.applet.vo.messagepush;
import lombok.Data;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;
import java.io.Serializable;
import java.util.List;
/**
* @Description 调用订阅消息接口发送消息给用户的最终结果实体类
* @Author 纪寒
* @Date 2023-03-15 10:19:23
* @Version 1.0
*/
@Root(name = "SubscribeMsgSentEvent", strict = false)
@Data
public class SubscribeMsgSentEventVO implements Serializable {
private static final long serialVersionUID = -6682105837610124794L;
/**
* 信息集合
*/
@ElementList(inline = true, required = false)
private List<SubscribeMsgSentEventListVO> subscribeMsgSentEventList;
}

View File

@ -0,0 +1,66 @@
package com.xinelu.applet.vo.messagepush;
import lombok.Data;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
import java.io.Serializable;
/**
* @Description 微信小程序消息推送回调实体类
* @Author 纪寒
* @Date 2023-03-15 10:14:17
* @Version 1.0
*/
@Root(name = "xml", strict = false)
@Data
public class WeChatMessagePushVO implements Serializable {
private static final long serialVersionUID = 6233209958847696141L;
/**
* 小程序账号
*/
@Element(name = "ToUserName", required = false)
private String toUserName;
/**
* 用户openid
*/
@Element(name = "FromUserName", required = false)
private String fromUserName;
/**
* 时间戳
*/
@Element(name = "CreateTime", required = false)
private String createTime;
/**
* 消息类型
*/
@Element(name = "MsgType", required = false)
private String msgType;
/**
* 事件类型
*/
@Element(name = "Event", required = false)
private String event;
/**
* 当用户触发订阅消息弹框后触发时间集合
*/
@Element(name = "SubscribeMsgPopupEvent", required = false)
private SubscribeMsgPopupEventVO subscribeMsgPopupEvent;
/**
* 当用户在手机端服务通知里消息卡片右上角...管理消息时
*/
@Element(name = "SubscribeMsgChangeEvent", required = false)
private SubscribeMsgChangeEventVO subscribeMsgChangeEvent;
/**
* 当用户在手机端服务通知里消息卡片右上角...管理消息时
*/
@Element(name = "SubscribeMsgSentEvent", required = false)
private SubscribeMsgSentEventVO subscribeMsgSentEvent;
}

View File

@ -0,0 +1,30 @@
package com.xinelu.applet.vo.nursingstationgoods;
import com.xinelu.common.custominterface.Update;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Description 修改默认地址参数实体类
* @Author 纪寒
* @Date 2023-01-11 16:29:16
* @Version 1.0
*/
@Data
public class UpdateDefaultAddressVO implements Serializable {
private static final long serialVersionUID = -5824121578070763076L;
/**
* 主键id
*/
@NotNull(message = "收货地址id不能为空", groups = {Update.class})
private Long id;
/**
* 默认地址标识01
*/
@NotNull(message = "默认收货地址标识不能为空!", groups = {Update.class})
private Integer defaultAddressFlag;
}

View File

@ -0,0 +1,44 @@
package com.xinelu.applet.vo.patientcenter;
import com.xinelu.common.custominterface.Insert;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* @Description 个人中心优惠券前端传入VO
* @Author ZH
* @Date 2023-02-27
*/
@Data
public class PatientCenterCouponVO implements Serializable {
private static final long serialVersionUID = -4238035673079939685L;
/**
* 会员id
*/
@NotNull(message = "会员信息不能为空", groups = {Insert.class})
private Long patientId;
/**
* 优惠券使用状态
*/
private String useStatus;
/**
* 领取方式新人福利NEW_PEOPLE_WELFARE活动赠送EVENT_GIFT消费返券CONSUME_REBATE
*/
private String receiveType;
/**
* 优惠券来源
*/
private String receiveSource;
/**
* 优惠券状态集合
*/
List<String> useStatusList;
}

View File

@ -0,0 +1,41 @@
package com.xinelu.applet.vo.patientcenter;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 用户签到信息实体类
* @Author 纪寒
* @Date 2023-02-24 15:37:07
* @Version 1.0
*/
@Data
public class PatientSignInVO implements Serializable {
private static final long serialVersionUID = -1266359305276156027L;
/**
* 用户id
*/
private Long patientId;
/**
* 签到天数每到一个周期以后自动清零
*/
private Integer totalSignInDays;
/**
* 签到次数
*/
private Integer signInCount;
/**
* 会员账户积分
*/
private Integer integral;
/**
* 当前签到日期
*/
private Integer todaySignInCount;
}

View File

@ -0,0 +1,55 @@
package com.xinelu.applet.vo.patientcenter;
import lombok.Data;
import java.io.Serializable;
/**
* @author ljh
* @version 1.0
* Create by 2023/2/27 16:50
*/
@Data
public class PatientSignInfoVO implements Serializable {
private static final long serialVersionUID = -1943601999448833477L;
/**
* 系统配置信息表累计签到天数
*/
private Integer totalSignInDays;
/**
* 系统配置信息表累计签到赠送积分数
*/
private Integer signInCount;
/**
* 系统配置信息表邀请好友赠送积分数值
*/
private Integer inviteFriends;
/**
* 系统配置信息表规则类型
*/
private String settingsType;
/**
* 会用用户当天是否签到标识01
*/
private Integer todaySignInCount;
/**
* 会员累计签到天数
*/
private Integer patientSignInCount;
/**
* 会员用户账户总积分
*/
private Integer integral;
/**
* 系统配置参数信息表积分数值
*/
private Integer integralCount;
}

View File

@ -64,4 +64,15 @@
</if>
</where>
</select>
<select id="getLoginFlagByPatientId" resultType="integer">
select login_flag
from patient_info
<where>
del_flag = 0
<if test="patientId != null and patientId != ''">
and id = #{patientId}
</if>
</where>
</select>
</mapper>

View File

@ -0,0 +1,513 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinelu.applet.mapper.nursingstationgoods.NursingStationGoodsMapper">
<resultMap type="com.xinelu.applet.dto.nursingstationgoods.GoodDetails" id="GoodDetailsResult">
<result property="storeInfoId" column="store_info_id"/>
<result property="nurseStationId" column="nurse_station_id"/>
<result property="goodsInfoId" column="goodsInfoId"/>
<result property="goodsCategoryId" column="goods_category_id"/>
<result property="goodsName" column="goods_name"/>
<result property="goodsPictureUrl" column="goods_picture_url"/>
<result property="goodsUnit" column="goods_unit"/>
<result property="goodsRemark" column="goods_remark"/>
<result property="goodsPurpose" column="goods_purpose"/>
<collection property="goodAttributeDetailsLists" javaType="java.util.List" resultMap="goodDetailsListsResult"/>
</resultMap>
<resultMap type="com.xinelu.applet.dto.nursingstationgoods.GoodAttributeDetailsList" id="goodDetailsListsResult">
<result property="goodsAttributeId" column="goodsAttributeId"/>
<result property="attributeDetailsId" column="attributeDetailsId"/>
<result property="attributeDetailsName" column="attribute_details_name"/>
<result property="attributeName" column="attribute_name"/>
<result property="attributePitureUrl" column="attribute_piture_url"/>
<result property="goodsPrice" column="goods_price"/>
<result property="goodsStock" column="goods_stock"/>
<result property="attributeDetailsSort" column="attributeDetailsSort"/>
</resultMap>
<select id="getGoodsCategoryList" parameterType="GoodsCategory" resultType="GoodsCategory">
select id,
parent_id,
goods_category_name,
goods_category_code,
goods_category_picture,
category_remark,
category_level,
sort,
create_by,
create_time,
update_by,
update_time
from goods_category
<where>
<if test="id != null">
and id =#{id}
</if>
<if test="parentId != null">
and parent_id =#{parentId}
</if>
<if test="goodsCategoryName != null and goodsCategoryName != ''">
and goods_category_name like concat('%', #{goodsCategoryName}, '%')
</if>
<if test="goodsCategoryCode != null and goodsCategoryCode != ''">
and goods_category_code = #{goodsCategoryCode}
</if>
<if test="goodsCategoryPicture != null and goodsCategoryPicture != ''">
and goods_category_picture = #{goodsCategoryPicture}
</if>
<if test="categoryRemark != null and categoryRemark != ''">
and category_remark = #{categoryRemark}
</if>
<if test="categoryLevel != null ">
and category_level = #{categoryLevel}
</if>
<if test="sort != null ">
and sort = #{sort}
</if>
</where>
ORDER BY
sort
</select>
<select id="getChildrenCategoryIds" parameterType="long" resultType="string">
SELECT getChildrenCategoryIds(#{parentId}) goodChildrenCategoryIds
</select>
<select id="getGoodsCategoryNameList" parameterType="com.xinelu.manage.vo.goodsCategory.GoodsCategoryNameVO"
resultType="com.xinelu.manage.vo.goodsCategory.GoodsCategoryNameVO">
select id,
parent_id,
goods_category_name,
goods_category_code,
goods_category_picture,
category_remark,
category_level,
sort
from goods_category
<where>
<if test="goodsCategoryNameId != null and goodsCategoryNameId.size() > 0">
and id in
<foreach item="goodsCategoryNameId" collection="goodsCategoryNameId" open="(" separator="," close=")">
#{goodsCategoryNameId}
</foreach>
</if>
and category_level != #{categoryLevel}
</where>
ORDER BY
id
</select>
<select id="getGoodsInfoList" parameterType="com.xinelu.applet.dto.nursingstationgoods.GoodsList"
resultType="com.xinelu.applet.dto.nursingstationgoods.GoodsList">
SELECT
gi.id goodsInfoId,
ga.id goodsAttributeId,
gad.id attributeDetailsId,
gi.nurse_station_id,
gi.goods_category_id,
gi.goods_name,
ga.attribute_name,
gad.attribute_details_name,
gi.goods_picture_url,
gi.goods_unit,
gi.sort,
gad.attribute_piture_url,
IFNULL((gad.goods_price) ,0) goods_price
FROM
goods_info gi
LEFT JOIN store_info si ON gi.store_info_id = si.id
LEFT JOIN goods_attribute ga ON ga.goods_id = gi.id
LEFT JOIN goods_attribute_details gad ON gad.goods_attribute_id = ga.id
<where>
<if test="goodsCategoryIds != null and goodsCategoryIds.size() > 0">
and gi.goods_category_id in
<foreach item="goodsCategoryIds" collection="goodsCategoryIds" open="(" separator="," close=")">
#{goodsCategoryIds}
</foreach>
</if>
<if test="goodsName != null and goodsName != ''">
and gi.goods_name like concat( #{goodsName}, '%')
</if>
and gi.whether_shelf = 1
and gi.nurse_station_id is NULL
</where>
ORDER BY gi.sort DESC, gi.id, gad.goods_price
</select>
<select id="getGoodsDetailsList" parameterType="com.xinelu.applet.dto.nursingstationgoods.GoodDetails" resultMap="GoodDetailsResult">
SELECT
gi.id goodsInfoId,
ga.id goodsAttributeId,
gad.id attributeDetailsId,
gi.store_info_id,
gi.nurse_station_id,
gi.goods_category_id,
gi.goods_name,
gi.goods_picture_url,
gi.goods_unit,
gi.goods_remark,
gi.goods_purpose,
ga.attribute_name,
ga.attribute_remark,
ga.sort goodsAttributeSort,
gad.attribute_details_name,
gad.attribute_piture_url,
gad.goods_stock,
gad.sort attributeDetailsSort,
gad.goods_price
FROM
goods_info gi
LEFT JOIN store_info si ON gi.store_info_id = si.id
LEFT JOIN goods_attribute ga ON ga.goods_id = gi.id
LEFT JOIN goods_attribute_details gad ON gad.goods_attribute_id = ga.id
<where>
<if test="goodsInfoId != null ">
and gi.id = #{goodsInfoId}
</if>
</where>
ORDER BY gad.sort DESC
</select>
<select id="getReceiveAddressInfoList" parameterType="com.xinelu.manage.vo.receiveAddressInfo.ReceiveAddressInfoVO"
resultType="com.xinelu.manage.vo.receiveAddressInfo.ReceiveAddressInfoVO">
select id,
patient_id,
openid,
unionid,
receive_name,
receive_phone,
receive_address,
area_code,
create_by,
create_time,
update_by,
update_time,
default_address_flag
from receive_address_info
<where>
<if test="patientId != null ">
and patient_id = #{patientId}
</if>
</where>
ORDER BY create_time DESC
</select>
<select id="selectReceiveAddressInfoByPatientId" parameterType="Long"
resultType="ReceiveAddressInfo">
select id,
patient_id,
openid,
unionid,
receive_name,
receive_phone,
receive_address,
area_code,
create_by,
create_time,
update_by,
update_time
from receive_address_info
<where>
<if test="patientId != null ">
and patient_id = #{patientId}
</if>
</where>
</select>
<select id="selectReceiveAddressInfoById" parameterType="Long"
resultType="ReceiveAddressInfo">
select id,
patient_id,
openid,
unionid,
receive_name,
receive_phone,
receive_address,
area_code,
create_by,
create_time,
update_by,
update_time
from receive_address_info
where id = #{id}
</select>
<insert id="insertReceiveAddressInfo" parameterType="ReceiveAddressInfo">
insert into receive_address_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">id,
</if>
<if test="patientId != null">patient_id,
</if>
<if test="openid != null">openid,
</if>
<if test="unionid != null">unionid,
</if>
<if test="receiveName != null">receive_name,
</if>
<if test="receivePhone != null">receive_phone,
</if>
<if test="receiveAddress != null">receive_address,
</if>
<if test="areaCode != null">area_code,
</if>
<if test="createBy != null">create_by,
</if>
<if test="createTime != null">create_time,
</if>
<if test="updateBy != null">update_by,
</if>
<if test="updateTime != null">update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},
</if>
<if test="patientId != null">#{patientId},
</if>
<if test="openid != null">#{openid},
</if>
<if test="unionid != null">#{unionid},
</if>
<if test="receiveName != null">#{receiveName},
</if>
<if test="receivePhone != null">#{receivePhone},
</if>
<if test="receiveAddress != null">#{receiveAddress},
</if>
<if test="areaCode != null">#{areaCode},
</if>
<if test="createBy != null">#{createBy},
</if>
<if test="createTime != null">#{createTime},
</if>
<if test="updateBy != null">#{updateBy},
</if>
<if test="updateTime != null">#{updateTime},
</if>
</trim>
</insert>
<update id="updateReceiveAddressInfo" parameterType="ReceiveAddressInfo">
update receive_address_info
<trim prefix="SET" suffixOverrides=",">
<if test="patientId != null">patient_id =
#{patientId},
</if>
<if test="openid != null">openid =
#{openid},
</if>
<if test="unionid != null">unionid =
#{unionid},
</if>
<if test="receiveName != null">receive_name =
#{receiveName},
</if>
<if test="receivePhone != null">receive_phone =
#{receivePhone},
</if>
<if test="receiveAddress != null">receive_address =
#{receiveAddress},
</if>
<if test="areaCode != null">area_code =
#{areaCode},
</if>
<if test="createBy != null">create_by =
#{createBy},
</if>
<if test="createTime != null">create_time =
#{createTime},
</if>
<if test="updateBy != null">update_by =
#{updateBy},
</if>
<if test="updateTime != null">update_time =
#{updateTime},
</if>
</trim>
where id = #{id}
</update>
<delete id="deleteReceiveAddressInfoByIds" parameterType="String">
delete from receive_address_info where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<select id="getSubordinateRegionsFindSuperiorRegions" parameterType="String"
resultType="com.xinelu.manage.vo.sysarea.SysAreaVO">
SELECT province.area_name province_name,
province.area_code province_code,
city.area_name city_name,
city.area_code city_code,
region.area_name region_name,
region.area_code region_code,
street.area_name street_name,
street.area_code street_code
FROM sys_area province,
sys_area city,
sys_area region,
sys_area street
WHERE city.parent_code = province.area_code
AND region.parent_code = city.area_code
AND street.parent_code = region.area_code
AND street.area_code = #{areaCode}
UNION ALL
SELECT province.area_name province_name,
province.area_code province_code,
city.area_name city_name,
city.area_code city_code,
region.area_name region_name,
region.area_code region_code,
'' as street_name,
'' as street_code
FROM sys_area province,
sys_area city,
sys_area region
WHERE city.parent_code = province.area_code
AND region.parent_code = city.area_code
AND region.area_code = #{areaCode} limit 1
</select>
<select id="selectGoodsOrderPatient" parameterType="com.xinelu.applet.dto.nursingstationgoods.GoodsOrderPatient"
resultType="com.xinelu.applet.dto.nursingstationgoods.GoodsOrderPatient">
SELECT
gr.id goodsId,
gr.nurse_station_id,
gr.patient_id,
gr.order_no,
gr.order_status,
gr.total_price,
gr.receiver,
gr.receive_address,
gr.phone,
gr.order_time,
gr.order_channel,
gr.buy_source,
god.goods_order_id,
god.goods_attribute_id,
god.goods_attribute_details_id,
god.order_no goodOrderNo,
god.goods_name,
god.goods_count,
god.goods_attribute_name,
god.goods_attribute_content,
god.goods_price,
god.total_price goodTotalPrice,
god.discount_price,
god.transport_price,
god.give_integral,
pi.id patientId,
pi.community_code,
pi.area_code,
pi.patient_code,
pi.patient_name,
pi.card_no,
pi.home_longitude,
pi.home_latitude,
pi.head_picture_url,
pi.integral
FROM goods_order gr
LEFT JOIN goods_order_details god ON gr.id = god.goods_order_id
LEFT JOIN patient_info pi ON pi.id = gr.patient_id
<where>
<if test="orderNo != null and orderNo != ''">
and gr.order_no = #{orderNo}
</if>
</where>
</select>
<select id="selectGoodsAttributeDetailsGoodsStockById" parameterType="Long"
resultType="GoodsAttributeDetails">
select id,
goods_attribute_id,
attribute_details_name,
goods_stock,
goods_price,
attribute_piture_url,
sort,
create_by,
create_time,
update_by,
update_time,
integral_exchange_flag,
integral_exchange_sill,
integral_exchange_count
from goods_attribute_details
where id = #{id}
</select>
<update id="updateGoodsAttributeDetails" parameterType="GoodsAttributeDetails">
update goods_attribute_details
<trim prefix="SET" suffixOverrides=",">
<if test="goodsAttributeId != null">goods_attribute_id =
#{goodsAttributeId},
</if>
<if test="attributeDetailsName != null">attribute_details_name =
#{attributeDetailsName},
</if>
<if test="goodsStock != null">goods_stock =
#{goodsStock},
</if>
<if test="goodsPrice != null">goods_price =
#{goodsPrice},
</if>
<if test="attributePitureUrl != null">attribute_piture_url =
#{attributePitureUrl},
</if>
<if test="sort != null">sort =
#{sort},
</if>
<if test="createBy != null">create_by =
#{createBy},
</if>
<if test="createTime != null">create_time =
#{createTime},
</if>
<if test="updateBy != null">update_by =
#{updateBy},
</if>
<if test="updateTime != null">update_time =
#{updateTime},
</if>
</trim>
where id = #{id}
</update>
<select id="selectCouponListByPatient" resultType="com.xinelu.applet.vo.coupon.CouponVO">
SELECT
coupon_id couponId,
coupon_title,
coupon_price,
coupon_consume_price,
coupon_description,
id patientCouponReceiveId,
patient_id,
receive_source,
expiration_start_time,
expiration_end_time,
receive_time,
use_status
FROM
patient_coupon_receive
<where>
<if test="patientId != null">
patient_id = #{patientId}
</if>
<if test="useStatus != null and useStatus !=''">
and use_status = #{useStatus}
</if>
</where>
order by coupon_price asc, coupon_consume_price asc
</select>
</mapper>

View File

@ -0,0 +1,225 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinelu.applet.mapper.patientcenter.PatientCenterMapper">
<!-- 商品信息标签映射-->
<resultMap type="com.xinelu.applet.vo.goodinfo.GoodInfoVO" id="GoodsInfoVOResult">
<result property="goodsInfoId" column="goodsInfoId"/>
<result property="nurseStationId" column="nurse_station_id"/>
<result property="goodsName" column="goods_name"/>
<result property="goodsPictureUrl" column="goods_picture_url"/>
<result property="goodsUnit" column="goods_unit"/>
<collection property="goodsAttributeDetailsList" javaType="java.util.List"
resultMap="goodsAttributeDetailsList"/>
</resultMap>
<!-- 商品属性明细信息标签映射-->
<resultMap type="com.xinelu.manage.vo.goodsInfo.GetGoodAttributeDetailsList"
id="goodsAttributeDetailsList">
<result property="goodsAttributeId" column="goods_attribute_id"/>
<result property="attributeDetailsId" column="attributeDetailsId"/>
<result property="attributeDetailsName" column="attribute_details_name"/>
<result property="goodsStock" column="goods_stock"/>
<result property="attributePitureUrl" column="attribute_piture_url"/>
<result property="integralExchangeFlag" column="integral_exchange_flag"/>
<result property="integralExchangeSill" column="integral_exchange_sill"/>
<result property="integralExchangeCount" column="integral_exchange_count"/>
</resultMap>
<select id="selectCouponByUseStatus" resultType="com.xinelu.applet.vo.coupon.CouponVO">
select
pcr.coupon_id couponId,
pcr.coupon_title,
pcr.coupon_price,
pcr.coupon_consume_price,
pcr.coupon_description,
pcr.id patientCouponReceiveId,
pcr.receive_source,
pcr.expiration_start_time,
pcr.expiration_end_time,
pcr.receive_time,
pcr.use_status
from patient_coupon_receive pcr
<where>
<if test="patientId != null ">
and pcr.patient_id = #{patientId}
</if>
<if test="receiveSource != null and receiveSource != ''">
AND pcr.receive_source = #{receiveSource}
</if>
<if test="useStatus != null and useStatus != ''">
AND pcr.use_status = #{useStatus}
</if>
<if test="useStatusList != null and useStatusList.size() > 0 ">
and pcr.use_status in
<foreach item="useStatus" collection="useStatusList" open="(" separator="," close=")">
#{useStatus}
</foreach>
</if>
</where>
order by pcr.coupon_price asc, pcr.coupon_consume_price asc
</select>
<select id="selectGoodsByExchangeFlag" resultType="com.xinelu.applet.dto.nursingstationgoods.GoodsList">
select
gi.id goodsInfoId,
gi.nurse_station_id,
gi.goods_name,
gi.goods_picture_url,
gi.goods_unit,
gad.goods_attribute_id,
gad.id attributeDetailsId,
gad.attribute_details_name,
gad.goods_stock,
gad.goods_price,
gad.attribute_piture_url,
gad.integral_exchange_flag,
gad.integral_exchange_sill,
gad.integral_exchange_count
from goods_info gi
LEFT JOIN goods_attribute ga ON ga.goods_id = gi.id
LEFT JOIN goods_attribute_details gad ON gad.goods_attribute_id = ga.id
<where>
<if test="integralExchangeFlag != null ">
and gad.integral_exchange_flag = #{integralExchangeFlag}
</if>
<if test="whetherShelf != null ">
and gi.whether_shelf = #{whetherShelf}
</if>
<if test="goodsPurpose != null and goodsPurpose != ''">
AND gi.goods_purpose = #{goodsPurpose}
</if>
</where>
ORDER BY gi.sort
</select>
<select id="selectCouponId" resultType="java.lang.Long">
SELECT id
from coupon
</select>
<select id="getPatientSignInInfo" resultType="com.xinelu.applet.vo.patientcenter.PatientSignInVO">
SELECT pi.id patientId,
pi.total_sign_in_days totalSignInDays,
pi.integral,
(select count(1) from patient_sign_in_info where patient_id = pi.id) signInCount,
(select count(1)
from patient_sign_in_info
where patient_id = pi.id
and sign_in_time = #{nowDate}) todaySignInCount
FROM patient_info pi
where pi.id = #{patientId}
</select>
<update id="updateTotalSignInDays" parameterType="long">
update patient_info
set total_sign_in_days = IFNULL(total_sign_in_days, 0) + 1,
update_time = now()
where id = #{patientId}
and del_flag = 0
</update>
<update id="updatePatientIntegral">
update patient_info
set integral = IFNULL(integral, 0) + #{integral},
update_time = now()
where id = #{patientId}
and del_flag = 0
</update>
<update id="clearTotalSignInDays">
update patient_info
set total_sign_in_days = 0,
update_time = now()
where id = #{patientId}
and del_flag = 0
</update>
<select id="selectPatientSignIn" resultType="com.xinelu.applet.vo.patientcenter.PatientSignInfoVO">
SELECT
id,
settings_name,
settings_content,
settings_type,
total_sign_in_days,
integral_count
FROM
system_settings_info
WHERE
settings_type in
<foreach item="rule" collection="ruleList" open="(" separator="," close=")">
#{rule}
</foreach>
</select>
<select id="getCouponNewPeople" resultType="com.xinelu.applet.vo.coupon.CouponVO">
select id couponId,
coupon_title,
coupon_code,
coupon_type,
coupon_reduction_days,
coupon_price,
coupon_consume_price,
coupon_description,
receive_type,
receive_count,
receive_limit_count,
use_scope,
show_sort,
"WAIT_RECEIVE" useStatus
from coupon
<where>
<if test="receiveType != null and receiveType != ''">
and receive_type = #{receiveType}
</if>
</where>
order by coupon_price asc, coupon_consume_price asc
</select>
<select id="getCouponByUseStatus" resultType="com.xinelu.applet.vo.coupon.CouponVO">
select
cp.use_scope,
pcr.coupon_reduction_days,
pcr.coupon_id couponId,
pcr.coupon_price,
pcr.coupon_consume_price,
pcr.coupon_description,
pcr.coupon_title,
pcr.id patientCouponReceiveId,
pcr.receive_source,
pcr.expiration_start_time,
pcr.expiration_end_time,
pcr.receive_time,
pcr.use_status
from patient_coupon_receive pcr
LEFT JOIN coupon cp ON cp.id = pcr.coupon_id
<where>
<if test="patientId != null ">
and pcr.patient_id = #{patientId}
</if>
<if test="receiveType != null and receiveType != ''">
AND cp.receive_type = #{receiveType}
</if>
<if test="receiveSource != null and receiveSource != ''">
AND pcr.receive_source = #{receiveSource}
</if>
<if test="useStatus != null and useStatus != ''">
AND pcr.use_status = #{useStatus}
</if>
</where>
order by pcr.coupon_price asc, pcr.coupon_consume_price asc
</select>
<select id="getPatientSignInfo" resultType="com.xinelu.applet.vo.patientcenter.PatientSignInfoVO">
SELECT total_sign_in_days patientSignInCount,
integral,
(SELECT count(1)
FROM patient_sign_in_info
WHERE patient_id = #{patientId}
AND sign_in_time = #{nowDate}) todaySignInCount
FROM patient_info
WHERE id = #{patientId}
AND del_flag = 0
</select>
</mapper>

View File

@ -0,0 +1,197 @@
package com.xinelu.manage.domain.goodsOrderDetails;
import com.xinelu.common.annotation.Excel;
import com.xinelu.common.core.domain.BaseDomain;
import com.xinelu.common.custominterface.Insert;
import com.xinelu.common.custominterface.Update;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 商品订单明细对象 goods_order_details
*
* @author xinyilu
* @date 2022-10-18
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "商品订单明细对象", description = "goods_order_details")
public class GoodsOrderDetails extends BaseDomain implements Serializable {
private static final long serialVersionUID = -2047412676286670313L;
/**
* 主键id
*/
private Long id;
/**
* 商品订单表id
*/
@ApiModelProperty(value = "商品订单表id")
@Excel(name = "商品订单表id")
@NotNull(message = "商品订单表id为空", groups = {Insert.class, Update.class})
private Long goodsOrderId;
/**
* 商品属性id
*/
@ApiModelProperty(value = "商品属性id")
@Excel(name = "商品属性id")
@NotNull(message = "商品属性id不能为空", groups = {Insert.class, Update.class})
private Long goodsAttributeId;
/**
* 商品属性明细id
*/
@ApiModelProperty(value = "商品属性明细id")
@Excel(name = "商品属性明细id")
@NotNull(message = "商品属性明细id不能为空", groups = {Insert.class, Update.class})
private Long goodsAttributeDetailsId;
/**
* 订单编号
*/
@ApiModelProperty(value = "订单编号")
@Excel(name = "订单编号")
private String orderNo;
/**
* 商品名称
*/
@ApiModelProperty(value = "商品名称")
@Excel(name = "商品名称")
@NotBlank(message = "商品名称不能为空", groups = {Insert.class, Update.class})
@Length(max = 50, message = "商品名称不能超过50位", groups = {Insert.class, Update.class})
private String goodsName;
/**
* 商品数量
*/
@ApiModelProperty(value = "商品数量")
@Excel(name = "商品数量")
@NotNull(message = "商品数量不能为空", groups = {Insert.class, Update.class})
@Length(max = 10, message = "商品数量不能超过10位", groups = {Insert.class, Update.class})
private Integer goodsCount;
/**
* 商品属性名称
*/
@ApiModelProperty(value = "商品属性名称")
@Excel(name = "商品属性名称")
private String goodsAttributeName;
/**
* 商品属性内容
*/
@ApiModelProperty(value = "商品属性内容")
@Excel(name = "商品属性内容")
private String goodsAttributeContent;
/**
* 商品单价
*/
@ApiModelProperty(value = "商品单价")
@Excel(name = "商品单价", readConverterExp = "元=")
@NotNull(message = "商品单价不能为空", groups = {Insert.class, Update.class})
@Length(max = 10, message = "商品单价不能超过10位", groups = {Insert.class, Update.class})
private BigDecimal goodsPrice;
/**
* 应付总金额
*/
@ApiModelProperty(value = "应付总金额")
@Excel(name = "应付总金额", readConverterExp = "元=")
private BigDecimal totalPrice;
/**
* 优惠金额
*/
@ApiModelProperty(value = "优惠金额")
@Excel(name = "优惠金额", readConverterExp = "元=")
private BigDecimal discountPrice;
/**
* 运费金额
*/
@ApiModelProperty(value = "运费金额")
@Excel(name = "运费金额", readConverterExp = "元=")
private BigDecimal transportPrice;
/**
* 赠送积分
*/
@ApiModelProperty(value = "赠送积分")
@Excel(name = "赠送积分")
private Integer giveIntegral;
/**
* 01
*/
private Integer delFlag;
/**
* 优惠券id
*/
private Long couponId;
/**
* 积分抵扣数量
*/
private Integer integralDeductionCount;
/**
* 积分抵扣金额
*/
private BigDecimal integralDeductionPrice;
/**
* 优惠券名称
*/
private String couponTitle;
/**
* 积分兑换商品使用积分数值
*/
private Integer integralExchangeSill;
/**
* 积分兑换商品数量
*/
private Integer integralExchangeCount;
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("goodsOrderId", getGoodsOrderId())
.append("orderNo", getOrderNo())
.append("goodsName", getGoodsName())
.append("goodsCount", getGoodsCount())
.append("goodsAttributeName", getGoodsAttributeName())
.append("goodsAttributeContent", getGoodsAttributeContent())
.append("goodsPrice", getGoodsPrice())
.append("totalPrice", getTotalPrice())
.append("discountPrice", getDiscountPrice())
.append("transportPrice", getTransportPrice())
.append("giveIntegral", getGiveIntegral())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@ -0,0 +1,140 @@
package com.xinelu.manage.domain.patientcouponreceive;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinelu.common.annotation.Excel;
import com.xinelu.common.core.domain.BaseDomain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 会员用户优惠券领取记录对象 patient_coupon_receive
*
* @author xinyilu
* @date 2023-02-24
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "会员用户优惠券领取记录对象", description = "patient_coupon_receive")
public class PatientCouponReceive extends BaseDomain implements Serializable {
private static final long serialVersionUID = 5822850923451694701L;
/**
* 主键id
*/
private Long id;
/**
* 会员id
*/
@ApiModelProperty(value = "会员id")
@Excel(name = "会员id")
private Long patientId;
/**
* 优惠券id
*/
@ApiModelProperty(value = "优惠券id")
@Excel(name = "优惠券id")
private Long couponId;
/**
* 新人福利NEW_PEOPLE_WELFARE活动赠送EVENT_GIFT消费返券CONSUME_REBATE
*/
@ApiModelProperty(value = "新人福利NEW_PEOPLE_WELFARE活动赠送EVENT_GIFT消费返券CONSUME_REBATE")
@Excel(name = "新人福利NEW_PEOPLE_WELFARE活动赠送EVENT_GIFT消费返券CONSUME_REBATE")
private String receiveSource;
/**
* 有效期开始时间yyyy-MM-dd HH:mm:ss
*/
@ApiModelProperty(value = "有效期开始时间yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "有效期开始时间yyyy-MM-dd HH:mm:ss", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime expirationStartTime;
/**
* 有效期结束时间yyyy-MM-dd HH:mm:ss
*/
@ApiModelProperty(value = "有效期结束时间yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "有效期结束时间yyyy-MM-dd HH:mm:ss", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime expirationEndTime;
/**
* 领取时间yyyy-MM-dd HH:mm:ss
*/
@ApiModelProperty(value = "领取时间yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "领取时间yyyy-MM-dd HH:mm:ss", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime receiveTime;
/**
* 未使用NOT_USED已使用USED已过期EXPIRED
*/
@ApiModelProperty(value = "未使用NOT_USED已使用USED已过期EXPIRED")
@Excel(name = "未使用NOT_USED已使用USED已过期EXPIRED")
private String useStatus;
/**
* 优惠券名称
*/
@ApiModelProperty(value = "优惠券名称")
@Excel(name = "优惠券名称")
private String couponTitle;
/**
* 优惠券面额
*/
@ApiModelProperty(value = "优惠券面额")
@Excel(name = "优惠券面额")
private BigDecimal couponPrice;
/**
* 优惠券适用门槛
*/
@ApiModelProperty(value = "优惠券适用门槛")
@Excel(name = "优惠券适用门槛")
private BigDecimal couponConsumePrice;
/**
* 优惠券概述包括使用范围使用注意事项等信息
*/
@ApiModelProperty(value = "优惠券概述,包括使用范围,使用注意事项等信息")
@Excel(name = "优惠券概述,包括使用范围,使用注意事项等信息")
private String couponDescription;
/**
* 优惠券有效期单位
*/
private Integer couponReductionDays;
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("patientId", getPatientId())
.append("couponId", getCouponId())
.append("receiveSource", getReceiveSource())
.append("expirationStartTime", getExpirationStartTime())
.append("expirationEndTime", getExpirationEndTime())
.append("receiveTime", getReceiveTime())
.append("useStatus", getUseStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@ -0,0 +1,103 @@
package com.xinelu.manage.domain.patientintegralchange;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinelu.common.annotation.Excel;
import com.xinelu.common.core.domain.BaseDomain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 会员积分变更记录对象 patient_integral_change
*
* @author xinyilu
* @date 2023-02-27
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "会员积分变更记录对象", description = "patient_integral_change")
public class PatientIntegralChange extends BaseDomain implements Serializable {
private static final long serialVersionUID = 3874412439515378186L;
/**
* 主键id
*/
private Long id;
/**
* 会员id
*/
@ApiModelProperty(value = "会员id")
@Excel(name = "会员id")
private Long patientId;
/**
* 原始积分
*/
@ApiModelProperty(value = "原始积分")
@Excel(name = "原始积分")
private Integer originalIntegral;
/**
* 变动积分
*/
@ApiModelProperty(value = "变动积分")
@Excel(name = "变动积分")
private Integer changeIntegral;
/**
* 积分变更时间
*/
@ApiModelProperty(value = "积分变更时间")
@JsonFormat(pattern = "yyyy-MM-dd, HH:mm:ss")
@Excel(name = "积分变更时间", width = 30, dateFormat = "yyyy-MM-dd, HH:mm:ss")
private LocalDateTime changeTime;
/**
* 积分变动类型商品兑换COMMODITY_EXCHANGE好友邀请FRIEND_INVITATION观看视频WATCH_VIDEO
* 会员签到SIGN_IN
*/
@ApiModelProperty(value = "积分变动类型商品兑换COMMODITY_EXCHANGE好友邀请FRIEND_INVITATION观看视频WATCH_VIDEO会员签到SIGN_IN")
@Excel(name = "积分变动类型商品兑换COMMODITY_EXCHANGE好友邀请FRIEND_INVITATION观看视频WATCH_VIDEO会员签到SIGN_IN")
private String changeType;
/**
* 积分变更描述
*/
@ApiModelProperty(value = "积分变更描述")
@Excel(name = "积分变更描述")
private String changeRemark;
/**
* 积分变更方式手机AppMOBILE_APP微信小程序WECHAT_APPLET支付宝小程序ALI_PAY_APPLET
*/
@ApiModelProperty(value = "积分变更方式手机AppMOBILE_APP微信小程序WECHAT_APPLET支付宝小程序ALI_PAY_APPLET")
@Excel(name = "积分变更方式手机AppMOBILE_APP微信小程序WECHAT_APPLET支付宝小程序ALI_PAY_APPLET")
private String changeIntegralChannel;
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("patientId", getPatientId())
.append("originalIntegral", getOriginalIntegral())
.append("changeIntegral", getChangeIntegral())
.append("changeTime", getChangeTime())
.append("changeType", getChangeType())
.append("changeRemark", getChangeRemark())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@ -0,0 +1,72 @@
package com.xinelu.manage.domain.patientsignininfo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinelu.common.annotation.Excel;
import com.xinelu.common.core.domain.BaseDomain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
import java.time.LocalDate;
/**
* 会员用户签到记录对象 patient_sign_in_info
*
* @author xinyilu
* @date 2023-02-27
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "会员用户签到记录对象", description = "patient_sign_in_info")
public class PatientSignInInfo extends BaseDomain implements Serializable {
private static final long serialVersionUID = -6783715945093928258L;
/**
* 主键id
*/
private Long id;
/**
* 会员id
*/
@ApiModelProperty(value = "会员id")
@Excel(name = "会员id")
private Long patientId;
/**
* 签到时间yyyy-MM-dd同一天只记录一次
*/
@ApiModelProperty(value = "签到时间yyyy-MM-dd同一天只记录一次")
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "签到时间yyyy-MM-dd同一天只记录一次", width = 30, dateFormat = "yyyy-MM-dd")
private LocalDate signInTime;
/**
* 签到方式手机AppMOBILE_APP微信小程序WECHAT_APPLET支付宝小程序ALI_PAY_APPLET
*/
@ApiModelProperty(value = "签到方式手机AppMOBILE_APP微信小程序WECHAT_APPLET支付宝小程序ALI_PAY_APPLET")
@Excel(name = "签到方式手机AppMOBILE_APP微信小程序WECHAT_APPLET支付宝小程序ALI_PAY_APPLET")
private String signInChannel;
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("patientId", getPatientId())
.append("signInTime", getSignInTime())
.append("signInChannel", getSignInChannel())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@ -0,0 +1,131 @@
package com.xinelu.manage.domain.subscribemessagerecord;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinelu.common.annotation.Excel;
import com.xinelu.common.core.domain.BaseDomain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Objects;
/**
* 微信小程序订阅消息记录对象 subscribe_message_record
*
* @author xinyilu
* @date 2023-03-14
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "微信小程序订阅消息记录对象", description = "subscribe_message_record")
public class SubscribeMessageRecord extends BaseDomain implements Serializable {
private static final long serialVersionUID = -474969938563834831L;
/**
* 主键id
*/
private Long id;
/**
* 会员id
*/
@ApiModelProperty(value = "会员id")
@Excel(name = "会员id")
private Long patientId;
/**
* 微信unionid标识
*/
@ApiModelProperty(value = "微信unionid标识")
@Excel(name = "微信unionid标识")
private String unionid;
/**
* 微信小程序的openid
*/
@ApiModelProperty(value = "微信小程序的openid")
@Excel(name = "微信小程序的openid")
private String openid;
/**
* 消息模板id
*/
@ApiModelProperty(value = "消息模板id")
@Excel(name = "消息模板id")
private String templateId;
/**
* 订阅消息类型消费提醒CONSUME_MESSAGE_PUSH优惠券到期提醒COUPON_EXPIRE_MESSAGE_PUSH积分过期提醒INTEGRAL_EXPIRE_MESSAGE_PUSH
*/
@ApiModelProperty(value = "订阅消息类型消费提醒CONSUME_MESSAGE_PUSH优惠券到期提醒COUPON_EXPIRE_MESSAGE_PUSH积分过期提醒INTEGRAL_EXPIRE_MESSAGE_PUSH")
@Excel(name = "订阅消息类型消费提醒CONSUME_MESSAGE_PUSH优惠券到期提醒COUPON_EXPIRE_MESSAGE_PUSH积分过期提醒INTEGRAL_EXPIRE_MESSAGE_PUSH")
private String messageType;
/**
* 用于订阅消息次数
*/
@ApiModelProperty(value = "用于订阅消息次数")
@Excel(name = "用于订阅消息次数")
private Integer subscribeCount;
/**
* 订阅时间
*/
@ApiModelProperty(value = "订阅时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "订阅时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime subscribeTime;
/**
* 微信小程序账户id
*/
private String appletId;
/**
* 订阅状态accept接受reject拒绝
*/
private String subscribeStatus;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SubscribeMessageRecord that = (SubscribeMessageRecord) o;
return Objects.equals(openid, that.openid) && Objects.equals(templateId, that.templateId);
}
@Override
public int hashCode() {
return Objects.hash(openid, templateId);
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("patientId", getPatientId())
.append("unionid", getUnionid())
.append("openid", getOpenid())
.append("templateId", getTemplateId())
.append("messageType", getMessageType())
.append("subscribeCount", getSubscribeCount())
.append("subscribeTime", getSubscribeTime())
.append("appletId", getAppletId())
.append("subscribeStatus", getSubscribeStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@ -0,0 +1,119 @@
package com.xinelu.manage.domain.subscribemessagesendrecord;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinelu.common.annotation.Excel;
import com.xinelu.common.core.domain.BaseDomain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 微信小程序订阅消息发送结果记录对象 subscribe_message_send_record
*
* @author xinyilu
* @date 2023-03-16
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "微信小程序订阅消息发送结果记录对象", description = "subscribe_message_send_record")
public class SubscribeMessageSendRecord extends BaseDomain implements Serializable {
private static final long serialVersionUID = 4503696547761494422L;
/**
* 主键id
*/
private Long id;
/**
* 微信unionid
*/
@ApiModelProperty(value = "微信unionid")
@Excel(name = "微信unionid")
private String unionid;
/**
* 微信openid
*/
@ApiModelProperty(value = "微信openid")
@Excel(name = "微信openid")
private String openid;
/**
* 微信小程序id
*/
@ApiModelProperty(value = "微信小程序id")
@Excel(name = "微信小程序id")
private String appletId;
/**
* 订阅消息发送时间
*/
@ApiModelProperty(value = "订阅消息发送时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "订阅消息发送时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime subscribeTime;
/**
* 消息模板id
*/
@ApiModelProperty(value = "消息模板id")
@Excel(name = "消息模板id")
private String templateId;
/**
* 消息id
*/
@ApiModelProperty(value = "消息id")
@Excel(name = "消息id")
private String msgId;
/**
* 订阅消息类型预约服务付款通知提醒APPOINT_ORDER_MESSAGE_PUSH优惠券领取提醒COUPON_RECEIVE_MESSAGE_PUSH商品订单支付成功提醒GOODS_ORDER_MESSAGE_PUSH
*/
@ApiModelProperty(value = "订阅消息类型")
@Excel(name = "订阅消息类型")
private String messageType;
/**
* 推送结果状态码0表示成功
*/
@ApiModelProperty(value = "推送结果状态码")
@Excel(name = "推送结果状态码", readConverterExp = "0=表示成功")
private Integer errorCode;
/**
* 推送结果状态码success成功
*/
@ApiModelProperty(value = "推送结果状态码success成功")
@Excel(name = "推送结果状态码success成功")
private String errorStatus;
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("unionid", getUnionid())
.append("openid", getOpenid())
.append("appletId", getAppletId())
.append("subscribeTime", getSubscribeTime())
.append("templateId", getTemplateId())
.append("msgId", getMsgId())
.append("errorCode", getErrorCode())
.append("errorStatus", getErrorStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@ -0,0 +1,24 @@
package com.xinelu.manage.dto.subscribemessagerecord;
import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord;
import lombok.Data;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.List;
/**
* @author ljh
* @version 1.0
* Create by 2023/3/15 10:01
*/
@Data
public class SubscribeMessageRecordDTO implements Serializable {
private static final long serialVersionUID = -5480052884317349349L;
/**
* 微信小程序订阅消息记录对象集合
**/
@Valid
List<SubscribeMessageRecord> subscribeMessageRecordList;
}

View File

@ -0,0 +1,71 @@
package com.xinelu.manage.mapper.goodsOrderDetails;
import com.xinelu.manage.domain.goodsOrderDetails.GoodsOrderDetails;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 商品订单明细Mapper接口
*
* @author xinyilu
* @date 2022-10-18
*/
public interface GoodsOrderDetailsMapper {
/**
* 查询商品订单明细
*
* @param id 商品订单明细主键
* @return 商品订单明细
*/
GoodsOrderDetails selectGoodsOrderDetailsById(Long id);
/**
* 查询商品订单明细列表
*
* @param goodsOrderDetails 商品订单明细
* @return 商品订单明细集合
*/
List<GoodsOrderDetails> selectGoodsOrderDetailsList(GoodsOrderDetails goodsOrderDetails);
/**
* 新增商品订单明细
*
* @param goodsOrderDetails 商品订单明细
* @return 结果
*/
int insertGoodsOrderDetails(GoodsOrderDetails goodsOrderDetails);
/**
* 修改商品订单明细
*
* @param goodsOrderDetails 商品订单明细
* @return 结果
*/
int updateGoodsOrderDetails(GoodsOrderDetails goodsOrderDetails);
/**
* 删除商品订单明细
*
* @param id 商品订单明细主键
* @return 结果
*/
int deleteGoodsOrderDetailsById(Long id);
/**
* 批量删除商品订单明细
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
int deleteGoodsOrderDetailsByIds(Long[] ids);
/**
* 根据订单数量和订单明细查询订单信息
*
* @param orderNo 订单编号
* @param goodsOrderDetailId 明细id
* @return 订单明细信息
*/
GoodsOrderDetails getGoodsOrderDetailInfo(@Param("orderNo") String orderNo, @Param("goodsOrderDetailId") Long goodsOrderDetailId);
}

View File

@ -0,0 +1,130 @@
package com.xinelu.manage.mapper.patientcouponreceive;
import com.xinelu.manage.domain.patientcouponreceive.PatientCouponReceive;
import com.xinelu.manage.vo.patientcouponreceive.PatientCouponReceiveInfoVO;
import com.xinelu.manage.vo.patientcouponreceive.PatientCouponReceiveVO;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
/**
* 会员用户优惠券领取记录Mapper接口
*
* @author xinyilu
* @date 2023-02-24
*/
public interface PatientCouponReceiveMapper {
/**
* 查询会员用户优惠券领取记录
*
* @param id 会员用户优惠券领取记录主键
* @return 会员用户优惠券领取记录
*/
PatientCouponReceive selectPatientCouponReceiveById(Long id);
/**
* 查询会员用户优惠券领取记录列表
*
* @param patientCouponReceive 会员用户优惠券领取记录
* @return 会员用户优惠券领取记录集合
*/
List<PatientCouponReceive> selectPatientCouponReceiveList(PatientCouponReceive patientCouponReceive);
/**
* 新增会员用户优惠券领取记录
*
* @param patientCouponReceive 会员用户优惠券领取记录
* @return 结果
*/
int insertPatientCouponReceive(PatientCouponReceive patientCouponReceive);
/**
* 修改会员用户优惠券领取记录
*
* @param patientCouponReceive 会员用户优惠券领取记录
* @return 结果
*/
int updatePatientCouponReceive(PatientCouponReceive patientCouponReceive);
/**
* 删除会员用户优惠券领取记录
*
* @param id 会员用户优惠券领取记录主键
* @return 结果
*/
int deletePatientCouponReceiveById(Long id);
/**
* 批量删除会员用户优惠券领取记录
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
int deletePatientCouponReceiveByIds(Long[] ids);
/**
* 批量新增用户优惠券信息
*
* @param couponReceiveList 优惠券信息集合
* @return 新增数量
*/
int insertBatchPatientReceive(@Param("couponReceiveList") List<PatientCouponReceive> couponReceiveList);
/**
* 查询会员用户过期的优惠券领取记录列表
*
* @param expirationEndTime 过期的优惠券时间
* @param couponUseStatus 优惠券状态
* @return 会员用户优惠券领取记录集合
*/
List<PatientCouponReceive> getPatientCouponExpirationEndTime(@Param("expirationEndTime") LocalDateTime expirationEndTime, @Param("couponUseStatus") String couponUseStatus);
/**
* 批量更新优惠券状态
*
* @param couponUseStatus 状态
* @param idList id集合
* @return 更新数量
*/
int updateCouponReceiveStatus(@Param("couponUseStatus") String couponUseStatus, @Param("idList") List<Long> idList);
/**
* 批量更新优惠券状态集合
*
* @param couponUseStatus 状态
* @param idList 优惠券id集合
* @return int
**/
int updateCouponReceiveStatusList(@Param("couponUseStatus") String couponUseStatus, @Param("idList") List<Long> idList);
/**
* 查询用户所属的优惠券券信息
*
* @param patientId 会员id
* @param couponId 优惠券id
* @return 用户优惠券信息
*/
PatientCouponReceiveVO getPatientCouponInfo(@Param("patientId") Long patientId, @Param("couponId") Long couponId);
/**
* 优惠用户优惠表中的优惠券状态
*
* @param patientId 会员id
* @param couponId 优惠券id
* @param useStatus 优惠券状态
* @return 数量
*/
int updatePatientCouponUseStatus(@Param("patientId") Long patientId, @Param("couponId") Long couponId, @Param("useStatus") String useStatus);
/**
* 查询会员用户优惠券领取记录
*
* @param patientId 会员用户主键
* @param couponId 优惠券领取主键
* @return 会员用户优惠券领取记录
*/
PatientCouponReceiveInfoVO selectPatientCouponReceive(@Param("patientId") Long patientId, @Param("couponId") Long couponId);
}

View File

@ -0,0 +1,61 @@
package com.xinelu.manage.mapper.patientintegralchange;
import com.xinelu.manage.domain.patientintegralchange.PatientIntegralChange;
import java.util.List;
/**
* 会员积分变更记录Mapper接口
*
* @author xinyilu
* @date 2023-02-27
*/
public interface PatientIntegralChangeMapper {
/**
* 查询会员积分变更记录
*
* @param id 会员积分变更记录主键
* @return 会员积分变更记录
*/
PatientIntegralChange selectPatientIntegralChangeById(Long id);
/**
* 查询会员积分变更记录列表
*
* @param patientIntegralChange 会员积分变更记录
* @return 会员积分变更记录集合
*/
List<PatientIntegralChange> selectPatientIntegralChangeList(PatientIntegralChange patientIntegralChange);
/**
* 新增会员积分变更记录
*
* @param patientIntegralChange 会员积分变更记录
* @return 结果
*/
int insertPatientIntegralChange(PatientIntegralChange patientIntegralChange);
/**
* 修改会员积分变更记录
*
* @param patientIntegralChange 会员积分变更记录
* @return 结果
*/
int updatePatientIntegralChange(PatientIntegralChange patientIntegralChange);
/**
* 删除会员积分变更记录
*
* @param id 会员积分变更记录主键
* @return 结果
*/
int deletePatientIntegralChangeById(Long id);
/**
* 批量删除会员积分变更记录
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
int deletePatientIntegralChangeByIds(Long[] ids);
}

View File

@ -0,0 +1,72 @@
package com.xinelu.manage.mapper.patientsignininfo;
import com.xinelu.manage.domain.patientsignininfo.PatientSignInInfo;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDate;
import java.util.List;
/**
* 会员用户签到记录Mapper接口
*
* @author xinyilu
* @date 2023-02-27
*/
public interface PatientSignInInfoMapper {
/**
* 查询会员用户签到记录
*
* @param id 会员用户签到记录主键
* @return 会员用户签到记录
*/
PatientSignInInfo selectPatientSignInInfoById(Long id);
/**
* 查询会员用户签到记录列表
*
* @param patientSignInInfo 会员用户签到记录
* @return 会员用户签到记录集合
*/
List<PatientSignInInfo> selectPatientSignInInfoList(PatientSignInInfo patientSignInInfo);
/**
* 新增会员用户签到记录
*
* @param patientSignInInfo 会员用户签到记录
* @return 结果
*/
int insertPatientSignInInfo(PatientSignInInfo patientSignInInfo);
/**
* 修改会员用户签到记录
*
* @param patientSignInInfo 会员用户签到记录
* @return 结果
*/
int updatePatientSignInInfo(PatientSignInInfo patientSignInInfo);
/**
* 删除会员用户签到记录
*
* @param id 会员用户签到记录主键
* @return 结果
*/
int deletePatientSignInInfoById(Long id);
/**
* 批量删除会员用户签到记录
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
int deletePatientSignInInfoByIds(Long[] ids);
/**
* 根据签到日期查询当前人员有没有签到过
*
* @param patientId 会员id
* @param signInTime 签到日期
* @return 签到数量
*/
int getPatientSignInInfoCountByDate(@Param("patientId") Long patientId, @Param("signInTime") LocalDate signInTime);
}

View File

@ -0,0 +1,74 @@
package com.xinelu.manage.mapper.receiveAddressInfo;
import com.xinelu.manage.domain.receiveAddressInfo.ReceiveAddressInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 收货人地址信息Mapper接口
*
* @author xinyilu
* @date 2022-10-18
*/
public interface ReceiveAddressInfoMapper {
/**
* 查询收货人地址信息
*
* @param id 收货人地址信息主键
* @return 收货人地址信息
*/
ReceiveAddressInfo selectReceiveAddressInfoById(Long id);
/**
* 查询收货人地址信息列表
*
* @param receiveAddressInfo 收货人地址信息
* @return 收货人地址信息集合
*/
List<ReceiveAddressInfo> selectReceiveAddressInfoList(ReceiveAddressInfo receiveAddressInfo);
/**
* 新增收货人地址信息
*
* @param receiveAddressInfo 收货人地址信息
* @return 结果
*/
int insertReceiveAddressInfo(ReceiveAddressInfo receiveAddressInfo);
/**
* 修改收货人地址信息
*
* @param receiveAddressInfo 收货人地址信息
* @return 结果
*/
int updateReceiveAddressInfo(ReceiveAddressInfo receiveAddressInfo);
/**
* 删除收货人地址信息
*
* @param id 收货人地址信息主键
* @return 结果
*/
int deleteReceiveAddressInfoById(Long id);
/**
* 批量删除收货人地址信息
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
int deleteReceiveAddressInfoByIds(Long[] ids);
/**
* 查询当前收货地址是否存在
*
* @param patientId 会员id
* @param receiveName 收货人名称
* @param receivePhone 收货人电话
* @param receiveAddress 收货地址
* @return 数量
*/
int getReceiveAddressInfo(@Param("patientId") Long patientId, @Param("receiveName") String receiveName,
@Param("receivePhone") String receivePhone, @Param("receiveAddress") String receiveAddress);
}

View File

@ -0,0 +1,108 @@
package com.xinelu.manage.mapper.subscribemessagerecord;
import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 微信小程序订阅消息记录Mapper接口
*
* @author xinyilu
* @date 2023-03-14
*/
public interface SubscribeMessageRecordMapper {
/**
* 查询微信小程序订阅消息记录
*
* @param id 微信小程序订阅消息记录主键
* @return 微信小程序订阅消息记录
*/
SubscribeMessageRecord selectSubscribeMessageRecordById(Long id);
/**
* 查询微信小程序订阅消息记录列表
*
* @param subscribeMessageRecord 微信小程序订阅消息记录
* @return 微信小程序订阅消息记录集合
*/
List<SubscribeMessageRecord> selectSubscribeMessageRecordList(SubscribeMessageRecord subscribeMessageRecord);
/**
* 新增微信小程序订阅消息记录
*
* @param subscribeMessageRecord 微信小程序订阅消息记录
* @return 结果
*/
int insertSubscribeMessageRecord(SubscribeMessageRecord subscribeMessageRecord);
/**
* 修改微信小程序订阅消息记录
*
* @param subscribeMessageRecord 微信小程序订阅消息记录
* @return 结果
*/
int updateSubscribeMessageRecord(SubscribeMessageRecord subscribeMessageRecord);
/**
* 删除微信小程序订阅消息记录
*
* @param id 微信小程序订阅消息记录主键
* @return 结果
*/
int deleteSubscribeMessageRecordById(Long id);
/**
* 批量删除微信小程序订阅消息记录
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
int deleteSubscribeMessageRecordByIds(Long[] ids);
/**
* 根据用户idopenid消息模板id查询微信小程序订阅消息记录
*
* @param patientId 会员id
* @param openid openid
* @param templateId 消息模板id
* @return com.xinyilu.base.domain.subscribemessagerecord.SubscribeMessageRecord
**/
SubscribeMessageRecord selectSubscribeMessageRecordByPatientId(@Param("patientId") Long patientId, @Param("openid") String openid, @Param("templateId") String templateId);
/**
* 根据用户id查询微信小程序订阅消息记录次数
*
* @param subscribeMessageRecord 微信小程序订阅消息记录
* @return int
**/
int selectSubscribeMessageRecordByCount(SubscribeMessageRecord subscribeMessageRecord);
/**
* 批量新增微信小程序订阅消息记录
*
* @param subscribeMessageRecordList 新增微信小程序订阅消息记录
* @return int
**/
int insertSubscribeMessageRecordList(List<SubscribeMessageRecord> subscribeMessageRecordList);
/**
* 根据会员openid与templateId修改微信小程序订阅消息记录
*
* @param openId 微信openid
* @param templateId 模板id
* @param subscribeStatus 订阅状态
* @return int
**/
int updateSubscribeMessageTemplateId(@Param("openId") String openId, @Param("templateId") String templateId, @Param("subscribeStatus") String subscribeStatus, @Param("patientId") Long patientId);
/**
* 查询
*
* @param ids 会员id
* @param subscribeStatus 订阅状态
* @param messageType 订阅消息类型
* @return List<SubscribeMessageRecord>
*/
List<SubscribeMessageRecord> selectSubscribeList(@Param("list") List<Long> ids, @Param("subscribeStatus") String subscribeStatus, @Param("messageType") String messageType);
}

View File

@ -0,0 +1,22 @@
package com.xinelu.manage.mapper.subscribemessagesendrecord;
import com.xinelu.manage.domain.subscribemessagesendrecord.SubscribeMessageSendRecord;
import java.util.List;
/**
* 微信小程序订阅消息发送结果记录Mapper接口
*
* @author xinyilu
* @date 2023-03-16
*/
public interface SubscribeMessageSendRecordMapper {
/**
* 批量新增微信小程序订阅消息发送记录
*
* @param subscribeMessageSendRecordList 微信小程序订阅发送消息记录
* @return int
**/
int insertSubscribeMessageSendRecordList(List<SubscribeMessageSendRecord> subscribeMessageSendRecordList);
}

View File

@ -0,0 +1,22 @@
package com.xinelu.manage.vo.patientcouponreceive;
import com.xinelu.manage.domain.patientcouponreceive.PatientCouponReceive;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* @author ljh
* @version 1.0
* Create by 2023/3/15 9:07
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class PatientCouponReceiveInfoVO extends PatientCouponReceive implements Serializable {
private static final long serialVersionUID = 7762303477160252595L;
/**
* 优惠券类型满减券FULL_REDUCTION_COUPON代金券CASH_COUPON兑换券EXCHANGE_COUPON折扣券DISCOUNT_COUPON',
**/
private String couponType;
}

View File

@ -0,0 +1,76 @@
package com.xinelu.manage.vo.patientcouponreceive;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* @Description 优惠券信息与用户优惠券领取信息实体类
* @Author 纪寒
* @Date 2023-03-01 16:21:07
* @Version 1.0
*/
@Data
public class PatientCouponReceiveVO implements Serializable {
private static final long serialVersionUID = -7141760788932626416L;
/**
* 主键id
*/
private Long id;
/**
* 会员id
*/
private Long patientId;
/**
* 优惠券id
*/
private Long couponId;
/**
* 新人福利NEW_PEOPLE_WELFARE活动赠送EVENT_GIFT消费返券CONSUME_REBATE
*/
private String receiveSource;
/**
* 有效期开始时间yyyy-MM-dd HH:mm:ss
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime expirationStartTime;
/**
* 有效期结束时间yyyy-MM-dd HH:mm:ss
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime expirationEndTime;
/**
* 领取时间yyyy-MM-dd HH:mm:ss
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime receiveTime;
/**
* 未使用NOT_USED已使用USED已过期EXPIRED
*/
private String useStatus;
/**
* 优惠券面额
*/
private BigDecimal couponPrice;
/**
* 优惠券名称
*/
private String couponTitle;
/**
* 优惠券使用门槛
*/
private BigDecimal couponConsumePrice;
}

View File

@ -0,0 +1,141 @@
package com.xinelu.manage.vo.receiveAddressInfo;
import com.xinelu.common.annotation.Excel;
import com.xinelu.common.custominterface.Insert;
import com.xinelu.common.custominterface.Update;
import com.xinelu.manage.vo.sysarea.SysAreaVO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* @author ljh
* @version 1.0
* Create by 2022/10/25 10:36
*/
@Data
public class ReceiveAddressInfoVO implements Serializable {
private static final long serialVersionUID = -4835574485358136057L;
/**
* 主键id
*/
private Long id;
/**
* 会员id
*/
@ApiModelProperty(value = "会员id")
@Excel(name = "会员id")
@NotNull(message = "会员id为空", groups = {Insert.class, Update.class})
private Long patientId;
/**
* 微信openid
*/
@ApiModelProperty(value = "微信openid")
@Excel(name = "微信openid")
private String openid;
/**
* 微信unionid
*/
@ApiModelProperty(value = "微信unionid")
@Excel(name = "微信unionid")
private String unionid;
/**
* 收货人名称
*/
@ApiModelProperty(value = "收货人名称")
@Excel(name = "收货人名称")
@NotBlank(message = "收货人名称为空", groups = {Insert.class, Update.class})
@Length(max = 30, message = "收货人名称不能超过30位", groups = {Insert.class, Update.class})
private String receiveName;
/**
* 联系电话
*/
@ApiModelProperty(value = "联系电话")
@Excel(name = "联系电话")
@NotBlank(message = "联系电话不能为空", groups = {Insert.class, Update.class})
@Length(max = 11, message = "联系电话不能超过11位", groups = {Insert.class, Update.class})
private String receivePhone;
/**
* 收货人地址
*/
@ApiModelProperty(value = "收货人地址")
@Excel(name = "收货人地址")
@NotBlank(message = "收货人地址不能为空", groups = {Insert.class, Update.class})
@Length(max = 50, message = "收货人地址不能超过50位", groups = {Insert.class, Update.class})
private String receiveAddress;
/**
* 区域编码
*/
@ApiModelProperty(value = "区域编码")
@Excel(name = "区域编码")
@Length(max = 20, message = "区域编码不能超过20位", groups = {Insert.class, Update.class})
private String areaCode;
/**
* 区域集合
*/
List<SysAreaVO> sysAreaVOList;
/**
* 省名称
*/
private String provinceName;
/**
* 省区域编码
*/
private String provinceCode;
/**
* 市名称
*/
private String cityName;
/**
* 市区域编码
*/
private String cityCode;
/**
* 区域名称
*/
private String regionName;
/**
* 区区域编码
*/
private String regionCode;
/**
* 街道名称
*/
private String streetName;
/**
* 街道区域编码
*/
private String streetCode;
/**
* 区域名称
*/
private String areaName;
/**
* 默认收货地址标识01
*/
private Integer defaultAddressFlag;
}

View File

@ -0,0 +1,311 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinelu.manage.mapper.goodsOrderDetails.GoodsOrderDetailsMapper">
<resultMap type="GoodsOrderDetails" id="GoodsOrderDetailsResult">
<result property="id" column="id"/>
<result property="goodsOrderId" column="goods_order_id"/>
<result property="orderNo" column="order_no"/>
<result property="goodsName" column="goods_name"/>
<result property="goodsCount" column="goods_count"/>
<result property="goodsAttributeName" column="goods_attribute_name"/>
<result property="goodsAttributeContent" column="goods_attribute_content"/>
<result property="goodsPrice" column="goods_price"/>
<result property="totalPrice" column="total_price"/>
<result property="discountPrice" column="discount_price"/>
<result property="transportPrice" column="transport_price"/>
<result property="giveIntegral" column="give_integral"/>
<result property="delFlag" column="del_flag"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="couponId" column="coupon_id"/>
<result property="integralDeductionCount" column="integral_deduction_count"/>
<result property="integralDeductionPrice" column="integral_deduction_price"/>
<result property="couponTitle" column="coupon_title"/>
<result property="integralExchangeSill" column="integral_exchange_sill"/>
<result property="integralExchangeCount" column="integral_exchange_count"/>
</resultMap>
<sql id="selectGoodsOrderDetailsVo">
select id,
goods_order_id,
order_no,
goods_name,
goods_count,
goods_attribute_name,
goods_attribute_content,
goods_price,
total_price,
discount_price,
transport_price,
give_integral,
del_flag,
create_by,
create_time,
update_by,
update_time,
coupon_id,
integral_deduction_count,
integral_deduction_price,
couponTitle,
integral_exchange_sill,
integral_exchange_count
from goods_order_details
</sql>
<select id="selectGoodsOrderDetailsList" parameterType="GoodsOrderDetails" resultMap="GoodsOrderDetailsResult">
<include refid="selectGoodsOrderDetailsVo"/>
<where>
<if test="goodsOrderId != null ">
and goods_order_id = #{goodsOrderId}
</if>
<if test="orderNo != null and orderNo != ''">
and order_no = #{orderNo}
</if>
<if test="goodsName != null and goodsName != ''">
and goods_name like concat('%', #{goodsName}, '%')
</if>
<if test="goodsCount != null ">
and goods_count = #{goodsCount}
</if>
<if test="goodsAttributeName != null and goodsAttributeName != ''">
and goods_attribute_name like concat('%', #{goodsAttributeName}, '%')
</if>
<if test="goodsAttributeContent != null and goodsAttributeContent != ''">
and goods_attribute_content = #{goodsAttributeContent}
</if>
<if test="goodsPrice != null ">
and goods_price = #{goodsPrice}
</if>
<if test="totalPrice != null ">
and total_price = #{totalPrice}
</if>
<if test="discountPrice != null ">
and discount_price = #{discountPrice}
</if>
<if test="transportPrice != null ">
and transport_price = #{transportPrice}
</if>
<if test="giveIntegral != null ">
and give_integral = #{giveIntegral}
</if>
<if test="couponId != null ">
and coupon_id = #{couponId}
</if>
<if test="integralDeductionCount != null ">
and integral_deduction_count = #{integralDeductionCount}
</if>
<if test="integralDeductionPrice != null ">
and integral_deduction_price = #{integralDeductionPrice}
</if>
</where>
</select>
<select id="selectGoodsOrderDetailsById" parameterType="Long"
resultMap="GoodsOrderDetailsResult">
<include refid="selectGoodsOrderDetailsVo"/>
where id = #{id}
</select>
<insert id="insertGoodsOrderDetails" parameterType="GoodsOrderDetails" useGeneratedKeys="true"
keyProperty="id">
insert into goods_order_details
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="goodsOrderId != null">goods_order_id,
</if>
<if test="goodsAttributeId != null">goods_attribute_id,
</if>
<if test="goodsAttributeDetailsId != null">goods_attribute_details_id,
</if>
<if test="orderNo != null">order_no,
</if>
<if test="goodsName != null">goods_name,
</if>
<if test="goodsCount != null">goods_count,
</if>
<if test="goodsAttributeName != null">goods_attribute_name,
</if>
<if test="goodsAttributeContent != null">goods_attribute_content,
</if>
<if test="goodsPrice != null">goods_price,
</if>
<if test="totalPrice != null">total_price,
</if>
<if test="discountPrice != null">discount_price,
</if>
<if test="transportPrice != null">transport_price,
</if>
<if test="giveIntegral != null">give_integral,
</if>
<if test="delFlag != null">del_flag,
</if>
<if test="createBy != null">create_by,
</if>
<if test="createTime != null">create_time,
</if>
<if test="updateBy != null">update_by,
</if>
<if test="updateTime != null">update_time,
</if>
<if test="couponId != null">coupon_id,
</if>
<if test="integralDeductionCount != null">integral_deduction_count,
</if>
<if test="integralDeductionPrice != null">integral_deduction_price,
</if>
<if test="couponTitle != null">coupon_title,
</if>
<if test="integralExchangeSill != null">integral_exchange_sill,
</if>
<if test="integralExchangeCount != null">integral_exchange_count,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="goodsOrderId != null">#{goodsOrderId},
</if>
<if test="goodsAttributeId != null">#{goodsAttributeId},
</if>
<if test="goodsAttributeDetailsId != null">#{goodsAttributeDetailsId},
</if>
<if test="orderNo != null">#{orderNo},
</if>
<if test="goodsName != null">#{goodsName},
</if>
<if test="goodsCount != null">#{goodsCount},
</if>
<if test="goodsAttributeName != null">#{goodsAttributeName},
</if>
<if test="goodsAttributeContent != null">#{goodsAttributeContent},
</if>
<if test="goodsPrice != null">#{goodsPrice},
</if>
<if test="totalPrice != null">#{totalPrice},
</if>
<if test="discountPrice != null">#{discountPrice},
</if>
<if test="transportPrice != null">#{transportPrice},
</if>
<if test="giveIntegral != null">#{giveIntegral},
</if>
<if test="delFlag != null">#{delFlag},
</if>
<if test="createBy != null">#{createBy},
</if>
<if test="createTime != null">#{createTime},
</if>
<if test="updateBy != null">#{updateBy},
</if>
<if test="updateTime != null">#{updateTime},
</if>
<if test="couponId != null">#{couponId},
</if>
<if test="integralDeductionCount != null">#{integralDeductionCount},
</if>
<if test="integralDeductionPrice != null">#{integralDeductionPrice},
</if>
<if test="couponTitle != null">#{couponTitle},
</if>
<if test="integralExchangeSill != null">#{integralExchangeSill},
</if>
<if test="integralExchangeCount != null">#{integralExchangeCount},
</if>
</trim>
</insert>
<update id="updateGoodsOrderDetails" parameterType="GoodsOrderDetails">
update goods_order_details
<trim prefix="SET" suffixOverrides=",">
<if test="goodsOrderId != null">goods_order_id =
#{goodsOrderId},
</if>
<if test="orderNo != null">order_no =
#{orderNo},
</if>
<if test="goodsName != null">goods_name =
#{goodsName},
</if>
<if test="goodsCount != null">goods_count =
#{goodsCount},
</if>
<if test="goodsAttributeName != null">goods_attribute_name =
#{goodsAttributeName},
</if>
<if test="goodsAttributeContent != null">goods_attribute_content =
#{goodsAttributeContent},
</if>
<if test="goodsPrice != null">goods_price =
#{goodsPrice},
</if>
<if test="totalPrice != null">total_price =
#{totalPrice},
</if>
<if test="discountPrice != null">discount_price =
#{discountPrice},
</if>
<if test="transportPrice != null">transport_price =
#{transportPrice},
</if>
<if test="giveIntegral != null">give_integral =
#{giveIntegral},
</if>
<if test="delFlag != null">del_flag =
#{delFlag},
</if>
<if test="createBy != null">create_by =
#{createBy},
</if>
<if test="createTime != null">create_time =
#{createTime},
</if>
<if test="updateBy != null">update_by =
#{updateBy},
</if>
<if test="updateTime != null">update_time =
#{updateTime},
</if>
<if test="couponId != null">coupon_id =
#{couponId},
</if>
<if test="integralDeductionCount != null">integral_deduction_count =
#{integralDeductionCount},
</if>
<if test="integralDeductionPrice != null">integral_deduction_price =
#{integralDeductionPrice},
</if>
<if test="couponTitle != null">coupon_title =
#{couponTitle},
</if>
<if test="integralExchangeSill != null">integral_exchange_sill =
#{integralExchangeSill},
</if>
<if test="integralExchangeCount != null">integral_exchange_count =
#{integralExchangeCount},
</if>
</trim>
where id = #{id}
</update>
<delete id="deleteGoodsOrderDetailsById" parameterType="Long">
delete
from goods_order_details
where id = #{id}
</delete>
<delete id="deleteGoodsOrderDetailsByIds" parameterType="String">
delete from goods_order_details where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<select id="getGoodsOrderDetailInfo" resultType="goodsOrderDetails">
select order_no, goods_attribute_details_id, goods_count
FROM goods_order_details
WHERE order_no = #{orderNo}
AND goods_attribute_details_id = #{goodsOrderDetailId}
</select>
</mapper>

View File

@ -0,0 +1,366 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinelu.manage.mapper.patientcouponreceive.PatientCouponReceiveMapper">
<resultMap type="PatientCouponReceive" id="PatientCouponReceiveResult">
<result property="id" column="id"/>
<result property="patientId" column="patient_id"/>
<result property="couponId" column="coupon_id"/>
<result property="receiveSource" column="receive_source"/>
<result property="expirationStartTime" column="expiration_start_time"/>
<result property="expirationEndTime" column="expiration_end_time"/>
<result property="receiveTime" column="receive_time"/>
<result property="useStatus" column="use_status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="couponTitle" column="coupon_title"/>
<result property="couponPrice" column="coupon_price"/>
<result property="couponConsumePrice" column="coupon_consume_price"/>
<result property="couponReductionDays" column="coupon_reduction_days"/>
<result property="couponDescription" column="coupon_description"/>
</resultMap>
<sql id="selectPatientCouponReceiveVo">
select id,
patient_id,
coupon_id,
receive_source,
expiration_start_time,
expiration_end_time,
receive_time,
use_status,
create_by,
create_time,
update_by,
update_time,
coupon_title,
coupon_price,
coupon_consume_price,
coupon_description,
coupon_reduction_days
from patient_coupon_receive
</sql>
<select id="selectPatientCouponReceiveList" parameterType="PatientCouponReceive"
resultMap="PatientCouponReceiveResult">
<include refid="selectPatientCouponReceiveVo"/>
<where>
<if test="patientId != null ">
and patient_id = #{patientId}
</if>
<if test="couponId != null ">
and coupon_id = #{couponId}
</if>
<if test="receiveSource != null and receiveSource != ''">
and receive_source = #{receiveSource}
</if>
<if test="expirationStartTime != null ">
and expiration_start_time = #{expirationStartTime}
</if>
<if test="expirationEndTime != null ">
and expiration_end_time = #{expirationEndTime}
</if>
<if test="receiveTime != null ">
and receive_time = #{receiveTime}
</if>
<if test="useStatus != null and useStatus != ''">
and use_status = #{useStatus}
</if>
<if test="couponTitle != null and couponTitle != ''">
and coupon_title = #{couponTitle}
</if>
<if test="couponPrice != null ">
and coupon_price = #{couponPrice}
</if>
<if test="couponConsumePrice != null ">
and coupon_consume_price = #{couponConsumePrice}
</if>
<if test="couponDescription != null and couponDescription != ''">
and coupon_description = #{couponDescription}
</if>
</where>
</select>
<select id="selectPatientCouponReceiveById" parameterType="Long"
resultMap="PatientCouponReceiveResult">
<include refid="selectPatientCouponReceiveVo"/>
where id = #{id}
</select>
<insert id="insertPatientCouponReceive" parameterType="PatientCouponReceive" useGeneratedKeys="true"
keyProperty="id">
insert into patient_coupon_receive
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="patientId != null">patient_id,
</if>
<if test="couponId != null">coupon_id,
</if>
<if test="receiveSource != null">receive_source,
</if>
<if test="expirationStartTime != null">expiration_start_time,
</if>
<if test="expirationEndTime != null">expiration_end_time,
</if>
<if test="receiveTime != null">receive_time,
</if>
<if test="useStatus != null">use_status,
</if>
<if test="createBy != null">create_by,
</if>
<if test="createTime != null">create_time,
</if>
<if test="updateBy != null">update_by,
</if>
<if test="updateTime != null">update_time,
</if>
<if test="couponTitle != null">coupon_title,
</if>
<if test="couponPrice != null">coupon_price,
</if>
<if test="couponConsumePrice != null">coupon_consume_price,
</if>
<if test="couponDescription != null">coupon_description,
</if>
<if test="couponReductionDays != null">coupon_reduction_days,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="patientId != null">#{patientId},
</if>
<if test="couponId != null">#{couponId},
</if>
<if test="receiveSource != null">#{receiveSource},
</if>
<if test="expirationStartTime != null">#{expirationStartTime},
</if>
<if test="expirationEndTime != null">#{expirationEndTime},
</if>
<if test="receiveTime != null">#{receiveTime},
</if>
<if test="useStatus != null">#{useStatus},
</if>
<if test="createBy != null">#{createBy},
</if>
<if test="createTime != null">#{createTime},
</if>
<if test="updateBy != null">#{updateBy},
</if>
<if test="updateTime != null">#{updateTime},
</if>
<if test="couponTitle != null">#{couponTitle},
</if>
<if test="couponPrice != null">#{couponPrice},
</if>
<if test="couponConsumePrice != null">#{couponConsumePrice},
</if>
<if test="couponDescription != null">#{couponDescription},
</if>
<if test="couponReductionDays != null">#{couponReductionDays},
</if>
</trim>
</insert>
<update id="updatePatientCouponReceive" parameterType="PatientCouponReceive">
update patient_coupon_receive
<trim prefix="SET" suffixOverrides=",">
<if test="patientId != null">patient_id =
#{patientId},
</if>
<if test="couponId != null">coupon_id =
#{couponId},
</if>
<if test="receiveSource != null">receive_source =
#{receiveSource},
</if>
<if test="expirationStartTime != null">expiration_start_time =
#{expirationStartTime},
</if>
<if test="expirationEndTime != null">expiration_end_time =
#{expirationEndTime},
</if>
<if test="receiveTime != null">receive_time =
#{receiveTime},
</if>
<if test="useStatus != null">use_status =
#{useStatus},
</if>
<if test="createBy != null">create_by =
#{createBy},
</if>
<if test="createTime != null">create_time =
#{createTime},
</if>
<if test="updateBy != null">update_by =
#{updateBy},
</if>
<if test="updateTime != null">update_time =
#{updateTime},
</if>
<if test="couponTitle != null">coupon_title =
#{couponTitle},
</if>
<if test="couponPrice != null">coupon_price =
#{couponPrice},
</if>
<if test="couponConsumePrice != null">coupon_consume_price =
#{couponConsumePrice},
</if>
<if test="couponDescription != null">coupon_description =
#{couponDescription},
</if>
<if test="couponReductionDays != null">coupon_reduction_days =
#{couponReductionDays},
</if>
</trim>
where id = #{id}
</update>
<delete id="deletePatientCouponReceiveById" parameterType="Long">
delete
from patient_coupon_receive
where id = #{id}
</delete>
<delete id="deletePatientCouponReceiveByIds" parameterType="String">
delete from patient_coupon_receive where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<insert id="insertBatchPatientReceive" parameterType="java.util.List">
insert into patient_coupon_receive(
patient_id,
coupon_id,
receive_source,
expiration_start_time,
expiration_end_time,
receive_time,
use_status,
create_time,
coupon_title,
coupon_price,
coupon_consume_price,
coupon_description,
coupon_reduction_days
) values
<foreach item="couponReceive" index="index" collection="couponReceiveList" separator=",">
(
#{couponReceive.patientId},
#{couponReceive.couponId},
#{couponReceive.receiveSource},
#{couponReceive.expirationStartTime},
#{couponReceive.expirationEndTime},
#{couponReceive.receiveTime},
#{couponReceive.useStatus},
#{couponReceive.createTime},
#{couponReceive.couponTitle},
#{couponReceive.couponPrice},
#{couponReceive.couponConsumePrice},
#{couponReceive.couponDescription},
#{couponReceive.couponReductionDays}
)
</foreach>
</insert>
<select id="getPatientCouponExpirationEndTime"
resultMap="PatientCouponReceiveResult">
select id,
patient_id,
coupon_id,
receive_source,
expiration_start_time,
expiration_end_time,
receive_time,
use_status,
create_by,
create_time,
update_by,
update_time,
coupon_title,
coupon_price,
coupon_consume_price,
coupon_description,
coupon_reduction_days
from patient_coupon_receive
<where>
<if test="expirationEndTime != null ">
and expiration_end_time &lt;= #{expirationEndTime} and use_status &lt;&gt; #{couponUseStatus}
</if>
</where>
</select>
<update id="updateCouponReceiveStatus">
update patient_coupon_receive set use_status = #{couponUseStatus}, update_time = now()
where id in
<foreach item="id" collection="idList" open="(" separator="," close=")">
#{id}
</foreach>
</update>
<update id="updateCouponReceiveStatusList">
update patient_coupon_receive set use_status = #{couponUseStatus}, update_time = now()
<where>
id in
<foreach item="id" collection="idList" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</update>
<select id="getPatientCouponInfo" resultType="com.xinelu.manage.vo.patientcouponreceive.PatientCouponReceiveVO">
SELECT pcr.id,
pcr.patient_id,
pcr.coupon_id,
pcr.receive_source,
pcr.expiration_start_time,
pcr.expiration_end_time,
pcr.receive_time,
pcr.use_status,
cp.coupon_price,
IFNULL(cp.coupon_title, '') coupon_title,
cp.coupon_consume_price
FROM patient_coupon_receive pcr
INNER JOIN coupon cp ON pcr.coupon_id = cp.id
WHERE patient_id = #{patientId}
and coupon_id = #{couponId}
</select>
<update id="updatePatientCouponUseStatus">
update patient_coupon_receive
set use_status = #{useStatus},
update_time = now()
where patient_id = #{patientId}
and coupon_id = #{couponId}
and use_status &lt;&gt; #{useStatus}
</update>
<select id="selectPatientCouponReceive"
resultType="com.xinelu.manage.vo.patientcouponreceive.PatientCouponReceiveInfoVO">
select pcr.id,
pcr.patient_id,
pcr.coupon_id,
pcr.receive_source,
pcr.expiration_start_time,
pcr.expiration_end_time,
pcr.receive_time,
pcr.use_status,
pcr.create_by,
pcr.create_time,
pcr.update_by,
pcr.update_time,
pcr.coupon_title,
pcr.coupon_price,
pcr.coupon_consume_price,
pcr.coupon_description,
pcr.coupon_reduction_days,
(SELECT coupon_type FROM coupon where id = #{couponId}) coupon_type
from patient_coupon_receive pcr
where pcr.patient_id = #{patientId}
and pcr.coupon_id = #{couponId}
</select>
</mapper>

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinelu.manage.mapper.patientintegralchange.PatientIntegralChangeMapper">
<resultMap type="PatientIntegralChange" id="PatientIntegralChangeResult">
<result property="id" column="id"/>
<result property="patientId" column="patient_id"/>
<result property="originalIntegral" column="original_integral"/>
<result property="changeIntegral" column="change_integral"/>
<result property="changeTime" column="change_time"/>
<result property="changeType" column="change_type"/>
<result property="changeRemark" column="change_remark"/>
<result property="changeIntegralChannel" column="change_integral_channel"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<sql id="selectPatientIntegralChangeVo">
select id, patient_id, original_integral, change_integral, change_time, change_type, change_remark,change_integral_channel, create_by, create_time, update_by, update_time from patient_integral_change
</sql>
<select id="selectPatientIntegralChangeList" parameterType="PatientIntegralChange"
resultMap="PatientIntegralChangeResult">
<include refid="selectPatientIntegralChangeVo"/>
<where>
<if test="patientId != null ">
and patient_id = #{patientId}
</if>
<if test="originalIntegral != null ">
and original_integral = #{originalIntegral}
</if>
<if test="changeIntegral != null ">
and change_integral = #{changeIntegral}
</if>
<if test="changeTime != null ">
and change_time = #{changeTime}
</if>
<if test="changeType != null and changeType != ''">
and change_type = #{changeType}
</if>
<if test="changeRemark != null and changeRemark != ''">
and change_remark = #{changeRemark}
</if>
</where>
</select>
<select id="selectPatientIntegralChangeById" parameterType="Long"
resultMap="PatientIntegralChangeResult">
<include refid="selectPatientIntegralChangeVo"/>
where id = #{id}
</select>
<insert id="insertPatientIntegralChange" parameterType="PatientIntegralChange" useGeneratedKeys="true"
keyProperty="id">
insert into patient_integral_change
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="patientId != null">patient_id,
</if>
<if test="originalIntegral != null">original_integral,
</if>
<if test="changeIntegral != null">change_integral,
</if>
<if test="changeTime != null">change_time,
</if>
<if test="changeType != null">change_type,
</if>
<if test="changeRemark != null">change_remark,
</if>
<if test="changeIntegralChannel != null">change_integral_channel,
</if>
<if test="createBy != null">create_by,
</if>
<if test="createTime != null">create_time,
</if>
<if test="updateBy != null">update_by,
</if>
<if test="updateTime != null">update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="patientId != null">#{patientId},
</if>
<if test="originalIntegral != null">#{originalIntegral},
</if>
<if test="changeIntegral != null">#{changeIntegral},
</if>
<if test="changeTime != null">#{changeTime},
</if>
<if test="changeType != null">#{changeType},
</if>
<if test="changeRemark != null">#{changeRemark},
</if>
<if test="changeIntegralChannel != null">#{changeIntegralChannel},
</if>
<if test="createBy != null">#{createBy},
</if>
<if test="createTime != null">#{createTime},
</if>
<if test="updateBy != null">#{updateBy},
</if>
<if test="updateTime != null">#{updateTime},
</if>
</trim>
</insert>
<update id="updatePatientIntegralChange" parameterType="PatientIntegralChange">
update patient_integral_change
<trim prefix="SET" suffixOverrides=",">
<if test="patientId != null">patient_id =
#{patientId},
</if>
<if test="originalIntegral != null">original_integral =
#{originalIntegral},
</if>
<if test="changeIntegral != null">change_integral =
#{changeIntegral},
</if>
<if test="changeTime != null">change_time =
#{changeTime},
</if>
<if test="changeType != null">change_type =
#{changeType},
</if>
<if test="changeRemark != null">change_remark =
#{changeRemark},
</if>
<if test="changeIntegralChannel != null">change_integral_channel =
#{changeIntegralChannel},
</if>
<if test="createBy != null">create_by =
#{createBy},
</if>
<if test="createTime != null">create_time =
#{createTime},
</if>
<if test="updateBy != null">update_by =
#{updateBy},
</if>
<if test="updateTime != null">update_time =
#{updateTime},
</if>
</trim>
where id = #{id}
</update>
<delete id="deletePatientIntegralChangeById" parameterType="Long">
delete from patient_integral_change where id = #{id}
</delete>
<delete id="deletePatientIntegralChangeByIds" parameterType="String">
delete from patient_integral_change where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinelu.manage.mapper.patientsignininfo.PatientSignInInfoMapper">
<resultMap type="PatientSignInInfo" id="PatientSignInInfoResult">
<result property="id" column="id"/>
<result property="patientId" column="patient_id"/>
<result property="signInTime" column="sign_in_time"/>
<result property="signInChannel" column="sign_in_channel"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<sql id="selectPatientSignInInfoVo">
select id, patient_id, sign_in_time, sign_in_channel, create_by, create_time, update_by, update_time from patient_sign_in_info
</sql>
<select id="selectPatientSignInInfoList" parameterType="PatientSignInInfo" resultMap="PatientSignInInfoResult">
<include refid="selectPatientSignInInfoVo"/>
<where>
<if test="patientId != null ">
and patient_id = #{patientId}
</if>
<if test="signInTime != null ">
and sign_in_time = #{signInTime}
</if>
<if test="signInChannel != null and signInChannel != ''">
and sign_in_channel = #{signInChannel}
</if>
</where>
</select>
<select id="selectPatientSignInInfoById" parameterType="Long"
resultMap="PatientSignInInfoResult">
<include refid="selectPatientSignInInfoVo"/>
where id = #{id}
</select>
<insert id="insertPatientSignInInfo" parameterType="PatientSignInInfo">
insert into patient_sign_in_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">id,
</if>
<if test="patientId != null">patient_id,
</if>
<if test="signInTime != null">sign_in_time,
</if>
<if test="signInChannel != null">sign_in_channel,
</if>
<if test="createBy != null">create_by,
</if>
<if test="createTime != null">create_time,
</if>
<if test="updateBy != null">update_by,
</if>
<if test="updateTime != null">update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},
</if>
<if test="patientId != null">#{patientId},
</if>
<if test="signInTime != null">#{signInTime},
</if>
<if test="signInChannel != null">#{signInChannel},
</if>
<if test="createBy != null">#{createBy},
</if>
<if test="createTime != null">#{createTime},
</if>
<if test="updateBy != null">#{updateBy},
</if>
<if test="updateTime != null">#{updateTime},
</if>
</trim>
</insert>
<update id="updatePatientSignInInfo" parameterType="PatientSignInInfo">
update patient_sign_in_info
<trim prefix="SET" suffixOverrides=",">
<if test="patientId != null">patient_id =
#{patientId},
</if>
<if test="signInTime != null">sign_in_time =
#{signInTime},
</if>
<if test="signInChannel != null">sign_in_channel =
#{signInChannel},
</if>
<if test="createBy != null">create_by =
#{createBy},
</if>
<if test="createTime != null">create_time =
#{createTime},
</if>
<if test="updateBy != null">update_by =
#{updateBy},
</if>
<if test="updateTime != null">update_time =
#{updateTime},
</if>
</trim>
where id = #{id}
</update>
<delete id="deletePatientSignInInfoById" parameterType="Long">
delete from patient_sign_in_info where id = #{id}
</delete>
<delete id="deletePatientSignInInfoByIds" parameterType="String">
delete from patient_sign_in_info where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<select id="getPatientSignInInfoCountByDate" resultType="int">
select count(1) from patient_sign_in_info where patient_id = #{patientId} and sign_in_time = #{signInTime}
</select>
</mapper>

View File

@ -0,0 +1,200 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinelu.manage.mapper.receiveAddressInfo.ReceiveAddressInfoMapper">
<resultMap type="ReceiveAddressInfo" id="ReceiveAddressInfoResult">
<result property="id" column="id"/>
<result property="patientId" column="patient_id"/>
<result property="openid" column="openid"/>
<result property="unionid" column="unionid"/>
<result property="receiveName" column="receive_name"/>
<result property="receivePhone" column="receive_phone"/>
<result property="receiveAddress" column="receive_address"/>
<result property="areaCode" column="area_code"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="defaultAddressFlag" column="default_address_flag"/>
</resultMap>
<sql id="selectReceiveAddressInfoVo">
select id,
patient_id,
openid,
unionid,
receive_name,
receive_phone,
receive_address,
area_code,
create_by,
create_time,
update_by,
update_time,
default_address_flag
from receive_address_info
</sql>
<select id="selectReceiveAddressInfoList" parameterType="ReceiveAddressInfo" resultMap="ReceiveAddressInfoResult">
<include refid="selectReceiveAddressInfoVo"/>
<where>
<if test="patientId != null ">
and patient_id = #{patientId}
</if>
<if test="openid != null and openid != ''">
and openid = #{openid}
</if>
<if test="unionid != null and unionid != ''">
and unionid = #{unionid}
</if>
<if test="receiveName != null and receiveName != ''">
and receive_name like concat('%', #{receiveName}, '%')
</if>
<if test="receivePhone != null and receivePhone != ''">
and receive_phone = #{receivePhone}
</if>
<if test="receiveAddress != null and receiveAddress != ''">
and receive_address = #{receiveAddress}
</if>
<if test="areaCode != null and areaCode != ''">
and area_code = #{areaCode}
</if>
</where>
</select>
<select id="selectReceiveAddressInfoById" parameterType="Long"
resultMap="ReceiveAddressInfoResult">
<include refid="selectReceiveAddressInfoVo"/>
where id = #{id}
</select>
<insert id="insertReceiveAddressInfo" parameterType="ReceiveAddressInfo">
insert into receive_address_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">id,
</if>
<if test="patientId != null">patient_id,
</if>
<if test="openid != null">openid,
</if>
<if test="unionid != null">unionid,
</if>
<if test="receiveName != null">receive_name,
</if>
<if test="receivePhone != null">receive_phone,
</if>
<if test="receiveAddress != null">receive_address,
</if>
<if test="areaCode != null">area_code,
</if>
<if test="createBy != null">create_by,
</if>
<if test="createTime != null">create_time,
</if>
<if test="updateBy != null">update_by,
</if>
<if test="updateTime != null">update_time,
</if>
<if test="defaultAddressFlag != null">default_address_flag,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},
</if>
<if test="patientId != null">#{patientId},
</if>
<if test="openid != null">#{openid},
</if>
<if test="unionid != null">#{unionid},
</if>
<if test="receiveName != null">#{receiveName},
</if>
<if test="receivePhone != null">#{receivePhone},
</if>
<if test="receiveAddress != null">#{receiveAddress},
</if>
<if test="areaCode != null">#{areaCode},
</if>
<if test="createBy != null">#{createBy},
</if>
<if test="createTime != null">#{createTime},
</if>
<if test="updateBy != null">#{updateBy},
</if>
<if test="updateTime != null">#{updateTime},
</if>
<if test="defaultAddressFlag != null">#{defaultAddressFlag},
</if>
</trim>
</insert>
<update id="updateReceiveAddressInfo" parameterType="ReceiveAddressInfo">
update receive_address_info
<trim prefix="SET" suffixOverrides=",">
<if test="patientId != null">patient_id =
#{patientId},
</if>
<if test="openid != null">openid =
#{openid},
</if>
<if test="unionid != null">unionid =
#{unionid},
</if>
<if test="receiveName != null">receive_name =
#{receiveName},
</if>
<if test="receivePhone != null">receive_phone =
#{receivePhone},
</if>
<if test="receiveAddress != null">receive_address =
#{receiveAddress},
</if>
<if test="areaCode != null">area_code =
#{areaCode},
</if>
<if test="createBy != null">create_by =
#{createBy},
</if>
<if test="createTime != null">create_time =
#{createTime},
</if>
<if test="updateBy != null">update_by =
#{updateBy},
</if>
<if test="updateTime != null">update_time =
#{updateTime},
</if>
<if test="defaultAddressFlag != null">default_address_flag =
#{defaultAddressFlag},
</if>
</trim>
where id = #{id}
</update>
<delete id="deleteReceiveAddressInfoById" parameterType="Long">
delete
from receive_address_info
where id = #{id}
</delete>
<delete id="deleteReceiveAddressInfoByIds" parameterType="String">
delete from receive_address_info where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<select id="getReceiveAddressInfo" resultType="int">
SELECT
count(1) as receiveCount
FROM
receive_address_info
WHERE
patient_id = #{patientId}
AND receive_name = #{receiveName}
AND receive_phone = #{receivePhone}
AND receive_address = #{receiveAddress}
</select>
</mapper>

View File

@ -0,0 +1,307 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinelu.manage.mapper.subscribemessagerecord.SubscribeMessageRecordMapper">
<resultMap type="SubscribeMessageRecord" id="SubscribeMessageRecordResult">
<result property="id" column="id"/>
<result property="patientId" column="patient_id"/>
<result property="unionid" column="unionid"/>
<result property="openid" column="openid"/>
<result property="templateId" column="template_id"/>
<result property="messageType" column="message_type"/>
<result property="subscribeCount" column="subscribe_count"/>
<result property="subscribeTime" column="subscribe_time"/>
<result property="appletId" column="applet_id"/>
<result property="subscribeStatus" column="subscribe_status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<sql id="selectSubscribeMessageRecordVo">
select id,
patient_id,
unionid,
openid,
template_id,
message_type,
subscribe_count,
subscribe_time,
applet_id,
subscribe_status,
create_by,
create_time,
update_by,
update_time
from subscribe_message_record
</sql>
<select id="selectSubscribeMessageRecordList" parameterType="SubscribeMessageRecord"
resultType="SubscribeMessageRecord">
<include refid="selectSubscribeMessageRecordVo"/>
<where>
<if test="patientId != null ">
and patient_id = #{patientId}
</if>
<if test="unionid != null and unionid != ''">
and unionid = #{unionid}
</if>
<if test="openid != null and openid != ''">
and openid = #{openid}
</if>
<if test="templateId != null and templateId != ''">
and template_id = #{templateId}
</if>
<if test="messageType != null and messageType != ''">
and message_type = #{messageType}
</if>
<if test="subscribeCount != null ">
and subscribe_count = #{subscribeCount}
</if>
<if test="subscribeTime != null ">
and subscribe_time = #{subscribeTime}
</if>
</where>
GROUP BY openid,template_id
</select>
<select id="selectSubscribeMessageRecordById" parameterType="Long"
resultMap="SubscribeMessageRecordResult">
<include refid="selectSubscribeMessageRecordVo"/>
where id = #{id}
</select>
<insert id="insertSubscribeMessageRecord"
parameterType="SubscribeMessageRecord"
useGeneratedKeys="true"
keyProperty="id">
insert into subscribe_message_record
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="patientId != null">patient_id,
</if>
<if test="unionid != null">unionid,
</if>
<if test="openid != null">openid,
</if>
<if test="templateId != null">template_id,
</if>
<if test="messageType != null">message_type,
</if>
<if test="subscribeCount != null">subscribe_count,
</if>
<if test="subscribeTime != null">subscribe_time,
</if>
<if test="appletId != null">applet_id,
</if>
<if test="subscribeStatus != null">subscribe_status,
</if>
<if test="createBy != null">create_by,
</if>
<if test="createTime != null">create_time,
</if>
<if test="updateBy != null">update_by,
</if>
<if test="updateTime != null">update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="patientId != null">#{patientId},
</if>
<if test="unionid != null">#{unionid},
</if>
<if test="openid != null">#{openid},
</if>
<if test="templateId != null">#{templateId},
</if>
<if test="messageType != null">#{messageType},
</if>
<if test="subscribeCount != null">#{subscribeCount},
</if>
<if test="subscribeTime != null">#{subscribeTime},
</if>
<if test="appletId != null">#{appletId},
</if>
<if test="subscribeStatus != null">#{subscribeStatus},
</if>
<if test="createBy != null">#{createBy},
</if>
<if test="createTime != null">#{createTime},
</if>
<if test="updateBy != null">#{updateBy},
</if>
<if test="updateTime != null">#{updateTime},
</if>
</trim>
</insert>
<update id="updateSubscribeMessageRecord"
parameterType="SubscribeMessageRecord">
update subscribe_message_record
<trim prefix="SET" suffixOverrides=",">
<if test="patientId != null">patient_id =
#{patientId},
</if>
<if test="unionid != null">unionid =
#{unionid},
</if>
<if test="openid != null">openid =
#{openid},
</if>
<if test="templateId != null">template_id =
#{templateId},
</if>
<if test="messageType != null">message_type =
#{messageType},
</if>
<if test="subscribeCount != null">subscribe_count =
#{subscribeCount},
</if>
<if test="subscribeTime != null">subscribe_time =
#{subscribeTime},
</if>
<if test="appletId != null">applet_id =
#{appletId},
</if>
<if test="subscribeStatus != null">subscribe_status =
#{subscribeStatus},
</if>
<if test="createBy != null">create_by =
#{createBy},
</if>
<if test="createTime != null">create_time =
#{createTime},
</if>
<if test="updateBy != null">update_by =
#{updateBy},
</if>
<if test="updateTime != null">update_time =
#{updateTime},
</if>
</trim>
where id = #{id}
</update>
<delete id="deleteSubscribeMessageRecordById" parameterType="Long">
delete
from subscribe_message_record
where id = #{id}
</delete>
<delete id="deleteSubscribeMessageRecordByIds" parameterType="String">
delete from subscribe_message_record where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<select id="selectSubscribeMessageRecordByPatientId" parameterType="SubscribeMessageRecord"
resultMap="SubscribeMessageRecordResult">
<include refid="selectSubscribeMessageRecordVo"/>
<where>
<if test="patientId != null ">
and patient_id = #{patientId}
</if>
<if test="openid != null and openid != ''">
and openid = #{openid}
</if>
<if test="templateId != null and templateId != ''">
and template_id = #{templateId}
</if>
</where>
</select>
<select id="selectSubscribeMessageRecordByCount"
resultType="Integer">
select COUNT(1)
from subscribe_message_record
<where>
<if test="patientId != null ">
and patient_id = #{patientId}
</if>
<if test="unionid != null and unionid != ''">
and unionid = #{unionid}
</if>
<if test="openid != null and openid != ''">
and openid = #{openid}
</if>
<if test="templateId != null and templateId != ''">
and template_id = #{templateId}
</if>
<if test="messageType != null and messageType != ''">
and message_type = #{messageType}
</if>
<if test="subscribeCount != null ">
and subscribe_count = #{subscribeCount}
</if>
<if test="subscribeTime != null ">
and subscribe_time = #{subscribeTime}
</if>
</where>
</select>
<select id="selectSubscribeList"
resultType="com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord">
select id,
patient_id,
unionid,
openid,
template_id,
message_type,
subscribe_count,
subscribe_time,
applet_id,
subscribe_status
from subscribe_message_record
where patient_id in
<foreach item="list" collection="list" open="(" separator="," close=")">
#{list}
</foreach>
and subscribe_status =#{subscribeStatus}
and message_type =#{messageType}
</select>
<insert id="insertSubscribeMessageRecordList" parameterType="java.util.List">
insert into subscribe_message_record(
patient_id,
unionid,
openid,
template_id,
message_type,
subscribe_count,
subscribe_time,
applet_id,
subscribe_status,
create_by,
create_time,
update_by,
update_time
) values
<foreach item="subscribeMessageRecordList" index="index" collection="list" separator=",">
(
#{subscribeMessageRecordList.patientId},
#{subscribeMessageRecordList.unionid},
#{subscribeMessageRecordList.openid},
#{subscribeMessageRecordList.templateId},
#{subscribeMessageRecordList.messageType},
#{subscribeMessageRecordList.subscribeCount},
#{subscribeMessageRecordList.subscribeTime},
#{subscribeMessageRecordList.appletId},
#{subscribeMessageRecordList.subscribeStatus},
#{subscribeMessageRecordList.createBy},
#{subscribeMessageRecordList.createTime},
#{subscribeMessageRecordList.updateBy},
#{subscribeMessageRecordList.updateTime}
)
</foreach>
</insert>
<update id="updateSubscribeMessageTemplateId">
update subscribe_message_record
set patient_id = #{patientId}, subscribe_status = #{subscribeStatus}, update_time = now()
where openid = #{openId} and template_id = #{templateId}
</update>
</mapper>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinelu.manage.mapper.subscribemessagesendrecord.SubscribeMessageSendRecordMapper">
<insert id="insertSubscribeMessageSendRecordList" parameterType="java.util.List">
insert into subscribe_message_send_record(
openid,
applet_id,
subscribe_time,
template_id,
msg_id,
message_type,
error_code,
error_status,
create_time
) values
<foreach item="sendRecord" index="index" collection="list" separator=",">
(
#{sendRecord.openid},
#{sendRecord.appletId},
#{sendRecord.subscribeTime},
#{sendRecord.templateId},
#{sendRecord.msgId},
#{sendRecord.messageType},
#{sendRecord.errorCode},
#{sendRecord.errorStatus},
#{sendRecord.createTime}
)
</foreach>
</insert>
</mapper>