Merge branch 'Bulbasaur' of gitee.com:beijing_hongye_huicheng/lilishop into feature/pg

This commit is contained in:
paulGao 2021-06-21 11:56:25 +08:00
commit 7564a4627a
280 changed files with 5923 additions and 2384 deletions

View File

@ -82,9 +82,6 @@ public class GoodsBuyerController {
@NotNull(message = "SKU ID不能为空") @PathVariable("skuId") String skuId) {
Map<String, Object> map = goodsSkuService.getGoodsSkuDetail(goodsId, skuId);
return ResultUtil.data(map);
}

View File

@ -1,8 +1,13 @@
package cn.lili.controller.other;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.utils.PageUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.system.entity.dos.AppVersion;
import cn.lili.modules.system.service.AppVersionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
@ -33,4 +38,13 @@ public class AppVersionBuyerController {
public ResultMessage<Object> getAppVersion(@PathVariable String appType) {
return ResultUtil.data(appVersionService.getAppVersion(appType));
}
@ApiOperation(value = "获取版本号列表")
@ApiImplicitParam(name = "appType", value = "app类型", required = true, paramType = "path")
@GetMapping("/appVersion/{appType}")
public ResultMessage<IPage<AppVersion>> appVersion(@PathVariable String appType, PageVO pageVO) {
IPage<AppVersion> page = appVersionService.page(PageUtil.initPage(pageVO), new LambdaQueryWrapper<AppVersion>().eq(AppVersion::getType, appType));
return ResultUtil.data(page);
}
}

View File

@ -0,0 +1,48 @@
package cn.lili.controller.other.broadcast;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.broadcast.entity.dos.Studio;
import cn.lili.modules.broadcast.service.StudioService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 买家端,直播间接口
*
* @author Bulbasaur
* @date: 2021/5/20 12:03 下午
*/
@RestController
@Api(tags = "买家端,直播间接口")
@RequestMapping("/buyer/broadcast/studio")
public class StudioController {
@Autowired
private StudioService studioService;
@ApiOperation(value = "获取店铺直播间列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "recommend", value = "是否推荐", paramType = "query", dataType = "int"),
@ApiImplicitParam(name = "status", value = "直播间状态", paramType = "query", dataType = "String")
})
@GetMapping
public ResultMessage<IPage<Studio>> page(PageVO pageVO, Integer recommend, String status) {
return ResultUtil.data(studioService.studioList(pageVO, recommend, status));
}
@ApiOperation(value = "获取店铺直播间回放地址")
@GetMapping("/getLiveInfo/{roomId}")
public ResultMessage<Object> getLiveInfo(Integer roomId) {
return ResultUtil.data(studioService.getLiveInfo(roomId));
}
}

View File

@ -17,6 +17,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -30,6 +31,7 @@ import java.io.IOException;
* @author Chopper
* @date 2020-11-25 19:29
*/
@Slf4j
@RestController
@Api(tags = "买家端,web联合登录")
@RequestMapping("/buyer/connect")
@ -93,7 +95,7 @@ public class ConnectBuyerWebController {
try {
return ResultUtil.data(connectService.appLoginCallback(authUser, uuid));
} catch (Exception e) {
e.printStackTrace();
log.error("unionID登录错误",e);
}
return null;
}

View File

