瀏覽代碼

commit message

Chopper 5 年之前
當前提交
3785bdb3bb
共有 100 個文件被更改,包括 5620 次插入0 次删除
  1. 43 0
      .gitignore
  2. 204 0
      README.md
  3. 33 0
      admin/.gitignore
  4. 118 0
      admin/.mvn/wrapper/MavenWrapperDownloader.java
  5. 二進制
      admin/.mvn/wrapper/maven-wrapper.jar
  6. 2 0
      admin/.mvn/wrapper/maven-wrapper.properties
  7. 44 0
      admin/pom.xml
  8. 50 0
      admin/src/main/java/cn/lili/admin/AdminApplication.java
  9. 20 0
      admin/src/main/resources/application.properties
  10. 38 0
      buyer-api/pom.xml
  11. 36 0
      buyer-api/src/main/java/cn/lili/BuyerApiApplication.java
  12. 23 0
      buyer-api/src/main/java/cn/lili/controller/SwaggerBootstrapUiDemoApplication.java
  13. 68 0
      buyer-api/src/main/java/cn/lili/controller/distribution/DistributionBuyerController.java
  14. 63 0
      buyer-api/src/main/java/cn/lili/controller/distribution/DistributionCashBuyerController.java
  15. 61 0
      buyer-api/src/main/java/cn/lili/controller/distribution/DistributionGoodsBuyerController.java
  16. 50 0
      buyer-api/src/main/java/cn/lili/controller/distribution/DistributionOrderBuyerController.java
  17. 44 0
      buyer-api/src/main/java/cn/lili/controller/goods/CategoryBuyerController.java
  18. 124 0
      buyer-api/src/main/java/cn/lili/controller/goods/GoodsBuyerController.java
  19. 98 0
      buyer-api/src/main/java/cn/lili/controller/member/CouponBuyerController.java
  20. 68 0
      buyer-api/src/main/java/cn/lili/controller/member/FootprintController.java
  21. 86 0
      buyer-api/src/main/java/cn/lili/controller/member/MemberAddressBuyerController.java
  22. 91 0
      buyer-api/src/main/java/cn/lili/controller/member/MemberCollectionController.java
  23. 78 0
      buyer-api/src/main/java/cn/lili/controller/member/MemberEvaluationBuyerController.java
  24. 56 0
      buyer-api/src/main/java/cn/lili/controller/member/MemberMessageBuyerController.java
  25. 60 0
      buyer-api/src/main/java/cn/lili/controller/member/MemberReceiptController.java
  26. 44 0
      buyer-api/src/main/java/cn/lili/controller/member/MemberSignBuyerController.java
  27. 130 0
      buyer-api/src/main/java/cn/lili/controller/member/MemberWalletBuyerController.java
  28. 45 0
      buyer-api/src/main/java/cn/lili/controller/member/MemberWithdrawApplyBuyerController.java
  29. 51 0
      buyer-api/src/main/java/cn/lili/controller/member/PointsHistoryBuyerController.java
  30. 46 0
      buyer-api/src/main/java/cn/lili/controller/member/RechargeBuyerController.java
  31. 58 0
      buyer-api/src/main/java/cn/lili/controller/member/ServiceNoticeBuyerController.java
  32. 72 0
      buyer-api/src/main/java/cn/lili/controller/other/ArticleBuyerController.java
  33. 44 0
      buyer-api/src/main/java/cn/lili/controller/other/FeedbackBuyerController.java
  34. 38 0
      buyer-api/src/main/java/cn/lili/controller/other/LogisticsBuyerController.java
  35. 48 0
      buyer-api/src/main/java/cn/lili/controller/other/PageBuyerController.java
  36. 160 0
      buyer-api/src/main/java/cn/lili/controller/passport/MemberBuyerController.java
  37. 56 0
      buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerBindController.java
  38. 98 0
      buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerWebController.java
  39. 72 0
      buyer-api/src/main/java/cn/lili/controller/passport/connect/MiniProgramBuyerController.java
  40. 104 0
      buyer-api/src/main/java/cn/lili/controller/payment/CashierController.java
  41. 38 0
      buyer-api/src/main/java/cn/lili/controller/payment/CashierRefundController.java
  42. 68 0
      buyer-api/src/main/java/cn/lili/controller/promotion/PintuanBuyerController.java
  43. 49 0
      buyer-api/src/main/java/cn/lili/controller/promotion/PointsGoodsBuyerController.java
  44. 49 0
      buyer-api/src/main/java/cn/lili/controller/promotion/SeckillBuyerController.java
  45. 75 0
      buyer-api/src/main/java/cn/lili/controller/purchase/PurchaseBuyerController.java
  46. 56 0
      buyer-api/src/main/java/cn/lili/controller/purchase/PurchaseQuotedController.java
  47. 110 0
      buyer-api/src/main/java/cn/lili/controller/store/StoreBuyerController.java
  48. 133 0
      buyer-api/src/main/java/cn/lili/controller/trade/AfterSaleBuyerController.java
  49. 240 0
      buyer-api/src/main/java/cn/lili/controller/trade/CartController.java
  50. 120 0
      buyer-api/src/main/java/cn/lili/controller/trade/OrderBuyerController.java
  51. 99 0
      buyer-api/src/main/java/cn/lili/controller/trade/OrderComplaintBuyerController.java
  52. 51 0
      buyer-api/src/main/java/cn/lili/controller/trade/ReceiptBuyerController.java
  53. 46 0
      buyer-api/src/main/java/cn/lili/controller/trade/RechargeTradeBuyerController.java
  54. 44 0
      buyer-api/src/main/java/cn/lili/controller/trade/WalletLogBuyerController.java
  55. 120 0
      buyer-api/src/main/java/cn/lili/security/BuyerAuthenticationFilter.java
  56. 86 0
      buyer-api/src/main/java/cn/lili/security/BuyerSecurityConfig.java
  57. 303 0
      buyer-api/src/main/resources/application.yml
  58. 19 0
      buyer-api/src/main/resources/banner.txt
  59. 1 0
      buyer-api/src/main/resources/static/MP_verify_qSyvBPhDsPdxvOhC.txt
  60. 75 0
      buyer-api/src/test/java/cn/lili/buyer/test/cart/CartTest.java
  61. 52 0
      buyer-api/src/test/java/cn/lili/buyer/test/cart/FileTest.java
  62. 29 0
      buyer-api/src/test/java/cn/lili/buyer/test/cart/MemberCouponTest.java
  63. 298 0
      buyer-api/src/test/resources/application.yml
  64. 33 0
      common-api/pom.xml
  65. 21 0
      common-api/src/main/java/cn/lili/CommonApiApplication.java
  66. 99 0
      common-api/src/main/java/cn/lili/controller/common/FileController.java
  67. 38 0
      common-api/src/main/java/cn/lili/controller/common/LogoController.java
  68. 59 0
      common-api/src/main/java/cn/lili/controller/common/RegionController.java
  69. 51 0
      common-api/src/main/java/cn/lili/controller/common/SliderImageController.java
  70. 53 0
      common-api/src/main/java/cn/lili/controller/common/SmsController.java
  71. 106 0
      common-api/src/main/java/cn/lili/controller/common/UploadController.java
  72. 68 0
      common-api/src/main/java/cn/lili/controller/security/CommonSecurityConfig.java
  73. 8 0
      common-api/src/main/resources/META-INF/additional-spring-configuration-metadata.json
  74. 299 0
      common-api/src/main/resources/application.yml
  75. 二進制
      common-api/src/main/resources/slider/images/1.jpg
  76. 二進制
      common-api/src/main/resources/slider/images/10.jpg
  77. 二進制
      common-api/src/main/resources/slider/images/11.jpg
  78. 二進制
      common-api/src/main/resources/slider/images/12.jpg
  79. 二進制
      common-api/src/main/resources/slider/images/13.jpg
  80. 二進制
      common-api/src/main/resources/slider/images/14.jpg
  81. 二進制
      common-api/src/main/resources/slider/images/15.jpg
  82. 二進制
      common-api/src/main/resources/slider/images/16.jpg
  83. 二進制
      common-api/src/main/resources/slider/images/17.jpg
  84. 二進制
      common-api/src/main/resources/slider/images/18.jpg
  85. 二進制
      common-api/src/main/resources/slider/images/19.jpg
  86. 二進制
      common-api/src/main/resources/slider/images/2.jpg
  87. 二進制
      common-api/src/main/resources/slider/images/20.jpg
  88. 二進制
      common-api/src/main/resources/slider/images/21.jpg
  89. 二進制
      common-api/src/main/resources/slider/images/22.jpg
  90. 二進制
      common-api/src/main/resources/slider/images/23.jpg
  91. 二進制
      common-api/src/main/resources/slider/images/3.jpg
  92. 二進制
      common-api/src/main/resources/slider/images/4.jpg
  93. 二進制
      common-api/src/main/resources/slider/images/5.jpg
  94. 二進制
      common-api/src/main/resources/slider/images/6.jpg
  95. 二進制
      common-api/src/main/resources/slider/images/7.jpg
  96. 二進制
      common-api/src/main/resources/slider/images/8.jpg
  97. 二進制
      common-api/src/main/resources/slider/images/9.jpg
  98. 二進制
      common-api/src/main/resources/slider/slider/1-w.png
  99. 二進制
      common-api/src/main/resources/slider/slider/2-w.png
  100. 二進制
      common-api/src/main/resources/slider/slider/3-w.png

+ 43 - 0
.gitignore

@@ -0,0 +1,43 @@
+/.idea/
+target
+*.iml
+*.class
+.DS_Store
+*.classpath
+*.project
+*.log
+.settings/
+.factorypath
+
+log/
+*.factorypath
+*.log
+lili-shop/src/main/java/cn/lili/generator/CodeGenerator.java
+lili-logs
+
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+
+### VS Code ###
+.vscode/

+ 204 - 0
README.md

@@ -0,0 +1,204 @@
+## Lilishop B2B2C商城系统
+
+### 介绍
+**官网**:https://pickmall.cn
+
+Lilishop 是一款Java开发,基于SpringBoot的B2B2C多用户商城,前端使用 Vue、uniapp-app开发 **系统全端全部代码开源**
+
+商城展示端包含 PC、H5、小程序、APP。
+
+商城包含 会员模块、**第三方登录模块**、**第三方支付模块**、**楼层装修模块**、订单模块、分销模块、文章模块、系统设置模块、流量分析模块
+
+系统包含各种中间件、搜索引擎、多级缓存、分布式事务、分布式任务调度等,支持Docker,支持k8s。是一款高性能,支持高并发等商城系统。
+
+开箱即用,简单配置即可部署一套属于您的系统。
+
+完美支持二开、学生毕业设计答辩等各个场景
+
+### 文档
+
+**产品文档**(需求、架构、使用、部署、开发):https://docs.pickmall.cn
+
+
+### 项目链接
+
+**Java后台**:https://gitee.com/beijing_hongye_huicheng/lili-shop.git
+
+**Vue后台前端**: https://gitee.com/beijing_hongye_huicheng/lili-shop-ui.git
+
+**Uni-app**:https://gitee.com/beijing_hongye_huicheng/lili-shop-uniapp.git
+
+**docker一键部署**:https://gitee.com/beijing_hongye_huicheng/docker.git
+
+### 演示地址
+
+**运营后台**:https://admin-b2b2c.pickmall.cn 账号:admin/123456
+
+**店铺后台**:https://store-b2b2c.pickmall.cn 账号:13011111111/111111
+
+**用户前台**:https://pc-b2b2c.pickmall.cn
+
+**移动端**:https://m-b2b2c.pickmall.cn
+
+![image-20210511171611793](https://pickmall.cn/assets/imgs/h5-qrcode.png)
+
+### 3行命令搭建本地环境
+
+#### 下载docker脚本
+`git clone https://gitee.com/beijing_hongye_huicheng/docker.git `
+##### 部署基础环境
+`docker-compose up -d`
+##### 部署应用
+`docker-compose -f docker-compose-application.yml up -d`
+
+### 交流群
+
+**QQ群**:961316482
+
+
+
+### 技术选型
+
+##### Java后台
+
+| 说明           | 框架            |
+| -------------- | --------------- |
+| 基础框架       | Spring Boot     |
+| MVC框架        | Spring MVC      |
+| 持久框架       | Mybatis-Plus    |
+| 程序构建       | Maven           |
+| 关系型数据库   | MySQL           |
+| 消息中间件AMQP | RocketMQ        |
+| 缓存           | Redis +MongoDB  |
+| 搜索引擎       | Elasticsearch   |
+| 安全框架       | Spring Security |
+| 数据库连接池   | Druid           |
+| 数据库分库分表 | sharding        |
+| 定时任务       | xxl-job         |
+| 负载均衡       | Nginx           |
+| 静态资源       | 阿里云OSS       |
+| 短信           | 阿里云短信      |
+| 日志处理       | Log4j           |
+| 接口规范       | RESTful         |
+| 接口文档       | Swagger         |
+| 认证           | JWT             |
+
+##### 前端-运营后台、店铺后台
+
+| 说明       | 框架       |
+| ---------- | ---------- |
+| 构建工具   | webpack    |
+| JS版本     | ES6        |
+| 基础JS框架 | Vue.js     |
+| 视频播放器 | Dplayer    |
+| 路由管理   | Vue Router |
+| 状态管理   | Vuex       |
+| 基础UI库   | iView      |
+| UI界面基于 | iView      |
+| 网络请求   | axios      |
+| CSS预处理  | scss       |
+| 代码检查   | ESLint     |
+| 数据可视化 | AntV g2    |
+| 地图引擎   | amap       |
+
+##### 前端-移动端
+
+| 说明      | 架构    |
+| --------- | ------- |
+| 基础UI库  | uViewui |
+| 基础框架  | uni-app |
+| CSS预处理 | scss    |
+| 地图引擎  | amap    |
+
+
+
+### 功能列表
+
+<table>
+  <tr><td colspan="2">运营后台功能</td></tr>
+  <tr><td>首页</td><td>平台统计、待办事项、流量统计</td></tr>
+  <tr><td rowspan="5">会员</td><td>会员列表</td></tr>
+  <tr><td>评价列表</td></tr>
+  <tr><td>积分历史</td></tr>
+  <tr><td>会员资金</td></tr>
+  <tr><td>充值记录</td></tr>
+  <tr><td rowspan="6">订单</td><td>商品订单</td></tr>
+  <tr><td>订单售后</td></tr>
+  <tr><td>交易投诉</td></tr>
+  <tr><td>售后原因</td></tr>
+  <tr><td>收款流水</td></tr>
+  <tr><td>退款流水</td></tr>
+  <tr><td rowspan="6">商品</td><td>商品列表</td></tr>
+  <tr><td>商品审核</td></tr>
+  <tr><td>商品分类</td></tr>
+  <tr><td>商品品牌</td></tr>
+  <tr><td>商品规格</td></tr>
+  <tr><td>计量单位</td></tr>
+  <tr><td rowspan="5">促销</td><td>优惠券</td></tr>
+  <tr><td>秒杀活动</td></tr>
+  <tr><td>拼团活动</td></tr>
+  <tr><td>积分商品</td></tr>
+  <tr><td>积分分类</td></tr>
+  <tr><td rowspan="5">店铺</td><td>店铺管理</td></tr>
+  <tr><td>店铺结算</td></tr>
+  <tr><td>店铺结算</td></tr>
+  <tr><td>店铺结算</td></tr>
+  <tr><td>店铺对账</td></tr>
+  <tr><td rowspan="9">运营</td><td>店铺对账</td></tr>
+  <tr><td>PC端楼层装修</td></tr>
+  <tr><td>移动端楼层装修</td></tr>
+  <tr><td>分销管理</td></tr>
+  <tr><td>文章管理</td></tr>
+  <tr><td>意见反馈</td></tr>
+  <tr><td>站内信</td></tr>
+   <tr><td>短信管理</td></tr>
+   <tr><td>APP版本管理</td></tr>
+   <tr><td rowspan="4">统计</td><td>会员统计</td></tr>
+   <tr><td>订单统计</td></tr>
+   <tr><td>商品统计</td></tr>
+   <tr><td>流量统计</td></tr>
+   <tr><td rowspan="11">设置</td><td>用户管理</td></tr>
+   <tr><td>菜单管理</td></tr>
+   <tr><td>部门管理</td></tr>
+   <tr><td>系统设置</td></tr>
+   <tr><td>OSS资源</td></tr>
+   <tr><td>行政地区</td></tr>
+   <tr><td>物流公司</td></tr>
+   <tr><td>信任登录</td></tr>
+   <tr><td>支付设置</td></tr>
+   <tr><td>验证码管理</td></tr>
+   <tr><td>敏感词管理</td></tr>
+</table>
+
+<table>
+  <tr><td colspan="2">店铺后台功能列表</td></tr>
+  <tr><td rowspan="3">首页</td><td>店铺信息</td></tr>
+  <tr><td>待办事项</td></tr>
+  <tr><td>平台公告</td></tr>
+  <tr><td rowspan="3">商品</td><td>商品发布</td></tr>
+  <tr><td>商品列表</td></tr>
+  <tr><td>店铺商品分类</td></tr>
+  <tr><td rowspan="5">订单</td><td>商品订单</td></tr>
+  <tr><td>退货管理</td></tr>
+  <tr><td>退款管理</td></tr>
+  <tr><td>投诉管理</td></tr>
+  <tr><td>评价管理</td></tr>
+  <tr><td rowspan="3">财务</td><td>财务对账</td></tr>
+  <tr><td>店铺结算</td></tr>
+  <tr><td>发票管理</td></tr>
+  <tr><td rowspan="5">促销</td><td>拼团管理</td></tr>
+  <tr><td>秒杀活动</td></tr>
+  <tr><td>满额活动</td></tr>
+  <tr><td>优惠券</td></tr>
+  <tr><td>分销商品</td></tr>
+  <tr><td rowspan="2">统计</td><td>商品统计</td></tr>
+  <tr><td>订单统计</td></tr>
+  <tr><td rowspan="5">设置</td><td>配送模板</td></tr>
+  <tr><td>物流公司</td></tr>
+  <tr><td>店铺设置</td></tr>
+  <tr><td>自提点管理</td></tr>
+  <tr><td>系统消息</td></tr>
+</table>
+
+### 授权
+Lilishop学习免费,限制商用,如果需要商业使用请联系我们。QQ3409056806

+ 33 - 0
admin/.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 118 - 0
admin/.mvn/wrapper/MavenWrapperDownloader.java

@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+    private static final String WRAPPER_VERSION = "0.5.6";
+    /**
+     * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+     */
+    private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+            + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+    /**
+     * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+     * use instead of the default one.
+     */
+    private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+            ".mvn/wrapper/maven-wrapper.properties";
+
+    /**
+     * Path where the maven-wrapper.jar will be saved to.
+     */
+    private static final String MAVEN_WRAPPER_JAR_PATH =
+            ".mvn/wrapper/maven-wrapper.jar";
+
+    /**
+     * Name of the property which should be used to override the default download url for the wrapper.
+     */
+    private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+    public static void main(String args[]) {
+        System.out.println("- Downloader started");
+        File baseDirectory = new File(args[0]);
+        System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+        // If the maven-wrapper.properties exists, read it and check if it contains a custom
+        // wrapperUrl parameter.
+        File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+        String url = DEFAULT_DOWNLOAD_URL;
+        if (mavenWrapperPropertyFile.exists()) {
+            FileInputStream mavenWrapperPropertyFileInputStream = null;
+            try {
+                mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+                Properties mavenWrapperProperties = new Properties();
+                mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+                url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+            } catch (IOException e) {
+                System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+            } finally {
+                try {
+                    if (mavenWrapperPropertyFileInputStream != null) {
+                        mavenWrapperPropertyFileInputStream.close();
+                    }
+                } catch (IOException e) {
+                    // Ignore ...
+                }
+            }
+        }
+        System.out.println("- Downloading from: " + url);
+
+        File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+        if (!outputFile.getParentFile().exists()) {
+            if (!outputFile.getParentFile().mkdirs()) {
+                System.out.println(
+                        "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+            }
+        }
+        System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+        try {
+            downloadFileFromURL(url, outputFile);
+            System.out.println("Done");
+            System.exit(0);
+        } catch (Throwable e) {
+            System.out.println("- Error downloading");
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+        if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+            String username = System.getenv("MVNW_USERNAME");
+            char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+            Authenticator.setDefault(new Authenticator() {
+                @Override
+                protected PasswordAuthentication getPasswordAuthentication() {
+                    return new PasswordAuthentication(username, password);
+                }
+            });
+        }
+        URL website = new URL(urlString);
+        ReadableByteChannel rbc;
+        rbc = Channels.newChannel(website.openStream());
+        FileOutputStream fos = new FileOutputStream(destination);
+        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+        fos.close();
+        rbc.close();
+    }
+
+}

二進制
admin/.mvn/wrapper/maven-wrapper.jar


+ 2 - 0
admin/.mvn/wrapper/maven-wrapper.properties

@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

+ 44 - 0
admin/pom.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>cn.lili</groupId>
+        <artifactId>lili-shop-parent</artifactId>
+        <version>1.0.1</version>
+    </parent>
+
+    <artifactId>admin</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>de.codecentric</groupId>
+            <artifactId>spring-boot-admin-starter-server</artifactId>
+            <version>2.3.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-mail</artifactId>-->
+<!--        </dependency> -->
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 50 - 0
admin/src/main/java/cn/lili/admin/AdminApplication.java

@@ -0,0 +1,50 @@
+package cn.lili.admin;
+
+import de.codecentric.boot.admin.server.config.AdminServerProperties;
+import de.codecentric.boot.admin.server.config.EnableAdminServer;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
+
+import java.util.UUID;
+
+@Configuration
+@EnableAutoConfiguration
+@EnableAdminServer
+public class AdminApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(AdminApplication.class, args);
+    }
+
+    @Configuration
+    public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
+
+        private final AdminServerProperties adminServer;
+
+        public SecuritySecureConfig(AdminServerProperties adminServer) {
+            this.adminServer = adminServer;
+        }
+
+        @Override
+        protected void configure(HttpSecurity http) throws Exception {
+            SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
+            successHandler.setTargetUrlParameter("redirectTo");
+            successHandler.setDefaultTargetUrl(this.adminServer.path("/"));
+            http.authorizeRequests().antMatchers("/instances**").permitAll();
+            http.authorizeRequests(
+                    (authorizeRequests) -> authorizeRequests.antMatchers(this.adminServer.path("/assets/**")).permitAll() // 授予公众对所有静态资产和登录页面的访问权限。
+                            .antMatchers(this.adminServer.path("/login")).permitAll().anyRequest().authenticated() //其他所有请求都必须经过验证。
+            ).formLogin(
+                    (formLogin) -> formLogin.loginPage(this.adminServer.path("/login")).successHandler(successHandler).and() // 	配置登录和注销。
+            ).logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout"))).httpBasic(Customizer.withDefaults()) // 启用HTTP基本支持。这是Spring Boot Admin Client注册所必需的。
+                    .csrf().disable()
+                    .rememberMe((rememberMe) -> rememberMe.key(UUID.randomUUID().toString()).tokenValiditySeconds(1209600));
+        }
+
+    }
+}

