diff --git a/pom.xml b/pom.xml index 7049c98..2a9a4d5 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,7 @@ 2.3 0.9.1 1.18.4 + 2.7.1 @@ -220,6 +221,13 @@ xinelu-nurse-applet ${xinelu.version} + + + + org.simpleframework + simple-xml + ${simple-xml.version} + diff --git a/xinelu-common/pom.xml b/xinelu-common/pom.xml index e68911b..8a9c64e 100644 --- a/xinelu-common/pom.xml +++ b/xinelu-common/pom.xml @@ -151,24 +151,23 @@ org.springframework spring-websocket + com.squareup.okio okio 1.12.0 + com.squareup.okhttp okhttp 2.7.5 + com.google.code.gson gson - - javax.xml.bind - jaxb-api - @@ -176,10 +175,16 @@ hutool-all 5.4.7 + org.apache.tomcat.embed tomcat-embed-websocket + + + org.springframework.integration + spring-integration-redis + diff --git a/xinelu-common/src/main/java/com/xinelu/common/enums/BuySourceEnum.java b/xinelu-common/src/main/java/com/xinelu/common/enums/BuySourceEnum.java new file mode 100644 index 0000000..3eb3adb --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/enums/BuySourceEnum.java @@ -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; + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/enums/CouponAndIntegralFlagEnum.java b/xinelu-common/src/main/java/com/xinelu/common/enums/CouponAndIntegralFlagEnum.java new file mode 100644 index 0000000..00e9033 --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/enums/CouponAndIntegralFlagEnum.java @@ -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; + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/enums/CouponReceiveTypeEnum.java b/xinelu-common/src/main/java/com/xinelu/common/enums/CouponReceiveTypeEnum.java new file mode 100644 index 0000000..0d1ec32 --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/enums/CouponReceiveTypeEnum.java @@ -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; + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/enums/CouponTypeEnum.java b/xinelu-common/src/main/java/com/xinelu/common/enums/CouponTypeEnum.java new file mode 100644 index 0000000..ef39342 --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/enums/CouponTypeEnum.java @@ -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; + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/enums/CouponUseStatusEnum.java b/xinelu-common/src/main/java/com/xinelu/common/enums/CouponUseStatusEnum.java new file mode 100644 index 0000000..428829c --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/enums/CouponUseStatusEnum.java @@ -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; + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/enums/GoodsPurposeEnum.java b/xinelu-common/src/main/java/com/xinelu/common/enums/GoodsPurposeEnum.java new file mode 100644 index 0000000..598ba7c --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/enums/GoodsPurposeEnum.java @@ -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; + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/enums/IntegralChangeType.java b/xinelu-common/src/main/java/com/xinelu/common/enums/IntegralChangeType.java new file mode 100644 index 0000000..4583733 --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/enums/IntegralChangeType.java @@ -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; + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/enums/OrderTypeEnum.java b/xinelu-common/src/main/java/com/xinelu/common/enums/OrderTypeEnum.java new file mode 100644 index 0000000..6bccd80 --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/enums/OrderTypeEnum.java @@ -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; + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/enums/SubscribeMessageTypeEnum.java b/xinelu-common/src/main/java/com/xinelu/common/enums/SubscribeMessageTypeEnum.java new file mode 100644 index 0000000..1d0053e --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/enums/SubscribeMessageTypeEnum.java @@ -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; + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/enums/WhetherShelfEnum.java b/xinelu-common/src/main/java/com/xinelu/common/enums/WhetherShelfEnum.java new file mode 100644 index 0000000..aaff1c3 --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/enums/WhetherShelfEnum.java @@ -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; + } + +} + diff --git a/xinelu-common/src/main/java/com/xinelu/common/utils/RedisDistributedLockUtils.java b/xinelu-common/src/main/java/com/xinelu/common/utils/RedisDistributedLockUtils.java new file mode 100644 index 0000000..3dfd73d --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/utils/RedisDistributedLockUtils.java @@ -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); + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/utils/aes/AesException.java b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/AesException.java new file mode 100644 index 0000000..3da46f3 --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/AesException.java @@ -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; + } + +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/utils/aes/ByteGroup.java b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/ByteGroup.java new file mode 100644 index 0000000..1fcacb9 --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/ByteGroup.java @@ -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 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(); + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/utils/aes/PKCS7Encoder.java b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/PKCS7Encoder.java new file mode 100644 index 0000000..86f1920 --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/PKCS7Encoder.java @@ -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; + } + +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/utils/aes/SHA1.java b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/SHA1.java new file mode 100644 index 0000000..7f4d926 --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/SHA1.java @@ -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 + *