@ -12,6 +12,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -25,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
* @author Chopper
* @date 2020-12-18 16:59
*/
@Slf4j
@RestController
@Api(tags = "买家端,收银台接口")
@RequestMapping("/buyer/cashier")
@ -63,7 +65,7 @@ public class CashierController {
try {
return cashierSupport.payment(paymentMethodEnum, paymentClientEnum, request, response, payParam);
} catch (Exception e) {
e.printStackTrace();
log.error("收银台支付错误",e);
}
return null;

View File

@ -17,29 +17,29 @@ import java.util.List;
/**
* 买家端,限时抢购接口
* 买家端,秒杀活动接口
*
* @author paulG
* @date 2020/11/17 2:30 下午
*/
@Api(tags = "买家端,限时抢购接口")
@Api(tags = "买家端,秒杀活动接口")
@RestController
@RequestMapping("/buyer/promotion/seckill")
public class SeckillBuyerController {
/**
* 限时抢购
* 秒杀活动
*/
@Autowired
private SeckillApplyService seckillApplyService;
@ApiOperation(value = "获取当天限时抢购信息")
@ApiOperation(value = "获取当天秒杀活动信息")
@GetMapping
public ResultMessage<List<SeckillTimelineVO>> getSeckillTime() {
return ResultUtil.data(seckillApplyService.getSeckillTimeline());
}
@ApiOperation(value = "获取某个时刻的限时抢购商品信息")
@ApiOperation(value = "获取某个时刻的秒杀活动商品信息")
@GetMapping("/{timeline}")
public ResultMessage<List<SeckillGoodsVO>> getSeckillGoods(@PathVariable Integer timeline) {
return ResultUtil.data(seckillApplyService.getSeckillGoods(timeline));

View File

@ -4,9 +4,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:
@ -153,6 +150,7 @@ ignored:
- /buyer/memberEvaluation/**/goodsEvaluation
- /buyer/memberEvaluation/**/evaluationNumber
- /buyer/appVersion/**
- /buyer/broadcast/studio/**
- /druid/**
- /swagger-ui.html
- /doc.html
@ -262,7 +260,8 @@ lili:
# account:
# username: elastic
# password: LiLiShopES
logstash:
server: 192.168.0.116:4560
rocketmq:
promotion-topic: lili_promotion_topic
promotion-group: lili_promotion_group

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--应用名称-->
<property name="APP_NAME" value="buyer-api"/>
<!--日志文件保存路径-->
<property name="LOG_FILE_PATH" value="lili-logs"/>
<contextName>${APP_NAME}</contextName>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--输出到elk的LOGSTASH-->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>127.0.0.1:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
</providers>
<!--自定义字段 区分项目-->
<customFields>{"appName":"${APP_NAME}"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>

View File

@ -5,6 +5,7 @@ import cn.lili.modules.file.plugin.FileManagerPlugin;
import cn.lili.modules.goods.entity.dos.Brand;
import cn.lili.modules.goods.service.BrandService;
import com.xkcoding.http.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@ -19,6 +20,7 @@ import java.util.List;
* @author paulG
* @since 2020/11/14
**/
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
class FileTest {
@ -43,7 +45,7 @@ class FileTest {
// 上传至第三方云服务或服务器
brand.setLogo(fileManagerPlugin.inputStreamUpload(inputStream, brand.getId() + ".png"));
} catch (IOException e) {
e.printStackTrace();
log.error("上传你文件出错",e);
}
}
brandService.updateBatchById(categoryList);

View File

@ -2,9 +2,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:

View File

@ -8,6 +8,7 @@ import cn.lili.common.verification.service.VerificationService;
import cn.lili.common.vo.ResultMessage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -17,8 +18,9 @@ import org.springframework.web.bind.annotation.*;
* @author Chopper
* @date 2020/11/26 15:41
*/
@RequestMapping("/common/slider")
@Slf4j
@RestController
@RequestMapping("/common/slider")
@Api(tags = "滑块验证码接口")
public class SliderImageController {
@ -35,7 +37,7 @@ public class SliderImageController {
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
log.error("获取校验接口错误",e);
return null;
}
}

View File

@ -4,9 +4,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--应用名称-->
<property name="APP_NAME" value="common-api"/>
<!--日志文件保存路径-->
<property name="LOG_FILE_PATH" value="lili-logs"/>
<contextName>${APP_NAME}</contextName>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--输出到elk的LOGSTASH-->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- 配置elk日志收集 配饰的是 LOGSTASH 的地址-->
<destination>127.0.0.1:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
</providers>
<!--自定义字段 区分项目-->
<customFields>{"appName":"${APP_NAME}"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>

View File

@ -2,9 +2,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:
@ -80,7 +77,7 @@ spring:
default-datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.0.116:3306/lilishop?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
url: jdbc:mysql://192.168.0.116:3306/Bulbasaur?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root
password: lilishop
maxActive: 20
@ -150,6 +147,7 @@ ignored:
- /buyer/memberEvaluation/**/goodsEvaluation
- /buyer/memberEvaluation/**/evaluationNumber
- /buyer/appVersion/**
- /buyer/broadcast/studio/**
- /store/login/**
- /manager/user/login
- /manager/user/refresh/**
@ -252,7 +250,7 @@ lili:
# jwt 细节设定
jwt-setting:
# token过期时间分钟
tokenExpireTime: 60
tokenExpireTime: 30
# 使用Spring @Cacheable注解失效时间
cache:
@ -276,6 +274,8 @@ lili:
# username: elastic
# password: LiLiShopES
logstash:
server: 192.168.0.116:4560
rocketmq:
promotion-topic: lili_promotion_topic
promotion-group: lili_promotion_group

View File

@ -15,6 +15,8 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 分销订单入库
*
@ -28,7 +30,7 @@ public class DistributionOrderExecute implements OrderStatusChangeEvent, EveryDa
@Autowired
private DistributionOrderService distributionOrderService;
//分销订单持久层
@Autowired
@Resource
private DistributionOrderMapper distributionOrderMapper;

View File

@ -0,0 +1,92 @@
package cn.lili.event.impl;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.ExperienceSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 会员经验值
*
* @author Bulbasaur
* @date: 2021/5/16 11:16 下午
*/
@Service
public class MemberExperienceExecute implements MemberRegisterEvent, GoodsCommentCompleteEvent, OrderStatusChangeEvent {
//配置
@Autowired
private SettingService settingService;
//会员
@Autowired
private MemberService memberService;
//订单
@Autowired
private OrderService orderService;
/**
* 会员注册赠送经验值
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//赠送会员经验值
memberService.updateMemberExperience(Long.valueOf(experienceSetting.getRegister().longValue()), true, member.getId(), "会员注册,赠送经验值" + experienceSetting.getRegister());
}
/**
* 商品评价赠送经验值
* @param memberEvaluation 会员评价
*/
@Override
public void goodsComment(MemberEvaluation memberEvaluation) {
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//赠送会员经验值
memberService.updateMemberExperience(Long.valueOf(experienceSetting.getComment().longValue()), true, memberEvaluation.getMemberId(), "会员评价,赠送经验值" + experienceSetting.getComment());
}
/**
* 完成订单赠送经验值
* @param orderMessage 订单消息
*/
@Override
public void orderChange(OrderMessage orderMessage) {
if(orderMessage.getNewStatus().equals(OrderStatusEnum.COMPLETED)){
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//获取订单信息
Order order = orderService.getBySn(orderMessage.getOrderSn());
//计算赠送经验值数量
Double point= CurrencyUtil.mul(experienceSetting.getMoney(),order.getFlowPrice(),0);
//赠送会员经验值
memberService.updateMemberExperience(point.longValue(), true, order.getMemberId(), "会员下单,赠送经验值" + point + "");
}
}
/**
* 获取经验值设置
* @return 经验值设置
*/
private ExperienceSetting getExperienceSetting(){
Setting setting = settingService.get(SettingEnum.EXPERIENCE_SETTING.name());
return new Gson().fromJson(setting.getSettingValue(), ExperienceSetting.class);
}
}

View File

@ -1,30 +1,37 @@
package cn.lili.event.impl;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.event.AfterSaleStatusChangeEvent;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.member.service.MemberWalletService;
import cn.lili.modules.order.order.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.PointSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import com.google.gson.Gson;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 会员积分
*
* @author Chopper
* @author Bulbasaur
* @date 2020-07-03 11:20
*/
@Service
public class MemberPointExecute implements MemberRegisterEvent, GoodsCommentCompleteEvent {
public class MemberPointExecute implements MemberRegisterEvent, GoodsCommentCompleteEvent, OrderStatusChangeEvent, AfterSaleStatusChangeEvent {
//配置
@Autowired
@ -32,22 +39,80 @@ public class MemberPointExecute implements MemberRegisterEvent, GoodsCommentComp
//会员
@Autowired
private MemberService memberService;
//订单
@Autowired
private OrderService orderService;
/**
* 会员注册赠送积分
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
//获取签到积分赠送设置
Setting setting = settingService.get(SettingEnum.POINT_SETTING.name());
PointSetting pointSetting = new Gson().fromJson(setting.getSettingValue(), PointSetting.class);
//获取积分设置
PointSetting pointSetting=getPointSetting();
//赠送会员积分
memberService.updateMemberPoint(Long.valueOf(pointSetting.getRegister().longValue()), 1, member.getId(), "会员注册,赠送积分" + pointSetting.getRegister() + "");
memberService.updateMemberPoint(Long.valueOf(pointSetting.getRegister().longValue()), true, member.getId(), "会员注册,赠送积分" + pointSetting.getRegister() + "");
}
/**
* 会员评价赠送积分
* @param memberEvaluation 会员评价
*/
@Override
public void goodsComment(MemberEvaluation memberEvaluation) {
//获取签到积分赠送设置
Setting setting = settingService.get(SettingEnum.POINT_SETTING.name());
PointSetting pointSetting = new Gson().fromJson(setting.getSettingValue(), PointSetting.class);
//获取积分设置
PointSetting pointSetting=getPointSetting();
//赠送会员积分
memberService.updateMemberPoint(Long.valueOf(pointSetting.getComment().longValue()), 1, memberEvaluation.getMemberId(), "会员评价,赠送积分" + pointSetting.getComment() + "");
memberService.updateMemberPoint(Long.valueOf(pointSetting.getComment().longValue()), true, memberEvaluation.getMemberId(), "会员评价,赠送积分" + pointSetting.getComment() + "");
}
/**
* 非积分订单订单完成后赠送积分
* @param orderMessage 订单消息
*/
@Override
public void orderChange(OrderMessage orderMessage) {
if(orderMessage.getNewStatus().equals(OrderStatusEnum.COMPLETED)){
//根据订单编号获取订单数据,如果为积分订单则跳回
Order order = orderService.getBySn(orderMessage.getOrderSn());
if(order.getOrderPromotionType().equals(OrderPromotionTypeEnum.POINT.name())){
return;
}
//获取积分设置
PointSetting pointSetting=getPointSetting();
//计算赠送积分数量
Double point=CurrencyUtil.mul(pointSetting.getMoney(),order.getFlowPrice(),0);
//赠送会员积分
memberService.updateMemberPoint(point.longValue(), true, order.getMemberId(), "会员下单,赠送积分" + point + "");
}
}
/**
* 提交售后后扣除积分
* @param afterSale 售后
*/
@Override
public void afterSaleStatusChange(AfterSale afterSale) {
if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.COMPLETE.name())) {
//获取积分设置
PointSetting pointSetting=getPointSetting();
//计算扣除积分数量
Double point=CurrencyUtil.mul(pointSetting.getMoney(), afterSale.getActualRefundPrice(),0);
//扣除会员积分
memberService.updateMemberPoint(point.longValue(), false, afterSale.getMemberId(), "会员退款,扣除积分" + point + "");
}
}
/**
* 获取积分设置
* @return 积分设置
*/
private PointSetting getPointSetting(){
Setting setting = settingService.get(SettingEnum.POINT_SETTING.name());
return new Gson().fromJson(setting.getSettingValue(), PointSetting.class);
}
}

View File

@ -11,12 +11,11 @@ import cn.lili.modules.message.service.NoticeMessageService;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.order.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderTypeEnum;
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.order.trade.entity.enums.AfterSaleTypeEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -83,7 +82,7 @@ public class NoticeMessageExecute implements TradeEvent, OrderStatusChangeEvent,
break;
//如果是拼团订单发送拼团成功消息
case UNDELIVERED:
if(orderDetailVO.getOrder().getOrderType().equals(OrderTypeEnum.PINTUAN.name())){
if(orderDetailVO.getOrder().getOrderPromotionType().equals(OrderPromotionTypeEnum.PINTUAN.name())){
//拼团成功消息
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.PINTUAN_SUCCESS);
}

View File

@ -10,8 +10,6 @@ import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.payment.entity.RefundLog;
import cn.lili.modules.payment.kit.Payment;
import cn.lili.modules.payment.kit.enums.PaymentMethodEnum;
import cn.lili.modules.payment.service.PaymentService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -24,9 +22,6 @@ import org.springframework.stereotype.Service;
@Service
public class PaymentExecute implements OrderStatusChangeEvent {
//支付日志
@Autowired
private PaymentService paymentService;
//订单
@Autowired
private OrderService orderService;

View File

@ -0,0 +1,41 @@
package cn.lili.event.impl;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.promotion.entity.dos.CouponActivity;
import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.service.CouponActivityService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 注册赠券活动
*
* @author Bulbasaur
* @date: 2021/5/24 10:48 上午
*/
@Component
public class RegisteredCouponActivityExecute implements MemberRegisterEvent {
@Autowired
private CouponActivityService couponActivityService;
/**
* 获取进行中的注册赠券的优惠券活动
* 发送注册赠券
*
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
List<CouponActivity> couponActivities = couponActivityService.list(new LambdaQueryWrapper<CouponActivity>()
.eq(CouponActivity::getCouponActivityType, CouponActivityTypeEnum.REGISTERED.name())
.eq(CouponActivity::getPromotionStatus, PromotionStatusEnum.START.name()));
couponActivityService.registered(couponActivities, member);
}
}

View File

@ -0,0 +1,62 @@
package cn.lili.event.impl;
import cn.hutool.core.util.RandomUtil;
import cn.lili.common.utils.CommonUtil;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 虚拟商品
*
* @author Bulbasaur
* @date: 2021/5/29 9:17 上午
*/
@Component
public class VerificationOrderExecute implements OrderStatusChangeEvent {
@Autowired
private OrderService orderService;
@Override
public void orderChange(OrderMessage orderMessage) {
//订单状态为待核验添加订单添加核验码
if (orderMessage.getNewStatus().equals(OrderStatusEnum.TAKE)) {
//获取订单信息
Order order = orderService.getBySn(orderMessage.getOrderSn());
//获取随机数判定是否存在
String code = getCode(order.getStoreId());
//设置订单验证码
orderService.update(new LambdaUpdateWrapper<Order>()
.set(Order::getVerificationCode, code)
.eq(Order::getSn, orderMessage.getOrderSn()));
}
}
/**
* 获取随机数
* 判断当前店铺下是否使用验证码如果已使用则重新获取
*
* @param storeId 店铺ID
* @return
*/
private String getCode(String storeId) {
//获取八位验证码
String code = Long.toString(RandomUtil.randomLong(10000000, 99999999));
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<Order>()
.eq(Order::getVerificationCode, code)
.eq(Order::getStoreId, storeId);
if (orderService.getOne(lambdaQueryWrapper) == null) {
return code;
} else {
return this.getCode(storeId);
}
}
}

View File

@ -44,7 +44,6 @@ public class BillExecute implements EveryDayExecute {
//获取当前时间
DateTime endTime =DateUtil.date();
//批量商家结算
for (StoreSettlementDay storeSettlementDay : storeList) {

View File

@ -0,0 +1,25 @@
package cn.lili.timetask.handler.impl.broadcast;
import cn.lili.modules.broadcast.service.CommodityService;
import cn.lili.timetask.handler.EveryHourExecute;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 小程序直播状态获取
*
* @author Bulbasaur
* @date: 2021/5/20 2:52 下午
*/
@Component
public class BroadcastExecute implements EveryHourExecute {
@Autowired
private CommodityService commodityService;
@Override
public void execute() {
//同步直播商品状态
commodityService.getGoodsWareHouse();
}
}

View File

@ -0,0 +1,80 @@
package cn.lili.timetask.handler.impl.coupon;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.lili.modules.promotion.entity.dos.CouponActivity;
import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.service.CouponActivityService;
import cn.lili.timetask.handler.EveryMinuteExecute;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 优惠券活动状态监测
*
* @author Bulbasaur
* @date: 2021/5/24 10:08 上午
*/
@Component
public class CouponActivityExecute implements EveryMinuteExecute {
@Autowired
private CouponActivityService couponActivityService;
@Override
public void execute() {
//精确发券活动
specify();
//注册赠券的活动
registered();
}
/**
* 监测精确发券活动
* 达到活动时间发送优惠券
*/
private void specify(){
DateTime dateTime=DateUtil.date();
List<CouponActivity> couponActivities=couponActivityService.list(new LambdaQueryWrapper<CouponActivity>()
.eq(CouponActivity::getCouponActivityType, CouponActivityTypeEnum.SPECIFY.name())
.le(CouponActivity::getStartTime, dateTime)
.eq(CouponActivity::getPromotionStatus,PromotionStatusEnum.NEW.name()));
//如果有符合要求的优惠券活动发送优惠券
if(couponActivities.size()>0){
for (CouponActivity couponActivity:couponActivities) {
couponActivityService.specify(couponActivity.getId());
//修改精准发券优惠券活动状态
couponActivityService.update(new LambdaUpdateWrapper<CouponActivity>()
.eq(CouponActivity::getId,couponActivity.getId())
.set(CouponActivity::getPromotionStatus,PromotionStatusEnum.END.name()));
}
}
}
/**
* 注册赠券活动状态监测
*/
private void registered(){
//开启注册赠券优惠券活动
LambdaUpdateWrapper<CouponActivity> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.eq(CouponActivity::getCouponActivityType, CouponActivityTypeEnum.REGISTERED.name())
.eq(CouponActivity::getPromotionStatus, PromotionStatusEnum.NEW.name())
.le(CouponActivity::getStartTime, DateUtil.date())
.set(CouponActivity::getPromotionStatus,PromotionStatusEnum.START.name());
couponActivityService.update(lambdaUpdateWrapper);
//关闭注册赠券优惠券活动
LambdaUpdateWrapper<CouponActivity> endWrapper = new LambdaUpdateWrapper<>();
endWrapper.eq(CouponActivity::getCouponActivityType, CouponActivityTypeEnum.REGISTERED.name())
.eq(CouponActivity::getPromotionStatus, PromotionStatusEnum.START.name())
.le(CouponActivity::getEndTime, DateUtil.date())
.set(CouponActivity::getPromotionStatus,PromotionStatusEnum.END.name());
couponActivityService.update(endWrapper);
}
}

View File

@ -0,0 +1,38 @@
package cn.lili.timetask.handler.impl.coupon;
import cn.hutool.core.date.DateUtil;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
import cn.lili.modules.promotion.service.MemberCouponService;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 优惠券状态监测
*
* @author Bulbasaur
* @date: 2021/5/24 10:08 上午
*/
@Component
public class CouponExecute implements EveryDayExecute {
@Autowired
private MemberCouponService memberCouponService;
/**
* 检测优惠券的使用时间超期未使用则失效
* 此方法用于领取*天后失效优惠券使用
*/
@Override
public void execute() {
LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<MemberCoupon>()
.eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name())
.le(MemberCoupon::getEndTime, DateUtil.date())
.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
this.memberCouponService.update(updateWrapper);
}
}

View File

@ -39,7 +39,6 @@ public class GoodsExecute implements EveryDayExecute {
new QueryWrapper<MemberEvaluation>()
.between("create_time", DateUtil.yesterday(), new DateTime()));
System.out.println("评论数量" + list.size());
for (Map<String, Object> map : list) {
goodsMapper.addGoodsCommentNum(Integer.parseInt(map.get("num").toString()), map.get("goods_id").toString());
}

View File

@ -3,15 +3,21 @@ package cn.lili.timetask.handler.impl.promotion;
import cn.lili.modules.order.cart.entity.vo.FullDiscountVO;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dos.Seckill;
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.entity.vos.CouponVO;
import cn.lili.modules.promotion.entity.vos.PintuanVO;
import cn.lili.modules.promotion.service.*;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.SeckillSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
@ -55,6 +61,13 @@ public class PromotionEverydayExecute implements EveryDayExecute {
@Autowired
private PromotionGoodsService promotionGoodsService;
// 系统设置
@Autowired
private SettingService settingService;
//秒杀活动
@Autowired
private SeckillService seckillService;
/**
* 将已过期的促销活动置为结束
@ -69,52 +82,26 @@ public class PromotionEverydayExecute implements EveryDayExecute {
//结束条件 活动结束时间大于当前时间
query.addCriteria(Criteria.where("endTime").lt(new Date()));
try {
//关闭满减活动
List<FullDiscountVO> fullDiscountVOS = mongoTemplate.find(query, FullDiscountVO.class);
if (!fullDiscountVOS.isEmpty()) {
List<String> ids = new ArrayList<>();
//循环活动 关闭活动
for (FullDiscountVO vo : fullDiscountVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
fullDiscountService.update(this.getUpdatePromotionWrapper(ids));
}
} catch (Exception e) {
log.error("满减活动关闭错误", e);
}
try {
//关闭拼团活动
List<PintuanVO> pintuanVOS = mongoTemplate.find(query, PintuanVO.class);
if (!pintuanVOS.isEmpty()) {
//准备修改活动的id
List<String> ids = new ArrayList<>();
for (PintuanVO vo : pintuanVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
pintuanService.update(this.getUpdatePromotionWrapper(ids));
//将活动商品对照表进行结束处理
promotionGoodsService.update(this.getUpdatePromotionGoodsWrapper(ids));
}
} catch (Exception e) {
log.error("拼团活动关闭错误", e);
}
//结束满减活动
endFullDiscount(query);
//关闭拼团活动
endPintuan(query);
//结束优惠券
endCoupon(query);
//定时创建活动
addSeckill();
}
/**
* 结束优惠券活动
*
* @param query
*/
private void endCoupon(Query query) {
try {
//关闭优惠券活动
@ -142,15 +129,87 @@ public class PromotionEverydayExecute implements EveryDayExecute {
} catch (Exception e) {
log.error("优惠券活动关闭错误", e);
}
}
/**
* 结束拼团活动
*
* @param query
*/
private void endPintuan(Query query) {
try {
//关闭拼团活动
List<PintuanVO> pintuanVOS = mongoTemplate.find(query, PintuanVO.class);
if (!pintuanVOS.isEmpty()) {
//准备修改活动的id
List<String> ids = new ArrayList<>();
for (PintuanVO vo : pintuanVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
pintuanService.update(this.getUpdatePromotionWrapper(ids));
//将活动商品对照表进行结束处理
promotionGoodsService.update(this.getUpdatePromotionGoodsWrapper(ids));
}
} catch (Exception e) {
log.error("拼团活动关闭错误", e);
}
}
/**
* 结束满减活动
*
* @param query
*/
private void endFullDiscount(Query query) {
try {
//关闭满减活动
List<FullDiscountVO> fullDiscountVOS = mongoTemplate.find(query, FullDiscountVO.class);
if (!fullDiscountVOS.isEmpty()) {
List<String> ids = new ArrayList<>();
//循环活动 关闭活动
for (FullDiscountVO vo : fullDiscountVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
fullDiscountService.update(this.getUpdatePromotionWrapper(ids));
}
} catch (Exception e) {
log.error("满减活动关闭错误", e);
}
}
/**
* 添加秒杀活动
* 从系统设置中获取秒杀活动的配置
* 添加30天后的秒杀活动
*/
private void addSeckill() {
Setting setting = settingService.get(SettingEnum.SECKILL_SETTING.name());
SeckillSetting seckillSetting = new Gson().fromJson(setting.getSettingValue(), SeckillSetting.class);
Seckill seckill = new Seckill(30, seckillSetting.getHours(), seckillSetting.getSeckillRule());
seckillService.saveSeckill(seckill);
}
/**
* 获取促销修改查询条件 修改活动状态
*
* @param ids
* @return
* @param ids 促销活动ID
* @return 促销活动商品查询Wrapper
*/
private UpdateWrapper getUpdatePromotionWrapper(List<String> ids) {
UpdateWrapper updateWrapper = new UpdateWrapper<>();
@ -162,8 +221,8 @@ public class PromotionEverydayExecute implements EveryDayExecute {
/**
* 获取商品的促销修改查询条件 修改商品状态
*
* @param ids
* @return
* @param ids 促销活动ID
* @return 促销活动商品修改Wrapper
*/
private UpdateWrapper getUpdatePromotionGoodsWrapper(List<String> ids) {
UpdateWrapper updateWrapper = new UpdateWrapper<>();

View File

@ -186,7 +186,6 @@ class PageViewStatistics {
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
this.date = calendar.getTime();
System.out.println(DateUtil.toString(date,DateUtil.STANDARD_FORMAT));
}
}

View File

@ -0,0 +1,36 @@
package cn.lili.trigger.executor;
import cn.hutool.json.JSONUtil;
import cn.lili.common.delayqueue.BroadcastMessage;
import cn.lili.common.trigger.model.TimeExecuteConstant;
import cn.lili.modules.broadcast.service.StudioService;
import cn.lili.trigger.TimeTriggerExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 直播间事件触发
*
* @author Bulbasaur
* @date: 2021/6/1 5:02 下午
*/
@Slf4j
@Component(TimeExecuteConstant.BROADCAST_EXECUTOR)
public class BroadcastTimeTriggerExecutor implements TimeTriggerExecutor {
@Autowired
private StudioService studioService;
@Override
public void execute(Object object) {
//直播间订单消息
BroadcastMessage broadcastMessage = JSONUtil.toBean(JSONUtil.parseObj(object), BroadcastMessage.class);
if (broadcastMessage != null && broadcastMessage.getStudioId() != null) {
log.info("直播间消费:{}", broadcastMessage);
// 修改直播间状态
studioService.updateStudioStatus(broadcastMessage);
}
}
}

View File

@ -29,6 +29,6 @@ public class PromotionDelayQueueListen extends AbstractDelayQueueListen {
@Override
public String setDelayQueueName() {
return DelayQueueEnums.PROMOTION_QUEUE.name();
return DelayQueueEnums.PROMOTION.name();
}
}

View File

@ -4,9 +4,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:
@ -49,7 +46,7 @@ spring:
open-in-view: false
# Redis
redis:
host: 127.0.0.1
host: 192.168.0.116
port: 6379
password: lilishop
lettuce:
@ -80,7 +77,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&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
url: jdbc:mysql://127.0.0.1:3306/Bulbasaur?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root
password: lilishop
maxActive: 20
@ -282,6 +279,8 @@ lili:
notice-send-group: lili_send_notice_group
after-sale-topic: lili_after_sale_topic
after-sale-group: lili_after_sale_group
broadcast-topic: lili_broadcast_topic
broadcast-group: lili_broadcast_group
rocketmq:
name-server: 127.0.0.1:9876
producer:

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--应用名称-->
<property name="APP_NAME" value="consumer"/>
<!--日志文件保存路径-->
<property name="LOG_FILE_PATH" value="lili-logs"/>
<contextName>${APP_NAME}</contextName>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--输出到elk的LOGSTASH-->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- 配置elk日志收集 配饰的是 LOGSTASH 的地址-->
<destination>192.168.0.116:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
</providers>
<!--自定义字段 区分项目-->
<customFields>{"appName":"${APP_NAME}"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>

View File

@ -45,47 +45,16 @@
<de.codecentric>2.3.1</de.codecentric>
<userAgentUtils>1.21</userAgentUtils>
<interceptor-api>1.2</interceptor-api>
<poi-version>4.1.2</poi-version>
<poi-ooxml-version>4.1.2</poi-ooxml-version>
<logstash-logback-encoder>6.6</logstash-logback-encoder>
<zxing>3.4.1</zxing>
<slf4j-api>1.7.28</slf4j-api>
<xk-time>2.2.0</xk-time>
<commons-text>1.4</commons-text>
</properties>
<dependencies>
<dependency>
<groupId>javax.interceptor</groupId>
<artifactId>javax.interceptor-api</artifactId>
<version>${interceptor-api}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${de.codecentric}</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.28</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.github.xkzhangsan</groupId>
<artifactId>xk-time</artifactId>
<version>2.2.0</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-thymeleaf</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -356,23 +325,11 @@
<artifactId>simple-http</artifactId>
<version>${simple-http-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4-runtime -->
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>${antlr4-runtime-version}</version>
</dependency>
<!-- http client -->
<!-- <dependency>-->
<!-- <groupId>org.apache.httpcomponents</groupId>-->
<!-- <artifactId>httpclient</artifactId>-->
<!-- <version>${httpclient-version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.squareup.okhttp3</groupId>-->
<!-- <artifactId>okhttp</artifactId>-->
<!-- <version>${okhttp-version}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
@ -385,8 +342,54 @@
<artifactId>UserAgentUtils</artifactId>
<version>${userAgentUtils}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi-version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi-ooxml-version}</version>
</dependency>
<!--集成logstash-->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>${logstash-logback-encoder}</version>
</dependency>
<dependency>
<groupId>javax.interceptor</groupId>
<artifactId>javax.interceptor-api</artifactId>
<version>${interceptor-api}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${de.codecentric}</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>${zxing}</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>${zxing}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api}</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.github.xkzhangsan</groupId>
<artifactId>xk-time</artifactId>
<version>${xk-time}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>

View File

@ -1,6 +1,7 @@
package cn.lili.common.aop.limiter;
import cn.lili.common.aop.limiter.annotation.LimitPoint;
import cn.lili.common.exception.ServiceException;
import com.google.common.collect.ImmutableList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -21,6 +22,7 @@ import java.lang.reflect.Method;
/**
* 流量拦截
*
* @author Chopper
*/
@Aspect
@ -42,7 +44,7 @@ public class LimitInterceptor {
}
@Around("execution(public * *(..)) && @annotation(cn.lili.common.aop.limiter.annotation.LimitPoint)")
public Object interceptor(ProceedingJoinPoint pjp) {
public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
LimitPoint limitPointAnnotation = method.getAnnotation(LimitPoint.class);
@ -65,22 +67,26 @@ public class LimitInterceptor {
try {
Number count = redisTemplate.execute(limitScript, keys, limitCount, limitPeriod);
log.info("Access try count is {} for name={} and key = {}", count, name, key);
if (count != null && count.intValue() <= limitCount) {
// 如果缓存里没有值或者他的值小于限制频率
if (count.intValue() <= limitCount) {
return pjp.proceed();
} else {
throw new RuntimeException("访问过于频繁,请稍后再试");
}
} catch (Throwable e) {
if (e instanceof RuntimeException) {
throw new RuntimeException(e.getLocalizedMessage());
throw new ServiceException("访问过于频繁,请稍后再试");
}
}
//如果从redis中执行都值判定为空则这里跳过
catch (NullPointerException e) {
return pjp.proceed();
} catch (Exception e) {
throw new RuntimeException("服务器异常,请稍后再试");
}
}
//默认unknown常量值
private static final String UNKNOWN = "unknown";
//获取ip
public String getIpAddress() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = request.getHeader("x-forwarded-for");

View File

@ -219,7 +219,7 @@ public enum CachePrefix {
STORE_ID_FULL_DISCOUNT,
/**
* 限时抢购活动缓存key前缀
* 秒杀活动活动缓存key前缀
*/
STORE_ID_SECKILL,

View File

@ -1,6 +1,7 @@
package cn.lili.common.cache.impl;
import cn.lili.common.cache.Cache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
@ -18,6 +19,7 @@ import java.util.function.Consumer;
*
* @author Chopepr
*/
@Slf4j
@Component
public class RedisCache implements Cache {
@ -158,7 +160,7 @@ public class RedisCache implements Cache {
return null;
} catch (IOException e) {
e.printStackTrace();
log.error("scan错误",e);
throw new RuntimeException(e);
}
});

View File

@ -98,7 +98,7 @@ public abstract class BaseElasticsearchService {
log.info(" Indicates whether the requisite number of shard copies were started for each shard in the index before timing out :{}", createIndexResponse.isShardsAcknowledged());
return;
} catch (Exception e) {
e.printStackTrace();
log.error("创建索引错误",e);
throw new ElasticsearchException("创建索引 {" + index + "} 失败:" + e.getMessage());
}
}
@ -420,7 +420,7 @@ public abstract class BaseElasticsearchService {
try {
searchResponse = client.search(searchRequest, COMMON_OPTIONS);
} catch (IOException e) {
e.printStackTrace();
log.error("es 搜索错误",e);
}
return searchResponse;
}

View File

@ -97,7 +97,8 @@ public enum ResultCode {
USER_RECEIPT_NOT_EXIST(20014, "会员发票信息不存在"),
USER_EDIT_ERROR(20015, "用户修改失败"),
USER_OLD_PASSWORD_ERROR(20016, "旧密码不正确"),
USER_COLLECTION_EXIST(2001, "无法重复收藏"),
USER_COLLECTION_EXIST(20017, "无法重复收藏"),
USER_GRADE_IS_DEFAULT(20018, "会员等级为默认会员等级"),
DELETE_EXIST(2001, "无法重复收藏"),
/**
@ -124,61 +125,97 @@ public enum ResultCode {
* 购物车
*/
CART_ERROR(30001, "读取结算页的购物车异常"),
CART_PINTUAN_NOT_EXIST_ERROR(30002, "拼团活动不存在错误"),
CART_PINTUAN_LIMIT_ERROR(30003, "购买数量超过拼团活动限制数量"),
SHIPPING_NOT_APPLY(30005, "购物商品不支持当前收货地址配送"),
/**
* 订单
*/
ORDER_ERROR(31001, "创建订单异常,请稍后重试"),
ORDER_NOT_EXIST(31002, "订单不存在"),
ORDER_DELIVERED_ERROR(31003, "订单状态错误,无法进行确认收货"),
ORDER_UPDATE_PRICE_ERROR(31004, "已支付的订单不能修改金额"),
ORDER_LOGISTICS_ERROR(31005, "物流错误"),
ORDER_DELIVER_ERROR(31006, "物流错误"),
ORDER_NOT_USER(31007, "非当前会员的订单"),
ORDER_TAKE_ERROR(31008, "当前订单无法核销"),
MEMBER_ADDRESS_NOT_EXIST(31009, "订单无收货地址,请先配置收货地址"),
ORDER_DELIVER_NUM_ERROR(31010, "没有待发货的订单"),
/**
* 支付
*/
PAY_UN_WANTED(32000, "当前订单不需要付款,返回订单列表等待系统订单出库即可"),
PAY_SUCCESS(32001, "支付成功"),
PAY_INCONSISTENT_ERROR(32002, "付款金额和应付金额不一致"),
PAY_DOUBLE_ERROR(32003, "订单已支付,不能再次进行支付"),
PAY_CASHIER_ERROR(32004, "收银台信息获取错误"),
PAY_ERROR(32005, "支付业务异常,请稍后重试"),
PAY_BAN(32006, "当前订单不需要付款,请返回订单列表重新操作"),
PAY_PARTIAL_ERROR(32007, "该订单已部分支付,请前往订单中心进行支付"),
PAY_NOT_SUPPORT(32008, "支付暂不支持"),
PAY_CLIENT_TYPE_ERROR(32009, "错误的客户端"),
PAY_POINT_ENOUGH(32010, "积分不足,不能兑换"),
PAY_NOT_EXIST_ORDER(32011, "支付订单不存在"),
/**
* 售后
*/
AFTER_SALES_NOT_PAY_ERROR(33001, "当前订单未支付,不能申请售后"),
AFTER_SALES_CANCEL_ERROR(33002, "当前售后单无法取消"),
AFTER_SALES_BAN(33003, "订单状态不允许申请售后,请联系平台或商家"),
AFTER_SALES_DOUBLE_ERROR(33004, "售后已审核,无法重复操作"),
AFTER_SALES_LOGISTICS_ERROR(33005, "物流公司错误,请重新选择"),
AFTER_STATUS_ERROR(33006, "售后状态错误,请刷新页面"),
/**
* 投诉
*/
COMPLAINT_ORDER_ITEM_EMPTY_ERROR(33100, "订单不存在"),
COMPLAINT_SKU_EMPTY_ERROR(33101, "商品已下架,如需投诉请联系平台客服"),
COMPLAINT_ERROR(33102, "投诉异常,请稍后重试"),
/**
* 余额
*/
WALLET_NOT_EXIT_ERROR(34000, "钱包不存在,请联系管理员"),
WALLET_INSUFFICIENT(34001, "余额不足以支付订单,请充值!"),
WALLET_WITHDRAWAL_INSUFFICIENT(34002, "可提现金额不足!"),
WALLET_ERROR_INSUFFICIENT(34003, "零钱提现失败!"),
WALLET_REMARK_ERROR(34004, "请填写审核备注!"),
WALLET_APPLY_ERROR(34005, "提现申请异常!"),
/**
@ -195,52 +232,74 @@ public enum ResultCode {
* 优惠券
*/
COUPON_EDIT_STATUS_SUCCESS(41001, "修改状态成功!"),
COUPON_CANCELLATION_SUCCESS(41002, "会员优惠券作废成功"),
COUPON_EXPIRED(41003, "优惠券已使用/已过期,不能使用"),
COUPON_EDIT_STATUS_ERROR(41004, "优惠券修改状态失败!"),
/**
* 拼团
*/
PINTUAN_MANUAL_OPEN_SUCCESS(42001, "手动开启拼团活动成功"),
PINTUAN_MANUAL_CLOSE_SUCCESS(42002, "手动关闭拼团活动成功"),
PINTUAN_ADD_SUCCESS(42003, "添加拼团活动成功"),
PINTUAN_EDIT_SUCCESS(42004, "修改拼团活动成功"),
PINTUAN_DELETE_SUCCESS(42005, "删除拼团活动成功"),
PINTUAN_MANUAL_OPEN_ERROR(42006, "手动开启拼团活动失败"),
PINTUAN_MANUAL_CLOSE_ERROR(42007, "手动关闭拼团活动失败"),
PINTUAN_ADD_ERROR(42008, "添加拼团活动失败"),
PINTUAN_EDIT_ERROR(42009, "修改拼团活动失败"),
PINTUAN_DELETE_ERROR(42010, "删除拼团活动失败"),
/**
* 满额活动
*/
FULL_DISCOUNT_EDIT_SUCCESS(43001, "修改满优惠活动成功"),
FULL_DISCOUNT_EDIT_DELETE(43002, "删除满优惠活动成功"),
/**
* 店铺
*/
STORE_NOT_EXIST(50001, "此店铺不存在"),
STORE_NAME_EXIST_ERROR(50002, "店铺名称已存在!"),
STORE_APPLY_DOUBLE_ERROR(50003, "已有店铺,无需重复申请!"),
/**
* 结算单
*/
BILL_CHECK_ERROR(51001, "只有已出账结算单可以核对"),
BILL_COMPLETE_ERROR(51002, "只有已审核结算单可以支付"),
/**
* 文章
*/
ARTICLE_CATEGORY_NAME_EXIST(60001, "文章分类名称已存在"),
ARTICLE_CATEGORY_PARENT_NOT_EXIST(60002, "文章分类父分类不存在"),
ARTICLE_CATEGORY_BEYOND_TWO(60003, "最多为二级分类,操作失败"),
ARTICLE_CATEGORY_DELETE_ERROR(60004, "该文章分类下存在子分类,不能删除"),
ARTICLE_CATEGORY_HAS_ARTICLE(60005, "该文章分类下存在文章,不能删除"),
ARTICLE_CATEGORY_NO_DELETION(60007, "默认文章分类不能进行删除"),
ARTICLE_NO_DELETION(60008, "默认文章不能进行删除"),
@ -248,8 +307,11 @@ public enum ResultCode {
* 页面
*/
PAGE_NOT_EXIST(61001, "页面不存在"),
PAGE_OPEN_DELETE_ERROR(61002, "当前页面为开启状态,无法删除"),
PAGE_DELETE_ERROR(61003, "当前页面为唯一页面,无法删除"),
PAGE_RELEASE_ERROR(61004, "页面已发布,无需重复提交"),
/**
@ -266,39 +328,49 @@ public enum ResultCode {
* 站内信
*/
NOTICE_NOT_EXIST(80101, "当前消息模板不存在"),
NOTICE_ERROR(80102, "修改站内信异常,请稍后重试"),
/**
* OSS
*/
OSS_NOT_EXIST(80201, "OSS未配置"),
OSS_EXCEPTION(80202, "文件上传失败,请稍后重试"),
/**
* 验证码
*/
VERIFICATION_SEND_SUCCESS(80301, "短信验证码,发送成功"),
VERIFICATION_ERROR(80302, "验证失败"),
VERIFICATION_SMS_ERROR(80303, "短信验证码错误,请重新校验"),
VERIFICATION_SMS_EXPIRED_ERROR(80304, "验证码已失效,请重新校验"),
/**
* 配置错误
*/
ALIPAY_NOT_SETTING(80401, "支付宝支付未配置"),
ALIPAY_EXCEPTION(80402, "支付宝支付错误,请稍后重试"),
ALIPAY_PARAMS_EXCEPTION(80403, "支付宝参数异常"),
/**
* 微信相关异常
*/
WECHAT_CONNECT_NOT_SETTING(80500, "微信联合登陆信息未配置"),
WECHAT_PAYMENT_NOT_SETTING(80501, "微信支付信息未配置"),
WECHAT_QRCODE_ERROR(80502, "微信二维码生成异常"),
WECHAT_MP_MESSAGE_ERROR(80503, "微信小程序小消息订阅异常"),
APP_VERSION_EXIST(80600, "APP版本已存在")
;
APP_VERSION_EXIST(80600, "APP版本已存在");
private final Integer code;
private final String message;

View File

@ -119,7 +119,6 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
default:
return;
}
//如果是测试模式 默认验证码 6个1
if (systemSetting.getIsTestModel()) {
code = "111111";
@ -156,7 +155,7 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
try {
SendSmsResponse response = client.sendSms(sendSmsRequest);
} catch (Exception e) {
e.printStackTrace();
log.error("发送短信错误",e);
}
}
@ -192,7 +191,7 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
try {
client.sendBatchSms(sendBatchSmsRequest);
} catch (Exception e) {
e.printStackTrace();
log.error("批量发送短信错误",e);
}
}
@ -203,8 +202,6 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
public void addSmsSign(SmsSign smsSign) throws Exception {
//设置参数添加短信签名
com.aliyun.dysmsapi20170525.Client client = this.createClient();
System.out.println(smsSign.getBusinessLicense().substring(smsSign.getBusinessLicense().lastIndexOf(".") + 1));
System.out.println(smsSign.getLicense().substring(smsSign.getLicense().lastIndexOf(".")));
//营业执照
AddSmsSignRequest.AddSmsSignRequestSignFileList signFileList0 = new AddSmsSignRequest.AddSmsSignRequestSignFileList()
.setFileContents(Base64Utils.encode(smsSign.getBusinessLicense()))
@ -367,7 +364,7 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
config.endpoint = "dysmsapi.aliyuncs.com";
return new com.aliyun.dysmsapi20170525.Client(config);
} catch (Exception e) {
e.printStackTrace();
log.error("短信初始化错误",e);
}
return null;
}

View File

@ -2,8 +2,6 @@ package cn.lili.common.trigger.delay.queue;
import cn.lili.common.trigger.delay.AbstractDelayQueueMachineFactory;
import cn.lili.common.trigger.enums.DelayQueueEnums;
import cn.lili.common.trigger.interfaces.TimeTrigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
@ -18,11 +16,9 @@ import org.springframework.stereotype.Component;
@Component
public class PromotionDelayQueue extends AbstractDelayQueueMachineFactory {
@Autowired
private TimeTrigger timeTrigger;
@Override
public String setDelayQueueName() {
return DelayQueueEnums.PROMOTION_QUEUE.name();
return DelayQueueEnums.PROMOTION.name();
}
}

View File

@ -7,9 +7,9 @@ public enum DelayQueueEnums {
/**
* 促销任务队列
* 促销活动
*/
PROMOTION_QUEUE("促销任务队列");
PROMOTION("促销活动");
private String description;

View File

@ -6,7 +6,7 @@ package cn.lili.common.trigger.enums;
* @author paulG
* @since 2021/5/7
*/
public enum PromotionDelayTypeEnums {
public enum DelayTypeEnums {
/**
* 促销活动
@ -15,11 +15,16 @@ public enum PromotionDelayTypeEnums {
/**
* 拼团订单
*/
PINTUAN_ORDER("拼团订单");
PINTUAN_ORDER("拼团订单"),
/**
* 直播
*/
BROADCAST("直播");
private String description;
PromotionDelayTypeEnums(String description) {
DelayTypeEnums(String description) {
this.description = description;
}

View File

@ -0,0 +1,34 @@
package cn.lili.common.delayqueue;
import cn.hutool.core.date.DateTime;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* 直播消息实体
*
* @author Bulbasaur
* @date: 2021/6/1 4:48 下午
*/
@Data
@NoArgsConstructor
public class BroadcastMessage {
/**
* 直播间ID
*/
private String studioId;
/**
* 状态
*/
private String status;
public BroadcastMessage(String studioId, String status) {
this.studioId = studioId;
this.status = status;
}
}

View File

@ -13,4 +13,9 @@ public abstract class TimeExecuteConstant {
*/
public static final String PROMOTION_EXECUTOR = "promotionTimeTriggerExecutor";
/**
* 直播间延迟加载执行器
*/
public static final String BROADCAST_EXECUTOR = "broadcastTimeTriggerExecutor";
}

View File

@ -1,6 +1,6 @@
package cn.lili.common.trigger.util;
import cn.lili.common.trigger.enums.PromotionDelayTypeEnums;
import cn.lili.common.trigger.enums.DelayTypeEnums;
/**
* 延时任务工具类
@ -22,7 +22,7 @@ public class DelayQueueTools {
* @param id id
* @return 唯一键
*/
public static String wrapperUniqueKey(PromotionDelayTypeEnums type, String id) {
public static String wrapperUniqueKey(DelayTypeEnums type, String id) {
return "{TIME_TRIGGER_" + type.name() + "}_" + id;
}

View File

@ -1,5 +1,6 @@
package cn.lili.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.util.Base64;
@ -12,6 +13,7 @@ import java.io.*;
*
* @author Chopper
*/
@Slf4j
public class Base64DecodeMultipartFile implements MultipartFile {
private final byte[] imgContent;
@ -64,7 +66,7 @@ public class Base64DecodeMultipartFile implements MultipartFile {
stream = new FileOutputStream(dest);
stream.write(imgContent);
} catch (IOException e) {
e.printStackTrace();
log.error("transferTo错误",e);
}finally {
stream.close();
}
@ -92,7 +94,7 @@ public class Base64DecodeMultipartFile implements MultipartFile {
byte[] bytes = Base64.getDecoder().decode(base64);
stream = new ByteArrayInputStream(bytes);
} catch (Exception e) {
e.printStackTrace();
log.error("base64ToInputStream错误",e);
}
return stream;
}
@ -109,13 +111,13 @@ public class Base64DecodeMultipartFile implements MultipartFile {
}
data = swapStream.toByteArray();
} catch (IOException e) {
e.printStackTrace();
log.error("转码错误",e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
log.error("inputStreamToStream错误",e);
}
}
}

View File

@ -1,5 +1,7 @@
package cn.lili.common.utils;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -11,24 +13,9 @@ import javax.servlet.http.HttpServletResponse;
* @version v1.0
* 2020-12-14 09:32
*/
@Slf4j
public class CookieUtil {
/**
* 新增cookie
*
* @param key key值
* @param value 对应值
* @param response 响应
*/
public static void addCookie(String key, String value, HttpServletResponse response) {
try {
Cookie c = new Cookie(key, value);
c.setPath("/");
response.addCookie(c);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 新增cookie
@ -45,7 +32,7 @@ public class CookieUtil {
c.setPath("/");
response.addCookie(c);
} catch (Exception e) {
e.printStackTrace();
log.error("新增cookie错误",e);
}
}
@ -61,7 +48,7 @@ public class CookieUtil {
c.setMaxAge(0);
response.addCookie(c);
} catch (Exception e) {
e.printStackTrace();
log.error("删除cookie错误",e);
}
}
@ -83,7 +70,7 @@ public class CookieUtil {
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("获取cookie错误",e);
}
return null;
}

View File

@ -56,6 +56,24 @@ public final class CurrencyUtil {
return b1.multiply(b2).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @param scale 表示表示需要精确到小数点以后几位
* @return 两个参数的积
*/
public static Double mul(double v1, double v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供相对精确的除法运算当发生除不尽的情况时 精确到小数点以后10位以后的数字四舍五入
*

View File

@ -1,9 +1,12 @@
package cn.lili.common.utils;
import org.apache.http.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
@ -21,7 +24,6 @@ import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLException;
@ -30,10 +32,9 @@ import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Slf4j
public class HttpClientUtils {
// org.apache.http.impl.client.CloseableHttpClient
@ -146,11 +147,9 @@ public class HttpClientUtils {
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
} else {
System.out.println(response.getStatusLine().getStatusCode());
}
} catch (Exception e) {
e.printStackTrace();
log.error("get请求错误",e);
} finally {
try {
if (response != null) {
@ -158,71 +157,9 @@ public class HttpClientUtils {
}
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
log.error("Get错误",e);
}
}
return resultString;
}
public static String doPost(String url, Map<String, String> param) {
// 创建HttpClient对象
CloseableHttpClient httpClient = getHttpClient();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "utf-8");
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doPostJson(String url, String json) {
// 创建HttpClient对象
CloseableHttpClient httpClient = getHttpClient();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
}

View File

@ -1,13 +1,12 @@
package cn.lili.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -17,6 +16,7 @@ import java.util.concurrent.TimeUnit;
* @author paulG
* @since 2020/11/7
**/
@Slf4j
@Component
public class RedisUtil {
@Autowired
@ -38,51 +38,11 @@ public class RedisUtil {
}
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("指定缓存失效时间错误",e);
return false;
}
}
/**
* 根据key 获取过期时间
*
* @param key 不能为null
* @return 时间() 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断key是否存在
*
* @param key
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
//============================String=============================
@ -120,7 +80,7 @@ public class RedisUtil {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("缓存放入错误",e);
return false;
}
@ -143,215 +103,13 @@ public class RedisUtil {
}
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("普通缓存放入并设置时间错误",e);
return false;
}
}
/**
* 递增
*
* @param key
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
*
* @param key
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
//================================Map=================================
/**
* HashGet
*
* @param key 不能为null
* @param item 不能为null
* @return
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
*
* @param key
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
*
* @param key
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
*
* @param key
* @param map 对应多个键值
* @param time 时间()
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key
* @param item
* @param value
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key
* @param item
* @param value
* @param time 时间() 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除hash表中的值
*
* @param key 不能为null
* @param item 可以使多个 不能为null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
*
* @param key 不能为null
* @param item 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key
* @param item
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
*
* @param key
* @param item
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
//============================set=============================
/**
* 根据key获取Set中的所有值
*
* @param key
* @return
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
*
* @param key
* @param value
* @return true 存在 false不存在
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
@ -364,112 +122,11 @@ public class RedisUtil {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
log.error("将数据放入set缓存错误",e);
return 0;
}
}
/**
* 将set数据放入缓存
*
* @param key
* @param time 时间()
* @param values 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 获取set缓存的长度
*
* @param key
* @return
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值为value的
*
* @param key
* @param values 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//===============================listByParentId=================================
/**
* 获取list缓存的内容
*
* @param key
* @param start 开始
* @param end 结束 0 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
*
* @param key
* @return
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通过索引 获取list中的值
*
* @param key
* @param index 索引 index>=0时 0 表头1 第二个元素依次类推index<0时-1表尾-2倒数第二个元素依次类推
* @return
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
@ -483,7 +140,7 @@ public class RedisUtil {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("将list放入缓存错误",e);
return false;
}
}
@ -504,7 +161,7 @@ public class RedisUtil {
}
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("将list放入缓存错误",e);
return false;
}
}
@ -521,27 +178,11 @@ public class RedisUtil {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("将list放入缓存错误",e);
return false;
}
}
/**
* 将list放入缓存
*
* @param key
* @param value
* @return
*/
public <T> boolean lPush(String key, List<T> value) {
try {
redisTemplate.opsForList().leftPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
@ -559,46 +200,12 @@ public class RedisUtil {
}
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("将list放入缓存错误",e);
return false;
}
}
/**
* 根据索引修改list中的某条数据
*
* @param key
* @param index 索引
* @param value
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
*
* @param key
* @param count 移除多少个
* @param value
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//===============================ZSet=================================
/**

View File

@ -82,7 +82,7 @@ public class VerificationServiceImpl implements VerificationService {
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
log.error("创建校验错误",e);
return null;
}
}

View File

@ -1,6 +1,7 @@
package cn.lili.config.elasticsearch;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
@ -27,6 +28,7 @@ import java.util.List;
* @author paulG
* @since 2020/10/13
**/
@Slf4j
@Configuration
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
@ -96,7 +98,7 @@ public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
try {
this.client.close();
} catch (IOException e) {
e.printStackTrace();
log.error("es clientClose错误",e);
}
}

View File

@ -61,4 +61,8 @@ public class RocketmqCustomProperties {
private String afterSaleGroup;
private String broadcastTopic;
private String broadcastGroup;
}

View File

@ -58,7 +58,7 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
//删除缓存
cache.vagueDel("{regions}");
} catch (Exception e) {
e.printStackTrace();
log.error("同步行政数据错误",e);
}
}

View File

@ -0,0 +1,64 @@
package cn.lili.modules.broadcast.entity.dos;
import cn.lili.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* 小程序直播商品
* @author Bulbasaur
* @date: 2021/5/17 9:34 上午
*
*/
@Data
@Entity
@ApiModel(value = "Commodity", description = "直播商品")
@TableName("li_commodity")
@Table(name = "li_commodity")
public class Commodity extends BaseEntity {
@ApiModelProperty(value = "图片")
private String goodsImage;
@ApiModelProperty(value = "商品名称")
private String name;
//1一口价只需要传入priceprice2不传
// 2价格区间price字段为左边界price2字段为右边界price和price2必传
// 3显示折扣价price字段为原价price2字段为现价 price和price2必传
@ApiModelProperty(value = "价格类型")
private Integer priceType;
@ApiModelProperty(value = "价格")
private Double price;
@ApiModelProperty(value = "价格2")
private Double price2;
@ApiModelProperty(value = "商品详情页的小程序路径")
private String url;
@ApiModelProperty(value = "微信程序直播商品ID")
private Integer liveGoodsId;
@ApiModelProperty(value = "审核单ID")
private String auditId;
@ApiModelProperty(value = "审核状态")
private String auditStatus;
@ApiModelProperty(value = "店铺ID")
private String storeId;
@ApiModelProperty(value = "商品ID")
private String goodsId;
@ApiModelProperty(value = "规格ID")
private String skuId;
}

View File

@ -0,0 +1,97 @@
package cn.lili.modules.broadcast.entity.dos;
import cn.lili.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* 小程序直播间
*
* @author Bulbasaur
* @date: 2021/5/17 9:47 上午
*/
@Data
@Entity
@ApiModel(value = "直播间")
@TableName("li_studio")
@Table(name = "li_studio")
public class Studio extends BaseEntity {
/**
* 直播间名字最短3个汉字最长17个汉字1个汉字相当于2个字符
*/
@ApiModelProperty(value = "直播间名字")
private String name;
/**
* 背景图填入mediaIDmediaID获取后三天内有效图片mediaID的获取请参考以下文档 https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html直播间背景图图片规则建议像素1080*1920大小不超过2M
*/
@ApiModelProperty(value = "背景图")
private String coverImg;
/**
* 直播计划开始时间开播时间需要在当前时间的10分钟后 并且 开始时间不能在 6 个月后
*/
@ApiModelProperty(value = "开始时间")
private String startTime;
/**
* 直播计划结束时间开播时间和结束时间间隔不得短于30分钟不得超过24小时
*/
@ApiModelProperty(value = "结束时间")
private String endTime;
/**
* 主播昵称最短2个汉字最长15个汉字1个汉字相当于2个字符
*/
@ApiModelProperty(value = "主播昵称")
private String anchorName;
/**
* 主播微信号如果未实名认证需要先前往小程序直播小程序进行实名验证, 小程序二维码链接https://res.wx.qq.com/op_res/9rSix1dhHfK4rR049JL0PHJ7TpOvkuZ3mE0z7Ou_Etvjf-w1J_jVX0rZqeStLfwh
*/
@ApiModelProperty(value = "主播微信号")
private String anchorWechat;
/**
* 分享图填入mediaIDmediaID获取后三天内有效图片mediaID的获取请参考以下文档 https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html直播间分享图图片规则建议像素800*640大小不超过1M
*/
@ApiModelProperty(value = "分享图")
private String shareImg;
/**
* 购物直播频道封面图填入mediaIDmediaID获取后三天内有效图片mediaID的获取请参考以下文档 https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html; 购物直播频道封面图图片规则建议像素800*800大小不超过100KB
*/
@ApiModelProperty(value = "封面图")
private String feedsImg;
@ApiModelProperty(value = "回放视频链接")
private String mediaUrl;
@ApiModelProperty(value = "房间ID")
private Integer roomId;
@ApiModelProperty(value = "小程序直播码")
private String qrCodeUrl;
@ApiModelProperty(value = "店铺ID")
private String storeId;
@ApiModelProperty(value = "直播间商品数量")
private Integer roomGoodsNum;
@ApiModelProperty(value = "直播间商品(最多展示两个商品name/goodsImage)")
private String roomGoodsList;
@ApiModelProperty(value = "推荐直播间")
private boolean recommend;
@ApiModelProperty(value = "直播间状态")
private String status;
}

View File

@ -0,0 +1,47 @@
package cn.lili.modules.broadcast.entity.dos;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* 直播商品
*
* @author Bulbasaur
* @date: 2021/5/18 5:42 下午
*/
@Data
@Entity
@ApiModel(value = "直播商品")
@TableName("li_studio_commodity")
@Table(name = "li_studio_commodity")
@NoArgsConstructor
public class StudioCommodity {
@Id
@TableId
@TableField
@Column(columnDefinition = "bigint(20)")
@ApiModelProperty(value = "唯一标识", hidden = true)
private String id;
@ApiModelProperty(value = "房间ID")
private Integer roomId;
@ApiModelProperty(value = "商品ID")
private Integer goodsId;
public StudioCommodity(Integer roomId, Integer goodsId) {
this.roomId = roomId;
this.goodsId = goodsId;
}
}

View File

@ -0,0 +1,22 @@
package cn.lili.modules.broadcast.entity.dto;
import lombok.Data;
/**
* 直播商品DTO
* 用于获取直播商品状态时使用
*
* @author Bulbasaur
* @date: 2021/5/25 12:12 下午
*/
@Data
public class CommodityDTO {
//商品ID
private Integer goods_id;
//商品名称
private String name;
//地址
private String url;
//审核状态
private Integer audit_status;
}

View File

@ -0,0 +1,43 @@
package cn.lili.modules.broadcast.entity.dto;
import cn.lili.common.utils.BeanUtil;
import cn.lili.modules.broadcast.entity.dos.Commodity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 微信小程序直播商品DTO
* @author Bulbasaur
* @date: 2021/5/17 11:03 上午
*
*/
@Data
@NoArgsConstructor
public class GoodsInfo {
@ApiModelProperty(value = "图片mediaID")
private String coverImgUrl;
@ApiModelProperty(value = "商品名称")
private String name;
//1一口价只需要传入priceprice2不传
// 2价格区间price字段为左边界price2字段为右边界price和price2必传
// 3显示折扣价price字段为原价price2字段为现价 price和price2必传
@ApiModelProperty(value = "价格类型")
private Integer priceType;
@ApiModelProperty(value = "价格")
private Double price;
@ApiModelProperty(value = "价格2")
private Double price2;
@ApiModelProperty(value = "商品详情页的小程序路径")
private String url;
public GoodsInfo(Commodity commodity){
BeanUtil.copyProperties(commodity, this);
}
}

View File

@ -0,0 +1,18 @@
package cn.lili.modules.broadcast.entity.dto;
import io.swagger.annotations.ApiModelProperty;
/**
* 用于直播间前台使用的直播间商品DTO
*
* @author Bulbasaur
* @date: 2021/5/20 2:34 下午
*/
public class SimpleCommodity {
@ApiModelProperty(value = "图片")
private String goodsImage;
@ApiModelProperty(value = "商品名称")
private String name;
}

View File

@ -0,0 +1,27 @@
package cn.lili.modules.broadcast.entity.enums;
/**
* 直播间状态
* @author Bulbasaur
* @date: 2021/5/31 10:32 上午
*
*/
public enum StudioStatusEnum {
NEW("新建"), START("开始"), END("结束");
private final String clientName;
StudioStatusEnum(String des) {
this.clientName = des;
}
public String clientName() {
return this.clientName;
}
public String value() {
return this.name();
}
}

View File

@ -0,0 +1,21 @@
package cn.lili.modules.broadcast.entity.vos;
import cn.lili.modules.broadcast.entity.dos.Commodity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 直播商品VO
*
* @author Bulbasaur
* @date: 2021/5/26 6:09 下午
*/
@Data
public class CommodityVO extends Commodity {
@ApiModelProperty(value = "SKU库存")
private Integer quantity;
@ApiModelProperty(value = "店铺名称")
private String storeName;
}

View File

@ -0,0 +1,22 @@
package cn.lili.modules.broadcast.entity.vos;
import cn.lili.modules.broadcast.entity.dos.Commodity;
import cn.lili.modules.broadcast.entity.dos.Studio;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* 直播间VO
*
* @author Bulbasaur
* @date: 2021/5/31 11:58 上午
*/
@Data
public class StudioVO extends Studio {
@ApiModelProperty(value = "直播间商品列表")
private List<Commodity> commodityList;
}

View File

@ -0,0 +1,35 @@
package cn.lili.modules.broadcast.mapper;
import cn.lili.modules.broadcast.entity.dos.Commodity;
import cn.lili.modules.broadcast.entity.dto.SimpleCommodity;
import cn.lili.modules.broadcast.entity.vos.CommodityVO;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 直播商品数据层
*
* @author Bulbasaur
* @date: 2021/5/17 9:56 上午
*/
public interface CommodityMapper extends BaseMapper<Commodity> {
@Select("SELECT live_goods_id FROM li_commodity WHERE audit_status='0' or audit_status='1'")
List<String> getAuditCommodity();
@Select("SELECT * FROM li_commodity c INNER JOIN li_studio_commodity sc ON sc.goods_id = c.live_goods_id WHERE sc.room_id =#{roomId}")
List<Commodity> getCommodityByRoomId(Integer roomId);
@Select("SELECT goods_image FROM li_commodity c INNER JOIN li_studio_commodity sc ON sc.goods_id = c.live_goods_id WHERE sc.room_id =#{roomId}")
List<String> getSimpleCommodityByRoomId(Integer roomId);
@Select("SELECT c.*,gs.quantity,s.store_name FROM li_commodity c INNER JOIN li_goods_sku gs ON c.sku_id = gs.id INNER JOIN li_store s ON s.id=c.store_id ${ew.customSqlSegment}")
IPage<CommodityVO> commodityVOList(IPage<CommodityVO> page, @Param(Constants.WRAPPER) Wrapper<CommodityVO> queryWrapper);
}

View File

@ -0,0 +1,13 @@
package cn.lili.modules.broadcast.mapper;
import cn.lili.modules.broadcast.entity.dos.StudioCommodity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* 直播间-商品关联持久层
* @author Bulbasaur
* @date: 2021/5/17 3:14 下午
*
*/
public interface StudioCommodityMapper extends BaseMapper<StudioCommodity> {
}

View File

@ -0,0 +1,14 @@
package cn.lili.modules.broadcast.mapper;
import cn.lili.modules.broadcast.entity.dos.Studio;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* 直播间数据层
*
* @author Bulbasaur
* @date: 2021/5/17 9:56 上午
*/
public interface StudioMapper extends BaseMapper<Studio> {
}

View File

@ -0,0 +1,45 @@
package cn.lili.modules.broadcast.service;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.broadcast.entity.dos.Commodity;
import cn.lili.modules.broadcast.entity.vos.CommodityVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 直播商品业务层
*
* @author Bulbasaur
* @date: 2021/5/17 10:39 上午
*/
public interface CommodityService extends IService<Commodity> {
/**
* 添加直播商品
* @return 添加结果
*/
boolean addCommodity(List<Commodity> commodity);
/**
* 删除直播商品
* @param goodsId 直播商品ID
* @return 删除结果
*/
boolean deleteCommodity(String goodsId);
/**
* 查询微信小程序直播商品审核状态
*/
void getGoodsWareHouse();
/**
* 查看直播商品分页
* @param pageVO 分页
* @param name 商品名称
* @param auditStatus 审核状态
* @return 直播商品分页
*/
IPage<CommodityVO> commodityList(PageVO pageVO, String name, String auditStatus);
}

View File

@ -0,0 +1,13 @@
package cn.lili.modules.broadcast.service;
import cn.lili.modules.broadcast.entity.dos.StudioCommodity;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 直播间-商品关联业务层
*
* @author Bulbasaur
* @date: 2021/5/17 3:19 下午
*/
public interface StudioCommodityService extends IService<StudioCommodity> {
}

View File

@ -0,0 +1,79 @@
package cn.lili.modules.broadcast.service;
import cn.lili.common.delayqueue.BroadcastMessage;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.broadcast.entity.dos.Studio;
import cn.lili.modules.broadcast.entity.vos.StudioVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 直播间业务层
*
* @author Bulbasaur
* @date: 2021/5/17 10:02 上午
*/
public interface StudioService extends IService<Studio> {
/**
* 创建直播间
* 直播间默认手机直播
* 默认开启点赞商品货架评论回放
* @param studio 直播间
* @return 开启状态
*/
Boolean create(Studio studio);
/**
* 修改直播间
* 直播间默认手机直播
* @param studio 直播间
* @return 修改状态
*/
Boolean edit(Studio studio);
/**
* 获取直播间信息
* @param id 直播间ID
* @return 直播间VO
*/
StudioVO getStudioVO(String id);
/**
* 获取直播间回放
* @param roomId 房间ID
* @return 直播间回放地址
*/
String getLiveInfo(Integer roomId);
/**
* 推送商品
* @param roomId 店铺ID
* @param goodsId 商品ID
* @return 操作结果
*/
Boolean push(Integer roomId,Integer goodsId);
/**
* 删除商品
* @param roomId 店铺ID
* @param goodsId 商品ID
* @return 操作结果
*/
Boolean goodsDeleteInRoom(Integer roomId,Integer goodsId);
/**
* 获取直播间列表
* @param pageVO 分页
* @param recommend 是否推荐
* @param status 直播间状态
* @return 直播间分页
*/
IPage<Studio> studioList(PageVO pageVO, Integer recommend, String status);
/**
* 修改直播间状态
* @param broadcastMessage 直播间消息
*/
void updateStudioStatus(BroadcastMessage broadcastMessage);
}

View File

@ -0,0 +1,112 @@
package cn.lili.modules.broadcast.serviceimpl;
import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.utils.PageUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.broadcast.entity.dos.Commodity;
import cn.lili.modules.broadcast.entity.dto.CommodityDTO;
import cn.lili.modules.broadcast.entity.vos.CommodityVO;
import cn.lili.modules.broadcast.mapper.CommodityMapper;
import cn.lili.modules.broadcast.service.CommodityService;
import cn.lili.modules.broadcast.util.WechatLivePlayerUtil;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.service.GoodsSkuService;
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.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 直播商品业务层实现
*
* @author Bulbasaur
* @date: 2021/5/17 11:16 上午
*/
@Service
public class CommodityServiceImpl extends ServiceImpl<CommodityMapper, Commodity> implements CommodityService {
@Autowired
private WechatLivePlayerUtil wechatLivePlayerUtil;
@Autowired
private GoodsSkuService goodsSkuService;
@Override
public boolean addCommodity(List<Commodity> commodityList) {
for (Commodity commodity : commodityList) {
//检测直播商品
checkCommodity(commodity);
//添加直播商品
JSONObject json = wechatLivePlayerUtil.addGoods(commodity);
if(!json.getStr("errcode").equals("0")){
throw new ServiceException(json.getStr("errmsg"));
}
commodity.setLiveGoodsId(Convert.toInt(json.getStr("goodsId")));
commodity.setAuditId(json.getStr("auditId"));
commodity.setStoreId(UserContext.getCurrentUser().getStoreId());
//默认为待审核状态
commodity.setAuditStatus("0");
this.save(commodity);
}
return true;
}
private void checkCommodity(Commodity commodity) {
//商品是否审核通过
GoodsSku goodsSku = goodsSkuService.getById(commodity.getSkuId());
if (!goodsSku.getIsAuth().equals(GoodsAuthEnum.PASS.name())) {
throw new ServiceException(goodsSku.getGoodsName() + " 未审核通过,不能添加直播商品");
}
//是否已添加规格商品
if (this.count(new LambdaQueryWrapper<Commodity>().eq(Commodity::getSkuId, commodity.getSkuId())) > 0) {
throw new ServiceException(goodsSku.getGoodsName() + " 已添加规格商品,无法重复增加");
}
}
@Override
public boolean deleteCommodity(String goodsId) {
JSONObject json = wechatLivePlayerUtil.deleteGoods(goodsId);
if (json.getStr("errcode").equals("0")) {
return this.remove(new LambdaQueryWrapper<Commodity>().eq(Commodity::getLiveGoodsId, goodsId));
}
return false;
}
@Override
public void getGoodsWareHouse() {
//查询审核中的商品
List<String> goodsIdList = this.baseMapper.getAuditCommodity();
if (goodsIdList.size() > 0) {
//同步状态
JSONObject json = wechatLivePlayerUtil.getGoodsWareHouse(goodsIdList);
//修改状态
List<CommodityDTO> commodityDTOList = JSONUtil.toList((JSONArray) json.get("goods"), CommodityDTO.class);
for (CommodityDTO commodityDTO : commodityDTOList) {
//修改审核状态
this.update(new LambdaUpdateWrapper<Commodity>()
.eq(Commodity::getLiveGoodsId, commodityDTO.getGoods_id())
.set(Commodity::getAuditStatus, commodityDTO.getAudit_status()));
}
}
}
@Override
public IPage<CommodityVO> commodityList(PageVO pageVO, String name, String auditStatus) {
return this.baseMapper.commodityVOList(PageUtil.initPage(pageVO),
new QueryWrapper<CommodityVO>().like(name != null, "c.name", name)
.eq(auditStatus != null, "c.audit_status", auditStatus)
.eq(UserContext.getCurrentUser().getRole().equals(UserEnums.STORE), "c.store_id", UserContext.getCurrentUser().getStoreId())
.orderByDesc("create_time"));
}
}

View File

@ -0,0 +1,17 @@
package cn.lili.modules.broadcast.serviceimpl;
import cn.lili.modules.broadcast.entity.dos.StudioCommodity;
import cn.lili.modules.broadcast.mapper.StudioCommodityMapper;
import cn.lili.modules.broadcast.service.StudioCommodityService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* 直播间-商品关联业务层实现
*
* @author Bulbasaur
* @date: 2021/5/17 3:20 下午
*/
@Service
public class StudioCommodityServiceImpl extends ServiceImpl<StudioCommodityMapper, StudioCommodity> implements StudioCommodityService {
}

View File

@ -0,0 +1,212 @@
package cn.lili.modules.broadcast.serviceimpl;
import cn.hutool.json.JSONUtil;
import cn.lili.common.delayqueue.BroadcastMessage;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.trigger.enums.DelayTypeEnums;
import cn.lili.common.trigger.interfaces.TimeTrigger;
import cn.lili.common.trigger.model.TimeExecuteConstant;
import cn.lili.common.trigger.model.TimeTriggerMsg;
import cn.lili.common.trigger.util.DelayQueueTools;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.utils.DateUtil;
import cn.lili.common.utils.PageUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.config.rocketmq.RocketmqCustomProperties;
import cn.lili.modules.broadcast.entity.dos.Studio;
import cn.lili.modules.broadcast.entity.dos.StudioCommodity;
import cn.lili.modules.broadcast.entity.enums.StudioStatusEnum;
import cn.lili.modules.broadcast.entity.vos.StudioVO;
import cn.lili.modules.broadcast.mapper.CommodityMapper;
import cn.lili.modules.broadcast.mapper.StudioMapper;
import cn.lili.modules.broadcast.service.StudioCommodityService;
import cn.lili.modules.broadcast.service.StudioService;
import cn.lili.modules.broadcast.util.WechatLivePlayerUtil;
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.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Map;
/**
* 小程序直播间业务层实现
*
* @author Bulbasaur
* @date: 2021/5/17 10:04 上午
*/
@Service
public class StudioServiceImpl extends ServiceImpl<StudioMapper, Studio> implements StudioService {
@Autowired
private WechatLivePlayerUtil wechatLivePlayerUtil;
@Autowired
private StudioCommodityService studioCommodityService;
@Resource
private CommodityMapper commodityMapper;
//延时任务
@Autowired
private TimeTrigger timeTrigger;
//Rocketmq
@Autowired
private RocketmqCustomProperties rocketmqCustomProperties;
@Override
public Boolean create(Studio studio) {
try {
//创建小程序直播
Map<String, String> roomMap = wechatLivePlayerUtil.create(studio);
studio.setRoomId(Integer.parseInt(roomMap.get("roomId")));
studio.setQrCodeUrl(roomMap.get("qrcodeUrl"));
studio.setStoreId(UserContext.getCurrentUser().getStoreId());
studio.setStatus(StudioStatusEnum.NEW.name());
//直播间添加成功发送直播间开启关闭延时任务
if (this.save(studio)) {
//直播开启延时任务
BroadcastMessage broadcastMessage = new BroadcastMessage(studio.getId(), StudioStatusEnum.START.name());
TimeTriggerMsg timeTriggerMsg = new TimeTriggerMsg(TimeExecuteConstant.BROADCAST_EXECUTOR,
Long.parseLong(studio.getStartTime()) * 1000L, broadcastMessage,
DelayQueueTools.wrapperUniqueKey(DelayTypeEnums.BROADCAST, studio.getId()),
rocketmqCustomProperties.getPromotionTopic());
// 发送促销活动开始的延时任务
this.timeTrigger.addDelay(timeTriggerMsg);
//直播结束延时任务
broadcastMessage = new BroadcastMessage(studio.getId(), StudioStatusEnum.END.name());
timeTriggerMsg = new TimeTriggerMsg(TimeExecuteConstant.BROADCAST_EXECUTOR,
Long.parseLong(studio.getEndTime()) * 1000L, broadcastMessage,
DelayQueueTools.wrapperUniqueKey(DelayTypeEnums.BROADCAST, studio.getId()),
rocketmqCustomProperties.getPromotionTopic());
// 发送促销活动开始的延时任务
this.timeTrigger.addDelay(timeTriggerMsg);
}
return true;
} catch (Exception e) {
throw new ServiceException(ResultCode.ERROR);
}
}
@Override
public Boolean edit(Studio studio) {
Studio oldStudio = this.getById(studio.getId());
wechatLivePlayerUtil.editRoom(studio);
if (this.updateById(studio)) {
// 发送更新延时任务
//直播间开始
BroadcastMessage broadcastMessage = new BroadcastMessage(studio.getId(), StudioStatusEnum.START.name());
this.timeTrigger.edit(
TimeExecuteConstant.BROADCAST_EXECUTOR,
broadcastMessage,
Long.parseLong(oldStudio.getStartTime()),
Long.parseLong(studio.getStartTime()),
DelayQueueTools.wrapperUniqueKey(DelayTypeEnums.BROADCAST, studio.getId()),
DateUtil.getDelayTime(Long.parseLong(studio.getStartTime())),
rocketmqCustomProperties.getPromotionTopic());
//直播间结束
broadcastMessage = new BroadcastMessage(studio.getId(), StudioStatusEnum.START.name());
this.timeTrigger.edit(
TimeExecuteConstant.BROADCAST_EXECUTOR,
broadcastMessage,
Long.parseLong(oldStudio.getEndTime()),
Long.parseLong(studio.getEndTime()),
DelayQueueTools.wrapperUniqueKey(DelayTypeEnums.BROADCAST, studio.getId()),
DateUtil.getDelayTime(Long.parseLong(studio.getEndTime())),
rocketmqCustomProperties.getPromotionTopic());
}
return true;
}
@Override
public StudioVO getStudioVO(String id) {
StudioVO studioVO = new StudioVO();
//获取直播间信息
BeanUtil.copyProperties(this.getById(id), studioVO);
//获取直播间商品信息
studioVO.setCommodityList(commodityMapper.getCommodityByRoomId(studioVO.getRoomId()));
return studioVO;
}
@Override
public String getLiveInfo(Integer roomId) {
Studio studio = this.getByRoomId(roomId);
//获取直播间并判断回放内容是否为空如果为空则获取直播间回放并保存
if (studio.getMediaUrl() != null) {
return studio.getMediaUrl();
} else {
String mediaUrl = wechatLivePlayerUtil.getLiveInfo(roomId);
studio.setMediaUrl(mediaUrl);
this.save(studio);
return mediaUrl;
}
}
@Override
public Boolean push(Integer roomId, Integer goodsId) {
//调用微信接口添加直播间商品并进行记录
if (wechatLivePlayerUtil.pushGoods(roomId, goodsId)) {
studioCommodityService.save(new StudioCommodity(roomId, goodsId));
//添加直播间商品数量
Studio studio = this.getByRoomId(roomId);
studio.setRoomGoodsNum(studio.getRoomGoodsNum() != null ? studio.getRoomGoodsNum() + 1 : 1);
//设置直播间默认的商品前台展示只展示两个
if (studio.getRoomGoodsNum() < 3) {
studio.setRoomGoodsList(JSONUtil.toJsonStr(commodityMapper.getSimpleCommodityByRoomId(roomId)));
}
return this.updateById(studio);
}
return false;
}
@Override
public Boolean goodsDeleteInRoom(Integer roomId, Integer goodsId) {
//调用微信接口删除直播间商品并进行记录
if (wechatLivePlayerUtil.goodsDeleteInRoom(roomId, goodsId)) {
studioCommodityService.remove(new QueryWrapper<StudioCommodity>().eq("room_id", roomId).eq("goods_id", goodsId));
//减少直播间商品数量
Studio studio = this.getByRoomId(roomId);
studio.setRoomGoodsNum(studio.getRoomGoodsNum() - 1);
//设置直播间默认的商品前台展示只展示两个
if (studio.getRoomGoodsNum() < 3) {
studio.setRoomGoodsList(JSONUtil.toJsonStr(commodityMapper.getSimpleCommodityByRoomId(roomId)));
}
return this.updateById(studio);
}
return false;
}
@Override
public IPage<Studio> studioList(PageVO pageVO, Integer recommend, String status) {
return this.page(PageUtil.initPage(pageVO), new QueryWrapper<Studio>()
.eq(recommend != null, "recommend", true)
.eq(status != null, "status", status)
.orderByDesc("create_time"));
}
@Override
public void updateStudioStatus(BroadcastMessage broadcastMessage) {
this.update(new LambdaUpdateWrapper<Studio>()
.eq(Studio::getId, broadcastMessage.getStudioId())
.set(Studio::getStatus, broadcastMessage.getStatus()));
}
/**
* 根据直播间ID获取直播间
*
* @param roomId 直播间ID
* @return 直播间
*/
private Studio getByRoomId(Integer roomId) {
return this.getOne(new LambdaQueryWrapper<Studio>().eq(Studio::getRoomId, roomId));
}
}

View File

@ -0,0 +1,261 @@
package cn.lili.modules.broadcast.util;
import cn.hutool.json.JSONObject;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.base.entity.enums.ClientTypeEnum;
import cn.lili.modules.broadcast.entity.dos.Commodity;
import cn.lili.modules.broadcast.entity.dos.Studio;
import cn.lili.modules.broadcast.entity.dto.GoodsInfo;
import cn.lili.modules.message.util.WechatAccessTokenUtil;
import cn.lili.modules.system.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 微信小程序直播工具类
*
* @author Bulbasaur
* @date: 2021/5/17 10:16 上午
*/
@Slf4j
@Component
public class WechatLivePlayerUtil {
@Autowired
private WechatAccessTokenUtil wechatAccessTokenUtil;
@Autowired
private WechatMediaUtil wechatMediaUtil;
/**
* 创建小程序直播间
*
* @param studio 小程序直播
* @return 房间ID
*/
public Map<String, String> create(Studio studio) throws Exception {
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxaapi/broadcast/room/create?access_token=" + token;
//添加直播间
Map<String, String> map = this.mockRoom(token, studio);
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序直播间创建结果:" + content);
if (!json.getStr("errcode").equals("0")) {
throw new ServiceException(json.getStr("errmsg"));
}
Map<String, String> roomMap = new HashMap<>();
roomMap.put("roomId", json.getStr("roomId"));
roomMap.put("qrcodeUrl", json.getStr("qrcode_url"));
return roomMap;
}
/**
* 创建小程序直播间
*
* @param studio 小程序直播
* @return 房间ID
*/
public boolean editRoom(Studio studio) {
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxaapi/broadcast/room/editroom?access_token=" + token;
//修改直播间
Map<String, String> map = this.mockRoom(token, studio);
map.put("id", studio.getRoomId().toString());
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序直播间修改结果:" + content);
if (!json.getStr("errcode").equals("0")) {
throw new ServiceException(json.getStr("errmsg"));
}
return true;
}
/**
* 获取直播间回放
*
* @param roomId 房间ID
* @return 回放地址
*/
public String getLiveInfo(Integer roomId) {
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxa/business/getliveinfo?access_token=" + token;
Map<String, Object> map = new HashMap<>();
// 获取回放
map.put("action", "get_replay");
// 直播间ID
map.put("room_id", roomId);
// 起始拉取视频0表示从第一个视频片段开始拉取
map.put("start", "0");
// 每次拉取的数量建议100以内
map.put("limit", "1");
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序获取信息:" + content);
//TODO get media_url
return json.getStr("live_replay");
}
/**
* 推送直播间商品
*
* @param roomId 房间ID
* @param goodsId 商品ID
* @return 操作结果
*/
public Boolean pushGoods(Integer roomId, Integer goodsId) {
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxaapi/broadcast/room/addgoods?access_token=" + token;
Map<String, Object> map = new HashMap<>();
// 直播间回放
Integer[] ids = {goodsId};
map.put("ids", ids);
// 商品ID
map.put("roomId", roomId);
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("直播间导入商品:" + content);
if (!json.getStr("errcode").equals("0")) {
throw new ServiceException(json.getStr("errmsg"));
}
return true;
}
/**
* 删除直播间商品
*
* @param roomId 房间ID
* @param goodsId 商品ID
* @return 操作结果
*/
public Boolean goodsDeleteInRoom(Integer roomId, Integer goodsId) {
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/deleteInRoom?access_token=" + token;
Map<String, Integer> map = new HashMap<>();
// 直播间回放
map.put("goodsId", goodsId);
// 商品ID
map.put("roomId", roomId);
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序直播间删除商品:" + content);
return json.getStr("errcode").equals("0");
}
/**
* 添加直播商品
*
* @param commodity 直播商品
* @return 添加结果
*/
public JSONObject addGoods(Commodity commodity) {
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/add?access_token=" + token;
//商品名称最长14个汉字
if (commodity.getName().length() > 14) {
commodity.setName(commodity.getName().substring(0, 13));
}
//新建微信商品DTO
GoodsInfo goodsInfo = new GoodsInfo(commodity);
//上传微信临时图片
goodsInfo.setCoverImgUrl(wechatMediaUtil.uploadMedia(token, "image", commodity.getGoodsImage()));
Map<String, GoodsInfo> map = new HashMap<>();
//调用新增直播商品接口
map.put("goodsInfo", goodsInfo);
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序添加直播商品结果:" + content);
return json;
}
/**
* 删除直播商品
*
* @param goodsId 商品ID
* @return 删除结果
*/
public JSONObject deleteGoods(String goodsId) {
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/delete?access_token=" + token;
Map<String, Object> map = new HashMap<>();
map.put("goodsId", goodsId);
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序删除直播商品结果:" + content);
return json;
}
/**
* 查询直播商品状态
*
* @param goodsIdList 商品ID列表
* @return 删除结果
*/
public JSONObject getGoodsWareHouse(List<String> goodsIdList) {
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxa/business/getgoodswarehouse?access_token=" + token;
Map<String, Object> map = new HashMap<>();
map.put("goods_ids", goodsIdList);
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序查询直播商品结果:" + content);
return json;
}
private Map<String, String> mockRoom(String token, Studio studio) {
Map<String, String> map = new HashMap<>();
// 背景图
map.put("coverImg", wechatMediaUtil.uploadMedia(token, "image", studio.getCoverImg()));
// 分享图
map.put("shareImg", wechatMediaUtil.uploadMedia(token, "image", studio.getShareImg()));
// 购物直播频道封面图
map.put("feedsImg", wechatMediaUtil.uploadMedia(token, "image", studio.getFeedsImg()));
// 直播间名字
map.put("name", studio.getName());
// 直播计划开始时间
map.put("startTime", studio.getStartTime());
// 直播计划结束时间
map.put("endTime", studio.getEndTime());
// 主播昵称
map.put("anchorName", studio.getAnchorName());
// 主播微信号
map.put("anchorWechat", studio.getAnchorWechat());
// 直播间类型
map.put("type", "0");
// 是否关闭点赞
map.put("closeLike", "0");
// 是否关闭货架
map.put("closeGoods", "0");
// 是否关闭评论
map.put("closeComment", "0");
// 直播间名字
map.put("closeReplay", "0");
return map;
}
}

View File

@ -0,0 +1,123 @@
package cn.lili.modules.broadcast.util;
import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
/**
* 微信媒体工具
*
* @author Bulbasaur
* @date: 2021/5/19 8:02 下午
*/
@Slf4j
@Component
public class WechatMediaUtil {
/**
* 上传多媒体数据到微信服务器
* @param accessToken 从微信获取到的access_token
* @param mediaFileUrl 来自网络上面的媒体文件地址
* @return
*/
public String uploadMedia(String accessToken, String type, String mediaFileUrl) {
/*
* 上传媒体文件到微信服务器需要请求的地址
*/
String MEDIA_URL = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
StringBuffer resultStr = null;
//拼装url地址
String mediaStr = MEDIA_URL.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type);
URL mediaUrl;
try {
String boundary = "----WebKitFormBoundaryOYXo8heIv9pgpGjT";
URL url = new URL(mediaStr);
HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
//让输入输出流开启
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
//使用post方式请求的时候必须关闭缓存
urlConn.setUseCaches(false);
//设置请求头的Content-Type属性
urlConn.setRequestProperty("Content-Type", "multipart/form-data; boundary="+boundary);
urlConn.setRequestMethod("POST");
//获取输出流使用输出流拼接请求体
OutputStream out = urlConn.getOutputStream();
//读取文件的数据,构建一个GET请求然后读取指定地址中的数据
mediaUrl = new URL(mediaFileUrl);
HttpURLConnection mediaConn = (HttpURLConnection)mediaUrl.openConnection();
//设置请求方式
mediaConn.setRequestMethod("GET");
//设置可以打开输入流
mediaConn.setDoInput(true);
//获取传输的数据类型
String contentType = mediaConn.getHeaderField("Content-Type");
//将获取大到的类型转换成扩展名
String fileExt = judgeType(contentType);
//获取输入流从mediaURL里面读取数据
InputStream in = mediaConn.getInputStream();
BufferedInputStream bufferedIn = new BufferedInputStream(in);
//数据读取到这个数组里面
byte[] bytes = new byte[1024];
int size = 0;
//使用outputStream流输出信息到请求体当中去
out.write(("--"+boundary+"\r\n").getBytes());
out.write(("Content-Disposition: form-data; name=\"media\";\r\n"
+ "filename=\""+(new Date().getTime())+fileExt+"\"\r\n"
+ "Content-Type: "+contentType+"\r\n\r\n").getBytes());
while( (size = bufferedIn.read(bytes)) != -1) {
out.write(bytes, 0, size);
}
//切记这里的换行符不能少否则将会报41005错误
out.write(("\r\n--"+boundary+"--\r\n").getBytes());
bufferedIn.close();
in.close();
mediaConn.disconnect();
InputStream resultIn = urlConn.getInputStream();
InputStreamReader reader = new InputStreamReader(resultIn);
BufferedReader bufferedReader = new BufferedReader(reader);
String tempStr = null;
resultStr = new StringBuffer();
while((tempStr = bufferedReader.readLine()) != null) {
resultStr.append(tempStr);
}
bufferedReader.close();
reader.close();
resultIn.close();
urlConn.disconnect();
} catch (Exception e) {
log.error("微信媒体上传失败",e);
}
JSONObject jsonObject=new JSONObject(resultStr.toString());
return jsonObject.get("media_id").toString();
}
/**
* 通过传过来的contentType判断是哪一种类型
* @param contentType 获取来自连接的contentType
* @return
*/
public String judgeType(String contentType) {
String fileExt = "";
switch (contentType){
case "image/png":
fileExt = ".png";
break;
case "image/jpeg":
fileExt = ".jpeg";
break;
case "image/jpg":
fileExt = ".jpg";
break;
}
return fileExt;
}
}

View File

@ -7,8 +7,6 @@ import cn.lili.modules.connect.mapper.ConnectConfigMapper;
import cn.lili.modules.connect.service.ConnectConfigService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -23,8 +21,6 @@ import java.util.List;
@Service
@Transactional(rollbackFor = Exception.class)
public class ConnectConfigServiceImpl extends ServiceImpl<ConnectConfigMapper, ConnectConfig> implements ConnectConfigService {
@Autowired
private ConnectConfigMapper connectConfigMapper;
@Override
public List<ConnectConfigForm> listForms() {

View File

@ -339,7 +339,7 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
return JSONUtil.parseObj(result);
}
} catch (Exception e) {
e.printStackTrace();
log.error("解密,获取微信信息错误",e);
}
throw new ServiceException(ResultCode.USER_CONNECT_ERROR);
}

View File

@ -29,6 +29,7 @@ import cn.lili.modules.system.entity.dto.connect.dto.QQConnectSettingItem;
import cn.lili.modules.system.entity.dto.connect.dto.WechatConnectSettingItem;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -45,6 +46,7 @@ import java.util.regex.Pattern;
* @version v1.0
* 2020-11-25 21:16
*/
@Slf4j
@Component
public class ConnectUtil {
@ -106,7 +108,7 @@ public class ConnectUtil {
try {
httpServletResponse.sendRedirect(url);
} catch (Exception e) {
e.printStackTrace();
log.error("登录回调错误",e);
}
}

View File

@ -1,5 +1,7 @@
package cn.lili.modules.connect.util;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
@ -11,6 +13,7 @@ import java.net.UnknownHostException;
* @version v1.0
* 2020-12-08 15:32
*/
@Slf4j
public class IpUtils {
/**
@ -22,7 +25,7 @@ public class IpUtils {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
log.error("获取本机IP错误",e);
return null;
}
}

View File

@ -3,7 +3,7 @@ package cn.lili.modules.distribution.mapper;
import cn.hutool.core.date.DateTime;
import cn.lili.modules.distribution.entity.dos.DistributionOrder;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
/**
* 分销订单数据处理层
@ -16,9 +16,8 @@ public interface DistributionOrderMapper extends BaseMapper<DistributionOrder> {
/**
* 分销提佣
*/
@Select("UPDATE li_distribution AS d " +
"SET d.can_rebate =(d.can_rebate +(SELECT SUM( dorder.rebate ) FROM li_distribution_order AS dorder WHERE dorder.distribution_id = d.id AND " +
"dorder.distribution_order_status=#{distributionOrderStatus} AND dorder.settle_cycle< #{settleCycle} ))")
@Update("UPDATE li_distribution AS d " +
"SET d.can_rebate =(d.can_rebate +(SELECT SUM( dorder.rebate ) FROM li_distribution_order AS dorder WHERE dorder.distribution_id = d.id AND dorder.distribution_order_status=#{distributionOrderStatus} AND dorder.settle_cycle< #{settleCycle} ))")
void rebate(String distributionOrderStatus, DateTime settleCycle);
}

View File

@ -34,9 +34,6 @@ import org.springframework.transaction.annotation.Transactional;
@Transactional
public class DistributionGoodsServiceImpl extends ServiceImpl<DistributionGoodsMapper, DistributionGoods> implements DistributionGoodsService {
//分销商品
@Autowired
private DistributionGoodsMapper distributionGoodsMapper;
//分销员
@Autowired
private DistributionService distributionService;
@ -48,22 +45,22 @@ public class DistributionGoodsServiceImpl extends ServiceImpl<DistributionGoodsM
public IPage<DistributionGoodsVO> goodsPage(DistributionGoodsSearchParams searchParams) {
//获取商家的分销商品列表
if (UserContext.getCurrentUser().getRole().equals(UserEnums.STORE)) {
return distributionGoodsMapper.getDistributionGoodsVO(PageUtil.initPage(searchParams), searchParams.storeQueryWrapper());
return this.baseMapper.getDistributionGoodsVO(PageUtil.initPage(searchParams), searchParams.storeQueryWrapper());
} else if (UserContext.getCurrentUser().getRole().equals(UserEnums.MEMBER)) {
//判断当前登录用户是否为分销员
Distribution distribution = distributionService.getDistribution();
if (distribution != null) {
//判断查看已选择的分销商品列表
if (searchParams.isChecked()) {
return distributionGoodsMapper.selectGoods(PageUtil.initPage(searchParams), searchParams.distributionQueryWrapper(), distribution.getId());
return this.baseMapper.selectGoods(PageUtil.initPage(searchParams), searchParams.distributionQueryWrapper(), distribution.getId());
} else {
return distributionGoodsMapper.notSelectGoods(PageUtil.initPage(searchParams), searchParams.distributionQueryWrapper(), distribution.getId());
return this.baseMapper.notSelectGoods(PageUtil.initPage(searchParams), searchParams.distributionQueryWrapper(), distribution.getId());
}
}
throw new ServiceException(ResultCode.DISTRIBUTION_NOT_EXIST);
}
//如果是平台则直接进行查询
return distributionGoodsMapper.getDistributionGoodsVO(PageUtil.initPage(searchParams), searchParams.distributionQueryWrapper());
return this.baseMapper.getDistributionGoodsVO(PageUtil.initPage(searchParams), searchParams.distributionQueryWrapper());
}
@Override

View File

@ -11,6 +11,7 @@ import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Date;
@ -35,18 +36,23 @@ public class Category extends BaseEntity {
@ApiModelProperty(value = "分类名称")
private String name;
@NotEmpty(message = "请选择父分类")
@ApiModelProperty(value = "父id, 根节点为0")
private String parentId;
@NotNull(message = "层级不能为空")
@ApiModelProperty(value = "层级, 从0开始")
private Integer level;
@NotNull(message = "排序值不能为空")
@ApiModelProperty(value = "排序值")
private BigDecimal sortOrder;
@NotNull(message = "请填写佣金比例")
@ApiModelProperty(value = "佣金比例")
private Double commissionRate;
@NotEmpty(message = "分类图标不能为空")
@ApiModelProperty(value = "分类图标")
private String image;

View File

@ -112,9 +112,6 @@ public class DraftGoods extends BaseEntity {
@ApiModelProperty(value = "运费模板id")
private String templateId;
@ApiModelProperty(value = "运费承担者")
private String freightPayer;
@ApiModelProperty(value = "是否自营")
private Boolean selfOperated;
/**
@ -154,4 +151,10 @@ public class DraftGoods extends BaseEntity {
@ApiModelProperty(value = "sku列表JSON")
private String skuListJson;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsTypeEnum
*/
@ApiModelProperty(value = "商品类型", required = true)
private String goodsType;
}

View File

@ -145,11 +145,6 @@ public class Goods extends BaseEntity {
*/
@ApiModelProperty(value = "运费模板id")
private String templateId;
/**
* 谁承担运费 BUYER买家承担STORE卖家承担
*/
@ApiModelProperty(value = " 谁承担运费 BUYER买家承担STORE卖家承担")
private String freightPayer;
/**
* 审核状态
*
@ -190,11 +185,19 @@ public class Goods extends BaseEntity {
@ApiModelProperty(value = "销售模式", required = true)
private String salesModel;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsTypeEnum
*/
@ApiModelProperty(value = "商品类型", required = true)
private String goodsType;
@ApiModelProperty(value = "商品参数json", hidden = true)
@Column(columnDefinition = "TEXT")
@JsonIgnore
private String params;
public Goods() {
}
@ -206,7 +209,6 @@ public class Goods extends BaseEntity {
this.sn = goodsOperationDTO.getSn();
this.price = goodsOperationDTO.getPrice();
this.weight = goodsOperationDTO.getWeight();
this.freightPayer = goodsOperationDTO.getFreightPayer();
this.templateId = goodsOperationDTO.getTemplateId();
this.recommend = goodsOperationDTO.isRecommend();
this.sellingPoint = goodsOperationDTO.getSellingPoint();
@ -220,6 +222,6 @@ public class Goods extends BaseEntity {
}
//如果立即上架则
this.marketEnable = goodsOperationDTO.isRelease() ? GoodsStatusEnum.UPPER.name() : GoodsStatusEnum.DOWN.name();
this.goodsType=goodsOperationDTO.getGoodsType();
}
}

View File

@ -131,8 +131,6 @@ public class GoodsSku extends BaseEntity {
@ApiModelProperty(value = "运费模板id")
private String templateId;
@ApiModelProperty(value = " 谁承担运费 BUYER买家承担STORE卖家承担")
private String freightPayer;
/**
* @see GoodsAuthEnum
*/
@ -160,6 +158,11 @@ public class GoodsSku extends BaseEntity {
@ApiModelProperty(value = "销售模式", required = true)
private String salesModel;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsTypeEnum
*/
@ApiModelProperty(value = "商品类型", required = true)
private String goodsType;
@Override
public Date getUpdateTime() {

View File

@ -16,7 +16,7 @@ import java.util.List;
import java.util.Map;
/**
* 商品查询条件
* 商品编辑DTO
*
* @author pikachu
* @date 2020-02-24 19:27:20
@ -66,9 +66,6 @@ public class GoodsOperationDTO implements Serializable {
@Max(value = 99999999, message = "重量不能超过99999999")
private Double weight;
@ApiModelProperty(value = "谁承担运费 BUYER买家承担STORE卖家承担", required = true)
private String freightPayer;
@ApiModelProperty(value = "详情")
private String intro;
@ -118,4 +115,10 @@ public class GoodsOperationDTO implements Serializable {
@ApiModelProperty(value = "是否重新生成sku数据")
private Boolean regeneratorSkuFlag = true;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsTypeEnum
*/
@ApiModelProperty(value = "商品类型")
private String goodsType;
}

View File

@ -67,6 +67,12 @@ public class GoodsSearchParams extends PageVO {
@ApiModelProperty(value = "是否为推荐商品")
private Boolean recommend;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsTypeEnum
*/
@ApiModelProperty(value = "商品类型")
private String goodsType;
public <T> QueryWrapper<T> queryWrapper() {
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
if (StringUtils.isNotEmpty(goodsId)) {
@ -108,6 +114,10 @@ public class GoodsSearchParams extends PageVO {
if (recommend != null) {
queryWrapper.le("recommend", recommend);
}
if (goodsType != null) {
queryWrapper.eq("goods_type", goodsType);
}
queryWrapper.eq("delete_flag", false);
this.betweenWrapper(queryWrapper);
return queryWrapper;

View File

@ -1,28 +0,0 @@
package cn.lili.modules.goods.entity.enums;
/**
* 商品运费承担者
*
* @author pikachu
* @date 2020-02-26 23:24:13
*/
public enum GoodsFreightEnum {
/**
* 买家承担运费
*/
BUYER("买家承担运费"),
/**
* 卖家承担运费
*/
STORE("卖家承担运费");
private final String description;
GoodsFreightEnum(String description) {
this.description = description;
}
public String description() {
return description;
}
}

View File

@ -0,0 +1,29 @@
package cn.lili.modules.goods.entity.enums;
/**
* 商品类型
*
* @author Bulbasaur
* @date: 2021/5/28 4:23 下午
*/
public enum GoodsTypeEnum {
PHYSICAL_GOODS("实物商品"),
VIRTUAL_GOODS("虚拟商品"),
E_COUPON("电子卡券");
private final String description;
GoodsTypeEnum(String description) {
this.description = description;
}
public String description() {
return description;
}
}

View File

@ -109,11 +109,10 @@ public interface GoodsService extends IService<Goods> {
* 设置商品运费模板
*
* @param goodsIds 商品列表
* @param freightPayer 承担运费者
* @param templateId 运费模板ID
* @return 操作结果
*/
Boolean freight(List<String> goodsIds, String freightPayer, String templateId);
Boolean freight(List<String> goodsIds, String templateId);
/**
* 修改商品库存数量

View File

@ -24,18 +24,14 @@ import java.util.List;
@Transactional
public class CategoryBrandServiceImpl extends ServiceImpl<CategoryBrandMapper, CategoryBrand> implements CategoryBrandService {
//分类品牌绑定
@Autowired
private CategoryBrandMapper categoryBrandMapper;
@Override
public List<CategoryBrandVO> getCategoryBrandList(String categoryId) {
return categoryBrandMapper.getCategoryBrandList(categoryId);
return this.baseMapper.getCategoryBrandList(categoryId);
}
@Override
public void deleteByCategoryId(String categoryId) {
categoryBrandMapper.delete(new LambdaUpdateWrapper<CategoryBrand>().eq(CategoryBrand::getCategoryId, categoryId));
this.baseMapper.delete(new LambdaUpdateWrapper<CategoryBrand>().eq(CategoryBrand::getCategoryId, categoryId));
}
@Override

View File

@ -17,7 +17,6 @@ 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 lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -40,9 +39,6 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
//缓存
@Autowired
private Cache cache;
//分类
@Autowired
private CategoryMapper categoryMapper;
@Override
public List<Category> dbList(String parentId) {
@ -159,7 +155,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
.ne(category.getId() != null, "id", category.getId())
.eq(DELETE_FLAG_COLUMN, false)
.orderByAsc("sort_order");
return this.categoryMapper.selectList(queryWrapper);
return this.baseMapper.selectList(queryWrapper);
}
@Override
@ -188,7 +184,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
.set("sort_order", category.getSortOrder())
.set(DELETE_FLAG_COLUMN, category.getDeleteFlag())
.set("commission_rate", category.getCommissionRate());
categoryMapper.update(category, updateWrapper);
this.baseMapper.update(category, updateWrapper);
removeCache();
}

View File

@ -23,12 +23,10 @@ import java.util.List;
@Service
@Transactional
public class CategorySpecificationServiceImpl extends ServiceImpl<CategorySpecificationMapper, CategorySpecification> implements CategorySpecificationService {
@Autowired
private CategorySpecificationMapper categorySpecificationMapper;
@Override
public List<CategorySpecificationVO> getCategorySpecList(String categoryId) {
return categorySpecificationMapper.getCategorySpecList(categoryId);
return this.baseMapper.getCategorySpecList(categoryId);
}
@Override
@ -38,6 +36,6 @@ public class CategorySpecificationServiceImpl extends ServiceImpl<CategorySpecif
@Override
public void deleteByCategoryId(String categoryId) {
categorySpecificationMapper.delete(new LambdaQueryWrapper<CategorySpecification>().eq(CategorySpecification::getCategoryId,categoryId));
this.baseMapper.delete(new LambdaQueryWrapper<CategorySpecification>().eq(CategorySpecification::getCategoryId,categoryId));
}
}

View File

@ -16,7 +16,6 @@ import cn.lili.modules.goods.service.GoodsGalleryService;
import cn.lili.modules.goods.service.GoodsSkuService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -70,7 +69,7 @@ public class DraftGoodsServiceImpl extends ServiceImpl<DraftGoodsMapper, DraftGo
draftGoods.setGoodsGalleryListJson(JSONUtil.toJsonStr(draftGoods.getGoodsGalleryList()));
draftGoods.setSkuListJson(JSONUtil.toJsonStr(this.getGoodsSkuList(draftGoods.getSkuList())));
draftGoods.setGoodsParamsListJson(JSONUtil.toJsonStr(draftGoods.getGoodsParamsList()));
this.saveOrUpdate(draftGoods);
this.save(draftGoods);
}
@Override

View File

@ -32,9 +32,7 @@ public class GoodsGalleryServiceImpl extends ServiceImpl<GoodsGalleryMapper, Goo
//文件
@Autowired
private FileManagerPlugin fileManagerPlugin;
//商品相册数据层
@Autowired
private GoodsGalleryMapper goodsGalleryMapper;
//设置
@Autowired
private SettingService settingService;
@ -43,7 +41,7 @@ public class GoodsGalleryServiceImpl extends ServiceImpl<GoodsGalleryMapper, Goo
@Override
public void add(List<String> goodsGalleryList, String goodsId) {
//删除原来商品相册信息
this.goodsGalleryMapper.delete(new UpdateWrapper<GoodsGallery>().eq("goods_id", goodsId));
this.baseMapper.delete(new UpdateWrapper<GoodsGallery>().eq("goods_id", goodsId));
//确定好图片选择器后进行处理
int i = 0;
for (String origin : goodsGalleryList) {
@ -53,7 +51,7 @@ public class GoodsGalleryServiceImpl extends ServiceImpl<GoodsGalleryMapper, Goo
// 默认第一个为默认图片
galley.setIsDefault(i == 0 ? 1 : 0);
i++;
this.goodsGalleryMapper.insert(galley);
this.baseMapper.insert(galley);
}
}
@ -77,6 +75,6 @@ public class GoodsGalleryServiceImpl extends ServiceImpl<GoodsGalleryMapper, Goo
@Override
public List<GoodsGallery> goodsGalleryList(String goodsId) {
//根据商品id查询商品相册
return goodsGalleryMapper.selectList(new QueryWrapper<GoodsGallery>().eq("goods_id", goodsId));
return this.baseMapper.selectList(new QueryWrapper<GoodsGallery>().eq("goods_id", goodsId));
}
}

View File

@ -102,41 +102,19 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
@Override
public void addGoods(GoodsOperationDTO goodsOperationDTO) {
Goods goods = new Goods(goodsOperationDTO);
//判定商品是否需要审核
this.checkNeedAuth(goods);
//检查商品
this.checkGoods(goods);
// 向goods加入图片
this.setGoodsGalleryParam(goodsOperationDTO.getGoodsGalleryList().get(0), goods);
//商品添加卖家信息
StoreVO storeDetail = this.storeService.getStoreDetail();
goods.setStoreId(storeDetail.getId());
goods.setStoreName(storeDetail.getStoreName());
if (storeDetail.getSelfOperated() != null) {
goods.setSelfOperated(storeDetail.getSelfOperated());
}
// 评论次数
goods.setCommentNum(0);
// 购买次数
goods.setBuyCount(0);
// 购买次数
goods.setQuantity(0);
// 商品评分
goods.setGrade(100.0);
//添加商品
this.save(goods);
// 添加商品参数
if (goodsOperationDTO.getGoodsParamsList() != null && !goodsOperationDTO.getGoodsParamsList().isEmpty()) {
this.goodsParamsService.addParams(goodsOperationDTO.getGoodsParamsList(), goods.getId());
}
// 添加商品sku信息
this.goodsSkuService.add(goodsOperationDTO.getSkuList(), goods);
// 添加相册
if (goodsOperationDTO.getGoodsGalleryList() != null && !goodsOperationDTO.getGoodsGalleryList().isEmpty()) {
this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId());
@ -146,35 +124,25 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
@Override
public void editGoods(GoodsOperationDTO goodsOperationDTO, String goodsId) {
this.checkExist(goodsId);
Goods goods = new Goods(goodsOperationDTO);
goods.setId(goodsId);
//是否需要审核
this.checkNeedAuth(goods);
//检查商品信息
this.checkGoods(goods);
// 向goods加入图片
this.setGoodsGalleryParam(goodsOperationDTO.getGoodsGalleryList().get(0), goods);
//商品添加卖家信息
StoreVO storeDetail = this.storeService.getStoreDetail();
if (storeDetail.getSelfOperated() != null) {
goods.setSelfOperated(storeDetail.getSelfOperated());
}
goods.setStoreId(storeDetail.getId());
goods.setStoreName(storeDetail.getStoreName());
//修改商品
this.updateById(goods);
// 添加商品参数
this.goodsParamsService.addParams(goodsOperationDTO.getGoodsParamsList(), goods.getId());
//修改商品规格
if (goodsOperationDTO.getGoodsParamsList() != null && !goodsOperationDTO.getGoodsParamsList().isEmpty()) {
this.goodsParamsService.addParams(goodsOperationDTO.getGoodsParamsList(), goods.getId());
}
//修改商品sku信息
this.goodsSkuService.update(goodsOperationDTO.getSkuList(), goods, goodsOperationDTO.getRegeneratorSkuFlag());
// 添加相册
this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId());
if (goodsOperationDTO.getGoodsGalleryList() != null && !goodsOperationDTO.getGoodsGalleryList().isEmpty()) {
this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId());
}
}
@Override
@ -305,9 +273,8 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
}
@Override
public Boolean freight(List<String> goodsIds, String freightPayer, String templateId) {
public Boolean freight(List<String> goodsIds, String templateId) {
LambdaUpdateWrapper<Goods> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.set(Goods::getFreightPayer, freightPayer);
lambdaUpdateWrapper.set(Goods::getTemplateId, templateId);
lambdaUpdateWrapper.in(Goods::getId, goodsIds);
return this.update(lambdaUpdateWrapper);
@ -355,16 +322,62 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
}
/**
* 商品是否需要审核
* 检查商品信息
* 如果商品是虚拟商品则无需配置配送模板
* 如果商品是实物商品需要配置配送模板
* 判断商品是否存在
* 判断商品是否需要审核
* 判断当前用户是否为店铺
*
* @param goods 商品
*/
private void checkNeedAuth(Goods goods) {
private void checkGoods(Goods goods) {
//判断商品类型
switch (goods.getGoodsType()) {
case "PHYSICAL_GOODS":
if (goods.getTemplateId().equals("0")) {
throw new ServiceException("实物商品需选择配送模板");
}
break;
case "VIRTUAL_GOODS":
if (!goods.getTemplateId().equals("0")) {
throw new ServiceException("虚拟商品不需要选择配送模板");
}
break;
default:
throw new ServiceException("需选择商品类型");
}
//检查商品是否存在--修改商品时使用
if (goods.getId() != null) {
this.checkExist(goods.getId());
} else {
// 评论次数
goods.setCommentNum(0);
// 购买次数
goods.setBuyCount(0);
// 购买次数
goods.setQuantity(0);
// 商品评分
goods.setGrade(100.0);
}
//获取商品系统配置决定是否审核
Setting setting = settingService.get(SettingEnum.GOODS_SETTING.name());
GoodsSetting goodsSetting = JSONUtil.toBean(setting.getSettingValue(), GoodsSetting.class);
//是否需要审核
goods.setIsAuth(Boolean.TRUE.equals(goodsSetting.getGoodsCheck()) ? GoodsAuthEnum.TOBEAUDITED.name() : GoodsAuthEnum.PASS.name());
//判断当前用户是否为店铺
if (UserContext.getCurrentUser().getRole().equals(UserEnums.STORE)) {
StoreVO storeDetail = this.storeService.getStoreDetail();
if (storeDetail.getSelfOperated() != null) {
goods.setSelfOperated(storeDetail.getSelfOperated());
}
goods.setStoreId(storeDetail.getId());
goods.setStoreName(storeDetail.getStoreName());
goods.setSelfOperated(storeDetail.getSelfOperated());
} else {
throw new ServiceException("当前未登录店铺");
}
}
/**

View File

@ -510,6 +510,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
if (goods.getSelfOperated() != null) {
goodsSku.setSelfOperated(goods.getSelfOperated());
}
goodsSku.setGoodsType(goods.getGoodsType());
EsGoodsIndex goodsIndex = (EsGoodsIndex) resultMap.get("goodsIndex");
skus.add(goodsSku);
goodsIndices.add(goodsIndex);
@ -566,8 +567,6 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
sku.setIntro(goods.getIntro());
sku.setMobileIntro(goods.getMobileIntro());
sku.setGoodsUnit(goods.getGoodsUnit());
//运费
sku.setFreightPayer(goods.getFreightPayer());
//商品状态
sku.setIsAuth(goods.getIsAuth());
sku.setSalesModel(goods.getSalesModel());
@ -594,6 +593,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
StringBuilder goodsName = new StringBuilder(goods.getGoodsName());
//规格商品缩略图
String thumbnail = "";
String small = "";
//规格值
Map<String, Object> specMap = new HashMap<>();
//商品属性
@ -613,6 +613,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
throw new ServiceException("sku图片至少为一个");
}
thumbnail = goodsGalleryService.getGoodsGallery(images.get(0).get("url")).getThumbnail();
small = goodsGalleryService.getGoodsGallery(images.get(0).get("url")).getSmall();
} else {
//设置商品名称
goodsName.append(" ").append(m.getValue());
@ -637,6 +638,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
//设置规格信息
sku.setGoodsName(goodsName.toString());
sku.setThumbnail(thumbnail);
sku.setSmall(small);
//规格信息
sku.setId(Convert.toStr(map.get("id"), ""));

View File

@ -5,6 +5,7 @@ import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberPointsHistory;
import cn.lili.modules.member.service.MemberPointsHistoryService;
import cn.lili.modules.member.service.MemberService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
@ -17,6 +18,7 @@ import org.springframework.stereotype.Component;
* @author Chopper
* @date 2020/11/17 7:22 下午
*/
@Slf4j
@Aspect
@Component
public class PointLogInterceptor {
@ -62,7 +64,7 @@ public class PointLogInterceptor {
memberPointsHistoryService.save(memberPointsHistory);
}
} catch (Exception e) {
e.printStackTrace();
log.error("积分操作错误",e);
}

View File

@ -85,6 +85,14 @@ public class Member extends BaseEntity {
@ApiModelProperty(value = "最后一次登录时间")
private Date lastLoginDate;
@ApiModelProperty(value = "会员等级ID")
private String gradeId;
@Min(message = "必须为数字", value = 0)
@ApiModelProperty(value = "经验值数量")
private Long experience;
public Member(String username, String password, String mobile) {
this.username = username;
this.password = password;

View File

@ -0,0 +1,40 @@
package cn.lili.modules.member.entity.dos;
import cn.lili.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
/**
* 会员等级
*
* @author Bulbasaur
* @date 2021/5/14 5:43 下午
*/
@Data
@Entity
@Table(name = "li_member_grade")
@TableName("li_member_grade")
@ApiModel(value = "会员等级")
public class MemberGrade extends BaseEntity {
@NotNull
@ApiModelProperty(value = "等级名称")
private String gradeName;
@NotNull
@ApiModelProperty(value = "等级图片")
private String gradeImage;
@NotNull
@ApiModelProperty(value = "所需经验值")
private Integer experienceValue;
@ApiModelProperty(value = "是否为默认等级")
private Boolean isDefault;
}

View File

@ -15,8 +15,8 @@ public class MemberPointMessage {
@ApiModelProperty(value = "积分")
private Long point;
@ApiModelProperty(value = "类型 1为增加")
private Integer type;
@ApiModelProperty(value = "是否增加积分")
private Boolean type;
@ApiModelProperty(value = "会员id")
private String memberId;

Some files were not shown because too many files have changed in this diff Show More