+ 20 - 0
admin/src/main/resources/application.properties

@@ -0,0 +1,20 @@
+# 应用程序名称
+spring.application.name=SpringBootAdmin
+# 应用程序端口
+server.port=8000
+management.endpoints.web.exposure.include=*
+management.endpoint.health.show-details=always
+#账号密码
+spring.security.user.name=admin
+spring.security.user.password=admin
+spring.mail.host=smtp.qq.com
+# to和from都要配置,否则发送邮件时会报错
+spring.boot.admin.notify.mail.to=1814994716@qq.com
+spring.boot.admin.notify.mail.from=1814994716@qq.com
+# 邮件的用户名和密码
+spring.mail.username=1814994716@qq.com
+spring.mail.password=abcdefg123456!@#$%^
+# 日志文件路径
+logging.file.path=lili-logs/admin
+# 文件格式
+logging.pattern.file=%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx

+ 38 - 0
buyer-api/pom.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+        <properties>
+            <enjoy.version>4.3</enjoy.version>
+        </properties>
+    <artifactId>buyer-api</artifactId>
+    <parent>
+        <groupId>cn.lili</groupId>
+        <artifactId>lili-shop-parent</artifactId>
+        <version>1.0.1</version>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>cn.lili</groupId>
+            <artifactId>framework</artifactId>
+            <version>1.0.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.jfinal</groupId>
+            <artifactId>enjoy</artifactId>
+            <version>${enjoy.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 36 - 0
buyer-api/src/main/java/cn/lili/BuyerApiApplication.java

@@ -0,0 +1,36 @@
+package cn.lili;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.task.TaskExecutor;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+/**
+ * 买家API
+ *
+ * @author Chopper
+ * @date 2020/11/16 10:03 下午
+ */
+@SpringBootApplication
+@EnableJpaAuditing
+@EnableCaching
+@EnableAsync
+public class BuyerApiApplication {
+
+
+    @Primary
+    @Bean
+    public TaskExecutor primaryTaskExecutor() {
+        return new ThreadPoolTaskExecutor();
+    }
+
+    public static void main(String[] args) {
+        System.setProperty("es.set.netty.runtime.available.processors", "false");
+        SpringApplication.run(BuyerApiApplication.class, args);
+    }
+}

+ 23 - 0
buyer-api/src/main/java/cn/lili/controller/SwaggerBootstrapUiDemoApplication.java

@@ -0,0 +1,23 @@
+package cn.lili.controller;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import springfox.documentation.spring.web.SpringfoxWebMvcConfiguration;
+
+/**
+ * SwaggerBootstrapUiDemoApplication
+ *
+ * @author Chopper
+ * @version v1.0
+ * 2020-12-09 20:09
+ */
+@ConditionalOnClass(SpringfoxWebMvcConfiguration.class)
+public class SwaggerBootstrapUiDemoApplication  implements WebMvcConfigurer {
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+    }
+}

+ 68 - 0
buyer-api/src/main/java/cn/lili/controller/distribution/DistributionBuyerController.java

@@ -0,0 +1,68 @@
+package cn.lili.controller.distribution;
+
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.distribution.entity.dos.Distribution;
+import cn.lili.modules.distribution.entity.dos.DistributionOrder;
+import cn.lili.modules.distribution.entity.vos.DistributionOrderSearchParams;
+import cn.lili.modules.distribution.service.DistributionOrderService;
+import cn.lili.modules.distribution.service.DistributionService;
+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 lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * 买家端,分销员接口
+ *
+ * @author pikachu
+ * @date: 2020/11/16 10:03 下午
+ */
+@RestController
+@Api(tags = "买家端,分销员接口")
+@RequestMapping("/buyer/distribution")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class DistributionBuyerController {
+
+    /**
+     * 分销员
+     */
+    private final DistributionService distributionService;
+    /**
+     * 分销员订单
+     */
+    private final DistributionOrderService distributionOrderService;
+
+    //申请分销员
+    @ApiOperation(value = "申请分销员")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "name", value = "姓名", required = true, paramType = "query", dataType = "String"),
+            @ApiImplicitParam(name = "idNumber", value = "身份证号", required = true, paramType = "query", dataType = "String")
+    })
+    @PostMapping
+    public ResultMessage<Object> applyDistribution(@RequestParam String name, @RequestParam String idNumber) {
+        return ResultUtil.data(distributionService.applyDistribution(name, idNumber));
+    }
+
+    @ApiOperation(value = "获取分销员分页订单列表")
+    @GetMapping("/distributionOrder")
+    public ResultMessage<IPage<DistributionOrder>> distributionOrderPage(DistributionOrderSearchParams distributionOrderSearchParams) {
+        distributionOrderSearchParams.setDistributionId(UserContext.getCurrentUser().getId());
+        return ResultUtil.data(distributionOrderService.getDistributionOrderPage(distributionOrderSearchParams));
+    }
+
+    @ApiOperation(value = "获取当前会员的分销员信息", notes = "可根据分销员信息查询待提现金额以及冻结金额等信息")
+    @GetMapping
+    public ResultMessage<Distribution> getDistribution() {
+        //检查分销开关
+        distributionService.checkDistributionSetting();
+
+        return ResultUtil.data(distributionService.getDistribution());
+    }
+}

+ 63 - 0
buyer-api/src/main/java/cn/lili/controller/distribution/DistributionCashBuyerController.java

@@ -0,0 +1,63 @@
+package cn.lili.controller.distribution;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.distribution.entity.dos.DistributionCash;
+import cn.lili.modules.distribution.service.DistributionCashService;
+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 lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.constraints.NotNull;
+
+
+/**
+ * 买家端,分销商品佣金提现接口
+ *
+ * @author pikachu
+ * @date: 2020/11/16 10:03 下午
+ */
+@RestController
+@Api(tags = "买家端,分销商品佣金提现接口")
+@RequestMapping("/buyer/distribution/cash")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class DistributionCashBuyerController {
+
+    /**
+     * 分销佣金
+     */
+    private final DistributionCashService distributionCashService;
+    /**
+     * 分销员提现
+     */
+    private final DistributionCashService distributorCashService;
+
+
+    @ApiOperation(value = "分销员提现")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "price", value = "申请金额", required = true, paramType = "query", dataType = "double")
+    })
+    @PostMapping
+    public ResultMessage<Boolean> cash(@NotNull @ApiIgnore Double price) {
+        Boolean result = distributionCashService.cash(price);
+        return ResultUtil.data(result);
+    }
+
+    @ApiOperation(value = "分销员提现历史")
+    @GetMapping
+    public ResultMessage<IPage<DistributionCash>> casHistory(PageVO page) {
+        return ResultUtil.data(distributorCashService.getDistributionCash(page));
+    }
+
+
+}

+ 61 - 0
buyer-api/src/main/java/cn/lili/controller/distribution/DistributionGoodsBuyerController.java

@@ -0,0 +1,61 @@
+package cn.lili.controller.distribution;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.distribution.entity.dto.DistributionGoodsSearchParams;
+import cn.lili.modules.distribution.entity.vos.DistributionGoodsVO;
+import cn.lili.modules.distribution.service.DistributionGoodsService;
+import cn.lili.modules.distribution.service.DistributionSelectedGoodsService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 买家端,分销商品接口
+ *
+ * @author Bulbasaur
+ * @date: 2020/11/16 10:06 下午
+ */
+@RestController
+@Api(tags = "买家端,分销商品接口")
+@RequestMapping("/buyer/distributionGoods")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class DistributionGoodsBuyerController {
+
+    /**
+     * 分销商品
+     */
+    private final DistributionGoodsService distributionGoodsService;
+    /**
+     * 选择分销商品
+     */
+    private final DistributionSelectedGoodsService distributionSelectedGoodsService;
+
+
+    @ApiOperation(value = "获取分销商商品列表")
+    @GetMapping
+    public ResultMessage<IPage<DistributionGoodsVO>> distributionGoods(DistributionGoodsSearchParams distributionGoodsSearchParams) {
+        return ResultUtil.data(distributionGoodsService.goodsPage(distributionGoodsSearchParams));
+    }
+
+    @ApiOperation(value = "选择分销商品")
+    @ApiImplicitParam(name = "distributionGoodsId", value = "分销ID", required = true, dataType = "String", paramType = "path")
+    @GetMapping(value = "/checked/{distributionGoodsId}")
+    public ResultMessage<IPage<DistributionGoodsVO>> distributionCheckGoods(
+            @NotNull(message = "分销商品不能为空") @PathVariable("distributionGoodsId") String distributionGoodsId) {
+        if (distributionSelectedGoodsService.add(distributionGoodsId)) {
+            return ResultUtil.success(ResultCode.SUCCESS);
+        }
+        return ResultUtil.error(ResultCode.ERROR);
+    }
+}

+ 50 - 0
buyer-api/src/main/java/cn/lili/controller/distribution/DistributionOrderBuyerController.java

@@ -0,0 +1,50 @@
+package cn.lili.controller.distribution;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.distribution.entity.dos.DistributionOrder;
+import cn.lili.modules.distribution.entity.vos.DistributionOrderSearchParams;
+import cn.lili.modules.distribution.service.DistributionOrderService;
+import cn.lili.modules.distribution.service.DistributionService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+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 pikachu
+ * @date: 2020/11/16 10:03 下午
+ */
+@RestController
+@Api(tags = "买家端,分销订单接口")
+@RequestMapping("/buyer/distribution/order")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class DistributionOrderBuyerController {
+
+    /**
+     * 分销订单
+     */
+    private final DistributionOrderService distributionOrderService;
+    /**
+     * 分销员
+     */
+    private final DistributionService distributionService;
+
+
+    @ApiOperation(value = "分销员订单")
+    @GetMapping
+    public ResultMessage<IPage<DistributionOrder>> casHistory(DistributionOrderSearchParams distributionOrderSearchParams) {
+        //获取当前登录的分销员
+        distributionOrderSearchParams.setDistributionId(distributionService.getDistribution().getId());
+        return ResultUtil.data(distributionOrderService.getDistributionOrderPage(distributionOrderSearchParams));
+    }
+
+
+}

+ 44 - 0
buyer-api/src/main/java/cn/lili/controller/goods/CategoryBuyerController.java

@@ -0,0 +1,44 @@
+package cn.lili.controller.goods;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.goods.entity.vos.CategoryVO;
+import cn.lili.modules.goods.service.CategoryService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+
+/**
+ * 买家端,商品分类接口
+ *
+ * @author Chopper
+ * @date: 2020/11/16 10:05 下午
+ */
+@RestController
+@Api(tags = "买家端,商品分类接口")
+@RequestMapping("/buyer/category")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class CategoryBuyerController {
+    /**
+     * 商品分类
+     */
+    private final CategoryService categoryService;
+
+    @ApiOperation(value = "获取商品分类列表")
+    @ApiImplicitParam(name = "parentId", value = "上级分类ID,全部分类为:0", required = true, dataType = "Long", paramType = "path")
+    @GetMapping(value = "/get/{parentId}")
+    public ResultMessage<List<CategoryVO>> list(@NotNull(message = "分类ID不能为空") @PathVariable String parentId) {
+
+        return ResultUtil.data(categoryService.listAllChildren(parentId));
+    }
+}

+ 124 - 0
buyer-api/src/main/java/cn/lili/controller/goods/GoodsBuyerController.java

@@ -0,0 +1,124 @@
+package cn.lili.controller.goods;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.distribution.service.DistributionService;
+import cn.lili.modules.goods.entity.dos.Goods;
+import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
+import cn.lili.modules.goods.entity.vos.GoodsVO;
+import cn.lili.modules.goods.service.GoodsService;
+import cn.lili.modules.goods.service.GoodsSkuService;
+import cn.lili.modules.search.entity.dos.EsGoodsIndex;
+import cn.lili.modules.search.entity.dos.EsGoodsRelatedInfo;
+import cn.lili.modules.search.entity.dto.EsGoodsSearchDTO;
+import cn.lili.modules.search.service.EsGoodsSearchService;
+import cn.lili.modules.statistics.aop.PageViewPoint;
+import cn.lili.modules.statistics.aop.enums.PageViewEnum;
+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 lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 买家端,商品接口
+ *
+ * @author Chopper
+ * @date 2020/11/16 10:06 下午
+ */
+@Api(tags = "买家端,商品接口")
+@RestController
+@RequestMapping("/buyer/goods")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class GoodsBuyerController {
+
+    /**
+     * 商品
+     */
+    private final GoodsService goodsService;
+    /**
+     * 商品SKU
+     */
+    private final GoodsSkuService goodsSkuService;
+    /**
+     * ES商品搜索
+     */
+    private final EsGoodsSearchService goodsSearchService;
+    /**
+     * 分销员
+     */
+    private final DistributionService distributionService;
+
+
+    @ApiOperation(value = "通过id获取商品信息")
+    @ApiImplicitParam(name = "goodsId", value = "商品ID", required = true, paramType = "path", dataType = "Long")
+    @GetMapping(value = "/get/{goodsId}")
+    public ResultMessage<GoodsVO> get(@NotNull(message = "商品ID不能为空") @PathVariable("goodsId") String id) {
+        return ResultUtil.data(goodsService.getGoodsVO(id));
+    }
+
+    @ApiOperation(value = "通过id获取商品信息")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "goodsId", value = "商品ID", required = true, paramType = "path"),
+            @ApiImplicitParam(name = "skuId", value = "skuId", required = true, paramType = "path"),
+            @ApiImplicitParam(name = "distributionId", value = "分销员ID", dataType = "String", paramType = "query")
+    })
+    @GetMapping(value = "/sku/{goodsId}/{skuId}")
+    @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,
+                                                     String distributionId) {
+
+        Map<String, Object> map = goodsSkuService.getGoodsSkuDetail(goodsId, skuId);
+
+        //判断如果传递分销员则进行记录
+        if (CharSequenceUtil.isNotEmpty(distributionId)) {
+            distributionService.bindingDistribution(distributionId);
+        }
+
+        return ResultUtil.data(map);
+    }
+
+    @ApiOperation(value = "获取商品分页列表")
+    @GetMapping
+    public ResultMessage<IPage<Goods>> getByPage(GoodsSearchParams goodsSearchParams) {
+        return ResultUtil.data(goodsService.queryByParams(goodsSearchParams));
+    }
+
+    @ApiOperation(value = "从ES中获取商品信息")
+    @GetMapping("/es")
+    public ResultMessage<Page<EsGoodsIndex>> getGoodsByPageFromEs(EsGoodsSearchDTO goodsSearchParams, PageVO pageVO) {
+        pageVO.setNotConvert(true);
+        Page<EsGoodsIndex> esGoodsIndices = goodsSearchService.searchGoods(goodsSearchParams, pageVO);
+        return ResultUtil.data(esGoodsIndices);
+    }
+
+    @ApiOperation(value = "从ES中获取相关商品品牌名称,分类名称及属性")
+    @GetMapping("/es/related")
+    public ResultMessage<EsGoodsRelatedInfo> getGoodsRelatedByPageFromEs(EsGoodsSearchDTO goodsSearchParams, PageVO pageVO) {
+        pageVO.setNotConvert(true);
+        EsGoodsRelatedInfo selector = goodsSearchService.getSelector(goodsSearchParams, pageVO);
+        return ResultUtil.data(selector);
+    }
+
+    @ApiOperation(value = "获取搜索热词")
+    @GetMapping("/hot-words")
+    public ResultMessage<List<String>> getGoodsHotWords(Integer start, Integer end) {
+        List<String> hotWords = goodsSearchService.getHotWords(start, end);
+        return ResultUtil.data(hotWords);
+    }
+
+}

+ 98 - 0
buyer-api/src/main/java/cn/lili/controller/member/CouponBuyerController.java

@@ -0,0 +1,98 @@
+package cn.lili.controller.member;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.promotion.entity.dos.MemberCoupon;
+import cn.lili.modules.promotion.entity.vos.CouponSearchParams;
+import cn.lili.modules.promotion.entity.vos.CouponVO;
+import cn.lili.modules.promotion.service.CouponService;
+import cn.lili.modules.promotion.service.MemberCouponService;
+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 lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 买家端,买家优惠券接口
+ *
+ * @author paulG
+ * @date 2020/11/17 3:35 下午
+ */
+@RestController
+@Api(tags = "买家端,买家优惠券接口")
+@RequestMapping("/buyer/promotion/coupon")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class CouponBuyerController {
+
+    /**
+     * 优惠券
+     */
+    private final CouponService couponService;
+
+    /**
+     * 会员优惠券
+     */
+    private final MemberCouponService memberCouponService;
+
+    @GetMapping
+    @ApiOperation(value = "获取可领取优惠券列表")
+    public ResultMessage<IPage<CouponVO>> getCouponList(CouponSearchParams queryParam, PageVO page) {
+        IPage<CouponVO> canUseCoupons = couponService.getCanReceiveCoupons(queryParam, page);
+        return ResultUtil.data(canUseCoupons);
+    }
+
+    @ApiOperation(value = "获取当前会员的优惠券列表")
+    @GetMapping("/getCoupons")
+    public ResultMessage<IPage<MemberCoupon>> getCoupons(CouponSearchParams param, PageVO pageVo) {
+        param.setMemberId(UserContext.getCurrentUser().getId());
+        return ResultUtil.data(memberCouponService.getMemberCoupons(param, pageVo));
+    }
+
+    @ApiOperation(value = "获取当前会员的对于当前商品可使用的优惠券列表")
+    @GetMapping("/canUse")
+    public ResultMessage<IPage<MemberCoupon>> getCouponsByCanUse(CouponSearchParams param, Double totalPrice, PageVO pageVo) {
+        param.setMemberId(UserContext.getCurrentUser().getId());
+        return ResultUtil.data(memberCouponService.getMemberCouponsByCanUse(param, totalPrice, pageVo));
+    }
+
+    @ApiOperation(value = "获取当前会员可使用的优惠券数量")
+    @GetMapping("/getCouponsNum")
+    public ResultMessage<Object> getMemberCouponsNum() {
+        return ResultUtil.data(memberCouponService.getMemberCouponsNum());
+    }
+
+    @ApiOperation(value = "会员领取优惠券")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "couponId", value = "优惠券ID", required = true, dataType = "Long", paramType = "path")
+    })
+    @GetMapping("/receive/{couponId}")
+    public ResultMessage<Object> receiveCoupon(@NotNull(message = "优惠券ID不能为空") @PathVariable("couponId") String couponId) {
+        memberCouponService.checkCouponLimit(couponId, UserContext.getCurrentUser().getId());
+        memberCouponService.receiveCoupon(couponId, UserContext.getCurrentUser().getId(), UserContext.getCurrentUser().getNickName());
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+    @ApiOperation(value = "通过id获取")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "优惠券ID", required = true, dataType = "Long", paramType = "path")
+    })
+    @GetMapping(value = "/get/{id}")
+    public ResultMessage<MemberCoupon> get(@NotNull(message = "优惠券ID不能为空") @PathVariable("id") String id) {
+        MemberCoupon memberCoupon = memberCouponService.getById(id);
+        return ResultUtil.data(memberCoupon);
+    }
+
+
+}

