Merge pull request #86

pg
This commit is contained in:
misworga831 2023-05-17 14:23:10 +08:00 committed by GitHub
commit 62ac16b705
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 1001 additions and 357 deletions

View File

@ -88,3 +88,4 @@ ALTER TABLE li_foot_print ADD `store_id` varchar(255) DEFAULT NULL COMMENT '店
*/
ALTER TABLE li_member_withdraw_apply ADD `real_name` varchar(255) DEFAULT NULL;
ALTER TABLE li_member_withdraw_apply ADD `connect_number` varchar(255) DEFAULT NULL;
ALTER TABLE li_member_withdraw_apply ADD `error_message` text DEFAULT NULL;

View File

@ -99,7 +99,7 @@ public class BuyerAuthenticationFilter extends BasicAuthenticationFilter {
AuthUser authUser = new Gson().fromJson(json, AuthUser.class);
//校验redis中是否有权限
if (cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MEMBER) + jwt)) {
if (cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MEMBER,authUser.getId()) + jwt)) {
//构造返回信息
List<GrantedAuthority> auths = new ArrayList<>();
auths.add(new SimpleGrantedAuthority("ROLE_" + authUser.getRole().name()));

View File

@ -24,13 +24,13 @@ spring:
boot:
admin:
client:
url: http://127.0.0.1:8000
url: http://192.168.0.108:8000
cache:
type: redis
# Redis
redis:
host: 127.0.0.1
port: 6379
host: 192.168.31.108
port: 30379
password: lilishop
lettuce:
pool:
@ -60,7 +60,7 @@ spring:
default-datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/lilishop?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
url: jdbc:mysql://192.168.31.108:30306/lilishop?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root
password: lilishop
maxActive: 50
@ -241,16 +241,16 @@ lili:
sk: zhNKVrJK6UPOhqIjn8AQvG37b9sz6
#域名
domain:
pc: http://127.0.0.1:8888
wap: http://127.0.0.1:8888
seller: http://127.0.0.1:8888
admin: http://127.0.0.1:8888
pc: http://192.168.0.108:8888
wap: http://192.168.0.108:8888
seller: http://192.168.0.108:8888
admin: http://192.168.0.108:8888
#api地址
api:
buyer: https://z171l91606.51mypc.cn
base: http://127.0.0.1:8888
manager: http://127.0.0.1:8888
seller: http://127.0.0.1:8888
base: http://192.168.0.108:8888
manager: http://192.168.0.108:8888
seller: http://192.168.0.108:8888
# jwt 细节设定
jwt-setting:
@ -269,7 +269,7 @@ lili:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: 127.0.0.1:9200
cluster-nodes: 192.168.31.108:30920
index:
number-of-replicas: 0
number-of-shards: 3
@ -282,26 +282,26 @@ lili:
logstash:
server: 127.0.0.1:4560
rocketmq:
promotion-topic: lili_promotion_topic
promotion-group: lili_promotion_group
msg-ext-topic: lili_msg_topic
msg-ext-group: lili_msg_group
goods-topic: lili_goods_topic
goods-group: lili_goods_group
order-topic: lili_order_topic
order-group: lili_order_group
member-topic: lili_member_topic
member-group: lili_member_group
other-topic: lili_other_topic
other-group: lili_other_group
notice-topic: lili_notice_topic
notice-group: lili_notice_group
notice-send-topic: lili_send_notice_topic
notice-send-group: lili_send_notice_group
after-sale-topic: lili_after_sale_topic
after-sale-group: lili_after_sale_group
promotion-topic: shop_lili_promotion_topic
promotion-group: shop_lili_promotion_group
msg-ext-topic: shop_lili_msg_topic
msg-ext-group: shop_lili_msg_group
goods-topic: shop_lili_goods_topic
goods-group: shop_lili_goods_group
order-topic: shop_lili_order_topic
order-group: shop_lili_order_group
member-topic: shop_lili_member_topic
member-group: shop_lili_member_group
other-topic: shop_lili_other_topic
other-group: shop_lili_other_group
notice-topic: shop_lili_notice_topic
notice-group: shop_lili_notice_group
notice-send-topic: shop_lili_send_notice_topic
notice-send-group: shop_lili_send_notice_group
after-sale-topic: shop_lili_after_sale_topic
after-sale-group: shop_lili_after_sale_group
rocketmq:
name-server: 127.0.0.1:9876
name-server: 192.168.31.108:30876
isVIPChannel: false
producer:
group: lili_group
@ -310,7 +310,7 @@ rocketmq:
xxl:
job:
admin:
addresses: http://127.0.0.1:9001/xxl-job-admin
addresses: http://192.168.31.108:30001/xxl-job-admin
executor:
appname: xxl-job-executor-lilishop
address:

View File

@ -39,11 +39,6 @@ public class DistributionOrderExecute implements OrderStatusChangeEvent, EveryDa
*/
@Autowired
private DistributionOrderService distributionOrderService;
/**
* 分销订单持久层
*/
@Resource
private DistributionOrderMapper distributionOrderMapper;
@Autowired
private SettingService settingService;

View File

@ -40,19 +40,19 @@ public class MemberExecute implements MemberLoginEvent, MemberConnectLoginEvent
@Override
public void memberConnectLogin(Member member, ConnectAuthUser authUser) {
log.info("unionid:"+authUser.getToken().getUnionId());
log.info("openid:"+authUser.getUuid());
//保存UnionID
if (StrUtil.isNotBlank(authUser.getToken().getUnionId())) {
connectService.loginBindUser(member.getId(), authUser.getToken().getUnionId(), authUser.getSource());
connectService.loginBindUser(member.getId(), authUser.getToken().getUnionId(), authUser.getSource().name());
}
//保存OpenID
if (StrUtil.isNotBlank(authUser.getUuid())) {
log.info("authUser.getSource():"+authUser.getSource());
log.info("authUser.getType():"+authUser.getType());
SourceEnum sourceEnum = SourceEnum.getSourceEnum(ConnectEnum.valueOf(authUser.getSource()), ClientTypeEnum.valueOf(authUser.getType()));
SourceEnum sourceEnum = SourceEnum.getSourceEnum(authUser.getSource(), authUser.getType());
connectService.loginBindUser(member.getId(), authUser.getUuid(), sourceEnum.name());
}
//保存手机号判断用户是否存手机号如果不存在则保存手机号
if (StrUtil.isNotBlank(authUser.getPhone())&&StrUtil.isBlank(member.getMobile())) {
memberService.changeMobile(member.getId(),member.getMobile());
}
}
}

View File

