Merge branch 'master' into qiuqiu
This commit is contained in:
commit
701ea240ab
71
README.md
71
README.md
@ -26,7 +26,7 @@ Lilishop 是一款Java开发,基于SpringBoot研发的B2B2C多用户商城,
|
||||
### 文档
|
||||
|
||||
**产品文档**(需求、架构、使用、部署、开发):https://docs.pickmall.cn
|
||||
|
||||
**功能清单** 功能列表:https://docs.qq.com/sheet/DQ1Z2dWJKUnBRZEt5
|
||||
|
||||
### 项目链接(gitee)
|
||||
|
||||
@ -194,42 +194,23 @@ PS:单独部署的话,数据库文件访问这里:https://gitee.com/beijing_
|
||||
|
||||
#### 计划每个月发布一个版本,具体时间可能有出入
|
||||
|
||||
时间:2021年6月15日
|
||||
|
||||
```
|
||||
新增功能:
|
||||
1.微信小程序直播
|
||||
2.优惠券活动
|
||||
3.新人赠券
|
||||
4.准确发券
|
||||
5.用户等级
|
||||
6.数据导出
|
||||
7.订单批量
|
||||
8.APP版本升级检测
|
||||
9.积分商城
|
||||
|
||||
功能优化:
|
||||
1.优惠券有效期增加类型:设置领取后*内有效。
|
||||
2.秒杀活动设置为每天开启,需设置秒杀活动开启时间。
|
||||
3.店铺配送模板,配送地区如果选择省份则下方的市级地址不展示。
|
||||
4.店铺配送模板支持,店铺包邮。
|
||||
5.普通商品设置去除卖家承担运费。
|
||||
|
||||
```
|
||||
|
||||
时间:2021年7月15日
|
||||
|
||||
```
|
||||
新增功能:
|
||||
1.会员权益
|
||||
2.支持用户升级会员
|
||||
3.供求单
|
||||
4.IM:腾讯云智服
|
||||
5.服务商品
|
||||
6.店铺支持订单核销
|
||||
7.店铺自提点
|
||||
1.积分商城
|
||||
2.店铺移动端
|
||||
3.店铺支持发货单
|
||||
4.供求单
|
||||
5.店铺自提点
|
||||
6.移动端展示附近店铺
|
||||
7.开屏广告
|
||||
8.会员站内消息
|
||||
9.移动端店铺入驻
|
||||
功能优化:
|
||||
1.用户分享商城、关注店铺、邀请新用户可获取积分、经验值。
|
||||
2.隐私管理功能
|
||||
2.移动端店铺首页优化
|
||||
```
|
||||
|
||||
时间:2021年8月16日
|
||||
@ -237,15 +218,37 @@ PS:单独部署的话,数据库文件访问这里:https://gitee.com/beijing_
|
||||
```
|
||||
新增功能:
|
||||
1.微淘功能
|
||||
2.店铺移动端
|
||||
3.店铺发货单
|
||||
2.相册管理功能
|
||||
3.店铺申请品牌
|
||||
4.第三方商品导入(淘宝、99api)
|
||||
5.用户等级
|
||||
6.用户升级会员
|
||||
7.会员权益
|
||||
8.促销活动:第二件*折
|
||||
9.促销活动:商品打包价
|
||||
10.促销活动:商品组合购
|
||||
11.促销活动:进店赠券
|
||||
12.代客退单
|
||||
功能优化:
|
||||
1.批量上传商品分类
|
||||
2.店铺维护开票项目
|
||||
3.店铺展示营销中心
|
||||
```
|
||||
|
||||
时间:2021年9月15日
|
||||
|
||||
```
|
||||
新增功能:
|
||||
增加供应商功能
|
||||
1.增加供应商功能
|
||||
2.商品预售
|
||||
3.商品预约
|
||||
4.电子券码
|
||||
5.企业会员
|
||||
6.企业会员购
|
||||
7.商品批发价
|
||||
功能优化:
|
||||
1.店铺运费模板支持按照体积计算
|
||||
2.店铺支持自定义移动端首页
|
||||
```
|
||||
|
||||
### 版本升级
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package cn.lili.controller.goods;
|
||||
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.enums.ResultUtil;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.vo.PageVO;
|
||||
import cn.lili.common.vo.ResultMessage;
|
||||
import cn.lili.modules.distribution.service.DistributionService;
|
||||
@ -20,6 +22,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.data.domain.Page;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -37,6 +40,7 @@ import java.util.Map;
|
||||
* @author Chopper
|
||||
* @date 2020/11/16 10:06 下午
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "买家端,商品接口")
|
||||
@RestController
|
||||
@RequestMapping("/buyer/goods")
|
||||
@ -80,12 +84,18 @@ public class GoodsBuyerController {
|
||||
@PageViewPoint(type = PageViewEnum.SKU, id = "#id")
|
||||
public ResultMessage<Map<String, Object>> getSku(@NotNull(message = "商品ID不能为空") @PathVariable("goodsId") String goodsId,
|
||||
@NotNull(message = "SKU ID不能为空") @PathVariable("skuId") String skuId) {
|
||||
|
||||
try {
|
||||
// 读取选中的列表
|
||||
Map<String, Object> map = goodsSkuService.getGoodsSkuDetail(goodsId, skuId);
|
||||
|
||||
|
||||
|
||||
return ResultUtil.data(map);
|
||||
} catch (ServiceException se) {
|
||||
log.info(se.getMsg(), se);
|
||||
throw se;
|
||||
} catch (Exception e) {
|
||||
log.error(ResultCode.GOODS_ERROR.message(), e);
|
||||
return ResultUtil.error(ResultCode.GOODS_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取商品分页列表")
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package cn.lili.controller.payment;
|
||||
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.enums.ResultUtil;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.vo.ResultMessage;
|
||||
import cn.lili.modules.payment.kit.CashierSupport;
|
||||
import cn.lili.modules.payment.kit.dto.PayParam;
|
||||
@ -12,6 +13,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 +27,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
* @author Chopper
|
||||
* @date 2020-12-18 16:59
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@Api(tags = "买家端,收银台接口")
|
||||
@RequestMapping("/buyer/cashier")
|
||||
@ -62,8 +65,11 @@ public class CashierController {
|
||||
|
||||
try {
|
||||
return cashierSupport.payment(paymentMethodEnum, paymentClientEnum, request, response, payParam);
|
||||
} catch (ServiceException se) {
|
||||
log.info("支付异常", se);
|
||||
throw se;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("收银台支付错误", e);
|
||||
}
|
||||
return null;
|
||||
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -50,8 +50,17 @@ public class CartController {
|
||||
public ResultMessage<Object> add(@NotNull(message = "产品id不能为空") String skuId,
|
||||
@NotNull(message = "购买数量不能为空") @Min(value = 1, message = "加入购物车数量必须大于0") Integer num,
|
||||
String cartType) {
|
||||
try {
|
||||
//读取选中的列表
|
||||
cartService.add(skuId, num, cartType);
|
||||
return ResultUtil.success();
|
||||
} catch (ServiceException se) {
|
||||
log.info(se.getMsg(), se);
|
||||
throw se;
|
||||
} catch (Exception e) {
|
||||
log.error(ResultCode.CART_ERROR.message(), e);
|
||||
throw new ServiceException(ResultCode.CART_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -150,8 +159,9 @@ public class CartController {
|
||||
try {
|
||||
//读取选中的列表
|
||||
return ResultUtil.data(this.cartService.getCheckedTradeDTO(CartTypeEnum.valueOf(way)));
|
||||
} catch (ServiceException e) {
|
||||
throw e;
|
||||
} catch (ServiceException se) {
|
||||
log.error(se.getMsg(), se);
|
||||
throw se;
|
||||
} catch (Exception e) {
|
||||
log.error(ResultCode.CART_ERROR.message(), e);
|
||||
throw new ServiceException(ResultCode.CART_ERROR);
|
||||
@ -193,6 +203,9 @@ public class CartController {
|
||||
try {
|
||||
cartService.shippingMethod(selleId, shippingMethod, way);
|
||||
return ResultUtil.success();
|
||||
} catch (ServiceException se) {
|
||||
log.error(se.getMsg(), se);
|
||||
throw se;
|
||||
} catch (Exception e) {
|
||||
log.error(ResultCode.CART_ERROR.message(), e);
|
||||
throw new ServiceException(ResultCode.CART_ERROR);
|
||||
@ -228,8 +241,9 @@ public class CartController {
|
||||
try {
|
||||
//读取选中的列表
|
||||
return ResultUtil.data(this.cartService.createTrade(tradeParams));
|
||||
} catch (ServiceException e) {
|
||||
throw e;
|
||||
} catch (ServiceException se) {
|
||||
log.info(se.getMsg(), se);
|
||||
throw se;
|
||||
} catch (Exception e) {
|
||||
log.error(ResultCode.ORDER_ERROR.message(), e);
|
||||
throw new ServiceException(ResultCode.ORDER_ERROR);
|
||||
|
||||
@ -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
|
||||
|
||||
40
buyer-api/src/main/resources/logback.xml
Normal file
40
buyer-api/src/main/resources/logback.xml
Normal 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>
|
||||
@ -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);
|
||||
|
||||
@ -2,9 +2,6 @@ server:
|
||||
servlet:
|
||||
context-path: /
|
||||
|
||||
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
|
||||
# multipart:
|
||||
# location: /Users/lifenlong/Desktop/ceshi
|
||||
tomcat:
|
||||
uri-encoding: UTF-8
|
||||
threads:
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package cn.lili.controller.common;
|
||||
|
||||
import cn.lili.common.aop.limiter.annotation.LimitPoint;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.enums.ResultUtil;
|
||||
import cn.lili.common.verification.enums.VerificationEnums;
|
||||
@ -8,6 +9,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 +19,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,8 +38,8 @@ public class SliderImageController {
|
||||
} catch (ServiceException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
log.error("获取校验接口错误", e);
|
||||
throw new ServiceException(ResultCode.VERIFICATION_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,9 +4,6 @@ server:
|
||||
servlet:
|
||||
context-path: /
|
||||
|
||||
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
|
||||
# multipart:
|
||||
# location: /Users/lifenlong/Desktop/ceshi
|
||||
tomcat:
|
||||
uri-encoding: UTF-8
|
||||
threads:
|
||||
|
||||
41
common-api/src/main/resources/logback.xml
Normal file
41
common-api/src/main/resources/logback.xml
Normal 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>
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
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.dos.OrderItem;
|
||||
import cn.lili.modules.order.order.entity.dto.OrderMessage;
|
||||
import cn.lili.modules.order.order.entity.enums.OrderComplaintStatusEnum;
|
||||
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
|
||||
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
|
||||
import cn.lili.modules.order.order.service.OrderItemService;
|
||||
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 com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
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;
|
||||
@Autowired
|
||||
private OrderItemService orderItemService;
|
||||
@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()));
|
||||
//修改虚拟订单货物可以进行售后、投诉
|
||||
orderItemService.update(new LambdaUpdateWrapper<OrderItem>().eq(OrderItem::getOrderSn, orderMessage.getOrderSn())
|
||||
.set(OrderItem::getAfterSaleStatus, OrderItemAfterSaleStatusEnum.NOT_APPLIED)
|
||||
.set(OrderItem::getCommentStatus, OrderComplaintStatusEnum.NO_APPLY));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取随机数
|
||||
* 判断当前店铺下是否使用验证码,如果已使用则重新获取
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -44,6 +44,7 @@ public class OrderMessageListener implements RocketMQListener<MessageExt> {
|
||||
case ORDER_CREATE:
|
||||
String key = new String(messageExt.getBody());
|
||||
TradeDTO tradeDTO = (TradeDTO) cache.get(key);
|
||||
boolean result = true;
|
||||
for (TradeEvent event : tradeEvent) {
|
||||
try {
|
||||
event.orderCreate(tradeDTO);
|
||||
@ -52,8 +53,14 @@ public class OrderMessageListener implements RocketMQListener<MessageExt> {
|
||||
tradeDTO.getSn(),
|
||||
event.getClass().getName(),
|
||||
e);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
//如所有步骤顺利完成
|
||||
if (Boolean.TRUE.equals(result)) {
|
||||
//清除记录信息的trade cache key
|
||||
cache.remove(key);
|
||||
}
|
||||
break;
|
||||
//订单状态变更
|
||||
case STATUS_CHANGE:
|
||||
|
||||
@ -44,7 +44,6 @@ public class BillExecute implements EveryDayExecute {
|
||||
|
||||
//获取当前时间
|
||||
DateTime endTime =DateUtil.date();
|
||||
|
||||
//批量商家结算
|
||||
for (StoreSettlementDay storeSettlementDay : storeList) {
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
|
||||
@ -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,53 +82,27 @@ 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 {
|
||||
//结束满减活动
|
||||
endFullDiscount(query);
|
||||
|
||||
//关闭拼团活动
|
||||
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);
|
||||
endPintuan(query);
|
||||
|
||||
//结束优惠券
|
||||
endCoupon(query);
|
||||
|
||||
//定时创建活动
|
||||
addSeckill();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束优惠券活动
|
||||
*
|
||||
* @param query
|
||||
*/
|
||||
private void endCoupon(Query query) {
|
||||
|
||||
try {
|
||||
//关闭优惠券活动
|
||||
List<CouponVO> couponVOS = mongoTemplate.find(query, CouponVO.class);
|
||||
@ -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<>();
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,6 +29,6 @@ public class PromotionDelayQueueListen extends AbstractDelayQueueListen {
|
||||
|
||||
@Override
|
||||
public String setDelayQueueName() {
|
||||
return DelayQueueEnums.PROMOTION_QUEUE.name();
|
||||
return DelayQueueEnums.PROMOTION.name();
|
||||
}
|
||||
}
|
||||
|
||||
41
consumer/src/main/resources/logback.xml
Normal file
41
consumer/src/main/resources/logback.xml
Normal 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>
|
||||
@ -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>
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
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;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
@ -17,10 +16,10 @@ import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 流量拦截
|
||||
*
|
||||
* @author Chopper
|
||||
*/
|
||||
@Aspect
|
||||
@ -41,46 +40,44 @@ public class LimitInterceptor {
|
||||
this.limitScript = limitScript;
|
||||
}
|
||||
|
||||
@Around("execution(public * *(..)) && @annotation(cn.lili.common.aop.limiter.annotation.LimitPoint)")
|
||||
public Object interceptor(ProceedingJoinPoint pjp) {
|
||||
MethodSignature signature = (MethodSignature) pjp.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
LimitPoint limitPointAnnotation = method.getAnnotation(LimitPoint.class);
|
||||
@Before("@annotation(limitPointAnnotation)")
|
||||
public void interceptor(LimitPoint limitPointAnnotation) {
|
||||
LimitType limitType = limitPointAnnotation.limitType();
|
||||
String name = limitPointAnnotation.name();
|
||||
String key;
|
||||
int limitPeriod = limitPointAnnotation.period();
|
||||
int limitCount = limitPointAnnotation.limit();
|
||||
switch (limitType) {
|
||||
case IP:
|
||||
key = limitPointAnnotation.key() + getIpAddress();
|
||||
break;
|
||||
case CUSTOMER:
|
||||
key = limitPointAnnotation.key();
|
||||
break;
|
||||
default:
|
||||
key = StringUtils.upperCase(method.getName());
|
||||
key = limitPointAnnotation.key() + getIpAddress();
|
||||
}
|
||||
ImmutableList<String> keys = ImmutableList.of(StringUtils.join(limitPointAnnotation.prefix(), key));
|
||||
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) {
|
||||
return pjp.proceed();
|
||||
} else {
|
||||
throw new RuntimeException("访问过于频繁,请稍后再试");
|
||||
log.info("限制请求{}, 当前请求{},缓存key{}", limitCount, count.intValue(), key);
|
||||
//如果缓存里没有值,或者他的值小于限制频率
|
||||
if (count.intValue() >= limitCount) {
|
||||
throw new ServiceException("访问过于频繁,请稍后再试");
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw new RuntimeException(e.getLocalizedMessage());
|
||||
}
|
||||
//如果从redis中执行都值判定为空,则这里跳过
|
||||
catch (NullPointerException e) {
|
||||
return;
|
||||
} catch (ServiceException e) {
|
||||
throw e;
|
||||
} 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");
|
||||
|
||||
@ -219,7 +219,7 @@ public enum CachePrefix {
|
||||
STORE_ID_FULL_DISCOUNT,
|
||||
|
||||
/**
|
||||
* 限时抢购活动缓存key前缀
|
||||
* 秒杀活动活动缓存key前缀
|
||||
*/
|
||||
STORE_ID_SECKILL,
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ public enum ResultCode {
|
||||
/**
|
||||
* 失败返回码
|
||||
*/
|
||||
ERROR(400, "失败"),
|
||||
ERROR(400, "服务器繁忙,请稍后重试"),
|
||||
|
||||
/**
|
||||
* 失败返回码
|
||||
@ -34,6 +34,7 @@ public enum ResultCode {
|
||||
*/
|
||||
|
||||
WECHAT_CONNECT_NOT_EXIST(1001, "微信联合登录未配置"),
|
||||
VERIFICATION_EXIST(1002, "验证码服务异常"),
|
||||
/**
|
||||
* 分类
|
||||
*/
|
||||
@ -50,135 +51,222 @@ public enum ResultCode {
|
||||
/**
|
||||
* 商品
|
||||
*/
|
||||
GOODS_ERROR(11001, "商品异常,请稍后重试"),
|
||||
GOODS_NOT_EXIST(11001, "商品已下架"),
|
||||
GOODS_NAME_ERROR(11002, "商品名称不正确,名称应为2-50字符"),
|
||||
GOODS_UNDER_ERROR(11003, "商品下架失败"),
|
||||
GOODS_UPPER_ERROR(11004, "商品上架失败"),
|
||||
GOODS_AUTH_ERROR(11005, "商品审核失败"),
|
||||
POINT_GOODS_ERROR(11006, "积分商品业务异常,请稍后重试"),
|
||||
GOODS_SKU_SN_ERROR(11007, "商品SKU编号不能为空"),
|
||||
GOODS_SKU_PRICE_ERROR(11008, "商品SKU价格不能小于等于0"),
|
||||
GOODS_SKU_COST_ERROR(11009, "商品SKU成本价不能小于等于0"),
|
||||
GOODS_SKU_WEIGHT_ERROR(11010, "商品重量不能为负数"),
|
||||
GOODS_SKU_QUANTITY_ERROR(11011, "商品库存数量不能为负数"),
|
||||
GOODS_SKU_QUANTITY_NOT_ENOUGH(11011, "商品库存不足"),
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
PARAMETER_SAVE_ERROR(12001, "参数添加失败"),
|
||||
|
||||
PARAMETER_UPDATE_ERROR(12002, "参数编辑失败"),
|
||||
|
||||
/**
|
||||
* 规格
|
||||
*/
|
||||
SPEC_SAVE_ERROR(13001, "规格修改失败"),
|
||||
|
||||
SPEC_UPDATE_ERROR(13002, "规格修改失败"),
|
||||
|
||||
SPEC_DELETE_ERROR(13003, "此规格已绑定分类不允许删除"),
|
||||
|
||||
/**
|
||||
* 品牌
|
||||
*/
|
||||
BRAND_SAVE_ERROR(14001, "品牌添加失败"),
|
||||
|
||||
BRAND_UPDATE_ERROR(14002, "品牌修改失败"),
|
||||
|
||||
BRAND_DISABLE_ERROR(14003, "品牌禁用失败"),
|
||||
|
||||
BRAND_DELETE_ERROR(14004, "品牌删除失败"),
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*/
|
||||
USER_EDIT_SUCCESS(20001, "用户修改成功"),
|
||||
|
||||
USER_NOT_EXIST(20002, "用户不存在"),
|
||||
|
||||
USER_NOT_LOGIN(20003, "用户未登录"),
|
||||
|
||||
USER_AUTH_EXPIRED(20004, "用户已退出,请重新登录"),
|
||||
|
||||
USER_AUTHORITY_ERROR(20005, "权限不足"),
|
||||
|
||||
USER_CONNECT_LOGIN_ERROR(20006, "未找到登录信息"),
|
||||
|
||||
USER_NAME_EXIST(20007, "该用户名已被注册"),
|
||||
|
||||
USER_PHONE_EXIST(20008, "该手机号已被注册"),
|
||||
|
||||
USER_PHONE_NOT_EXIST(20009, "手机号不存在"),
|
||||
|
||||
USER_PASSWORD_ERROR(20010, "密码不正确"),
|
||||
|
||||
USER_NOT_PHONE(20011, "非当前用户的手机号"),
|
||||
|
||||
USER_CONNECT_ERROR(20012, "联合第三方登录,授权信息错误"),
|
||||
|
||||
USER_RECEIPT_REPEAT_ERROR(20013, "会员发票信息重复"),
|
||||
|
||||
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, "无法重复收藏"),
|
||||
|
||||
/**
|
||||
* 权限
|
||||
*/
|
||||
PERMISSION_DEPARTMENT_ROLE_ERROR(21001, "角色已绑定部门,请逐个删除"),
|
||||
|
||||
PERMISSION_USER_ROLE_ERROR(21002, "角色已绑定管理员,请逐个删除"),
|
||||
|
||||
PERMISSION_MENU_ROLE_ERROR(21003, "菜单已绑定角色,请先删除或编辑角色"),
|
||||
|
||||
PERMISSION_DEPARTMENT_DELETE_ERROR(21004, "部门已经绑定管理员,请先删除或编辑管理员"),
|
||||
|
||||
PERMISSION_BEYOND_TEN(21005, "最多可以设置10个角色"),
|
||||
|
||||
/**
|
||||
* 分销
|
||||
*/
|
||||
DISTRIBUTION_CLOSE(22000, "分销功能关闭"),
|
||||
|
||||
DISTRIBUTION_NOT_EXIST(22001, "分销员不存在"),
|
||||
|
||||
DISTRIBUTION_IS_APPLY(22002, "分销员已申请,无需重复提交"),
|
||||
|
||||
DISTRIBUTION_AUDIT_ERROR(22003, "审核分销员失败"),
|
||||
|
||||
DISTRIBUTION_RETREAT_ERROR(22004, "分销员清退失败"),
|
||||
|
||||
DISTRIBUTION_CASH_NOT_EXIST(22005, "分销员提现记录不存在"),
|
||||
|
||||
DISTRIBUTION_GOODS_DOUBLE(22006, "不能重复添加分销商品"),
|
||||
|
||||
/**
|
||||
* 购物车
|
||||
*/
|
||||
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, "没有待发货的订单"),
|
||||
|
||||
ORDER_NOT_SUPPORT_DISTRIBUTION(31011, "购物车中包含不支持配送的商品,请重新选择收货地址,或者重新选择商品"),
|
||||
|
||||
ORDER_CAN_NOT_CANCEL(31012, "当前订单状态不可取消"),
|
||||
|
||||
/**
|
||||
* 支付
|
||||
*/
|
||||
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, "支付订单不存在"),
|
||||
|
||||
CAN_NOT_RECHARGE_WALLET(32012, "不能使用余额进行充值"),
|
||||
|
||||
/**
|
||||
* 售后
|
||||
*/
|
||||
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 +283,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 +358,11 @@ public enum ResultCode {
|
||||
* 页面
|
||||
*/
|
||||
PAGE_NOT_EXIST(61001, "页面不存在"),
|
||||
|
||||
PAGE_OPEN_DELETE_ERROR(61002, "当前页面为开启状态,无法删除"),
|
||||
|
||||
PAGE_DELETE_ERROR(61003, "当前页面为唯一页面,无法删除"),
|
||||
|
||||
PAGE_RELEASE_ERROR(61004, "页面已发布,无需重复提交"),
|
||||
|
||||
/**
|
||||
@ -266,39 +379,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;
|
||||
|
||||
|
||||
@ -44,10 +44,21 @@ public class GlobalControllerExceptionHandler {
|
||||
|
||||
//如果是自定义异常,则获取异常,返回自定义错误消息
|
||||
if (e instanceof ServiceException) {
|
||||
ResultCode resultCode = ((ServiceException) e).getResultCode();
|
||||
ServiceException serviceException = ((ServiceException) e);
|
||||
ResultCode resultCode = serviceException.getResultCode();
|
||||
|
||||
Integer code = null;
|
||||
String message = null;
|
||||
|
||||
if (resultCode != null) {
|
||||
return ResultUtil.error(resultCode.code(), resultCode.message());
|
||||
code = resultCode.code();
|
||||
message = resultCode.message();
|
||||
}
|
||||
//如果有扩展消息,则输出异常中,跟随补充异常
|
||||
if (!serviceException.getMsg().equals(ServiceException.DEFAULT_MESSAGE)) {
|
||||
message += ":" + serviceException.getMsg();
|
||||
}
|
||||
return ResultUtil.error(code, message);
|
||||
}
|
||||
|
||||
//默认错误消息
|
||||
|
||||
@ -4,13 +4,19 @@ import cn.lili.common.enums.ResultCode;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 全局业务异常类
|
||||
*
|
||||
* @author Chopper
|
||||
*/
|
||||
@Data
|
||||
public class ServiceException extends RuntimeException {
|
||||
|
||||
private String msg;
|
||||
public static String DEFAULT_MESSAGE = "网络错误,请稍后重试!";
|
||||
|
||||
//异常消息
|
||||
private String msg = DEFAULT_MESSAGE;
|
||||
|
||||
//错误码
|
||||
private ResultCode resultCode;
|
||||
|
||||
public ServiceException(String msg) {
|
||||
@ -19,8 +25,7 @@ public class ServiceException extends RuntimeException {
|
||||
}
|
||||
|
||||
public ServiceException() {
|
||||
super("网络错误,请稍后重试!");
|
||||
this.msg = "网络错误,请稍后重试!";
|
||||
super();
|
||||
}
|
||||
|
||||
public ServiceException(ResultCode resultCode) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,9 +7,9 @@ public enum DelayQueueEnums {
|
||||
|
||||
|
||||
/**
|
||||
* 促销任务队列
|
||||
* 促销活动
|
||||
*/
|
||||
PROMOTION_QUEUE("促销任务队列");
|
||||
PROMOTION("促销活动");
|
||||
|
||||
private String description;
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -13,4 +13,9 @@ public abstract class TimeExecuteConstant {
|
||||
*/
|
||||
public static final String PROMOTION_EXECUTOR = "promotionTimeTriggerExecutor";
|
||||
|
||||
/**
|
||||
* 直播间延迟加载执行器
|
||||
*/
|
||||
public static final String BROADCAST_EXECUTOR = "broadcastTimeTriggerExecutor";
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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位,以后的数字四舍五入。
|
||||
*
|
||||
|
||||
@ -87,6 +87,9 @@ public class DateUtil {
|
||||
* @return
|
||||
*/
|
||||
public static Date endOfDate(Date date) {
|
||||
if (date == null) {
|
||||
date = new Date();
|
||||
}
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 23);
|
||||
@ -200,6 +203,7 @@ public class DateUtil {
|
||||
public static String toString(Date date) {
|
||||
return toString(date, STANDARD_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 把日期转换成字符串型
|
||||
*
|
||||
@ -209,6 +213,7 @@ public class DateUtil {
|
||||
public static String toString(Long date) {
|
||||
return toString(date, STANDARD_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 把日期转换成字符串型
|
||||
*
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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=================================
|
||||
|
||||
/**
|
||||
|
||||
@ -78,7 +78,7 @@ public class SliderImageUtil {
|
||||
graphics.dispose();
|
||||
|
||||
//添加水印
|
||||
ImageUtil.addWatermark(originalImage, "请滑动拼图");
|
||||
ImageUtil.addWatermark(originalImage, "LILI-SHOP");
|
||||
ByteArrayOutputStream newImageOs = new ByteArrayOutputStream();//新建流。
|
||||
ImageIO.write(newImage, TEMP_IMG_FILE_TYPE, newImageOs);//利用ImageIO类提供的write方法,将bi以png图片的数据模式写入流。
|
||||
byte[] newImagery = newImageOs.toByteArray();
|
||||
|
||||
@ -82,7 +82,7 @@ public class VerificationServiceImpl implements VerificationService {
|
||||
} catch (ServiceException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("创建校验错误",e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -61,4 +61,8 @@ public class RocketmqCustomProperties {
|
||||
|
||||
private String afterSaleGroup;
|
||||
|
||||
private String broadcastTopic;
|
||||
|
||||
private String broadcastGroup;
|
||||
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
|
||||
//删除缓存
|
||||
cache.vagueDel("{regions}");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("同步行政数据错误",e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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:一口价(只需要传入price,price2不传)
|
||||
//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;
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* 背景图,填入mediaID(mediaID获取后,三天内有效);图片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;
|
||||
|
||||
/**
|
||||
* 分享图,填入mediaID(mediaID获取后,三天内有效);图片mediaID的获取,请参考以下文档: https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html;直播间分享图,图片规则:建议像素800*640,大小不超过1M;
|
||||
*/
|
||||
@ApiModelProperty(value = "分享图")
|
||||
private String shareImg;
|
||||
|
||||
/**
|
||||
* 购物直播频道封面图,填入mediaID(mediaID获取后,三天内有效);图片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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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:一口价(只需要传入price,price2不传)
|
||||
//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);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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> {
|
||||
}
|
||||
@ -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> {
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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> {
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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"));
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
}
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,245 @@
|
||||
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 {
|
||||
//发送url
|
||||
String url = "https://api.weixin.qq.com/wxaapi/broadcast/room/create?access_token=";
|
||||
//添加直播间
|
||||
Map<String, String> map = this.mockRoom(studio);
|
||||
JSONObject json = this.doPostWithJson(url, map);
|
||||
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) {
|
||||
//发送url
|
||||
String url = "https://api.weixin.qq.com/wxaapi/broadcast/room/editroom?access_token=";
|
||||
|
||||
//修改直播间
|
||||
Map<String, String> map = this.mockRoom(studio);
|
||||
map.put("id", studio.getRoomId().toString());
|
||||
this.doPostWithJson(url, map);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取直播间回放
|
||||
*
|
||||
* @param roomId 房间ID
|
||||
* @return 回放地址
|
||||
*/
|
||||
public String getLiveInfo(Integer roomId) {
|
||||
//发送url
|
||||
String url = "https://api.weixin.qq.com/wxa/business/getliveinfo?access_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");
|
||||
JSONObject json = this.doPostWithJson(url, map);
|
||||
//TODO get media_url
|
||||
return json.getStr("live_replay");
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送直播间商品
|
||||
*
|
||||
* @param roomId 房间ID
|
||||
* @param goodsId 商品ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
public Boolean pushGoods(Integer roomId, Integer goodsId) {
|
||||
//发送url
|
||||
String url = "https://api.weixin.qq.com/wxaapi/broadcast/room/addgoods?access_token=";
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
//直播间回放
|
||||
Integer[] ids = {goodsId};
|
||||
map.put("ids", ids);
|
||||
//商品ID
|
||||
map.put("roomId", roomId);
|
||||
this.doPostWithJson(url, map);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除直播间商品
|
||||
*
|
||||
* @param roomId 房间ID
|
||||
* @param goodsId 商品ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
public Boolean goodsDeleteInRoom(Integer roomId, Integer goodsId) {
|
||||
//发送url
|
||||
String url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/deleteInRoom?access_token=";
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
//直播间回放
|
||||
map.put("goodsId", goodsId);
|
||||
//商品ID
|
||||
map.put("roomId", roomId);
|
||||
this.doPostWithJson(url, map);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加直播商品
|
||||
*
|
||||
* @param commodity 直播商品
|
||||
* @return 添加结果
|
||||
*/
|
||||
public JSONObject addGoods(Commodity commodity) {
|
||||
//发送url
|
||||
String url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/add?access_token=";
|
||||
|
||||
//商品名称,最长14个汉字
|
||||
if (commodity.getName().length() > 14) {
|
||||
commodity.setName(commodity.getName().substring(0, 13));
|
||||
}
|
||||
|
||||
//新建微信商品DTO
|
||||
GoodsInfo goodsInfo = new GoodsInfo(commodity);
|
||||
//上传微信临时图片
|
||||
goodsInfo.setCoverImgUrl(wechatMediaUtil.uploadMedia("image", commodity.getGoodsImage()));
|
||||
Map<String, GoodsInfo> map = new HashMap<>();
|
||||
//调用新增直播商品接口
|
||||
map.put("goodsInfo", goodsInfo);
|
||||
return this.doPostWithJson(url, map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除直播商品
|
||||
*
|
||||
* @param goodsId 商品ID
|
||||
* @return 删除结果
|
||||
*/
|
||||
public JSONObject deleteGoods(String goodsId) {
|
||||
//发送url
|
||||
String url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/delete?access_token=";
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("goodsId", goodsId);
|
||||
return this.doPostWithJson(url, map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询直播商品状态
|
||||
*
|
||||
* @param goodsIdList 商品ID列表
|
||||
* @return 删除结果
|
||||
*/
|
||||
public JSONObject getGoodsWareHouse(List<String> goodsIdList) {
|
||||
//发送url
|
||||
String url = "https://api.weixin.qq.com/wxa/business/getgoodswarehouse?access_token=";
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("goods_ids", goodsIdList);
|
||||
return this.doPostWithJson(url, map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求微信接口
|
||||
*
|
||||
* @param url 链接
|
||||
* @param map 参数
|
||||
* @return 返回内容
|
||||
*/
|
||||
private JSONObject doPostWithJson(String url, Map map) {
|
||||
//获取token
|
||||
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
|
||||
//请求链接添加token
|
||||
url += token;
|
||||
//发起请求
|
||||
String content = HttpUtils.doPostWithJson(url, map);
|
||||
//记录请求结果
|
||||
log.info("微信小程序请求结果:" + content);
|
||||
//获取请求内容,如果token过期则重新获取,如果出错则抛出错误
|
||||
JSONObject jsonObject = new JSONObject(content);
|
||||
if (jsonObject.get("errcode").equals("0")) {
|
||||
return jsonObject;
|
||||
} else if (jsonObject.get("errcode").equals("40001")) {
|
||||
wechatAccessTokenUtil.removeAccessToken(ClientTypeEnum.WECHAT_MP);
|
||||
return this.doPostWithJson(url, map);
|
||||
} else {
|
||||
throw new ServiceException(jsonObject.get("errmsg").toString());
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> mockRoom(Studio studio) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
//背景图
|
||||
map.put("coverImg", wechatMediaUtil.uploadMedia("image", studio.getCoverImg()));
|
||||
//分享图
|
||||
map.put("shareImg", wechatMediaUtil.uploadMedia("image", studio.getShareImg()));
|
||||
//购物直播频道封面图
|
||||
map.put("feedsImg", wechatMediaUtil.uploadMedia("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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,143 @@
|
||||
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.message.util.WechatAccessTokenUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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 {
|
||||
@Autowired
|
||||
private WechatAccessTokenUtil wechatAccessTokenUtil;
|
||||
|
||||
/**
|
||||
* 上传多媒体数据到微信服务器
|
||||
*
|
||||
* @param mediaFileUrl 来自网络上面的媒体文件地址
|
||||
* @return
|
||||
*/
|
||||
public String uploadMedia(String type, String mediaFileUrl) {
|
||||
//获取token
|
||||
String accessToken = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
|
||||
/*
|
||||
* 上传媒体文件到微信服务器需要请求的地址
|
||||
*/
|
||||
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());
|
||||
log.info("微信媒体上传:" + jsonObject.toString());
|
||||
//判断是否传递成功,如果token过期则重新获取
|
||||
if (jsonObject.get("errcode") != null && jsonObject.get("errcode").equals("40001")) {
|
||||
wechatAccessTokenUtil.removeAccessToken(ClientTypeEnum.WECHAT_MP);
|
||||
return this.uploadMedia(type, mediaFileUrl);
|
||||
} else if (jsonObject.get("errcode") != null) {
|
||||
throw new ServiceException(jsonObject.get("errmsg").toString());
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -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() {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -64,6 +64,10 @@ public class DraftGoods extends BaseEntity {
|
||||
@ApiModelProperty(value = "详情")
|
||||
private String intro;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "商品移动端详情")
|
||||
private String mobileIntro;
|
||||
|
||||
@Max(value = 99999999, message = "价格不能超过99999999")
|
||||
@ApiModelProperty(value = "商品价格")
|
||||
private Double price;
|
||||
@ -112,16 +116,8 @@ public class DraftGoods extends BaseEntity {
|
||||
@ApiModelProperty(value = "运费模板id")
|
||||
private String templateId;
|
||||
|
||||
@ApiModelProperty(value = "运费承担者")
|
||||
private String freightPayer;
|
||||
|
||||
@ApiModelProperty(value = "是否自营")
|
||||
private Boolean selfOperated;
|
||||
/**
|
||||
* 商品移动端详情
|
||||
*/
|
||||
@ApiModelProperty(value = "商品移动端详情")
|
||||
private String mobileIntro;
|
||||
|
||||
@ApiModelProperty(value = "商品视频")
|
||||
private String goodsVideo;
|
||||
@ -154,4 +150,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;
|
||||
|
||||
}
|
||||
@ -2,11 +2,14 @@ package cn.lili.modules.goods.entity.dos;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.lili.base.BaseEntity;
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
|
||||
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.xkcoding.http.util.StringUtil;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
@ -16,6 +19,7 @@ import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.Max;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 商品
|
||||
@ -145,11 +149,6 @@ public class Goods extends BaseEntity {
|
||||
*/
|
||||
@ApiModelProperty(value = "运费模板id")
|
||||
private String templateId;
|
||||
/**
|
||||
* 谁承担运费 BUYER:买家承担,STORE:卖家承担
|
||||
*/
|
||||
@ApiModelProperty(value = " 谁承担运费 BUYER:买家承担,STORE:卖家承担")
|
||||
private String freightPayer;
|
||||
/**
|
||||
* 审核状态
|
||||
*
|
||||
@ -190,11 +189,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 +213,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();
|
||||
@ -215,11 +221,35 @@ public class Goods extends BaseEntity {
|
||||
this.intro = goodsOperationDTO.getIntro();
|
||||
this.mobileIntro = goodsOperationDTO.getMobileIntro();
|
||||
this.cost = goodsOperationDTO.getCost();
|
||||
if (goodsOperationDTO.getGoodsParamsList() != null && goodsOperationDTO.getGoodsParamsList().isEmpty()) {
|
||||
this.params = JSONUtil.toJsonStr(goodsOperationDTO.getGoodsParamsList());
|
||||
if (goodsOperationDTO.getGoodsParamsDTOList() != null && goodsOperationDTO.getGoodsParamsDTOList().isEmpty()) {
|
||||
this.params = JSONUtil.toJsonStr(goodsOperationDTO.getGoodsParamsDTOList());
|
||||
}
|
||||
//如果立即上架则
|
||||
this.marketEnable = goodsOperationDTO.isRelease() ? GoodsStatusEnum.UPPER.name() : GoodsStatusEnum.DOWN.name();
|
||||
this.goodsType = goodsOperationDTO.getGoodsType();
|
||||
|
||||
//循环sku,判定sku是否有效
|
||||
for (Map<String, Object> sku : goodsOperationDTO.getSkuList()) {
|
||||
//判定参数不能为空
|
||||
if (sku.get("sn") == null) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_SN_ERROR);
|
||||
}
|
||||
if (StringUtil.isEmpty(sku.get("price").toString()) || Integer.parseInt( sku.get("price").toString()) <= 0) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_PRICE_ERROR);
|
||||
}
|
||||
if (StringUtil.isEmpty(sku.get("cost").toString()) || Integer.parseInt( sku.get("cost").toString()) <= 0) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_COST_ERROR);
|
||||
}
|
||||
//虚拟商品没有重量字段
|
||||
if(sku.containsKey("weight")) {
|
||||
if (StringUtil.isEmpty(sku.get("weight").toString()) || Integer.parseInt(sku.get("weight").toString()) < 0) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_WEIGHT_ERROR);
|
||||
}
|
||||
}
|
||||
if (StringUtil.isEmpty(sku.get("quantity").toString()) || Integer.parseInt( sku.get("quantity").toString()) < 0) {
|
||||
throw new ServiceException(ResultCode.GOODS_SKU_QUANTITY_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
package cn.lili.modules.goods.entity.dos;
|
||||
|
||||
import cn.lili.base.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* 商品关联参数
|
||||
*
|
||||
* @author pikachu
|
||||
* @date 2020-02-23 9:14:33
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "li_goods_params")
|
||||
@TableName("li_goods_params")
|
||||
@ApiModel(value = "商品关联参数")
|
||||
public class GoodsParams extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 商品id
|
||||
*/
|
||||
@TableField(value = "goods_id")
|
||||
@ApiModelProperty(value = "商品id", hidden = true)
|
||||
private String goodsId;
|
||||
/**
|
||||
* 参数id
|
||||
*/
|
||||
@TableField(value = "param_id")
|
||||
@ApiModelProperty(value = "参数id", required = true)
|
||||
private String paramId;
|
||||
/**
|
||||
* 参数名字
|
||||
*/
|
||||
@TableField(value = "param_name")
|
||||
@ApiModelProperty(value = "参数名字", required = true)
|
||||
private String paramName;
|
||||
/**
|
||||
* 参数值
|
||||
*/
|
||||
@TableField(value = "param_value")
|
||||
@ApiModelProperty(value = "参数值", required = true)
|
||||
@Length(max = 100, message = "参数值字符不能大于120")
|
||||
private String paramValue;
|
||||
|
||||
}
|
||||
@ -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,18 @@ 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;
|
||||
|
||||
public Double getWeight() {
|
||||
if (weight == null) {
|
||||
return 0d;
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getUpdateTime() {
|
||||
|
||||
@ -1,13 +1,17 @@
|
||||
package cn.lili.modules.goods.entity.dos;
|
||||
|
||||
import cn.lili.base.BaseEntity;
|
||||
import cn.lili.base.IdEntity;
|
||||
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 org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
@ -25,7 +29,9 @@ import javax.validation.constraints.NotNull;
|
||||
@Table(name = "li_parameters")
|
||||
@TableName("li_parameters")
|
||||
@ApiModel(value = "商品参数")
|
||||
public class Parameters extends BaseEntity {
|
||||
public class Parameters extends IdEntity {
|
||||
|
||||
|
||||
|
||||
private static final long serialVersionUID = -566510714456317006L;
|
||||
|
||||
@ -36,6 +42,7 @@ public class Parameters extends BaseEntity {
|
||||
|
||||
|
||||
@ApiModelProperty(value = "选择值")
|
||||
@NotEmpty(message = "参数选项值必填")
|
||||
private String options;
|
||||
|
||||
@ApiModelProperty(value = "是否可索引,0 不显示 1 显示", required = true)
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
package cn.lili.modules.goods.entity.dos;
|
||||
|
||||
import cn.lili.base.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
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 pikachu
|
||||
* @date 2020-02-18 15:18:56
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "li_spec_values")
|
||||
@TableName("li_spec_values")
|
||||
@ApiModel(value = "规格值")
|
||||
public class SpecValues extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 规格项id
|
||||
*/
|
||||
@TableField(value = "spec_id")
|
||||
@ApiModelProperty(value = "规格项id")
|
||||
private String specId;
|
||||
|
||||
/**
|
||||
* 规格值名字
|
||||
*/
|
||||
@TableField(value = "spec_value")
|
||||
@ApiModelProperty(value = "规格值名字")
|
||||
private String specValue;
|
||||
|
||||
}
|
||||
@ -1,11 +1,13 @@
|
||||
package cn.lili.modules.goods.entity.dos;
|
||||
|
||||
import cn.lili.base.BaseEntity;
|
||||
import cn.lili.base.IdEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
@ -21,7 +23,7 @@ import javax.validation.constraints.NotEmpty;
|
||||
@Table(name = "li_specification")
|
||||
@TableName("li_specification")
|
||||
@ApiModel(value = "规格项")
|
||||
public class Specification extends BaseEntity {
|
||||
public class Specification extends IdEntity {
|
||||
|
||||
private static final long serialVersionUID = 147792597901239486L;
|
||||
|
||||
@ -34,9 +36,19 @@ public class Specification extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 所属卖家 0属于平台
|
||||
* <p>
|
||||
* 店铺自定义规格暂时废弃 2021-06-23 后续推出新配置方式
|
||||
*/
|
||||
@ApiModelProperty(hidden = true)
|
||||
private String storeId;
|
||||
|
||||
/**
|
||||
* 规格值名字
|
||||
*/
|
||||
@TableField(value = "spec_value")
|
||||
@Column(columnDefinition = "TEXT")
|
||||
@ApiModelProperty(value = "规格值名字, 《,》分割")
|
||||
private String specValue;
|
||||
|
||||
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
package cn.lili.modules.goods.entity.dto;
|
||||
|
||||
import cn.lili.modules.goods.entity.dos.DraftGoods;
|
||||
import cn.lili.modules.goods.entity.dos.GoodsParams;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ -22,7 +21,7 @@ public class DraftGoodsDTO extends DraftGoods {
|
||||
|
||||
@ApiModelProperty(value = "商品参数")
|
||||
@Valid
|
||||
private List<GoodsParams> goodsParamsList;
|
||||
private List<GoodsParamsDTO> goodsParamsDTOList;
|
||||
|
||||
@ApiModelProperty(value = "商品图片")
|
||||
private List<String> goodsGalleryList;
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package cn.lili.modules.goods.entity.dto;
|
||||
|
||||
import cn.lili.modules.goods.entity.dos.GoodsParams;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
@ -16,7 +15,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 商品查询条件
|
||||
* 商品编辑DTO
|
||||
*
|
||||
* @author pikachu
|
||||
* @date 2020-02-24 19:27:20
|
||||
@ -66,9 +65,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;
|
||||
|
||||
@ -86,8 +82,7 @@ public class GoodsOperationDTO implements Serializable {
|
||||
private boolean recommend;
|
||||
|
||||
@ApiModelProperty(value = "商品参数")
|
||||
@Valid
|
||||
private List<GoodsParams> goodsParamsList;
|
||||
private List<GoodsParamsDTO> goodsParamsDTOList;
|
||||
|
||||
@ApiModelProperty(value = "商品图片")
|
||||
private List<String> goodsGalleryList;
|
||||
@ -118,4 +113,13 @@ 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;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package cn.lili.modules.goods.entity.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品关联参数
|
||||
*
|
||||
* @author pikachu
|
||||
* @date 2020-02-23 9:14:33
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(value = "商品参数分组")
|
||||
public class GoodsParamsDTO {
|
||||
|
||||
@TableField(value = "group_id")
|
||||
@ApiModelProperty(value = "分组id")
|
||||
private String groupId;
|
||||
|
||||
@TableField(value = "group_name")
|
||||
@ApiModelProperty(value = "分组名称")
|
||||
private String groupName;
|
||||
|
||||
@ApiModelProperty(value = "分组内的商品参数列表")
|
||||
private List<GoodsParamsItemDTO> goodsParamsItemDTOList;
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package cn.lili.modules.goods.entity.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
|
||||
/**
|
||||
* 商品参数项
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* 2021-06-24 15:41
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(value = "商品参数列表")
|
||||
public class GoodsParamsItemDTO {
|
||||
|
||||
@ApiModelProperty(value = "参数ID")
|
||||
private String paramId;
|
||||
|
||||
@ApiModelProperty(value = "参数名字")
|
||||
private String paramName;
|
||||
|
||||
@ApiModelProperty(value = "参数值")
|
||||
private String paramValue;
|
||||
|
||||
@ApiModelProperty(value = "是否可索引,0 不索引 1 索引")
|
||||
private Integer isIndex = 0;
|
||||
|
||||
@ApiModelProperty(value = "是否必填,0 不显示 1 显示")
|
||||
private Integer required = 0;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
package cn.lili.modules.goods.entity.dto;
|
||||
|
||||
import cn.lili.common.utils.StringUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 规格搜索参数
|
||||
*
|
||||
* @author paulG
|
||||
* @date 2020/12/19
|
||||
**/
|
||||
@Data
|
||||
public class SpecificationSearchParams {
|
||||
|
||||
|
||||
@ApiModelProperty(value = "规格名")
|
||||
private String specName;
|
||||
|
||||
@ApiModelProperty(value = "绑定分类")
|
||||
private String categoryPath;
|
||||
|
||||
@ApiModelProperty(value = "未删除 ")
|
||||
private Boolean deleteFlag;
|
||||
|
||||
public <T> QueryWrapper<T> queryWrapper() {
|
||||
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.like(StringUtils.isNotEmpty(specName), "spec_name", specName);
|
||||
queryWrapper.eq(deleteFlag != null, "delete_flag", deleteFlag);
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user