+ 68 - 0
buyer-api/src/main/java/cn/lili/controller/member/FootprintController.java

@@ -0,0 +1,68 @@
+package cn.lili.controller.member;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.member.service.FootprintService;
+import cn.lili.modules.search.entity.dos.EsGoodsIndex;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+
+/**
+ * 买家端,浏览历史接口
+ *
+ * @author Chopper
+ * @date: 2020/11/16 10:06 下午
+ */
+@RestController
+@Api(tags = "买家端,浏览历史接口")
+@RequestMapping("/buyer/footprint")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class FootprintController {
+
+    /**
+     * 会员足迹
+     */
+    private final FootprintService footprintService;
+
+    @ApiOperation(value = "分页获取")
+    @GetMapping
+    public ResultMessage<List<EsGoodsIndex>> getByPage(PageVO page) {
+        return ResultUtil.data(footprintService.footPrintPage(page));
+    }
+
+    @ApiOperation(value = "根据id删除")
+    @ApiImplicitParam(name = "ids", value = "商品ID", required = true, allowMultiple = true, dataType = "String", paramType = "path")
+    @DeleteMapping(value = "/delByIds/{ids}")
+    public ResultMessage<Object> delAllByIds(@NotNull(message = "商品ID不能为空") @PathVariable("ids") List ids) {
+        if (footprintService.deleteByIds(ids)) {
+            return ResultUtil.success(ResultCode.SUCCESS);
+        }
+        return ResultUtil.error(ResultCode.ERROR);
+    }
+
+    @ApiOperation(value = "清空足迹")
+    @DeleteMapping
+    public ResultMessage<Object> deleteAll() {
+        if (footprintService.clean()) {
+            return ResultUtil.success(ResultCode.SUCCESS);
+        }
+        return ResultUtil.error(ResultCode.ERROR);
+    }
+
+    @ApiOperation(value = "获取当前会员足迹数量")
+    @GetMapping(value = "/getFootprintNum")
+    public ResultMessage<Object> getFootprintNum() {
+        return ResultUtil.data(footprintService.getFootprintNum());
+    }
+
+}

+ 86 - 0
buyer-api/src/main/java/cn/lili/controller/member/MemberAddressBuyerController.java

@@ -0,0 +1,86 @@
+package cn.lili.controller.member;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.base.service.RegionService;
+import cn.lili.modules.member.entity.dos.MemberAddress;
+import cn.lili.modules.promotion.service.MemberAddressService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+
+/**
+ * 买家端,会员地址接口
+ *
+ * @author Bulbasaur
+ * @date: 2020/11/16 10:07 下午
+ */
+@RestController
+@Api(tags = "买家端,会员地址接口")
+@RequestMapping("/buyer/memberAddress")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MemberAddressBuyerController {
+
+    /**
+     * 会员收件地址
+     */
+    private final MemberAddressService memberAddressService;
+
+    private final RegionService regionService;
+
+    @ApiOperation(value = "获取会员收件地址分页列表")
+    @GetMapping
+    public ResultMessage<IPage<MemberAddress>> page(PageVO page) {
+        return ResultUtil.data(memberAddressService.getAddressByMember(page, UserContext.getCurrentUser().getId()));
+    }
+
+    @ApiOperation(value = "根据ID获取会员收件地址")
+    @ApiImplicitParam(name = "id", value = "会员地址ID", dataType = "String", paramType = "path")
+    @GetMapping(value = "/get/{id}")
+    public ResultMessage<MemberAddress> getShippingAddress(@PathVariable String id) {
+        return ResultUtil.data(memberAddressService.getMemberAddress(id));
+    }
+
+    @ApiOperation(value = "获取当前会员默认收件地址")
+    @GetMapping(value = "/get/default")
+    public ResultMessage<MemberAddress> getDefaultShippingAddress() {
+        return ResultUtil.data(memberAddressService.getDefaultMemberAddress());
+    }
+
+    @ApiOperation(value = "新增会员收件地址")
+    @PostMapping
+    public ResultMessage<MemberAddress> addShippingAddress(@Valid MemberAddress shippingAddress) {
+        //添加会员地址
+        shippingAddress.setMemberId(UserContext.getCurrentUser().getId());
+        return ResultUtil.data(memberAddressService.saveMemberAddress(shippingAddress));
+    }
+
+    @ApiOperation(value = "修改会员收件地址")
+    @PutMapping
+    public ResultMessage<MemberAddress> editShippingAddress(@Valid MemberAddress shippingAddress) {
+        //修改会员地址
+        shippingAddress.setMemberId(UserContext.getCurrentUser().getId());
+        return ResultUtil.data(memberAddressService.updateMemberAddress(shippingAddress));
+    }
+
+    @ApiOperation(value = "删除会员收件地址")
+    @ApiImplicitParam(name = "id", value = "会员地址ID", dataType = "String", paramType = "path")
+    @DeleteMapping(value = "/delById/{id}")
+    public ResultMessage<Object> delShippingAddressById(@PathVariable String id) {
+        if (memberAddressService.removeMemberAddress(id)) {
+            return ResultUtil.success(ResultCode.SUCCESS);
+        }
+        return ResultUtil.error(ResultCode.ERROR);
+    }
+
+}

+ 91 - 0
buyer-api/src/main/java/cn/lili/controller/member/MemberCollectionController.java

@@ -0,0 +1,91 @@
+package cn.lili.controller.member;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.member.service.GoodsCollectionService;
+import cn.lili.modules.member.service.StoreCollectionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 买家端,会员收藏接口
+ *
+ * @author Chopper
+ * @date: 2020/11/17 2:32 下午
+ */
+@RestController
+@Api(tags = "买家端,会员收藏接口")
+@RequestMapping("/buyer/member/collection")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MemberCollectionController {
+
+    /**
+     * 会员商品收藏
+     */
+    private final GoodsCollectionService goodsCollectionService;
+    /**
+     * 会员店铺
+     */
+    private final StoreCollectionService storeCollectionService;
+
+    @ApiOperation(value = "查询会员收藏列表")
+    @ApiImplicitParam(name = "type", value = "类型", dataType = "String", paramType = "path", example = "GOODS:商品,STORE:店铺")
+    @GetMapping("/{type}")
+    public ResultMessage<Object> goodsList(@PathVariable String type, PageVO page) {
+        if (type.equals("GOODS")) {
+            return ResultUtil.data(goodsCollectionService.goodsCollection(page));
+        }
+        return ResultUtil.data(storeCollectionService.storeCollection(page));
+    }
+
+    @ApiOperation(value = "添加会员收藏")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "type", value = "类型", dataType = "String", paramType = "path", example = "GOODS:商品,STORE:店铺"),
+            @ApiImplicitParam(name = "num", value = "值", dataType = "Long", paramType = "path")
+    })
+    @PostMapping("/add/{type}/{id}")
+    public ResultMessage<Object> addGoodsCollection(@PathVariable String type,
+                                                    @NotNull(message = "值不能为空") @PathVariable String id) {
+        if (type.equals("GOODS")) {
+            return ResultUtil.data(goodsCollectionService.addGoodsCollection(id));
+        }
+        return ResultUtil.data(storeCollectionService.addStoreCollection(id));
+
+    }
+
+    @ApiOperation(value = "删除会员收藏")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "type", value = "类型", dataType = "String", paramType = "path", example = "GOODS:商品,STORE:店铺"),
+            @ApiImplicitParam(name = "num", value = "值", dataType = "Long", paramType = "path")
+    })
+    @DeleteMapping(value = "/delete/{type}/{id}")
+    public ResultMessage<Object> deleteGoodsCollection(@PathVariable String type,
+                                                       @NotNull(message = "值不能为空") @PathVariable String id) {
+        if (type.equals("GOODS")) {
+            return ResultUtil.data(goodsCollectionService.deleteGoodsCollection(id));
+        }
+        return ResultUtil.data(storeCollectionService.deleteStoreCollection(id));
+    }
+
+    @ApiOperation(value = "查询会员是否收藏")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "type", value = "类型", dataType = "String", paramType = "path", example = "GOODS:商品,STORE:店铺"),
+            @ApiImplicitParam(name = "id", value = "值", dataType = "String", paramType = "path")
+    })
+    @GetMapping(value = "/isCollection/{type}/{id}")
+    public ResultMessage<Boolean> isCollection(@PathVariable String type,
+                                               @NotNull(message = "值不能为空") @PathVariable String id) {
+        if (type.equals("GOODS")) {
+            return ResultUtil.data(this.goodsCollectionService.isCollection(id));
+        }
+        return ResultUtil.data(this.storeCollectionService.isCollection(id));
+    }
+}

+ 78 - 0
buyer-api/src/main/java/cn/lili/controller/member/MemberEvaluationBuyerController.java

@@ -0,0 +1,78 @@
+package cn.lili.controller.member;
+
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.member.entity.dos.MemberEvaluation;
+import cn.lili.modules.member.entity.dto.EvaluationQueryParams;
+import cn.lili.modules.member.entity.dto.MemberEvaluationDTO;
+import cn.lili.modules.member.entity.vo.EvaluationNumberVO;
+import cn.lili.modules.member.entity.vo.MemberEvaluationVO;
+import cn.lili.modules.member.service.MemberEvaluationService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 买家端,会员商品评价接口
+ *
+ * @author Bulbasaur
+ * @date: 2020/11/16 10:08 下午
+ */
+@RestController
+@Api(tags = "买家端,会员商品评价接口")
+@RequestMapping("/buyer/memberEvaluation")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MemberEvaluationBuyerController {
+
+    /**
+     * 会员商品评价
+     */
+    private final MemberEvaluationService memberEvaluationService;
+
+    @ApiOperation(value = "添加会员评价")
+    @PostMapping
+    public ResultMessage<MemberEvaluationDTO> save(@Valid MemberEvaluationDTO memberEvaluationDTO) {
+        return ResultUtil.data(memberEvaluationService.addMemberEvaluation(memberEvaluationDTO));
+    }
+
+    @ApiOperation(value = "查看会员评价详情")
+    @ApiImplicitParam(name = "id", value = "评价ID", required = true, paramType = "path")
+    @GetMapping(value = "/get/{id}")
+    public ResultMessage<MemberEvaluationVO> save(@NotNull(message = "评价ID不能为空") @PathVariable("id") String id) {
+        return ResultUtil.data(memberEvaluationService.queryById(id));
+
+    }
+
+    @ApiOperation(value = "查看当前会员评价列表")
+    @GetMapping
+    public ResultMessage<IPage<MemberEvaluation>> queryMineEvaluation(EvaluationQueryParams evaluationQueryParams) {
+        //设置当前登录会员
+        evaluationQueryParams.setMemberId(UserContext.getCurrentUser().getId());
+        return ResultUtil.data(memberEvaluationService.queryByParams(evaluationQueryParams));
+    }
+
+    @ApiOperation(value = "查看某一个商品的评价列表")
+    @ApiImplicitParam(name = "goodsId", value = "商品ID", required = true, dataType = "Long", paramType = "path")
+    @GetMapping(value = "/{goodsId}/goodsEvaluation")
+    public ResultMessage<IPage<MemberEvaluation>> queryGoodsEvaluation(EvaluationQueryParams evaluationQueryParams,
+                                                                       @NotNull @PathVariable("goodsId") String goodsId) {
+        //设置查询查询商品
+        evaluationQueryParams.setGoodsId(goodsId);
+        return ResultUtil.data(memberEvaluationService.queryByParams(evaluationQueryParams));
+    }
+
+    @ApiOperation(value = "查看某一个商品的评价数量")
+    @ApiImplicitParam(name = "goodsId", value = "商品ID", required = true, dataType = "Long", paramType = "path")
+    @GetMapping(value = "/{goodsId}/evaluationNumber")
+    public ResultMessage<EvaluationNumberVO> queryEvaluationNumber(@NotNull @PathVariable("goodsId") String goodsId) {
+        return ResultUtil.data(memberEvaluationService.getEvaluationNumber(goodsId));
+    }
+}

+ 56 - 0
buyer-api/src/main/java/cn/lili/controller/member/MemberMessageBuyerController.java

@@ -0,0 +1,56 @@
+package cn.lili.controller.member;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.message.entity.enums.MessageStatusEnum;
+import cn.lili.modules.member.entity.dos.MemberMessage;
+import cn.lili.modules.member.entity.vo.MemberMessageQueryVO;
+import cn.lili.modules.member.service.MemberMessageService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 买家端,会员站内消息接口
+ *
+ * @author Bulbasaur
+ * @date: 2020/11/16 10:07 下午
+ */
+@RestController
+@Api(tags = "买家端,会员站内消息接口")
+@RequestMapping("/buyer/member/message")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MemberMessageBuyerController {
+
+    /**
+     * 会员站内消息
+     */
+    private final MemberMessageService memberMessageService;
+
+    @ApiOperation(value = "分页获取会员站内消息")
+    @GetMapping
+    public ResultMessage<IPage<MemberMessage>> page(MemberMessageQueryVO memberMessageQueryVO, PageVO page) {
+        return ResultUtil.data(memberMessageService.getPage(memberMessageQueryVO, page));
+    }
+
+    @ApiOperation(value = "消息已读")
+    @ApiImplicitParam(name = "messageId", value = "会员消息id", required = true, paramType = "path")
+    @PutMapping
+    public ResultMessage<Boolean> read(@PathVariable String messageId) {
+        return ResultUtil.data(memberMessageService.editStatus(MessageStatusEnum.ALREADY_READY.name(), messageId));
+    }
+
+    @ApiOperation(value = "消息删除")
+    @ApiImplicitParam(name = "messageId", value = "会员消息id", required = true, paramType = "path")
+    @DeleteMapping
+    public ResultMessage<Boolean> deleteMessage(@PathVariable String messageId) {
+        return ResultUtil.data(memberMessageService.deleteMessage(messageId));
+    }
+
+
+}

+ 60 - 0
buyer-api/src/main/java/cn/lili/controller/member/MemberReceiptController.java

@@ -0,0 +1,60 @@
+package cn.lili.controller.member;
+
+
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.member.entity.vo.MemberReceiptAddVO;
+import cn.lili.modules.member.entity.vo.MemberReceiptVO;
+import cn.lili.modules.member.service.MemberReceiptService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * 买家端,会员发票接口
+ *
+ * @author paulG
+ * @date: 2021-03-29 14:10:16
+ */
+@RestController
+@Api(tags = "买家端,会员发票接口")
+@RequestMapping("/buyer/member/receipt")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MemberReceiptController {
+
+    private final MemberReceiptService memberReceiptService;
+
+    @ApiOperation(value = "查询会员发票列表")
+    @GetMapping
+    public ResultMessage<Object> page(MemberReceiptVO memberReceiptVO, PageVO page) {
+        return ResultUtil.data(memberReceiptService.getPage(memberReceiptVO, page));
+    }
+
+    @ApiOperation(value = "新增会员发票")
+    @PostMapping
+    public ResultMessage<Object> add(MemberReceiptAddVO memberReceiptAddVO) {
+        return ResultUtil.data(memberReceiptService.addMemberReceipt(memberReceiptAddVO, UserContext.getCurrentUser().getId()));
+    }
+
+    @ApiOperation(value = "修改会员发票")
+    @ApiImplicitParam(name = "id", value = "会员发票id", required = true, paramType = "path")
+    @PutMapping
+    public ResultMessage<Object> update(@PathVariable String id, MemberReceiptAddVO memberReceiptAddVO) {
+        memberReceiptAddVO.setId(id);
+        return ResultUtil.data(memberReceiptService.editMemberReceipt(memberReceiptAddVO, id));
+    }
+
+    @ApiOperation(value = "会员发票删除")
+    @ApiImplicitParam(name = "id", value = "会员发票id", required = true, paramType = "path")
+    @DeleteMapping
+    public ResultMessage<Boolean> deleteMessage(@PathVariable String id) {
+        return ResultUtil.data(memberReceiptService.deleteMemberReceipt(id));
+    }
+
+}

+ 44 - 0
buyer-api/src/main/java/cn/lili/controller/member/MemberSignBuyerController.java

@@ -0,0 +1,44 @@
+package cn.lili.controller.member;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.member.entity.dos.MemberSign;
+import cn.lili.modules.member.service.MemberSignService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 会员签到控制器
+ *
+ * @author pikachu
+ * @date: 2020/11/16 10:07 下午
+ */
+@RestController
+@Api(tags = "买家端,会员签到API")
+@RequestMapping("/buyer/members/sign")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MemberSignBuyerController {
+
+    private final MemberSignService memberSignService;
+
+    @PostMapping
+    @ApiOperation(value = "会员签到")
+    public ResultMessage<Boolean> memberSign() {
+        return ResultUtil.data(memberSignService.memberSign());
+    }
+
+    @GetMapping
+    @ApiOperation(value = "根据时间查询会员签到表,类型是YYYYmm")
+    public ResultMessage<List<MemberSign>> memberSign(String time) {
+        return ResultUtil.data(memberSignService.getMonthSignDay(time));
+    }
+
+}

+ 130 - 0
buyer-api/src/main/java/cn/lili/controller/member/MemberWalletBuyerController.java

@@ -0,0 +1,130 @@
+package cn.lili.controller.member;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.exception.ServiceException;
+import cn.lili.common.security.AuthUser;
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.verification.enums.VerificationEnums;
+import cn.lili.common.verification.service.VerificationService;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.member.entity.dos.Member;
+import cn.lili.modules.member.entity.dos.MemberWallet;
+import cn.lili.modules.member.entity.vo.MemberWalletVO;
+import cn.lili.modules.member.service.MemberService;
+import cn.lili.modules.member.service.MemberWalletService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Pattern;
+
+/**
+ * 买家端,会员余额接口
+ *
+ * @author pikachu
+ * @date: 2020/11/16 10:07 下午
+ */
+@RestController
+@Api(tags = "买家端,会员余额接口")
+@RequestMapping("/buyer/members/wallet")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MemberWalletBuyerController {
+
+    /**
+     * 会员
+     */
+    private final MemberService memberService;
+    /**
+     * 会员余额
+     */
+    private final MemberWalletService memberWalletService;
+    /**
+     * 验证码
+     */
+    private final VerificationService verificationService;
+
+    @GetMapping
+    @ApiOperation(value = "查询会员预存款余额")
+    public ResultMessage<MemberWalletVO> get() {
+        AuthUser authUser = UserContext.getCurrentUser();
+        if (authUser != null) {
+            return ResultUtil.data(memberWalletService.getMemberWallet(authUser.getId()));
+        }
+        throw new ServiceException(ResultCode.USER_NOT_LOGIN);
+    }
+
+    @PostMapping(value = "/set-password")
+    @ApiOperation(value = "设置支付密码")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "password", value = "支付密码", required = true, dataType = "String", paramType = "query")
+    })
+    public ResultMessage<Object> setPassword(String password, @RequestHeader String uuid) {
+        AuthUser authUser = UserContext.getCurrentUser();
+        //校验当前用户是否存在
+        Member member = memberService.getById(authUser.getId());
+        if (member == null) {
+            throw new ServiceException(ResultCode.USER_NOT_EXIST);
+        }
+        //校验验证码
+        if (verificationService.check(uuid, VerificationEnums.WALLET_PASSWORD)) {
+            memberWalletService.setMemberWalletPassword(member, password);
+            return ResultUtil.error(ResultCode.SUCCESS);
+        } else {
+            return ResultUtil.error(ResultCode.VERIFICATION_ERROR);
+        }
+
+    }
+
+    @PostMapping(value = "/update-password/ordinary")
+    @ApiOperation(value = "普通方式进行支付密码的修改")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "oldPassword", value = "旧支付密码", required = true, dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "newPassword", value = "新支付密码", required = true, dataType = "String", paramType = "query")
+    })
+    public ResultMessage updatePassword(@RequestParam @Pattern(regexp = "[a-fA-F0-9]{32}", message = "旧密码格式不正确") String oldPassword,
+                                        @RequestParam @Pattern(regexp = "[a-fA-F0-9]{32}", message = "新密码格式不正确") String newPassword) {
+        AuthUser authUser = UserContext.getCurrentUser();
+        //校验当前用户是否存在
+        Member member = memberService.getById(authUser.getId());
+        if (member == null) {
+            throw new ServiceException(ResultCode.USER_NOT_EXIST);
+        }
+        MemberWallet memberWallet = this.memberWalletService.getOne(new QueryWrapper<MemberWallet>().eq("member_id", member.getId()));
+        //校验新旧密码是否一致
+        if (memberWallet != null) {
+            if (!new BCryptPasswordEncoder().matches(oldPassword, memberWallet.getWalletPassword())) {
+                throw new ServiceException(ResultCode.USER_OLD_PASSWORD_ERROR);
+            }
+            this.memberWalletService.setMemberWalletPassword(member, newPassword);
+            return ResultUtil.data("修改成功");
+        }
+        throw new ServiceException(ResultCode.ERROR);
+    }
+
+
+    @GetMapping(value = "/check")
+    @ApiOperation(value = "检测会员是否设置过支付密码,会员中心设置或者修改密码时使用")
+    public Boolean checkPassword() {
+        return memberWalletService.checkPassword();
+    }
+
+
+    @PostMapping(value = "/withdrawal")
+    @ApiOperation(value = "会员中心余额提现")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "price", value = "提现金额", required = true, dataType = "double", paramType = "query")
+    })
+    public ResultMessage<Boolean> withdrawal(@Max(value = 1000, message = "充值金额单次最多允许提现1000元") @Min(value = 1, message = "充值金额单次最少提现金额为1元") Double price) {
+        return ResultUtil.data(memberWalletService.applyWithdrawal(price));
+    }
+
+}