@ -31,15 +31,19 @@ public class MemberWalletExecute implements MemberWithdrawalEvent {
case SUCCESS:
//提现成功扣减冻结金额
memberWalletService.reduceFrozen(
new MemberWalletUpdateDTO(memberWithdrawalMessage.getPrice(), memberWithdrawalMessage.getMemberId(), "提现成功,余额提现", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
new MemberWalletUpdateDTO(memberWithdrawalMessage.getPrice(), memberWithdrawalMessage.getMemberId(), "提现成功,余额提现",
DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
break;
case ERROR:
//需要从冻结金额扣减到余额
memberWalletService.increaseWithdrawal(new MemberWalletUpdateDTO(memberWithdrawalMessage.getPrice(), memberWithdrawalMessage.getMemberId(), "提现失败,提现金额解冻到余额", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
memberWalletService.increaseWithdrawal(new MemberWalletUpdateDTO(memberWithdrawalMessage.getPrice(),
memberWithdrawalMessage.getMemberId(), "第三方提现失败,提现金额解冻到余额", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
break;
case FAIL_AUDITING:
//需要从冻结金额扣减到余额
memberWalletService.increaseWithdrawal(new MemberWalletUpdateDTO(memberWithdrawalMessage.getPrice(), memberWithdrawalMessage.getMemberId(), "审核拒绝,提现金额解冻到余额", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
memberWalletService.increaseWithdrawal(new MemberWalletUpdateDTO(memberWithdrawalMessage.getPrice(),
memberWithdrawalMessage.getMemberId(), "审核拒绝,提现金额解冻到余额", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
break;
default:
break;
}

View File

@ -0,0 +1,206 @@
package cn.lili.event.impl;
import cn.lili.event.StoreSettingChangeEvent;
import cn.lili.modules.distribution.service.DistributionGoodsService;
import cn.lili.modules.distribution.service.DistributionOrderService;
import cn.lili.modules.goods.service.DraftGoodsService;
import cn.lili.modules.member.service.MemberEvaluationService;
import cn.lili.modules.message.service.StoreMessageService;
import cn.lili.modules.order.aftersale.service.AfterSaleService;
import cn.lili.modules.order.order.service.OrderComplaintService;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.order.service.ReceiptService;
import cn.lili.modules.order.order.service.StoreFlowService;
import cn.lili.modules.promotion.service.*;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.service.BillService;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author ftyy
* @description: 店铺名称修改同步对应场景
* @date 2023/4/24
*/
@Service
public class StoreChangeEvent implements StoreSettingChangeEvent {
/**
* 优惠券活动表
*/
@Autowired
private CouponActivityService couponActivityService;
/**
* 砍价活动商品
*/
@Autowired
private KanjiaActivityGoodsService kanjiaActivityGoodsService;
/**
* 积分商品
*/
@Autowired
private PointsGoodsService pointsGoodsService;
/**
* 促销商品
*/
@Autowired
private PromotionGoodsService promotionGoodsService;
/**
* 秒杀活动活动
*/
@Autowired
private SeckillService seckillService;
/**
* 优惠券
*/
@Autowired
private CouponService couponService;
/**
* 满优惠活动
*/
@Autowired
private FullDiscountService fullDiscountService;
/**
* 拼团
*/
@Autowired
private PintuanService pintuanService;
/**
* 秒杀活动
*/
@Autowired
private SeckillApplyService seckillApplyService;
/**
* 订单
*/
@Autowired
private OrderService orderService;
/**
* 店铺流水
*/
@Autowired
private StoreFlowService storeFlowService;
/**
* 售后
*/
@Autowired
private AfterSaleService afterSaleService;
/**
* 订单投诉
*/
@Autowired
private OrderComplaintService orderComplaintService;
/**
* 发票
*/
@Autowired
private ReceiptService receiptService;
/**
* 会员优惠券
*/
@Autowired
private MemberCouponService memberCouponService;
/**
* 店铺消息
*/
@Autowired
private StoreMessageService storeMessageService;
/**
* 会员评价
*/
@Autowired
private MemberEvaluationService memberEvaluationService;
/**
* 结算单
*/
@Autowired
private BillService billService;
/**
* 分销商品
*/
@Autowired
private DistributionGoodsService distributionGoodsService;
/**
* 分销订单
*/
@Autowired
private DistributionOrderService distributionOrderService;
/**
* 草稿商品
*/
@Autowired
private DraftGoodsService draftGoodsService;
/**
* 店铺名称修改 同步更新相关店铺名称
*
* @param store 店铺信息
*/
@Override
public void storeSettingChange(Store store) {
UpdateWrapper updateWrapper = new UpdateWrapper<>()
.eq("store_id", store.getId())
.set("store_name", store.getStoreName());
//修改会员优惠券中店铺名称
memberCouponService.update(updateWrapper);
//修改优惠券活动中店铺名称
couponActivityService.update(updateWrapper);
//修改砍价活动商品中店铺名称
kanjiaActivityGoodsService.update(updateWrapper);
//修改积分商品中店铺名称
pointsGoodsService.update(updateWrapper);
//修改促销商品中店铺名称
promotionGoodsService.update(updateWrapper);
//修改秒杀活动活动中店铺名称
seckillService.update(updateWrapper);
//修改优惠券中店铺名称
couponService.update(updateWrapper);
//修改满优惠活动中店铺名称
fullDiscountService.update(updateWrapper);
//修改拼团中店铺名称
pintuanService.update(updateWrapper);
//修改秒杀活动中店铺名称
seckillApplyService.update(updateWrapper);
//修改发票中店铺名称
receiptService.update(updateWrapper);
//修改订单中的店铺名称
orderService.update(updateWrapper);
//修改店铺流水中店铺名称
storeFlowService.update(updateWrapper);
//修改售后中店铺名称
afterSaleService.update(updateWrapper);
//修改订单投诉中店铺名称
orderComplaintService.update(updateWrapper);
//修改店铺消息中的店铺名称
storeMessageService.update(updateWrapper);
//修改会员评价中店铺名称
memberEvaluationService.update(updateWrapper);
//修改结算单中店铺名称
billService.update(updateWrapper);
//修改分销订单中店铺名称
distributionOrderService.update(updateWrapper);
//修改分销商品中店铺名称
distributionGoodsService.update(updateWrapper);
//修改草稿商品中店铺名称
draftGoodsService.update(updateWrapper);
}
}

View File

@ -39,7 +39,6 @@ public class WechatMessageExecute implements OrderStatusChangeEvent, TradeEvent
public void orderChange(OrderMessage orderMessage) {
switch (orderMessage.getNewStatus()) {
case PAID:
case UNDELIVERED:
case DELIVERED:
case STAY_PICKED_UP:

View File

@ -234,6 +234,12 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
log.error("删除店铺商品索引事件执行异常,商品信息: " + new String(messageExt.getBody()), e);
}
break;
//同步商品分类名称
case CATEGORY_GOODS_NAME:
//分类ID
String id = new String(messageExt.getBody());
goodsService.categoryGoodsName(id);
break;
//商品评价
case GOODS_COMMENT_COMPLETE:
MemberEvaluation memberEvaluation = JSONUtil.toBean(new String(messageExt.getBody()), MemberEvaluation.class);
@ -376,7 +382,11 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
List<EsGoodsIndex> esGoodsIndices = new ArrayList<>();
for (GoodsSku goodsSku : goodsSkuList) {
EsGoodsIndex goodsIndex = this.settingUpGoodsIndexData(goods, goodsSku);
goodsIndex.setSkuSource(skuSource--);
skuSource--;
if (skuSource <= 0) {
skuSource = 1;
}
goodsIndex.setSkuSource(skuSource);
log.info("goodsSku{}", goodsSku);
log.info("生成商品索引 {}", goodsIndex);
esGoodsIndices.add(goodsIndex);

View File

@ -2,8 +2,6 @@ package cn.lili.timetask.handler.impl.order;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
@ -11,7 +9,6 @@ import cn.lili.modules.distribution.service.DistributionOrderService;
import cn.lili.modules.member.entity.dto.MemberEvaluationDTO;
import cn.lili.modules.member.entity.enums.EvaluationGradeEnum;
import cn.lili.modules.member.service.MemberEvaluationService;
import cn.lili.modules.order.aftersale.service.AfterSaleService;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.enums.CommentStatusEnum;
@ -69,9 +66,6 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
@Autowired
private MemberEvaluationService memberEvaluationService;
@Autowired
private AfterSaleService afterSaleService;
@Autowired
private DistributionOrderService distributionOrderService;
@ -88,14 +82,30 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
throw new ServiceException(ResultCode.ORDER_SETTING_ERROR);
}
try {
//自动确认收货
completedOrder(orderSetting);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
try {
//自动好评
memberEvaluation(orderSetting);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
try {
//关闭允许售后申请
closeAfterSale(orderSetting);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
try {
//关闭允许投诉
closeComplaint(orderSetting);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
/**
@ -115,6 +125,7 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
queryWrapper.le(Order::getLogisticsTime, receiveTime);
List<Order> list = orderService.list(queryWrapper);
try {
//判断是否有符合条件的订单进行订单完成处理
if (!list.isEmpty()) {
List<String> receiveSnList = list.stream().map(Order::getSn).collect(Collectors.toList());
@ -122,6 +133,9 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
orderService.systemComplete(orderSn);
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
/**
@ -152,7 +166,12 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
memberEvaluationDTO.setDescriptionScore(5);
memberEvaluationDTO.setServiceScore(5);
try {
memberEvaluationService.addMemberEvaluation(memberEvaluationDTO, false);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
}
@ -164,7 +183,10 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
* @param orderSetting 订单设置
*/
private void closeAfterSale(OrderSetting orderSetting) {
//为0则不限制
if (orderSetting.getCloseAfterSale() == null || orderSetting.getCloseAfterSale() == 0) {
return;
}
//订单关闭售后申请时间 = 当前时间 - 自动关闭售后申请天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getCloseAfterSale());
@ -205,6 +227,10 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
*/
private void closeComplaint(OrderSetting orderSetting) {
//为0则不限制
if (orderSetting.getCloseComplaint() == null || orderSetting.getCloseComplaint() == 0) {
return;
}
//订单关闭交易投诉申请时间 = 当前时间 - 自动关闭交易投诉申请天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getCloseComplaint());

View File

@ -72,7 +72,8 @@ public class OnlineMemberStatistics implements EveryHourExecute {
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
onlineMemberVOS.add(new OnlineMemberVO(calendar.getTime(), cache.keys(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MEMBER) + "*").size(), lastNum.get()));
onlineMemberVOS.add(new OnlineMemberVO(calendar.getTime(), cache.keys(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MEMBER) + "*").size(),
lastNum.get()));
//写入缓存
cache.put(CachePrefix.ONLINE_MEMBER.getPrefix(), onlineMemberVOS);

View File

@ -555,4 +555,16 @@ public enum CachePrefix {
public String getPrefix(UserEnums user) {
return "{" + this.name() + "_" + user.name() + "}_";
}
/**
* 获取缓存key值 + 用户端 +自定义前缀
* 例如三端都有用户体系需要分别登录如果用户名一致则redis中的权限可能会冲突出错
*
* @param user 角色
* @param customPrefix 自定义前缀
* @return 缓存key值
*/
public String getPrefix(UserEnums user, String customPrefix) {
return "{" + this.name() + "_" + user.name() + "}_" + customPrefix + "_";
}
}

View File

@ -19,6 +19,7 @@ import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "lili.data.rocketmq")
public class RocketmqCustomProperties {
private String promotionTopic;
private String promotionGroup;

View File

@ -65,7 +65,7 @@ public class UserContext {
AuthUser authUser = getAuthUser(accessToken);
assert authUser != null;
if (!cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(authUser.getRole()) + accessToken)) {
if (!cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(authUser.getRole(), authUser.getId()) + accessToken)) {
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
return authUser;

View File

@ -42,13 +42,13 @@ public class TokenUtil {
//访问token
String accessToken = createToken(authUser, tokenProperties.getTokenExpireTime());
cache.put(CachePrefix.ACCESS_TOKEN.getPrefix(authUser.getRole()) + accessToken, 1,
cache.put(CachePrefix.ACCESS_TOKEN.getPrefix(authUser.getRole(), authUser.getId()) + accessToken, 1,
tokenProperties.getTokenExpireTime(), TimeUnit.MINUTES);
//刷新token生成策略如果是长时间有效的token用于app则默认15天有效期刷新token如果是普通用户登录则刷新token为普通token2倍数
Long expireTime = authUser.getLongTerm() ? 15 * 24 * 60L : tokenProperties.getTokenExpireTime() * 2;
String refreshToken = createToken(authUser, expireTime);
cache.put(CachePrefix.REFRESH_TOKEN.getPrefix(authUser.getRole()) + refreshToken, 1, expireTime, TimeUnit.MINUTES);
cache.put(CachePrefix.REFRESH_TOKEN.getPrefix(authUser.getRole(), authUser.getId()) + refreshToken, 1, expireTime, TimeUnit.MINUTES);
token.setAccessToken(accessToken);
token.setRefreshToken(refreshToken);
@ -85,11 +85,12 @@ public class TokenUtil {
//如果缓存中有刷新token &&
if (cache.hasKey(CachePrefix.REFRESH_TOKEN.getPrefix(userEnums) + oldRefreshToken)) {
if (cache.hasKey(CachePrefix.REFRESH_TOKEN.getPrefix(userEnums, authUser.getId()) + oldRefreshToken)) {
Token token = new Token();
//访问token
String accessToken = createToken(authUser, tokenProperties.getTokenExpireTime());
cache.put(CachePrefix.ACCESS_TOKEN.getPrefix(userEnums) + accessToken, 1, tokenProperties.getTokenExpireTime(), TimeUnit.MINUTES);
cache.put(CachePrefix.ACCESS_TOKEN.getPrefix(userEnums, authUser.getId()) + accessToken, 1, tokenProperties.getTokenExpireTime(),
TimeUnit.MINUTES);
//如果是信任登录设备则刷新token长度继续延长
Long expirationTime = tokenProperties.getTokenExpireTime() * 2;
@ -101,10 +102,10 @@ public class TokenUtil {
//刷新token生成策略如果是长时间有效的token用于app则默认15天有效期刷新token如果是普通用户登录则刷新token为普通token2倍数
String refreshToken = createToken(authUser, expirationTime);
cache.put(CachePrefix.REFRESH_TOKEN.getPrefix(userEnums) + refreshToken, 1, expirationTime, TimeUnit.MINUTES);
cache.put(CachePrefix.REFRESH_TOKEN.getPrefix(userEnums, authUser.getId()) + refreshToken, 1, expirationTime, TimeUnit.MINUTES);
token.setAccessToken(accessToken);
token.setRefreshToken(refreshToken);
cache.remove(CachePrefix.REFRESH_TOKEN.getPrefix(userEnums) + oldRefreshToken);
cache.remove(CachePrefix.REFRESH_TOKEN.getPrefix(userEnums, authUser.getId()) + oldRefreshToken);
return token;
} else {
throw new ServiceException(ResultCode.USER_AUTH_EXPIRED);

View File

@ -90,6 +90,7 @@ public abstract class BaseElasticsearchService {
request.settings(Settings.builder()
.put("index.number_of_shards", elasticsearchProperties.getIndex().getNumberOfShards())
.put("index.number_of_replicas", elasticsearchProperties.getIndex().getNumberOfReplicas())
.put("index.max_result_window", 100000) //最大查询结果数
.put("index.mapping.total_fields.limit", 2000));
//创建索引

View File

@ -1,7 +1,9 @@
package cn.lili.modules.connect.entity.dto;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.modules.connect.config.ConnectAuthEnum;
import cn.lili.modules.connect.entity.enums.AuthUserGender;
import cn.lili.modules.connect.entity.enums.ConnectEnum;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -65,14 +67,15 @@ public class ConnectAuthUser implements Serializable {
private AuthUserGender gender;
/**
* 用户来源
* 例如QQ微信微博等
*/
private String source;
private ConnectEnum source;
/**
* 类型
* 类型-客户端类型
* 例如PCWAP小程序
*/
private String type;
private ClientTypeEnum type;
/**
* 用户授权的token信息
*/

View File

@ -12,6 +12,8 @@ import cn.lili.modules.connect.entity.dto.AuthToken;
import cn.lili.modules.connect.entity.dto.ConnectAuthUser;
import cn.lili.modules.connect.entity.enums.AuthResponseStatus;
import cn.lili.modules.connect.entity.enums.AuthUserGender;
import cn.lili.modules.connect.entity.enums.ConnectEnum;
import cn.lili.modules.connect.entity.enums.SourceEnum;
import cn.lili.modules.connect.exception.AuthException;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
@ -119,7 +121,7 @@ public class BaseAuthAlipayRequest extends BaseAuthRequest {
.location(location)
.gender(AuthUserGender.getRealGender(response.getGender()))
.token(authToken)
.source(source.toString())
.source(ConnectEnum.ALIPAY)
.build();
}

View File

@ -69,8 +69,8 @@ public class BaseAuthQQRequest extends BaseAuthRequest {
.uuid(openId)
.gender(AuthUserGender.getRealGender(object.getString("gender")))
.token(authToken)
.source(ConnectEnum.QQ.name())
.type(ClientTypeEnum.PC.name())
.source(ConnectEnum.QQ)
.type(ClientTypeEnum.PC)
.build();
}

View File

@ -62,8 +62,8 @@ public class BaseAuthWeChatPCRequest extends BaseAuthRequest {
.uuid(authToken.getOpenId())
.gender(AuthUserGender.getWechatRealGender(object.getString("sex")))
.token(authToken)
.source(ConnectEnum.WECHAT.name())
.type(ClientTypeEnum.PC.name())
.source(ConnectEnum.WECHAT)
.type(ClientTypeEnum.PC)
.build();
}

View File

@ -64,8 +64,8 @@ public class BaseAuthWeChatRequest extends BaseAuthRequest {
.uuid(openId)
.gender(AuthUserGender.getWechatRealGender(object.getString("sex")))
.token(authToken)
.source(ConnectEnum.WECHAT.name())
.type(ClientTypeEnum.H5.name())
.source(ConnectEnum.WECHAT)
.type(ClientTypeEnum.H5)
.build();
}

View File

@ -12,6 +12,7 @@ import cn.lili.modules.connect.entity.dto.AuthToken;
import cn.lili.modules.connect.entity.dto.ConnectAuthUser;
import cn.lili.modules.connect.entity.enums.AuthResponseStatus;
import cn.lili.modules.connect.entity.enums.AuthUserGender;
import cn.lili.modules.connect.entity.enums.ConnectEnum;
import cn.lili.modules.connect.exception.AuthException;
import cn.lili.common.utils.HttpUtils;
import cn.lili.common.utils.IpUtils;
@ -72,7 +73,7 @@ public class BaseAuthWeiboRequest extends BaseAuthRequest {
.remark(object.getString("description"))
.gender(AuthUserGender.getRealGender(object.getString("gender")))
.token(authToken)
.source(source.toString())
.source(ConnectEnum.WEIBO)
.build();
}

View File

@ -191,15 +191,11 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
String phone = (String) userInfo.get("purePhoneNumber");
connectAuthUser.setUsername("m" + phone);
connectAuthUser.setPhone(phone);
connectAuthUser.setSource(ConnectEnum.WECHAT.name());
connectAuthUser.setType(ClientTypeEnum.WECHAT_MP.name());
} else {
connectAuthUser.setUsername(UuidUtils.getUUID());
connectAuthUser.setSource(ConnectEnum.WECHAT.name());
connectAuthUser.setType(ClientTypeEnum.WECHAT_MP.name());
}
connectAuthUser.setSource(ConnectEnum.WECHAT);
connectAuthUser.setType(ClientTypeEnum.WECHAT_MP);
AuthToken authToken = new AuthToken();
authToken.setUnionId(unionId);
@ -221,7 +217,7 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
connectQueryDTO.getUnionType())
.eq(CharSequenceUtil.isNotEmpty(connectQueryDTO.getUnionId()), Connect::getUnionId,
connectQueryDTO.getUnionId());
return this.getOne(queryWrapper);
return this.getOne(queryWrapper,false);
}
@Override
@ -270,8 +266,14 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
*/
private Token unionLoginCallback(ConnectAuthUser authUser, boolean longTerm) {
try {
Member member =null;
//判断是否传递手机号如果传递手机号则使用手机号登录
if(StrUtil.isNotBlank(authUser.getPhone())){
member = memberService.findByMobile(authUser.getPhone());
}
//如果未查到手机号的会员则使用第三方登录
if(member==null){
LambdaQueryWrapper<Connect> queryWrapper = new LambdaQueryWrapper<Connect>();
//使用UnionId登录
if (StrUtil.isNotBlank(authUser.getToken().getUnionId())) {
@ -279,15 +281,14 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
.eq(Connect::getUnionType, authUser.getSource());
} else {
//使用OpenID登录
SourceEnum sourceEnum = SourceEnum.getSourceEnum(ConnectEnum.valueOf(authUser.getType()),
ClientTypeEnum.valueOf(authUser.getSource()));
queryWrapper.eq(Connect::getUnionId, authUser.getToken().getUnionId())
SourceEnum sourceEnum = SourceEnum.getSourceEnum(authUser.getSource(), authUser.getType());
queryWrapper.eq(Connect::getUnionId, authUser.getUuid())
.eq(Connect::getUnionType, sourceEnum.name());
}
//查询绑定关系
Connect connect = this.getOne(queryWrapper);
Member member = new Member();
if (connect == null) {
member = memberService.autoRegister(authUser);
} else {
@ -299,6 +300,7 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
member = memberService.autoRegister(authUser);
}
}
}
//发送用户第三方登录消息
MemberConnectLoginMessage memberConnectLoginMessage = new MemberConnectLoginMessage();

View File

@ -184,4 +184,10 @@ public interface GoodsService extends IService<Goods> {
*/
long countStoreGoodsNum(String storeId);
/**
* 同步商品分类名称
*
* @param categoryId 分类ID
*/
void categoryGoodsName(String categoryId);
}

View File

@ -4,7 +4,9 @@ import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.event.TransactionCommitSendMQEvent;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.modules.goods.entity.dos.Category;
import cn.lili.modules.goods.entity.vos.CategoryVO;
import cn.lili.modules.goods.mapper.CategoryMapper;
@ -12,16 +14,19 @@ import cn.lili.modules.goods.service.CategoryBrandService;
import cn.lili.modules.goods.service.CategoryParameterGroupService;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.goods.service.CategorySpecificationService;
import cn.lili.rocketmq.tags.GoodsTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -55,6 +60,20 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
@Autowired
private CategorySpecificationService categorySpecificationService;
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
/**
* rocketMq
*/
@Autowired
private RocketMQTemplate rocketMQTemplate;
/**
* rocketMq配置
*/
@Autowired
private RocketmqCustomProperties rocketmqCustomProperties;
@Override
public List<Category> dbList(String parentId) {
return this.list(new LambdaQueryWrapper<Category>().eq(Category::getParentId, parentId));
@ -244,6 +263,8 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
updateWrapper.eq("id", category.getId());
this.baseMapper.update(category, updateWrapper);
removeCache();
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("同步商品分类名称",
rocketmqCustomProperties.getGoodsTopic(), GoodsTagsEnum.CATEGORY_GOODS_NAME.name(), category.getId()));
}

View File

@ -1,9 +1,11 @@
package cn.lili.modules.goods.serviceimpl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.modules.goods.entity.dos.Category;
import cn.lili.modules.goods.entity.dos.GoodsUnit;
import cn.lili.modules.goods.entity.dto.GoodsImportDTO;
@ -31,10 +33,7 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
@Slf4j
@Service
@ -51,10 +50,12 @@ public class GoodsImportServiceImpl implements GoodsImportService {
@Autowired
private GoodsService goodsService;
private static final int COLUMS = 15;
@Override
public void download(HttpServletResponse response) {
String storeId = "1376369067769724928";
// //Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId();
// String storeId = "1376369067769724928";
String storeId = Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId();
//创建Excel工作薄对象
Workbook workbook = new HSSFWorkbook();
//生成一个表格 设置页签
@ -165,6 +166,14 @@ public class GoodsImportServiceImpl implements GoodsImportService {
List<List<Object>> read = excelReader.read(1, excelReader.getRowCount());
for (List<Object> objects : read) {
GoodsImportDTO goodsImportDTO = new GoodsImportDTO();
if (objects.size() < COLUMS){
throw new ServiceException("请将表格内容填写完全!");
}
for (Object object : objects) {
if( CharSequenceUtil.isEmpty(object.toString()) || CharSequenceUtil.isBlank(object.toString())){
throw new ServiceException("请将表格内容填写完全!");
}
}
String categoryId = objects.get(2).toString().substring(0, objects.get(2).toString().indexOf("-"));

View File

@ -494,6 +494,16 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
.eq(Goods::getMarketEnable, GoodsStatusEnum.UPPER.name()));
}
@Override
public void categoryGoodsName(String categoryId) {
//获取分类下的商品
List<Goods> list = this.list(new LambdaQueryWrapper<Goods>().like(Goods::getCategoryPath,categoryId));
list.parallelStream().forEach(goods->{
//移除redis中商品缓存
cache.remove(CachePrefix.GOODS.getPrefix() + goods.getId());
});
}
/**
* 更新商品状态

View File

@ -3,6 +3,7 @@ package cn.lili.modules.goods.serviceimpl;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
@ -529,9 +530,9 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
public void updateStock(String skuId, Integer quantity) {
GoodsSku goodsSku = getGoodsSkuByIdFromCache(skuId);
if (goodsSku != null) {
if (quantity <= 0) {
goodsIndexService.deleteIndexById(goodsSku.getId());
}
//判断商品sku是否已经下架(修改商品库存为0时 会自动下架商品),再次更新商品库存时 需更新商品索引
Boolean isFlag = goodsSku.getQuantity()<= 0;
goodsSku.setQuantity(quantity);
boolean update =
this.update(new LambdaUpdateWrapper<GoodsSku>().eq(GoodsSku::getId, skuId).set(GoodsSku::getQuantity, quantity));
@ -546,6 +547,16 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
goodsSkus.add(goodsSku);
this.updateGoodsStuck(goodsSkus);
this.promotionGoodsService.updatePromotionGoodsStock(goodsSku.getId(), quantity);
//商品库存为0是删除商品索引
if (quantity <= 0) {
goodsIndexService.deleteIndexById(goodsSku.getId());
}
//商品SKU库存为0并且商品sku状态为上架时更新商品库存
if(isFlag && StrUtil.equals(goodsSku.getMarketEnable(),GoodsStatusEnum.UPPER.name())) {
List<String> goodsIds = new ArrayList<>();
goodsIds.add(goodsSku.getGoodsId());
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("更新商品", rocketmqCustomProperties.getGoodsTopic(), GoodsTagsEnum.UPDATE_GOODS_INDEX.name(), goodsIds));
}
}
}

View File

@ -200,8 +200,9 @@ public class KdniaoPlugin implements LogisticsPlugin {
JSONObject obj = JSONObject.parseObject(result);
log.info("电子面单响应:{}", result);
if (!"100".equals(obj.getString("ResultCode"))) {
resultMap.put("Reason",obj.getString("Reason"));
return resultMap;
// resultMap.put("Reason",obj.getString("Reason"));
throw new ServiceException(obj.getString("Reason"));
// return resultMap;
}
JSONObject orderJson = JSONObject.parseObject(obj.getString("Order"));

View File

@ -110,7 +110,7 @@ public class Member extends BaseEntity {
this.lastLoginDate = new Date();
}
public Member(String username, String password, String mobile, String nickName, String face) {
public Member(String username, String password, String face, String nickName, Integer sex,String mobile) {
this.username = username;
this.password = password;
this.mobile = mobile;
@ -118,20 +118,6 @@ public class Member extends BaseEntity {
this.disabled = true;
this.haveStore = false;
this.face = face;
this.sex = 0;
this.point = 0L;
this.totalPoint = 0L;
this.lastLoginDate = new Date();
}
public Member(String username, String password, String face, String nickName, Integer sex) {
this.username = username;
this.password = password;
this.mobile = "";
this.nickName = nickName;
this.disabled = true;
this.haveStore = false;
this.face = face;
this.sex = sex;
this.point = 0L;
this.totalPoint = 0L;

View File

@ -11,11 +11,10 @@ import cn.lili.modules.member.entity.dto.MemberAddDTO;
import cn.lili.modules.member.entity.dto.MemberEditDTO;
import cn.lili.modules.member.entity.vo.MemberSearchVO;
import cn.lili.modules.member.entity.vo.MemberVO;
import cn.lili.modules.member.entity.vo.QRLoginResultVo;
import cn.lili.modules.member.entity.vo.QRCodeLoginSessionVo;
import cn.lili.modules.member.entity.vo.QRLoginResultVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.elasticsearch.monitor.os.OsStats;
import java.util.List;
import java.util.Map;
@ -148,6 +147,14 @@ public interface MemberService extends IService<Member> {
*/
boolean changeMobile(String mobile);
/**
* 修改用户手机号
* @param memberId 会员ID
* @param mobile 手机号
* @return
*/
boolean changeMobile(String memberId,String mobile);
/**
* 通过手机号修改密码
@ -260,6 +267,13 @@ public interface MemberService extends IService<Member> {
*/
void logout(UserEnums userEnums);
/**
* 登出
*
* @param userId 用户id
*/
void logout(String userId);
/**
* 修改会员是否拥有店铺
*

View File

@ -189,10 +189,12 @@ public class ClerkServiceImpl extends ServiceImpl<ClerkMapper, Clerk> implements
clerk.setIsSuper(clerkAddDTO.getIsSuper());
//校验此会员是否已经是店员
Clerk temp = this.getClerkByMemberId(clerkAddDTO.getMemberId());
if (temp != null && !temp.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) {
//店员信息不为空
if (temp != null && !temp.getStoreId().equals(clerkAddDTO.getStoreId())) {
throw new ServiceException(ResultCode.CLERK_USER_ERROR);
}
if (temp != null && temp.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) {
if (temp != null && temp.getStoreId().equals(clerkAddDTO.getStoreId())) {
throw new ServiceException(ResultCode.CLERK_ALREADY_EXIT_ERROR);
}
//部门校验

View File

@ -122,6 +122,9 @@ public class MemberEvaluationServiceImpl extends ServiceImpl<MemberEvaluationMap
} else {
//获取用户信息 非自己评价时读取数据库
member = memberService.getById(order.getMemberId());
if (member == null) {
throw new ServiceException(ResultCode.USER_NOT_EXIST);
}
}
//获取商品信息
GoodsSku goodsSku = goodsSkuService.getGoodsSkuByIdFromCache(memberEvaluationDTO.getSkuId());

View File

@ -19,7 +19,6 @@ import cn.lili.common.security.token.Token;
import cn.lili.common.sensitive.SensitiveWordsFilter;
import cn.lili.common.utils.*;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.connect.config.ConnectAuthEnum;
import cn.lili.modules.connect.entity.Connect;
import cn.lili.modules.connect.entity.dto.ConnectAuthUser;
import cn.lili.modules.connect.service.ConnectService;
@ -248,9 +247,9 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
authUser.setAvatar("https://i.loli.net/2020/11/19/LyN6JF7zZRskdIe.png");
}
try {
String username = UuidUtils.getUUID();
Member member = new Member(username, UuidUtils.getUUID(), authUser.getAvatar(), authUser.getNickname(),
authUser.getGender() != null ? Convert.toInt(authUser.getGender().getCode()) : 0);
// String username = UuidUtils.getUUID();
Member member = new Member(authUser.getUsername(), UuidUtils.getUUID(), authUser.getAvatar(), authUser.getNickname(),
authUser.getGender() != null ? Convert.toInt(authUser.getGender().getCode()) : 0,authUser.getPhone());
member.setPassword(DEFAULT_PASSWORD);
// 发送会员注册信息
registerHandler(member);
@ -309,7 +308,8 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
this.save(member);
// 发送会员注册信息
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("new member register", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_REGISTER.name(), member));
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("new member register", rocketmqCustomProperties.getMemberTopic(),
MemberTagsEnum.MEMBER_REGISTER.name(), member));
}
@Override
@ -431,6 +431,15 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
return this.update(lambdaUpdateWrapper);
}
@Override
public boolean changeMobile(String memberId, String mobile) {
//修改会员手机号
LambdaUpdateWrapper<Member> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.eq(Member::getId, memberId);
lambdaUpdateWrapper.set(Member::getMobile, mobile);
return this.update(lambdaUpdateWrapper);
}
@Override
public boolean resetByMobile(String uuid, String password) {
String phone = cache.get(CachePrefix.FIND_MOBILE + uuid).toString();
@ -456,7 +465,8 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
checkMember(memberAddDTO.getUsername(), memberAddDTO.getMobile());
//添加会员
Member member = new Member(memberAddDTO.getUsername(), new BCryptPasswordEncoder().encode(memberAddDTO.getPassword()), memberAddDTO.getMobile());
Member member = new Member(memberAddDTO.getUsername(), new BCryptPasswordEncoder().encode(memberAddDTO.getPassword()),
memberAddDTO.getMobile());
registerHandler(member);
return member;
}
@ -525,7 +535,8 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
memberPointMessage.setPoint(point);
memberPointMessage.setType(type);
memberPointMessage.setMemberId(memberId);
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("update member point", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_POINT_CHANGE.name(), memberPointMessage));
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("update member point",
rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_POINT_CHANGE.name(), memberPointMessage));
return true;
}
return false;
@ -540,6 +551,10 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
updateWrapper.set("disabled", status);
updateWrapper.in("id", memberIds);
//如果是禁用
if (Boolean.FALSE.equals(status)) {
disableMemberLogout(memberIds);
}
return this.update(updateWrapper);
}
@ -680,8 +695,33 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
@Override
public void logout(UserEnums userEnums) {
String currentUserToken = UserContext.getCurrentUserToken();
AuthUser authUser = UserContext.getAuthUser(currentUserToken);
if (CharSequenceUtil.isNotEmpty(currentUserToken)) {
cache.remove(CachePrefix.ACCESS_TOKEN.getPrefix(userEnums) + currentUserToken);
cache.remove(CachePrefix.ACCESS_TOKEN.getPrefix(userEnums, authUser.getId()) + currentUserToken);
cache.vagueDel(CachePrefix.REFRESH_TOKEN.getPrefix(userEnums, authUser.getId()) );
}
}
@Override
public void logout(String userId) {
cache.vagueDel(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MANAGER, userId));
cache.vagueDel(CachePrefix.REFRESH_TOKEN.getPrefix(UserEnums.MANAGER, userId));
}
/**
* 禁用会员会员token删除
*
* @param memberIds 会员id
*/
public void disableMemberLogout(List<String> memberIds) {
if (memberIds != null) {
memberIds.forEach(memberId -> {
cache.vagueDel(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MEMBER, memberId));
cache.vagueDel(CachePrefix.REFRESH_TOKEN.getPrefix(UserEnums.MEMBER, memberId));
});
}
}

View File

@ -1,5 +1,6 @@
package cn.lili.modules.member.serviceimpl;
import cn.hutool.core.util.ObjectUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.RocketmqCustomProperties;
@ -19,6 +20,7 @@ import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.MemberTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
@ -62,8 +64,16 @@ public class MemberSignServiceImpl extends ServiceImpl<MemberSignMapper, MemberS
public Boolean memberSign() {
//获取当前会员信息
AuthUser authUser = UserContext.getCurrentUser();
if (authUser != null) {
if (ObjectUtil.isNotNull(authUser)) {
//获取当前用户当日签到日信息
LambdaQueryWrapper<MemberSign> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(MemberSign::getMemberId, authUser.getId());
queryWrapper.eq(MemberSign::getDay,DateUtil.getDayOfStart().intValue());
List<MemberSign> signSize = this.baseMapper.getTodayMemberSign(queryWrapper);
//当日签到信息不为空
if (!signSize.isEmpty()) {
throw new ServiceException(ResultCode.MEMBER_SIGN_REPEAT);
}
//当前签到天数的前一天日期
List<MemberSign> signs = this.baseMapper.getBeforeMemberSign(authUser.getId());
//构建参数

View File

@ -269,14 +269,15 @@ public class AfterSaleServiceImpl extends ServiceImpl<AfterSaleMapper, AfterSale
//根据售后单号获取售后单
AfterSale afterSale = OperationalJudgment.judgment(this.getBySn(afterSaleSn));
return logisticsService.getLogisticTrack(afterSale.getMLogisticsCode(), afterSale.getMLogisticsNo(), storeDetailService.getStoreDetail(afterSale.getStoreId()).getSalesConsigneeMobile());
return logisticsService.getLogisticTrack(afterSale.getMLogisticsCode(), afterSale.getMLogisticsNo(),
storeDetailService.getStoreDetail(afterSale.getStoreId()).getSalesConsigneeMobile());
}
@Override
@AfterSaleLogPoint(sn = "#afterSaleSn", description = "'售后-商家收货:单号['+#afterSaleSn+']" +
",处理结果['+serviceStatus='PASS'?'商家收货':'商家拒收'+']'")
@SystemLogPoint(description = "售后-商家收货", customerLog = "'售后-商家收货:单号['+#afterSaleSn+']" +
",处理结果['+serviceStatus='PASS'?'商家收货':'商家拒收'+']'")
@AfterSaleLogPoint(sn = "#afterSaleSn", description = "#serviceStatus.equals('PASS')?" +
"'售后-商家收货:单号['+#afterSaleSn+'],处理结果[商家收货]':'售后-商家收货:单号['+#afterSaleSn+'],处理结果[商家拒收],原因['+#remark+']'")
@SystemLogPoint(description = "售后-商家收货", customerLog = "#serviceStatus.equals('PASS')?" +
"'售后-商家收货:单号['+#afterSaleSn+'],处理结果[商家收货]':'售后-商家收货:单号['+#afterSaleSn+'],处理结果[商家拒收],原因['+#remark+']'")
@Transactional(rollbackFor = Exception.class)
public AfterSale storeConfirm(String afterSaleSn, String serviceStatus, String remark) {
//根据售后单号获取售后单
@ -515,7 +516,8 @@ public class AfterSaleServiceImpl extends ServiceImpl<AfterSaleMapper, AfterSale
break;
case RETURN_GOODS:
//是否为有效状态
boolean availableStatus = CharSequenceUtil.equalsAny(order.getOrderStatus(), OrderStatusEnum.DELIVERED.name(), OrderStatusEnum.COMPLETED.name());
boolean availableStatus = CharSequenceUtil.equalsAny(order.getOrderStatus(), OrderStatusEnum.DELIVERED.name(),
OrderStatusEnum.COMPLETED.name());
if (!PayStatusEnum.PAID.name().equals(order.getPayStatus()) && availableStatus) {
throw new ServiceException(ResultCode.AFTER_SALES_BAN);
}

View File

@ -16,6 +16,7 @@ import cn.lili.modules.order.cart.render.util.PromotionPriceUtil;
import cn.lili.modules.order.order.entity.dto.DiscountPriceItem;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.promotion.entity.dos.FullDiscount;
import cn.lili.modules.promotion.entity.enums.PromotionsScopeTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -70,6 +71,9 @@ public class FullDiscountRender implements CartRenderStep {
cart.setFullDiscount(fullDiscountVO);
Map<String, Double> skuPriceDetail = new HashMap<>(16);
for (CartSkuVO cartSkuVO : cart.getSkuList()) {
if (PromotionsScopeTypeEnum.PORTION_GOODS.name().equals(fullDiscountVO.getScopeType()) && fullDiscountVO.getScopeId() != null && !fullDiscountVO.getScopeId().contains(cartSkuVO.getGoodsSku().getId())) {
continue;
}
skuPriceDetail.put(cartSkuVO.getGoodsSku().getId(), cartSkuVO.getPriceDetailDTO().getGoodsPrice());
}
if (!skuPriceDetail.isEmpty()) {

View File

@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 促销价格计算业务层实现
@ -28,7 +29,8 @@ public class PromotionPriceUtil {
* @param discountPrice 需要分发的优惠金额
* @param promotionTypeEnum 促销类型
*/
public static void recountPrice(TradeDTO tradeDTO, Map<String, Double> skuPromotionDetail, Double discountPrice, PromotionTypeEnum promotionTypeEnum, String activityId) {
public static void recountPrice(TradeDTO tradeDTO, Map<String, Double> skuPromotionDetail, Double discountPrice,
PromotionTypeEnum promotionTypeEnum, String activityId) {
// sku 促销信息非空判定
if (skuPromotionDetail == null || skuPromotionDetail.size() == 0) {
@ -66,7 +68,7 @@ public class PromotionPriceUtil {
List<CartSkuVO> skuVOList = tradeDTO.getSkuList();
// 获取map分配sku的总数如果是最后一个商品分配金额则将金额从百分比改为总金额扣减避免出现小数除不尽
Integer count = skuPromotionDetail.size();
int count = skuPromotionDetail.size();
//已优惠金额
Double deducted = 0D;
@ -81,12 +83,12 @@ public class PromotionPriceUtil {
count--;
//sku 优惠金额
Double skuDiscountPrice = 0d;
Double skuDiscountPrice;
//非最后一个商品则按照比例计算
if (count > 0) {
//商品金额占比
Double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
//商品优惠金额
skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
//累加已优惠金额
@ -96,6 +98,27 @@ public class PromotionPriceUtil {
else {
skuDiscountPrice = CurrencyUtil.sub(discountPrice, deducted);
}
calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId);
}
}
}
calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId);
}
/**
* 计算购物车商品优惠金额
*
* @param cartSkuVO 购物车商品
* @param skuDiscountPrice 商品优惠金额
* @param promotionTypeEnum 优惠类型
* @param activityId 优惠活动id
*/
private static void calculateCartSkuPromotionsPrice(CartSkuVO cartSkuVO, Double skuDiscountPrice, PromotionTypeEnum promotionTypeEnum,
String activityId) {
//优惠券金额则计入优惠券 其他则计入总的discount price
if (promotionTypeEnum == PromotionTypeEnum.COUPON) {
@ -147,12 +170,68 @@ public class PromotionPriceUtil {
);
}
}
/**
* 特殊情况处理如参与多个促销活动部分商品在其他促销计算后的金额不足以满足与当前参与的促销活动的优惠金额只计算使用优惠券不足的情况
*
* @param skuVOList 获取购物车信息
* @param skuPromotionDetail 参与活动的商品以及商品总金额
* @param discountPrice 需要分发的优惠金额
* @param totalPrice 计算总金额
* @param promotionTypeEnum 优惠类型
* @param activityId 优惠活动id
*/
private static void calculateNotEnoughPromotionsPrice(List<CartSkuVO> skuVOList, Map<String, Double> skuPromotionDetail, Double discountPrice,
Double totalPrice, PromotionTypeEnum promotionTypeEnum, String activityId) {
// 特殊情况处理如参与多个促销活动部分商品在其他促销计算后的金额不足以满足与当前参与的促销活动的优惠金额
// 但当前购物车内存在当前当前促销活动的其他商品且剩余金额也满足分摊不足商品的不足金额则分摊到其他商品上
// 满足当前促销的总优惠金额
if (skuPromotionDetail == null || skuPromotionDetail.isEmpty()) {
return;
}
long matchPromotionsZeroCount =
skuVOList.stream().filter(l -> l.getPriceDetailDTO().getFlowPrice() == 0 && skuPromotionDetail.containsKey(l.getGoodsSku().getId())).count();
long matchPromotionsCount = skuVOList.stream().filter(l -> skuPromotionDetail.containsKey(l.getGoodsSku().getId())).count();
if (matchPromotionsZeroCount == matchPromotionsCount) {
return;
}
// 获取剩余金额不足优惠金额的商品
List<CartSkuVO> unEnoughSku = skuVOList.stream().filter(k -> {
if (skuPromotionDetail.containsKey(k.getGoodsSku().getId()) && skuPromotionDetail.size() >= 2) {
//商品金额占比
double point = CurrencyUtil.div(k.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
//商品优惠金额
Double skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
return k.getPriceDetailDTO().getCouponPrice() > 0 && skuDiscountPrice > k.getPriceDetailDTO().getCouponPrice();
}
return false;
}).collect(Collectors.toList());
if (!unEnoughSku.isEmpty()) {
if (unEnoughSku.size() == skuVOList.size()) {
return;
}
for (CartSkuVO cartSkuVO : skuVOList) {
if (unEnoughSku.isEmpty()) {
break;
}
if (skuPromotionDetail.containsKey(cartSkuVO.getGoodsSku().getId()) && unEnoughSku.stream().noneMatch(k -> k.getGoodsSku().getId().equals(cartSkuVO.getGoodsSku().getId()))) {
// 商品金额占比
double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
// 商品优惠金额
Double skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
// 商品优惠金额 - 不足优惠金额 = 差额
Double sub = CurrencyUtil.sub(skuDiscountPrice, unEnoughSku.get(0).getPriceDetailDTO().getCouponPrice());
// 分摊到其他商品 其他商品原优惠金额 + 差额
calculateCartSkuPromotionsPrice(cartSkuVO, sub, promotionTypeEnum, activityId);
// 从不足商品列表中移除
unEnoughSku.remove(0);
}
}
} else {
return;
}
calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId);
}
/**
* 检查活动有效时间

View File

@ -19,6 +19,7 @@ import cn.lili.modules.system.entity.dto.payment.dto.PaymentSupportItem;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply;
import cn.lili.modules.wallet.entity.dto.TransferResultDTO;
import cn.lili.modules.wallet.service.MemberWalletService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -149,7 +150,7 @@ public class CashierSupport {
* @param paymentMethodEnum 支付渠道
* @param memberWithdrawApply 用户提现申请
*/
public boolean transfer(PaymentMethodEnum paymentMethodEnum, MemberWithdrawApply memberWithdrawApply) {
public TransferResultDTO transfer(PaymentMethodEnum paymentMethodEnum, MemberWithdrawApply memberWithdrawApply) {
Payment payment = (Payment) SpringContextUtil.getBean(paymentMethodEnum.getPlugin());
return payment.transfer(memberWithdrawApply);
}

View File

@ -7,6 +7,7 @@ import cn.lili.modules.payment.entity.RefundLog;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.modules.payment.kit.dto.PayParam;
import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply;
import cn.lili.modules.wallet.entity.dto.TransferResultDTO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -114,7 +115,7 @@ public interface Payment {
/**
* 提现
*/
default boolean transfer(MemberWithdrawApply memberWithdrawApply) {
default TransferResultDTO transfer(MemberWithdrawApply memberWithdrawApply) {
throw new ServiceException(ResultCode.PAY_ERROR);
}

View File

@ -27,6 +27,7 @@ import cn.lili.modules.system.entity.dto.payment.AlipayPaymentSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply;
import cn.lili.modules.wallet.entity.dto.TransferResultDTO;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.*;
@ -170,7 +171,8 @@ public class AliPayPlugin implements Payment {
payModel.setTimeoutExpress("3m");
payModel.setOutTradeNo(outTradeNo);
log.info("支付宝扫码:{}", payModel);
String resultStr = AliPayRequest.tradePrecreatePayToResponse(payModel, notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.ALIPAY)).getBody();
String resultStr =
AliPayRequest.tradePrecreatePayToResponse(payModel, notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.ALIPAY)).getBody();
log.info("支付宝扫码交互返回:{}", resultStr);
JSONObject jsonObject = JSONObject.parseObject(resultStr);
@ -202,7 +204,8 @@ public class AliPayPlugin implements Payment {
refundLog.setIsRefund(true);
refundLog.setReceivableNo(refundLog.getOutOrderNo());
} else {
refundLog.setErrorMessage(String.format("错误码:%s,错误原因:%s", alipayTradeRefundResponse.getSubCode(), alipayTradeRefundResponse.getSubMsg()));
refundLog.setErrorMessage(String.format("错误码:%s,错误原因:%s", alipayTradeRefundResponse.getSubCode(),
alipayTradeRefundResponse.getSubMsg()));
}
refundLogService.save(refundLog);
} catch (Exception e) {
@ -237,7 +240,7 @@ public class AliPayPlugin implements Payment {
* @param memberWithdrawApply 会员提现申请
*/
@Override
public boolean transfer(MemberWithdrawApply memberWithdrawApply) {
public TransferResultDTO transfer(MemberWithdrawApply memberWithdrawApply) {
AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
model.setOutBizNo(SnowFlake.createStr("T"));
model.setRemark("用户提现");
@ -257,15 +260,15 @@ public class AliPayPlugin implements Payment {
AlipayFundTransUniTransferResponse alipayFundTransUniTransferResponse = AliPayApi.uniTransferToResponse(model, null);
log.error("支付宝退款,参数:{},支付宝响应:{}", JSONUtil.toJsonStr(model), JSONUtil.toJsonStr(alipayFundTransUniTransferResponse));
if (alipayFundTransUniTransferResponse.isSuccess()) {
return true;
return TransferResultDTO.builder().result(true).build();
} else {
log.error(alipayFundTransUniTransferResponse.getSubMsg());
return TransferResultDTO.builder().result(false).response(alipayFundTransUniTransferResponse.getSubMsg()).build();
}
} catch (Exception e) {
log.error("用户提现异常:", e);
throw new ServiceException(ResultCode.PAY_ERROR);
return TransferResultDTO.builder().result(false).response(e.getMessage()).build();
}
return false;
}
/**

View File

@ -17,7 +17,6 @@ import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.connect.entity.Connect;
import cn.lili.modules.connect.entity.enums.ConnectEnum;
import cn.lili.modules.connect.entity.enums.SourceEnum;
import cn.lili.modules.connect.service.ConnectService;
import cn.lili.modules.member.entity.dto.ConnectQueryDTO;
@ -47,10 +46,10 @@ import cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply;
import cn.lili.modules.wallet.entity.dto.TransferResultDTO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.atp.Switch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -481,13 +480,15 @@ public class WechatPlugin implements Payment {
* @param memberWithdrawApply 会员提现申请
*/
@Override
public boolean transfer(MemberWithdrawApply memberWithdrawApply) {
public TransferResultDTO transfer(MemberWithdrawApply memberWithdrawApply) {
try {
//获取提现设置
WithdrawalSetting withdrawalSetting = new Gson().fromJson(settingService.get(SettingEnum.WITHDRAWAL_SETTING.name()).getSettingValue(), WithdrawalSetting.class);
WithdrawalSetting withdrawalSetting = new Gson().fromJson(settingService.get(SettingEnum.WITHDRAWAL_SETTING.name()).getSettingValue(),
WithdrawalSetting.class);
//获取用户OPENID
WechatConnectSetting wechatConnectSetting = new Gson().fromJson(settingService.get(SettingEnum.WECHAT_CONNECT.name()).getSettingValue(), WechatConnectSetting.class);
WechatConnectSetting wechatConnectSetting = new Gson().fromJson(settingService.get(SettingEnum.WECHAT_CONNECT.name()).getSettingValue()
, WechatConnectSetting.class);
String source = "";
for (WechatConnectSettingItem wechatConnectSettingItem : wechatConnectSetting.getWechatConnectSettingItems()) {
if (wechatConnectSettingItem.getAppId().equals(withdrawalSetting.getWechatAppId())) {
@ -548,12 +549,13 @@ public class WechatPlugin implements Payment {
log.info("微信提现响应 {}", response);
String body = response.getBody();
JSONObject jsonObject = JSONUtil.parseObj(body);
return jsonObject.getStr("batch_id") != null ? true : false;
return TransferResultDTO.builder().result(jsonObject.getStr("batch_id") != null).response(body).build();
//根据自身业务进行接下来的任务处理
} catch (Exception e) {
e.printStackTrace();
return TransferResultDTO.builder().result(false).response(e.getMessage()).build();
}
return false;
}
@ -670,7 +672,8 @@ public class WechatPlugin implements Payment {
String transactionId = jsonObject.getStr("transaction_id");
String refundId = jsonObject.getStr("refund_id");
RefundLog refundLog = refundLogService.getOne(new LambdaQueryWrapper<RefundLog>().eq(RefundLog::getPaymentReceivableNo, transactionId));
RefundLog refundLog = refundLogService.getOne(new LambdaQueryWrapper<RefundLog>().eq(RefundLog::getPaymentReceivableNo,
transactionId));
if (refundLog != null) {
refundLog.setIsRefund(true);
refundLog.setReceivableNo(refundId);
@ -683,7 +686,8 @@ public class WechatPlugin implements Payment {
String transactionId = jsonObject.getStr("transaction_id");
String refundId = jsonObject.getStr("refund_id");
RefundLog refundLog = refundLogService.getOne(new LambdaQueryWrapper<RefundLog>().eq(RefundLog::getPaymentReceivableNo, transactionId));
RefundLog refundLog = refundLogService.getOne(new LambdaQueryWrapper<RefundLog>().eq(RefundLog::getPaymentReceivableNo,
transactionId));
if (refundLog != null) {
refundLog.setReceivableNo(refundId);
refundLog.setErrorMessage(ciphertext.getStr("summary"));

View File

@ -107,4 +107,11 @@ public interface AdminUserService extends IService<AdminUser> {
*/
void logout(UserEnums userEnums);
/**
* 登出
*
* @param adminUserIds 用户id
*/
void logout(List<String> adminUserIds);
}

View File

@ -142,11 +142,24 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
@Override
public void logout(UserEnums userEnums) {
String currentUserToken = UserContext.getCurrentUserToken();
AuthUser authUser = UserContext.getAuthUser(currentUserToken);
if (CharSequenceUtil.isNotEmpty(currentUserToken)) {
cache.remove(CachePrefix.ACCESS_TOKEN.getPrefix(userEnums) + currentUserToken);
cache.remove(CachePrefix.ACCESS_TOKEN.getPrefix(userEnums, authUser.getId()) + currentUserToken);
cache.vagueDel(CachePrefix.REFRESH_TOKEN.getPrefix(userEnums, authUser.getId()));
}
}
@Override
public void logout(List<String> adminUserIds) {
if (adminUserIds == null || adminUserIds.isEmpty()) {
return;
}
adminUserIds.forEach(adminUserId -> {
cache.vagueDel(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MANAGER, adminUserId));
cache.vagueDel(CachePrefix.REFRESH_TOKEN.getPrefix(UserEnums.MANAGER, adminUserId));
});
}
@Override
public AdminUser findByUsername(String username) {
@ -234,6 +247,8 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
QueryWrapper<UserRole> queryWrapper = new QueryWrapper<>();
queryWrapper.in("user_id", ids);
userRoleService.remove(queryWrapper);
this.logout(ids);
}
/**

View File

@ -112,9 +112,9 @@ public abstract class AbstractPromotionsServiceImpl<M extends BaseMapper<T>, T e
List<T> promotionsList = this.list(new QueryWrapper<T>().in("id", ids));
for (T t : promotionsList) {
if (startTime != null && endTime != null) {
this.checkPromotions(t);
t.setStartTime(new Date(startTime));
t.setEndTime(new Date(endTime));
this.checkPromotions(t);
} else {
t.setStartTime(null);
t.setEndTime(null);

View File

@ -66,6 +66,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.SearchPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
@ -178,7 +179,7 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
skuCountQueryWrapper.eq("auth_flag", GoodsAuthEnum.PASS.name());
skuCountQueryWrapper.eq("market_enable", GoodsStatusEnum.UPPER.name());
skuCountQueryWrapper.eq("delete_flag", false);
skuCountQueryWrapper.ge("quantity", 0);
skuCountQueryWrapper.gt("quantity", 0);
resultMap = new HashMap<>();
resultMap.put(KEY_SUCCESS, 0L);
resultMap.put(KEY_FAIL, 0L);
@ -235,6 +236,9 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
if (count >= 1) {
skuSource -= count;
}
if (skuSource <= 0) {
skuSource = 1;
}
esGoodsIndex.setSkuSource(skuSource);
@ -672,14 +676,30 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
@Override
public void deleteEsGoodsPromotionByPromotionKey(String promotionsKey) {
ThreadUtil.execAsync(() -> {
for (int i = 0; ; i++) {
BulkRequest bulkRequest = new BulkRequest();
for (EsGoodsIndex goodsIndex : this.goodsIndexRepository.findAll()) {
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
nativeSearchQueryBuilder.withPageable(PageRequest.of(i, 1000));
try {
SearchHits<EsGoodsIndex> esGoodsIndices = this.restTemplate.search(nativeSearchQueryBuilder.build(), EsGoodsIndex.class);
if (esGoodsIndices.isEmpty() || esGoodsIndices.getSearchHits().isEmpty()) {
break;
}
for (SearchHit<EsGoodsIndex> searchHit : esGoodsIndices.getSearchHits()) {
EsGoodsIndex goodsIndex = searchHit.getContent();
UpdateRequest updateRequest = this.removePromotionByPromotionKey(goodsIndex, promotionsKey);
if (updateRequest != null) {
bulkRequest.add(updateRequest);
}
}
this.executeBulkUpdateRequest(bulkRequest);
} catch (Exception e) {
log.error("删除索引中指定的促销活动id的促销活动失败key: {}", promotionsKey, e);
return;
}
}
});
}

View File

@ -84,11 +84,12 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService {
//如果搜索词不为空且明显不是sql注入那么就将搜索词加入热搜词
//PS:线上环境运行很多客户反馈被sql攻击写在了搜索热词里这里控制命中关键字就不做热词统计如果线上比较严格可以调用关键词替换不过不建议这么做
if (CharSequenceUtil.isNotBlank(searchDTO.getKeyword()) && !SqlFilter.hit(searchDTO.getKeyword())) {
if (CharSequenceUtil.isNotBlank(searchDTO.getKeyword()) && Boolean.FALSE.equals(SqlFilter.hit(searchDTO.getKeyword()))) {
cache.incrementScore(CachePrefix.HOT_WORD.getPrefix(), searchDTO.getKeyword());
}
NativeSearchQueryBuilder searchQueryBuilder = createSearchQueryBuilder(searchDTO, pageVo);
NativeSearchQuery searchQuery = searchQueryBuilder.build();
searchQuery.setTrackTotalHits(true);
log.debug("searchGoods DSL:{}", searchQuery.getQuery());
SearchHits<EsGoodsIndex> search = restTemplate.search(searchQuery, EsGoodsIndex.class);
return SearchHitSupport.searchPageFor(search, searchQuery.getPageable());

View File

@ -100,6 +100,20 @@ public class Store extends BaseEntity {
@ApiModelProperty(value = "udesk IM标识")
private String merchantEuid;
public Boolean getPageShow() {
if(pageShow == null){
return false;
}
return pageShow;
}
public Boolean getSelfPickFlag() {
if(selfPickFlag == null){
return false;
}
return selfPickFlag;
}
@ApiModelProperty(value = "默认页面是否开启")
private Boolean pageShow;
@ -116,6 +130,8 @@ public class Store extends BaseEntity {
descriptionScore = 5.0;
goodsNum = 0;
collectionNum = 0;
this.selfPickFlag = false;
this.pageShow = false;
}
public Store(Member member, AdminStoreApplyDTO adminStoreApplyDTO) {
@ -130,6 +146,8 @@ public class Store extends BaseEntity {
descriptionScore = 5.0;
goodsNum = 0;
collectionNum = 0;
this.selfPickFlag = false;
this.pageShow = false;
}
}

View File

@ -9,6 +9,7 @@ import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.goods.entity.dos.GoodsSku;
@ -244,6 +245,13 @@ public class StoreServiceImpl extends ServiceImpl<StoreMapper, Store> implements
if (update) {
goodsService.underStoreGoods(id);
}
//删除店员token
clerkService.list(new LambdaQueryWrapper<Clerk>().eq(Clerk::getStoreId, id)).forEach(clerk -> {
cache.vagueDel(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.STORE, clerk.getMemberId()));
cache.vagueDel(CachePrefix.REFRESH_TOKEN.getPrefix(UserEnums.STORE, clerk.getMemberId()));
});
return update;
}
@ -371,7 +379,8 @@ public class StoreServiceImpl extends ServiceImpl<StoreMapper, Store> implements
clerkService.remove(new LambdaQueryWrapper<Clerk>().eq(Clerk::getShopkeeper, true));
List<Clerk> clerkList = new ArrayList<>();
//遍历已开启的店铺
for (Store store : this.list(new LambdaQueryWrapper<Store>().eq(Store::getDeleteFlag, false).eq(Store::getStoreDisable, StoreStatusEnum.OPEN.name()))) {
for (Store store : this.list(new LambdaQueryWrapper<Store>().eq(Store::getDeleteFlag, false).eq(Store::getStoreDisable,
StoreStatusEnum.OPEN.name()))) {
clerkList.add(new Clerk(store));
}
clerkService.saveBatch(clerkList);
@ -381,7 +390,8 @@ public class StoreServiceImpl extends ServiceImpl<StoreMapper, Store> implements
public List<GoodsSku> getToMemberHistory(String memberId) {
AuthUser currentUser = UserContext.getCurrentUser();
List<String> skuIdList = new ArrayList<>();
for (FootPrint footPrint : footprintService.list(new LambdaUpdateWrapper<FootPrint>().eq(FootPrint::getStoreId, currentUser.getStoreId()).eq(FootPrint::getMemberId, memberId))) {
for (FootPrint footPrint :
footprintService.list(new LambdaUpdateWrapper<FootPrint>().eq(FootPrint::getStoreId, currentUser.getStoreId()).eq(FootPrint::getMemberId, memberId))) {
if (footPrint.getSkuId() != null) {
skuIdList.add(footPrint.getSkuId());
}

View File

@ -67,4 +67,10 @@ public class MemberWithdrawApply extends BaseEntity {
@ApiModelProperty(value = "第三方平台账号")
private String connectNumber;
/**
* 支付宝登录账号
*/
@ApiModelProperty(value = "第三方错误消息")
private String errorMessage;
}

View File

@ -0,0 +1,24 @@
package cn.lili.modules.wallet.entity.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
/**
* 转账结果
*
* @author liushuai(liushuai711 @ gmail.com)
* @version v4.0
* @Description:
* @since 2023/5/6 16:10
*/
@Data
@Builder
public class TransferResultDTO {
@ApiModelProperty(value = "错误信息")
private String response;
@ApiModelProperty(value = "是否成功")
private Boolean result;
}

View File

@ -6,7 +6,6 @@ import cn.lili.modules.wallet.entity.dos.MemberWallet;
import cn.lili.modules.wallet.entity.dto.MemberWalletUpdateDTO;
import cn.lili.modules.wallet.entity.vo.MemberWalletVO;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 会员预存款业务层
@ -102,8 +101,7 @@ public interface MemberWalletService extends IService<MemberWallet> {
* 提现公共方法
*
* @param withdrawApplyId 会员零钱提现Id
* @return 操作状态
*/
Boolean withdrawal(String withdrawApplyId);
void withdrawal(String withdrawApplyId);
}

View File

@ -22,6 +22,7 @@ import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply;
import cn.lili.modules.wallet.entity.dos.WalletLog;
import cn.lili.modules.wallet.entity.dto.MemberWalletUpdateDTO;
import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage;
import cn.lili.modules.wallet.entity.dto.TransferResultDTO;
import cn.lili.modules.wallet.entity.enums.DepositServiceTypeEnum;
import cn.lili.modules.wallet.entity.enums.WithdrawStatusEnum;
import cn.lili.modules.wallet.entity.vo.MemberWalletVO;
@ -312,7 +313,7 @@ public class MemberWalletServiceImpl extends ServiceImpl<MemberWalletMapper, Mem
}
@Override
public Boolean withdrawal(String withdrawApplyId) {
public void withdrawal(String withdrawApplyId) {
MemberWithdrawApply memberWithdrawApply = memberWithdrawApplyService.getById(withdrawApplyId);
memberWithdrawApply.setInspectTime(new Date());
//获取提现设置
@ -320,20 +321,18 @@ public class MemberWalletServiceImpl extends ServiceImpl<MemberWalletMapper, Mem
WithdrawalSetting withdrawalSetting = new Gson().fromJson(setting.getSettingValue(), WithdrawalSetting.class);
//调用提现方法
boolean result = true;
if ("WECHAT".equals(withdrawalSetting.getType())) {
result = cashierSupport.transfer(PaymentMethodEnum.WECHAT, memberWithdrawApply);
} else if ("ALI".equals(withdrawalSetting.getType())) {
result = cashierSupport.transfer(PaymentMethodEnum.ALIPAY, memberWithdrawApply);
}
TransferResultDTO transferResultDTO = "WECHAT".equals(withdrawalSetting.getType()) ?
cashierSupport.transfer(PaymentMethodEnum.WECHAT, memberWithdrawApply) : cashierSupport.transfer(PaymentMethodEnum.ALIPAY,
memberWithdrawApply);
//成功则扣减冻结金额
//失败则恢复冻结金额
if (result) {
if (transferResultDTO.getResult()) {
memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.SUCCESS.name());
} else {
memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.ERROR.name());
memberWithdrawApply.setErrorMessage(transferResultDTO.getResponse());
}
//修改提现申请
this.memberWithdrawApplyService.updateById(memberWithdrawApply);
@ -348,7 +347,6 @@ public class MemberWalletServiceImpl extends ServiceImpl<MemberWalletMapper, Mem
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_WITHDRAWAL.name();
rocketMQTemplate.asyncSend(destination, memberWithdrawalMessage, RocketmqSendCallbackBuilder.commonCallback());
return result;
}
}

View File

@ -9,7 +9,6 @@ import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.DateUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.connect.entity.Connect;
import cn.lili.modules.connect.entity.enums.ConnectEnum;
import cn.lili.modules.connect.entity.enums.SourceEnum;
import cn.lili.modules.connect.service.ConnectService;
import cn.lili.modules.member.entity.dto.ConnectQueryDTO;
@ -79,16 +78,22 @@ public class WechatMessageUtil {
if (order == null) {
throw new ServiceException("订单" + sn + "不存在,发送微信公众号消息错误");
}
if (ClientTypeEnum.H5.name().equals(order.getClientType())) {
//获取微信消息
LambdaQueryWrapper<WechatMessage> wechatMessageQueryWrapper = new LambdaQueryWrapper();
wechatMessageQueryWrapper.eq(WechatMessage::getOrderStatus, order.getOrderStatus());
WechatMessage wechatMessage = wechatMessageService.getOne(wechatMessageQueryWrapper);
if (wechatMessage == null) {
log.error("未配置微信公众号消息");
return;
}
Connect connect = connectService.queryConnect(
ConnectQueryDTO.builder().userId(order.getMemberId()).unionType(ConnectEnum.WECHAT.name()).build()
ConnectQueryDTO.builder()
.userId(order.getMemberId())
.unionType(SourceEnum.WECHAT_OFFIACCOUNT_OPEN_ID.name())
.build()
);
if (connect == null) {
return;
@ -122,6 +127,7 @@ public class WechatMessageUtil {
log.error("消息发送请求:" + map.get("data"));
}
}
}
/**
* 发送微信消息
@ -135,6 +141,8 @@ public class WechatMessageUtil {
if (order == null) {
throw new ServiceException("订单" + sn + "不存在,发送订阅消息错误");
}
if (ClientTypeEnum.WECHAT_MP.name().equals(order.getClientType())) {
//获取微信消息
LambdaQueryWrapper<WechatMPMessage> wechatMPMessageQueryWrapper = new LambdaQueryWrapper();
wechatMPMessageQueryWrapper.eq(WechatMPMessage::getOrderStatus, order.getOrderStatus());
@ -174,7 +182,7 @@ public class WechatMessageUtil {
log.error("微信消息发送错误", e);
}
JSONObject json = new JSONObject(content);
log.info("微信消息发送结果:" + content);
log.info("微信小程序消息发送结果:" + content);
String errorMessage = json.getStr("errmsg");
String errcode = json.getStr("errcode");
//发送失败
@ -184,6 +192,7 @@ public class WechatMessageUtil {
log.error("消息发送请求:" + map.get("data"));
}
}
}
/**
* 构造数据中所需的内容

View File

@ -55,6 +55,10 @@ public enum GoodsTagsEnum {
* "收藏商品"
*/
GOODS_COLLECTION("收藏商品"),
/**
* 同步商品分类名称
*/
CATEGORY_GOODS_NAME("同步商品分类名称"),
/**
* "购买商品完成"
*/

56
im-api/README.md Normal file
View File

@ -0,0 +1,56 @@
### IM 配置文档
#### websocket连接中ws=http协议wss=https协议在前端配置时也许注意同步修改PS微信小程序只支持https
微信小程序配置需额外配置:前往微信平台,登陆自己的小程序
https://mp.weixin.qq.com/
配置内容: 开发 -> 开发设置 -> 服务器域名 -> socket合法域名 -> 添加 https://im-api.pickmall.cn(参考)
##### https NGINX配置参考
```
server {
listen 443 ssl;
ssl_certificate "/etc/nginx/ssl/pickmall.cn.pem";
ssl_certificate_key "/etc/nginx/ssl/pickmall.cn.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
include /etc/nginx/default.d/*.conf;
server_name im-api.pickmall.cn;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://127.0.0.1:8885;
}
}
```
##### http 参考配置
```
server {
listen 8885;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
include /etc/nginx/default.d/*.conf;
server_name im-api.pickmall.cn;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://127.0.0.1:8885;
}
}
```

View File

@ -30,6 +30,7 @@ import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
@ -183,6 +184,14 @@ public class AdminUserManagerController {
}
user.setStatus(status);
adminUserService.updateById(user);
//登出用户
if (Boolean.FALSE.equals(status)) {
List<String> userIds = new ArrayList<>();
userIds.add(userId);
adminUserService.logout(userIds);
}
return ResultUtil.success();
}

View File

@ -86,7 +86,8 @@ public class ManagerAuthenticationFilter extends BasicAuthenticationFilter {
//如果不是超级管理员 则鉴权
if (Boolean.FALSE.equals(authUser.getIsSuper())) {
//获取缓存中的权限
Map<String, List<String>> permission = (Map<String, List<String>>) cache.get(CachePrefix.PERMISSION_LIST.getPrefix(UserEnums.MANAGER) + authUser.getId());
Map<String, List<String>> permission =
(Map<String, List<String>>) cache.get(CachePrefix.PERMISSION_LIST.getPrefix(UserEnums.MANAGER) + authUser.getId());
//获取数据(GET 请求)权限
if (request.getMethod().equals(RequestMethod.GET.name())) {
@ -143,7 +144,7 @@ public class ManagerAuthenticationFilter extends BasicAuthenticationFilter {
AuthUser authUser = new Gson().fromJson(json, AuthUser.class);
//校验redis中是否有权限
if (cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MANAGER) + jwt)) {
if (cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MANAGER, authUser.getId()) + jwt)) {
//用户角色
List<GrantedAuthority> auths = new ArrayList<>();
auths.add(new SimpleGrantedAuthority("ROLE_" + authUser.getRole().name()));

View File

@ -29,15 +29,9 @@ public class GoodsImportController {
@PostMapping(value = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ApiOperation(value = "上传文件,商品批量添加")
public ResultMessage<Object> importExcel(@RequestPart("files") MultipartFile files) {
try {
public ResultMessage<Object> importExcel(@RequestPart("files") MultipartFile files) throws Exception {
goodsImportService.importExcel(files);
return ResultUtil.success(ResultCode.SUCCESS);
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException(ResultCode.ERROR);
}
}

View File

@ -51,7 +51,8 @@ public class StoreAuthenticationFilter extends BasicAuthenticationFilter {
@SneakyThrows
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException,
ServletException {
//从header中获取jwt
String jwt = request.getHeader(SecurityEnum.HEADER_TOKEN.getValue());
//如果没有token 则return
@ -89,7 +90,7 @@ public class StoreAuthenticationFilter extends BasicAuthenticationFilter {
AuthUser authUser = new Gson().fromJson(json, AuthUser.class);
//校验redis中是否有权限
if (cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.STORE) + jwt)) {
if (cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.STORE, authUser.getId()) + jwt)) {
//用户角色
List<GrantedAuthority> auths = new ArrayList<>();
auths.add(new SimpleGrantedAuthority("ROLE_" + authUser.getRole().name()));
@ -124,7 +125,8 @@ public class StoreAuthenticationFilter extends BasicAuthenticationFilter {
//如果不是超级管理员 则鉴权
if (!authUser.getIsSuper()) {
//获取缓存中的权限
Map<String, List<String>> permission = (Map<String, List<String>>) cache.get(CachePrefix.PERMISSION_LIST.getPrefix(UserEnums.STORE) + authUser.getId());
Map<String, List<String>> permission =
(Map<String, List<String>>) cache.get(CachePrefix.PERMISSION_LIST.getPrefix(UserEnums.STORE) + authUser.getId());
//获取数据(GET 请求)权限
if (request.getMethod().equals(RequestMethod.GET.name())) {