+ * + * @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); + } + } +} diff --git a/xinelu-common/src/main/java/com/xinelu/common/utils/aes/WXBizMsgCrypt.java b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/WXBizMsgCrypt.java new file mode 100644 index 0000000..c595c4b --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/WXBizMsgCrypt.java @@ -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; + } + +} \ No newline at end of file diff --git a/xinelu-common/src/main/java/com/xinelu/common/utils/aes/XMLParse.java b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/XMLParse.java new file mode 100644 index 0000000..e2b6ac3 --- /dev/null +++ b/xinelu-common/src/main/java/com/xinelu/common/utils/aes/XMLParse.java @@ -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 = "\n" + "\n" + + "\n" + + "%3$s\n" + "\n" + ""; + return String.format(format, encrypt, signature, timestamp, nonce); + } +} diff --git a/xinelu-framework/src/main/java/com/xinelu/framework/aspectj/MobileRequestAuthorizationAspect.java b/xinelu-framework/src/main/java/com/xinelu/framework/aspectj/MobileRequestAuthorizationAspect.java new file mode 100644 index 0000000..d1ce0be --- /dev/null +++ b/xinelu-framework/src/main/java/com/xinelu/framework/aspectj/MobileRequestAuthorizationAspect.java @@ -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 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); + } + } +} diff --git a/xinelu-framework/src/main/java/com/xinelu/framework/config/AsyncExecutorConfig.java b/xinelu-framework/src/main/java/com/xinelu/framework/config/AsyncExecutorConfig.java new file mode 100644 index 0000000..a8c4058 --- /dev/null +++ b/xinelu-framework/src/main/java/com/xinelu/framework/config/AsyncExecutorConfig.java @@ -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; + } +} diff --git a/xinelu-framework/src/main/java/com/xinelu/framework/config/RedisDistributedLockUtilsConfig.java b/xinelu-framework/src/main/java/com/xinelu/framework/config/RedisDistributedLockUtilsConfig.java new file mode 100644 index 0000000..58e1457 --- /dev/null +++ b/xinelu-framework/src/main/java/com/xinelu/framework/config/RedisDistributedLockUtilsConfig.java @@ -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()); + } +} diff --git a/xinelu-nurse-applet/pom.xml b/xinelu-nurse-applet/pom.xml index 63437ec..7567c88 100644 --- a/xinelu-nurse-applet/pom.xml +++ b/xinelu-nurse-applet/pom.xml @@ -40,5 +40,11 @@ swagger-models 1.6.2 + + + + org.simpleframework + simple-xml + \ No newline at end of file diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/controller/nursingstationgoods/NursingStationGoodsController.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/controller/nursingstationgoods/NursingStationGoodsController.java new file mode 100644 index 0000000..d075c94 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/controller/nursingstationgoods/NursingStationGoodsController.java @@ -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 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 defaultAddressList) { + if (CollectionUtils.isEmpty(defaultAddressList)) { + return AjaxResult.error("请选择要设置的收货地址信息!"); + } + return nursingStationGoodsService.updateDefaultAddress(defaultAddressList); + } +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/controller/patientcenter/PatientCenterController.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/controller/patientcenter/PatientCenterController.java new file mode 100644 index 0000000..556f272 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/controller/patientcenter/PatientCenterController.java @@ -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 + */ + @MobileRequestAuthorization + @GetMapping("/selectCoupon") + public TableDataInfo selectCoupon(@Validated(Insert.class) PatientCenterCouponVO patientCenterCouponVO) { + startPage(); + List list = patientCenterService.selectCouponByUseStatus(patientCenterCouponVO); + return getDataTable(list); + } + + /** + * 个人中心积分兑换-查询可以兑换的商品 + * + * @return List + */ + @MobileRequestAuthorization + @GetMapping("selectExchangeGoods") + public TableDataInfo selectExchangeGoods() { + startPage(); + List 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 + */ + @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()); + } +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/controller/wechatappletcallback/WeChatAppletCallBackController.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/controller/wechatappletcallback/WeChatAppletCallBackController.java new file mode 100644 index 0000000..9c9602e --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/controller/wechatappletcallback/WeChatAppletCallBackController.java @@ -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); + } +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/dto/appletcallback/MessageSignDTO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/dto/appletcallback/MessageSignDTO.java new file mode 100644 index 0000000..f3397e9 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/dto/appletcallback/MessageSignDTO.java @@ -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; +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/dto/patientcenter/PatientCenterCouponDTO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/dto/patientcenter/PatientCenterCouponDTO.java new file mode 100644 index 0000000..6f6a144 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/dto/patientcenter/PatientCenterCouponDTO.java @@ -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; +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/mapper/nurseapplogin/NurseAppLoginMapper.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/mapper/nurseapplogin/NurseAppLoginMapper.java index 15ed9e6..64dbc33 100644 --- a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/mapper/nurseapplogin/NurseAppLoginMapper.java +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/mapper/nurseapplogin/NurseAppLoginMapper.java @@ -20,4 +20,12 @@ public interface NurseAppLoginMapper { * @return PatientDiseaseInfo */ PatientAndDiseaseVO getPatientDiseaseByPatientId(@Param("patientId") Long patientId); + + /** + * 查询信息完善标识符 + * + * @param patientId 账号信息 + * @return 数量 + */ + Integer getLoginFlagByPatientId(@Param("patientId") Long patientId); } diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/mapper/nursingstationgoods/NursingStationGoodsMapper.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/mapper/nursingstationgoods/NursingStationGoodsMapper.java new file mode 100644 index 0000000..562203f --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/mapper/nursingstationgoods/NursingStationGoodsMapper.java @@ -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 getGoodsCategoryList(GoodsCategory goodsCategory); + + /** + * 根据商品分类id查询商品信息 + * + * @param goodsList 商品信息 + * @return 商品基本信息集合 + */ + List getGoodsInfoList(GoodsList goodsList); + + /** + * 查询商品二级分类信息列表 + * + * @param goodsCategory 商品分类信息 + * @return 商品分类信息集合 + */ + List getGoodsCategoryNameList(GoodsCategoryNameVO goodsCategory); + + /** + * 商品属性信息 + * + * @param goodsInfoId 商品详细id + * @return java.util.List + **/ + GoodDetails getGoodsDetailsList(Long goodsInfoId); + + /** + * 根据被护理人id查询基本信息 + * + * @param patientId 被护理人id + * @return com.xinyilu.base.domain.patientinfo.PatientInfo + **/ + List getReceiveAddressInfoList(Long patientId); + + /** + * 根据被护理人id查询基本信息集合 + * + * @param patientId 被护理人id + * @return java.util.List + **/ + List 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 + */ + List selectCouponListByPatient(@Param("patientId") Long patientId, @Param("useStatus") String useStatus); +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/mapper/patientcenter/PatientCenterMapper.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/mapper/patientcenter/PatientCenterMapper.java new file mode 100644 index 0000000..68fc236 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/mapper/patientcenter/PatientCenterMapper.java @@ -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 + */ + List selectCouponByUseStatus(PatientCenterCouponVO patientCenterCouponVO); + + /** + * 积分兑换 - 查询积分兑换商品 + * + * @param integralExchangeFlag 积分兑换标识 + * @param whetherShelf 是否上架 + * @param goodsPurpose 商品用途 + * @return List + */ + List selectGoodsByExchangeFlag(@Param("integralExchangeFlag") Integer integralExchangeFlag, @Param("whetherShelf") Integer whetherShelf, @Param("goodsPurpose") String goodsPurpose); + + /** + * 查询优惠券表所有id(待领取优惠券) + * + * @return List + */ + List 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 selectPatientSignIn(@Param("patientId") Long patientId, + @Param("nowDate") LocalDate nowDate, + @Param("ruleList") List ruleList); + + /** + * 新人福利查询优惠券 + * + * @param receiveType 新人福利标识1/ + * @return java.util.List + **/ + List getCouponNewPeople(String receiveType); + + /** + * 根据优惠券状态查询优惠券信息 + * + * @param patientCenterCouponDTO 用户信息及优惠券状态 + * @return List + */ + List getCouponByUseStatus(PatientCenterCouponDTO patientCenterCouponDTO); + + /** + * 查询用户签到信息和积分信息 + * + * @param patientId 会员id + * @param nowDate 当前时间 + * @return 信息 + */ + PatientSignInfoVO getPatientSignInfo(@Param("patientId") Long patientId, @Param("nowDate") LocalDate nowDate); +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/messagepush/Impl/MessagePushServiceImpl.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/messagepush/Impl/MessagePushServiceImpl.java new file mode 100644 index 0000000..2647526 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/messagepush/Impl/MessagePushServiceImpl.java @@ -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 paramsMap = new LinkedHashMap<>(); + paramsMap.put("touser", subscribeMessageRecord.getOpenid()); + paramsMap.put("template_id", appletChatConfig.getSignTemplateId()); + paramsMap.put("page", appletPageConfig.getIntegralPageUrl()); + //模板内容 + Map 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 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 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 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; + } + } + } +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/messagepush/MessagePushService.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/messagepush/MessagePushService.java new file mode 100644 index 0000000..92f823b --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/messagepush/MessagePushService.java @@ -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 paramsMap); +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/nursingstationgoods/INursingStationGoodsService.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/nursingstationgoods/INursingStationGoodsService.java new file mode 100644 index 0000000..4ea3f35 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/nursingstationgoods/INursingStationGoodsService.java @@ -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 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 defaultAddressList); +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/nursingstationgoods/impl/NursingStationGoodsServiceImpl.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/nursingstationgoods/impl/NursingStationGoodsServiceImpl.java new file mode 100644 index 0000000..6587cc2 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/nursingstationgoods/impl/NursingStationGoodsServiceImpl.java @@ -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 + **/ + @Override + public List getGoodsCategoryList(GoodsCategory goodsCategory) { + return nursingStationGoodsMapper.getGoodsCategoryList(goodsCategory); + } + + /** + * 查询商品二级分类信息列表 + * + * @param goodsCategoryId 商品分类信息 + * @return 商品分类信息集合 + */ + @Override + public AjaxResult getGoodsCategoryNameList(Long goodsCategoryId) { + //查询当前分类下属所有分类id集合 + List 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 + **/ + @Override + public TableDataInfo getGoodsInfoList(GoodsList goodsList) { + if (Objects.nonNull(goodsList) && Objects.isNull(goodsList.getGoodsCategoryId())) { + throw new ServiceException("所选商品分类不能为空!"); + } + //查询当前分类下属所有分类id集合 + List childCategoryIds = this.getChildCategoryIds(goodsList.getGoodsCategoryId()); + goodsList.setGoodsCategoryIds(childCategoryIds); + pageServiceUtil.startPage(); + List 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 couponVOList = nursingStationGoodsMapper.selectCouponListByPatient(patientId, CouponUseStatusEnum.NOT_USED.getInfo()); + //用流筛选出用户未使用以及未过期的 优惠券信息 + List couponVO = couponVOList.stream() + .filter(cou -> (Objects.nonNull(cou.getExpirationEndTime()))).filter(coupon -> (coupon.getExpirationEndTime().isAfter(LocalDateTime.now()))).collect(Collectors.toList()); + //未过期的优惠券塞入返回值中 返回 + goodsDetailsList.setCouponList(couponVO); + //做差集取出用户未使用以及 过期的 优惠券信息 + List couponSubtractList = new ArrayList<>(CollectionUtils.subtract(couponVOList, couponVO)); + if (CollectionUtils.isNotEmpty(couponSubtractList)) { + //取出会员用户优惠券领取记录表id集合 + List 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 + **/ + @Override + public AjaxResult getReceiveAddressInfoList(Long patientId) { + //根据id查询所有的地址 + List receiveAddressInfoList = nursingStationGoodsMapper.getReceiveAddressInfoList(patientId); + //取出list集合中所有的AreaCode + List 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 sysStreetAreaMap = sysAreaMapper.getNurseStationAreaByList(areaCodeList).stream().filter(item -> StringUtils.isNotBlank(item.getStreetCode())).collect(Collectors.toMap(SysAreaVO::getStreetCode, item -> item)); + //所在区的编码集合 + List 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 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 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 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 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 getChildCategoryIds(Long categoryId) { + //查询当前分类下属所有分类id集合 + String childrenCategoryIds = nursingStationGoodsMapper.getChildrenCategoryIds(categoryId); + //分割 ,去除第一个“ ” 获取数据 转换类型 + String[] split; + List 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); + } + } +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/patientcenter/PatientCenterService.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/patientcenter/PatientCenterService.java new file mode 100644 index 0000000..d08b370 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/patientcenter/PatientCenterService.java @@ -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 + */ + List selectCouponByUseStatus(PatientCenterCouponVO patientCenterCouponVO); + + /** + * 个人中心积分兑换 - 查询积分兑换商品 + * + * @return AjaxResult + */ + List selectExchangeGoods(); + + /** + * 获取积分返回规则 + * + * @param patientId 用户id + * @return com.xinyilu.nurseapplet.domain.vo.patientcenter.PatientSignInfoVO + **/ + PatientSignInfoVO selectPatientSignIn(Long patientId); + + /** + * 新人福利优惠券 + * + * @param patientCenterCouponVO 用户信息及优惠券状态 + * @return List + */ + 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); +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/patientcenter/impl/PatientCenterServiceImpl.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/patientcenter/impl/PatientCenterServiceImpl.java new file mode 100644 index 0000000..0ca33d1 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/patientcenter/impl/PatientCenterServiceImpl.java @@ -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 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public List selectCouponByUseStatus(PatientCenterCouponVO patientCenterCouponVO) { + patientCenterCouponVO.setReceiveSource(CouponReceiveTypeEnum.NEW_PEOPLE_WELFARE.getInfo()); + List useStatusList = Arrays.asList(CouponUseStatusEnum.USED.getInfo(), CouponUseStatusEnum.NOT_USED.getInfo(), CouponUseStatusEnum.EXPIRED.getInfo()); + patientCenterCouponVO.setUseStatusList(useStatusList); + List 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 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 ruleList = Arrays.asList(SettingsTypeEnum.INVITE_FRIENDS.getInfo(), SettingsTypeEnum.SIGN_IN_RULE.getInfo()); + Map 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 messageRecord = new SubscribeMessageRecord(); + messageRecord.setPatientId(subscribeMessageRecord.get(0).getPatientId()); + messageRecord.setOpenid(subscribeMessageRecord.get(0).getOpenid()); + //查询数据库中的数据 并去重 + List subscribeMessageRecords = subscribeMessageRecordMapper.selectSubscribeMessageRecordList(messageRecord); + //前端穿过聊的数据并去重 + List subscribeRecordVO = subscribeMessageRecord.stream().distinct().collect(Collectors.toList()); + //求出差集 要新增的 + List messageRecordSubtract = new ArrayList<>(CollectionUtils.subtract(subscribeRecordVO, subscribeMessageRecords)); + //求出交集 要修改的 + List 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 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public TableDataInfo getCouponByUseStatus(PatientCenterCouponDTO patientCenterCouponDTO) { + //用户无登录情况下 + if (Objects.isNull(patientCenterCouponDTO.getPatientId())) { + pageServiceUtil.startPage(); + List 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 couponNewPeople = patientCenterMapper.getCouponNewPeople(CouponReceiveTypeEnum.NEW_PEOPLE_WELFARE.getInfo()); + return pageServiceUtil.getDataTable(couponNewPeople); + } + pageServiceUtil.startPage(); + List 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); + } + } +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/wechatappletcallback/WeChatAppletCallBackService.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/wechatappletcallback/WeChatAppletCallBackService.java new file mode 100644 index 0000000..c9a5a36 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/wechatappletcallback/WeChatAppletCallBackService.java @@ -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); +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/wechatappletcallback/impl/WeChatAppletCallBackServiceImpl.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/wechatappletcallback/impl/WeChatAppletCallBackServiceImpl.java new file mode 100644 index 0000000..ce6c096 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/service/wechatappletcallback/impl/WeChatAppletCallBackServiceImpl.java @@ -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 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 existMessageRecordList = subscribeMessageRecordMapper.selectSubscribeMessageRecordList(subscribeMessageRecord); + List 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 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 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 existMessageRecordList = subscribeMessageRecordMapper.selectSubscribeMessageRecordList(subscribeMessageRecord); + List 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 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 + */ + private List createSubscribeMessageRecordList(PatientInfo patientInfo, WeChatMessagePushVO weChatMessagePushVO, String eventType) { + List 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 + */ + private List 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()); + } +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/utils/XmlUtil.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/utils/XmlUtil.java new file mode 100644 index 0000000..6793acc --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/utils/XmlUtil.java @@ -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; + } +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgChangeEventVO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgChangeEventVO.java new file mode 100644 index 0000000..5359f1a --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgChangeEventVO.java @@ -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 subscribeMsgPopupEventList; +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgPopupEventListVO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgPopupEventListVO.java new file mode 100644 index 0000000..5f0a563 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgPopupEventListVO.java @@ -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; +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgPopupEventVO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgPopupEventVO.java new file mode 100644 index 0000000..e907408 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgPopupEventVO.java @@ -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 subscribeMsgPopupEventList; +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgSentEventListVO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgSentEventListVO.java new file mode 100644 index 0000000..1a0e8d1 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgSentEventListVO.java @@ -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; +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgSentEventVO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgSentEventVO.java new file mode 100644 index 0000000..892d557 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/SubscribeMsgSentEventVO.java @@ -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 subscribeMsgSentEventList; +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/WeChatMessagePushVO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/WeChatMessagePushVO.java new file mode 100644 index 0000000..c4e12d8 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/messagepush/WeChatMessagePushVO.java @@ -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; +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/nursingstationgoods/UpdateDefaultAddressVO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/nursingstationgoods/UpdateDefaultAddressVO.java new file mode 100644 index 0000000..641136f --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/nursingstationgoods/UpdateDefaultAddressVO.java @@ -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; + + /** + * 默认地址标识,0:否,1:是 + */ + @NotNull(message = "默认收货地址标识不能为空!", groups = {Update.class}) + private Integer defaultAddressFlag; +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/patientcenter/PatientCenterCouponVO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/patientcenter/PatientCenterCouponVO.java new file mode 100644 index 0000000..e4ba6e7 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/patientcenter/PatientCenterCouponVO.java @@ -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 useStatusList; +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/patientcenter/PatientSignInVO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/patientcenter/PatientSignInVO.java new file mode 100644 index 0000000..3fd3360 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/patientcenter/PatientSignInVO.java @@ -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; +} diff --git a/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/patientcenter/PatientSignInfoVO.java b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/patientcenter/PatientSignInfoVO.java new file mode 100644 index 0000000..d0d55f8 --- /dev/null +++ b/xinelu-nurse-applet/src/main/java/com/xinelu/applet/vo/patientcenter/PatientSignInfoVO.java @@ -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; + + /** + * 会用用户当天是否签到标识,0:都,1:是 + */ + private Integer todaySignInCount; + + /** + * 会员累计签到天数 + */ + private Integer patientSignInCount; + + /** + * 会员用户账户总积分 + */ + private Integer integral; + + /** + * 系统配置参数信息表积分数值 + */ + private Integer integralCount; +} diff --git a/xinelu-nurse-applet/src/main/resources/mapper/applet/nurseapplogin/NurseAppLoginMapper.xml b/xinelu-nurse-applet/src/main/resources/mapper/applet/nurseapplogin/NurseAppLoginMapper.xml index 94e45b9..f9e2506 100644 --- a/xinelu-nurse-applet/src/main/resources/mapper/applet/nurseapplogin/NurseAppLoginMapper.xml +++ b/xinelu-nurse-applet/src/main/resources/mapper/applet/nurseapplogin/NurseAppLoginMapper.xml @@ -64,4 +64,15 @@ + + diff --git a/xinelu-nurse-applet/src/main/resources/mapper/applet/nursingStationGoods/NursingStationGoodsMapper.xml b/xinelu-nurse-applet/src/main/resources/mapper/applet/nursingStationGoods/NursingStationGoodsMapper.xml new file mode 100644 index 0000000..d1121e8 --- /dev/null +++ b/xinelu-nurse-applet/src/main/resources/mapper/applet/nursingStationGoods/NursingStationGoodsMapper.xml @@ -0,0 +1,513 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + insert into receive_address_info + + id, + + patient_id, + + openid, + + unionid, + + receive_name, + + receive_phone, + + receive_address, + + area_code, + + create_by, + + create_time, + + update_by, + + update_time, + + + + #{id}, + + #{patientId}, + + #{openid}, + + #{unionid}, + + #{receiveName}, + + #{receivePhone}, + + #{receiveAddress}, + + #{areaCode}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + + + + + update receive_address_info + + patient_id = + #{patientId}, + + openid = + #{openid}, + + unionid = + #{unionid}, + + receive_name = + #{receiveName}, + + receive_phone = + #{receivePhone}, + + receive_address = + #{receiveAddress}, + + area_code = + #{areaCode}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where id = #{id} + + + + delete from receive_address_info where id in + + #{id} + + + + + + + + + + + + update goods_attribute_details + + goods_attribute_id = + #{goodsAttributeId}, + + attribute_details_name = + #{attributeDetailsName}, + + goods_stock = + #{goodsStock}, + + goods_price = + #{goodsPrice}, + + attribute_piture_url = + #{attributePitureUrl}, + + sort = + #{sort}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where id = #{id} + + + + diff --git a/xinelu-nurse-applet/src/main/resources/mapper/applet/patientcenter/PatientCenterMapper.xml b/xinelu-nurse-applet/src/main/resources/mapper/applet/patientcenter/PatientCenterMapper.xml new file mode 100644 index 0000000..939d694 --- /dev/null +++ b/xinelu-nurse-applet/src/main/resources/mapper/applet/patientcenter/PatientCenterMapper.xml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 patient_info + set integral = IFNULL(integral, 0) + #{integral}, + update_time = now() + where id = #{patientId} + and del_flag = 0 + + + + update patient_info + set total_sign_in_days = 0, + update_time = now() + where id = #{patientId} + and del_flag = 0 + + + + + + + + + + diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/goodsOrderDetails/GoodsOrderDetails.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/goodsOrderDetails/GoodsOrderDetails.java new file mode 100644 index 0000000..0a0b8d5 --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/goodsOrderDetails/GoodsOrderDetails.java @@ -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; + + /** + * 0:否,1:是 + */ + 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(); + } +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/patientcouponreceive/PatientCouponReceive.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/patientcouponreceive/PatientCouponReceive.java new file mode 100644 index 0000000..74d2b2d --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/patientcouponreceive/PatientCouponReceive.java @@ -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(); + } +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/patientintegralchange/PatientIntegralChange.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/patientintegralchange/PatientIntegralChange.java new file mode 100644 index 0000000..02c28ef --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/patientintegralchange/PatientIntegralChange.java @@ -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; + + /** + * 积分变更方式,手机App:MOBILE_APP,微信小程序:WECHAT_APPLET,支付宝小程序:ALI_PAY_APPLET + */ + @ApiModelProperty(value = "积分变更方式,手机App:MOBILE_APP,微信小程序:WECHAT_APPLET,支付宝小程序:ALI_PAY_APPLET") + @Excel(name = "积分变更方式,手机App:MOBILE_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(); + } +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/patientsignininfo/PatientSignInInfo.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/patientsignininfo/PatientSignInInfo.java new file mode 100644 index 0000000..49a423f --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/patientsignininfo/PatientSignInInfo.java @@ -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; + + /** + * 签到方式,手机App:MOBILE_APP,微信小程序:WECHAT_APPLET,支付宝小程序:ALI_PAY_APPLET + */ + @ApiModelProperty(value = "签到方式,手机App:MOBILE_APP,微信小程序:WECHAT_APPLET,支付宝小程序:ALI_PAY_APPLET") + @Excel(name = "签到方式,手机App:MOBILE_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(); + } +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/subscribemessagerecord/SubscribeMessageRecord.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/subscribemessagerecord/SubscribeMessageRecord.java new file mode 100644 index 0000000..24630b8 --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/subscribemessagerecord/SubscribeMessageRecord.java @@ -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(); + } +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/subscribemessagesendrecord/SubscribeMessageSendRecord.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/subscribemessagesendrecord/SubscribeMessageSendRecord.java new file mode 100644 index 0000000..a6c6336 --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/domain/subscribemessagesendrecord/SubscribeMessageSendRecord.java @@ -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(); + } +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/dto/subscribemessagerecord/SubscribeMessageRecordDTO.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/dto/subscribemessagerecord/SubscribeMessageRecordDTO.java new file mode 100644 index 0000000..253e20d --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/dto/subscribemessagerecord/SubscribeMessageRecordDTO.java @@ -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 subscribeMessageRecordList; +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/goodsOrderDetails/GoodsOrderDetailsMapper.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/goodsOrderDetails/GoodsOrderDetailsMapper.java new file mode 100644 index 0000000..eb02cf2 --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/goodsOrderDetails/GoodsOrderDetailsMapper.java @@ -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 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); +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/patientcouponreceive/PatientCouponReceiveMapper.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/patientcouponreceive/PatientCouponReceiveMapper.java new file mode 100644 index 0000000..c013787 --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/patientcouponreceive/PatientCouponReceiveMapper.java @@ -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 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 couponReceiveList); + + /** + * 查询会员用户过期的优惠券领取记录列表 + * + * @param expirationEndTime 过期的优惠券时间 + * @param couponUseStatus 优惠券状态 + * @return 会员用户优惠券领取记录集合 + */ + List getPatientCouponExpirationEndTime(@Param("expirationEndTime") LocalDateTime expirationEndTime, @Param("couponUseStatus") String couponUseStatus); + + /** + * 批量更新优惠券状态 + * + * @param couponUseStatus 状态 + * @param idList id集合 + * @return 更新数量 + */ + int updateCouponReceiveStatus(@Param("couponUseStatus") String couponUseStatus, @Param("idList") List idList); + + + /** + * 批量更新优惠券状态集合 + * + * @param couponUseStatus 状态 + * @param idList 优惠券id集合 + * @return int + **/ + int updateCouponReceiveStatusList(@Param("couponUseStatus") String couponUseStatus, @Param("idList") List 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); +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/patientintegralchange/PatientIntegralChangeMapper.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/patientintegralchange/PatientIntegralChangeMapper.java new file mode 100644 index 0000000..d0c0c98 --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/patientintegralchange/PatientIntegralChangeMapper.java @@ -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 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); +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/patientsignininfo/PatientSignInInfoMapper.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/patientsignininfo/PatientSignInInfoMapper.java new file mode 100644 index 0000000..1fd6651 --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/patientsignininfo/PatientSignInInfoMapper.java @@ -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 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); +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/receiveAddressInfo/ReceiveAddressInfoMapper.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/receiveAddressInfo/ReceiveAddressInfoMapper.java new file mode 100644 index 0000000..40eb349 --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/receiveAddressInfo/ReceiveAddressInfoMapper.java @@ -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 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); +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagerecord/SubscribeMessageRecordMapper.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagerecord/SubscribeMessageRecordMapper.java new file mode 100644 index 0000000..5a550b8 --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagerecord/SubscribeMessageRecordMapper.java @@ -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 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); + + /** + * 根据用户id,openid,消息模板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 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 + */ + List selectSubscribeList(@Param("list") List ids, @Param("subscribeStatus") String subscribeStatus, @Param("messageType") String messageType); +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.java new file mode 100644 index 0000000..456172d --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.java @@ -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 subscribeMessageSendRecordList); +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/vo/patientcouponreceive/PatientCouponReceiveInfoVO.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/vo/patientcouponreceive/PatientCouponReceiveInfoVO.java new file mode 100644 index 0000000..037df6d --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/vo/patientcouponreceive/PatientCouponReceiveInfoVO.java @@ -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; +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/vo/patientcouponreceive/PatientCouponReceiveVO.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/vo/patientcouponreceive/PatientCouponReceiveVO.java new file mode 100644 index 0000000..2250d08 --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/vo/patientcouponreceive/PatientCouponReceiveVO.java @@ -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; +} diff --git a/xinelu-nurse-manage/src/main/java/com/xinelu/manage/vo/receiveAddressInfo/ReceiveAddressInfoVO.java b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/vo/receiveAddressInfo/ReceiveAddressInfoVO.java new file mode 100644 index 0000000..8e45fa7 --- /dev/null +++ b/xinelu-nurse-manage/src/main/java/com/xinelu/manage/vo/receiveAddressInfo/ReceiveAddressInfoVO.java @@ -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 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; + + /** + * 默认收货地址标识,0:否,1:是 + */ + private Integer defaultAddressFlag; +} diff --git a/xinelu-nurse-manage/src/main/resources/mapper/manage/goodsOrderDetails/GoodsOrderDetailsMapper.xml b/xinelu-nurse-manage/src/main/resources/mapper/manage/goodsOrderDetails/GoodsOrderDetailsMapper.xml new file mode 100644 index 0000000..8d6f540 --- /dev/null +++ b/xinelu-nurse-manage/src/main/resources/mapper/manage/goodsOrderDetails/GoodsOrderDetailsMapper.xml @@ -0,0 +1,311 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + insert into goods_order_details + + goods_order_id, + + goods_attribute_id, + + goods_attribute_details_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, + + coupon_title, + + integral_exchange_sill, + + integral_exchange_count, + + + + #{goodsOrderId}, + + #{goodsAttributeId}, + + #{goodsAttributeDetailsId}, + + #{orderNo}, + + #{goodsName}, + + #{goodsCount}, + + #{goodsAttributeName}, + + #{goodsAttributeContent}, + + #{goodsPrice}, + + #{totalPrice}, + + #{discountPrice}, + + #{transportPrice}, + + #{giveIntegral}, + + #{delFlag}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + #{couponId}, + + #{integralDeductionCount}, + + #{integralDeductionPrice}, + + #{couponTitle}, + + #{integralExchangeSill}, + + #{integralExchangeCount}, + + + + + + update goods_order_details + + goods_order_id = + #{goodsOrderId}, + + order_no = + #{orderNo}, + + goods_name = + #{goodsName}, + + goods_count = + #{goodsCount}, + + goods_attribute_name = + #{goodsAttributeName}, + + goods_attribute_content = + #{goodsAttributeContent}, + + goods_price = + #{goodsPrice}, + + total_price = + #{totalPrice}, + + discount_price = + #{discountPrice}, + + transport_price = + #{transportPrice}, + + give_integral = + #{giveIntegral}, + + del_flag = + #{delFlag}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + coupon_id = + #{couponId}, + + integral_deduction_count = + #{integralDeductionCount}, + + integral_deduction_price = + #{integralDeductionPrice}, + + coupon_title = + #{couponTitle}, + + integral_exchange_sill = + #{integralExchangeSill}, + + integral_exchange_count = + #{integralExchangeCount}, + + + where id = #{id} + + + + delete + from goods_order_details + where id = #{id} + + + + delete from goods_order_details where id in + + #{id} + + + + + diff --git a/xinelu-nurse-manage/src/main/resources/mapper/manage/patientcouponreceive/PatientCouponReceiveMapper.xml b/xinelu-nurse-manage/src/main/resources/mapper/manage/patientcouponreceive/PatientCouponReceiveMapper.xml new file mode 100644 index 0000000..96b3072 --- /dev/null +++ b/xinelu-nurse-manage/src/main/resources/mapper/manage/patientcouponreceive/PatientCouponReceiveMapper.xml @@ -0,0 +1,366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + insert into patient_coupon_receive + + 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, + + + + #{patientId}, + + #{couponId}, + + #{receiveSource}, + + #{expirationStartTime}, + + #{expirationEndTime}, + + #{receiveTime}, + + #{useStatus}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + #{couponTitle}, + + #{couponPrice}, + + #{couponConsumePrice}, + + #{couponDescription}, + + #{couponReductionDays}, + + + + + + update patient_coupon_receive + + patient_id = + #{patientId}, + + coupon_id = + #{couponId}, + + receive_source = + #{receiveSource}, + + expiration_start_time = + #{expirationStartTime}, + + expiration_end_time = + #{expirationEndTime}, + + receive_time = + #{receiveTime}, + + use_status = + #{useStatus}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + coupon_title = + #{couponTitle}, + + coupon_price = + #{couponPrice}, + + coupon_consume_price = + #{couponConsumePrice}, + + coupon_description = + #{couponDescription}, + + coupon_reduction_days = + #{couponReductionDays}, + + + where id = #{id} + + + + delete + from patient_coupon_receive + where id = #{id} + + + + delete from patient_coupon_receive where id in + + #{id} + + + + + 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 + + ( + #{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} + ) + + + + + + + update patient_coupon_receive set use_status = #{couponUseStatus}, update_time = now() + where id in + + #{id} + + + + + update patient_coupon_receive set use_status = #{couponUseStatus}, update_time = now() + + id in + + #{id} + + + + + + + + update patient_coupon_receive + set use_status = #{useStatus}, + update_time = now() + where patient_id = #{patientId} + and coupon_id = #{couponId} + and use_status <> #{useStatus} + + + + diff --git a/xinelu-nurse-manage/src/main/resources/mapper/manage/patientintegralchange/PatientIntegralChangeMapper.xml b/xinelu-nurse-manage/src/main/resources/mapper/manage/patientintegralchange/PatientIntegralChangeMapper.xml new file mode 100644 index 0000000..b19ef66 --- /dev/null +++ b/xinelu-nurse-manage/src/main/resources/mapper/manage/patientintegralchange/PatientIntegralChangeMapper.xml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + insert into patient_integral_change + + patient_id, + + original_integral, + + change_integral, + + change_time, + + change_type, + + change_remark, + + change_integral_channel, + + create_by, + + create_time, + + update_by, + + update_time, + + + + #{patientId}, + + #{originalIntegral}, + + #{changeIntegral}, + + #{changeTime}, + + #{changeType}, + + #{changeRemark}, + + #{changeIntegralChannel}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + + + + + update patient_integral_change + + patient_id = + #{patientId}, + + original_integral = + #{originalIntegral}, + + change_integral = + #{changeIntegral}, + + change_time = + #{changeTime}, + + change_type = + #{changeType}, + + change_remark = + #{changeRemark}, + + change_integral_channel = + #{changeIntegralChannel}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where id = #{id} + + + + delete from patient_integral_change where id = #{id} + + + + delete from patient_integral_change where id in + + #{id} + + + diff --git a/xinelu-nurse-manage/src/main/resources/mapper/manage/patientsignininfo/PatientSignInInfoMapper.xml b/xinelu-nurse-manage/src/main/resources/mapper/manage/patientsignininfo/PatientSignInInfoMapper.xml new file mode 100644 index 0000000..ed49b89 --- /dev/null +++ b/xinelu-nurse-manage/src/main/resources/mapper/manage/patientsignininfo/PatientSignInInfoMapper.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + select id, patient_id, sign_in_time, sign_in_channel, create_by, create_time, update_by, update_time from patient_sign_in_info + + + + + + + + insert into patient_sign_in_info + + id, + + patient_id, + + sign_in_time, + + sign_in_channel, + + create_by, + + create_time, + + update_by, + + update_time, + + + + #{id}, + + #{patientId}, + + #{signInTime}, + + #{signInChannel}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + + + + + update patient_sign_in_info + + patient_id = + #{patientId}, + + sign_in_time = + #{signInTime}, + + sign_in_channel = + #{signInChannel}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where id = #{id} + + + + delete from patient_sign_in_info where id = #{id} + + + + delete from patient_sign_in_info where id in + + #{id} + + + + + \ No newline at end of file diff --git a/xinelu-nurse-manage/src/main/resources/mapper/manage/receiveAddressInfo/ReceiveAddressInfoMapper.xml b/xinelu-nurse-manage/src/main/resources/mapper/manage/receiveAddressInfo/ReceiveAddressInfoMapper.xml new file mode 100644 index 0000000..4e1b39f --- /dev/null +++ b/xinelu-nurse-manage/src/main/resources/mapper/manage/receiveAddressInfo/ReceiveAddressInfoMapper.xml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + insert into receive_address_info + + id, + + patient_id, + + openid, + + unionid, + + receive_name, + + receive_phone, + + receive_address, + + area_code, + + create_by, + + create_time, + + update_by, + + update_time, + + default_address_flag, + + + + #{id}, + + #{patientId}, + + #{openid}, + + #{unionid}, + + #{receiveName}, + + #{receivePhone}, + + #{receiveAddress}, + + #{areaCode}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + #{defaultAddressFlag}, + + + + + + update receive_address_info + + patient_id = + #{patientId}, + + openid = + #{openid}, + + unionid = + #{unionid}, + + receive_name = + #{receiveName}, + + receive_phone = + #{receivePhone}, + + receive_address = + #{receiveAddress}, + + area_code = + #{areaCode}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + default_address_flag = + #{defaultAddressFlag}, + + + where id = #{id} + + + + delete + from receive_address_info + where id = #{id} + + + + delete from receive_address_info where id in + + #{id} + + + + + diff --git a/xinelu-nurse-manage/src/main/resources/mapper/manage/subscribemessagerecord/SubscribeMessageRecordMapper.xml b/xinelu-nurse-manage/src/main/resources/mapper/manage/subscribemessagerecord/SubscribeMessageRecordMapper.xml new file mode 100644 index 0000000..27bc353 --- /dev/null +++ b/xinelu-nurse-manage/src/main/resources/mapper/manage/subscribemessagerecord/SubscribeMessageRecordMapper.xml @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + 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, + + + + #{patientId}, + + #{unionid}, + + #{openid}, + + #{templateId}, + + #{messageType}, + + #{subscribeCount}, + + #{subscribeTime}, + + #{appletId}, + + #{subscribeStatus}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + + + + + update subscribe_message_record + + patient_id = + #{patientId}, + + unionid = + #{unionid}, + + openid = + #{openid}, + + template_id = + #{templateId}, + + message_type = + #{messageType}, + + subscribe_count = + #{subscribeCount}, + + subscribe_time = + #{subscribeTime}, + + applet_id = + #{appletId}, + + subscribe_status = + #{subscribeStatus}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where id = #{id} + + + + delete + from subscribe_message_record + where id = #{id} + + + + delete from subscribe_message_record where id in + + #{id} + + + + + + + + + + + + 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 + + ( + #{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} + ) + + + + + update subscribe_message_record + set patient_id = #{patientId}, subscribe_status = #{subscribeStatus}, update_time = now() + where openid = #{openId} and template_id = #{templateId} + + diff --git a/xinelu-nurse-manage/src/main/resources/mapper/manage/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.xml b/xinelu-nurse-manage/src/main/resources/mapper/manage/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.xml new file mode 100644 index 0000000..25ec845 --- /dev/null +++ b/xinelu-nurse-manage/src/main/resources/mapper/manage/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.xml @@ -0,0 +1,33 @@ + + + + + + insert into subscribe_message_send_record( + openid, + applet_id, + subscribe_time, + template_id, + msg_id, + message_type, + error_code, + error_status, + create_time + ) values + + ( + #{sendRecord.openid}, + #{sendRecord.appletId}, + #{sendRecord.subscribeTime}, + #{sendRecord.templateId}, + #{sendRecord.msgId}, + #{sendRecord.messageType}, + #{sendRecord.errorCode}, + #{sendRecord.errorStatus}, + #{sendRecord.createTime} + ) + + + \ No newline at end of file