+ 45 - 0
buyer-api/src/main/java/cn/lili/controller/member/MemberWithdrawApplyBuyerController.java

@@ -0,0 +1,45 @@
+package cn.lili.controller.member;
+
+
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.member.entity.dos.MemberWithdrawApply;
+import cn.lili.modules.member.entity.vo.MemberWithdrawApplyQueryVO;
+import cn.lili.modules.member.service.MemberWithdrawApplyService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * 买家端,余额提现记录接口
+ *
+ * @author pikachu
+ * @date: 2020/11/16 10:07 下午
+ */
+@RestController
+@Api(tags = "买家端,余额提现记录接口")
+@RequestMapping("/buyer/member/withdrawApply")
+@Transactional(rollbackFor = Exception.class)
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MemberWithdrawApplyBuyerController {
+
+    private final MemberWithdrawApplyService memberWithdrawApplyService;
+
+
+    @ApiOperation(value = "分页获取提现记录")
+    @GetMapping
+    public ResultMessage<IPage<MemberWithdrawApply>> getByPage(PageVO page, MemberWithdrawApplyQueryVO memberWithdrawApplyQueryVO) {
+        memberWithdrawApplyQueryVO.setMemberId(UserContext.getCurrentUser().getId());
+        //构建查询 返回数据
+        IPage<MemberWithdrawApply> memberWithdrawApplyIPage = memberWithdrawApplyService.getMemberWithdrawPage(page, memberWithdrawApplyQueryVO);
+        return ResultUtil.data(memberWithdrawApplyIPage);
+    }
+
+}

+ 51 - 0
buyer-api/src/main/java/cn/lili/controller/member/PointsHistoryBuyerController.java

@@ -0,0 +1,51 @@
+package cn.lili.controller.member;
+
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.PageUtil;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.member.entity.dos.MemberPointsHistory;
+import cn.lili.modules.member.entity.vo.MemberPointsHistoryVO;
+import cn.lili.modules.member.service.MemberPointsHistoryService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+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 2020-02-25 14:10:16
+ */
+@RestController
+@Api(tags = "买家端,会员积分历史接口")
+@RequestMapping("/buyer/member/memberPointsHistory")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class PointsHistoryBuyerController {
+
+    private final MemberPointsHistoryService memberPointsHistoryService;
+
+    @ApiOperation(value = "分页获取")
+    @GetMapping(value = "/getByPage")
+    public ResultMessage<IPage<MemberPointsHistory>> getByPage(PageVO page) {
+
+        LambdaQueryWrapper<MemberPointsHistory> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(MemberPointsHistory::getMemberId, UserContext.getCurrentUser().getId());
+
+        return ResultUtil.data(memberPointsHistoryService.page(PageUtil.initPage(page), queryWrapper));
+    }
+
+    @ApiOperation(value = "获取会员积分VO")
+    @GetMapping(value = "/getMemberPointsHistoryVO")
+    public ResultMessage<MemberPointsHistoryVO> getMemberPointsHistoryVO() {
+        return ResultUtil.data(memberPointsHistoryService.getMemberPointsHistoryVO(UserContext.getCurrentUser().getId()));
+    }
+}

+ 46 - 0
buyer-api/src/main/java/cn/lili/controller/member/RechargeBuyerController.java

@@ -0,0 +1,46 @@
+package cn.lili.controller.member;
+
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.order.trade.entity.dos.Recharge;
+import cn.lili.modules.order.trade.entity.vo.RechargeQueryVO;
+import cn.lili.modules.order.trade.service.RechargeService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 买家端,预存款充值记录接口
+ *
+ * @author pikachu
+ * @date: 2020/11/16 10:07 下午
+ */
+@RestController
+@Api(tags = "买家端,预存款充值记录接口")
+@RequestMapping("/buyer/member/recharge")
+@Transactional(rollbackFor = Exception.class)
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class RechargeBuyerController {
+
+    @Autowired
+    private RechargeService rechargeService;
+
+    @ApiOperation(value = "分页获取预存款充值记录")
+    @GetMapping
+    public ResultMessage<IPage<Recharge>> getByPage(PageVO page) {
+        //构建查询参数
+        RechargeQueryVO rechargeQueryVO = new RechargeQueryVO();
+        rechargeQueryVO.setMemberId(UserContext.getCurrentUser().getId());
+        //构建查询 返回数据
+        IPage<Recharge> rechargePage = rechargeService.rechargePage(page, rechargeQueryVO);
+        return ResultUtil.data(rechargePage);
+    }
+}

+ 58 - 0
buyer-api/src/main/java/cn/lili/controller/member/ServiceNoticeBuyerController.java

@@ -0,0 +1,58 @@
+package cn.lili.controller.member;
+
+import cn.lili.common.utils.PageUtil;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.system.entity.dos.ServiceNotice;
+import cn.lili.modules.system.service.ServiceNoticeService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * 买家端,会员站服务消息接口
+ *
+ * @author Chopper
+ * @date: 2020/11/17 2:31 下午
+ */
+@RestController
+@RequestMapping("/service/notice")
+@Api(tags = "买家端,会员站服务消息接口")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class ServiceNoticeBuyerController {
+
+    /**
+     * 服务消息
+     */
+    private final ServiceNoticeService serviceNoticeService;
+
+    @ApiOperation(value = "获取消息详情")
+    @ApiImplicitParam(name = "id", value = "商品ID", required = true, dataType = "Long", paramType = "path")
+    @GetMapping(value = "/{id}")
+    public ResultMessage<ServiceNotice> get(@PathVariable String id) {
+        ServiceNotice serviceNotice = serviceNoticeService.getById(id);
+        return ResultUtil.data(serviceNotice);
+    }
+
+    @ApiOperation(value = "分页获取服务消息")
+    @GetMapping
+    @ApiImplicitParam(name = "storeId", value = "商家id,默认为-1,代表平台消息,如果查询某商家发布的消息,传递商家id即可", dataType = "int", paramType = "query")
+    public ResultMessage<IPage<ServiceNotice>> getByPage(PageVO page, String storeId) {
+        ServiceNotice serviceNotice = new ServiceNotice();
+        if (storeId == null) {
+            storeId = "-1";
+        }
+        serviceNotice.setStoreId(storeId);
+        IPage<ServiceNotice> data = serviceNoticeService.page(PageUtil.initPage(page));
+        return ResultUtil.data(data);
+    }
+}

+ 72 - 0
buyer-api/src/main/java/cn/lili/controller/other/ArticleBuyerController.java

@@ -0,0 +1,72 @@
+package cn.lili.controller.other;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.page.entity.dos.Article;
+import cn.lili.modules.page.entity.dto.ArticleSearchParams;
+import cn.lili.modules.page.entity.vos.ArticleCategoryVO;
+import cn.lili.modules.page.entity.vos.ArticleVO;
+import cn.lili.modules.page.service.ArticleCategoryService;
+import cn.lili.modules.page.service.ArticleService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 买家端,文章接口
+ *
+ * @author Chopper
+ * @date: 2020/11/16 10:02 下午
+ */
+@RestController
+@Api(tags = "买家端,文章接口")
+@RequestMapping("/buyer/article")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class ArticleBuyerController {
+
+    /**
+     * 文章
+     */
+    private final ArticleService articleService;
+
+    /**
+     * 文章分类
+     */
+    private final ArticleCategoryService articleCategoryService;
+
+    @ApiOperation(value = "获取文章分类列表")
+    @GetMapping(value = "/articleCategory/list")
+    public ResultMessage<List<ArticleCategoryVO>> getArticleCategoryList() {
+        return ResultUtil.data(articleCategoryService.allChildren());
+    }
+
+    @ApiOperation(value = "分页获取")
+    @GetMapping
+    public ResultMessage<IPage<ArticleVO>> getByPage(ArticleSearchParams articleSearchParams) {
+        return ResultUtil.data(articleService.articlePage(articleSearchParams));
+    }
+
+    @ApiOperation(value = "通过id获取文章")
+    @ApiImplicitParam(name = "id", value = "文章ID", required = true, paramType = "path")
+    @GetMapping(value = "/get/{id}")
+    public ResultMessage<Article> get(@NotNull(message = "文章ID") @PathVariable("id") String id) {
+        return ResultUtil.data(articleService.customGet(id));
+    }
+
+    @ApiOperation(value = "通过类型获取文章")
+    @ApiImplicitParam(name = "type", value = "文章类型", required = true, paramType = "path")
+    @GetMapping(value = "/type/{type}")
+    public ResultMessage<Article> getByType(@NotNull(message = "文章类型") @PathVariable("type") String type) {
+        return ResultUtil.data(articleService.customGetByType(type));
+    }
+}

+ 44 - 0
buyer-api/src/main/java/cn/lili/controller/other/FeedbackBuyerController.java

@@ -0,0 +1,44 @@
+package cn.lili.controller.other;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.page.entity.dos.Feedback;
+import cn.lili.modules.page.service.FeedbackService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 买家端,意见反馈接口
+ *
+ * @author Bulbasaur
+ * @date 2020-05-5 15:10:16
+ */
+@RestController
+@Api(tags = "买家端,意见反馈接口")
+@RequestMapping("/buyer/feedback")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class FeedbackBuyerController {
+
+    /**
+     * 意见反馈
+     */
+    private final FeedbackService feedbackService;
+
+    @ApiOperation(value = "添加意见反馈")
+    @PostMapping()
+    public ResultMessage<Object> save(Feedback feedback) {
+        feedback.setUserName(UserContext.getCurrentUser().getNickName());
+        if (feedbackService.save(feedback)) {
+            return ResultUtil.success(ResultCode.SUCCESS);
+        }
+        return ResultUtil.error(ResultCode.ERROR);
+    }
+
+}

+ 38 - 0
buyer-api/src/main/java/cn/lili/controller/other/LogisticsBuyerController.java

@@ -0,0 +1,38 @@
+package cn.lili.controller.other;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.system.entity.dos.Logistics;
+import cn.lili.modules.system.service.LogisticsService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+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;
+
+import java.util.List;
+
+/**
+ * 买家端,物流公司接口
+ *
+ * @author Bulbasaur
+ * @date 2020-05-5 15:10:16
+ */
+@RestController
+@Api(tags = "买家端,物流公司接口")
+@RequestMapping("/buyer/logistics")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class LogisticsBuyerController {
+
+    private final LogisticsService logisticsService;
+
+
+    @ApiOperation(value = "分页获取物流公司")
+    @GetMapping
+    public ResultMessage<List<Logistics>> getByPage() {
+        return ResultUtil.data(logisticsService.getOpenLogistics());
+    }
+
+}

+ 48 - 0
buyer-api/src/main/java/cn/lili/controller/other/PageBuyerController.java

@@ -0,0 +1,48 @@
+package cn.lili.controller.other;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.page.entity.dto.PageDataDTO;
+import cn.lili.modules.page.entity.enums.PageEnum;
+import cn.lili.modules.page.entity.vos.PageDataVO;
+import cn.lili.modules.page.service.PageDataService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+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.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 买家端,页面接口
+ *
+ * @author Chopper
+ * @date 2020/11/16 10:08 下午
+ */
+@RestController
+@Api(tags = "买家端,页面接口")
+@RequestMapping("/buyer/pageData")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class PageBuyerController {
+
+    /**
+     * 页面管理
+     */
+    private final PageDataService pageService;
+
+    @ApiOperation(value = "获取首页数据")
+    @GetMapping("/getIndex")
+    public ResultMessage<PageDataVO> getIndex(@RequestParam String clientType) {
+        PageDataDTO pageDataDTO = new PageDataDTO(PageEnum.INDEX.name());
+        pageDataDTO.setPageClientType(clientType);
+        return ResultUtil.data(pageService.getPageData(pageDataDTO));
+    }
+
+    @ApiOperation(value = "获取页面数据")
+    @GetMapping
+    public ResultMessage<PageDataVO> get(PageDataDTO pageDataDTO) {
+        return ResultUtil.data(pageService.getPageData(pageDataDTO));
+    }
+}

+ 160 - 0
buyer-api/src/main/java/cn/lili/controller/passport/MemberBuyerController.java

@@ -0,0 +1,160 @@
+package cn.lili.controller.passport;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.sms.SmsUtil;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.verification.enums.VerificationEnums;
+import cn.lili.common.verification.service.VerificationService;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.member.entity.dos.Member;
+import cn.lili.modules.member.entity.dto.MemberEditDTO;
+import cn.lili.modules.member.service.MemberService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 买家端,会员接口
+ *
+ * @author Chopper
+ * @date: 2020/11/16 10:07 下午
+ */
+@RestController
+@Api(tags = "买家端,会员接口")
+@RequestMapping("/buyer/members")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MemberBuyerController {
+
+    /**
+     * 会员
+     */
+    private final MemberService memberService;
+
+    private final SmsUtil smsUtil;
+
+    private final VerificationService verificationService;
+
+
+    @ApiOperation(value = "登录接口")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "username", value = "用户名", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query")
+    })
+    @PostMapping("/userLogin")
+    public ResultMessage<Object> userLogin(@NotNull(message = "用户名不能为空") @RequestParam String username,
+                                           @NotNull(message = "密码不能为空") @RequestParam String password,
+                                           @RequestHeader String uuid) {
+        if (verificationService.check(uuid, VerificationEnums.LOGIN)) {
+            return ResultUtil.data(this.memberService.usernameLogin(username, password));
+        } else {
+            return ResultUtil.error(ResultCode.VERIFICATION_ERROR);
+        }
+    }
+
+    @ApiOperation(value = "短信登录接口")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "mobile", value = "手机号", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "code", value = "验证码", required = true, paramType = "query")
+    })
+    @PostMapping("/smsLogin")
+    public ResultMessage<Object> smsLogin(@NotNull(message = "手机号为空") @RequestParam String mobile,
+                                          @NotNull(message = "验证码为空") @RequestParam String code,
+                                          @RequestHeader String uuid) {
+//        if(smsUtil.verifyCode(mobile,VerificationEnums.LOGIN,uuid,code)){
+        return ResultUtil.data(memberService.mobilePhoneLogin(mobile));
+//        }else {
+//            return ResultUtil.error("验证码错误");
+//        }
+    }
+
+    @ApiOperation(value = "注册用户")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "username", value = "用户名", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "mobilePhone", value = "手机号", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "code", value = "验证码", required = true, paramType = "query")
+    })
+    @PostMapping("/register")
+    public ResultMessage<Object> register(@NotNull(message = "用户名不能为空") @RequestParam String username,
+                                          @NotNull(message = "密码不能为空") @RequestParam String password,
+                                          @NotNull(message = "手机号为空") @RequestParam String mobilePhone,
+                                          @RequestHeader String uuid,
+                                          @NotNull(message = "验证码不能为空") @RequestParam String code) {
+
+        boolean result = smsUtil.verifyCode(mobilePhone, VerificationEnums.REGISTER, uuid, code);
+        if (result) {
+            return ResultUtil.data(memberService.register(username, password, mobilePhone));
+        } else {
+            return ResultUtil.error(ResultCode.VERIFICATION_SMS_ERROR);
+        }
+    }
+
+    @ApiOperation(value = "获取当前登录用户接口")
+    @GetMapping
+    public ResultMessage<Member> getUserInfo() {
+
+        return ResultUtil.data(memberService.getUserInfo());
+    }
+
+    @ApiOperation(value = "通过短信重置密码")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "mobile", value = "手机号", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "password", value = "是否保存登录", required = true, paramType = "query")
+    })
+    @PostMapping("/resetByMobile")
+    public ResultMessage<Member> resetByMobile(@NotNull(message = "手机号为空") @RequestParam String mobile,
+                                               @NotNull(message = "验证码为空") @RequestParam String code,
+                                               @RequestHeader String uuid) {
+        //校验短信验证码是否正确
+        if (smsUtil.verifyCode(mobile, VerificationEnums.FIND_USER, uuid, code)) {
+            //校验是否通过手机号可获取会员,存在则将会员信息存入缓存,有效时间3分钟
+            if (memberService.findByMobile(uuid, mobile)) {
+                return ResultUtil.success(ResultCode.SUCCESS);
+            }
+        }
+        return ResultUtil.error(ResultCode.VERIFICATION_ERROR);
+    }
+
+    @ApiOperation(value = "修改密码")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "mobile", value = "手机号", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "password", value = "是否保存登录", required = true, paramType = "query")
+    })
+    @PostMapping("/resetPassword")
+    public ResultMessage<Object> resetByMobile(@NotNull(message = "密码为空") @RequestParam String password, @RequestHeader String uuid) {
+
+        return ResultUtil.data(memberService.resetByMobile(uuid, password));
+    }
+
+    @ApiOperation(value = "修改用户自己资料")
+    @PutMapping("/editOwn")
+    public ResultMessage<Member> editOwn(MemberEditDTO memberEditDTO) {
+
+        return ResultUtil.data(memberService.editOwn(memberEditDTO));
+    }
+
+    @ApiOperation(value = "修改密码")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "password", value = "旧密码", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "newPassword", value = "新密码", required = true, paramType = "query")
+    })
+    @PutMapping("/modifyPass")
+    public ResultMessage<Member> modifyPass(@NotNull(message = "旧密码不能为空") @RequestParam String password,
+                                            @NotNull(message = "新密码不能为空") @RequestParam String newPassword) {
+        return ResultUtil.data(memberService.modifyPass(password, newPassword));
+    }
+
+
+    @ApiOperation(value = "刷新token")
+    @GetMapping("/refresh/{refreshToken}")
+    public ResultMessage<Object> refreshToken(@NotNull(message = "刷新token不能为空") @PathVariable String refreshToken) {
+        return ResultUtil.data(this.memberService.refreshToken(refreshToken));
+    }
+
+}

+ 56 - 0
buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerBindController.java

@@ -0,0 +1,56 @@
+package cn.lili.controller.passport.connect;
+
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.connect.service.ConnectService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 买家端,app/小程序 联合登录
+ *
+ * @author Chopper
+ * @date 2020-11-25 19:29
+ */
+@RestController
+@Api(tags = "买家端,app/小程序 联合登录")
+@RequestMapping("/buyer/connect/bind")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class ConnectBuyerBindController {
+
+    private final ConnectService connectService;
+
+    @ApiOperation(value = "unionID 绑定")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "unionID", value = "unionID", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "type", value = "type", required = true, paramType = "query")
+    })
+    @PostMapping
+    public void unionIDBind(@RequestParam String unionID, @RequestParam String type) {
+        connectService.bind(unionID, type);
+    }
+
+    @ApiOperation(value = "unionID 解绑")
+    @ApiImplicitParam(name = "type", value = "type", required = true, paramType = "query")
+    @PostMapping("/unbind")
+    public void unionIDBind(@RequestParam String type) {
+        connectService.unbind(type);
+    }
+
+
+    @GetMapping("/list")
+    @ApiOperation(value = "绑定列表")
+    public ResultMessage<List<String>> bindList() {
+        return ResultUtil.data(connectService.bindList());
+    }
+
+
+}

+ 98 - 0
buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerWebController.java

