diff --git a/README.md b/README.md
index 733cafd4..2ec84fdb 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,9 @@
## Lilishop B2B2C商城系统
+##### 开源不易,如有帮助请点Star
+[](https://gitee.com/beijing_hongye_huicheng/lilishop/stargazers)
+
+
### 介绍
**官网**:https://pickmall.cn
@@ -60,21 +64,24 @@ Lilishop 是一款Java开发,基于SpringBoot的B2B2C多用户商城,前端
`git clone https://gitee.com/beijing_hongye_huicheng/docker.git `
##### 部署基础环境
`docker-compose up -d`
+
##### 部署应用
`docker-compose -f docker-compose-application.yml up -d`
+PS:单独部署的话,数据库文件访问这里:https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql
+
##### 各个地址
| API | 地址 |
| -------------- | --------------- |
-| 买家api | http://127.0.0.1:8888 |
-| 商家api | http://127.0.0.1:8889 |
-| 管理端api | http://127.0.0.1:8887 |
-| 通用api | http://127.0.0.1:8890 |
+| 买家API | http://127.0.0.1:8888 |
+| 商家API | http://127.0.0.1:8889 |
+| 管理端API | http://127.0.0.1:8887 |
+| 通用API | http://127.0.0.1:8890 |
-| 演示 | 地址 |
+| 前端演示 | 地址 |
| -------------- | --------------- |
| PC | http://127.0.0.1:10000 |
| WAP | http://127.0.0.1:10001 |
@@ -83,6 +90,44 @@ Lilishop 是一款Java开发,基于SpringBoot的B2B2C多用户商城,前端
+
+
+### 功能列表
+
+
+
+#### 平台功能
+
+
+
+
+
+#### 商家端功能
+
+
+
+
+
+
+
+### 功能展示
+
+
+
+#### 移动端
+
+
+
+
+
+
+
+#### 管理端
+
+
+
+
+
### 技术选型
##### Java后台
@@ -136,125 +181,35 @@ Lilishop 是一款Java开发,基于SpringBoot的B2B2C多用户商城,前端
| CSS预处理 | scss |
| 地图引擎 | amap |
-
-
-### 功能列表
-
-
- 运营后台功能 |
- 首页 | 平台统计、待办事项、流量统计 |
- 会员 | 会员列表 |
- 评价列表 |
- 积分历史 |
- 会员资金 |
- 充值记录 |
- 订单 | 商品订单 |
- 订单售后 |
- 交易投诉 |
- 售后原因 |
- 收款流水 |
- 退款流水 |
- 商品 | 商品列表 |
- 商品审核 |
- 商品分类 |
- 商品品牌 |
- 商品规格 |
- 计量单位 |
- 促销 | 优惠券 |
- 秒杀活动 |
- 拼团活动 |
- 积分商品 |
- 积分分类 |
- 店铺 | 店铺管理 |
- 店铺结算 |
- 店铺结算 |
- 店铺结算 |
- 店铺对账 |
- 运营 | 店铺对账 |
- PC端楼层装修 |
- 移动端楼层装修 |
- 分销管理 |
- 文章管理 |
- 意见反馈 |
- 站内信 |
- 短信管理 |
- APP版本管理 |
- 统计 | 会员统计 |
- 订单统计 |
- 商品统计 |
- 流量统计 |
- 设置 | 用户管理 |
- 菜单管理 |
- 部门管理 |
- 系统设置 |
- OSS资源 |
- 行政地区 |
- 物流公司 |
- 信任登录 |
- 支付设置 |
- 验证码管理 |
- 敏感词管理 |
-
-
-
- 店铺后台功能列表 |
- 首页 | 店铺信息 |
- 待办事项 |
- 平台公告 |
- 商品 | 商品发布 |
- 商品列表 |
- 店铺商品分类 |
- 订单 | 商品订单 |
- 退货管理 |
- 退款管理 |
- 投诉管理 |
- 评价管理 |
- 财务 | 财务对账 |
- 店铺结算 |
- 发票管理 |
- 促销 | 拼团管理 |
- 秒杀活动 |
- 满额活动 |
- 优惠券 |
- 分销商品 |
- 统计 | 商品统计 |
- 订单统计 |
- 设置 | 配送模板 |
- 物流公司 |
- 店铺设置 |
- 自提点管理 |
- 系统消息 |
-
-
### 技术亮点
1.后端框架基于Springboot,构建基于maven,持久层使用MyBatisPlus。使用elasticsearch、redis、mongodb、rocketmq 等各种中间健。都是主流架构,轻松应对各种环境。
-
+
2.支持集群、分布式,支持docker 轻松部署,解决各种复杂场景!
-
+
3.代码模块清晰,主要分为三端api(买家、卖家、管理),各端API互相隔离,自己鉴权,自己操作业务。
-
+
4.使用阿里开源的RocketMQ,基于mq解决各种并发场景,解决事务一致性,解决搞并发延迟场景问题。
-
+
5.项目使用多级缓存,应用不同场景,redis缓存业务数据、mongodb缓存关系型多对多关系问题、nginx缓存高频访问低频修改的页面。
-
+
6.支持各种联合登陆,支持各种客户端的支付问题,灵活配置灵活开启。
-
+
7.内置完善的楼层装修机制,各种拖拉拽,维护跳转页面或外网,即便是一个什么都不懂的运营也可以轻松掌握。
-
+
8.内置阿里短信接口,可以在线申请短信模版。内置阿里oss系统,可以对文件执行各种操作。oss商家端资源相互隔离。
-
+
10.强大的统计报表,统计效果,可以实现各个场景,包含在线人数,历史在线人数,活跃人数等信息。
-
+
11.标准Api接口、提供swagger文档,快速二开。
-
+
12.分布式调度任务中心,解决分布式定时任务多次执行问题。
-
+
13.代码注释完善,快速上手。
-
+
14.非移动端采用IView框架,各种自定义插件、选择器实现。移动端采用uniapp,一次编写,全端使用
-
+
15.已经对接好各种第三方插件,支持各种复杂等联合登陆,联合支付等场景。
diff --git a/consumer/src/main/java/cn/lili/timetask/handler/impl/promotion/PromotionEverydayExecute.java b/consumer/src/main/java/cn/lili/timetask/handler/impl/promotion/PromotionEverydayExecute.java
index 8a504ab7..f0e67719 100644
--- a/consumer/src/main/java/cn/lili/timetask/handler/impl/promotion/PromotionEverydayExecute.java
+++ b/consumer/src/main/java/cn/lili/timetask/handler/impl/promotion/PromotionEverydayExecute.java
@@ -11,7 +11,6 @@ import cn.lili.modules.promotion.service.*;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
-import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
@@ -59,11 +58,14 @@ public class PromotionEverydayExecute implements EveryDayExecute {
public void execute() {
Query query = new Query();
- query.addCriteria(Criteria.where("promotionStatus").ne(PromotionStatusEnum.END.name()).orOperator(Criteria.where("promotionStatus").ne(PromotionStatusEnum.CLOSE.name())));
+// 结束条件 活动关闭/活动结束
+ query.addCriteria(Criteria.where("promotionStatus").ne(PromotionStatusEnum.END.name())
+ .orOperator(Criteria.where("promotionStatus").ne(PromotionStatusEnum.CLOSE.name())));
query.addCriteria(Criteria.where("endTime").lt(new Date()));
List promotionIds = new ArrayList<>();
+ //关闭满减活动
List fullDiscountVOS = mongoTemplate.find(query, FullDiscountVO.class);
if (!fullDiscountVOS.isEmpty()) {
List ids = new ArrayList<>();
@@ -80,9 +82,10 @@ public class PromotionEverydayExecute implements EveryDayExecute {
fullDiscountService.update(this.getUpdatePromotionWrapper(ids));
promotionIds.addAll(ids);
}
-
+ //关闭拼团活动
List pintuanVOS = mongoTemplate.find(query, PintuanVO.class);
if (!pintuanVOS.isEmpty()) {
+ //准备修改活动的id
List ids = new ArrayList<>();
for (PintuanVO vo : pintuanVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
@@ -98,6 +101,7 @@ public class PromotionEverydayExecute implements EveryDayExecute {
promotionIds.addAll(ids);
}
+ //关闭优惠券活动
List couponVOS = mongoTemplate.find(query, CouponVO.class);
if (!couponVOS.isEmpty()) {
List ids = new ArrayList<>();
@@ -121,13 +125,22 @@ public class PromotionEverydayExecute implements EveryDayExecute {
}
+ /**
+ * 获取促销修改查询条件 修改活动状态
+ * @param ids
+ * @return
+ */
private UpdateWrapper getUpdatePromotionWrapper(List ids) {
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.in("id", ids);
updateWrapper.set("promotion_status", PromotionStatusEnum.END.name());
return updateWrapper;
}
-
+ /**
+ * 获取商品的促销修改查询条件 修改商品状态
+ * @param ids
+ * @return
+ */
private UpdateWrapper getUpdatePromotionGoodsWrapper(List ids) {
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.in("promotion_id", ids);
diff --git a/consumer/src/main/java/cn/lili/trigger/executor/PromotionTimeTriggerExecutor.java b/consumer/src/main/java/cn/lili/trigger/executor/PromotionTimeTriggerExecutor.java
index d3daf329..c0aee57d 100644
--- a/consumer/src/main/java/cn/lili/trigger/executor/PromotionTimeTriggerExecutor.java
+++ b/consumer/src/main/java/cn/lili/trigger/executor/PromotionTimeTriggerExecutor.java
@@ -12,7 +12,6 @@ import cn.lili.config.rocketmq.RocketmqCustomProperties;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.service.PromotionService;
-import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -65,6 +64,7 @@ public class PromotionTimeTriggerExecutor implements TimeTriggerExecutor {
}
return;
}
+ //拼团订单消息
PintuanOrderMessage pintuanOrderMessage = JSONUtil.toBean(JSONUtil.parseObj(object), PintuanOrderMessage.class);
if (pintuanOrderMessage != null && pintuanOrderMessage.getPintuanId() != null) {
log.info("拼团订单信息消费:{}", pintuanOrderMessage);
diff --git a/framework/src/main/java/cn/lili/common/token/base/generate/StoreTokenGenerate.java b/framework/src/main/java/cn/lili/common/token/base/generate/StoreTokenGenerate.java
index 963eeb49..0496fcea 100644
--- a/framework/src/main/java/cn/lili/common/token/base/generate/StoreTokenGenerate.java
+++ b/framework/src/main/java/cn/lili/common/token/base/generate/StoreTokenGenerate.java
@@ -6,13 +6,11 @@ import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.token.Token;
import cn.lili.common.token.TokenUtil;
import cn.lili.common.token.base.AbstractTokenGenerate;
-import cn.lili.common.enums.SwitchEnum;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.service.StoreService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -37,10 +35,10 @@ public class StoreTokenGenerate extends AbstractTokenGenerate {
public Token createToken(String username, Boolean longTerm) {
// 生成token
Member member = memberService.findByUsername(username);
- if (member.getHaveStore().equals(SwitchEnum.CLOSE.name())) {
+ if (!member.getHaveStore()) {
throw new ServiceException("该会员未开通店铺");
}
- AuthUser user = new AuthUser(member.getUsername(), member.getId(),member.getNickName(), UserEnums.STORE);
+ AuthUser user = new AuthUser(member.getUsername(), member.getId(), member.getNickName(), UserEnums.STORE);
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Store::getMemberId, member.getId());
Store store = storeService.getOne(queryWrapper);
diff --git a/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsIndexServiceImpl.java b/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsIndexServiceImpl.java
index 2de787c3..257714ae 100644
--- a/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsIndexServiceImpl.java
+++ b/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsIndexServiceImpl.java
@@ -24,7 +24,6 @@ import cn.lili.modules.search.repository.EsGoodsIndexRepository;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.search.service.EsGoodsSearchService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.IterableUtil;
import org.elasticsearch.action.search.SearchResponse;
@@ -44,6 +43,7 @@ import java.util.stream.Collectors;
/**
* 商品索引业务层实现
+ *
* @author paulG
* @since 2020/10/14
**/
@@ -64,19 +64,26 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
@Override
public void addIndex(EsGoodsIndex goods) {
+ //索引名称拼接
String indexName = elasticsearchProperties.getIndexPrefix() + "_" + EsSuffix.GOODS_INDEX_NAME;
try {
+ //分词器分词
AnalyzeRequest analyzeRequest = AnalyzeRequest.withIndexAnalyzer(indexName, "ik_max_word", goods.getGoodsName());
AnalyzeResponse analyze = client.indices().analyze(analyzeRequest, RequestOptions.DEFAULT);
List tokens = analyze.getTokens();
+
if (goods.getAttrList() != null && !goods.getAttrList().isEmpty()) {
+ //保存分词
for (EsGoodsAttribute esGoodsAttribute : goods.getAttrList()) {
wordsToDb(esGoodsAttribute.getValue());
}
}
+ //分析词条
for (AnalyzeResponse.AnalyzeToken token : tokens) {
+ //保存词条进入数据库
wordsToDb(token.getTerm());
}
+ //生成索引
goodsIndexRepository.save(goods);
} catch (IOException e) {
log.error("为商品[" + goods.getGoodsName() + "]生成索引异常", e);
@@ -112,6 +119,7 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
@Override
public void updateIndexCommentNum(String id, Integer commentNum, Integer highPraiseNum, Double grade) {
EsGoodsIndex goodsIndex = this.findById(id);
+ //写入新的商品数据
goodsIndex.setCommentNum(commentNum);
goodsIndex.setHighPraiseNum(highPraiseNum);
goodsIndex.setGrade(grade);
@@ -139,8 +147,10 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
@Override
public void initIndex(List goodsIndexList) {
+ //索引名称拼接
String indexName = elasticsearchProperties.getIndexPrefix() + "_" + EsSuffix.GOODS_INDEX_NAME;
// deleteIndexRequest(indexName);
+ //如果索引不存在,则创建索引
if (!indexExist(indexName)) {
createIndexRequest(indexName);
}
@@ -156,11 +166,14 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
public void updateEsGoodsIndex(String id, BasePromotion promotion, String key, Double price) {
EsGoodsIndex goodsIndex = findById(id);
if (goodsIndex != null) {
+ //如果有促销活动开始,则将促销金额写入
if (promotion.getPromotionStatus().equals(PromotionStatusEnum.START.name()) && price != null) {
goodsIndex.setPromotionPrice(price);
} else {
+ //否则促销金额为商品原价
goodsIndex.setPromotionPrice(goodsIndex.getPrice());
}
+ //更新索引
this.updateGoodsIndexPromotion(goodsIndex, key, promotion);
} else {
log.error("更新索引商品促销信息失败!skuId 为 【{}】的索引不存在!", id);
@@ -170,6 +183,7 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
@Override
public void updateEsGoodsIndexByList(List promotionGoodsList, BasePromotion promotion, String key) {
if (promotionGoodsList != null) {
+ //循环更新 促销商品索引
for (PromotionGoods promotionGoods : promotionGoodsList) {
updateEsGoodsIndex(promotionGoods.getSkuId(), promotion, key, promotionGoods.getPrice());
}
@@ -186,15 +200,20 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
@Override
public void updateEsGoodsIndexAllByList(BasePromotion promotion, String key) {
List goodsIndices;
+ //如果storeid不为空,则表示是店铺活动
if (promotion.getStoreId() != null) {
EsGoodsSearchDTO searchDTO = new EsGoodsSearchDTO();
searchDTO.setStoreId(promotion.getStoreId());
+ //查询出店铺商品
Page esGoodsIndices = goodsSearchService.searchGoods(searchDTO, null);
goodsIndices = esGoodsIndices.getContent();
} else {
+ //否则是平台活动
Iterable all = goodsIndexRepository.findAll();
+// 查询出全部商品
goodsIndices = new ArrayList<>(IterableUtil.toCollection(all));
}
+ //更新商品索引
for (EsGoodsIndex goodsIndex : goodsIndices) {
this.updateGoodsIndexPromotion(goodsIndex, key, promotion);
}
@@ -202,8 +221,10 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
@Override
public void deleteEsGoodsPromotionIndexByList(List skuIds, PromotionTypeEnum promotionType) {
+ //批量删除活动索引
for (String skuId : skuIds) {
EsGoodsIndex goodsIndex = findById(skuId);
+ //商品索引不为空
if (goodsIndex != null) {
Map promotionMap = goodsIndex.getPromotionMap();
if (promotionMap != null && !promotionMap.isEmpty()) {
@@ -220,16 +241,19 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
}
/**
- * 清除所以商品索引的无效促销活动
+ * 清除所有商品索引的无效促销活动
*/
@Override
public void cleanInvalidPromotion() {
Iterable all = goodsIndexRepository.findAll();
for (EsGoodsIndex goodsIndex : all) {
Map promotionMap = goodsIndex.getPromotionMap();
+ //获取商品索引
if (promotionMap != null && !promotionMap.isEmpty()) {
+ //促销不为空则进行清洗
for (Map.Entry entry : promotionMap.entrySet()) {
BasePromotion promotion = (BasePromotion) entry.getValue();
+ //判定条件为活动已结束
if (promotion.getEndTime().getTime() > DateUtil.date().getTime()) {
promotionMap.remove(entry.getKey());
}
@@ -258,6 +282,8 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
@Override
public Map getPromotionMap(String id) {
EsGoodsIndex goodsIndex = this.findById(id);
+
+ // 如果商品索引不为空,返回促销信息,否则返回空
if (goodsIndex != null) {
Map promotionMap = goodsIndex.getPromotionMap();
if (promotionMap == null || promotionMap.isEmpty()) {
@@ -278,11 +304,14 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
@Override
public List getPromotionIdByPromotionType(String id, PromotionTypeEnum promotionTypeEnum) {
Map promotionMap = this.getPromotionMap(id);
+ //如果没有促销信息,则返回新的
if (promotionMap == null || promotionMap.isEmpty()) {
return new ArrayList<>();
}
+ //对促销进行过滤
List keyCollect = promotionMap.keySet().stream().filter(i -> i.contains(promotionTypeEnum.name())).collect(Collectors.toList());
List promotionIds = new ArrayList<>();
+ //写入促销id
for (String key : keyCollect) {
BasePromotion promotion = (BasePromotion) promotionMap.get(key);
promotionIds.add(promotion.getId());
@@ -299,25 +328,37 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
@Override
public EsGoodsIndex resetEsGoodsIndex(GoodsSku goodsSku) {
EsGoodsIndex index = new EsGoodsIndex(goodsSku);
+ //获取活动信息
Map goodsCurrentPromotionMap = promotionService.getGoodsCurrentPromotionMap(index);
+ //写入促销信息
index.setPromotionMap(goodsCurrentPromotionMap);
this.addIndex(index);
return index;
}
+ /**
+ * 修改商品活动索引
+ *
+ * @param goodsIndex 商品索引
+ * @param key 关键字
+ * @param promotion 活动
+ */
private void updateGoodsIndexPromotion(EsGoodsIndex goodsIndex, String key, BasePromotion promotion) {
Map promotionMap;
+ //数据非空处理,如果空给一个新的信息
if (goodsIndex.getPromotionMap() == null || goodsIndex.getPromotionMap().isEmpty()) {
promotionMap = new HashMap<>(1);
} else {
promotionMap = goodsIndex.getPromotionMap();
}
-
-
+ //如果活动已结束
if (promotion.getPromotionStatus().equals(PromotionStatusEnum.END.name()) || promotion.getPromotionStatus().equals(PromotionStatusEnum.CLOSE.name())) {
+ //如果存在活动
if (promotionMap.containsKey(key)) {
+ //删除活动
promotionMap.remove(key);
} else {
+ //不存在则说明是秒杀活动,尝试删除秒杀信息
this.removePromotionKey(key, promotionMap, PromotionTypeEnum.SECKILL.name());
}
} else {
@@ -337,9 +378,13 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
* @param needRemoveKeys 需移除的促销活动
*/
private void removePromotionKey(String currentKey, Map promotionMap, String... needRemoveKeys) {
+ //判定是否需要移除
if (CharSequenceUtil.containsAny(currentKey, needRemoveKeys)) {
+
List removeKeys = new ArrayList<>();
+ //促销循环
for (String entry : promotionMap.keySet()) {
+ //需要移除则进行移除处理
for (String needRemoveKey : needRemoveKeys) {
if (entry.contains(needRemoveKey) && currentKey.contains(needRemoveKey)) {
removeKeys.add(entry);
@@ -347,6 +392,7 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
}
}
}
+ //移除促销信息
promotionMap.keySet().removeAll(removeKeys);
}
}
diff --git a/framework/src/main/java/cn/lili/modules/store/entity/dto/StoreEditDTO.java b/framework/src/main/java/cn/lili/modules/store/entity/dto/StoreEditDTO.java
index 16273681..33616b57 100644
--- a/framework/src/main/java/cn/lili/modules/store/entity/dto/StoreEditDTO.java
+++ b/framework/src/main/java/cn/lili/modules/store/entity/dto/StoreEditDTO.java
@@ -20,7 +20,7 @@ public class StoreEditDTO extends StoreDetail {
private String storeDisable;
@ApiModelProperty(value = "是否自营", required = true)
- private Integer selfOperated;
+ private Boolean selfOperated;
@ApiModelProperty(value = "经纬度")
private String storeCenter;
diff --git a/framework/src/main/java/cn/lili/modules/store/serviceimpl/StoreServiceImpl.java b/framework/src/main/java/cn/lili/modules/store/serviceimpl/StoreServiceImpl.java
index 3f5ba6b2..6921a843 100644
--- a/framework/src/main/java/cn/lili/modules/store/serviceimpl/StoreServiceImpl.java
+++ b/framework/src/main/java/cn/lili/modules/store/serviceimpl/StoreServiceImpl.java
@@ -2,7 +2,6 @@ package cn.lili.modules.store.serviceimpl;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
-import cn.lili.common.enums.SwitchEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
@@ -35,11 +34,11 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import javax.annotation.Resource;
import java.util.Optional;
/**
@@ -53,7 +52,7 @@ import java.util.Optional;
public class StoreServiceImpl extends ServiceImpl implements StoreService {
//店铺
- @Autowired
+ @Resource
private StoreMapper storeMapper;
//会员
@Autowired
@@ -102,24 +101,24 @@ public class StoreServiceImpl extends ServiceImpl implements
throw new ServiceException(ResultCode.USER_NOT_EXIST);
}
//判断是否拥有店铺
- if (SwitchEnum.OPEN.name().equals(member.getHaveStore())) {
+ if (member.getHaveStore()) {
throw new ServiceException(ResultCode.STORE_APPLY_DOUBLE_ERROR);
}
//添加店铺
- Store store=new Store(member,adminStoreApplyDTO);
+ Store store = new Store(member, adminStoreApplyDTO);
this.save(store);
//判断是否存在店铺详情,如果没有则进行新建,如果存在则进行修改
- StoreDetail storeDetail = new StoreDetail(store,adminStoreApplyDTO);
+ StoreDetail storeDetail = new StoreDetail(store, adminStoreApplyDTO);
storeDetailService.save(storeDetail);
//设置会员-店铺信息
memberService.update(new LambdaUpdateWrapper()
- .eq(Member::getId,member.getId())
- .set(Member::getHaveStore,SwitchEnum.OPEN.name())
- .set(Member::getStoreId,store.getId()));
+ .eq(Member::getId, member.getId())
+ .set(Member::getHaveStore, true)
+ .set(Member::getStoreId, store.getId()));
return store;
}
@@ -177,6 +176,12 @@ public class StoreServiceImpl extends ServiceImpl implements
store.setStoreDisable(StoreStatusEnum.OPEN.value());
//添加店铺页面
pageDataService.addStorePageData(store.getId());
+ //修改会员 表示已有店铺
+ Member member = memberService.getById(store.getMemberId());
+ member.setHaveStore(true);
+ member.setStoreId(id);
+ memberService.updateById(member);
+
} else {
store.setStoreDisable(StoreStatusEnum.REFUSED.value());
}
@@ -194,6 +199,7 @@ public class StoreServiceImpl extends ServiceImpl implements
goodsService.underStoreGoods(id);
return this.updateById(store);
}
+
throw new ServiceException(ResultCode.STORE_NOT_EXIST);
}
@@ -285,26 +291,26 @@ public class StoreServiceImpl extends ServiceImpl implements
@Override
public void updateStoreGoodsNum(String storeId) {
//获取店铺已上架已审核通过商品数量
- Integer goodsNum=goodsService.count(new LambdaQueryWrapper()
- .eq(Goods::getStoreId,storeId)
+ Integer goodsNum = goodsService.count(new LambdaQueryWrapper()
+ .eq(Goods::getStoreId, storeId)
.eq(Goods::getIsAuth, GoodsAuthEnum.PASS.name())
.eq(Goods::getMarketEnable, GoodsStatusEnum.UPPER.name()));
//修改店铺商品数量
this.update(new LambdaUpdateWrapper()
- .set(Store::getGoodsNum,goodsNum)
- .eq(Store::getId,storeId));
+ .set(Store::getGoodsNum, goodsNum)
+ .eq(Store::getId, storeId));
}
@Override
public void updateStoreCollectionNum(String goodsId) {
- String storeId=goodsSkuService.getById(goodsId).getStoreId();
+ String storeId = goodsSkuService.getById(goodsId).getStoreId();
//获取店铺收藏数量
- Integer collectionNum=storeCollectionService.count(new LambdaQueryWrapper()
- .eq(StoreCollection::getStoreId,storeId));
+ Integer collectionNum = storeCollectionService.count(new LambdaQueryWrapper()
+ .eq(StoreCollection::getStoreId, storeId));
//修改店铺收藏数量
this.update(new LambdaUpdateWrapper()
- .set(Store::getCollectionNum,collectionNum)
- .eq(Store::getId,storeId));
+ .set(Store::getCollectionNum, collectionNum)
+ .eq(Store::getId, storeId));
}
/**
diff --git a/manager-api/src/main/java/cn/lili/controller/other/ElasticsearchController.java b/manager-api/src/main/java/cn/lili/controller/other/ElasticsearchController.java
index a5237cb1..25f8a32f 100644
--- a/manager-api/src/main/java/cn/lili/controller/other/ElasticsearchController.java
+++ b/manager-api/src/main/java/cn/lili/controller/other/ElasticsearchController.java
@@ -46,11 +46,14 @@ public class ElasticsearchController {
@GetMapping
public void init() {
+ //查询商品信息
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(GoodsSku::getIsAuth, GoodsAuthEnum.PASS.name());
queryWrapper.eq(GoodsSku::getMarketEnable, GoodsStatusEnum.UPPER.name());
+
List list = goodsSkuService.list(queryWrapper);
List esGoodsIndices = new ArrayList<>();
+ //库存锁是在redis做的,所以生成索引,同时更新一下redis中的库存数量
for (GoodsSku goodsSku : list) {
EsGoodsIndex index = new EsGoodsIndex(goodsSku);
Map goodsCurrentPromotionMap = promotionService.getGoodsCurrentPromotionMap(index);
@@ -58,6 +61,7 @@ public class ElasticsearchController {
esGoodsIndices.add(index);
stringRedisTemplate.opsForValue().set(GoodsSkuService.getStockCacheKey(goodsSku.getId()), goodsSku.getQuantity().toString());
}
+ //初始化商品索引
esGoodsIndexService.initIndex(esGoodsIndices);
Assertions.assertTrue(true);
}
diff --git a/pom.xml b/pom.xml
index b957fccf..038c1a81 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,6 @@
buyer-api
manager-api
seller-api
- socket-api
common-api
consumer
diff --git a/socket-api/pom.xml b/socket-api/pom.xml
deleted file mode 100644
index f798e24c..00000000
--- a/socket-api/pom.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
- 4.0.0
-
- socket-api
-
- cn.lili
- lili-shop-parent
- 1.0.1
-
-
-
-
- cn.lili
- framework
- 1.0.1
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
-
\ No newline at end of file
diff --git a/socket-api/src/main/java/cn/lili/SocketApiApplication.java b/socket-api/src/main/java/cn/lili/SocketApiApplication.java
deleted file mode 100644
index 947991d7..00000000
--- a/socket-api/src/main/java/cn/lili/SocketApiApplication.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package cn.lili;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
-
-/**
- * @author Chopper
- */
-@SpringBootApplication
-public class SocketApiApplication extends WebMvcConfigurerAdapter {
-
-
- public static void main(String[] args) {
-
- System.setProperty("es.set.netty.runtime.available.processors", "false");
- SpringApplication.run(SocketApiApplication.class, args);
- }
-
- @Override
- public void addCorsMappings(CorsRegistry registry) {
-
- registry.addMapping("/**")
- .allowCredentials(true)
- .allowedHeaders("*") //允许任何头
- .allowedOrigins("*") //允许任何域名
- .allowedMethods("*"); //允许任何方法
- }
-
-
-}
diff --git a/socket-api/src/main/java/cn/lili/scocket/listener/MessageSendListener.java b/socket-api/src/main/java/cn/lili/scocket/listener/MessageSendListener.java
deleted file mode 100644
index 8e26701a..00000000
--- a/socket-api/src/main/java/cn/lili/scocket/listener/MessageSendListener.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package cn.lili.scocket.listener;
-
-import cn.hutool.json.JSONUtil;
-import cn.lili.common.rocketmq.tags.OtherTagsEnum;
-import cn.lili.common.utils.BeanUtil;
-import cn.lili.modules.message.entity.dos.Message;
-import cn.lili.modules.message.entity.enums.MessageShowType;
-import cn.lili.modules.message.entity.vos.MessageShowVO;
-import cn.lili.modules.message.mapper.StoreMessageMapper;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.rocketmq.common.message.MessageExt;
-import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
-import org.apache.rocketmq.spring.core.RocketMQListener;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.messaging.simp.SimpMessagingTemplate;
-import org.springframework.stereotype.Component;
-import org.springframework.web.bind.annotation.CrossOrigin;
-
-/**
- * @author paulG
- * @since 2020/12/9
- **/
-@Component
-@CrossOrigin
-@Slf4j
-@RocketMQMessageListener(topic = "${lili.data.rocketmq.other-topic}", consumerGroup = "${lili.data.rocketmq.other-group}")
-public class MessageSendListener implements RocketMQListener {
-
-
-
- @Autowired
- private SimpMessagingTemplate simpMessagingTemplate;
-
- @Override
- public void onMessage(MessageExt messageExt) {
- log.info(messageExt.getTags());
- switch (OtherTagsEnum.valueOf(messageExt.getTags())) {
- //站内消息提醒
- case MESSAGE:
- System.out.println("消息提醒");
- sendNoticeMessage(messageExt);
- break;
- default:
- break;
- }
- }
-
- /**
- * 给商家发送站内信息
- *
- * @param messageExt
- */
- private void sendNoticeMessage(MessageExt messageExt) {
- MessageShowVO messageVO = new MessageShowVO();
- Message message = JSONUtil.toBean(new String(messageExt.getBody()), Message.class);
- //构建vo
- BeanUtil.copyProperties(message, messageVO);
- messageVO.setType(MessageShowType.NOTICE.name());
- if (message.getMessageRange().equals("ALL")) {
- simpMessagingTemplate.convertAndSend("/topic/subscribe", messageVO);
- } else {
- for (String id : message.getUserIds()) {
- simpMessagingTemplate.convertAndSendToUser("SHOP_" + id, "/queue/subscribe", messageVO);
- }
- }
- }
-}
diff --git a/socket-api/src/main/java/cn/lili/scocket/listener/ScoketSecurityConfig.java b/socket-api/src/main/java/cn/lili/scocket/listener/ScoketSecurityConfig.java
deleted file mode 100644
index 85eb8558..00000000
--- a/socket-api/src/main/java/cn/lili/scocket/listener/ScoketSecurityConfig.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package cn.lili.scocket.listener;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
-
-/**
- * spring Security 核心配置类 Store安全配置中心
- *
- * @author Chopper
- * @version v4.0
- * @Description:
- * @since 2020/11/14 16:20
- */
-@Slf4j
-@Configuration
-@EnableGlobalMethodSecurity(prePostEnabled = true)
-
-public class ScoketSecurityConfig extends WebSecurityConfigurerAdapter {
-
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
-
- ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry = http
- .authorizeRequests();
- registry.antMatchers("**").permitAll();
- }
-
-}
diff --git a/socket-api/src/main/resources/application.yml b/socket-api/src/main/resources/application.yml
deleted file mode 100644
index c10a84e8..00000000
--- a/socket-api/src/main/resources/application.yml
+++ /dev/null
@@ -1,298 +0,0 @@
-server:
- port: 8885
- servlet:
- context-path: /
-
- # 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
- # multipart:
- # location: /Users/lifenlong/Desktop/ceshi
- tomcat:
- uri-encoding: UTF-8
- threads:
- min-spare: 50
- max: 1000
-
-# 与Spring Boot 2一样,默认情况下,大多数端点都不通过http公开,我们公开了所有端点。对于生产,您应该仔细选择要公开的端点。
-management:
- # health:
- # elasticsearch:
- # enabled: false
- # datasource:
- # enabled: false
- endpoints:
- web:
- exposure:
- include: '*'
-spring:
- # 要在其中注册的Spring Boot Admin Server的URL。
- boot:
- admin:
- client:
- url: http://127.0.0.1:8000
- # mongodb
- data:
- mongodb:
- host: 127.0.0.1
- port: 27017
- database: lilishop
- username: root
- password: lilishop
- authentication-database: admin
- # replica-set-name: mongoreplset
- cache:
- type: redis
-
- jpa:
- # 自动生成表结构
- generate-ddl: true
- open-in-view: false
- # Redis
- redis:
- host: 127.0.0.1
- port: 6379
- password: lilishop
- lettuce:
- pool:
- # 连接池最大连接数(使用负值表示没有限制) 默认 8
- max-active: 200
- # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
- max-wait: 20
- # 连接池中的最大空闲连接 默认 8
- max-idle: 10
- # 连接池中的最小空闲连接 默认 8
- min-idle: 8
- # 文件大小上传配置
- servlet:
- multipart:
- max-file-size: 20MB
- max-request-size: 20MB
- jackson:
- time-zone: GMT+8
- serialization:
- #关闭jackson 对json做解析
- fail-on-empty-beans: false
-
- shardingsphere:
- datasource:
- # 数据库名称,可自定义,可以为多个,以逗号隔开,每个在这里定义的库,都要在下面定义连接属性
- names: default-datasource
- default-datasource:
- type: com.alibaba.druid.pool.DruidDataSource
- driverClassName: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://127.0.0.1:3306/lilishop?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
- username: root
- password: lilishop
- maxActive: 20
- initialSize: 5
- maxWait: 60000
- minIdle: 5
- timeBetweenEvictionRunsMillis: 60000
- minEvictableIdleTimeMillis: 300000
- validationQuery: SELECT 1 FROM DUAL
- testWhileIdle: true
- testOnBorrow: false
- testOnReturn: false
- #是否缓存preparedStatement,也就是PSCache。在mysql下建议关闭。 PSCache对支持游标的数据库性能提升巨大,比如说oracle。
- poolPreparedStatements: false
- #要启用PSCache,-1为关闭 必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true 可以把这个数值配置大一些,比如说100
- maxOpenPreparedStatements: -1
- #配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
- filters: stat,wall,log4j2
- #通过connectProperties属性来打开mergeSql功能;慢SQL记录
- connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
- #合并多个DruidDataSource的监控数据
- useGlobalDataSourceStat: true
- loginUsername: druid
- loginPassword: druid
- # sharding:
- # default-data-source-name: default-datasource
- # #需要拆分的表,可以设置多个 在 li_order 级别即可
- # tables:
- # #需要进行分表的逻辑表名
- # li_order:
- # #实际的表结点,下面代表的是li_order_为开头的所有表,如果能确定表的范围例如按月份分表,这里的写法是data2020.li_order_$->{2020..2021}_$->{01..12} 表示例如 li_order_2020_01 li_order_2020_03 li_order_2021_01
- # actual-data-nodes: data2020.li_order_$->{2019..2021}_$->{01..12}
- # table-strategy:
- # # 分表策略,根据创建日期
- # standard:
- # sharding-column: create_time
- # #分表策略
- # precise-algorithm-class-name: cn.lili.config.sharding.CreateTimeShardingTableAlgorithm
- # #范围查询实现
- # range-algorithm-class-name: cn.lili.config.sharding.CreateTimeShardingTableAlgorithm
- props:
- #是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭
- sql:
- show: true
-
-# 忽略鉴权url
-ignored:
- urls:
- - /editor-app/**
- - /actuator**
- - /actuator/**
- - /MP_verify_qSyvBPhDsPdxvOhC.txt
- - /weixin/**
- - /source/**
- - /buyer/mini-program/**
- - /buyer/cashier/**
- - /buyer/pageData/**
- - /buyer/article/**
- - /buyer/goods/**
- - /buyer/category/**
- - /buyer/shop/**
- - /buyer/connect/**
- - /buyer/members/smsLogin
- - /buyer/members/refresh/*
- - /buyer/members/refresh**
- - /buyer/promotion/pintuan
- - /buyer/promotion/seckill
- - /buyer/memberEvaluation/**/goodsEvaluation
- - /buyer/memberEvaluation/**/evaluationNumber
- - /store/login/**
- - /manager/user/login
- - /manager/user/refresh/**
- - /druid/**
- - /swagger-ui.html
- - /doc.html
- - /swagger-resources/**
- - /swagger/**
- - /**/**.js
- - /**/**.png
- - /**/**.css
- - /webjars/**
- - /v2/api-docs
- - /configuration/ui
- - /boot-admin
- statics:
- - /**/*.js
- - /**/*.css
- - /**/*.png
- - /**/*.ico
-
-# Swagger界面内容配置
-swagger:
- title: lili API接口文档
- description: lili Api Documentation
- version: 1.0.0
- termsOfServiceUrl: https://pickmall.cn
- contact:
- name: lili
- url: https://pickmall.cn
- email: admin@pickmall.com
-
-# Mybatis-plus
-mybatis-plus:
- mapper-locations: classpath*:mapper/*.xml
- configuration:
- #缓存开启
- cache-enabled: true
- #日志
-# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
-
-# 日志
-logging:
- # 输出级别
- level:
- cn.lili: info
- # org.hibernate: debug
- # org.springframework: debug
- # org.springframework.data.mongodb.core: debug
- file:
- # 指定路径
- path: lili-logs
- # 最大保存天数
- max-history: 7
- # 每个文件最大大小
- max-size: 5MB
-#加密参数
-jasypt:
- encryptor:
- password: lili
-
-lili:
- system:
- isDemoSite: true
- statistics:
- # 在线人数统计 X 小时。这里设置48,即统计过去48小时每小时在线人数
- onlineMember: 48
- # 当前在线人数刷新时间间隔,单位秒,设置为600,则每10分钟刷新一次
- currentOnlineUpdate: 600
- #qq lbs 申请
- lbs:
- key: 4BYBZ-7MT6S-PUAOA-6BNWL-FJUD7-UUFXT
- sk: zhNKVrJK6UPOhqIjn8AQvG37b9sz6
- #域名
- domain:
- pc: http://127.0.0.1:8888
- wap: http://127.0.0.1:8888
- seller: http://127.0.0.1:8888
- admin: http://127.0.0.1:8888
- #api地址
- api:
- buyer: https://z171l91606.51mypc.cn/
- base: http://127.0.0.1:8888
- manager: http://127.0.0.1:8888
- seller: http://127.0.0.1:8888
-
- # jwt 细节设定
- jwt-setting:
- # token过期时间(分钟)
- tokenExpireTime: 60
-
- # 使用Spring @Cacheable注解失效时间
- cache:
- # 过期时间 单位秒 永久不过期设为-1
- timeout: 1500
- #多线程配置
- thread:
- corePoolSize: 5
- maxPoolSize: 50
- queueCapacity: 50
- data:
- elasticsearch:
- cluster-name: elasticsearch
- cluster-nodes: 127.0.0.1:9200
- index:
- number-of-replicas: 0
- number-of-shards: 3
- index-prefix: lili
- schema: http
- # account:
- # username: elastic
- # password: LiLiShopES
-
- rocketmq:
- promotion-topic: lili_promotion_topic
- promotion-group: lili_promotion_group
- msg-ext-topic: lili_msg_topic
- msg-ext-group: lili_msg_group
- goods-topic: lili_goods_topic
- goods-group: lili_goods_group
- order-topic: lili_order_topic
- order-group: lili_order_group
- member-topic: lili_member_topic
- member-group: lili_member_group
- other-topic: lili_other_topic
- other-group: lili_other_group
- notice-topic: lili_notice_topic
- notice-group: lili_notice_group
- notice-send-topic: lili_send_notice_topic
- notice-send-group: lili_send_notice_group
-rocketmq:
- name-server: 127.0.0.1:9876
- producer:
- group: lili_group
- send-message-timeout: 30000
-
-xxl:
- job:
- admin:
- addresses: http://127.0.0.1:9001/xxl-job-admin
- executor:
- appname: xxl-job-executor-lilishop
- address:
- ip:
- port: 8891
- logpath: ./xxl-job/executor
- logretentiondays: 7
\ No newline at end of file