@@ -0,0 +1,98 @@
+package cn.lili.controller.passport.connect;
+
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.token.Token;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.connect.entity.dto.AuthCallback;
+import cn.lili.modules.connect.entity.dto.ConnectAuthUser;
+import cn.lili.modules.connect.request.AuthRequest;
+import cn.lili.modules.connect.service.ConnectService;
+import cn.lili.modules.connect.util.ConnectUtil;
+import cn.lili.modules.connect.util.UuidUtils;
+import cn.lili.modules.member.service.MemberService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 买家端,web联合登录
+ *
+ * @author Chopper
+ * @date 2020-11-25 19:29
+ */
+@RestController
+@Api(tags = "买家端,web联合登录")
+@RequestMapping("/buyer/connect")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class ConnectBuyerWebController {
+
+    private final ConnectService connectService;
+
+    private final MemberService memberService;
+
+    private final ConnectUtil connectUtil;
+
+
+    @GetMapping("/login/web/{type}")
+    @ApiOperation(value = "WEB信任登录授权")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "type", value = "登录方式:QQ,微信,微信_PC",
+                    allowableValues = "QQ,WECHAT,WECHAT_PC", paramType = "path")
+    })
+    public ResultMessage<String> webAuthorize(@PathVariable String type, HttpServletResponse response) throws IOException {
+        AuthRequest authRequest = connectUtil.getAuthRequest(type);
+        String authorizeUrl = authRequest.authorize(UuidUtils.getUUID());
+        response.sendRedirect(authorizeUrl);
+        return ResultUtil.data(authorizeUrl);
+    }
+
+
+    @ApiOperation(value = "信任登录统一回调地址", hidden = true)
+    @GetMapping("/callback/{type}")
+    public void callBack(@PathVariable String type, AuthCallback callback, HttpServletResponse httpServletResponse) throws IOException {
+        connectUtil.callback(type, callback, httpServletResponse);
+    }
+
+    @ApiOperation(value = "信任登录响应结果获取")
+    @GetMapping("/result")
+    public ResultMessage<Object> callBackResult(String state) {
+        if (state == null) {
+            return ResultUtil.error(ResultCode.USER_CONNECT_LOGIN_ERROR);
+        }
+        return connectUtil.getResult(state);
+    }
+
+    @GetMapping("/register/auto")
+    @ApiOperation(value = "WEB信任登录授权")
+    public ResultMessage<Token> webAuthorize() {
+        Token token = memberService.autoRegister();
+        return ResultUtil.data(token);
+    }
+
+    @ApiOperation(value = "unionID登录")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "openId", value = "openid", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "type", value = "联合类型", required = true,
+                    allowableValues = "WECHAT,QQ,ALIPAY,WEIBO,APPLE", paramType = "query"),
+            @ApiImplicitParam(name = "uniAccessToken", value = "联合登陆返回的accessToken", required = true, paramType = "query")
+    })
+    @GetMapping("/app/login")
+    public ResultMessage<Token> unionIDLogin(ConnectAuthUser authUser, @RequestHeader("uuid") String uuid) {
+        try {
+            return ResultUtil.data(connectService.appLoginCallback(authUser, uuid));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+}

+ 72 - 0
buyer-api/src/main/java/cn/lili/controller/passport/connect/MiniProgramBuyerController.java

@@ -0,0 +1,72 @@
+package cn.lili.controller.passport.connect;
+
+import cn.lili.common.token.Token;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.connect.entity.dto.WechatMPLoginParams;
+import cn.lili.modules.connect.service.ConnectService;
+import cn.lili.modules.message.entity.dos.WechatMPMessage;
+import cn.lili.modules.message.service.ShortLinkService;
+import cn.lili.modules.message.service.WechatMPMessageService;
+import cn.lili.modules.message.util.WechatMpCodeUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 买家端,小程序登录接口
+ *
+ * @author Chopper
+ * @date 2021/2/19 09:28
+ */
+@RestController
+@RequestMapping("/buyer/mini-program")
+@Api(tags = "买家端,小程序登录接口")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MiniProgramBuyerController {
+
+    public final ConnectService connectService;
+    public final WechatMpCodeUtil wechatMpCodeUtil;
+
+    public final WechatMPMessageService wechatMPMessageService;
+    public final ShortLinkService shortLinkService;
+
+    @GetMapping("/auto-login")
+    @ApiOperation(value = "小程序自动登录")
+    public ResultMessage<Token> autoLogin(@RequestHeader String uuid, WechatMPLoginParams params) {
+        params.setUuid(uuid);
+        return ResultUtil.data(this.connectService.miniProgramAutoLogin(params));
+    }
+
+    @GetMapping("/subscribeMessage")
+    @ApiOperation(value = "消息订阅")
+    public ResultMessage<List<WechatMPMessage>> autoLogin() {
+        return ResultUtil.data(wechatMPMessageService.list());
+    }
+
+    @GetMapping("/mp/unlimited")
+    @ApiOperation(value = "小程序二维码生成:不限制数量,但是限制长度,只能存放32为长度")
+    public ResultMessage<String> unlimited(String page, String scene) {
+        return ResultUtil.data(wechatMpCodeUtil.createCode(page, scene));
+    }
+
+    @GetMapping("/mp/qrcode")
+    @ApiOperation(value = "小程序二维码生成:只适用于少量场景,多数场景需要unlimited接口实现")
+    public ResultMessage<String> qrcode(String page) {
+        return ResultUtil.data(wechatMpCodeUtil.createQrCode(page));
+    }
+
+    @GetMapping("/mp/unlimited/scene")
+    @ApiOperation(value = "根据shortlink 获取页面参数")
+    public ResultMessage<String> getScene(String id) {
+        return ResultUtil.data(shortLinkService.getById(id).getOriginalParams());
+    }
+
+}

+ 104 - 0
buyer-api/src/main/java/cn/lili/controller/payment/CashierController.java

@@ -0,0 +1,104 @@
+package cn.lili.controller.payment;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.payment.kit.CashierSupport;
+import cn.lili.modules.payment.kit.dto.PayParam;
+import cn.lili.modules.payment.kit.enums.PaymentClientEnum;
+import cn.lili.modules.payment.kit.enums.PaymentMethodEnum;
+import cn.lili.modules.payment.kit.params.dto.CashierParam;
+import cn.lili.modules.payment.service.PaymentService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 买家端,收银台接口
+ *
+ * @author Chopper
+ * @date 2020-12-18 16:59
+ */
+@RestController
+@Api(tags = "买家端,收银台接口")
+@RequestMapping("/buyer/cashier")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class CashierController {
+
+
+    private final CashierSupport cashierSupport;
+
+    private final PaymentService paymentService;
+
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "client", value = "客户端类型", paramType = "path", allowableValues = "PC,H5,WECHAT_MP,APP")
+    })
+    @GetMapping(value = "/tradeDetail")
+    @ApiOperation(value = "获取支付详情")
+    public ResultMessage paymentParams(@Validated PayParam payParam) {
+        CashierParam cashierParam = cashierSupport.cashierParam(payParam);
+        return ResultUtil.data(cashierParam);
+    }
+
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "paymentMethod", value = "支付方式", paramType = "path", allowableValues = "WECHAT,ALIPAY"),
+            @ApiImplicitParam(name = "paymentClient", value = "调起方式", paramType = "path", allowableValues = "APP,NATIVE,JSAPI,H5,MP")
+    })
+    @GetMapping(value = "/pay/{paymentMethod}/{paymentClient}")
+    @ApiOperation(value = "支付")
+    public ResultMessage payment(
+            HttpServletRequest request,
+            HttpServletResponse response,
+            @PathVariable String paymentMethod,
+            @PathVariable String paymentClient,
+            @Validated PayParam payParam) {
+        PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(paymentMethod);
+        PaymentClientEnum paymentClientEnum = PaymentClientEnum.valueOf(paymentClient);
+
+        try {
+            return cashierSupport.payment(paymentMethodEnum, paymentClientEnum, request, response, payParam);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+
+
+    }
+
+    @ApiOperation(value = "支付回调")
+    @RequestMapping(value = "/callback/{paymentMethod}", method = {RequestMethod.GET, RequestMethod.POST})
+    public ResultMessage<Object> callback(HttpServletRequest request, @PathVariable String paymentMethod) {
+
+        PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(paymentMethod);
+
+        cashierSupport.callback(paymentMethodEnum, request);
+
+        return ResultUtil.success(ResultCode.PAY_SUCCESS);
+    }
+
+    @ApiOperation(value = "支付异步通知")
+    @RequestMapping(value = "/notify/{paymentMethod}", method = {RequestMethod.GET, RequestMethod.POST})
+    public void notify(HttpServletRequest request, @PathVariable String paymentMethod) {
+
+        PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(paymentMethod);
+
+        cashierSupport.notify(paymentMethodEnum, request);
+
+    }
+
+    @ApiOperation(value = "查询支付结果")
+    @GetMapping(value = "/result")
+    public ResultMessage<Boolean> paymentResult(PayParam payParam) {
+        return ResultUtil.data(cashierSupport.paymentResult(payParam));
+    }
+}

+ 38 - 0
buyer-api/src/main/java/cn/lili/controller/payment/CashierRefundController.java

@@ -0,0 +1,38 @@
+package cn.lili.controller.payment;
+
+import cn.lili.modules.payment.kit.RefundSupport;
+import cn.lili.modules.payment.kit.enums.PaymentMethodEnum;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 买家端,退款回调
+ *
+ * @author Chopper
+ * @date 2020-12-18 16:59
+ */
+@Api(tags = "买家端,退款回调")
+@RestController
+@RequestMapping("/buyer/cashier/refund")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class CashierRefundController {
+
+
+    private final RefundSupport refundSupport;
+
+
+    @ApiOperation(value = "退款通知")
+    @RequestMapping(value = "/notify/{paymentMethod}", method = {RequestMethod.GET, RequestMethod.POST})
+    public void notify(HttpServletRequest request, @PathVariable String paymentMethod) {
+        PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(paymentMethod);
+        refundSupport.notify(paymentMethodEnum, request);
+    }
+}

+ 68 - 0
buyer-api/src/main/java/cn/lili/controller/promotion/PintuanBuyerController.java

@@ -0,0 +1,68 @@
+package cn.lili.controller.promotion;
+
+import cn.hutool.core.date.DateUtil;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.promotion.entity.dto.PromotionGoodsDTO;
+import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
+import cn.lili.modules.promotion.entity.enums.PromotionTypeEnum;
+import cn.lili.modules.promotion.entity.vos.PintuanMemberVO;
+import cn.lili.modules.promotion.entity.vos.PintuanShareVO;
+import cn.lili.modules.promotion.entity.vos.PromotionGoodsSearchParams;
+import cn.lili.modules.promotion.service.PintuanService;
+import cn.lili.modules.promotion.service.PromotionGoodsService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 买家端,拼团接口
+ *
+ * @author paulG
+ * @date 2021/2/20
+ **/
+@Api(tags = "买家端,拼团接口")
+@RestController
+@RequestMapping("/buyer/promotion/pintuan")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class PintuanBuyerController {
+
+    private final PromotionGoodsService promotionGoodsService;
+
+    private final PintuanService pintuanService;
+
+    @ApiOperation(value = "获取拼团商品")
+    @GetMapping
+    public ResultMessage<IPage<PromotionGoodsDTO>> getPintuanCategory(String goodsName, String categoryPath, PageVO pageVo) {
+        PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
+        searchParams.setGoodsName(goodsName);
+        searchParams.setPromotionType(PromotionTypeEnum.PINTUAN.name());
+        searchParams.setPromotionStatus(PromotionStatusEnum.START.name());
+        searchParams.setCategoryPath(categoryPath);
+        searchParams.setEndTime(DateUtil.date().getTime());
+        return ResultUtil.data(promotionGoodsService.getPromotionGoods(searchParams, pageVo));
+    }
+
+
+    @ApiOperation(value = "获取当前拼团活动的未成团的会员")
+    @GetMapping("/{pintuanId}/members")
+    public ResultMessage<List<PintuanMemberVO>> getPintuanMember(@PathVariable String pintuanId) {
+        return ResultUtil.data(pintuanService.getPintuanMember(pintuanId));
+    }
+
+    @ApiOperation(value = "获取当前拼团订单的拼团分享信息")
+    @GetMapping("/share")
+    public ResultMessage<PintuanShareVO> share(String parentOrderSn, String skuId) {
+        return ResultUtil.data(pintuanService.getPintuanShareInfo(parentOrderSn, skuId));
+    }
+
+}

+ 49 - 0
buyer-api/src/main/java/cn/lili/controller/promotion/PointsGoodsBuyerController.java

@@ -0,0 +1,49 @@
+package cn.lili.controller.promotion;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.promotion.entity.dos.PointsGoodsCategory;
+import cn.lili.modules.promotion.entity.vos.PointsGoodsSearchParams;
+import cn.lili.modules.promotion.entity.vos.PointsGoodsVO;
+import cn.lili.modules.promotion.service.PointsGoodsCategoryService;
+import cn.lili.modules.promotion.service.PointsGoodsService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+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 paulG
+ * @date 2021/1/19
+ **/
+@RestController
+@Api(tags = "买家端,积分商品接口")
+@RequestMapping("/buyer/promotion/pointsGoods")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class PointsGoodsBuyerController {
+
+    private final PointsGoodsService pointsGoodsService;
+
+    private final PointsGoodsCategoryService pointsGoodsCategoryService;
+
+    @GetMapping
+    @ApiOperation(value = "分页获取积分商品")
+    public ResultMessage<IPage<PointsGoodsVO>> getPointsGoodsPage(PointsGoodsSearchParams searchParams, PageVO page) {
+        IPage<PointsGoodsVO> pointsGoodsByPage = pointsGoodsService.getPointsGoodsByPage(searchParams, page);
+        return ResultUtil.data(pointsGoodsByPage);
+    }
+
+    @GetMapping("/category")
+    @ApiOperation(value = "获取积分商品分类分页")
+    public ResultMessage<IPage<PointsGoodsCategory>> page(String name, PageVO page) {
+        return ResultUtil.data(pointsGoodsCategoryService.getCategoryByPage(name, page));
+    }
+
+}

+ 49 - 0
buyer-api/src/main/java/cn/lili/controller/promotion/SeckillBuyerController.java

@@ -0,0 +1,49 @@
+package cn.lili.controller.promotion;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.promotion.entity.vos.SeckillGoodsVO;
+import cn.lili.modules.promotion.entity.vos.SeckillTimelineVO;
+import cn.lili.modules.promotion.service.SeckillApplyService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+/**
+ * 买家端,限时抢购接口
+ *
+ * @author paulG
+ * @date 2020/11/17 2:30 下午
+ */
+@Api(tags = "买家端,限时抢购接口")
+@RestController
+@RequestMapping("/buyer/promotion/seckill")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class SeckillBuyerController {
+
+    /**
+     * 限时抢购
+     */
+    private final SeckillApplyService seckillApplyService;
+
+    @ApiOperation(value = "获取当天限时抢购信息")
+    @GetMapping
+    public ResultMessage<List<SeckillTimelineVO>> getSeckillTime() {
+        return ResultUtil.data(seckillApplyService.getSeckillTimeline());
+    }
+
+    @ApiOperation(value = "获取某个时刻的限时抢购商品信息")
+    @GetMapping("/{timeline}")
+    public ResultMessage<List<SeckillGoodsVO>> getSeckillGoods(@PathVariable Integer timeline) {
+        return ResultUtil.data(seckillApplyService.getSeckillGoods(timeline));
+    }
+
+}

+ 75 - 0
buyer-api/src/main/java/cn/lili/controller/purchase/PurchaseBuyerController.java

@@ -0,0 +1,75 @@
+package cn.lili.controller.purchase;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.purchase.entity.dos.PurchaseOrder;
+import cn.lili.modules.purchase.entity.params.PurchaseOrderSearchParams;
+import cn.lili.modules.purchase.entity.vos.PurchaseOrderVO;
+import cn.lili.modules.purchase.service.PurchaseOrderService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 买家端,采购接口
+ *
+ * @author Chopper
+ * @date: 2020/11/16 10:06 下午
+ */
+@Api(tags = "买家端,采购接口")
+@RestController
+@RequestMapping("/buyer/purchase")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class PurchaseBuyerController {
+
+    /**
+     * 采购单
+     */
+    private final PurchaseOrderService purchaseOrderService;
+
+    @ApiOperation(value = "添加采购单")
+    @PostMapping
+    public ResultMessage<PurchaseOrderVO> addPurchaseOrderVO(PurchaseOrderVO purchaseOrderVO) {
+        return ResultUtil.data(purchaseOrderService.addPurchaseOrder(purchaseOrderVO));
+    }
+
+    @ApiOperation(value = "采购单分页")
+    @GetMapping
+    public ResultMessage<IPage<PurchaseOrder>> get(PurchaseOrderSearchParams purchaseOrderSearchParams) {
+        return ResultUtil.data(purchaseOrderService.page(purchaseOrderSearchParams));
+    }
+
+    @ApiOperation(value = "采购单详情")
+    @ApiImplicitParam(name = "id", value = "采购单ID", required = true, dataType = "Long", paramType = "path")
+    @GetMapping("/{id}")
+    public ResultMessage<PurchaseOrderVO> getPurchaseOrder(@NotNull @PathVariable String id) {
+        return ResultUtil.data(purchaseOrderService.getPurchaseOrder(id));
+    }
+
+    @ApiOperation(value = "会员采购单分页")
+    @GetMapping("/getByMember")
+    public ResultMessage<IPage<PurchaseOrder>> getByMember(PurchaseOrderSearchParams purchaseOrderSearchParams) {
+        purchaseOrderSearchParams.setMemberId(UserContext.getCurrentUser().getId());
+        return ResultUtil.data(purchaseOrderService.page(purchaseOrderSearchParams));
+    }
+
+    @ApiOperation(value = "关闭采购单")
+    @ApiImplicitParam(name = "id", value = "采购单ID", required = true, dataType = "Long", paramType = "path")
+    @PutMapping("/{id}")
+    public ResultMessage<Object> close(@NotNull @PathVariable String id) {
+
+        if (purchaseOrderService.close(id)) {
+            return ResultUtil.success(ResultCode.SUCCESS);
+        }
+        return ResultUtil.error(ResultCode.ERROR);
+    }
+
+}

+ 56 - 0
buyer-api/src/main/java/cn/lili/controller/purchase/PurchaseQuotedController.java

@@ -0,0 +1,56 @@
+package cn.lili.controller.purchase;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.purchase.entity.dos.PurchaseQuoted;
+import cn.lili.modules.purchase.entity.vos.PurchaseQuotedVO;
+import cn.lili.modules.purchase.service.PurchaseQuotedService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 买家端,采购报价接口
+ *
+ * @author Bulbasaur
+ * @date: 2020/11/16 10:06 下午
+ */
+@Api(tags = "买家端,采购报价接口")
+@RestController
+@RequestMapping("/buyer/purchaseQuoted")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class PurchaseQuotedController {
+
+    /**
+     * 采购单报价
+     */
+    private final PurchaseQuotedService purchaseQuotedService;
+
+    @ApiOperation(value = "添加采购单报价")
+    @PostMapping
+    public ResultMessage<PurchaseQuoted> addPurchaseOrderVO(PurchaseQuotedVO purchaseQuotedVO) {
+        return ResultUtil.data(purchaseQuotedService.addPurchaseQuoted(purchaseQuotedVO));
+    }
+
+    @ApiOperation(value = "报价列表")
+    @ApiImplicitParam(name = "purchaseOrderId", value = "报价单ID", required = true, dataType = "String", paramType = "path")
+    @GetMapping("/purchaseOrder/{purchaseOrderId}")
+    public ResultMessage<List<PurchaseQuoted>> get(@NotNull @PathVariable String purchaseOrderId) {
+        return ResultUtil.data(purchaseQuotedService.getByPurchaseOrderId(purchaseOrderId));
+    }
+
+    @ApiOperation(value = "报价单详情")
+    @ApiImplicitParam(name = "id", value = "报价单ID", required = true, dataType = "String", paramType = "path")
+    @GetMapping(value = "purchaseQuoted/{id}")
+    public ResultMessage<PurchaseQuotedVO> getPurchaseQuoted(@NotNull @PathVariable String id) {
+        return ResultUtil.data(purchaseQuotedService.getById(id));
+    }
+
+
+}

+ 110 - 0
buyer-api/src/main/java/cn/lili/controller/store/StoreBuyerController.java

@@ -0,0 +1,110 @@
+package cn.lili.controller.store;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.statistics.aop.PageViewPoint;
+import cn.lili.modules.statistics.aop.enums.PageViewEnum;
+import cn.lili.modules.store.entity.dto.StoreBankDTO;
+import cn.lili.modules.store.entity.dto.StoreCompanyDTO;
+import cn.lili.modules.store.entity.dto.StoreOtherInfoDTO;
+import cn.lili.modules.store.entity.vos.*;
+import cn.lili.modules.store.service.StoreDetailService;
+import cn.lili.modules.store.service.StoreGoodsLabelService;
+import cn.lili.modules.store.service.StoreService;
+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 lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+
+/**
+ * 买家端,店铺接口
+ *
+ * @author Bulbasaur
+ * @date: 2020/11/17 2:32 下午
+ */
+@RestController
+@RequestMapping("/buyer/store")
+@Api(tags = "买家端,店铺接口")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class StoreBuyerController {
+
+    /**
+     * 店铺
+     */
+    private final StoreService storeService;
+    /**
+     * 店铺商品分类
+     */
+    private final StoreGoodsLabelService storeGoodsLabelService;
+    /**
+     * 店铺详情
+     */
+    private final StoreDetailService storeDetailService;
+
+    @ApiOperation(value = "获取店铺列表分页")
+    @GetMapping
+    public ResultMessage<IPage<StoreVO>> getByPage(StoreSearchParams entity, PageVO page) {
+        return ResultUtil.data(storeService.findByConditionPage(entity, page));
+    }
+
+    @ApiOperation(value = "通过id获取店铺信息")
+    @ApiImplicitParam(name = "id", value = "店铺ID", required = true, paramType = "path")
+    @GetMapping(value = "/get/detail/{id}")
+    @PageViewPoint(type = PageViewEnum.STORE, id = "#id")
+    public ResultMessage<StoreBasicInfoVO> detail(@NotNull @PathVariable String id) {
+        return ResultUtil.data(storeDetailService.getStoreBasicInfoDTO(id));
+    }
+
+    @ApiOperation(value = "通过id获取店铺商品分类")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "店铺ID", required = true, paramType = "path")
+    })
+    @GetMapping(value = "/label/get/{id}")
+    public ResultMessage<List<StoreGoodsLabelVO>> storeGoodsLabel(@NotNull @PathVariable String id) {
+        return ResultUtil.data(storeGoodsLabelService.listByStoreId(id));
+    }
+
+    @ApiOperation(value = "申请店铺第一步-填写企业信息")
+    @PutMapping(value = "/apply/first")
+    public ResultMessage<Object> applyFirstStep(StoreCompanyDTO storeCompanyDTO) {
+        if (storeService.applyFirstStep(storeCompanyDTO)) {
+            return ResultUtil.success(ResultCode.SUCCESS);
+        }
+        return ResultUtil.error(ResultCode.ERROR);
+    }
+
+    @ApiOperation(value = "申请店铺第二步-填写银行信息")
+    @PutMapping(value = "/apply/second")
+    public ResultMessage<Object> applyFirstStep(StoreBankDTO storeBankDTO) {
+        if (storeService.applySecondStep(storeBankDTO)) {
+            return ResultUtil.success(ResultCode.SUCCESS);
+        }
+        return ResultUtil.error(ResultCode.ERROR);
+    }
+
+    @ApiOperation(value = "申请店铺第三步-填写其他信息")
+    @PutMapping(value = "/apply/third")
+    public ResultMessage<Object> applyFirstStep(StoreOtherInfoDTO storeOtherInfoDTO) {
+        if (storeService.applyThirdStep(storeOtherInfoDTO)) {
+            return ResultUtil.success(ResultCode.SUCCESS);
+        }
+        return ResultUtil.error(ResultCode.ERROR);
+    }
+
+    @ApiOperation(value = "获取当前登录会员的店铺信息-入驻店铺")
+    @GetMapping(value = "/apply")
+    public ResultMessage<StoreDetailVO> apply() {
+        return ResultUtil.data(storeDetailService.getStoreDetailVOByMemberId(UserContext.getCurrentUser().getId()));
+    }
+}

+ 133 - 0
buyer-api/src/main/java/cn/lili/controller/trade/AfterSaleBuyerController.java

@@ -0,0 +1,133 @@
+package cn.lili.controller.trade;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.order.order.entity.dos.AfterSale;
+import cn.lili.modules.order.order.entity.dos.AfterSaleReason;
+import cn.lili.modules.order.order.entity.dto.AfterSaleDTO;
+import cn.lili.modules.order.order.entity.vo.AfterSaleApplyVO;
+import cn.lili.modules.order.order.entity.vo.AfterSaleSearchParams;
+import cn.lili.modules.order.order.entity.vo.AfterSaleVO;
+import cn.lili.modules.order.order.service.AfterSaleReasonService;
+import cn.lili.modules.order.order.service.AfterSaleService;
+import cn.lili.modules.store.entity.dto.StoreAfterSaleAddressDTO;
+import cn.lili.modules.order.trade.entity.dos.AfterSaleLog;
+import cn.lili.modules.order.order.service.AfterSaleLogService;
+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 lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 买家端,售后管理接口
+ *
+ * @author Chopper
+ * @date 2020/11/16 10:02 下午
+ */
+@RestController
+@Api(tags = "买家端,售后管理接口")
+@RequestMapping("/buyer/afterSale")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class AfterSaleBuyerController {
+
+    /**
+     * 售后
+     */
+    private final AfterSaleService afterSaleService;
+
+    /**
+     * 售后原因
+     */
+    private final AfterSaleReasonService afterSaleReasonService;
+
+    /**
+     * 售后日志
+     */
+    private final AfterSaleLogService afterSaleLogService;
+
+    @ApiOperation(value = "查看售后服务详情")
+    @ApiImplicitParam(name = "sn", value = "售后单号", required = true, paramType = "path")
+    @GetMapping(value = "/get/{sn}")
+    public ResultMessage<AfterSaleVO> get(@NotNull(message = "售后单号") @PathVariable("sn") String sn) {
+        return ResultUtil.data(afterSaleService.getAfterSale(sn));
+    }
+
+    @ApiOperation(value = "分页获取售后服务")
+    @GetMapping(value = "/page")
+    public ResultMessage<IPage<AfterSaleVO>> getByPage(AfterSaleSearchParams searchParams) {
+        return ResultUtil.data(afterSaleService.getAfterSalePages(searchParams));
+    }
+
+    @ApiOperation(value = "获取申请售后页面信息")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "sn", value = "订单货物编号", required = true, dataType = "String", paramType = "path")
+    })
+    @GetMapping(value = "/applyAfterSaleInfo/{sn}")
+    public ResultMessage<AfterSaleApplyVO> applyAfterSaleInfo(@PathVariable String sn) {
+        return ResultUtil.data(afterSaleService.getAfterSaleDTO(sn));
+    }
+
+    @PostMapping(value = "/save/{orderItemSn}")
+    @ApiImplicitParam(name = "orderItemSn", value = "订单货物编号", required = true, paramType = "query")
+    @ApiOperation(value = "申请售后")
+    public ResultMessage<AfterSale> save(AfterSaleDTO afterSaleDTO) {
+        return ResultUtil.data(afterSaleService.saveAfterSale(afterSaleDTO));
+
+    }
+
+    @ApiOperation(value = "买家 退回 物流信息")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "afterSaleSn", value = "售后sn", required = true, dataType = "String", paramType = "path"),
+            @ApiImplicitParam(name = "logisticsNo", value = "发货单号", required = true, dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "logisticsId", value = "物流公司id", required = true, dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "mDeliverTime", value = "买家发货时间", required = true, dataType = "date", paramType = "query")
+
+    })
+    @PostMapping(value = "/delivery/{afterSaleSn}")
+    public ResultMessage<AfterSale> delivery(@NotNull(message = "售后编号不能为空") @PathVariable("afterSaleSn") String afterSaleSn,
+                                             @NotNull(message = "发货单号不能为空") @RequestParam String logisticsNo,
+                                             @NotNull(message = "请选择物流公司") @RequestParam String logisticsId,
+                                             @NotNull(message = "请选择发货时间") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date mDeliverTime) {
+        return ResultUtil.data(afterSaleService.buyerDelivery(afterSaleSn, logisticsNo, logisticsId, mDeliverTime));
+    }
+
+    @ApiOperation(value = "售后,取消售后")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "afterSaleSn", value = "售后sn", required = true, dataType = "String", paramType = "path")
+    })
+    @PostMapping(value = "/cancel/{afterSaleSn}")
+    public ResultMessage<AfterSale> cancel(@NotNull(message = "参数非法") @PathVariable("afterSaleSn") String afterSaleSn) {
+        return ResultUtil.data(afterSaleService.cancel(afterSaleSn));
+    }
+
+    @ApiOperation(value = "获取商家售后收件地址")
+    @ApiImplicitParam(name = "sn", value = "售后单号", required = true, paramType = "path")
+    @GetMapping(value = "/getStoreAfterSaleAddress/{sn}")
+    public ResultMessage<StoreAfterSaleAddressDTO> getStoreAfterSaleAddress(@NotNull(message = "售后单号") @PathVariable("sn") String sn) {
+        return ResultUtil.data(afterSaleService.getStoreAfterSaleAddressDTO(sn));
+    }
+
+    @ApiOperation(value = "获取售后原因")
+    @ApiImplicitParam(name = "serviceType", value = "售后类型", required = true, paramType = "path", allowableValues = "CANCEL,RETURN_GOODS,RETURN_MONEY,COMPLAIN")
+    @GetMapping(value = "/get/afterSaleReason/{serviceType}")
+    public ResultMessage<List<AfterSaleReason>> getAfterSaleReason(@PathVariable String serviceType) {
+        return ResultUtil.data(afterSaleReasonService.afterSaleReasonList(serviceType));
+    }
+
+    @ApiOperation(value = "获取售后日志")
+    @ApiImplicitParam(name = "sn", value = "售后编号", required = true, paramType = "path")
+    @GetMapping(value = "/get/getAfterSaleLog/{sn}")
+    public ResultMessage<List<AfterSaleLog>> getAfterSaleLog(@PathVariable String sn) {
+        return ResultUtil.data(afterSaleLogService.getAfterSaleLog(sn));
+    }
+
+}

+ 240 - 0
buyer-api/src/main/java/cn/lili/controller/trade/CartController.java

@@ -0,0 +1,240 @@
+package cn.lili.controller.trade;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.exception.ServiceException;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.order.cart.entity.dto.TradeDTO;
+import cn.lili.modules.order.cart.entity.enums.CartTypeEnum;
+import cn.lili.modules.order.cart.entity.vo.TradeParams;
+import cn.lili.modules.order.cart.service.CartService;
+import cn.lili.modules.order.order.entity.vo.ReceiptVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 买家端,购物车接口
+ *
+ * @author Chopper
+ * @date 2020/11/16 10:04 下午
+ */
+@Slf4j
+@RestController
+@Api(tags = "买家端,购物车接口")
+@RequestMapping("/buyer/trade/carts")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class CartController {
+
+    /**
+     * 购物车
+     */
+    private final CartService cartService;
+
+
+    @ApiOperation(value = "向购物车中添加一个产品")
+    @PostMapping
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "skuId", value = "产品ID", required = true, dataType = "Long", paramType = "query"),
+            @ApiImplicitParam(name = "num", value = "此产品的购买数量", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "cartType", value = "购物车类型,默认加入购物车", paramType = "query")
+    })
+    public ResultMessage<Object> add(@NotNull(message = "产品id不能为空") String skuId,
+                                     @NotNull(message = "购买数量不能为空") @Min(value = 1, message = "加入购物车数量必须大于0") Integer num,
+                                     String cartType) {
+        cartService.add(skuId, num, cartType);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+
+    @ApiOperation(value = "获取购物车页面购物车详情")
+    @GetMapping("/all")
+    public ResultMessage<TradeDTO> cartAll() {
+        return ResultUtil.data(this.cartService.getAllTradeDTO());
+    }
+
+    @ApiOperation(value = "获取购物车数量")
+    @GetMapping("/count")
+    public ResultMessage<Long> cartCount(@RequestParam(required = false) Boolean checked) {
+        return ResultUtil.data(this.cartService.getCartNum(checked));
+    }
+
+    @ApiOperation(value = "获取购物车可用优惠券数量")
+    @GetMapping("/coupon/num")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "way", value = "购物车购买:CART/立即购买:BUY_NOW/拼团购买:PINTUAN / 积分购买:POINT ", required = true, paramType = "query")
+    })
+    public ResultMessage<Long> cartCouponNum(String way) {
+        return ResultUtil.data(this.cartService.getCanUseCoupon(CartTypeEnum.valueOf(way)));
+    }
+
+    @ApiOperation(value = "更新购物车中单个产品数量", notes = "更新购物车中的多个产品的数量或选中状态")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "skuId", value = "产品id数组", required = true, dataType = "Long", paramType = "path"),
+            @ApiImplicitParam(name = "num", value = "产品数量", dataType = "int", paramType = "query"),
+    })
+    @PostMapping(value = "/sku/num/{skuId}")
+    public ResultMessage<Object> update(@NotNull(message = "产品id不能为空") @PathVariable(name = "skuId") String skuId,
+                                        Integer num) {
+        cartService.updateNum(skuId, num);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+
+    @ApiOperation(value = "更新购物车中单个产品", notes = "更新购物车中的多个产品的数量或选中状态")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "skuId", value = "产品id数组", required = true, dataType = "Long", paramType = "path")
+    })
+    @PostMapping(value = "/sku/checked/{skuId}")
+    public ResultMessage<Object> updateChecked(@NotNull(message = "产品id不能为空") @PathVariable(name = "skuId") String skuId,
+                                               boolean checked) {
+        cartService.checked(skuId, checked);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+
+    @ApiOperation(value = "购物车选中设置")
+    @PostMapping(value = "/sku/checked", produces = MediaType.APPLICATION_JSON_VALUE)
+    public ResultMessage<Object> updateAll(boolean checked) {
+        cartService.checkedAll(checked);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+
+    @ApiOperation(value = "批量设置某商家的商品为选中或不选中")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "storeId", value = "卖家id", required = true, dataType = "Long", paramType = "path"),
+            @ApiImplicitParam(name = "checked", value = "是否选中", required = true, dataType = "int", paramType = "query", allowableValues = "0,1")
+    })
+    @ResponseBody
+    @PostMapping(value = "/store/{storeId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public ResultMessage<Object> updateStoreAll(@NotNull(message = "卖家id不能为空") @PathVariable(name = "storeId") String storeId, boolean checked) {
+        cartService.checkedStore(storeId, checked);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+
+    @ApiOperation(value = "清空购物车")
+    @DeleteMapping()
+    public ResultMessage<Object> clean() {
+        cartService.clean();
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+
+    @ApiOperation(value = "删除购物车中的一个或多个产品")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "skuIds", value = "产品id", required = true, dataType = "Long", paramType = "path", allowMultiple = true)
+    })
+    @DeleteMapping(value = "/sku/remove")
+    public ResultMessage<Object> delete(String[] skuIds) {
+        cartService.delete(skuIds);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+
+    @ApiOperation(value = "获取结算页面购物车详情")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "way", value = "购物车购买:CART/立即购买:BUY_NOW/拼团购买:PINTUAN / 积分购买:POINT ", required = true, paramType = "query")
+    })
+    @GetMapping("/checked")
+    public ResultMessage<TradeDTO> cartChecked(@NotNull(message = "读取选中列表") String way) {
+        try {
+            // 读取选中的列表
+            return ResultUtil.data(this.cartService.getCheckedTradeDTO(CartTypeEnum.valueOf(way)));
+        } catch (ServiceException e) {
+            throw e;
+        } catch (Exception e) {
+            log.error(ResultCode.CART_ERROR.message(), e);
+            return ResultUtil.error(ResultCode.CART_ERROR);
+        }
+    }
+
+    @ApiOperation(value = "选择收货地址")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "shippingAddressId", value = "收货地址id ", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "way", value = "购物车类型 ", paramType = "query")
+    })
+    @GetMapping("/shippingAddress")
+    public ResultMessage<Object> shippingAddress(@NotNull(message = "收货地址ID不能为空") String shippingAddressId,
+                                                 String way) {
+        try {
+            cartService.shippingAddress(shippingAddressId, way);
+            return ResultUtil.success(ResultCode.SUCCESS);
+        } catch (ServiceException se) {
+            log.error(ResultCode.SHIPPING_NOT_APPLY.message(), se);
+            return ResultUtil.error(ResultCode.SHIPPING_NOT_APPLY);
+        } catch (Exception e) {
+            log.error(ResultCode.CART_ERROR.message(), e);
+            return ResultUtil.error(ResultCode.CART_ERROR);
+        }
+    }
+
+    @ApiOperation(value = "选择配送方式")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "shippingMethod", value = "配送方式:SELF_PICK_UP(自提)," +
+                    "LOCAL_TOWN_DELIVERY(同城配送)," +
+                    "LOGISTICS(物流) ", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "selleId", value = "店铺id", paramType = "query"),
+            @ApiImplicitParam(name = "way", value = "购物车类型 ", paramType = "query")
+    })
+    @GetMapping("/shippingMethod")
+    public ResultMessage<Object> shippingMethod(@NotNull(message = "配送方式不能为空") String shippingMethod,
+                                                String selleId,
+                                                String way) {
+        try {
+            cartService.shippingMethod(selleId, shippingMethod, way);
+            return ResultUtil.success(ResultCode.SUCCESS);
+        } catch (Exception e) {
+            log.error(ResultCode.CART_ERROR.message(), e);
+            return ResultUtil.error(ResultCode.CART_ERROR);
+        }
+    }
+
+    @ApiOperation(value = "选择发票")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "way", value = "购物车购买:CART/立即购买:BUY_NOW/拼团购买:PINTUAN / 积分购买:POINT ", required = true, paramType = "query"),
+    })
+    @GetMapping("/select/receipt")
+    public ResultMessage<Object> selectReceipt(String way, ReceiptVO receiptVO) {
+        this.cartService.shippingReceipt(receiptVO, way);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+    @ApiOperation(value = "选择优惠券")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "way", value = "购物车购买:CART/立即购买:BUY_NOW/拼团购买:PINTUAN / 积分购买:POINT ", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "memberCouponId", value = "优惠券id ", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "used", value = "使用true 弃用false ", required = true, paramType = "query")
+    })
+    @GetMapping("/select/coupon")
+    public ResultMessage<Object> selectCoupon(String way, @NotNull(message = "优惠券id不能为空") String memberCouponId, boolean used) {
+        this.cartService.selectCoupon(memberCouponId, way, used);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+
+    @ApiOperation(value = "创建交易")
+    @PostMapping(value = "/create/trade", consumes = "application/json", produces = "application/json")
+    public ResultMessage<Object> crateTrade(@RequestBody TradeParams tradeParams) {
+        try {
+            // 读取选中的列表
+            return ResultUtil.data(this.cartService.createTrade(tradeParams));
+        } catch (Exception e) {
+            log.error(ResultCode.ORDER_ERROR.message(), e);
+            if (e.getMessage().equals(ResultCode.SHIPPING_NOT_APPLY.message())) {
+                return ResultUtil.error(ResultCode.SHIPPING_NOT_APPLY);
+            }
+            return ResultUtil.error(ResultCode.ORDER_ERROR);
+        }
+    }
+}

+ 120 - 0
buyer-api/src/main/java/cn/lili/controller/trade/OrderBuyerController.java

@@ -0,0 +1,120 @@
+package cn.lili.controller.trade;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.security.AuthUser;
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.order.order.entity.dos.Order;
+import cn.lili.modules.order.order.entity.dto.OrderSearchParams;
+import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
+import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
+import cn.lili.modules.order.order.entity.vo.OrderSimpleVO;
+import cn.lili.modules.order.order.service.OrderService;
+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 lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 买家端,订单接口
+ *
+ * @author Chopper
+ * @date 2020/11/16 10:08 下午
+ */
+@RestController
+@Api(tags = "买家端,订单接口")
+@RequestMapping("/buyer/orders")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class OrderBuyerController {
+
+    /**
+     * 订单
+     */
+    private final OrderService orderService;
+
+    @ApiOperation(value = "查询会员订单列表")
+    @GetMapping
+    public ResultMessage<IPage<OrderSimpleVO>> queryMineOrder(OrderSearchParams orderSearchParams) {
+        AuthUser currentUser = UserContext.getCurrentUser();
+        orderSearchParams.setMemberId(currentUser.getId());
+        return ResultUtil.data(orderService.queryByParams(orderSearchParams));
+    }
+
+    @ApiOperation(value = "订单明细")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderSn", value = "订单编号", required = true, paramType = "path")
+    })
+    @GetMapping(value = "/{orderSn}")
+    public ResultMessage<OrderDetailVO> detail(@NotNull(message = "订单编号不能为空") @PathVariable("orderSn") String orderSn) {
+        return ResultUtil.data(orderService.queryDetail(orderSn));
+    }
+
+    @ApiOperation(value = "确认收货")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderSn", value = "订单编号", required = true, paramType = "path")
+    })
+    @PostMapping(value = "/{orderSn}/receiving")
+    public ResultMessage<Object> receiving(@NotNull(message = "订单编号不能为空") @PathVariable("orderSn") String orderSn) {
+        Order order = orderService.getBySn(orderSn);
+        if (order == null) {
+            return ResultUtil.error(ResultCode.ORDER_NOT_EXIST);
+        }
+        //判定是否是待收货状态
+        if (!order.getOrderStatus().equals(OrderStatusEnum.DELIVERED.name())) {
+            return ResultUtil.error(ResultCode.ORDER_DELIVERED_ERROR);
+        }
+        orderService.complete(orderSn);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+    @ApiOperation(value = "取消订单")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderSn", value = "订单编号", required = true, dataType = "String", paramType = "path"),
+            @ApiImplicitParam(name = "reason", value = "取消原因", required = true, dataType = "String", paramType = "query")
+    })
+    @PostMapping(value = "/{orderSn}/cancel")
+    public ResultMessage<Object> cancel(@ApiIgnore @PathVariable String orderSn, @RequestParam String reason) {
+        orderService.cancel(orderSn, reason);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+    @ApiOperation(value = "删除订单")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderSn", value = "订单编号", required = true, dataType = "String", paramType = "path")
+    })
+    @DeleteMapping(value = "/{orderSn}")
+    public ResultMessage<Object> deleteOrder(@PathVariable String orderSn) {
+        orderService.deleteOrder(orderSn);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+    @ApiOperation(value = "查询物流踪迹")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderSn", value = "订单编号", required = true, dataType = "String", paramType = "path")
+    })
+    @PostMapping(value = "/getTraces/{orderSn}")
+    public ResultMessage<Object> getTraces(@NotBlank(message = "订单编号不能为空") @PathVariable String orderSn) {
+        return ResultUtil.data(orderService.getTraces(orderSn));
+    }
+
+
+    @ApiOperation(value = "开票")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderSn", value = "订单编号", required = true, dataType = "String", paramType = "path")
+    })
+    @PostMapping(value = "/receipt/{orderSn}")
+    public ResultMessage<Object> invoice(@NotBlank(message = "订单编号不能为空") @PathVariable String orderSn) {
+        return ResultUtil.data(orderService.invoice(orderSn));
+    }
+
+
+}

+ 99 - 0
buyer-api/src/main/java/cn/lili/controller/trade/OrderComplaintBuyerController.java

@@ -0,0 +1,99 @@
+package cn.lili.controller.trade;
+
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.security.AuthUser;
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.order.order.entity.dos.OrderComplaint;
+import cn.lili.modules.order.order.entity.dto.OrderComplaintDTO;
+import cn.lili.modules.order.order.entity.enums.CommunicationOwnerEnum;
+import cn.lili.modules.order.order.entity.vo.OrderComplaintCommunicationVO;
+import cn.lili.modules.order.order.entity.vo.OrderComplaintSearchParams;
+import cn.lili.modules.order.order.entity.vo.OrderComplaintVO;
+import cn.lili.modules.order.order.service.OrderComplaintCommunicationService;
+import cn.lili.modules.order.order.service.OrderComplaintService;
+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 lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 买家端,交易投诉接口
+ *
+ * @author paulG
+ * @since 2020/12/7
+ **/
+@RestController
+@Api(tags = "买家端,交易投诉接口")
+@RequestMapping("/buyer/complain")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class OrderComplaintBuyerController {
+
+    /**
+     * 交易投诉
+     */
+    private final OrderComplaintService orderComplaintService;
+
+    /**
+     * 交易投诉沟通
+     */
+    private final OrderComplaintCommunicationService orderComplaintCommunicationService;
+
+
+    @ApiOperation(value = "通过id获取")
+    @ApiImplicitParam(name = "id", value = "投诉单ID", required = true, paramType = "path")
+    @GetMapping(value = "/{id}")
+    public ResultMessage<OrderComplaintVO> get(@PathVariable String id) {
+        return ResultUtil.data(orderComplaintService.getOrderComplainById(id));
+    }
+
+    @ApiOperation(value = "分页获取")
+    @GetMapping
+    public ResultMessage<IPage<OrderComplaint>> get(OrderComplaintSearchParams searchParams, PageVO pageVO) {
+        searchParams.setMemberId(UserContext.getCurrentUser().getId());
+        return ResultUtil.data(orderComplaintService.getOrderComplainByPage(searchParams, pageVO));
+
+    }
+
+    @ApiOperation(value = "添加交易投诉")
+    @PostMapping
+    public ResultMessage<OrderComplaint> add(@Valid OrderComplaintDTO orderComplaintDTO) {
+        return ResultUtil.data(orderComplaintService.addOrderComplain(orderComplaintDTO));
+    }
+
+    @ApiOperation(value = "添加交易投诉对话")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "complainId", value = "投诉单ID", required = true, paramType = "query"),
+            @ApiImplicitParam(name = "content", value = "内容", required = true, paramType = "query")
+    })
+    @PostMapping("/communication")
+    public ResultMessage<OrderComplaintCommunicationVO> addCommunication(@RequestParam String complainId, @RequestParam String content) {
+        AuthUser currentUser = UserContext.getCurrentUser();
+        OrderComplaintCommunicationVO communicationVO = new OrderComplaintCommunicationVO(complainId, content, CommunicationOwnerEnum.BUYER.name(), currentUser.getId(), currentUser.getNickName());
+        if (orderComplaintCommunicationService.addCommunication(communicationVO)) {
+            return ResultUtil.data(communicationVO);
+
+        }
+        return ResultUtil.error(ResultCode.ERROR);
+    }
+
+    @ApiOperation(value = "取消售后")
+    @ApiImplicitParam(name = "id", value = "投诉单ID", required = true, paramType = "path")
+    @PutMapping(value = "/status/{id}")
+    public ResultMessage<Object> cancel(@PathVariable String id) {
+        if (orderComplaintService.cancel(id)) {
+            return ResultUtil.success(ResultCode.SUCCESS);
+        }
+        return ResultUtil.error(ResultCode.ERROR);
+    }
+
+
+}

+ 51 - 0
buyer-api/src/main/java/cn/lili/controller/trade/ReceiptBuyerController.java

@@ -0,0 +1,51 @@
+package cn.lili.controller.trade;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.order.order.entity.dos.Receipt;
+import cn.lili.modules.order.order.entity.dto.OrderReceiptDTO;
+import cn.lili.modules.order.order.entity.dto.ReceiptSearchParams;
+import cn.lili.modules.order.order.service.ReceiptService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 买家端,发票接口
+ *
+ * @author paulG
+ * @since 2021/1/12
+ **/
+@RestController
+@Api(tags = "买家端,发票接口")
+@RequestMapping("/buyer/trade/receipt")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class ReceiptBuyerController {
+
+    private final ReceiptService receiptService;
+
+    @ApiOperation(value = "获取发票详情")
+    @GetMapping("/{id}")
+    public ResultMessage<Receipt> getDetail(@PathVariable String id) {
+        return ResultUtil.data(this.receiptService.getDetail(id));
+    }
+
+    @ApiOperation(value = "获取发票分页信息")
+    @GetMapping
+    public ResultMessage<IPage<OrderReceiptDTO>> getPage(ReceiptSearchParams searchParams, PageVO pageVO) {
+        return ResultUtil.data(this.receiptService.getReceiptData(searchParams, pageVO));
+    }
+
+    @ApiOperation(value = "保存发票信息")
+    @PostMapping
+    public ResultMessage<Receipt> save(@Valid Receipt receipt) {
+        return ResultUtil.data(receiptService.saveReceipt(receipt));
+    }
+
+}

+ 46 - 0
buyer-api/src/main/java/cn/lili/controller/trade/RechargeTradeBuyerController.java

@@ -0,0 +1,46 @@
+package cn.lili.controller.trade;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.order.trade.entity.dos.Recharge;
+import cn.lili.modules.order.trade.service.RechargeService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+
+/**
+ * 买家端,预存款充值记录接口
+ *
+ * @author paulG
+ * @date: 2020/11/16 10:07 下午
+ */
+@RestController
+@Api(tags = "买家端,预存款充值记录接口")
+@RequestMapping("/buyer/trade/recharge")
+@Transactional(rollbackFor = Exception.class)
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class RechargeTradeBuyerController {
+
+    private final RechargeService rechargeService;
+
+    @PostMapping
+    @ApiOperation(value = "创建余额充值订单")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "price", value = "充值金额", required = true, dataType = "double", paramType = "query")
+    })
+    public ResultMessage<Recharge> create(@Max(value = 10000, message = "充值金额单次最多允许充值10000元") @Min(value = 1, message = "充值金额单次最少充值金额为1元") Double price) {
+        Recharge recharge = this.rechargeService.recharge(price);
+        return ResultUtil.data(recharge);
+    }
+
+}

+ 44 - 0
buyer-api/src/main/java/cn/lili/controller/trade/WalletLogBuyerController.java

@@ -0,0 +1,44 @@
+package cn.lili.controller.trade;
+
+import cn.lili.common.security.AuthUser;
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.utils.PageUtil;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.order.trade.entity.dos.WalletLog;
+import cn.lili.modules.order.trade.service.WalletLogService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+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 pikachu
+ * @date: 2020/11/16 10:07 下午
+ */
+@RestController
+@Api(tags = "买家端,预存款变动日志记录接口")
+@RequestMapping("/buyer/wallet/log")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class WalletLogBuyerController {
+
+    private final WalletLogService walletLogService;
+
+    @ApiOperation(value = "分页获取预存款变动日志")
+    @GetMapping
+    public ResultMessage<IPage<WalletLog>> getByPage(PageVO page) {
+        //获取当前登录用户
+        AuthUser authUser = UserContext.getCurrentUser();
+        //构建查询 返回数据
+        IPage<WalletLog> depositLogPage = walletLogService.page(PageUtil.initPage(page), new QueryWrapper<WalletLog>().eq("member_id", authUser.getId()));
+        return ResultUtil.data(depositLogPage);
+    }
+}

+ 120 - 0
buyer-api/src/main/java/cn/lili/security/BuyerAuthenticationFilter.java

@@ -0,0 +1,120 @@
+package cn.lili.security;
+
+import cn.hutool.core.util.StrUtil;
+import cn.lili.common.cache.Cache;
+import cn.lili.common.cache.CachePrefix;
+import cn.lili.common.security.AuthUser;
+import cn.lili.common.security.enums.SecurityEnum;
+import cn.lili.common.security.enums.UserEnums;
+import cn.lili.common.token.SecretKeyUtil;
+import cn.lili.common.utils.ResponseUtil;
+import com.google.gson.Gson;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwts;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * 认证结果过滤器
+ *
+ * @author Chopper
+ * @version v4.1
+ * @date 2020/11/17 3:37 下午
+ * @Description:
+ * @since
+ */
+@Slf4j
+public class BuyerAuthenticationFilter extends BasicAuthenticationFilter {
+
+
+    /**
+     * 缓存
+     */
+    private final Cache cache;
+
+    /**
+     * 自定义构造器
+     *
+     * @param authenticationManager
+     * @param cache
+     */
+    public BuyerAuthenticationFilter(AuthenticationManager authenticationManager,
+                                     Cache cache) {
+        super(authenticationManager);
+        this.cache = cache;
+    }
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
+
+        //从header中获取jwt
+        String jwt = request.getHeader(SecurityEnum.HEADER_TOKEN.getValue());
+        try {
+            // 如果没有token 则return
+            if (StrUtil.isBlank(jwt)) {
+                chain.doFilter(request, response);
+                return;
+            }
+            //获取用户信息,存入context
+            UsernamePasswordAuthenticationToken authentication = getAuthentication(jwt, response);
+            SecurityContextHolder.getContext().setAuthentication(authentication);
+        } catch (Exception e) {
+            log.error("BuyerAuthenticationFilter-> member authentication exception:", e);
+        }
+        chain.doFilter(request, response);
+    }
+
+    /**
+     * 解析用户
+     *
+     * @param jwt
+     * @param response
+     * @return
+     */
+    private UsernamePasswordAuthenticationToken getAuthentication(String jwt, HttpServletResponse response) {
+
+        try {
+            Claims claims
+                    = Jwts.parser()
+                    .setSigningKey(SecretKeyUtil.generalKeyByDecoders())
+                    .parseClaimsJws(jwt).getBody();
+            //获取存储在claims中的用户信息
+            String json = claims.get(SecurityEnum.USER_CONTEXT.getValue()).toString();
+            AuthUser authUser = new Gson().fromJson(json, AuthUser.class);
+
+            // 校验redis中是否有权限
+            if (cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MEMBER) + jwt)) {
+                //构造返回信息
+                List<GrantedAuthority> auths = new ArrayList<>();
+                auths.add(new SimpleGrantedAuthority("ROLE_" + authUser.getRole().name()));
+                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(authUser.getUsername(), null, auths);
+                authentication.setDetails(authUser);
+                return authentication;
+            }
+            ResponseUtil.output(response, 403, ResponseUtil.resultMap(false, 403, "登录已失效,请重新登录"));
+            return null;
+        } catch (ExpiredJwtException e) {
+            log.debug("user analysis exception:", e);
+        } catch (Exception e) {
+            log.error("user analysis exception:", e);
+        }
+        return null;
+    }
+
+}
+

+ 86 - 0
buyer-api/src/main/java/cn/lili/security/BuyerSecurityConfig.java

@@ -0,0 +1,86 @@
+package cn.lili.security;
+
+import cn.lili.common.cache.Cache;
+import cn.lili.common.security.CustomAccessDeniedHandler;
+import cn.lili.common.utils.SpringContextUtil;
+import cn.lili.config.properties.IgnoredUrlsProperties;
+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;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.web.cors.CorsConfigurationSource;
+
+/**
+ * spring Security 核心配置类 Buyer安全配置中心
+ *
+ * @author Chopper
+ * @version v4.0
+ * @Description:
+ * @since 2020/11/14 16:20
+ */
+
+@Slf4j
+@Configuration
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class BuyerSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    /**
+     * 忽略验权配置
+     */
+    private final IgnoredUrlsProperties ignoredUrlsProperties;
+
+
+
+    /**
+     * spring security -》 权限不足处理
+     */
+    private final CustomAccessDeniedHandler accessDeniedHandler;
+
+
+    private final Cache<String> cache;
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+
+        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
+                .authorizeRequests();
+        // 配置的url 不需要授权
+        for (String url : ignoredUrlsProperties.getUrls()) {
+            registry.antMatchers(url).permitAll();
+        }
+        registry
+                .and()
+                // 禁止网页iframe
+                .headers().frameOptions().disable()
+                .and()
+                .logout()
+                .permitAll()
+                .and()
+                .authorizeRequests()
+                // 任何请求
+                .anyRequest()
+                // 需要身份认证
+                .authenticated()
+                .and()
+                // 允许跨域
+                .cors().configurationSource((CorsConfigurationSource) SpringContextUtil.getBean("corsConfigurationSource")).and()
+                // 关闭跨站请求防护
+                .csrf().disable()
+                // 前后端分离采用JWT 不需要session
+                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+                .and()
+                // 自定义权限拒绝处理类
+                .exceptionHandling().accessDeniedHandler(accessDeniedHandler)
+                .and()
+                // 添加JWT认证过滤器
+                .addFilter(new BuyerAuthenticationFilter(authenticationManager(), cache));
+    }
+
+
+}

+ 303 - 0
buyer-api/src/main/resources/application.yml

@@ -0,0 +1,303 @@
+server:
+  port: 8888
+
+  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
+  # 文件大小上传配置
+  servlet:
+    multipart:
+      max-file-size: 20MB
+      max-request-size: 20MB
+  cache:
+    type: redis
+  #JPA
+  jpa:
+    # 自动生成表结构
+    generate-ddl: true
+    open-in-view: false
+  #jackson json解析
+  jackson:
+    time-zone: GMT+8
+    serialization:
+      #关闭jackson 对json做解析
+      fail-on-empty-beans: false
+
+  # mongodb
+  data:
+    mongodb:
+      host: 127.0.0.1
+      port: 27017
+      database: lilishop
+      username: root
+      password: lilishop
+      authentication-database: admin
+  #      replica-set-name: mongoreplset
+
+  # 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
+  #mysql
+  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
+
+# 忽略TOKEN 鉴权 的url
+ignored:
+  urls:
+    - /editor-app/**
+    - /actuator**
+    - /actuator/**
+    - /MP_verify_qSyvBPhDsPdxvOhC.txt
+    - /weixin/**
+    - /source/**
+    - /buyer/store/**
+    - /buyer/mini-program/**
+    - /buyer/cashier/**
+    - /buyer/pageData/**
+    - /buyer/article/**
+    - /buyer/goods/**
+    - /buyer/category/**
+    - /buyer/shop/**
+    - /buyer/connect/**
+    - /buyer/members/**
+    - /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: debug
+    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: https://pc-b2b2c.pickmall.cn
+    wap: https://m-b2b2c.pickmall.cn
+    store: https://store-b2b2c.pickmall.cn
+    admin: https://admin-b2b2c.pickmall.cn
+  #api地址
+  api:
+    buyer: https://buyer-api.pickmall.cn
+    common: https://common-api.pickmall.cn
+    manager: https://admin-api.pickmall.cn
+    store: https://store-api.pickmall.cn
+
+  # 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
+      after-sale-topic: lili_after_sale_topic
+      after-sale-group: lili_after_sale_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

+ 19 - 0
buyer-api/src/main/resources/banner.txt

@@ -0,0 +1,19 @@
+ ___       ___  ___       ___                 ________ ________  _______   ________  _____ ______   ___       __   ________  ________  ___  __       
+|\  \     |\  \|\  \     |\  \               |\  _____\\   __  \|\  ___ \ |\   __  \|\   _ \  _   \|\  \     |\  \|\   __  \|\   __  \|\  \|\  \     
+\ \  \    \ \  \ \  \    \ \  \  ____________\ \  \__/\ \  \|\  \ \   __/|\ \  \|\  \ \  \\\__\ \  \ \  \    \ \  \ \  \|\  \ \  \|\  \ \  \/  /|_   
+ \ \  \    \ \  \ \  \    \ \  \|\____________\ \   __\\ \   _  _\ \  \_|/_\ \   __  \ \  \\|__| \  \ \  \  __\ \  \ \  \\\  \ \   _  _\ \   ___  \  
+  \ \  \____\ \  \ \  \____\ \  \|____________|\ \  \_| \ \  \\  \\ \  \_|\ \ \  \ \  \ \  \    \ \  \ \  \|\__\_\  \ \  \\\  \ \  \\  \\ \  \\ \  \ 
+   \ \_______\ \__\ \_______\ \__\              \ \__\   \ \__\\ _\\ \_______\ \__\ \__\ \__\    \ \__\ \____________\ \_______\ \__\\ _\\ \__\\ \__\
+    \|_______|\|__|\|_______|\|__|               \|__|    \|__|\|__|\|_______|\|__|\|__|\|__|     \|__|\|____________|\|_______|\|__|\|__|\|__| \|__|
+
+
+
+                                                 ___       ___  ___       ___                 ________  ___  ___  ________  ________
+                                                |\  \     |\  \|\  \     |\  \               |\   ____\|\  \|\  \|\   __  \|\   __  \
+                                                \ \  \    \ \  \ \  \    \ \  \  ____________\ \  \___|\ \  \\\  \ \  \|\  \ \  \|\  \
+                                                 \ \  \    \ \  \ \  \    \ \  \|\____________\ \_____  \ \   __  \ \  \\\  \ \   ____\
+                                                  \ \  \____\ \  \ \  \____\ \  \|____________|\|____|\  \ \  \ \  \ \  \\\  \ \  \___|
+                                                   \ \_______\ \__\ \_______\ \__\               ____\_\  \ \__\ \__\ \_______\ \__\
+                                                    \|_______|\|__|\|_______|\|__|              |\_________\|__|\|__|\|_______|\|__|
+                                                                                                \|_________|
+

+ 1 - 0
buyer-api/src/main/resources/static/MP_verify_qSyvBPhDsPdxvOhC.txt

@@ -0,0 +1 @@
+qSyvBPhDsPdxvOhC

+ 75 - 0
buyer-api/src/test/java/cn/lili/buyer/test/cart/CartTest.java

@@ -0,0 +1,75 @@
+package cn.lili.buyer.test.cart;
+
+import cn.hutool.json.JSONUtil;
+import cn.lili.modules.goods.entity.vos.CategoryVO;
+import cn.lili.modules.goods.service.CategoryService;
+import cn.lili.modules.order.cart.entity.dto.TradeDTO;
+import cn.lili.modules.order.cart.entity.enums.CartTypeEnum;
+import cn.lili.modules.order.cart.entity.vo.TradeParams;
+import cn.lili.modules.order.cart.service.CartService;
+import cn.lili.modules.payment.service.PaymentService;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+/**
+ * @author paulG
+ * @since 2020/11/14
+ **/
+@RunWith(SpringRunner.class)
+@SpringBootTest
+class CartTest {
+
+    @Autowired
+    private CartService cartService;
+
+    @Autowired
+    private CategoryService categoryService;
+
+    @Autowired
+    private PaymentService paymentService;
+
+
+    @Test
+    void getAll() {
+        TradeDTO allTradeDTO = cartService.getAllTradeDTO();
+        Assertions.assertNotNull(allTradeDTO);
+        System.out.println(JSONUtil.toJsonStr(allTradeDTO));
+    }
+
+    @Test
+    void deleteAll() {
+        cartService.delete(new String[]{"1344220459059404800"});
+        Assertions.assertTrue(true);
+    }
+
+    @Test
+    void createTrade() {
+//        TradeDTO allTradeDTO = cartService.getAllTradeDTO();
+//        Assert.assertNotNull(allTradeDTO);
+//        System.out.println(JsonUtil.objectToJson(allTradeDTO));
+        cartService.createTrade(new TradeParams());
+    }
+
+    @Test
+    void getAllCategory() {
+        List<CategoryVO> allCategory = categoryService.categoryTree();
+        for (CategoryVO categoryVO : allCategory) {
+            System.out.println(categoryVO);
+        }
+        Assertions.assertTrue(true);
+    }
+
+
+    @Test
+    void storeCoupon() {
+        cartService.selectCoupon("1333318596239843328", CartTypeEnum.CART.name(), true);
+        Assertions.assertTrue(true);
+    }
+
+}

+ 52 - 0
buyer-api/src/test/java/cn/lili/buyer/test/cart/FileTest.java

@@ -0,0 +1,52 @@
+package cn.lili.buyer.test.cart;
+
+
+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 org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.*;
+import java.net.URL;
+import java.util.List;
+
+/**
+ * @author paulG
+ * @since 2020/11/14
+ **/
+@RunWith(SpringRunner.class)
+@SpringBootTest
+class FileTest {
+
+
+    @Autowired
+    private FileManagerPlugin fileManagerPlugin;
+
+    @Autowired
+    private BrandService brandService;
+
+    @Test
+    void test() throws Exception {
+        List<Brand> categoryList = brandService.list();
+        for (Brand brand : categoryList) {
+            try {
+                if (StringUtil.isEmpty(brand.getLogo()) || brand.getLogo().indexOf("lilishop") > 1) {
+                    continue;
+                }
+                URL url = new URL(brand.getLogo());
+                InputStream inputStream = url.openStream();
+                // 上传至第三方云服务或服务器
+                brand.setLogo(fileManagerPlugin.inputStreamUpload(inputStream, brand.getId() + ".png"));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        brandService.updateBatchById(categoryList);
+    }
+
+}

+ 29 - 0
buyer-api/src/test/java/cn/lili/buyer/test/cart/MemberCouponTest.java

@@ -0,0 +1,29 @@
+package cn.lili.buyer.test.cart;
+
+import cn.lili.modules.promotion.service.MemberCouponService;
+import org.junit.Assert;
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * @author paulG
+ * @since 2020/11/27
+ **/
+@RunWith(SpringRunner.class)
+@SpringBootTest
+class MemberCouponTest {
+
+    @Autowired
+    private MemberCouponService memberCouponService;
+
+    @Test
+    void receiveCoupon() {
+        memberCouponService.receiveCoupon("1333318596239843328", "1326834797335306240", "1");
+        Assert.assertTrue(true);
+    }
+
+
+}

+ 298 - 0
buyer-api/src/test/resources/application.yml

@@ -0,0 +1,298 @@
+server:
+  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://192.168.0.116:8000
+  # mongodb
+  data:
+    mongodb:
+      host: 192.168.0.116
+      port: 27017
+      database: lilishop
+      username: root
+      password: lilishop
+      authentication-database: admin
+  #      replica-set-name: mongoreplset
+  cache:
+    type: redis
+  #amqp
+  #  rabbitmq:
+  #    host: 192.168.0.116
+  jpa:
+    # 自动生成表结构
+    generate-ddl: true
+    open-in-view: false
+  # Redis
+  redis:
+    host: 192.168.0.116
+    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://192.168.0.116:3306/new-lili?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/store/**
+    - /buyer/connect/**
+    - /buyer/members/**
+    - /buyer/promotion/pintuan/**
+    - /buyer/promotion/seckill/**
+    - /buyer/promotion/pointsGoods/**
+    - /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://192.168.0.116:8888
+    wap: http://192.168.0.116:8888
+    seller: http://192.168.0.116:8888
+    admin: http://192.168.0.116:8888
+  #api地址
+  api:
+    buyer: https://z171l91606.51mypc.cn
+    base: http://192.168.0.116:8888
+    manager: http://192.168.0.116:8888
+    seller: http://192.168.0.116: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: 192.168.0.116: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: 192.168.0.116:9876
+  producer:
+    group: lili_group
+    send-message-timeout: 30000
+
+xxl:
+  job:
+    admin:
+      addresses: http://192.168.0.116:9001/xxl-job-admin
+    executor:
+      appname: xxl-job-executor-lilishop
+      address:
+      ip:
+      port: 8891
+      logpath: ./xxl-job/executor
+      logretentiondays: 7

+ 33 - 0
common-api/pom.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>cn.lili</groupId>
+        <artifactId>lili-shop-parent</artifactId>
+        <version>1.0.1</version>
+    </parent>
+
+    <groupId>cn.lili</groupId>
+    <artifactId>common-api</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>cn.lili</groupId>
+            <artifactId>framework</artifactId>
+            <version>1.0.1</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+    
+</project>

+ 21 - 0
common-api/src/main/java/cn/lili/CommonApiApplication.java

@@ -0,0 +1,21 @@
+package cn.lili;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cache.annotation.EnableCaching;
+
+/**
+ * 基础API
+ *
+ * @author Chopper
+ * @date 2020/11/17 3:38 下午
+ */
+@EnableCaching
+@SpringBootApplication
+public class CommonApiApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(CommonApiApplication.class, args);
+    }
+
+}

+ 99 - 0
common-api/src/main/java/cn/lili/controller/common/FileController.java

@@ -0,0 +1,99 @@
+package cn.lili.controller.common;
+
+import cn.lili.common.cache.Cache;
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.exception.ServiceException;
+import cn.lili.common.security.AuthUser;
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.security.enums.UserEnums;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.PageVO;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.common.vo.SearchVO;
+import cn.lili.modules.file.entity.File;
+import cn.lili.modules.file.entity.dto.FileOwnerDTO;
+import cn.lili.modules.file.service.FileService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+
+/**
+ * 文件管理管理接口
+ *
+ * @author Chopper
+ * @date 2020/11/26 15:41
+ */
+@RestController
+@Api(tags = "文件管理管理接口")
+@RequestMapping("/common/file")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class FileController {
+
+    private final FileService fileService;
+
+    private final Cache cache;
+
+    @ApiOperation(value = "获取自己的图片资源")
+    @GetMapping
+    @ApiImplicitParam(name = "title", value = "名称模糊匹配")
+    public ResultMessage<IPage<File>> getFileList(@RequestHeader String accessToken, File file, SearchVO searchVO, PageVO pageVo) {
+
+        AuthUser authUser = UserContext.getAuthUser(cache, accessToken);
+        FileOwnerDTO fileOwnerDTO = new FileOwnerDTO();
+        //只有买家才写入自己id
+        if (authUser.getRole().equals(UserEnums.MEMBER)) {
+            fileOwnerDTO.setOwnerId(authUser.getId());
+        }//如果是店铺,则写入店铺id
+        else if (authUser.getRole().equals(UserEnums.STORE)) {
+            fileOwnerDTO.setOwnerId(authUser.getStoreId());
+        }
+        fileOwnerDTO.setUserEnums(authUser.getRole().name());
+        return ResultUtil.data(fileService.customerPageOwner(fileOwnerDTO, file, searchVO, pageVo));
+    }
+
+    @ApiOperation(value = "文件重命名")
+    @PostMapping(value = "/rename")
+    public ResultMessage<File> upload(@RequestHeader String accessToken, String id, String newName) {
+
+        AuthUser authUser = UserContext.getAuthUser(cache, accessToken);
+        File file = fileService.getById(id);
+        file.setName(newName);
+        //操作图片属性判定
+        switch (authUser.getRole()) {
+            case MEMBER:
+                if (file.getOwnerId().equals(authUser.getId()) && file.getUserEnums().equals(authUser.getRole().name())) {
+                    break;
+                }
+                throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
+            case STORE:
+                if (file.getOwnerId().equals(authUser.getStoreId()) && file.getUserEnums().equals(authUser.getRole().name())) {
+                    break;
+                }
+                throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
+            case MANAGER:
+                if (file.getUserEnums().equals(authUser.getRole().name())) {
+                    break;
+                }
+                throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
+        }
+        fileService.updateById(file);
+        return ResultUtil.data(file);
+    }
+
+    @ApiOperation(value = "文件删除")
+    @DeleteMapping(value = "/delete/{ids}")
+    public ResultMessage delete(@RequestHeader String accessToken, @PathVariable List<String> ids) {
+
+        AuthUser authUser = UserContext.getAuthUser(cache, accessToken);
+        fileService.batchDelete(ids, authUser);
+        return ResultUtil.success(ResultCode.SUCCESS);
+    }
+
+}

+ 38 - 0
common-api/src/main/java/cn/lili/controller/common/LogoController.java

@@ -0,0 +1,38 @@
+package cn.lili.controller.common;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.system.entity.enums.SettingEnum;
+import cn.lili.modules.system.service.SettingService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+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 Chopper
+ * @date 2020/11/26 15:41
+ */
+@RestController
+@Api(tags = "文件管理管理接口")
+@RequestMapping("/common/logo")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class LogoController {
+
+    @Autowired
+    private SettingService settingService;
+
+    @ApiOperation(value = "获取logo")
+    @GetMapping
+    public ResultMessage<Object> getFileList() {
+        return ResultUtil.data(settingService.get(SettingEnum.BASE_SETTING.name()));
+    }
+
+
+}

+ 59 - 0
common-api/src/main/java/cn/lili/controller/common/RegionController.java

@@ -0,0 +1,59 @@
+package cn.lili.controller.common;
+
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.base.service.RegionService;
+import cn.lili.modules.system.entity.dos.Region;
+import cn.lili.modules.system.entity.vo.RegionVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+
+/**
+ * 地址信息接口
+ *
+ * @author Chopper
+ * @date: 2020/11/16 10:07 下午
+ */
+@RestController
+@Api(tags = "地址信息接口")
+@RequestMapping("/common/region")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class RegionController {
+
+
+    private final RegionService regionService;
+
+    @ApiOperation(value = "点地图获取地址信息")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "cityCode", value = "城市code", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "townName", value = "镇名称", dataType = "Long", paramType = "query")
+    })
+    @GetMapping(value = "/region")
+    public ResultMessage<Object> getRegion(@RequestParam String cityCode,@RequestParam String townName) {
+        return ResultUtil.data(regionService.getRegion(cityCode,townName));
+    }
+
+
+    @GetMapping(value = "/item/{id}")
+    @ApiImplicitParam(name = "id", value = "地区ID", required = true, dataType = "String", paramType = "path")
+    @ApiOperation(value = "通过id获取子地区")
+    public ResultMessage<List<Region>> getItem(@PathVariable String id) {
+        return ResultUtil.data(regionService.getItem(id));
+    }
+
+    @GetMapping(value = "/allCity")
+    @ApiOperation(value = "获取所有的省-市")
+    public ResultMessage<List<RegionVO>> getAllCity() {
+        return ResultUtil.data(regionService.getAllCity());
+    }
+
+
+}

+ 51 - 0
common-api/src/main/java/cn/lili/controller/common/SliderImageController.java

@@ -0,0 +1,51 @@
+package cn.lili.controller.common;
+
+import cn.lili.common.aop.limiter.annotation.LimitPoint;
+import cn.lili.common.exception.ServiceException;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.verification.enums.VerificationEnums;
+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.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 滑块验证码接口
+ *
+ * @author Chopper
+ * @date 2020/11/26 15:41
+ */
+@RequestMapping("/common/slider")
+@RestController
+@Api(tags = "滑块验证码接口")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class SliderImageController {
+
+
+    private final VerificationService verificationService;
+
+    //一分钟同一个ip请求10次
+    @LimitPoint(name = "slider_image", key = "verification")
+    @GetMapping("/{verificationEnums}")
+    @ApiOperation(value = "获取校验接口")
+    public ResultMessage getSliderImage(@RequestHeader String uuid, @PathVariable VerificationEnums verificationEnums) {
+        try {
+            return ResultUtil.data(verificationService.createVerification(verificationEnums, uuid));
+        } catch (ServiceException e) {
+            throw e;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @LimitPoint(name = "slider_image", key = "verification_pre_check", limit = 600)
+    @PostMapping("/{verificationEnums}")
+    @ApiOperation(value = "验证码预校验")
+    public ResultMessage verificationImage(Integer xPos, @RequestHeader String uuid, @PathVariable VerificationEnums verificationEnums) {
+        return ResultUtil.data(verificationService.preCheck(xPos, uuid, verificationEnums));
+    }
+}

+ 53 - 0
common-api/src/main/java/cn/lili/controller/common/SmsController.java

@@ -0,0 +1,53 @@
+package cn.lili.controller.common;
+
+import cn.lili.common.aop.limiter.annotation.LimitPoint;
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.sms.SmsUtil;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.verification.enums.VerificationEnums;
+import cn.lili.common.verification.service.VerificationService;
+import cn.lili.common.vo.ResultMessage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 短信验证码接口
+ *
+ * @author Chopper
+ * @date 2020/11/26 15:41
+ */
+@RestController
+@Api(tags = "短信验证码接口")
+@RequestMapping("/common/sms")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class SmsController {
+
+    private final SmsUtil smsUtil;
+
+    private final VerificationService verificationService;
+
+    //一分钟同一个ip请求1次
+    @LimitPoint(name = "sms_send", key = "sms")
+    @ApiImplicitParams({
+            @ApiImplicitParam(paramType = "path", dataType = "String", name = "mobile", value = "手机号"),
+            @ApiImplicitParam(paramType = "header", dataType = "String", name = "uuid", value = "uuid"),
+    })
+    @GetMapping("/{verificationEnums}/{mobile}")
+    @ApiOperation(value = "发送短信验证码")
+    public ResultMessage getSmsCode(
+            @RequestHeader String uuid,
+            @PathVariable String mobile,
+            @PathVariable VerificationEnums verificationEnums) {
+        if (verificationService.check(uuid, verificationEnums)) {
+            smsUtil.sendSmsCode(mobile, verificationEnums, uuid);
+            return ResultUtil.success(ResultCode.VERIFICATION_SEND_SUCCESS);
+        } else {
+            return ResultUtil.error(ResultCode.VERIFICATION_SMS_EXPIRED_ERROR);
+        }
+    }
+}

+ 106 - 0
common-api/src/main/java/cn/lili/controller/common/UploadController.java

@@ -0,0 +1,106 @@
+package cn.lili.controller.common;
+
+import cn.hutool.core.util.StrUtil;
+import cn.lili.common.cache.Cache;
+import cn.lili.common.enums.ResultCode;
+import cn.lili.common.exception.ServiceException;
+import cn.lili.common.security.AuthUser;
+import cn.lili.common.security.context.UserContext;
+import cn.lili.common.security.enums.UserEnums;
+import cn.lili.common.utils.Base64DecodeMultipartFile;
+import cn.lili.common.utils.CommonUtil;
+import cn.lili.common.utils.ResultUtil;
+import cn.lili.common.utils.StringUtils;
+import cn.lili.common.vo.ResultMessage;
+import cn.lili.modules.file.entity.File;
+import cn.lili.modules.file.plugin.FileManagerPlugin;
+import cn.lili.modules.file.service.FileService;
+import cn.lili.modules.system.entity.dos.Setting;
+import cn.lili.modules.system.entity.enums.SettingEnum;
+import cn.lili.modules.system.service.SettingService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.InputStream;
+
+/**
+ * 文件上传接口
+ *
+ * @author Chopper
+ * @date 2020/11/26 15:41
+ */
+@Slf4j
+@RestController
+@Api(tags = "文件上传接口")
+@RequestMapping("/common/upload")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class UploadController {
+
+    private final FileService fileService;
+
+    private final SettingService settingService;
+
+    private final FileManagerPlugin fileManagerPlugin;
+
+    private final Cache cache;
+
+    @ApiOperation(value = "文件上传")
+    @PostMapping(value = "/file")
+    public ResultMessage<Object> upload(MultipartFile file,
+                                        String base64,
+                                        @RequestHeader String accessToken) {
+
+
+        AuthUser authUser = UserContext.getAuthUser(cache, accessToken);
+        //如果用户未登录,则无法上传图片
+        if (authUser == null) {
+            throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
+        }
+        Setting setting = settingService.getById(SettingEnum.OSS_SETTING.name());
+        if (setting == null || StrUtil.isBlank(setting.getSettingValue())) {
+            throw new ServiceException(ResultCode.OSS_NOT_EXIST);
+        }
+
+        if (StringUtils.isNotBlank(base64)) {
+            // base64上传
+            file = Base64DecodeMultipartFile.base64Convert(base64);
+        }
+        String result = "";
+        String fileKey = CommonUtil.rename(file.getOriginalFilename());
+        File newFile = new File();
+        try {
+            InputStream inputStream = file.getInputStream();
+            // 上传至第三方云服务或服务器
+            result = fileManagerPlugin.inputStreamUpload(inputStream, fileKey);
+            // 保存数据信息至数据库
+            newFile.setName(file.getOriginalFilename());
+            newFile.setFileSize(file.getSize());
+            newFile.setFileType(file.getContentType());
+            newFile.setFileKey(fileKey);
+            newFile.setUrl(result);
+            newFile.setCreateBy(authUser.getUsername());
+            newFile.setUserEnums(authUser.getRole().name());
+            //如果是店铺,则记录店铺id
+            if (authUser.getRole().equals(UserEnums.STORE.name())) {
+                newFile.setOwnerId(authUser.getStoreId());
+            } else {
+                newFile.setOwnerId(authUser.getId());
+            }
+            fileService.save(newFile);
+        } catch (Exception e) {
+            log.error("文件上传失败", e);
+            return ResultUtil.error(400, e.toString());
+        }
+        return ResultUtil.data(result);
+    }
+
+
+}

+ 68 - 0
common-api/src/main/java/cn/lili/controller/security/CommonSecurityConfig.java

@@ -0,0 +1,68 @@
+package cn.lili.controller.security;
+
+import cn.lili.common.cache.Cache;
+import cn.lili.common.security.CustomAccessDeniedHandler;
+import cn.lili.config.properties.IgnoredUrlsProperties;
+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;
+import org.springframework.web.cors.CorsConfigurationSource;
+
+/**
+ * spring Security 核心配置类 通用安全
+ *
+ * @author Chopper
+ * @version v4.0
+ * @Description:
+ * @since 2020/11/14 16:20
+ */
+@Slf4j
+@Configuration
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class CommonSecurityConfig extends WebSecurityConfigurerAdapter {
+
+
+    /**
+     * 忽略验权配置
+     */
+    private final IgnoredUrlsProperties ignoredUrlsProperties;
+
+    /**
+     * spring security -》 权限不足处理
+     */
+    private final CustomAccessDeniedHandler accessDeniedHandler;
+
+
+    private final Cache<String> cache;
+
+    private final CorsConfigurationSource corsConfigurationSource;
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+
+        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
+                .authorizeRequests();
+        registry
+                .and()
+                // 禁止网页iframe
+                .headers().frameOptions().disable()
+                .and()
+                .authorizeRequests()
+                // 任何请求
+                .anyRequest()
+                // 需要身份认证
+                .permitAll()
+                .and()
+                // 允许跨域
+                .cors().configurationSource(corsConfigurationSource).and()
+                // 关闭跨站请求防护
+                .csrf().disable();
+    }
+
+}

+ 8 - 0
common-api/src/main/resources/META-INF/additional-spring-configuration-metadata.json

@@ -0,0 +1,8 @@
+{
+  "properties": [
+    {
+      "name": "spring.http.multipart.location",
+      "type": "java.lang.String",
+      "description": "Description for spring.http.multipart.location."
+  }
+] }

+ 299 - 0
common-api/src/main/resources/application.yml

@@ -0,0 +1,299 @@
+server:
+  port: 8890
+
+  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: https://pc.b2b2c.pickmall.cn
+    wap: https://m.b2b2c.pickmall.cn
+    store: https://store.b2b2c.pickmall.cn
+    admin: https://admin.b2b2c.pickmall.cn
+  #api地址
+  api:
+    buyer: https://buyer-api.pickmall.cn
+    common: https://common-api.pickmall.cn
+    manager: https://admin-api.pickmall.cn
+    store: https://store-api.pickmall.cn
+
+  # 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

二進制
common-api/src/main/resources/slider/images/1.jpg


二進制
common-api/src/main/resources/slider/images/10.jpg


二進制
common-api/src/main/resources/slider/images/11.jpg


二進制
common-api/src/main/resources/slider/images/12.jpg


二進制
common-api/src/main/resources/slider/images/13.jpg


二進制
common-api/src/main/resources/slider/images/14.jpg


二進制
common-api/src/main/resources/slider/images/15.jpg


二進制
common-api/src/main/resources/slider/images/16.jpg


二進制
common-api/src/main/resources/slider/images/17.jpg


二進制
common-api/src/main/resources/slider/images/18.jpg


二進制
common-api/src/main/resources/slider/images/19.jpg


二進制
common-api/src/main/resources/slider/images/2.jpg


二進制
common-api/src/main/resources/slider/images/20.jpg


二進制
common-api/src/main/resources/slider/images/21.jpg


二進制
common-api/src/main/resources/slider/images/22.jpg


二進制
common-api/src/main/resources/slider/images/23.jpg


二進制
common-api/src/main/resources/slider/images/3.jpg


二進制
common-api/src/main/resources/slider/images/4.jpg


二進制
common-api/src/main/resources/slider/images/5.jpg


二進制
common-api/src/main/resources/slider/images/6.jpg


二進制
common-api/src/main/resources/slider/images/7.jpg


二進制
common-api/src/main/resources/slider/images/8.jpg


二進制
common-api/src/main/resources/slider/images/9.jpg


二進制
common-api/src/main/resources/slider/slider/1-w.png


二進制
common-api/src/main/resources/slider/slider/2-w.png


二進制
common-api/src/main/resources/slider/slider/3-w.png


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