ccj hace 1 año
commit
0b5935f71d
Se han modificado 100 ficheros con 8993 adiciones y 0 borrados
  1. BIN
      .DS_Store
  2. 2 0
      .gitattributes
  3. 70 0
      .gitignore
  4. 145 0
      pom.xml
  5. 22 0
      sendGoodNotPlat.xml
  6. 641 0
      sql/unimall_tmp.sql
  7. BIN
      unimall-admin-api/.DS_Store
  8. 101 0
      unimall-admin-api/pom.xml
  9. BIN
      unimall-admin-api/src/.DS_Store
  10. BIN
      unimall-admin-api/src/main/.DS_Store
  11. BIN
      unimall-admin-api/src/main/java/.DS_Store
  12. BIN
      unimall-admin-api/src/main/java/com/.DS_Store
  13. BIN
      unimall-admin-api/src/main/java/com/iotechn/.DS_Store
  14. BIN
      unimall-admin-api/src/main/java/com/iotechn/unimall/.DS_Store
  15. BIN
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/.DS_Store
  16. 786 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/AdminCheckQuartz.java
  17. 289 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/MyApplicationLisenter.java
  18. 13 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/UnimallAdminApiApplication.java
  19. BIN
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/.DS_Store
  20. 79 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/admin/AdminService.java
  21. 248 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/admin/AdminServiceImpl.java
  22. 72 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/advertisement/AdminAdvertisementService.java
  23. 111 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/advertisement/AdminAdvertisementServiceImpl.java
  24. 40 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/appraise/AdminAppraise.java
  25. 46 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/appraise/AdminAppraiseImpl.java
  26. 62 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/category/AdminCategoryService.java
  27. 301 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/category/AdminCategoryServiceImpl.java
  28. 54 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/config/AdminMerchantConfigService.java
  29. 74 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/config/AdminMerchantConfigServiceImpl.java
  30. 82 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/coupon/AdminCouponService.java
  31. 123 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/coupon/AdminCouponServiceImpl.java
  32. 20 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dashboard/DashboardService.java
  33. 86 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dashboard/DashboardServiceImpl.java
  34. 50 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dict/DictDataService.java
  35. 77 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dict/DictDataserviceImpl.java
  36. 48 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dict/DictTypeService.java
  37. 86 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dict/DictTypeServiceImpl.java
  38. 62 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/freight/AdminFreightTemplateService.java
  39. 146 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/freight/AdminFreightTemplateServiceImpl.java
  40. 64 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/goods/AdminGoodsService.java
  41. 413 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/goods/AdminGoodsServiceImpl.java
  42. 55 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/goods/AdminGroupShopGoodsService.java
  43. 290 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/goods/AdminGroupShopGoodsServiceImpl.java
  44. 40 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/log/loginLog/SysLogininforService.java
  45. 87 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/log/loginLog/SysLogininforServiceImpl.java
  46. 40 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/log/operLog/OperLogService.java
  47. 87 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/log/operLog/OperLogServiceImpl.java
  48. 21 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/monitor/online/UserOnlineService.java
  49. 45 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/monitor/online/UserOnlineServiceImpl.java
  50. 11 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/monitor/server/ServerService.java
  51. 22 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/monitor/server/ServerServiceImpl.java
  52. 57 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/order/AdminOrderService.java
  53. 196 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/order/AdminOrderServiceImpl.java
  54. 54 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/recommend/AdminRecommendService.java
  55. 94 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/recommend/AdminRecommendServiceImpl.java
  56. 65 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/role/RoleService.java
  57. 141 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/role/RoleServiceImpl.java
  58. 76 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/IShopAccountService.java
  59. 61 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/IShopLogService.java
  60. 97 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/IShopOrderService.java
  61. 65 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/IShopTranService.java
  62. 177 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/impl/ShopAccountServiceImpl.java
  63. 129 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/impl/ShopLogServiceImpl.java
  64. 567 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/impl/ShopOrderServiceImpl.java
  65. 138 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/impl/ShopTranServiceImpl.java
  66. 74 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/tools/gen/GenTableService.java
  67. 179 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/tools/gen/GenTableServiceImpl.java
  68. 62 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/user/AdminUserService.java
  69. 686 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/user/AdminUserServiceImpl.java
  70. BIN
      unimall-admin-api/src/main/lib/dangdang-open-sdk.jar
  71. 1 0
      unimall-admin-api/src/main/resources/application.properties
  72. BIN
      unimall-admin/.DS_Store
  73. 17 0
      unimall-admin/.babelrc
  74. 3 0
      unimall-admin/.eslintignore
  75. 185 0
      unimall-admin/.eslintrc.js
  76. 10 0
      unimall-admin/.postcssrc.js
  77. 67 0
      unimall-admin/build/build.js
  78. 64 0
      unimall-admin/build/check-versions.js
  79. BIN
      unimall-admin/build/logo.png
  80. 108 0
      unimall-admin/build/utils.js
  81. 5 0
      unimall-admin/build/vue-loader.conf.js
  82. 107 0
      unimall-admin/build/webpack.base.conf.js
  83. 98 0
      unimall-admin/build/webpack.dev.conf.js
  84. 188 0
      unimall-admin/build/webpack.prod.conf.js
  85. 6 0
      unimall-admin/config/dep.env.js
  86. 6 0
      unimall-admin/config/dev.env.js
  87. 88 0
      unimall-admin/config/index.js
  88. 6 0
      unimall-admin/config/prod.env.js
  89. BIN
      unimall-admin/dist/favicon.ico
  90. 0 0
      unimall-admin/dist/index.html
  91. 0 0
      unimall-admin/dist/static/css/app.b4173d64.css
  92. 1 0
      unimall-admin/dist/static/css/chunk-0042.f12b97fc.css
  93. 1 0
      unimall-admin/dist/static/css/chunk-0661.05e63149.css
  94. 1 0
      unimall-admin/dist/static/css/chunk-0e44.b126e1c1.css
  95. 0 0
      unimall-admin/dist/static/css/chunk-1220.b4ab4382.css
  96. 1 0
      unimall-admin/dist/static/css/chunk-14e1.9f405cf9.css
  97. 0 0
      unimall-admin/dist/static/css/chunk-192f.02e44736.css
  98. 0 0
      unimall-admin/dist/static/css/chunk-1ee7.f42c833d.css
  99. 0 0
      unimall-admin/dist/static/css/chunk-1f81.6c259890.css
  100. 1 0
      unimall-admin/dist/static/css/chunk-21ca.7473bdb6.css

BIN
.DS_Store


+ 2 - 0
.gitattributes

@@ -0,0 +1,2 @@
+*.sql linguist-language=java
+*.html linguist-language=java

+ 70 - 0
.gitignore

@@ -0,0 +1,70 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**
+!**/src/test/**
+
+### 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/
+
+### maven ###
+.mvn
+mvnw
+mvnw.cmd
+
+###properties###
+/unimall-launcher/src/main/resources/application-dev.properties
+/unimall-launcher/src/main/resources/application-prd.properties
+
+### target ###
+/target/
+/unimall-admin-api/target/
+/unimall-app-api/target/
+/unimall-biz/target/
+/unimall-data/target/
+/unimall-core/target/
+/unimall-launcher/target/
+/unimall-plugin-core/target/
+/unimall-app/unpackage/dist/
+/unimall-app/unpackage/resources/
+/unimall-app/unpackage/debug/
+/unimall-admin/dist.zip
+
+###node_modules###
+/unimall-admin/node_modules/
+/unimall-app/node_modules/
+
+
+###logs###
+unimall.log
+unimall.log.*.gz
+unimall.log.*.tmp
+
+
+### plugins ###
+/plugins/
+/unimall-app/pages/plugins/
+/unimall-admin/src/views/plugins/

+ 145 - 0
pom.xml

@@ -0,0 +1,145 @@
+<?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>
+	<packaging>pom</packaging>
+	<parent>
+		<groupId>org.springframework.boot</groupId>
+		<artifactId>spring-boot-starter-parent</artifactId>
+		<version>2.1.2.RELEASE</version>
+		<relativePath/> <!-- lookup parent from repository -->
+	</parent>
+	<groupId>com.iotechn</groupId>
+	<artifactId>unimall</artifactId>
+	<version>0.0.1-RELEASE</version>
+	<name>unimall</name>
+	<description>App,MiniProgram</description>
+
+	<properties>
+		<java.version>1.8</java.version>
+	</properties>
+
+	<repositories>
+		<repository>
+			<id>maven-ali</id>
+			<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
+			<releases>
+				<enabled>true</enabled>
+			</releases>
+			<snapshots>
+				<enabled>true</enabled>
+				<updatePolicy>always</updatePolicy>
+				<checksumPolicy>fail</checksumPolicy>
+			</snapshots>
+		</repository>
+	</repositories>
+
+	<modules>
+		<module>unimall-core</module>
+		<module>unimall-data</module>
+		<module>unimall-biz</module>
+		<module>unimall-app-api</module>
+		<module>unimall-admin-api</module>
+		<module>unimall-launcher</module>
+		<module>unimall-plugin-core</module>
+	</modules>
+
+	<dependencyManagement>
+		<dependencies>
+
+			<!-- http客户端 -->
+			<dependency>
+				<groupId>com.squareup.okhttp3</groupId>
+				<artifactId>okhttp</artifactId>
+				<version>3.10.0</version>
+			</dependency>
+
+			<!-- 良心云 sms -->
+			<dependency>
+				<groupId>com.github.qcloudsms</groupId>
+				<artifactId>qcloudsms</artifactId>
+				<version>1.0.5</version>
+			</dependency>
+
+			<!-- 阿里云 SMS -->
+			<dependency>
+				<groupId>com.aliyun</groupId>
+				<artifactId>aliyun-java-sdk-core</artifactId>
+				<version>4.1.1</version>
+			</dependency>
+
+			<!-- 阿里云对象存储 -->
+			<dependency>
+				<groupId>com.aliyun.oss</groupId>
+				<artifactId>aliyun-sdk-oss</artifactId>
+				<version>2.8.3</version>
+			</dependency>
+
+			<!-- mybatis plus 依赖 -->
+			<dependency>
+				<groupId>com.baomidou</groupId>
+				<artifactId>mybatis-plus-boot-starter</artifactId>
+				<version>2.2.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.baomidou</groupId>
+				<artifactId>mybatis-plus-support</artifactId>
+				<version>2.2.0</version>
+			</dependency>
+
+			<!-- mysql -->
+			<dependency>
+				<groupId>mysql</groupId>
+				<artifactId>mysql-connector-java</artifactId>
+				<version>8.0.15</version>
+			</dependency>
+
+			<!-- 阿里巴巴 数据源 Druid -->
+			<dependency>
+				<groupId>com.alibaba</groupId>
+				<artifactId>druid</artifactId>
+				<version>1.1.8</version>
+			</dependency>
+
+			<!-- lombok 工具 -->
+			<dependency>
+				<groupId>org.projectlombok</groupId>
+				<artifactId>lombok</artifactId>
+				<version>1.18.4</version>
+				<scope>provided</scope>
+			</dependency>
+
+			<!-- 阿里巴巴 json 解析 -->
+			<dependency>
+				<groupId>com.alibaba</groupId>
+				<artifactId>fastjson</artifactId>
+				<version>1.2.31</version>
+			</dependency>
+
+			<!-- 微信第三方封装Api -->
+			<dependency>
+				<groupId>com.github.binarywang</groupId>
+				<artifactId>weixin-java-pay</artifactId>
+				<version>3.3.0</version>
+				<exclusions>
+					<exclusion>
+						<artifactId>qrcode-utils</artifactId>
+						<groupId>com.github.binarywang</groupId>
+					</exclusion>
+				</exclusions>
+			</dependency>
+
+		</dependencies>
+	</dependencyManagement>
+
+	<!-- 发布maven私服 -->
+	<!--<distributionManagement>-->
+		<!--<repository>-->
+			<!--<id>iotechn-release</id>-->
+			<!--<name>unimall maven</name>-->
+			<!--<url>http://maven.iotechn.com/repository/maven-releases/</url>-->
+		<!--</repository>-->
+	<!--</distributionManagement>-->
+
+</project>

+ 22 - 0
sendGoodNotPlat.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="GBK"?>
+<request>
+    <functionID>dangdang.order.goods.send</functionID>
+    <time>2023-10-07 16:03:47</time>
+    <OrdersList>
+        <OrderInfo>
+            <orderID>47737103184</orderID>
+            <logisticsName>ÖÐͨ¿ìµÝ</logisticsName>
+            <logisticsNameAb>ZTO</logisticsNameAb>
+            <logisticsTel>400-827-0270</logisticsTel>
+            <logisticsOrderID>74100279398668</logisticsOrderID>
+            <SendGoodsList>
+                <ItemInfo>
+                    <itemID>11550504942</itemID>
+                    <sendGoodsCount>1</sendGoodsCount>
+                    <belongProductsPromoID></belongProductsPromoID>
+                    <productItemId>47737103184001</productItemId>
+                </ItemInfo>
+            </SendGoodsList>
+        </OrderInfo>
+    </OrdersList>
+</request>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 641 - 0
sql/unimall_tmp.sql


BIN
unimall-admin-api/.DS_Store


+ 101 - 0
unimall-admin-api/pom.xml

@@ -0,0 +1,101 @@
+<?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>com.iotechn</groupId>
+		<artifactId>unimall</artifactId>
+		<version>0.0.1-RELEASE</version>
+	</parent>
+	<groupId>com.iotechn</groupId>
+	<artifactId>unimall-admin-api</artifactId>
+	<version>0.0.1-RELEASE</version>
+	<name>unimall-admin-api</name>
+	<description>后台管理Api</description>
+
+	<properties>
+		<java.version>1.8</java.version>
+	</properties>
+
+	<repositories>
+		<repository>
+			<id>maven-ali</id>
+			<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
+			<releases>
+				<enabled>true</enabled>
+			</releases>
+			<snapshots>
+				<enabled>true</enabled>
+				<updatePolicy>always</updatePolicy>
+				<checksumPolicy>fail</checksumPolicy>
+			</snapshots>
+		</repository>
+		<repository>
+			<id>iotechn-release</id>
+			<name>unimall maven</name>
+			<url>http://maven.iotechn.com/repository/maven-releases/</url>
+		</repository>
+	</repositories>
+
+	<dependencies>
+		<dependency>
+			<groupId>commons-httpclient</groupId>
+			<artifactId>commons-httpclient</artifactId>
+			<version>3.1</version>
+		</dependency>
+		<!-- 引入本地jar -->
+		<dependency>
+			<groupId>com.dangdang.openplatform.openapi</groupId>
+			<artifactId>sdk</artifactId>
+			<version>1.0-SNAPSHOT</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/src/main/lib/dangdang-open-sdk.jar</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>com.iotechn</groupId>
+			<artifactId>unimall-core</artifactId>
+			<version>0.0.1-RELEASE</version>
+		</dependency>
+		<!-- 插件核心依赖 勿删 -->
+		<dependency>
+			<groupId>com.iotechn</groupId>
+			<artifactId>unimall-plugin-core</artifactId>
+			<version>0.0.1-RELEASE</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.iotechn</groupId>
+			<artifactId>unimall-data</artifactId>
+			<version>0.0.1-RELEASE</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.iotechn</groupId>
+			<artifactId>unimall-biz</artifactId>
+			<version>0.0.1-RELEASE</version>
+		</dependency>
+
+		<!-- 微信第三方封装Api -->
+		<dependency>
+			<groupId>com.github.binarywang</groupId>
+			<artifactId>weixin-java-pay</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+			<optional>true</optional>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+
+</project>

BIN
unimall-admin-api/src/.DS_Store


BIN
unimall-admin-api/src/main/.DS_Store


BIN
unimall-admin-api/src/main/java/.DS_Store


BIN
unimall-admin-api/src/main/java/com/.DS_Store


BIN
unimall-admin-api/src/main/java/com/iotechn/.DS_Store


BIN
unimall-admin-api/src/main/java/com/iotechn/unimall/.DS_Store


BIN
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/.DS_Store


+ 786 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/AdminCheckQuartz.java

@@ -0,0 +1,786 @@
+package com.iotechn.unimall.admin;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.dangdang.openplatform.openapi.sdk.ApiException;
+import com.dangdang.openplatform.openapi.sdk.SdkClient;
+import com.dangdang.openplatform.openapi.sdk.internal.util.FileItem;
+import com.dangdang.openplatform.openapi.sdk.request.order.OrderDetailsGetRequest;
+import com.dangdang.openplatform.openapi.sdk.request.order.OrderGoodsSendRequest;
+import com.dangdang.openplatform.openapi.sdk.request.order.OrdersContentDecryptRequest;
+import com.dangdang.openplatform.openapi.sdk.requestmodel.order.EncryptDTO;
+import com.dangdang.openplatform.openapi.sdk.requestmodel.order.OrderDetailsGet;
+import com.dangdang.openplatform.openapi.sdk.response.order.OrderDetailsGetResponse;
+import com.dangdang.openplatform.openapi.sdk.response.order.OrderGoodsSendResponse;
+import com.dangdang.openplatform.openapi.sdk.response.order.OrdersContentDecryptResponse;
+import com.dangdang.openplatform.openapi.sdk.responsemodel.order.CryptUserInfo;
+import com.dangdang.openplatform.openapi.sdk.responsemodel.order.OrdersContentDecryptDTO;
+import com.iotechn.unimall.admin.api.user.AdminUserServiceImpl;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.data.component.LockComponent;
+import com.iotechn.unimall.data.domain.GroupShopDO;
+import com.iotechn.unimall.data.domain.OrderDO;
+import com.iotechn.unimall.data.domain.SpuDO;
+import com.iotechn.unimall.data.domain.shop.ShopAccount;
+import com.iotechn.unimall.data.domain.shop.ShopLog;
+import com.iotechn.unimall.data.domain.shop.ShopOrder;
+import com.iotechn.unimall.data.domain.shop.ShopTran;
+import com.iotechn.unimall.data.dto.shop.XmlObject.OrderDetail;
+import com.iotechn.unimall.data.dto.shop.XmlObject.SendGood;
+import com.iotechn.unimall.data.dto.shop.XmlObject.SendGoodsInfo;
+import com.iotechn.unimall.data.enums.GroupShopAutomaticRefundType;
+import com.iotechn.unimall.data.enums.OrderStatusType;
+import com.iotechn.unimall.data.enums.StatusType;
+import com.iotechn.unimall.data.mapper.GroupShopMapper;
+import com.iotechn.unimall.data.mapper.OrderMapper;
+import com.iotechn.unimall.data.mapper.SpuMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopAccountMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopLogMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopOrderMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopTranMapper;
+import com.iotechn.unimall.data.util.XMLUtil;
+import org.apache.commons.httpclient.Cookie;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.cookie.CookiePolicy;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.support.TransactionCallbackWithoutResult;
+import org.springframework.transaction.support.TransactionTemplate;
+import org.springframework.util.CollectionUtils;
+
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * Created by rize on 2019/7/21.
+ */
+@Component
+@EnableScheduling
+public class AdminCheckQuartz {
+
+    private static final Logger logger = LoggerFactory.getLogger(AdminCheckQuartz.class);
+    private static final String ORDER_STATUS_LOCK = "ORDER_STATUS_QUARTZ_LOCK";
+    private static final String GROUP_SHOP_START_LOCK = "GROUP_SHOP_START_LOCK";
+    private static final String GROUP_SHOP_END_LOCK = "GROUP_SHOP_END_LOCK";
+    private static final String GROUP_SHOP_LOCK_LOCK = "GROUP_SHOP_LOCK_LOCK";
+    @Autowired
+    private ShopOrderMapper shopOrderMapper;
+    @Autowired
+    private ShopAccountMapper shopAccountMapper;
+    @Autowired
+    private ShopTranMapper shopTranMapper;
+    @Autowired
+    private ShopLogMapper shopLogMapper;
+    ExecutorService pool = Executors.newFixedThreadPool(2);
+
+    /**
+     * 订单数据定时轮训处理 每小时执行一次
+     */
+    @Scheduled(cron = "0 0 7-22 * * ? ")
+    public void task1(){
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                doSomething1();
+            }
+        }).start();
+    }
+    /**
+     * 订单数据定时轮训处理 每3小时执行一次
+     */
+//    @Scheduled(cron = "0 0 0 1/1 * ? ")
+    public void task2(){
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                doSomething2();
+            }
+        }).start();
+    }
+    public void dealOrder() throws Exception {
+        try{
+            List<ShopOrder> shopOrders = shopOrderMapper.selectList(new EntityWrapper<ShopOrder>()
+                    .eq("dang_order_status","未发货")
+                    .eq("order_status_name","卖家已发货"));
+            for (ShopOrder qqq:shopOrders
+            ) {
+                ShopAccount shopAccount = shopAccountMapper.selectById(qqq.getAccountId());
+                flushCookie(shopAccount);
+                CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+                HttpGet get = new HttpGet("https://shop.kongfz.com/buyer/order/index/?pageCurr=1&pageShow=9999&orderId="+qqq.getOrderId());
+                //这里可以设置请求参数,token等
+                get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+                get.addHeader("cookie",shopAccount.getFuziCookie());
+                get.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
+                CloseableHttpResponse response = httpClient.execute(get);//执行获取响应
+                try{
+
+                    if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){//根据状态码处理
+                        String strTmp= EntityUtils.toString(response.getEntity(),"UTF-8");
+                        //返回字符串
+                        String res = unicodeToString(strTmp);
+                        JSONObject datas = JSONObject.parseObject(res);//转换成JSON格式
+                        Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                        List<ShopOrder> data = JSONArray.parseArray(datas.get("data").toString(),ShopOrder.class);//"data"是根据返回值设定
+                        for (ShopOrder tmp: data
+                        ) {
+                            //正则表达式,用于匹配非数字串,+号用于匹配出多个非数字串
+                            String regEx="[^0-9]+";
+                            Pattern pattern = Pattern.compile(regEx);
+                            //用定义好的正则表达式拆分字符串,把字符串中的数字留出来
+                            String[] cs = pattern.split(tmp.getRemarkText());
+                            String dangOrder = "";
+                            for (String str:cs
+                            ) {
+                                if(dangOrder.length()>= 11 || str.equals("*")){
+                                    break;
+                                }
+                                dangOrder += str;
+                            }
+                            tmp.setDangOrder(dangOrder);
+                            tmp.setAccountId(shopAccount.getId());
+                            Long time  = Long.parseLong(tmp.getShippingTime())+8*60*60;
+                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
+                            String time1 = sdf.format(new Date(time * 1000));
+                            tmp.setShippingTime(time1);
+                            tmp.setDeleteFlag(0);
+                            tmp.setGmtUpdate(new Date());
+                            tmp.setGmtCreate(new Date());
+                            if(tmp.getShippingComName().equals("快递包裹")||tmp.getShippingComName().equals("挂号印刷品")){
+                                tmp.setShippingComName("中国邮政");
+                            }
+                            ShopOrder tt = new ShopOrder();
+                            tt.setOrderId(tmp.getOrderId());
+                            tt =  shopOrderMapper.selectOne(tt);
+                            if(tt == null){
+                                shopOrderMapper.insert(tmp);
+                            }
+                            else{
+                                if(!tt.getDangOrder().equals(tmp.getDangOrder())||!tt.getShippingComName().equals(tmp.getShippingComName())){
+                                    shopOrderMapper.update(tmp,new EntityWrapper<ShopOrder>().eq("order_id",tt.getOrderId()));
+                                }
+                                dangOrderDeal(shopAccount,qqq);
+                            }
+                        }
+
+                    }
+
+
+                } catch (IOException e) {
+                    throw e;
+                }
+                finally {
+                    response.close();
+                    httpClient.close();
+                }
+            }
+        }
+        catch (Exception e) {
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("同步定时任务异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+            e.printStackTrace();
+        }
+    }
+
+    public void pullOrderList() throws Exception {
+        try{
+            List<ShopAccount> listAccount = shopAccountMapper.selectList(new EntityWrapper<ShopAccount>().eq("delete_flag",0));
+            for (ShopAccount shopAccount:listAccount
+            ) {
+                flushCookie(shopAccount);
+                for(int i=1;i<=5;i++){
+                    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+                    HttpGet get = new HttpGet("https://shop.kongfz.com/buyer/order/index/?pageCurr="+i+"&pageShow=300&orderStatus=ShippedToReceipt");
+                    //这里可以设置请求参数,token等
+                    get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+                    get.addHeader("cookie",shopAccount.getFuziCookie());
+
+                    CloseableHttpResponse response = httpClient.execute(get);//执行获取响应
+                    try{
+
+                        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){//根据状态码处理
+                            String strTmp= EntityUtils.toString(response.getEntity(),"UTF-8");
+                            //返回字符串
+                            String res = unicodeToString(strTmp);
+                            JSONObject datas = JSONObject.parseObject(res);//转换成JSON格式
+                            Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                            List<ShopOrder> data = JSONArray.parseArray(datas.get("data").toString(),ShopOrder.class);//"data"是根据返回值设定
+                            if(data.size() == 0){
+                                break;
+                            }
+                            for (ShopOrder tmp: data
+                            ) {
+                                //正则表达式,用于匹配非数字串,+号用于匹配出多个非数字串
+                                String regEx="[^0-9]+";
+                                Pattern pattern = Pattern.compile(regEx);
+                                //用定义好的正则表达式拆分字符串,把字符串中的数字留出来
+                                String[] cs = pattern.split(tmp.getRemarkText());
+                                String dangOrder = "";
+                                for (String str:cs
+                                ) {
+                                    if(dangOrder.length()>= 11 || str.equals("*")){
+                                        break;
+                                    }
+                                    dangOrder += str;
+                                }
+                                tmp.setDangOrder(dangOrder);
+                                tmp.setAccountId(shopAccount.getId());
+                                Long time  = Long.parseLong(tmp.getShippingTime())+8*60*60;
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                                sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
+                                String time1 = sdf.format(new Date(time * 1000));
+                                tmp.setShippingTime(time1);
+                                tmp.setDeleteFlag(0);
+                                tmp.setGmtUpdate(new Date());
+                                tmp.setGmtCreate(new Date());
+                                if(tmp.getShippingComName().equals("快递包裹")||tmp.getShippingComName().equals("挂号印刷品")){
+                                    tmp.setShippingComName("中国邮政");
+                                }
+                                ShopOrder tt = new ShopOrder();
+                                tt.setOrderId(tmp.getOrderId());
+                                tt =  shopOrderMapper.selectOne(tt);
+                                if(tt == null){
+                                    shopOrderMapper.insert(tmp);
+                                }
+                                else{
+                                    if(tt.getDangOrderStatus().equals("未发货")&&!tt.getDangOrder().equals(tmp.getDangOrder())){
+                                        shopOrderMapper.update(tmp,new EntityWrapper<ShopOrder>().eq("order_id",tt.getOrderId()));
+                                    }
+                                }
+                            }
+
+                        }
+
+
+                    } catch (IOException e) {
+                        throw e;
+                    }
+                    finally {
+                        response.close();
+                        httpClient.close();
+                    }
+                }
+
+            }
+        }
+        catch (Exception e){
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("爬取定时任务异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+            e.printStackTrace();
+        }
+
+    }
+    public void flushCookie(ShopAccount shopAccount){
+        try{
+            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+            HttpGet getMethod = new HttpGet("https://shop.kongfz.com/buyer/order/index/?pageCurr=1&pageShow=30");
+            getMethod.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+            getMethod.addHeader("cookie",shopAccount.getFuziCookie());
+            try{
+                httpClient.execute(getMethod);
+            }
+            catch (Exception e){
+                e.printStackTrace();
+            }
+            CloseableHttpResponse response = httpClient.execute(getMethod);//执行获取响应
+            try{
+                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//根据状态码处理
+                    String strTmp= EntityUtils.toString(response.getEntity(),"UTF-8");
+                    JSONObject datas = JSONObject.parseObject(strTmp);//转换成JSON格式
+                    Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                    if(status){
+                        return;
+                    }
+                }
+            }
+            catch (Exception e){
+                e.printStackTrace();
+            }
+            finally {
+                response.close();
+                httpClient.close();
+            }
+
+            System.out.println("原cookies = "+shopAccount.getFuziCookie());
+
+            // 登陆 Url
+            String loginUrl = "https://login.kongfz.com/Pc/Login/account";
+            BasicCookieStore store= new BasicCookieStore();
+            httpClient =HttpClients.custom().setDefaultCookieStore(store).build();
+            // 模拟登陆,按实际服务器端要求选用 Post 或 Get 请求方式
+            HttpPost httpPost = new HttpPost(loginUrl);
+
+            // 装填参数
+            List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();
+            nvps.add(new BasicNameValuePair("loginName", shopAccount.getFuziAccount()));
+            nvps.add(new BasicNameValuePair("loginPass", shopAccount.getFuziPassword()));
+            // 设置参数到请求对象中
+            httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
+
+            // 设置header信息
+            // 指定报文头【Content-type】、【User-Agent】
+            httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
+
+            // 执行请求操作,并拿到结果(同步阻塞)
+            response = httpClient.execute(httpPost);
+            if(response.getStatusLine().getStatusCode() == 302){
+                List<org.apache.http.cookie.Cookie> cookielist = store.getCookies();
+                String nCookie = "";
+                for(org.apache.http.cookie.Cookie cookie: cookielist){
+                    String name=cookie.getName();
+                    String value=cookie.getValue();
+                    nCookie += name + "="+value+";";
+                }
+                System.out.println("nCookie:" + nCookie);
+                shopAccount.setFuziCookie(nCookie);
+                shopAccountMapper.updateById(shopAccount);
+                ShopLog shopLog = new ShopLog();
+                shopLog.setGmtCreate(new Date());
+                shopLog.setTitle("更新cookie成功");
+                shopLog.setContent("账号:"+shopAccount.getFuziAccount()+",cookie:"+nCookie);
+                shopLogMapper.insert(shopLog);
+            }
+            else{
+                ShopLog shopLog = new ShopLog();
+                shopLog.setGmtCreate(new Date());
+                shopLog.setTitle("更新cookie失败");
+                shopLog.setContent(response.toString());
+                shopLogMapper.insert(shopLog);
+            }
+            // 释放链接
+            response.close();
+
+        }catch (Exception e) {
+            e.printStackTrace();
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("更新cookie异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+        }
+
+    }
+
+    /**
+     * Unicode转 汉字字符串
+     *
+     * @param str
+     *            \u6728
+     * @return '木' 26408
+     */
+    public static String unicodeToString(String str) {
+
+        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
+        Matcher matcher = pattern.matcher(str);
+        char ch;
+        while (matcher.find()) {
+            // group 6728
+            String group = matcher.group(2);
+            // ch:'木' 26408
+            ch = (char) Integer.parseInt(group, 16);
+            // group1 \u6728
+            String group1 = matcher.group(1);
+            str = str.replace(group1, ch + "");
+        }
+        return str;
+    }
+    public void dangOrderDeal(ShopAccount shopAccount, ShopOrder shopOrder) throws Exception {
+        try{
+            /**
+             * 获取一下店铺的所有静态参数
+             */
+            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+            SdkClient sdkClient = new SdkClient(shopAccount.getDangAppKey(),shopAccount.getDangAppSecret(),shopAccount.getDangSession(),shopAccount.getDangVersion());
+
+            OrderDetailsGetRequest ss = new OrderDetailsGetRequest();
+            OrderDetailsGet orderDetailsGet = new OrderDetailsGet();
+            orderDetailsGet.setO(shopOrder.getDangOrder());
+            ss.setOrderDetailsGet(orderDetailsGet);
+            OrderDetailsGetResponse resultt = null;
+            try {
+                resultt = sdkClient.excute(ss);
+                if(resultt.getOrderID() == null){
+                    shopOrder.setDangOrderStatus("订单错误");
+                    shopOrderMapper.updateById(shopOrder);
+                    ShopLog shopLog = new ShopLog();
+                    shopLog.setGmtCreate(new Date());
+                    shopLog.setTitle("当当订单编号错误");
+                    shopLog.setContent("店铺:"+shopAccount.getDangName()+",孔网订单:"+shopOrder.getOrderId()+",当当订单:"+shopOrder.getDangOrder());
+                    shopLogMapper.insert(shopLog);
+                    return;
+                }
+            } catch (ApiException e) {
+                throw e;
+            }
+
+            /**
+             * 从当当获取订单内应当有的所有图书
+             */
+            OrderDetailsGetRequest odgr = new OrderDetailsGetRequest();
+            OrderDetailsGet ogg = new OrderDetailsGet();
+            ogg.setO(shopOrder.getDangOrder());
+            odgr.setOrderDetailsGet(ogg);
+            OrderDetailsGetResponse odgrp = null;
+            try {
+                odgrp = sdkClient.excute(odgr);
+            } catch (ApiException e) {
+                throw e;
+            }
+            SdkClient jiemi = new SdkClient(shopAccount.getDangAppKey(),shopAccount.getDangAppSecret(),shopAccount.getDangSession(),shopAccount.getDangVersion());
+            OrdersContentDecryptRequest ordersContentDecryptRequest=new OrdersContentDecryptRequest();
+
+            List<EncryptDTO> encryptVOS = new ArrayList<EncryptDTO>();
+
+            EncryptDTO encryptVO1 = new EncryptDTO();
+            encryptVO1.setO(resultt.getOrderID().toString());
+            encryptVO1.setEncrypt_content(resultt.getEncrypt_content());
+            encryptVOS.add(encryptVO1);
+
+            ordersContentDecryptRequest.setO_cryptStr(JSON.toJSONString(encryptVOS));
+            OrdersContentDecryptResponse ordersContentDecryptResponse = null;
+            try {
+                ordersContentDecryptResponse=jiemi.excute(ordersContentDecryptRequest);
+            } catch (ApiException e) {
+                throw e;
+            }
+            List<OrdersContentDecryptDTO> data = ordersContentDecryptResponse.getData();
+            CryptUserInfo cryptUserInfo = data.get(0).getCryptUserInfo();
+
+
+
+            OrderDetail o = (OrderDetail) XMLUtil.convertXmlStrToObject(OrderDetail.class, odgrp.getBody());
+            SendGoodsInfo sgi = new SendGoodsInfo();
+            sgi.setConsigneeAddr(cryptUserInfo.getConsigneeAddr());
+            sgi.setConsigneeMobileTel(cryptUserInfo.getConsigneeMobileTel());
+            sgi.setConsigneeTel(cryptUserInfo.getConsigneeTel());
+            sgi.setConsigneeName(cryptUserInfo.getConsigneeName());
+            o.setSendGoodsInfo(sgi);
+            List<com.iotechn.unimall.data.dto.shop.XmlObject.ItemInfo> itemInfo = o.getItemsList().getItemInfo();
+            /**
+             * 将多个图书拼接XML
+             */
+            String itemsStr = "";
+            for (com.iotechn.unimall.data.dto.shop.XmlObject.ItemInfo ii : itemInfo) {
+                Map<String, Object> hashMap = new HashMap<>();
+                hashMap.put("DANG_DANG_ITEM_ID", ii.getItemID());
+                hashMap.put("SHU_LIANG", ii.getOrderCount());
+                hashMap.put("PRODUCT_ID", ii.getProductItemId());
+                itemsStr += SendGood.processTemplate(SendGood.ONE_ITEM, hashMap);
+            }
+
+
+            /**
+             * 组成OrderInfo
+             */
+            Wrapper wrapper = new EntityWrapper();
+            wrapper.like("fuzi_name",shopOrder.getShippingComName());
+            wrapper.eq("delete_flag",0);
+            List<ShopTran> list = shopTranMapper.selectList(wrapper);
+            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+            stringObjectHashMap.put("DANG_DANG_ORDER", shopOrder.getDangOrder());
+            if(list.size() == 0 ){
+//                throw new Exception("物流公司不存在");
+                System.out.println("物流公司不存在");
+                stringObjectHashMap.put("KUAI_DI_GONG_SI", "99999");
+                stringObjectHashMap.put("KUAI_DI_BIANMA", "99999");
+                stringObjectHashMap.put("KUAI_DI_GONG_SI_DIAN_HUA", "99999");
+            }
+            else{
+                stringObjectHashMap.put("KUAI_DI_GONG_SI", list.get(0).getName());
+                stringObjectHashMap.put("KUAI_DI_BIANMA", list.get(0).getCode1());
+                stringObjectHashMap.put("KUAI_DI_GONG_SI_DIAN_HUA", list.get(0).getPhone());
+            }
+            stringObjectHashMap.put("KUAI_DI_DAN_HAO", shopOrder.getShipmentNum());
+            stringObjectHashMap.put("SEND_ITEMS", itemsStr);
+
+            String orderListStr = SendGood.processTemplate(SendGood.ONE_ORDER, stringObjectHashMap);
+            HashMap<String, Object> tmplHash = new HashMap<>();
+            tmplHash.put("SEND_TIME", dateFormat.format(new Date()));
+            tmplHash.put("ORDER_LIST", orderListStr);
+
+            String xmlFileStr = SendGood.processTemplate(SendGood.TMPL, tmplHash);
+            System.out.println(xmlFileStr);
+            PrintWriter out = null;
+            try {
+                out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("sendGoodNotPlat.xml"), "GBK")));
+            }catch (Exception e) {
+                throw e;
+            }
+            out.write(xmlFileStr);
+            out.close();
+            System.out.println("XML文件创建成功!");
+
+
+            /**
+             * 发货!!
+             */
+            OrderGoodsSendRequest sendGoodsRequest = new OrderGoodsSendRequest();
+            sendGoodsRequest.setSendGoodsFile(new FileItem(new File("sendGoodNotPlat.xml")));
+            OrderGoodsSendResponse result = null;
+            try {
+                result = sdkClient.excute(sendGoodsRequest);
+            } catch (ApiException e) {
+                throw e;
+            }
+            System.out.println(result.toString());
+            if(result.getResult().getOrdersList().get(0).getOrderOperCode() == 0 || result.getResult().getOrdersList().get(0).getOrderOperCode() == 605){
+                ShopLog shopLog = new ShopLog();
+                shopLog.setGmtCreate(new Date());
+                shopLog.setTitle("当当订单发货成功");
+                shopLog.setContent("店铺:"+shopAccount.getDangName()+",孔网订单:"+shopOrder.getOrderId()+",当当订单:"+shopOrder.getDangOrder());
+                shopLogMapper.insert(shopLog);
+                shopOrder.setDangOrderStatus("已发货");
+                shopOrderMapper.update(shopOrder,new EntityWrapper<ShopOrder>().eq("order_id",shopOrder.getOrderId()));
+            }
+            else{
+                ShopLog shopLog = new ShopLog();
+                shopLog.setGmtCreate(new Date());
+                shopLog.setTitle("当当订单发货失败");
+                shopLog.setContent("店铺:"+shopAccount.getDangName()+",孔网订单:"+shopOrder.getOrderId()+",当当订单:"+shopOrder.getDangOrder()+",快递:"+shopOrder.getShippingComName());
+                shopLogMapper.insert(shopLog);
+            }
+        }
+        catch (Exception e){
+            e.printStackTrace();
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("当当发货异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+        }
+
+    }
+    /**
+     * 需要处理的任务
+     * */
+    private void doSomething1() {
+        try{
+            List<ShopAccount> list = shopAccountMapper.selectList(new EntityWrapper<>());
+            for (ShopAccount shopAccount:list
+            ) {
+                logger.info("开始刷新cookie doSomething1");
+                flushCookie(shopAccount);
+                logger.info("结束刷新cookie doSomething1");
+                List<ShopOrder> shopOrders = shopOrderMapper.selectList(new EntityWrapper<ShopOrder>()
+                        .eq("dang_order_status","未发货")
+                        .eq("account_id",shopAccount.getId())
+                        .eq("order_status_name","卖家已发货"));
+
+                logger.info("获取待自动发货数据 doSomething1",shopOrders);
+                for (ShopOrder qqq:shopOrders
+                ) {
+                    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+                    HttpGet get = new HttpGet("https://shop.kongfz.com/buyer/order/index/?pageCurr=1&pageShow=300&orderId="+qqq.getOrderId());
+                    //这里可以设置请求参数,token等
+                    get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+                    get.addHeader("cookie",shopAccount.getFuziCookie());
+                    get.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
+                    logger.info("开始获取孔网订单 doSomething1");
+                    CloseableHttpResponse response = httpClient.execute(get);//执行获取响应
+                    logger.info("结束获取孔网订单 doSomething1");
+                    try{
+
+                        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){//根据状态码处理
+                            String strTmp= EntityUtils.toString(response.getEntity(),"UTF-8");
+                            //返回字符串
+                            String res = unicodeToString(strTmp);
+                            JSONObject datas = JSONObject.parseObject(res);//转换成JSON格式
+                            Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                            List<ShopOrder> data = JSONArray.parseArray(datas.get("data").toString(),ShopOrder.class);//"data"是根据返回值设定
+
+                            logger.info("已获取孔网订单 doSomething1  ",data.size());
+                            for (ShopOrder tmp: data
+                            ) {
+                                //正则表达式,用于匹配非数字串,+号用于匹配出多个非数字串
+                                String regEx="[^0-9]+";
+                                Pattern pattern = Pattern.compile(regEx);
+                                //用定义好的正则表达式拆分字符串,把字符串中的数字留出来
+                                String[] cs = pattern.split(tmp.getRemarkText());
+                                String dangOrder = "";
+                                for (String str:cs
+                                ) {
+                                    if(dangOrder.length()>= 11 || str.equals("*")){
+                                        break;
+                                    }
+                                    dangOrder += str;
+                                }
+                                tmp.setDangOrder(dangOrder);
+                                tmp.setAccountId(shopAccount.getId());
+                                Long time  = Long.parseLong(tmp.getShippingTime())+8*60*60;
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                                sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
+                                String time1 = sdf.format(new Date(time * 1000));
+                                tmp.setShippingTime(time1);
+                                tmp.setDeleteFlag(0);
+                                tmp.setGmtUpdate(new Date());
+                                tmp.setGmtCreate(new Date());
+                                if(tmp.getShippingComName().equals("快递包裹")||tmp.getShippingComName().equals("挂号印刷品")){
+                                    tmp.setShippingComName("中国邮政");
+                                }
+                                ShopOrder tt = new ShopOrder();
+                                tt.setOrderId(tmp.getOrderId());
+                                tt =  shopOrderMapper.selectOne(tt);
+                                if(tt == null){
+                                    shopOrderMapper.insert(tmp);
+                                }
+                                else{
+                                    if(!tt.getDangOrder().equals(tmp.getDangOrder())||!tt.getShippingComName().equals(tmp.getShippingComName())){
+                                        shopOrderMapper.update(tmp,new EntityWrapper<ShopOrder>().eq("order_id",tt.getOrderId()));
+                                    }
+                                    logger.info("开始当当发货 doSomething1");
+                                    dangOrderDeal(shopAccount,qqq);
+                                    logger.info("结束当当发货 doSomething1");
+                                }
+                            }
+
+                        }
+
+
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                    finally {
+                        response.close();
+                        httpClient.close();
+                    }
+                }
+            }
+
+        }
+        catch (Exception e) {
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("同步定时任务异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+            e.printStackTrace();
+        }
+
+    }
+    private void doSomething2() {
+        try{
+            List<ShopAccount> list = shopAccountMapper.selectList(new EntityWrapper<>());
+            for (ShopAccount shopAccount:list
+            ) {
+                flushCookie(shopAccount);
+                for (int i = 1; i <= 5; i++) {
+                    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+                    HttpGet get = new HttpGet("https://shop.kongfz.com/buyer/order/index/?pageCurr=" + i + "&pageShow=300&orderStatus=ShippedToReceipt");
+                    //这里可以设置请求参数,token等
+                    get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+                    get.addHeader("cookie", shopAccount.getFuziCookie());
+
+                    CloseableHttpResponse response = httpClient.execute(get);//执行获取响应
+                    try {
+                        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//根据状态码处理
+                            String strTmp = EntityUtils.toString(response.getEntity(), "UTF-8");
+                            //返回字符串
+                            String res = unicodeToString(strTmp);
+                            JSONObject datas = JSONObject.parseObject(res);//转换成JSON格式
+                            Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                            List<ShopOrder> data = JSONArray.parseArray(datas.get("data").toString(), ShopOrder.class);//"data"是根据返回值设定
+                            if (data.size() == 0) {
+                                break;
+                            }
+                            for (ShopOrder tmp : data
+                            ) {
+                                //正则表达式,用于匹配非数字串,+号用于匹配出多个非数字串
+                                String regEx = "[^0-9]+";
+                                Pattern pattern = Pattern.compile(regEx);
+                                //用定义好的正则表达式拆分字符串,把字符串中的数字留出来
+                                String[] cs = pattern.split(tmp.getRemarkText());
+                                String dangOrder = "";
+                                for (String str : cs
+                                ) {
+                                    if (dangOrder.length() >= 11 || str.equals("*")) {
+                                        break;
+                                    }
+                                    dangOrder += str;
+                                }
+                                tmp.setDangOrder(dangOrder);
+                                tmp.setAccountId(shopAccount.getId());
+                                Long time  = Long.parseLong(tmp.getShippingTime())+8*60*60;
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                                sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
+                                String time1 = sdf.format(new Date(time * 1000));
+                                tmp.setShippingTime(time1);
+                                tmp.setDeleteFlag(0);
+                                tmp.setGmtUpdate(new Date());
+                                tmp.setGmtCreate(new Date());
+                                if (tmp.getShippingComName().equals("快递包裹") || tmp.getShippingComName().equals("挂号印刷品")) {
+                                    tmp.setShippingComName("中国邮政");
+                                }
+                                ShopOrder tt = new ShopOrder();
+                                tt.setOrderId(tmp.getOrderId());
+                                tt = shopOrderMapper.selectOne(tt);
+                                if (tt == null) {
+                                    shopOrderMapper.insert(tmp);
+                                } else {
+                                    if (tt.getDangOrderStatus().equals("未发货") && !tt.getDangOrder().equals(tmp.getDangOrder())) {
+                                        shopOrderMapper.update(tmp, new EntityWrapper<ShopOrder>().eq("order_id", tt.getOrderId()));
+                                    }
+                                }
+                            }
+                        }
+                    } catch (IOException e) {
+                        throw e;
+                    } finally {
+                        response.close();
+                        httpClient.close();
+                    }
+                }
+            }
+            doSomething2();
+        }
+        catch (Exception e){
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("爬取定时任务异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+            e.printStackTrace();
+        }
+
+    }
+
+}

+ 289 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/MyApplicationLisenter.java

@@ -0,0 +1,289 @@
+package com.iotechn.unimall.admin;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.dangdang.openplatform.openapi.sdk.ApiException;
+import com.dangdang.openplatform.openapi.sdk.SdkClient;
+import com.dangdang.openplatform.openapi.sdk.internal.util.FileItem;
+import com.dangdang.openplatform.openapi.sdk.request.order.OrderDetailsGetRequest;
+import com.dangdang.openplatform.openapi.sdk.request.order.OrderGoodsSendRequest;
+import com.dangdang.openplatform.openapi.sdk.request.order.OrdersContentDecryptRequest;
+import com.dangdang.openplatform.openapi.sdk.requestmodel.order.EncryptDTO;
+import com.dangdang.openplatform.openapi.sdk.requestmodel.order.OrderDetailsGet;
+import com.dangdang.openplatform.openapi.sdk.response.order.OrderDetailsGetResponse;
+import com.dangdang.openplatform.openapi.sdk.response.order.OrderGoodsSendResponse;
+import com.dangdang.openplatform.openapi.sdk.response.order.OrdersContentDecryptResponse;
+import com.dangdang.openplatform.openapi.sdk.responsemodel.order.CryptUserInfo;
+import com.dangdang.openplatform.openapi.sdk.responsemodel.order.OrdersContentDecryptDTO;
+import com.iotechn.unimall.data.domain.shop.ShopAccount;
+import com.iotechn.unimall.data.domain.shop.ShopLog;
+import com.iotechn.unimall.data.domain.shop.ShopOrder;
+import com.iotechn.unimall.data.domain.shop.ShopTran;
+import com.iotechn.unimall.data.dto.shop.XmlObject.OrderDetail;
+import com.iotechn.unimall.data.dto.shop.XmlObject.SendGood;
+import com.iotechn.unimall.data.dto.shop.XmlObject.SendGoodsInfo;
+import com.iotechn.unimall.data.mapper.shop.ShopAccountMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopLogMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopOrderMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopTranMapper;
+import com.iotechn.unimall.data.util.XMLUtil;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Author:chengchangjiang
+ * @Description:
+ * @Date:Created in 12:34 2022-06-16
+ */
+@Component
+public class MyApplicationLisenter implements ApplicationListener<ContextRefreshedEvent> {
+
+    private static Logger logger = LoggerFactory.getLogger(MyApplicationLisenter.class);
+
+    @Autowired
+    private ShopAccountMapper shopAccountMapper;
+
+    @Autowired
+    private ShopLogMapper shopLogMapper;
+    @Autowired
+    private ShopOrderMapper shopOrderMapper;
+    @Autowired
+    private ShopTranMapper shopTranMapper;
+    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    @Override
+    public void onApplicationEvent(ContextRefreshedEvent e) {
+        logger.info("实现了ApplicationListener的onApplicationEvent方法");
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                doSomething2();
+            }
+        }).start();
+    }
+    private void doSomething2() {
+        try{
+            List<ShopAccount> list = shopAccountMapper.selectList(new EntityWrapper<ShopAccount>().orderBy("id",false));
+            for (ShopAccount shopAccount:list
+            ) {
+                logger.info("开始刷新cookie doSomething2");
+                flushCookie(shopAccount);
+                logger.info("结束刷新cookie doSomething2");
+//                for (int i = 1; i <= 5; i++) {
+                    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+                    HttpGet get = new HttpGet("https://shop.kongfz.com/buyer/order/index/?pageCurr=" + 1 + "&pageShow=300&orderStatus=ShippedToReceipt");
+                    //这里可以设置请求参数,token等
+                    get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+                    get.addHeader("cookie", shopAccount.getFuziCookie());
+                    CloseableHttpResponse response = null;
+                    try {
+                        logger.info("开始获取孔网订单 doSomething2");
+                        response = httpClient.execute(get);//执行获取响应
+                        logger.info("结束获取孔网订单 doSomething2");
+                        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//根据状态码处理
+                            String strTmp = EntityUtils.toString(response.getEntity(), "UTF-8");
+                            //返回字符串
+                            String res = unicodeToString(strTmp);
+                            JSONObject datas = JSONObject.parseObject(res);//转换成JSON格式
+                            Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                            List<ShopOrder> data = JSONArray.parseArray(datas.get("data").toString(), ShopOrder.class);//"data"是根据返回值设定
+                            if (data.size() == 0) {
+                                break;
+                            }
+                            logger.info("已获取孔网订单 doSomething2  ",data.size());
+                            for (ShopOrder tmp : data
+                            ) {
+                                //正则表达式,用于匹配非数字串,+号用于匹配出多个非数字串
+                                String regEx = "[^0-9]+";
+                                Pattern pattern = Pattern.compile(regEx);
+                                //用定义好的正则表达式拆分字符串,把字符串中的数字留出来
+                                String[] cs = pattern.split(tmp.getRemarkText());
+                                String dangOrder = "";
+                                for (String str : cs
+                                ) {
+                                    if (dangOrder.length() >= 11 || str.equals("*")) {
+                                        break;
+                                    }
+                                    dangOrder += str;
+                                }
+                                tmp.setDangOrder(dangOrder);
+                                tmp.setAccountId(shopAccount.getId());
+                                Long time  = Long.parseLong(tmp.getShippingTime())+8*60*60;
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                                sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
+                                String time1 = sdf.format(new Date(time * 1000));
+                                tmp.setShippingTime(time1);
+                                tmp.setDeleteFlag(0);
+                                tmp.setGmtUpdate(new Date());
+                                tmp.setGmtCreate(new Date());
+                                if (tmp.getShippingComName().equals("快递包裹") || tmp.getShippingComName().equals("挂号印刷品")) {
+                                    tmp.setShippingComName("中国邮政");
+                                }
+                                ShopOrder tt = new ShopOrder();
+                                tt.setOrderId(tmp.getOrderId());
+                                tt = shopOrderMapper.selectOne(tt);
+                                if (tt == null) {
+                                    shopOrderMapper.insert(tmp);
+                                } else {
+                                    if (tt.getDangOrderStatus().equals("未发货") && !tt.getDangOrder().equals(tmp.getDangOrder())) {
+                                        shopOrderMapper.update(tmp, new EntityWrapper<ShopOrder>().eq("order_id", tt.getOrderId()));
+                                    }
+                                }
+                            }
+                        }
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    } finally {
+                        if(response != null){
+                            response.close();
+                        }
+                        httpClient.close();
+                    }
+//                }
+            }
+
+        }
+        catch (Exception e){
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("爬取定时任务异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+            e.printStackTrace();
+        }
+        doSomething2();
+
+    }
+    public void flushCookie(ShopAccount shopAccount) {
+        try {
+            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+            HttpGet getMethod = new HttpGet("https://shop.kongfz.com/buyer/order/index/?pageCurr=1&pageShow=30");
+            getMethod.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+            getMethod.addHeader("cookie", shopAccount.getFuziCookie());
+
+            httpClient.execute(getMethod);
+            CloseableHttpResponse response = httpClient.execute(getMethod);//执行获取响应
+            try {
+                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//根据状态码处理
+                    String strTmp = EntityUtils.toString(response.getEntity(), "UTF-8");
+                    JSONObject datas = JSONObject.parseObject(strTmp);//转换成JSON格式
+                    Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                    if (status) {
+                        return;
+                    }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                response.close();
+                httpClient.close();
+            }
+
+            System.out.println("原cookies = " + shopAccount.getFuziCookie());
+
+            // 登陆 Url
+            String loginUrl = "https://login.kongfz.com/Pc/Login/account";
+            BasicCookieStore store = new BasicCookieStore();
+            httpClient = HttpClients.custom().setDefaultCookieStore(store).build();
+            // 模拟登陆,按实际服务器端要求选用 Post 或 Get 请求方式
+            HttpPost httpPost = new HttpPost(loginUrl);
+
+            // 装填参数
+            List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();
+            nvps.add(new BasicNameValuePair("loginName", shopAccount.getFuziAccount()));
+            nvps.add(new BasicNameValuePair("loginPass", shopAccount.getFuziPassword()));
+            // 设置参数到请求对象中
+            httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
+
+            // 设置header信息
+            // 指定报文头【Content-type】、【User-Agent】
+            httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
+
+            // 执行请求操作,并拿到结果(同步阻塞)
+            response = httpClient.execute(httpPost);
+            if (response.getStatusLine().getStatusCode() == 302) {
+                List<org.apache.http.cookie.Cookie> cookielist = store.getCookies();
+                String nCookie = "";
+                for (org.apache.http.cookie.Cookie cookie : cookielist) {
+                    String name = cookie.getName();
+                    String value = cookie.getValue();
+                    nCookie += name + "=" + value + ";";
+                }
+                System.out.println("nCookie:" + nCookie);
+                shopAccount.setFuziCookie(nCookie);
+                shopAccountMapper.updateById(shopAccount);
+                ShopLog shopLog = new ShopLog();
+                shopLog.setGmtCreate(new Date());
+                shopLog.setTitle("更新cookie成功");
+                shopLog.setContent("账号:" + shopAccount.getFuziAccount() + ",cookie:" + nCookie);
+                shopLogMapper.insert(shopLog);
+            } else {
+                ShopLog shopLog = new ShopLog();
+                shopLog.setGmtCreate(new Date());
+                shopLog.setTitle("更新cookie失败");
+                shopLog.setContent(response.toString());
+                shopLogMapper.insert(shopLog);
+            }
+            // 释放链接
+            response.close();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("更新cookie异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+        }
+
+    }
+
+
+    /**
+     * Unicode转 汉字字符串
+     *
+     * @param str \u6728
+     * @return '木' 26408
+     */
+    public static String unicodeToString(String str) {
+
+        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
+        Matcher matcher = pattern.matcher(str);
+        char ch;
+        while (matcher.find()) {
+            // group 6728
+            String group = matcher.group(2);
+            // ch:'木' 26408
+            ch = (char) Integer.parseInt(group, 16);
+            // group1 \u6728
+            String group1 = matcher.group(1);
+            str = str.replace(group1, ch + "");
+        }
+        return str;
+    }
+
+}

+ 13 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/UnimallAdminApiApplication.java

@@ -0,0 +1,13 @@
+package com.iotechn.unimall.admin;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class UnimallAdminApiApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(UnimallAdminApiApplication.class, args);
+	}
+
+}

BIN
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/.DS_Store


+ 79 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/admin/AdminService.java

@@ -0,0 +1,79 @@
+package com.iotechn.unimall.admin.api.admin;
+
+import com.iotechn.unimall.core.Const;
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.dto.AdminDTO;
+import com.iotechn.unimall.data.model.Page;
+
+/**
+ * Created by rize on 2019/4/8.
+ */
+@HttpOpenApi(group = "admin", description = "管理员服务")
+public interface AdminService {
+
+	@HttpMethod(description = "管理员登录 返回AccessToken")
+	public String login(
+			@NotNull @HttpParam(name = "loginIp", type = HttpParamType.IP, description = "用户登陆IP") String loginIp,
+			@NotNull @HttpParam(name = "browserName", type = HttpParamType.BrowserName, description = "浏览器名称") String browserName,
+			@NotNull @HttpParam(name = "browserVersion", type = HttpParamType.BrowserVersion, description = "浏览器版本") String browserVersion,
+			@NotNull @HttpParam(name = "osName", type = HttpParamType.OsName, description = "系统名称") String osName,
+			@NotNull @HttpParam(name = "username", type = HttpParamType.COMMON, description = "用户名") String username,
+			@NotNull @HttpParam(name = "password", type = HttpParamType.COMMON, description = "密码") String password,
+			@NotNull @HttpParam(name = "verifyCode", type = HttpParamType.COMMON, description = "验证码") String verifyCode)
+			throws ServiceException;
+
+	@HttpMethod(description = "管理员登出")
+	public String logout(
+			@NotNull @HttpParam(name = Const.ADMIN_ACCESS_TOKEN, type = HttpParamType.HEADER, description = "访问Token") String accessToken,
+			@NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId)
+			throws ServiceException;
+
+	@HttpMethod(description = "管理员信息")
+	public AdminDTO info(
+			@NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId)
+			throws ServiceException;
+
+	@HttpMethod(description = "列表", permission = "admin:admin:list", permissionParentName = "系统管理", permissionName = "管理员")
+	public Page<AdminDTO> list(
+			@HttpParam(name = "username", type = HttpParamType.COMMON, description = "管理员名称搜索") String name,
+			@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+			@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页长度", valueDef = "20") Integer limit,
+			@NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId)
+			throws ServiceException;
+
+	@HttpMethod(description = "创建", permission = "admin:admin:create", permissionParentName = "系统管理", permissionName = "管理员")
+	public AdminDTO create(
+			@NotNull @HttpParam(name = "adminDTO", type = HttpParamType.COMMON, description = "欲创建的admin对象JSON") AdminDTO adminDTO,
+			@NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId)
+			throws ServiceException;
+
+	@HttpMethod(description = "修改", permission = "admin:admin:update", permissionParentName = "系统管理", permissionName = "管理员")
+	public String update(
+			@NotNull @HttpParam(name = "adminDTO", type = HttpParamType.COMMON, description = "欲修改的admin对象JSON") AdminDTO adminDTO,
+			@NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId)
+			throws ServiceException;
+
+	@HttpMethod(description = "删除", permission = "admin:admin:delete", permissionParentName = "系统管理", permissionName = "管理员")
+	public String delete(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "目标删除Id") Long id,
+			@NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId)
+			throws ServiceException;
+
+	@HttpMethod(description = "更改密码")
+	public String newPassword(
+			@HttpParam(name = Const.ADMIN_ACCESS_TOKEN, type = HttpParamType.HEADER, description = "访问Token") String accessToken,
+			@NotNull @HttpParam(name = "oldPassword", type = HttpParamType.COMMON, description = "老密码") String oldPassword,
+			@NotNull @HttpParam(name = "newPassword", type = HttpParamType.COMMON, description = "新密码") String newPassword,
+			@NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId)
+			throws ServiceException;
+
+	@HttpMethod(description = "发送登陆短信")
+	public Boolean sendLoginMsg(
+			@NotNull @HttpParam(name = "username", type = HttpParamType.COMMON, description = "用户名") String username,
+			@NotNull @HttpParam(name = "password", type = HttpParamType.COMMON, description = "密码") String password)
+			throws ServiceException;
+}

+ 248 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/admin/AdminServiceImpl.java

@@ -0,0 +1,248 @@
+package com.iotechn.unimall.admin.api.admin;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.Const;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.core.exception.ThirdPartServiceException;
+import com.iotechn.unimall.core.notify.SMSClient;
+import com.iotechn.unimall.core.notify.SMSResult;
+import com.iotechn.unimall.core.util.GeneratorUtil;
+import com.iotechn.unimall.core.util.MD5Util;
+import com.iotechn.unimall.data.component.CacheComponent;
+import com.iotechn.unimall.data.domain.AdminDO;
+import com.iotechn.unimall.data.domain.RoleDO;
+import com.iotechn.unimall.data.domain.RolePermissionDO;
+import com.iotechn.unimall.data.dto.AdminDTO;
+import com.iotechn.unimall.data.enums.AdminStatusType;
+import com.iotechn.unimall.data.enums.RoleStatusType;
+import com.iotechn.unimall.data.mapper.AdminMapper;
+import com.iotechn.unimall.data.mapper.RoleMapper;
+import com.iotechn.unimall.data.mapper.RolePermissionMapper;
+import com.iotechn.unimall.data.model.Page;
+import com.iotechn.unimall.data.util.IpUtils;
+import com.iotechn.unimall.data.util.SessionUtil;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by rize on 2019/4/8.
+ */
+@Service
+public class AdminServiceImpl implements AdminService {
+
+	@Autowired
+	private StringRedisTemplate userRedisTemplate;
+
+	@Autowired
+	private AdminMapper adminMapper;
+
+	@Autowired
+	private RoleMapper roleMapper;
+
+	@Autowired
+	private RolePermissionMapper rolePermissionMapper;
+
+	@Autowired
+	private CacheComponent cacheComponent;
+
+	@Autowired
+	private SMSClient smsClient;
+
+	private final static String ADMIN_MSG_CODE = "admin_msg_code_";
+
+	@Override
+	public String login(String loginIp, String browserName, String browserVersion, String osName, String username,
+			String password, String verifyCode) throws ServiceException {
+		String accessToken = generateAccessToken();
+		// 数据库查管理员
+		List<AdminDO> adminDOS = adminMapper.selectList(new EntityWrapper<AdminDO>().eq("username", username));
+		if (CollectionUtils.isEmpty(adminDOS)) {
+			throw new AdminServiceException(ExceptionDefinition.ADMIN_NOT_EXIST);
+		}
+		AdminDO adminDO = adminDOS.get(0);
+		// 短信验证码
+//        String code = cacheComponent.getRaw(ADMIN_MSG_CODE+adminDO.getPhone() );
+//        if(!"guest".equals(username) && (code == null || verifyCode==null || !code.equals(verifyCode))){
+//            throw new AdminServiceException(ExceptionDefinition.ADMIN_VERIFYCODE_ERROR);
+//        }
+
+		if (!MD5Util.verify(password, username, adminDO.getPassword())) {
+			throw new AdminServiceException(ExceptionDefinition.ADMIN_PASSWORD_ERROR);
+		}
+		List<Long> ids = JSONObject.parseArray(adminDO.getRoleIds(), Long.class);
+		if (CollectionUtils.isEmpty(ids)) {
+			throw new AdminServiceException(ExceptionDefinition.ADMIN_ROLE_IS_EMPTY);
+		}
+		List<RoleDO> roleDOList = roleMapper
+				.selectList(new EntityWrapper<RoleDO>().in("id", ids).eq("status", RoleStatusType.ACTIVE.getCode()));
+		List<String> roleNames = new LinkedList<>();
+		roleDOList.forEach(item -> {
+			roleNames.add(item.getName());
+		});
+		AdminDTO adminDTO = new AdminDTO();
+		adminDTO.setRoles(roleNames);
+		BeanUtils.copyProperties(adminDO, adminDTO);
+		adminDTO.setRoleIds(JSONObject.parseArray(adminDO.getRoleIds(), Long.class));
+		adminDTO.setPassword(null);
+		List<RolePermissionDO> rolePermissionDOList = rolePermissionMapper
+				.selectList(new EntityWrapper<RolePermissionDO>().in("role_id", ids).eq("deleted", 0));
+		List<String> permissionNames = new LinkedList<>();
+		rolePermissionDOList.forEach(item -> {
+			permissionNames.add(item.getPermission());
+		});
+		adminDTO.setPerms(permissionNames);
+		JSONObject loginUserInfo = (JSONObject) JSONObject.toJSON(adminDTO);
+		loginUserInfo.put("loginIp", loginIp);
+		loginUserInfo.put("loginTime", new Date());
+		loginUserInfo.put("browser", browserName + "(" + browserVersion + ")");
+		loginUserInfo.put("osName", osName);
+		userRedisTemplate.opsForValue().set(Const.ADMIN_REDIS_PREFIX + accessToken,
+				JSONObject.toJSONString(loginUserInfo), 30, TimeUnit.DAYS);
+		return accessToken;
+	}
+
+	@Override
+	public String logout(String accessToken, Long adminId) throws ServiceException {
+		userRedisTemplate.delete(Const.ADMIN_REDIS_PREFIX + accessToken);
+		return "ok";
+	}
+
+	@Override
+	public AdminDTO info(Long adminId) throws ServiceException {
+		return SessionUtil.getAdmin();
+	}
+
+	@Override
+	public Page<AdminDTO> list(String name, Integer page, Integer limit, Long adminId) throws ServiceException {
+		Wrapper<AdminDO> wrapper = new EntityWrapper<AdminDO>();
+		if (!StringUtils.isEmpty(name)) {
+			wrapper.like("username", name);
+		}
+		wrapper.orderBy("id", false);
+		Integer count = adminMapper.selectCount(wrapper);
+		List<AdminDO> adminDOS = adminMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+		List<AdminDTO> adminDTOS = new ArrayList<AdminDTO>(adminDOS.size());
+		for (AdminDO adminDO : adminDOS) {
+			AdminDTO adminDTO = new AdminDTO();
+			BeanUtils.copyProperties(adminDO, adminDTO);
+			adminDTO.setRoleIds(JSONObject.parseArray(adminDO.getRoleIds(), Long.class));
+			adminDTO.setPassword(null);
+			adminDTOS.add(adminDTO);
+		}
+		return new Page<>(adminDTOS, page, limit, count);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public AdminDTO create(AdminDTO adminDTO, Long adminId) throws ServiceException {
+		AdminDO adminDO = new AdminDO();
+		Integer count = adminMapper.selectCount(new EntityWrapper<AdminDO>().eq("username", adminDTO.getUsername()));
+		if (count > 0) {
+			throw new AdminServiceException(ExceptionDefinition.ADMIN_USER_NAME_REPEAT);
+		}
+		BeanUtils.copyProperties(adminDTO, adminDO);
+		adminDO.setPassword(MD5Util.md5(adminDO.getPassword(), adminDO.getUsername()));
+		adminDO.setRoleIds(JSONObject.toJSONString(adminDTO.getRoleIds()));
+		adminDO.setGmtUpdate(new Date());
+		adminDO.setGmtCreate(adminDO.getGmtUpdate());
+		adminDO.setStatus(AdminStatusType.ACTIVE.getCode());
+		adminDO.setLastLoginIp("0.0.0.0");
+		adminDO.setGmtLastLogin("1997-01-20 00:00:00");
+		if (adminMapper.insert(adminDO) > 0) {
+			adminDTO.setId(adminDO.getId());
+			return adminDTO;
+		}
+		throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public String update(AdminDTO adminDTO, Long adminId) throws ServiceException {
+		Long id = adminDTO.getId();
+		if (id == null) {
+			throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
+		}
+		AdminDO adminDO = new AdminDO();
+		BeanUtils.copyProperties(adminDTO, adminDO);
+		adminDO.setGmtUpdate(new Date());
+		AdminDO adminDOExist = adminMapper.selectById(id);
+		if (!StringUtils.isEmpty(adminDO.getPassword()) && !StringUtils.isEmpty(adminDOExist.getUsername())) {
+			adminDO.setPassword(MD5Util.md5(adminDO.getPassword(), adminDOExist.getUsername()));
+		}
+		adminDO.setUsername(null);
+		if (!CollectionUtils.isEmpty(adminDTO.getRoleIds())) {
+			adminDO.setRoleIds(JSONObject.toJSONString(adminDTO.getRoleIds()));
+		}
+		if (adminMapper.updateById(adminDO) > 0) {
+			return "ok";
+		}
+		throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public String delete(Long id, Long adminId) throws ServiceException {
+		if (adminMapper.deleteById(id) > 0) {
+			return "ok";
+		}
+		throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public String newPassword(String accessToken, String oldPassword, String newPassword, Long adminId)
+			throws ServiceException {
+		AdminDO adminDOExist = adminMapper.selectById(adminId);
+		if (!MD5Util.md5(oldPassword, adminDOExist.getUsername()).equals(adminDOExist.getPassword())) {
+			throw new AdminServiceException(ExceptionDefinition.ADMIN_PASSWORD_ERROR);
+		}
+		AdminDO adminDO = new AdminDO();
+		adminDO.setId(adminId);
+		adminDO.setPassword(MD5Util.md5(newPassword, adminDOExist.getUsername()));
+		if (adminMapper.updateById(adminDO) > 0) {
+			// logout(accessToken, adminId);
+			return "ok";
+		}
+		throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
+	}
+
+	@Override
+	public Boolean sendLoginMsg(String username, String password) throws ServiceException {
+		if ("guest".equals(username)) {
+			throw new AdminServiceException(ExceptionDefinition.ADMIN_GUEST_NOT_NEED_VERIFY_CODE);
+		}
+		AdminDO adminDO = new AdminDO();
+		adminDO.setUsername(username);
+		adminDO.setPassword(MD5Util.md5(password, username));
+		AdminDO admin = adminMapper.selectOne(adminDO);
+		if (admin == null) {
+			throw new AdminServiceException(ExceptionDefinition.ADMIN_USER_NOT_EXITS);
+		}
+		String code = GeneratorUtil.genSixVerifyCode();
+		cacheComponent.putRaw(ADMIN_MSG_CODE + admin.getPhone(), code, 300);
+		SMSResult smsResult = smsClient.sendAdminLoginVerify(admin.getPhone(), code);
+		if (!smsResult.isSucc()) {
+			throw new ThirdPartServiceException(smsResult.getMsg(),
+					ExceptionDefinition.ADMIN_VERIFY_CODE_SEND_FAIL.getCode());
+		}
+		return true;
+	}
+
+	private String generateAccessToken() {
+		return (UUID.randomUUID().toString().replace("-", ""));
+	}
+
+}

+ 72 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/advertisement/AdminAdvertisementService.java

@@ -0,0 +1,72 @@
+package com.iotechn.unimall.admin.api.advertisement;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.annotation.param.Range;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.AdvertisementDO;
+import com.iotechn.unimall.data.dto.RecommendDTO;
+import com.iotechn.unimall.data.enums.StatusType;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.List;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-08
+ * Time: 下午8:23
+ */
+
+@HttpOpenApi(group = "admin.advertisement", description = "广告推销")
+public interface AdminAdvertisementService {
+
+    @HttpMethod(description = "创建", permission = "promote:advertisement:create", permissionParentName = "推广管理", permissionName = "广告管理")
+    public Boolean addAdvertisement(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "adType", type = HttpParamType.COMMON, description = "广告类型") Integer adType,
+            @HttpParam(name = "title", type = HttpParamType.COMMON, description = "广告标题") String title,
+            @NotNull @HttpParam(name = "url", type = HttpParamType.COMMON, description = "广告地址") String url,
+            @NotNull @HttpParam(name = "imgUrl", type = HttpParamType.COMMON, description = "广告图片地址") String imgUrl,
+            @NotNull @HttpParam(name = "status", type = HttpParamType.COMMON, description = "广告状态") Integer status,
+            @NotNull @HttpParam(name = "color", type = HttpParamType.COMMON, description = "广告图片颜色") String color) throws ServiceException;
+
+    @HttpMethod(description = "删除", permission = "promote:advertisement:delete", permissionParentName = "推广管理", permissionName = "广告管理")
+    public Boolean deleteAdvertisement(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "adType", type = HttpParamType.COMMON, description = "广告类型") Integer adType,
+            @NotNull @HttpParam(name = "adId", type = HttpParamType.COMMON, description = "广告ID") Long adId) throws ServiceException;
+
+    @HttpMethod(description = "修改", permission = "promote:advertisement:update", permissionParentName = "推广管理", permissionName = "广告管理")
+    public Boolean updateAdvertisement(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "adId", type = HttpParamType.COMMON, description = "广告ID") Long adId,
+            @NotNull @HttpParam(name = "adType", type = HttpParamType.COMMON, description = "广告类型") Integer adType,
+            @HttpParam(name = "title", type = HttpParamType.COMMON, description = "广告标题") String title,
+            @HttpParam(name = "url", type = HttpParamType.COMMON, description = "广告地址") String url,
+            @HttpParam(name = "imgUrl", type = HttpParamType.COMMON, description = "广告图片地址") String imgUrl,
+            @HttpParam(name = "status", type = HttpParamType.COMMON, description = "广告状态") Integer status,
+            @HttpParam(name = "color", type = HttpParamType.COMMON, description = "广告图片颜色") String color) throws ServiceException;
+
+
+    @HttpMethod(description = "查询", permission = "promote:advertisement:query", permissionParentName = "推广管理", permissionName = "广告管理")
+    public Page<AdvertisementDO> queryAdvertisement(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @HttpParam(name = "adType", type = HttpParamType.COMMON, description = "广告类型") Integer adType,
+            @Range(min = 1) @HttpParam(name = "pageNo", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer pageNo,
+            @Range(min = 1) @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页面长度", valueDef = "10") Integer limit,
+            @HttpParam(name = "status", type = HttpParamType.COMMON, description = "广告状态") Integer status) throws ServiceException;
+
+    @HttpMethod(description = "查询", permission = "promote:advertisement:query", permissionParentName = "推广管理", permissionName = "广告管理")
+    public Page<AdvertisementDO> queryAllAdvertisement(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @Range(min = 1) @HttpParam(name = "pageNo", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer pageNo,
+            @Range(min = 1) @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页面长度", valueDef = "10") Integer pageSize
+    ) throws ServiceException;
+
+
+}

+ 111 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/advertisement/AdminAdvertisementServiceImpl.java

@@ -0,0 +1,111 @@
+package com.iotechn.unimall.admin.api.advertisement;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.component.CacheComponent;
+import com.iotechn.unimall.data.domain.AdvertisementDO;
+import com.iotechn.unimall.data.domain.OrderDO;
+import com.iotechn.unimall.data.enums.AdvertisementType;
+import com.iotechn.unimall.data.mapper.AdvertisementMapper;
+import com.iotechn.unimall.data.model.Page;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-08
+ * Time: 下午9:24
+ */
+@Service
+public class AdminAdvertisementServiceImpl implements AdminAdvertisementService {
+
+    @Autowired
+    private AdvertisementMapper advertisementMapper;
+    @Autowired
+    private CacheComponent cacheComponent;
+
+    private  final  static String  ADVERTISEMENT_NAME = "ADVERTISEMENT_TYPE_";
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean addAdvertisement(Long adminId, Integer adType, String title, String url, String imgUrl, Integer status,String color) throws ServiceException {
+
+        Date now = new Date();
+        AdvertisementDO advertisementDO = new AdvertisementDO(adType,title,url,imgUrl,status,color);
+        advertisementDO.setGmtCreate(now);
+        advertisementDO.setGmtUpdate(now);
+
+        if(advertisementMapper.insert(advertisementDO) > 0){
+            cacheComponent.delPrefixKey(ADVERTISEMENT_NAME);
+            return true;
+        }
+        throw new AdminServiceException(ExceptionDefinition.ADVERTISEMENT_SQL_ADD_FAILED);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean deleteAdvertisement(Long adminId,Integer adType, Long adId) throws ServiceException {
+
+        if(advertisementMapper.delete(new EntityWrapper<AdvertisementDO>()
+                .eq("id",adId)
+                .eq("ad_type",adType)) > 0){
+            cacheComponent.delPrefixKey(ADVERTISEMENT_NAME);
+            return true;
+        }
+        throw new AdminServiceException(ExceptionDefinition.ADVERTISEMENT_SQL_DELETE_FAILED);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean updateAdvertisement(Long adminId,Long adId, Integer adType, String title, String url, String imgUrl, Integer status,String color) throws ServiceException {
+        AdvertisementDO advertisementDO = new AdvertisementDO(adType,title,url,imgUrl,status,color);
+        advertisementDO.setId(adId);
+        advertisementDO.setGmtUpdate(new Date());
+        if(advertisementMapper.updateById(advertisementDO)>0){
+            cacheComponent.delPrefixKey(ADVERTISEMENT_NAME);
+            return  true;
+        }
+        throw new AdminServiceException(ExceptionDefinition.ADVERTISEMENT_SQL_UPDATE_FAILED);
+    }
+
+    @Override
+    public Page<AdvertisementDO> queryAdvertisement(Long adminId, Integer adType, Integer pageNo, Integer limit, Integer status) throws ServiceException {
+        Wrapper<AdvertisementDO> wrapper = new EntityWrapper<AdvertisementDO>();
+        if (adType != null) {
+            wrapper.eq("ad_type", adType);
+        }
+        if (status != null) {
+            wrapper.eq("status", status);
+        }
+
+        List<AdvertisementDO> advertisementDOList = advertisementMapper.selectPage(new RowBounds(limit *(pageNo - 1), limit),wrapper);
+        Integer count = advertisementMapper.selectCount(wrapper);
+
+        Page<AdvertisementDO> page = new Page<>(advertisementDOList,pageNo, limit,count);
+
+        return page;
+
+    }
+
+    //冗余,未使用
+    @Override
+    public Page<AdvertisementDO> queryAllAdvertisement(Long adminId,Integer pageNo,Integer pageSize) throws ServiceException {
+
+        List<AdvertisementDO> advertisementDOList = advertisementMapper.getAllAdvertisement(pageSize*(pageNo-1),pageSize);
+        Integer count = advertisementMapper.selectCount(null);
+        Page<AdvertisementDO> page = new Page<>(advertisementDOList,pageNo,pageSize,count);
+        return page;
+
+    }
+}

+ 40 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/appraise/AdminAppraise.java

@@ -0,0 +1,40 @@
+package com.iotechn.unimall.admin.api.appraise;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.dto.appraise.AppraiseResponseDTO;
+import com.iotechn.unimall.data.model.Page;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-15
+ * Time: 下午3:41
+ */
+@HttpOpenApi(group = "admin.appraise", description = "评论")
+public interface AdminAppraise {
+
+    @HttpMethod(description = "删除", permission = "operation:appraise:delete", permissionParentName = "运营管理", permissionName = "评论管理")
+    public boolean deleteAppraise(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "评论id") Long id) throws ServiceException;
+
+
+    @HttpMethod(description = "查询", permission = "operation:appraise:query", permissionParentName = "运营管理", permissionName = "评论管理")
+    public Page<AppraiseResponseDTO> getAppraiseList(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @HttpParam(name = "id", type = HttpParamType.COMMON, description = "评论id") Long id,
+            @HttpParam(name = "userName", type = HttpParamType.COMMON, description = "用户姓名") String userName,
+            @HttpParam(name = "spuName", type = HttpParamType.COMMON, description = "商品名字") String spuName,
+            @HttpParam(name = "orderId", type = HttpParamType.COMMON, description = "订单ID") Long orderId,
+            @HttpParam(name = "score", type = HttpParamType.COMMON, description = "评论id") Integer score,
+            @HttpParam(name = "content", type = HttpParamType.COMMON, description = "评论id") String content,
+            @HttpParam(name = "pageNo", type = HttpParamType.COMMON, description = "页码") Integer pageNo,
+            @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度") Integer limit) throws ServiceException;
+
+}

+ 46 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/appraise/AdminAppraiseImpl.java

@@ -0,0 +1,46 @@
+package com.iotechn.unimall.admin.api.appraise;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.dto.appraise.AppraiseResponseDTO;
+import com.iotechn.unimall.data.mapper.AppraiseMapper;
+import com.iotechn.unimall.data.model.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.util.List;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-15
+ * Time: 下午3:56
+ */
+@Service
+public class AdminAppraiseImpl implements  AdminAppraise {
+
+    @Autowired
+    private AppraiseMapper appraiseMapper;
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteAppraise(Long adminId, Long id) throws ServiceException {
+        return appraiseMapper.deleteById(id) > 0;
+    }
+
+    @Override
+    public Page<AppraiseResponseDTO> getAppraiseList(Long adminId, Long id, String userName, String spuName, Long orderId, Integer score, String content,Integer pageNo,Integer limit) throws ServiceException {
+
+        Integer count = appraiseMapper.countAppraiseCondition(id,userName ,spuName , orderId, score, content);
+
+        List<AppraiseResponseDTO> appraiseResponseDTOList = appraiseMapper.selectAppraiseCondition(id,userName ,spuName , orderId, score, content,(pageNo-1)*limit,limit);
+
+        Page<AppraiseResponseDTO> page = new Page<AppraiseResponseDTO>(appraiseResponseDTOList,pageNo,limit,count);
+
+        return page;
+    }
+}

+ 62 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/category/AdminCategoryService.java

@@ -0,0 +1,62 @@
+package com.iotechn.unimall.admin.api.category;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.annotation.param.Range;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.CategoryDO;
+import com.iotechn.unimall.data.dto.CategoryDTO;
+import com.iotechn.unimall.data.dto.CategoryTreeNodeDTO;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.List;
+
+/**
+ * Created by rize on 2019/7/12.
+ */
+@HttpOpenApi(group = "admin.category", description = "类目管理服务")
+public interface AdminCategoryService {
+
+    @HttpMethod(description = "获取二级类目树")
+    public List<CategoryTreeNodeDTO> categorySecondLevelTree() throws ServiceException;
+
+    @HttpMethod(description = "获取类目树")
+    public List<CategoryTreeNodeDTO> categoryTree() throws ServiceException;
+
+    @HttpMethod(description = "创建", permission = "operation:category:create", permissionParentName = "商品管理", permissionName = "类目管理")
+    public CategoryDO addCategory(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "title", type = HttpParamType.COMMON, description = "类目标题") String title,
+            @HttpParam(name = "parentId", type = HttpParamType.COMMON, description = "类目父节点", valueDef = "0") Long parentId,
+            @HttpParam(name = "iconUrl", type = HttpParamType.COMMON, description = "类目图标") String iconUrl,
+            @HttpParam(name = "picUrl", type = HttpParamType.COMMON, description = "类目图片") String picUrl,
+            @HttpParam(name = "level", type = HttpParamType.COMMON, description = "类目等级") Integer level) throws ServiceException;
+
+    @HttpMethod(description = "删除", permission = "operation:category:delete", permissionParentName = "商品管理", permissionName = "类目管理")
+    public boolean deleteCategory(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "类目ID") Long id) throws ServiceException;
+
+    @HttpMethod(description = "修改", permission = "operation:category:update", permissionParentName = "商品管理", permissionName = "类目管理")
+    public CategoryTreeNodeDTO updateCategory(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "类目ID") Long id,
+            @NotNull @HttpParam(name = "title", type = HttpParamType.COMMON, description = "类目标题") String title,
+            @NotNull @HttpParam(name = "parentId", type = HttpParamType.COMMON, description = "类目父节点") Long parentId,
+            @HttpParam(name = "iconUrl", type = HttpParamType.COMMON, description = "类目图标") String iconUrl,
+            @HttpParam(name = "picUrl", type = HttpParamType.COMMON, description = "类目图片") String picUrl,
+            @HttpParam(name = "level", type = HttpParamType.COMMON, description = "类目等级") Integer level) throws ServiceException;
+
+    @HttpMethod(description = "查询", permission = "operation:category:query", permissionParentName = "商品管理", permissionName = "类目管理")
+    public Page<CategoryTreeNodeDTO> queryCategory(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @HttpParam(name = "id", type = HttpParamType.COMMON, description = "类目ID") Long id,
+            @HttpParam(name = "title", type = HttpParamType.COMMON, description = "类目标题") String title,
+            @HttpParam(name = "level", type = HttpParamType.COMMON, description = "类目等级") Integer level,
+            @HttpParam(name = "parentId", type = HttpParamType.COMMON, description = "父类目id") Long parentId,
+            @Range(min = 1) @HttpParam(name = "pageNo", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer pageNo,
+            @Range(min = 1) @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "10") Integer limit) throws ServiceException;
+}

+ 301 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/category/AdminCategoryServiceImpl.java

@@ -0,0 +1,301 @@
+package com.iotechn.unimall.admin.api.category;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.iotechn.unimall.core.exception.*;
+import com.iotechn.unimall.data.component.CacheComponent;
+import com.iotechn.unimall.data.domain.CategoryDO;
+import com.iotechn.unimall.data.domain.SpuDO;
+import com.iotechn.unimall.data.dto.CategoryTreeNodeDTO;
+import com.iotechn.unimall.data.mapper.CategoryMapper;
+import com.iotechn.unimall.data.mapper.SpuMapper;
+import com.iotechn.unimall.data.model.Page;
+import com.iotechn.unimall.plugin.core.inter.IPluginUpdateCategory;
+import com.iotechn.unimall.plugin.core.manager.PluginsManager;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Created by rize on 2019/7/12.
+ */
+@Service
+public class AdminCategoryServiceImpl implements AdminCategoryService {
+
+    @Autowired
+    private CategoryMapper categoryMapper;
+
+    @Autowired
+    private SpuMapper spuMapper;
+
+
+    @Autowired
+    private CacheComponent cacheComponent;
+
+    @Autowired
+    private PluginsManager pluginsManager;
+
+    private static final String CA_CATEGORY_TREE = "CA_CATEGORY_TREE";
+
+    private static final String ADMIN_QUERY_CATEGORY_LIST = "ADMIN_QUERY_CATEGORY_LIST";
+
+    private static final String CA_CATEGORY_SECOND_LEVEL_TREE = "CA_CATEGORY_SECOND_LEVEL_TREE";
+
+    /**
+     * @return
+     * @throws ServiceException
+     */
+
+
+    /*获取两级目录树*/
+    public List<CategoryTreeNodeDTO> categorySecondLevelTree() throws ServiceException {
+        List<CategoryTreeNodeDTO> objList = cacheComponent.getObjList(CA_CATEGORY_SECOND_LEVEL_TREE, CategoryTreeNodeDTO.class);
+        if (objList != null) {
+            return objList;
+        }
+        List<CategoryTreeNodeDTO> list = null;
+        cacheComponent.putObj(CA_CATEGORY_SECOND_LEVEL_TREE, list, 60 * 60);
+        return list;
+    }
+
+
+    /*获取三级目录树。*/
+    //TODO 做下优化
+    @Override
+    public List<CategoryTreeNodeDTO> categoryTree() throws ServiceException {
+        List<CategoryTreeNodeDTO> objList = cacheComponent.getObjList(CA_CATEGORY_TREE, CategoryTreeNodeDTO.class);
+        if (objList != null) {
+            return objList;
+        }
+        List<CategoryDO> categoryDOS = categoryMapper.selectList(new EntityWrapper<>());
+        List<CategoryTreeNodeDTO> list = categoryDOS.stream().filter((item) -> (item.getParentId().equals(0l))).map(item -> {
+            CategoryTreeNodeDTO dto = new CategoryTreeNodeDTO();
+            dto.setLabel(item.getTitle());
+            dto.setLevel(0);
+            dto.setFullName(dto.getLabel());
+            dto.setValue(item.getId());
+            dto.setChildren(new LinkedList<>());
+            return dto;
+        }).collect(Collectors.toList());
+        list.forEach(item -> {
+            categoryDOS.forEach(categoryDO -> {
+                if (categoryDO.getParentId().equals(item.getValue())) {
+                    CategoryTreeNodeDTO categoryTreeNodeDTO = new CategoryTreeNodeDTO();
+                    categoryTreeNodeDTO.setChildren(new LinkedList<>());
+                    categoryTreeNodeDTO.setValue(categoryDO.getId());
+                    categoryTreeNodeDTO.setLabel(categoryDO.getTitle());
+                    categoryTreeNodeDTO.setLevel(1);
+                    categoryTreeNodeDTO.setParent(item.getValue());
+                    categoryTreeNodeDTO.setFullName(item.getFullName() + "/" + categoryDO.getTitle());
+                    item.getChildren().add(categoryTreeNodeDTO);
+                    categoryDOS.forEach(subCategoryDO -> {
+                        if (subCategoryDO.getParentId().equals(categoryTreeNodeDTO.getValue())) {
+                            CategoryTreeNodeDTO childCategoryNodeDTO = new CategoryTreeNodeDTO();
+                            childCategoryNodeDTO.setLabel(subCategoryDO.getTitle());
+                            childCategoryNodeDTO.setValue(subCategoryDO.getId());
+                            childCategoryNodeDTO.setLevel(2);
+                            childCategoryNodeDTO.setParent(categoryTreeNodeDTO.getValue());
+                            childCategoryNodeDTO.setFullName(categoryTreeNodeDTO.getFullName() + "/" + subCategoryDO.getTitle());
+                            categoryTreeNodeDTO.getChildren().add(childCategoryNodeDTO);
+                        }
+                    });
+                }
+            });
+        });
+        cacheComponent.putObj(CA_CATEGORY_TREE, list, 60 * 60);
+        return list;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public CategoryDO addCategory(Long adminId, String title, Long parentId, String iconUrl, String picUrl, Integer level) throws ServiceException {
+        CategoryDO parent = null;
+        CategoryDO categoryDO = new CategoryDO();
+        if (!parentId.equals(0l)) {
+            parent = categoryMapper.selectById(parentId);
+            if (parent == null) {
+                throw new AdminServiceException(ExceptionDefinition.PARENT_NODE_INFORMATION_ERROR);
+            }
+            categoryDO.setLevel(parent.getLevel() + 1);
+        } else {
+            categoryDO.setLevel(0);
+        }
+        categoryDO.setParentId(parentId);
+        categoryDO.setIconUrl(iconUrl);
+        categoryDO.setPicUrl(picUrl);
+        categoryDO.setTitle(title);
+        Date now = new Date();
+        categoryDO.setGmtCreate(now);
+        categoryDO.setGmtUpdate(now);
+
+        if (categoryMapper.insert(categoryDO) <= 0) {
+            throw new AdminServiceException(ExceptionDefinition.DATABASE_INSERT_FAILURE);
+        }
+        cacheComponent.del(CA_CATEGORY_TREE);
+        cacheComponent.del(ADMIN_QUERY_CATEGORY_LIST);
+        cacheComponent.del(CA_CATEGORY_SECOND_LEVEL_TREE);
+//        cacheComponent.del(CategoryBizService.CA_CATEGORY_ID_HASH);
+//        cacheComponent.del(CategoryBizService.CA_CATEGORY_LIST);
+        pluginInvokeUpdateCategory(categoryDO.getId());
+        return categoryDO;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteCategory(Long adminId, Long id) throws ServiceException {
+        Integer count_category = categoryMapper.selectCount(new EntityWrapper<CategoryDO>().eq("parent_id", id));
+        Integer count_spu = spuMapper.selectCount(new EntityWrapper<SpuDO>().eq("category_id", id));
+
+        if (count_category != 0 || count_spu != 0) {
+            throw new AppServiceException(ExceptionDefinition.CATEGORY_OUGHT_TO_EMPTY);
+        }
+        cacheComponent.del(CA_CATEGORY_TREE);
+        cacheComponent.del(ADMIN_QUERY_CATEGORY_LIST);
+        cacheComponent.del(CA_CATEGORY_SECOND_LEVEL_TREE);
+//        cacheComponent.del(CategoryBizService.CA_CATEGORY_ID_HASH);
+//        cacheComponent.del(CategoryBizService.CA_CATEGORY_LIST);
+        pluginInvokeUpdateCategory(id);
+        return categoryMapper.deleteById(id) > 0;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public CategoryTreeNodeDTO updateCategory(Long adminId, Long id, String title, Long parentId, String iconUrl, String picUrl, Integer level) throws ServiceException {
+        CategoryDO categoryDO = new CategoryDO();
+        if (id == null || parentId == null) {
+            throw new AdminServiceException(ExceptionDefinition.CATEGORY_OR_PARENT_NODE_IS_EMPTY);
+        }
+        categoryDO.setId(parentId);
+        CategoryDO categoryParent = categoryMapper.selectOne(categoryDO);
+
+        //传入父节点等于自身抛出异常
+        if (id.equals(parentId)) {
+            throw new AdminServiceException(ExceptionDefinition.PARENT_CAN_NOT_EQUALS_ONESELF);
+        }
+
+        if (categoryParent == null && !parentId.equals(0L)) {
+            throw new AdminServiceException(ExceptionDefinition.NOT_FIND_PARENT_NODE);
+        }
+        if (parentId.equals(0L)) {
+            categoryDO.setLevel(0);
+        } else {
+            categoryDO.setLevel(categoryParent.getLevel() + 1);
+        }
+        categoryDO.setId(id);
+        categoryDO.setGmtUpdate(new Date());
+        categoryDO.setParentId(parentId);
+        categoryDO.setTitle(title);
+        categoryDO.setPicUrl(picUrl);
+        categoryDO.setIconUrl(iconUrl);
+        if (categoryMapper.updateById(categoryDO) <= 0) {
+            throw new AdminServiceException(ExceptionDefinition.CATEGORY_UPDATE_FAILURE);
+        }
+        CategoryTreeNodeDTO categoryTreeNodeDTO = new CategoryTreeNodeDTO();
+        List<CategoryTreeNodeDTO> list = getCategoryList();
+        for (CategoryTreeNodeDTO temp : list) {
+            if (categoryDO.getId().equals(temp.getValue())) {
+                BeanUtils.copyProperties(temp, categoryTreeNodeDTO);
+                break;
+            }
+        }
+        cacheComponent.del(CA_CATEGORY_TREE);
+        cacheComponent.del(ADMIN_QUERY_CATEGORY_LIST);
+        cacheComponent.del(CA_CATEGORY_SECOND_LEVEL_TREE);
+//        cacheComponent.del(CategoryBizService.CA_CATEGORY_ID_HASH);
+//        cacheComponent.del(CategoryBizService.CA_CATEGORY_LIST);
+        pluginInvokeUpdateCategory(categoryDO.getId());
+        return categoryTreeNodeDTO;
+    }
+
+    //首先的到所有的类目的List<CategoryTreeNodeDTO>,在根据SQL查询得到的数据转化成传往前端的数据
+    @Override
+    public Page<CategoryTreeNodeDTO> queryCategory(Long adminId, Long id, String title, Integer level, Long parentId, Integer pageNo, Integer limit) throws ServiceException {
+        EntityWrapper wrapper = new EntityWrapper();
+        if (id != null) {
+            wrapper.eq("id", id);
+        }
+        if (title != null) {
+            wrapper.like("title", title);
+        }
+        if (level != null) {
+            wrapper.eq("level", level);
+        }
+        if (parentId != null) {
+            wrapper.eq("parent_id", parentId);
+        }
+        wrapper.orderBy("level");
+        Integer count = categoryMapper.selectCount(wrapper);
+
+        List<CategoryDO> categoryDOS = categoryMapper.selectPage(new RowBounds((pageNo - 1) * limit, limit), wrapper);
+        List<CategoryTreeNodeDTO> totalCategory = getCategoryList();
+        List<CategoryTreeNodeDTO> list = categoryDOS.stream().map(item -> {
+            CategoryTreeNodeDTO dto = new CategoryTreeNodeDTO();
+            for (CategoryTreeNodeDTO temp : totalCategory) {
+                if (temp.getValue().equals(item.getId())) {
+                    BeanUtils.copyProperties(temp, dto);
+                    return dto;
+                }
+            }
+            BeanUtils.copyProperties(item, dto);
+            ;
+            return dto;
+        }).collect(Collectors.toList());
+        Page<CategoryTreeNodeDTO> page = new Page<>(list, pageNo, limit, count);
+        return page;
+    }
+
+
+    //TODO 可以做出父节点查询所有子节点
+    //获得所有类目按类目等级排序的类目list,
+    private List<CategoryTreeNodeDTO> getCategoryList() {
+        List<CategoryTreeNodeDTO> objList = cacheComponent.getObjList(ADMIN_QUERY_CATEGORY_LIST, CategoryTreeNodeDTO.class);
+        if (objList != null) {
+            return objList;
+        }
+        EntityWrapper wrapper = new EntityWrapper();
+        wrapper.orderBy("level");
+        List<CategoryDO> categoryDOS = categoryMapper.selectList(wrapper);
+        List<CategoryTreeNodeDTO> list = categoryDOS.stream().map(item -> {
+            CategoryTreeNodeDTO dto = new CategoryTreeNodeDTO();
+            dto.setLabel(item.getTitle());
+            dto.setLevel(item.getLevel());
+            dto.setValue(item.getId());
+            dto.setParent(item.getParentId());
+            dto.setIconUrl(item.getIconUrl());
+            dto.setPicUrl(item.getPicUrl());
+            if (item.getLevel() == 0) {
+                dto.setFullName(dto.getLabel());
+            }
+            return dto;
+        }).collect(Collectors.toList());
+
+        for (CategoryTreeNodeDTO cOne : list) {
+
+            for (CategoryTreeNodeDTO cTwo : list) {
+                if (cOne.getParent().equals(cTwo.getValue())) {
+                    cOne.setFullName(cTwo.getFullName() + "/" + cOne.getLabel());
+                    break;
+                }
+            }
+
+        }
+        cacheComponent.putObj(ADMIN_QUERY_CATEGORY_LIST, list, 60 * 60);
+        return list;
+    }
+
+    private void pluginInvokeUpdateCategory(Long categoryId) {
+        List<IPluginUpdateCategory> plugins = pluginsManager.getPlugins(IPluginUpdateCategory.class);
+        if (!CollectionUtils.isEmpty(plugins)) {
+            for (IPluginUpdateCategory updateGoods : plugins) {
+                updateGoods.invokeCategoryUpdate(categoryId);
+            }
+        }
+    }
+
+
+}

+ 54 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/config/AdminMerchantConfigService.java

@@ -0,0 +1,54 @@
+package com.iotechn.unimall.admin.api.config;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.annotation.param.Range;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.CategoryDO;
+import com.iotechn.unimall.data.domain.ConfigDO;
+import com.iotechn.unimall.data.dto.CategoryTreeNodeDTO;
+import com.iotechn.unimall.data.dto.ConfigDTO;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.List;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-20
+ * Time: 上午10:18
+ */
+
+@HttpOpenApi(group = "admin.merchant", description = "商铺信息配置")
+public interface AdminMerchantConfigService {
+
+    @HttpMethod(description = "创建", permission = "promote:merchant:create", permissionParentName = "推广管理", permissionName = "商铺信息管理")
+    public boolean addMerchant(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "title", type = HttpParamType.COMMON, description = "商铺标题") String title,
+            @HttpParam(name = "logoUrl", type = HttpParamType.COMMON, description = "商铺logo") String logoUrl,
+            @HttpParam(name = "description", type = HttpParamType.COMMON, description = "商铺描述") String description,
+            @HttpParam(name = "address", type = HttpParamType.COMMON, description = "商铺地址") String address,
+            @NotNull @HttpParam(name = "showType", type = HttpParamType.COMMON, description = "展示方式") Integer showType
+    ) throws ServiceException;
+
+    @HttpMethod(description = "修改", permission = "promote:merchant:update", permissionParentName = "推广管理", permissionName = "商铺信息管理")
+    public boolean updateMerchant(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "title", type = HttpParamType.COMMON, description = "商铺标题") String title,
+            @HttpParam(name = "logoUrl", type = HttpParamType.COMMON, description = "商铺logo") String logoUrl,
+            @HttpParam(name = "description", type = HttpParamType.COMMON, description = "商铺描述") String description,
+            @HttpParam(name = "address", type = HttpParamType.COMMON, description = "商铺地址") String address,
+            @NotNull @HttpParam(name = "showType", type = HttpParamType.COMMON, description = "展示方式") Integer showType
+    ) throws ServiceException;
+
+    @HttpMethod(description = "查询", permission = "promote:merchant:query", permissionParentName = "推广管理", permissionName = "商铺信息管理")
+    public ConfigDTO getMerchant(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+
+}

+ 74 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/config/AdminMerchantConfigServiceImpl.java

@@ -0,0 +1,74 @@
+package com.iotechn.unimall.admin.api.config;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.ConfigDO;
+import com.iotechn.unimall.data.dto.ConfigDTO;
+import com.iotechn.unimall.data.mapper.ConfigMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-20
+ * Time: 上午10:47
+ */
+@Service
+public class AdminMerchantConfigServiceImpl implements AdminMerchantConfigService {
+
+    @Autowired
+    private ConfigMapper configMapper;
+
+//    @Autowired
+//    private ConfigBizService configBizService;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addMerchant(Long adminId, String title, String logoUrl, String description, String address, Integer showType) throws ServiceException {
+        Date now = new Date();
+        ConfigDO titleDO = new ConfigDO("title",title);
+            titleDO.setGmtCreate(now);titleDO.setGmtUpdate(now);
+        ConfigDO logoDO = new ConfigDO("logoUrl",logoUrl);
+            logoDO.setGmtCreate(now);logoDO.setGmtUpdate(now);
+        ConfigDO descDO = new ConfigDO("description",description);
+            descDO.setGmtCreate(now);descDO.setGmtUpdate(now);
+        ConfigDO addressDO = new ConfigDO("address",address);
+            addressDO.setGmtCreate(now);addressDO.setGmtUpdate(now);
+        ConfigDO showTypeDO = new ConfigDO("showType",String.valueOf(showType));
+            showTypeDO.setGmtCreate(now);showTypeDO.setGmtUpdate(now);
+        configMapper.insert(titleDO);
+        configMapper.insert(logoDO);
+        configMapper.insert(descDO);
+        configMapper.insert(addressDO);
+        configMapper.insert(showTypeDO);
+//        configBizService.clearMerchantConfigCache();
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateMerchant(Long adminId, String title, String logoUrl, String description, String address, Integer showType) throws ServiceException {
+        configMapper.update(new ConfigDO("title",title), new EntityWrapper<ConfigDO>().eq("key_word","title"));
+
+        configMapper.update(new ConfigDO("logoUrl",logoUrl), new EntityWrapper<ConfigDO>().eq("key_word","logoUrl"));
+
+        configMapper.update(new ConfigDO("description",description), new EntityWrapper<ConfigDO>().eq("key_word","description"));
+
+        configMapper.update(new ConfigDO("address",address), new EntityWrapper<ConfigDO>().eq("key_word","address"));
+
+        configMapper.update(new ConfigDO("showType",String.valueOf(showType)), new EntityWrapper<ConfigDO>().eq("key_word","showType"));
+
+//        configBizService.clearMerchantConfigCache();
+        return true;
+    }
+
+    @Override
+    public ConfigDTO getMerchant(Long adminId) throws ServiceException {
+        return null;
+    }
+}

+ 82 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/coupon/AdminCouponService.java

@@ -0,0 +1,82 @@
+package com.iotechn.unimall.admin.api.coupon;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.CouponDO;
+import com.iotechn.unimall.data.dto.CouponAdminDTO;
+import com.iotechn.unimall.data.dto.CouponDTO;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.Date;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-12
+ * Time: 下午10:47
+ */
+
+@HttpOpenApi(group = "admin.coupon", description = "优惠卷")
+public interface AdminCouponService {
+
+    @HttpMethod(description = "创建", permission = "promote:coupon:create", permissionParentName = "推广管理", permissionName = "优惠管理")
+    public CouponDO addCoupon(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "title", type = HttpParamType.COMMON, description = "优惠卷标题") String title,
+            @NotNull @HttpParam(name = "type", type = HttpParamType.COMMON, description = "优惠卷类别,如满减") Integer type,
+            @HttpParam(name = "description", type = HttpParamType.COMMON, description = "优惠卷描述") String description,
+            @NotNull @HttpParam(name = "total", type = HttpParamType.COMMON, description = "优惠卷总数") Integer total,
+            @NotNull @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "用户限制领取") Integer limit,
+            @NotNull @HttpParam(name = "discount", type = HttpParamType.COMMON, description = "优惠价格") Integer discount,
+            @NotNull @HttpParam(name = "min", type = HttpParamType.COMMON, description = "满足优惠的最低价格") Integer min,
+            @NotNull @HttpParam(name = "status", type = HttpParamType.COMMON, description = "优惠卷状态") Integer status,
+            @HttpParam(name = "categoryId", type = HttpParamType.COMMON, description = "优惠类别") Long categoryId,
+            @HttpParam(name = "days", type = HttpParamType.COMMON, description = "优惠时长") Integer days,
+            @HttpParam(name = "gmtStart", type = HttpParamType.COMMON, description = "优惠开始时间") Long gmtStart,
+            @HttpParam(name = "gmtEnd", type = HttpParamType.COMMON, description = "优惠结束时间") Long gmtEnd) throws ServiceException;
+
+    @HttpMethod(description = "删除", permission = "promote:coupon:delete", permissionParentName = "推广管理", permissionName = "优惠管理")
+    public Boolean deleteCoupon(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "优惠卷ID") Long id) throws ServiceException;
+
+    @HttpMethod(description = "修改", permission = "promote:coupon:update", permissionParentName = "推广管理", permissionName = "优惠管理")
+    public Boolean updateCoupon(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "优惠卷ID") Long id,
+            @NotNull @HttpParam(name = "title", type = HttpParamType.COMMON, description = "优惠卷标题") String title,
+            @NotNull @HttpParam(name = "type", type = HttpParamType.COMMON, description = "优惠卷类别,如满减") Integer type,
+            @HttpParam(name = "description", type = HttpParamType.COMMON, description = "优惠卷描述") String description,
+            @NotNull @HttpParam(name = "total", type = HttpParamType.COMMON, description = "优惠卷总数") Integer total,
+            @NotNull @HttpParam(name = "surplus", type = HttpParamType.COMMON, description = "优惠卷剩余") Integer surplus,
+            @NotNull @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "用户限制领取") Integer limit,
+            @NotNull @HttpParam(name = "discount", type = HttpParamType.COMMON, description = "优惠价格") Integer discount,
+            @NotNull @HttpParam(name = "min", type = HttpParamType.COMMON, description = "满足优惠的最低价格") Integer min,
+            @NotNull @HttpParam(name = "status", type = HttpParamType.COMMON, description = "优惠卷状态") Integer status,
+            @HttpParam(name = "categoryId", type = HttpParamType.COMMON, description = "优惠类别") Long categoryId,
+            @HttpParam(name = "days", type = HttpParamType.COMMON, description = "优惠时长") Integer days,
+            @HttpParam(name = "gmtStart", type = HttpParamType.COMMON, description = "优惠开始时间") Date gmtStart,
+            @HttpParam(name = "gmtEnd", type = HttpParamType.COMMON, description = "优惠结束时间") Date gmtEnd) throws ServiceException;
+
+    @HttpMethod(description = "修改", permission = "promote:coupon:update", permissionParentName = "推广管理", permissionName = "优惠管理")
+    public Boolean updateCouponStatus(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "优惠卷ID") Long id,
+            @NotNull @HttpParam(name = "status", type = HttpParamType.COMMON, description = "优惠卷状态") Integer status) throws ServiceException;
+
+
+    @HttpMethod(description = "查询", permission = "promote:coupon:query", permissionParentName = "推广管理", permissionName = "优惠管理")
+    public Page<CouponAdminDTO> queryCouponByTitle(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @HttpParam(name = "title", type = HttpParamType.COMMON, description = "优惠卷标题") String title,
+            @HttpParam(name = "type", type = HttpParamType.COMMON, description = "优惠卷类型") Integer type,
+            @HttpParam(name = "status", type = HttpParamType.COMMON, description = "优惠卷状态") Integer status,
+            @HttpParam(name = "pageNo", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer pageNo,
+            @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "10") Integer limit) throws ServiceException;
+
+}

+ 123 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/coupon/AdminCouponServiceImpl.java

@@ -0,0 +1,123 @@
+package com.iotechn.unimall.admin.api.coupon;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.CouponDO;
+import com.iotechn.unimall.data.dto.CouponAdminDTO;
+import com.iotechn.unimall.data.mapper.CouponMapper;
+import com.iotechn.unimall.data.mapper.UserCouponMapper;
+import com.iotechn.unimall.data.model.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-12
+ * Time: 下午11:26
+ */
+@Service
+public class AdminCouponServiceImpl implements AdminCouponService {
+
+    @Autowired
+    private CouponMapper couponMapper;
+
+    @Autowired
+    private UserCouponMapper userCouponMapper;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public CouponDO addCoupon(Long adminId, String title, Integer type, String description, Integer total, Integer limit, Integer discount, Integer min, Integer status, Long categoryId, Integer days, Long gmtStart, Long gmtEnd) throws ServiceException {
+
+        Date start = null;
+        Date end = null;
+        if (gmtEnd != null && gmtStart != null) {
+            start = new Date(gmtStart);
+            end = new Date(gmtEnd);
+        }
+
+        CouponDO couponDO = new CouponDO(title, type, description, total, total, limit, discount, min, status, categoryId, days, start, end);
+
+        Date now = new Date();
+        couponDO.setGmtCreate(now);
+        couponDO.setGmtUpdate(now);
+        if (couponMapper.insert(couponDO) > 0) {
+            return couponDO;
+        }
+        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean deleteCoupon(Long adminId, Long id) throws ServiceException {
+        EntityWrapper wrapperC = new EntityWrapper();
+        wrapperC.eq("id", id);
+        if (couponMapper.delete(wrapperC) <= 0) {
+            throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
+        }
+        EntityWrapper wrapperUC = new EntityWrapper();
+        wrapperUC.eq("coupon_id", id);
+        userCouponMapper.delete(wrapperUC);
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean updateCoupon(Long adminId, Long id, String title, Integer type, String description, Integer total, Integer surplus, Integer limit, Integer discount, Integer min, Integer status, Long categoryId, Integer days, Date gmtStart, Date gmtEnd) throws ServiceException {
+        CouponDO couponDO = new CouponDO(title, type, description, total, surplus, limit, discount, min, status, categoryId, days, gmtStart, gmtEnd);
+        couponDO.setId(id);
+        List<CouponDO> couponDOList = couponMapper.selectList(new EntityWrapper<CouponDO>().eq("id", id));
+        if (CollectionUtils.isEmpty(couponDOList)) {
+            throw new AdminServiceException(ExceptionDefinition.COUPON_NOT_EXIST);
+        }
+        Date now = new Date();
+        couponDO.setGmtCreate(couponDOList.get(0).getGmtCreate());
+        couponDO.setGmtUpdate(now);
+        return couponMapper.updateAllColumnById(couponDO) > 0;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean updateCouponStatus(Long adminId, Long id, Integer status) throws ServiceException {
+        CouponDO couponDO = new CouponDO();
+        couponDO.setId(id);
+        couponDO.setStatus(status);
+        couponDO.setGmtUpdate(new Date());
+        return couponMapper.updateById(couponDO) > 0;
+    }
+
+    @Override
+    public Page<CouponAdminDTO> queryCouponByTitle(Long adminId, String title, Integer type, Integer status, Integer pageNo, Integer limit) throws ServiceException {
+        EntityWrapper wrapper = new EntityWrapper();
+        Date now = new Date();
+        if (!StringUtils.isEmpty(title)) {
+            wrapper.like("title", title);
+        }
+        if (type != null) {
+            wrapper.eq("type", type);
+        }
+        if (status != null) {
+            if (status >= 0 && status < 2) {
+                wrapper.eq("status", status);
+                wrapper.andNew().gt("gmt_end", now).or().isNotNull("days"); //coupon -> conpon.gt("gmt_end", now).or().isNotNull("days")
+            } else if (status < 0) {
+                wrapper.lt("gmt_end", now);
+            } else {
+                throw new AdminServiceException(ExceptionDefinition.COUPON_CHECK_DATA_FAILED);
+            }
+        }
+        Integer count = couponMapper.selectCount(wrapper);
+        List<CouponAdminDTO> couponDTOList = couponMapper.getAdminCouponList(title, type, status, now, (pageNo - 1) * limit, limit);
+        Page<CouponAdminDTO> page = new Page<CouponAdminDTO>(couponDTOList, pageNo, limit, count);
+        return page;
+    }
+}

+ 20 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dashboard/DashboardService.java

@@ -0,0 +1,20 @@
+package com.iotechn.unimall.admin.api.dashboard;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+
+/**
+ * Created by rize on 2019/7/15.
+ */
+@HttpOpenApi(group = "admin.dashboard" , description = "首页数据服务")
+public interface DashboardService {
+
+    @HttpMethod(description = "聚合数据")
+    public Object integral(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId) throws ServiceException;
+
+}

+ 86 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dashboard/DashboardServiceImpl.java

@@ -0,0 +1,86 @@
+package com.iotechn.unimall.admin.api.dashboard;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.OrderDO;
+import com.iotechn.unimall.data.domain.SpuDO;
+import com.iotechn.unimall.data.dto.DashboardIntegralDTO;
+import com.iotechn.unimall.data.enums.OrderStatusType;
+import com.iotechn.unimall.data.mapper.OrderMapper;
+import com.iotechn.unimall.data.mapper.SpuMapper;
+import com.iotechn.unimall.data.model.KVModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Created by rize on 2019/7/15.
+ */
+@Service
+public class DashboardServiceImpl implements DashboardService {
+
+    @Autowired
+    private OrderMapper orderMapper;
+
+    @Autowired
+    private SpuMapper spuMapper;
+
+    @Override
+    public Object integral(Long adminId) throws ServiceException {
+        DashboardIntegralDTO dto = new DashboardIntegralDTO();
+        Integer orderWaitStock = orderMapper.selectCount(new EntityWrapper<OrderDO>().eq("status", OrderStatusType.WAIT_STOCK.getCode()));
+        Integer spuCount = spuMapper.selectCount(new EntityWrapper<SpuDO>());
+        List<KVModel<String, Long>> area = orderMapper.selectAreaStatistics();
+        List<KVModel<String, Long>> channel = orderMapper.selectChannelStatistics();
+        dto.setArea(area);
+        dto.setChannel(channel);
+        dto.setWaitStockCount(orderWaitStock);
+        dto.setGoodsCount(spuCount);
+        Integer days = 7;
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
+        String startDay = sdf.format(new Date(System.currentTimeMillis() - 1000l * 60 * 60 * 24 * days));
+        List<KVModel<String, Long>> orderCountKVList = orderMapper.selectOrderCountStatistics(startDay);
+        List<KVModel<String, Long>> orderSumKVList = orderMapper.selectOrderSumStatistics(startDay);
+        SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
+        List<Object[]> orderCount = new LinkedList<>();
+        Object[] orderCountNameArray = new Object[days];
+        Object[] orderCountValueArray = new Object[days];
+        orderCount.add(orderCountNameArray);
+        orderCount.add(orderCountValueArray);
+        dto.setDaysOrder(orderCount);
+        List<Object[]> orderSum = new LinkedList<>();
+        Object[] orderSumNameArray = new Object[days];
+        Object[] orderSumValueArray = new Object[days];
+        orderSum.add(orderSumNameArray);
+        orderSum.add(orderSumValueArray);
+        dto.setDaysSum(orderSum);
+        //这里是在补全 group by 为 0 的情况
+        for (int i = 0; i < days; i++) {
+            Date date = new Date(System.currentTimeMillis() - 1000l * 60 * 60 * 24 * i);
+            String key = sdfDay.format(date);
+            int i1 = orderCountKVList.indexOf(new KVModel<>(key, null));
+            if (i1 >= 0) {
+                orderCountNameArray[days - i - 1] = key;
+                orderCountValueArray[days - i - 1] = orderCountKVList.get(i1).getValue();
+            } else {
+                orderCountNameArray[days - i - 1] = key;
+                orderCountValueArray[days - i - 1] = 0;
+            }
+
+            int i2 = orderSumKVList.indexOf(new KVModel<>(key, null));
+            if (i2 >= 0) {
+                orderSumNameArray[days - i - 1] = key;
+                orderSumValueArray[days - i - 1] = orderSumKVList.get(i2).getValue();
+            } else {
+                orderSumNameArray[days - i - 1] = key;
+                orderSumValueArray[days - i - 1] = 0;
+            }
+        }
+        return dto;
+    }
+}

+ 50 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dict/DictDataService.java

@@ -0,0 +1,50 @@
+package com.iotechn.unimall.admin.api.dict;
+
+import java.util.List;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.sys.dict.SysDictData;
+import com.iotechn.unimall.data.model.Page;
+
+@HttpOpenApi(group = "admin.dictData", description = "字典数据服务")
+public interface DictDataService {
+	@HttpMethod(description = "创建", permission = "admin:dictData:add", permissionParentName = "系统管理", permissionName = "字典管理")
+	public Boolean add(
+			@NotNull @HttpParam(name = "dictData", type = HttpParamType.COMMON, description = "字典信息") SysDictData dictData)
+			throws ServiceException;
+
+	@HttpMethod(description = "列表", permission = "admin:dictData:list", permissionParentName = "系统管理", permissionName = "字典管理")
+	public Page<SysDictData> list(
+			@HttpParam(name = "dictType", type = HttpParamType.COMMON, description = "字典类型") String dictType,
+			@HttpParam(name = "dictLabel", type = HttpParamType.COMMON, description = "字典标签") String dictLabel,
+			@HttpParam(name = "status", type = HttpParamType.COMMON, description = "状态") String status,
+			@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+			@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+			throws ServiceException;
+
+	@HttpMethod(description = "删除", permission = "admin:dictData:delete", permissionParentName = "系统管理", permissionName = "字典管理")
+	public Boolean delete(
+			@NotNull @HttpParam(name = "dictCodes", type = HttpParamType.COMMON, description = "字典Id") String dictCodes)
+			throws ServiceException;
+
+	@HttpMethod(description = "修改", permission = "admin:dictData:update", permissionParentName = "系统管理", permissionName = "字典管理")
+	public Boolean update(
+			@NotNull @HttpParam(name = "dictData", type = HttpParamType.COMMON, description = "字典信息") SysDictData dictData)
+			throws ServiceException;
+
+	@HttpMethod(description = "查询", permission = "admin:dictData:get", permissionParentName = "系统管理", permissionName = "字典管理")
+	public SysDictData get(
+			@HttpParam(name = "dictCode", type = HttpParamType.COMMON, description = "字典ID") String dictCode)
+			throws ServiceException;
+
+	@HttpMethod(description = "根据字典类型查询所属数据", permission = "admin:dictData:selectDictDataByType", permissionParentName = "系统管理", permissionName = "字典管理")
+	public List<SysDictData> selectDictDataByType(
+			@HttpParam(name = "dictType", type = HttpParamType.COMMON, description = "字典类型") String dictType)
+			throws ServiceException;
+
+}

+ 77 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dict/DictDataserviceImpl.java

@@ -0,0 +1,77 @@
+package com.iotechn.unimall.admin.api.dict;
+
+import java.util.List;
+
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.sys.dict.SysDictData;
+import com.iotechn.unimall.data.mapper.sys.dict.SysDictDataMapper;
+import com.iotechn.unimall.data.model.Page;
+/**
+ * 
+ * @author dyl
+ *
+ */
+@Service
+public class DictDataserviceImpl implements DictDataService{
+
+	@Autowired
+	private SysDictDataMapper dictDataMapper;
+	
+	@Override
+	public Boolean add(SysDictData dictData) throws ServiceException {
+		return dictDataMapper.insert(dictData)>0;
+	}
+
+	@Override
+	public Page<SysDictData> list(String dictType, String dictLabel, String status,Integer page, Integer limit)
+			throws ServiceException {
+		Wrapper<SysDictData> wrapper = new EntityWrapper<SysDictData>();
+		if (!StringUtils.isEmpty(dictType)) {
+			wrapper.eq("dict_type", dictType);
+		}
+		if (!StringUtils.isEmpty(dictType)) {
+			wrapper.like("dict_label", dictLabel);
+		}
+		if (!StringUtils.isEmpty(status)) {
+			wrapper.like("status", status);
+		}
+		List<SysDictData> SysDictDataS = dictDataMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+		Integer count = dictDataMapper.selectCount(wrapper);
+		return new Page<SysDictData>(SysDictDataS, page, limit, count);
+	}
+
+	@Override
+	public Boolean delete(String dictCodes) throws ServiceException {
+		String[] ids=dictCodes.split(",");
+		Wrapper<SysDictData> wrapper = new EntityWrapper<SysDictData>();
+		wrapper.in("dict_code", ids);
+		return dictDataMapper.delete(wrapper)>0;
+	}
+
+	@Override
+	public Boolean update(SysDictData dictData) throws ServiceException {
+		return dictDataMapper.updateById(dictData)>0;
+	}
+
+	@Override
+	public SysDictData get(String dictCode) throws ServiceException {
+		return dictDataMapper.selectById(dictCode);
+	}
+
+	@Override
+	public List<SysDictData> selectDictDataByType(String dictType) throws ServiceException {
+		Wrapper<SysDictData> wrapper = new EntityWrapper<SysDictData>();
+        if (!StringUtils.isEmpty(dictType)) {
+            wrapper.eq("dict_type", dictType);
+        }
+		return dictDataMapper.selectList(wrapper);
+	}
+
+}

+ 48 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dict/DictTypeService.java

@@ -0,0 +1,48 @@
+package com.iotechn.unimall.admin.api.dict;
+
+import java.util.List;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.sys.dict.SysDictType;
+import com.iotechn.unimall.data.model.Page;
+
+@HttpOpenApi(group = "admin.dictType", description = "字典类型服务")
+public interface DictTypeService {
+	@HttpMethod(description = "创建", permission = "admin:dictType:add", permissionParentName = "系统管理", permissionName = "字典管理")
+	public Boolean add(
+			@NotNull @HttpParam(name = "dictType", type = HttpParamType.COMMON, description = "字典信息") SysDictType dictType)
+			throws ServiceException;
+
+	@HttpMethod(description = "列表", permission = "admin:dictType:list", permissionParentName = "系统管理", permissionName = "字典管理")
+	public Page<SysDictType> list(
+			@HttpParam(name = "dictName", type = HttpParamType.COMMON, description = "字典名称") String dictName,
+			@HttpParam(name = "dictType", type = HttpParamType.COMMON, description = "字典类型") String dictType,
+			@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+			@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+			throws ServiceException;
+
+	@HttpMethod(description = "删除", permission = "admin:dictType:delete", permissionParentName = "系统管理", permissionName = "字典管理")
+	public Boolean delete(
+			@NotNull @HttpParam(name = "dictIds", type = HttpParamType.COMMON, description = "字典Id") String dictIds)
+			throws ServiceException;
+
+	@HttpMethod(description = "修改", permission = "admin:dictType:update", permissionParentName = "系统管理", permissionName = "字典管理")
+	public Boolean update(
+			@NotNull @HttpParam(name = "dictType", type = HttpParamType.COMMON, description = "字典信息") SysDictType dictType)
+			throws ServiceException;
+
+	@HttpMethod(description = "查询", permission = "admin:dictType:get", permissionParentName = "系统管理", permissionName = "字典管理")
+	public SysDictType get(
+			@HttpParam(name = "dictId", type = HttpParamType.COMMON, description = "字典ID") Long dictId)
+			throws ServiceException;
+
+	@HttpMethod(description = "字典选择框列表", permission = "admin:dictType:optionselect", permissionParentName = "系统管理", permissionName = "字典管理")
+	public List<SysDictType> optionselect()throws ServiceException;
+
+
+}

+ 86 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/dict/DictTypeServiceImpl.java

@@ -0,0 +1,86 @@
+package com.iotechn.unimall.admin.api.dict;
+
+import java.util.List;
+
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.sys.dict.SysDictType;
+import com.iotechn.unimall.data.mapper.sys.dict.SysDictTypeMapper;
+import com.iotechn.unimall.data.model.Page;
+
+/**
+ * 
+ * @author dyl
+ *
+ */
+@Service
+public class DictTypeServiceImpl implements DictTypeService {
+
+	@Autowired
+	private SysDictTypeMapper typeMapper;
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public Boolean add(SysDictType sysDictType) throws ServiceException {
+		Long dictId;
+		if (sysDictType.getDictId() == null)
+			dictId = -1L;
+		else
+			dictId = sysDictType.getDictId();
+		SysDictType dictType = typeMapper.checkDictTypeUnique(sysDictType);
+		if (dictType != null && dictType.getDictId().longValue() != dictId.longValue()) {
+			throw new AdminServiceException(ExceptionDefinition.DICT_TYPE_HAS_EXISTED);
+		}
+		return typeMapper.insert(sysDictType) > 0;
+	}
+
+	@Override
+	public Page<SysDictType> list(String dictName, String dictType, Integer page, Integer limit)
+			throws ServiceException {
+		Wrapper<SysDictType> wrapper = new EntityWrapper<SysDictType>();
+		if (!StringUtils.isEmpty(dictName)) {
+			wrapper.like("dict_name", dictName);
+		}
+		if (!StringUtils.isEmpty(dictType)) {
+			wrapper.eq("dict_type", dictType);
+		}
+		List<SysDictType> SysDictTypeS = typeMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+		Integer count = typeMapper.selectCount(wrapper);
+		return new Page<SysDictType>(SysDictTypeS, page, limit, count);
+	}
+
+	@Override
+	public Boolean delete(String dictIds) throws ServiceException {
+		String[] ids=dictIds.split(",");
+		Wrapper<SysDictType> wrapper = new EntityWrapper<SysDictType>();
+		wrapper.in("dict_id", ids);
+		return typeMapper.delete(wrapper) > 0;
+	}
+
+	@Override
+	public Boolean update(SysDictType dictType) throws ServiceException {
+
+		return typeMapper.updateById(dictType) > 0;
+	}
+
+	@Override
+	public SysDictType get(Long dictId) throws ServiceException {
+		return typeMapper.selectById(dictId);
+	}
+
+	@Override
+	public List<SysDictType> optionselect() throws ServiceException {
+		return typeMapper.selectDictTypeAll();
+	}
+
+
+}

+ 62 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/freight/AdminFreightTemplateService.java

@@ -0,0 +1,62 @@
+package com.iotechn.unimall.admin.api.freight;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.annotation.param.Range;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.FreightTemplateCarriageDO;
+import com.iotechn.unimall.data.dto.freight.FreightTemplateDTO;
+
+import java.util.List;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-07
+ * Time: 下午3:37
+ */
+@HttpOpenApi(group = "admin.freight", description = "运费模板")
+public interface AdminFreightTemplateService {
+
+    @HttpMethod(description = "创建", permission = "operation:freight:create", permissionParentName = "运营管理", permissionName = "运费模板管理")
+    public boolean addFreightTemplate(
+            @NotNull @HttpParam(name = "templateName", type = HttpParamType.COMMON, description = "模板名称") String templateName,
+            @HttpParam(name = "spuLocation", type = HttpParamType.COMMON, description = "宝贝地址") String spuLocation,
+            @NotNull @HttpParam(name = "deliveryDeadline", type = HttpParamType.COMMON, description = "发货期限") Integer deliveryDeadline,
+            @NotNull @HttpParam(name = "defaultFreePrice", type = HttpParamType.COMMON, description = "默认满价包邮系列") Integer defaultFreePrice,
+            @NotNull @HttpParam(name = "defaultFirstNum", type = HttpParamType.COMMON, description = "默认首费") Integer defaultFirstNum,
+            @NotNull @Range(min = 1) @HttpParam(name = "defaultFirstPrice", type = HttpParamType.COMMON, description = "默认首件数量") Integer defaultFirstPrice,
+            @NotNull @HttpParam(name = "defaultContinueNum", type = HttpParamType.COMMON, description = "默认续费") Integer defaultContinueNum,
+            @NotNull @Range(min = 1) @HttpParam(name = "defaultContinuePrice", type = HttpParamType.COMMON, description = "默认续件数量") Integer defaultContinuePrice,
+            @HttpParam(name = "freightTemplateCarriageDOList", type = HttpParamType.COMMON, description = "特殊运费区") List freightTemplateCarriageDOList,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId
+    ) throws ServiceException;
+
+    @HttpMethod(description = "删除", permission = "operation:freight:delete", permissionParentName = "运营管理", permissionName = "运费模板管理")
+    public boolean deleteFreightTemplate(
+            @NotNull @HttpParam(name = "templateId", type = HttpParamType.COMMON, description = "模板ID") Long templateId,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+    @HttpMethod(description = "更新", permission = "operation:freight:update", permissionParentName = "运营管理", permissionName = "运费模板管理")
+    public boolean updateFreightTemplate(
+            @NotNull @HttpParam(name = "templateId", type = HttpParamType.COMMON, description = "模板名称") Long templateId,
+            @NotNull @HttpParam(name = "templateName", type = HttpParamType.COMMON, description = "模板名称") String templateName,
+            @HttpParam(name = "spuLocation", type = HttpParamType.COMMON, description = "宝贝地址") String spuLocation,
+            @NotNull @HttpParam(name = "deliveryDeadline", type = HttpParamType.COMMON, description = "发货期限") Integer deliveryDeadline,
+            @NotNull @HttpParam(name = "defaultFreePrice", type = HttpParamType.COMMON, description = "默认满价包邮系列") Integer defaultFreePrice,
+            @NotNull @Range(min = 1) @HttpParam(name = "defaultFirstNum", type = HttpParamType.COMMON, description = "默认首费") Integer defaultFirstNum,
+            @NotNull @Range(min = 0) @HttpParam(name = "defaultFirstPrice", type = HttpParamType.COMMON, description = "默认首件数量") Integer defaultFirstPrice,
+            @NotNull @Range(min = 1) @HttpParam(name = "defaultContinueNum", type = HttpParamType.COMMON, description = "默认续费") Integer defaultContinueNum,
+            @NotNull @Range(min = 0) @HttpParam(name = "defaultContinuePrice", type = HttpParamType.COMMON, description = "默认续件数量") Integer defaultContinuePrice,
+            @HttpParam(name = "freightTemplateCarriageDOList", type = HttpParamType.COMMON, description = "特殊运费区") List templateCarriageDOList,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+    @HttpMethod(description = "查询", permission = "operation:freight:query", permissionParentName = "运营管理", permissionName = "运费模板管理")
+    public List<FreightTemplateDTO> getAllFreightTemplate(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+}

+ 146 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/freight/AdminFreightTemplateServiceImpl.java

@@ -0,0 +1,146 @@
+package com.iotechn.unimall.admin.api.freight;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.TypeReference;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.component.CacheComponent;
+import com.iotechn.unimall.data.domain.FreightTemplateCarriageDO;
+import com.iotechn.unimall.data.domain.FreightTemplateDO;
+import com.iotechn.unimall.data.domain.SpuDO;
+import com.iotechn.unimall.data.dto.freight.FreightTemplateDTO;
+import com.iotechn.unimall.data.mapper.FreightTemplateCarriageMapper;
+import com.iotechn.unimall.data.mapper.FreightTemplateMapper;
+import com.iotechn.unimall.data.mapper.SpuMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-07
+ * Time: 下午4:25
+ */
+@Service
+public class AdminFreightTemplateServiceImpl implements AdminFreightTemplateService {
+
+    @Autowired
+    private FreightTemplateMapper freightTemplateMapper;
+
+    @Autowired
+    private FreightTemplateCarriageMapper freightTemplateCarriageMapper;
+
+    @Autowired
+    private SpuMapper spuMapper;
+
+    @Autowired
+    private CacheComponent cacheComponent;
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addFreightTemplate(String templateName, String spuLocation, Integer deliveryDeadline, Integer defaultFreePrice, Integer defaultFirstNum, Integer defaultFirstPrice, Integer defaultContinueNum, Integer defaultContinuePrice, List freightTemplateCarriageDOList, Long adminId) throws ServiceException {
+        Date now = new Date();
+        FreightTemplateDO freightTemplateDO = new FreightTemplateDO(templateName, spuLocation, deliveryDeadline, defaultFreePrice, defaultFirstNum, defaultFirstPrice, defaultContinueNum, defaultContinuePrice);
+        freightTemplateDO.setGmtCreate(now);
+        freightTemplateDO.setGmtUpdate(now);
+        int judgeSQL = freightTemplateMapper.insert(freightTemplateDO); //插入模板主表
+        if (judgeSQL <= 0) {
+            throw new AdminServiceException(ExceptionDefinition.FREIGHT_TEMPLATE_INSERT_FAILED);
+        }
+        if (CollectionUtils.isEmpty(freightTemplateCarriageDOList)) {
+            return true;
+        }
+        List<FreightTemplateCarriageDO> collect = (List<FreightTemplateCarriageDO>) freightTemplateCarriageDOList.stream().map(item -> {
+            FreightTemplateCarriageDO t = JSONObject.toJavaObject((JSON) item, FreightTemplateCarriageDO.class);
+            return t;
+        }).collect(Collectors.toList());
+        insertFreightTemplateCarriage(freightTemplateDO, collect, now);
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteFreightTemplate(Long templateId, Long adminId) throws ServiceException {
+        if (spuMapper.selectCount(new EntityWrapper<SpuDO>().eq("freight_template_id", templateId)) > 0) {
+            throw new AdminServiceException(ExceptionDefinition.FREIGHT_SPU_QUERY_HAS);
+        }
+        if (freightTemplateMapper.delete(new EntityWrapper<FreightTemplateDO>().eq("id", templateId)) <= 0) {
+            throw new AdminServiceException(ExceptionDefinition.FREIGHT_TEMPLATE_DELETE_FAILED);
+        }
+        if (freightTemplateCarriageMapper.delete(
+                new EntityWrapper<FreightTemplateCarriageDO>()
+                        .eq("template_id", templateId)) > 0) {
+//            cacheComponent.delPrefixKey(GoodsBizService.CA_SPU_PREFIX);
+            return true;
+        }
+        throw new AdminServiceException(ExceptionDefinition.FREIGHT_TEMPLATE_UPDATE_FAILED);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateFreightTemplate(Long templateId, String templateName, String spuLocation, Integer deliveryDeadline, Integer defaultFreePrice, Integer defaultFirstNum, Integer defaultFirstPrice, Integer defaultContinueNum, Integer defaultContinuePrice, List freightTemplateCarriageDOList, Long adminId) throws ServiceException {
+        Date now = new Date();
+        FreightTemplateDO freightTemplateDO = new FreightTemplateDO(templateName, spuLocation, deliveryDeadline, defaultFreePrice, defaultFirstNum, defaultFirstPrice, defaultContinueNum, defaultContinuePrice);
+        freightTemplateDO.setId(templateId);
+        freightTemplateDO.setGmtUpdate(now);
+        if (freightTemplateMapper.updateById(freightTemplateDO) <= 0) {    //如果主表修改失败
+            throw new AdminServiceException(ExceptionDefinition.FREIGHT_TEMPLATE_UPDATE_FAILED);
+        }
+        freightTemplateCarriageMapper.delete(new EntityWrapper<FreightTemplateCarriageDO>().eq("template_id", templateId));
+        if (CollectionUtils.isEmpty(freightTemplateCarriageDOList)) {
+            return true;
+        }
+        List<FreightTemplateCarriageDO> collect = (List<FreightTemplateCarriageDO>) freightTemplateCarriageDOList.stream().map(item -> {
+            FreightTemplateCarriageDO t = JSONObject.toJavaObject((JSON) item, FreightTemplateCarriageDO.class);
+            return t;
+        }).collect(Collectors.toList());
+        insertFreightTemplateCarriage(freightTemplateDO, collect, now);
+//        cacheComponent.delPrefixKey(GoodsBizService.CA_SPU_PREFIX);
+        return true;
+    }
+
+    private void insertFreightTemplateCarriage(FreightTemplateDO freightTemplateDO, List<FreightTemplateCarriageDO> freightTemplateCarriageDOList, Date now) throws ServiceException {
+        //表中设定可默认值,所以就不检查是否为空
+        for (FreightTemplateCarriageDO freightTemplateCarriageDO : freightTemplateCarriageDOList) {
+            freightTemplateCarriageDO.setTemplateId(freightTemplateDO.getId());
+            freightTemplateCarriageDO.setGmtCreate(now);
+            freightTemplateCarriageDO.setGmtUpdate(now);
+            Integer judgeSQL = freightTemplateCarriageMapper.insert(freightTemplateCarriageDO);
+            if (judgeSQL <= 0) {
+                throw new AdminServiceException(ExceptionDefinition.FREIGHT_CARRIAGE_INSERT_FAILED);
+            }
+        }
+    }
+
+    @Override
+    public List<FreightTemplateDTO> getAllFreightTemplate(Long adminId) throws ServiceException {
+        List<FreightTemplateDO> freightTemplateDOList = freightTemplateMapper.selectList(null); //查出主表所有数据
+        List<FreightTemplateDTO> freightTemplateDTOList = new ArrayList<>();
+        if (freightTemplateDOList == null || freightTemplateDOList.size() == 0) { //如果主表没有记录
+            return freightTemplateDTOList;
+        }
+        for (FreightTemplateDO freightTemplateDO : freightTemplateDOList) {  //查出副表中,主表每条数据对应的数据
+            FreightTemplateDTO freightTemplateDTO = new FreightTemplateDTO();
+            List<FreightTemplateCarriageDO> freightTemplateCarriageDOList = freightTemplateCarriageMapper.selectList(new EntityWrapper<FreightTemplateCarriageDO>()
+                    .eq("template_id", freightTemplateDO.getId()));
+            freightTemplateDTO.setFreightTemplateDO(freightTemplateDO);
+            freightTemplateDTO.setFreightTemplateCarriageDOList(freightTemplateCarriageDOList);
+            freightTemplateDTOList.add(freightTemplateDTO);
+        }
+        return freightTemplateDTOList;
+    }
+
+
+}

+ 64 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/goods/AdminGoodsService.java

@@ -0,0 +1,64 @@
+package com.iotechn.unimall.admin.api.goods;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.dto.goods.SpuDTO;
+import com.iotechn.unimall.data.dto.goods.SpuTreeNodeDTO;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.List;
+
+/**
+ * Created by rize on 2019/7/11.
+ */
+@HttpOpenApi(group = "admin.goods", description = "管理员商品服务")
+public interface AdminGoodsService {
+
+    @HttpMethod(description = "获取SPU树")
+    public List<SpuTreeNodeDTO> getSpuBigTree(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "创建", permission = "operation:goods:create", permissionParentName = "商品管理", permissionName = "商品管理")
+    public String create(
+            @NotNull @HttpParam(name = "spuDTO", type = HttpParamType.COMMON, description = "商品JSON数据") SpuDTO spuDTO,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "编辑", permission = "operation:goods:edit", permissionParentName = "商品管理", permissionName = "商品管理")
+    public String edit(
+            @NotNull @HttpParam(name = "spuDTO", type = HttpParamType.COMMON, description = "商品JSON数据") SpuDTO spuDTO,
+            @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+    @HttpMethod(description = "列表", permission = "operation:goods:list", permissionParentName = "商品管理", permissionName = "商品管理")
+    public Page<SpuDTO> list(
+            @HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+            @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit,
+            @HttpParam(name = "categoryId", type = HttpParamType.COMMON, description = "搜索分类") Long categoryId,
+            @HttpParam(name = "title", type = HttpParamType.COMMON, description = "搜索标题") String title,
+            @HttpParam(name = "barcode", type = HttpParamType.COMMON, description = "商品条形码") String barcode,
+            @HttpParam(name = "status", type = HttpParamType.COMMON, description = "商品状态") Integer status,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId) throws ServiceException;
+
+    @HttpMethod(description = "详情", permission = "operation:goods:detail", permissionParentName = "商品管理", permissionName = "商品管理")
+    public SpuDTO detail(
+            @NotNull @HttpParam(name = "spuId", type = HttpParamType.COMMON, description = "商品Id") Long spuId,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId) throws ServiceException;
+
+    @HttpMethod(description = "上下架", permission = "operation:goods:edit", permissionParentName = "商品管理", permissionName = "商品管理")
+    public SpuDTO freezeOrActivation(
+            @NotNull @HttpParam(name = "spuId", type = HttpParamType.COMMON, description = "商品Id") Long spuId,
+            @NotNull @HttpParam(name = "status", type = HttpParamType.COMMON, description = "商品想要变为的状态") Integer status,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "删除", permission = "operation:goods:delete", permissionParentName = "商品管理", permissionName = "商品管理")
+    public String delete(
+            @NotNull @HttpParam(name = "spuId", type = HttpParamType.COMMON, description = "商品Id") Long spuId,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId) throws ServiceException;
+
+}

+ 413 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/goods/AdminGoodsServiceImpl.java

@@ -0,0 +1,413 @@
+package com.iotechn.unimall.admin.api.goods;
+
+import com.baomidou.mybatisplus.entity.Column;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.Const;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.component.CacheComponent;
+import com.iotechn.unimall.data.domain.*;
+import com.iotechn.unimall.data.dto.goods.SpuDTO;
+import com.iotechn.unimall.data.dto.goods.SpuTreeNodeDTO;
+import com.iotechn.unimall.data.enums.BizType;
+import com.iotechn.unimall.data.enums.SpuStatusType;
+import com.iotechn.unimall.data.mapper.*;
+import com.iotechn.unimall.data.model.Page;
+import com.iotechn.unimall.plugin.core.inter.IPluginUpdateGoods;
+import com.iotechn.unimall.plugin.core.manager.PluginsManager;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Created by rize on 2019/7/11.
+ */
+@Service
+public class AdminGoodsServiceImpl implements AdminGoodsService {
+
+    @Autowired
+    private CategoryMapper categoryMapper;
+
+    @Autowired
+    private SpuMapper spuMapper;
+
+    @Autowired
+    private SkuMapper skuMapper;
+
+    @Autowired
+    private SpuAttributeMapper spuAttributeMapper;
+
+    @Autowired
+    private ImgMapper imgMapper;
+
+    @Autowired
+    private CartMapper cartMapper;
+
+
+
+    @Autowired
+    private PluginsManager pluginsManager;
+
+    @Autowired
+    private CacheComponent cacheComponent;
+
+    private static final Column[] spuBaseColumns = {
+            Column.create().column("id"),
+            Column.create().column("original_price").as("originalPrice"),
+            Column.create().column("price"),
+            Column.create().column("vip_price").as("vipPrice"),
+            Column.create().column("title"),
+            Column.create().column("sales"),
+            Column.create().column("img"),
+            Column.create().column("description"),
+            Column.create().column("category_id").as("categoryId"),
+            Column.create().column("freight_template_id").as("freightTemplateId"),
+            Column.create().column("unit"),
+            Column.create().column("status")};
+
+    /**
+     * 后台低频接口, 无需缓存
+     * @return
+     * @throws ServiceException
+     */
+    public List<SpuTreeNodeDTO> getSpuBigTree(Long adminId) throws  ServiceException{
+        List<CategoryDO> categoryDOS = categoryMapper.selectList(new EntityWrapper<CategoryDO>().orderBy("level"));
+        List<SpuDO> spuDOS = spuMapper.getSpuTitleAll();
+        List<SpuTreeNodeDTO> list = new ArrayList<>();
+        Integer recordLevelOne = 0;
+        Integer recordLevelTwo = 0;
+        for (int i = 0; i < categoryDOS.size(); i++) {
+            if(i != 0 && categoryDOS.get(i-1).getLevel().equals(0) && categoryDOS.get(i).getLevel().equals(1)){
+                recordLevelOne = i;
+            }
+            if(i != 0 && categoryDOS.get(i-1).getLevel().equals(1) && categoryDOS.get(i).getLevel().equals(2)){
+                recordLevelTwo = i;
+                break;
+            }
+        }
+
+        for (int i = 0; i < recordLevelOne; i++) {
+            CategoryDO categoryOnI = categoryDOS.get(i);    //一级类目
+            SpuTreeNodeDTO dtoOnI = new SpuTreeNodeDTO();
+            dtoOnI.setLabel(categoryOnI.getTitle());
+            dtoOnI.setValue("C_" + categoryOnI.getId());
+            dtoOnI.setId(categoryOnI.getId());
+            dtoOnI.setChildren(new LinkedList<>());
+            for (int j = recordLevelOne; j < recordLevelTwo; j++) {
+                CategoryDO categoryOnJ = categoryDOS.get(j);    //二级类目
+                if(!categoryOnJ.getParentId().equals(dtoOnI.getId())){
+                    continue;
+                }
+
+                SpuTreeNodeDTO dtoOnJ = new SpuTreeNodeDTO();
+                dtoOnJ.setLabel(categoryOnJ.getTitle());
+                dtoOnJ.setValue("C_" + categoryOnJ.getId());
+                dtoOnJ.setId(categoryOnJ.getId());
+                dtoOnJ.setChildren(new LinkedList<>());
+                
+                for (int p = recordLevelTwo; p <categoryDOS.size() ; p++) {
+                    CategoryDO categoryOnP = categoryDOS.get(p);    //三级类目
+                    if(!categoryOnP.getParentId().equals(dtoOnJ.getId())){
+                        continue;
+                    }
+
+                    SpuTreeNodeDTO dtoOnP = new SpuTreeNodeDTO();
+                    dtoOnP.setLabel(categoryOnP.getTitle());
+                    dtoOnP.setValue("C_" + categoryOnP.getId());
+                    dtoOnP.setId(categoryOnP.getId());
+                    dtoOnP.setChildren(new LinkedList<>());
+
+                    for (int k = 0; k < spuDOS.size(); k++) {
+                        if(k != 0 && spuDOS.get(k-1).getCategoryId().equals(dtoOnP.getId()) && !spuDOS.get(k).getCategoryId().equals(dtoOnP.getId())){
+                            break;
+                        }
+                        SpuDO spuDO = spuDOS.get(k);        //商品
+                        if(spuDO.getCategoryId().equals(dtoOnP.getId())){
+                            SpuTreeNodeDTO dtoOnK = new SpuTreeNodeDTO();
+                            dtoOnK.setLabel(spuDO.getTitle());
+                            dtoOnK.setValue("G_" + spuDO.getId());
+                            dtoOnK.setId(spuDO.getId());
+                            dtoOnK.setChildren(new LinkedList<>());
+                            dtoOnP.getChildren().add(dtoOnK);
+                        }
+                    }
+                    dtoOnJ.getChildren().add(dtoOnP);
+                }
+                dtoOnI.getChildren().add(dtoOnJ);
+            }
+            list.add(dtoOnI);
+        }
+        return list;
+    }
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public String create(SpuDTO spuDTO, Long adminId) throws ServiceException {
+        //参数校验
+        if (CollectionUtils.isEmpty(spuDTO.getSkuList())) {
+            throw new AdminServiceException(ExceptionDefinition.GOODS_SKU_LIST_EMPTY);
+        }
+        if (spuDTO.getId() != null) {
+            throw new AdminServiceException(ExceptionDefinition.GOODS_CREATE_HAS_ID);
+        }
+        if (spuDTO.getOriginalPrice() < spuDTO.getPrice() || spuDTO.getPrice() < spuDTO.getVipPrice() || spuDTO.getOriginalPrice() < spuDTO.getVipPrice()) {
+            throw new AdminServiceException(ExceptionDefinition.GOODS_PRICE_CHECKED_FAILED);
+        }
+        //校验Sku是否重复
+        List<String> barCodes = spuDTO.getSkuList().stream().map(item -> item.getBarCode()).collect(Collectors.toList());
+        List<SkuDO> existSkuDO = skuMapper.selectList(new EntityWrapper<SkuDO>().in("bar_code", barCodes));
+        if (!CollectionUtils.isEmpty(existSkuDO)) {
+            String spuIds = existSkuDO.stream().map(item -> item.getSpuId().toString()).collect(Collectors.joining(","));
+            String skuIds = existSkuDO.stream().map(item -> item.getBarCode()).collect(Collectors.joining(","));
+            throw new AdminServiceException(ExceptionDefinition
+                    .buildVariableException(ExceptionDefinition.GOODS_CREATE_BARCODE_REPEAT, spuIds, skuIds));
+        }
+        Date now = new Date();
+        SpuDO spuDO = new SpuDO();
+        BeanUtils.copyProperties(spuDTO, spuDO);
+        spuDO.setGmtUpdate(now);
+        spuDO.setGmtCreate(now);
+        spuDO.setSales(0);
+        spuMapper.insert(spuDO);
+        spuDTO.setId(spuDO.getId());
+        //插入SKU表
+        for (SkuDO skuDO : spuDTO.getSkuList()) {
+            if (skuDO.getOriginalPrice() < skuDO.getPrice() || skuDO.getPrice() < skuDO.getVipPrice() || skuDO.getOriginalPrice() < skuDO.getVipPrice()) {
+                throw new AdminServiceException(ExceptionDefinition.GOODS_PRICE_CHECKED_FAILED);
+            }
+            skuDO.setSpuId(spuDO.getId());
+            skuDO.setGmtUpdate(now);
+            skuDO.setGmtCreate(now);
+            skuDO.setFreezeStock(0);
+            skuMapper.insert(skuDO);
+        }
+        //插入spuAttr
+        insertSpuAttribute(spuDTO, now);
+        //插入IMG
+        insertSpuImg(spuDTO, spuDO.getId(), now);
+//        goodsBizService.clearGoodsCache(spuDO.getId());
+        pluginUpdateInvoke(spuDO.getId());
+
+//        cacheComponent.delPrefixKey(GoodsBizService.CA_SPU_PAGE_PREFIX);
+        return "ok";
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public String edit(SpuDTO spuDTO, Long adminId) throws ServiceException {
+        if (spuDTO.getId() == null) {
+            throw new AdminServiceException(ExceptionDefinition.PARAM_CHECK_FAILED);
+        }
+        if (CollectionUtils.isEmpty(spuDTO.getSkuList())) {
+            throw new AdminServiceException(ExceptionDefinition.GOODS_SKU_LIST_EMPTY);
+        }
+        if (spuDTO.getOriginalPrice() < spuDTO.getPrice() || spuDTO.getPrice() < spuDTO.getVipPrice() || spuDTO.getOriginalPrice() < spuDTO.getVipPrice()) {
+            throw new AdminServiceException(ExceptionDefinition.GOODS_PRICE_CHECKED_FAILED);
+        }
+        Date now = new Date();
+        SpuDO spuDO = new SpuDO();
+        BeanUtils.copyProperties(spuDTO, spuDO);
+        spuDO.setGmtUpdate(now);
+        spuMapper.updateById(spuDO);
+        List<String> barCodes = new LinkedList<>();
+        for (SkuDO skuDO : spuDTO.getSkuList()) {
+            if (skuDO.getOriginalPrice() < skuDO.getPrice() || skuDO.getPrice() < skuDO.getVipPrice() || skuDO.getOriginalPrice() < skuDO.getVipPrice()) {
+                throw new AdminServiceException(ExceptionDefinition.GOODS_PRICE_CHECKED_FAILED);
+            }
+            skuDO.setId(null);
+            skuDO.setSpuId(spuDO.getId());
+            skuDO.setGmtUpdate(now);
+            skuDO.setFreezeStock(0);
+            if (skuMapper.update(skuDO,
+                    new EntityWrapper<SkuDO>()
+                            .eq("bar_code", skuDO.getBarCode())) <= 0) {
+                skuDO.setGmtCreate(now);
+                skuMapper.insert(skuDO);
+            }
+            barCodes.add(skuDO.getBarCode());
+        }
+        //删除多余barCode
+        skuMapper.delete(new EntityWrapper<SkuDO>().eq("spu_id", spuDO.getId()).notIn("bar_code",barCodes));
+        //插入spuAttr
+        spuAttributeMapper.delete(new EntityWrapper<SpuAttributeDO>().eq("spu_id", spuDTO.getId()));
+        insertSpuAttribute(spuDTO, now);
+        imgMapper.delete(new EntityWrapper<ImgDO>().eq("biz_id", spuDO.getId()).eq("biz_type", BizType.GOODS.getCode()));
+        //插入IMG
+        insertSpuImg(spuDTO, spuDO.getId(), now);
+//        goodsBizService.clearGoodsCache(spuDTO.getId());
+        pluginUpdateInvoke(spuDTO.getId());
+
+//        cacheComponent.delPrefixKey(GoodsBizService.CA_SPU_PAGE_PREFIX);
+        return "ok";
+    }
+
+    private void insertSpuAttribute(SpuDTO spuDTO, Date now) {
+        if (!CollectionUtils.isEmpty(spuDTO.getAttributeList())) {
+            for (SpuAttributeDO spuAttributeDO : spuDTO.getAttributeList()) {
+                spuAttributeDO.setSpuId(spuDTO.getId());
+                spuAttributeDO.setGmtUpdate(now);
+                spuAttributeDO.setGmtCreate(now);
+                spuAttributeMapper.insert(spuAttributeDO);
+            }
+        }
+    }
+
+    private void insertSpuImg(SpuDTO spuDTO, Long bizId, Date now) {
+        List<String> imgList = spuDTO.getImgList();
+        List<ImgDO> imgDOList = imgList.stream().map(item -> {
+            ImgDO imgDO = new ImgDO();
+            imgDO.setBizType(BizType.GOODS.getCode());
+            imgDO.setBizId(bizId);
+            imgDO.setUrl(item);
+            imgDO.setGmtCreate(now);
+            imgDO.setGmtUpdate(now);
+            return imgDO;
+        }).collect(Collectors.toList());
+        imgMapper.insertImgs(imgDOList);
+    }
+
+    @Override
+    public Page<SpuDTO> list(Integer page, Integer limit, Long categoryId, String title,String barcode, Integer status, Long adminId) throws ServiceException {
+        Wrapper<SpuDO> wrapper = new EntityWrapper<SpuDO>();
+
+        if (!StringUtils.isEmpty(title)) {
+            wrapper.like("title", title);
+        }
+
+        if (categoryId != null && categoryId != 0L) {
+            List<CategoryDO> childrenList = categoryMapper.selectList(new EntityWrapper<CategoryDO>().eq("parent_id", categoryId));
+            // 传入类目拥有的三级类目集合
+            LinkedList<Long> childrenIds = new LinkedList<>();
+
+            // 传入类目没有子类目
+            if (CollectionUtils.isEmpty(childrenList)) {
+                // 则传入类目为三级类目
+                childrenIds.add(categoryId);
+            } else {
+
+                CategoryDO categoryDO = categoryMapper.selectById(categoryId);
+
+                // 检验传入类目是一级还是二级类目
+                if (categoryDO.getParentId() != 0L) {
+                    //二级分类
+                    childrenList.forEach(item -> {
+                        childrenIds.add(item.getId());
+                    });
+                } else {
+                    //一级分类
+                    childrenList.forEach(item -> {
+                        List<CategoryDO> leafList = categoryMapper.selectList(new EntityWrapper<CategoryDO>().eq("parent_id", item.getId()));
+                        if (!CollectionUtils.isEmpty(leafList)) {
+                            leafList.forEach(leafItem -> {
+                                childrenIds.add(leafItem.getId());
+                            });
+                        }
+                    });
+                }
+            }
+            wrapper.in("category_id", childrenIds);
+        }
+
+        if(status != null){
+            wrapper.eq("status", status.intValue() <= SpuStatusType.STOCK.getCode()?SpuStatusType.STOCK.getCode():SpuStatusType.SELLING.getCode());
+        }
+
+        if(barcode != null){
+            List<SkuDO> skuDOList = skuMapper.selectList(new EntityWrapper<SkuDO>().eq("bar_code", barcode));
+            if(!CollectionUtils.isEmpty(skuDOList)){
+                SkuDO skuDO = skuDOList.get(0);
+                wrapper.eq("id",skuDO.getSpuId());
+            }
+        }
+
+        wrapper.setSqlSelect(spuBaseColumns);
+        List<SpuDO> spuDOS = spuMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+
+        //组装SPU
+        List<SpuDTO> spuDTOList = new ArrayList<>();
+        spuDOS.forEach(item -> {
+            SpuDTO spuDTO = new SpuDTO();
+            BeanUtils.copyProperties(item, spuDTO);
+            List<SkuDO> skuDOList = skuMapper.selectList(new EntityWrapper<SkuDO>().eq("spu_id", item.getId()));
+            spuDTO.setSkuList(skuDOList);
+            spuDTOList.add(spuDTO);
+        });
+
+        Integer count = spuMapper.selectCount(wrapper);
+        Page<SpuDTO> dtoPage = new Page<>(spuDTOList, page, limit, count);
+
+        return dtoPage;
+    }
+
+    @Override
+    public SpuDTO detail(Long spuId, Long adminId) throws ServiceException {
+//        return goodsBizService.getGoods(spuId, null);
+        return null;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public String delete(Long spuId, Long adminId) throws ServiceException {
+        if (spuMapper.deleteById(spuId) <= 0) {
+            throw new AdminServiceException(ExceptionDefinition.GOODS_NOT_EXIST);
+        }
+        cartMapper.delete(new EntityWrapper<CartDO>().in("sku_id", skuMapper.getSkuIds(spuId)));
+        skuMapper.delete(new EntityWrapper<SkuDO>().eq("spu_id", spuId));
+        imgMapper.delete(new EntityWrapper<ImgDO>().eq("biz_id", spuId).eq("biz_type", BizType.GOODS.getCode()));
+        spuAttributeMapper.delete(new EntityWrapper<SpuAttributeDO>().eq("spu_id", spuId));
+//        goodsBizService.clearGoodsCache(spuId);
+        pluginUpdateInvoke(spuId);
+
+//        cacheComponent.delPrefixKey(GoodsBizService.CA_SPU_PAGE_PREFIX);
+        return "ok";
+    }
+
+    private void pluginUpdateInvoke(Long spuId) {
+        List<IPluginUpdateGoods> plugins = pluginsManager.getPlugins(IPluginUpdateGoods.class);
+        if (!CollectionUtils.isEmpty(plugins)) {
+            for (IPluginUpdateGoods updateGoods : plugins) {
+                updateGoods.invokeGoodsUpdate(spuId);
+            }
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public SpuDTO freezeOrActivation(Long spuId, Integer status, Long adminId) throws ServiceException {
+        SpuDO spuDO = spuMapper.selectById(spuId);
+
+        if(spuDO == null){
+            throw new AdminServiceException(ExceptionDefinition.GOODS_NOT_EXIST);
+        }
+
+        status = status <= SpuStatusType.STOCK.getCode() ? SpuStatusType.STOCK.getCode() : SpuStatusType.SELLING.getCode();
+
+        if(spuDO.getStatus().intValue() == status.intValue()){
+            throw new AdminServiceException(ExceptionDefinition.GOODS_NEED_STATUS_ERROR);
+        }
+
+        spuDO.setStatus(status);
+        spuDO.setGmtUpdate(new Date());
+        if(spuMapper.updateById(spuDO) <= 0){
+            throw new AdminServiceException(ExceptionDefinition.GOODS_UPDATE_SQL_FAILED);
+        }
+
+        SpuDTO spuDTO = new SpuDTO();
+        BeanUtils.copyProperties(spuDO,spuDTO);
+        List<SkuDO> skuDOList = skuMapper.selectList(new EntityWrapper<SkuDO>().eq("spu_id", spuDO.getId()));
+        spuDTO.setSkuList(skuDOList);
+
+//        cacheComponent.delPrefixKey(GoodsBizService.CA_SPU_PAGE_PREFIX);
+        return spuDTO;
+    }
+}

+ 55 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/goods/AdminGroupShopGoodsService.java

@@ -0,0 +1,55 @@
+package com.iotechn.unimall.admin.api.goods;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.annotation.param.Range;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.GroupShopSkuDO;
+import com.iotechn.unimall.data.dto.goods.GroupShopDTO;
+import com.iotechn.unimall.data.dto.goods.SpuDTO;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.List;
+
+@HttpOpenApi(group = "admin.groupShop", description = "管理团购商品服务")
+public interface AdminGroupShopGoodsService {
+
+    @HttpMethod(description = "增加", permission = "operation:groupShop:create", permissionParentName = "商品管理", permissionName = "团购商品管理")
+    public String addGroupShopSpu(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId,
+            @NotNull @HttpParam(name = "spuId", type = HttpParamType.COMMON, description = "spuId") Long spuId,
+            @NotNull @HttpParam(name = "gmtStart", type = HttpParamType.COMMON, description = "团购开始时间戳") Long gmtStart,
+            @NotNull @HttpParam(name = "gmtEnd", type = HttpParamType.COMMON, description = "团购结束时间戳") Long gmtEnd,
+            @NotNull @Range(min = 1) @HttpParam(name = "minimumNumber", type = HttpParamType.COMMON, description = "团购最低人数") Integer minimumNumber,
+            @NotNull @HttpParam(name = "automaticRefund", type = HttpParamType.COMMON, description = "团购人数未满是否自动退款")  Integer automaticRefund,
+            @NotNull @HttpParam(name = "groupShopSkuList", type = HttpParamType.COMMON, description = "团购sku链表") List groupShopSkuList) throws ServiceException;
+
+    @HttpMethod(description = "删除", permission = "operation:groupShop:delete", permissionParentName = "商品管理", permissionName = "团购商品管理")
+    public String deleteGroupShopSpu(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId,
+            @NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "团购商品的Id") Long id) throws  ServiceException;
+
+    @HttpMethod(description = "修改", permission = "operation:groupShop:update", permissionParentName = "商品管理", permissionName = "团购商品管理")
+    public GroupShopDTO editGroupShopSpu(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId,
+            @NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "团购商品spuID") Long id,
+            @NotNull @HttpParam(name = "spuId", type = HttpParamType.COMMON, description = "spuId") Long spuId,
+            @NotNull @HttpParam(name = "gmtStart", type = HttpParamType.COMMON, description = "团购开始时间戳") Long gmtStart,
+            @NotNull @HttpParam(name = "gmtEnd", type = HttpParamType.COMMON, description = "团购结束时间戳") Long gmtEnd,
+            @NotNull @Range(min = 1) @HttpParam(name = "minimumNumber", type = HttpParamType.COMMON, description = "团购最低人数") Integer minimumNumber,
+            @NotNull @HttpParam(name = "automaticRefund", type = HttpParamType.COMMON, description = "团购人数未满是否自动退款")  Integer automaticRefund,
+            @NotNull @HttpParam(name = "groupShopSkuList", type = HttpParamType.COMMON, description = "团购sku链表") List groupShopSkuDOList ) throws ServiceException;
+
+    @HttpMethod(description = "查询", permission = "operation:groupShop:query", permissionParentName = "商品管理", permissionName = "团购商品管理")
+    public Page<GroupShopDTO> queryGroupShop(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId,
+            @HttpParam(name = "id", type = HttpParamType.COMMON, description = "团购商品的ID") Long id,
+            @HttpParam(name = "spuName", type = HttpParamType.COMMON, description = "团购商品的名称") String spuName,
+            @HttpParam(name = "status", type = HttpParamType.COMMON, description = "团购商品的状态") Integer status,
+            @Range(min = 1) @HttpParam(name = "page", type = HttpParamType.COMMON, description = "团购商品页码", valueDef = "1") Integer page,
+            @Range(min = 1) @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "团购商品长度", valueDef = "20") Integer limit ) throws ServiceException;
+
+}

+ 290 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/goods/AdminGroupShopGoodsServiceImpl.java

@@ -0,0 +1,290 @@
+package com.iotechn.unimall.admin.api.goods;/*
+@PackageName:com.iotechn.unimall.admin.api.goods
+@ClassName: AdminGroupShopGoodsServiceImpl
+@Description:
+@author kbq
+@date 19-11-13下午4:21
+*/
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.iotechn.unimall.admin.api.order.AdminOrderService;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.component.CacheComponent;
+import com.iotechn.unimall.data.domain.*;
+import com.iotechn.unimall.data.dto.goods.GroupShopSkuDTO;
+import com.iotechn.unimall.data.dto.goods.GroupShopDTO;
+import com.iotechn.unimall.data.enums.GroupShopAutomaticRefundType;
+import com.iotechn.unimall.data.enums.StatusType;
+import com.iotechn.unimall.data.mapper.*;
+import com.iotechn.unimall.data.model.Page;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Comparator;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+@EnableScheduling
+public class AdminGroupShopGoodsServiceImpl implements AdminGroupShopGoodsService {
+
+    @Autowired
+    private SkuMapper skuMapper;
+
+    @Autowired
+    private SpuMapper spuMapper;
+
+    @Autowired
+    private GroupShopMapper groupShopMapper;
+
+    @Autowired
+    private GroupShopSkuMapper groupShopSkuMapper;
+
+    @Autowired
+    private CacheComponent cacheComponent;
+
+    private static final String GROUP_SHOP_CACHE = "CA_GROUP_SHOP";
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public String addGroupShopSpu(Long adminId, Long spuId, Long gmtStart, Long gmtEnd, Integer minimumNumber, Integer automaticRefund, List groupShopSkuList) throws ServiceException {
+        // 1.转化为对应的GroupShopSkuDo类的链表
+        List<GroupShopSkuDO> groupShopSkuDOList = (List<GroupShopSkuDO>) groupShopSkuList.stream().map(t -> {
+            GroupShopSkuDO groupShopSkuDO = JSONObject.toJavaObject((JSON) t, GroupShopSkuDO.class);
+            return groupShopSkuDO;
+        }).sorted(Comparator.comparingInt(o -> ((GroupShopSkuDO) o).getSkuGroupShopPrice())).collect(Collectors.toList());
+
+        if (gmtStart.compareTo(gmtEnd) >= 0) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_START_MUST_LESS_THAN_END);
+        }
+
+        // 2.检验数据库中是否存在spuId对应的sku
+        SpuDO spuDO = spuMapper.selectById(spuId);
+        List<SkuDO> skuDOList = skuMapper.selectList((new EntityWrapper<SkuDO>().eq("spu_id", spuId)));
+        if (spuDO == null || CollectionUtils.isEmpty(skuDOList)) {
+            throw new AdminServiceException(ExceptionDefinition.SPU_NO_EXITS_OR_ONLY_SPU);
+        }
+        // 2.1 检验groupShop表中是否存在此商品
+        Integer count = groupShopMapper.selectCount((new EntityWrapper<GroupShopDO>().eq("spu_id", spuId)));
+        if (count > 0) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_ALREADY_EXIT);
+        }
+
+        Date timeStart = new Date(gmtStart);
+        Date timeEnd = new Date(gmtEnd);
+        Date now = new Date();
+        GroupShopDO groupShopDO = new GroupShopDO();
+
+        groupShopDO.setAlreadyBuyNumber(0);
+        groupShopDO.setMinimumNumber(minimumNumber);
+        groupShopDO.setGmtStart(timeStart);
+        groupShopDO.setGmtEnd(timeEnd);
+        groupShopDO.setAutomaticRefund(automaticRefund.compareTo(0) > 0 ? GroupShopAutomaticRefundType.YES.getCode() : GroupShopAutomaticRefundType.NO.getCode());
+        groupShopDO.setSpuId(spuId);
+        groupShopDO.setMinPrice(groupShopSkuDOList.get(0).getSkuGroupShopPrice());
+        groupShopDO.setMaxPrice(groupShopSkuDOList.get(groupShopSkuDOList.size() - 1).getSkuGroupShopPrice());
+        groupShopDO.setGmtCreate(now);
+        groupShopDO.setGmtUpdate(now);
+        // 3.设置是否在活动时间的状态
+        setGroupShopStatus(now, gmtStart, gmtEnd, spuDO, groupShopDO);
+        if (groupShopMapper.insert(groupShopDO) <= 0) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_SPU_ADD_SQL_QUERY_ERROR);
+        }
+
+        if (skuDOList.size() != groupShopSkuDOList.size()) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_SKU_NUMBER_ERROR);
+        }
+        // 4.插入groupShopSkuList
+        this.insertGroupShopSkuList(groupShopSkuDOList, skuDOList, groupShopDO.getId(), now);
+        cacheComponent.delPrefixKey(GROUP_SHOP_CACHE);
+        return "ok";
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public String deleteGroupShopSpu(Long adminId, Long id) throws ServiceException {
+
+        GroupShopDO groupShopDO = groupShopMapper.selectById(id);
+        if (groupShopDO == null) {
+            throw new AdminServiceException(ExceptionDefinition.SPU_NO_EXITS_OR_ONLY_SPU);
+        }
+
+        if (groupShopDO.getStatus() > 0) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_ALREAD_ATCIVE);
+        }
+
+        if (groupShopMapper.deleteById(id) <= 0) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_SPU_DELETE_SQL_QUERY_ERROR);
+        }
+        if (groupShopSkuMapper.delete((new EntityWrapper<GroupShopSkuDO>().eq("group_shop_id", id))) <= 0) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_SKU_DELETE_SQL_QUERY_ERROR);
+        }
+
+        cacheComponent.delPrefixKey(GROUP_SHOP_CACHE);
+        return "ok";
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public GroupShopDTO editGroupShopSpu(Long adminId, Long id, Long spuId, Long gmtStart, Long gmtEnd, Integer minimumNumber, Integer automaticRefund, List groupShopSkuList) throws ServiceException {
+        // 1.转化为对应的GroupShopSkuDo类的链表
+        List<GroupShopSkuDO> groupShopSkuDOList = (List<GroupShopSkuDO>) groupShopSkuList.stream().map(t -> {
+            GroupShopSkuDO groupShopSkuDO = JSONObject.toJavaObject((JSON) t, GroupShopSkuDO.class);
+            return groupShopSkuDO;
+        }).sorted(Comparator.comparingInt(o -> ((GroupShopSkuDO) o).getSkuGroupShopPrice())).collect(Collectors.toList());
+
+        if (gmtStart.compareTo(gmtEnd) >= 0) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_START_MUST_LESS_THAN_END);
+        }
+
+        SpuDO spuDO = spuMapper.selectById(spuId);
+        List<SkuDO> skuDOList = skuMapper.selectList((new EntityWrapper<SkuDO>().eq("spu_id", spuId)));
+        if (spuDO == null || CollectionUtils.isEmpty(skuDOList)) {
+            throw new AdminServiceException(ExceptionDefinition.SPU_NO_EXITS_OR_ONLY_SPU);
+        }
+
+        GroupShopDO groupShopDO = groupShopMapper.selectById(id);
+        if (groupShopDO == null) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_SPU_NO_EXITS);
+        }
+
+        if (groupShopDO.getStatus() > 0) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_ALREAD_ATCIVE);
+        }
+
+        Date timeStart = new Date(gmtStart);
+        Date timeEnd = new Date(gmtEnd);
+        Date now = new Date();
+
+        groupShopDO.setMinimumNumber(minimumNumber);
+        groupShopDO.setGmtStart(timeStart);
+        groupShopDO.setGmtEnd(timeEnd);
+        groupShopDO.setAutomaticRefund(automaticRefund.compareTo(0) > 0 ? StatusType.ACTIVE.getCode() : StatusType.LOCK.getCode());
+        groupShopDO.setSpuId(spuId);
+        groupShopDO.setMinPrice(groupShopSkuDOList.get(0).getSkuGroupShopPrice());
+        groupShopDO.setMinPrice(groupShopSkuDOList.get(groupShopSkuDOList.size() - 1).getSkuGroupShopPrice());
+        groupShopDO.setGmtUpdate(now);
+        this.setGroupShopStatus(now, gmtStart, gmtEnd, spuDO, groupShopDO);
+        if (groupShopMapper.updateById(groupShopDO) <= 0) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_SPU_UPDATE_SQL_QUERY_ERROR);
+        }
+
+        if (groupShopSkuMapper.delete((new EntityWrapper<GroupShopSkuDO>().eq("group_shop_id", id))) <= 0) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_SKU_DELETE_SQL_QUERY_ERROR);
+        }
+
+        if (skuDOList.size() != groupShopSkuDOList.size()) {
+            throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_SKU_NUMBER_ERROR);
+        }
+        // 4.插入groupShopSkuList
+        this.insertGroupShopSkuList(groupShopSkuDOList, skuDOList, groupShopDO.getId(), now);
+        cacheComponent.delPrefixKey(GROUP_SHOP_CACHE);
+        return new GroupShopDTO();
+    }
+
+    @Override
+    public Page<GroupShopDTO> queryGroupShop(Long adminId, Long id, String spuName, Integer status, Integer page, Integer limit) throws ServiceException {
+        EntityWrapper<GroupShopDO> groupShopSpuDOEntityWrapper = new EntityWrapper<GroupShopDO>();
+        if (id != null) {
+            groupShopSpuDOEntityWrapper.eq("id", id);
+        }
+
+        if (status != null) {
+            groupShopSpuDOEntityWrapper.eq("status", status);
+        }
+
+        if (spuName != null) {
+            EntityWrapper<SpuDO> spuDOEntityWrapper = new EntityWrapper<>();
+            spuDOEntityWrapper.setSqlSelect("id");
+            spuDOEntityWrapper.like("title", spuName);
+            List<Object> objectList = spuMapper.selectObjs(spuDOEntityWrapper);
+            List<String> collect = objectList.stream().map(s -> String.valueOf(s)).collect(Collectors.toList());
+            groupShopSpuDOEntityWrapper.in("spu_id", collect);
+        }
+
+        List<GroupShopDO> groupShopDOList = groupShopMapper.selectPage(new RowBounds((page - 1) * limit, limit), groupShopSpuDOEntityWrapper);
+        Integer count = groupShopMapper.selectCount(groupShopSpuDOEntityWrapper);
+        List<GroupShopDTO> groupShopDTOList = new LinkedList<>();
+
+        for (GroupShopDO groupShopDO : groupShopDOList) {
+            GroupShopDTO groupShopDTO = new GroupShopDTO();
+            SpuDO spuDO = spuMapper.selectById(groupShopDO.getSpuId());
+            BeanUtils.copyProperties(spuDO, groupShopDTO);
+            BeanUtils.copyProperties(groupShopDO, groupShopDTO);
+            /**
+             * 添加groupShopSkuDTOList
+             */
+            List<SkuDO> skuDOList = skuMapper.selectList((new EntityWrapper<SkuDO>().eq("spu_id", spuDO.getId())));
+            List<GroupShopSkuDO> groupShopSkuDOList = groupShopSkuMapper.selectList((new EntityWrapper<GroupShopSkuDO>()).eq("group_shop_id", groupShopDO.getId()));
+            List<GroupShopSkuDTO> groupShopSkuDTOList = groupShopSkuDOList.stream().map(s -> {
+                GroupShopSkuDTO groupShopSkuDTO = new GroupShopSkuDTO();
+                BeanUtils.copyProperties(s, groupShopSkuDTO);
+                return groupShopSkuDTO;
+            }).collect(Collectors.toList());
+
+            for (SkuDO skuDO : skuDOList) {
+                for (GroupShopSkuDTO groupShopSkuDTO : groupShopSkuDTOList) {
+                    if (groupShopSkuDTO.getSkuId().equals(skuDO.getId())) {
+                        BeanUtils.copyProperties(skuDO, groupShopSkuDTO);
+                        break;
+                    }
+                }
+            }
+            groupShopDTO.setGroupShopSkuDTOList(groupShopSkuDTOList);
+            groupShopDTOList.add(groupShopDTO);
+        }
+        return new Page<GroupShopDTO>(groupShopDTOList, page, limit, count);
+    }
+
+    private void setGroupShopStatus(Date now, Long gmtStart, Long gmtEnd, SpuDO spuDO, GroupShopDO groupShopDO) {
+        if (now.getTime() >= gmtStart.longValue() && now.getTime() < gmtEnd.longValue()) {
+            //3.1 商品本身是否处于下架状态
+            if (spuDO.getStatus().equals(StatusType.ACTIVE.getCode())) {
+                groupShopDO.setStatus(StatusType.ACTIVE.getCode());
+            } else {
+                groupShopDO.setStatus(StatusType.LOCK.getCode());
+            }
+        } else {
+            groupShopDO.setStatus(StatusType.LOCK.getCode());
+        }
+    }
+
+    private void insertGroupShopSkuList(List<GroupShopSkuDO> groupShopSkuDOList, List<SkuDO> skuDOList, Long groupShopId, Date now) throws ServiceException {
+        for (GroupShopSkuDO groupShopSkuDO : groupShopSkuDOList) {
+            boolean judge = false;
+            for (SkuDO sku : skuDOList) {
+                if (sku.getId().equals(groupShopSkuDO.getSkuId())) {
+                    judge = true;
+                    break;
+                }
+            }
+
+            if (!judge) {
+                throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_SKU_ID_ERROR);
+            }
+
+            if (groupShopSkuDO.getSkuGroupShopPrice() == null || groupShopSkuDO.getSkuGroupShopPrice().equals(0)) {
+                throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_SKU_PRICE_ERROR);
+            }
+
+            groupShopSkuDO.setGroupShopId(groupShopId);
+            groupShopSkuDO.setGmtCreate(now);
+            groupShopSkuDO.setGmtUpdate(now);
+            if (groupShopSkuMapper.insert(groupShopSkuDO) <= 0) {
+                throw new AdminServiceException(ExceptionDefinition.GROUP_SHOP_SKU_ADD_SQL_QUERY_ERROR);
+            }
+        }
+    }
+
+}

+ 40 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/log/loginLog/SysLogininforService.java

@@ -0,0 +1,40 @@
+package com.iotechn.unimall.admin.api.log.loginLog;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.log.SysLogininfor;
+import com.iotechn.unimall.data.model.Page;
+
+@HttpOpenApi(group = "admin.log.logininfor", description = "登陆日志管理")
+public interface SysLogininforService {
+	@HttpMethod(description = "登陆日志列表", permission = "admin:log:logininfor:list", permissionParentName = "日志管理", permissionName = "登陆日志管理")
+	public Page<SysLogininfor> list(
+			@HttpParam(name = "ipaddr", type = HttpParamType.COMMON, description = "登录地址") String ipaddr,
+			@HttpParam(name = "userName", type = HttpParamType.COMMON, description = "用户名称") String userName,
+			@HttpParam(name = "status", type = HttpParamType.COMMON, description = "状态") String status,
+			@HttpParam(name = "beginTime", type = HttpParamType.COMMON, description = "登陆开始时间") String beginTime,
+			@HttpParam(name = "endTime", type = HttpParamType.COMMON, description = "登陆结束时间") String endTime,
+			@HttpParam(name = "pageNum", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+			@HttpParam(name = "pageSize", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+			throws ServiceException;
+	@HttpMethod(description = "删除登陆日志", permission = "admin:log:logininfor:delete", permissionParentName = "日志管理", permissionName = "登陆日志管理")
+	public Boolean delete(
+			@NotNull @HttpParam(name = "infoIds", type = HttpParamType.COMMON, description = "日志Id") String infoIds)
+			throws ServiceException;
+	
+	@HttpMethod(description = "清空登陆日志", permission = "admin:log:logininfor:clean", permissionParentName = "日志管理", permissionName = "登陆日志管理")
+	public Boolean clean()throws ServiceException;
+	
+	@HttpMethod(description = "导出日志列表", permission = "admin:log:logininfor:export", permissionParentName = "日志管理", permissionName = "登陆日志管理")
+	public String export(
+			@HttpParam(name = "ipaddr", type = HttpParamType.COMMON, description = "登录地址") String ipaddr,
+			@HttpParam(name = "userName", type = HttpParamType.COMMON, description = "用户名称") String userName,
+			@HttpParam(name = "status", type = HttpParamType.COMMON, description = "状态") String status,
+			@HttpParam(name = "beginTime", type = HttpParamType.COMMON, description = "登陆开始时间") String beginTime,
+			@HttpParam(name = "endTime", type = HttpParamType.COMMON, description = "登陆结束时间") String endTime)
+			throws ServiceException;
+}

+ 87 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/log/loginLog/SysLogininforServiceImpl.java

@@ -0,0 +1,87 @@
+package com.iotechn.unimall.admin.api.log.loginLog;
+
+import java.util.List;
+
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.log.SysLogininfor;
+import com.iotechn.unimall.data.mapper.log.SysLogininforMapper;
+import com.iotechn.unimall.data.model.Page;
+import com.iotechn.unimall.data.util.ExcelUtil;
+
+/**
+ * 
+ * @author dyl
+ *
+ */
+@Service
+public class SysLogininforServiceImpl implements SysLogininforService {
+
+	@Autowired
+	private SysLogininforMapper logininforMapper;
+
+	@Override
+	public Page<SysLogininfor> list(String ipaddr, String userName, String status, String beginTime, String endTime,
+			Integer page, Integer limit) throws ServiceException {
+		Wrapper<SysLogininfor> wrapper = new EntityWrapper<SysLogininfor>();
+		if (!StringUtils.isEmpty(ipaddr)) {
+			wrapper.like("ipaddr", ipaddr);
+		}
+		if (!StringUtils.isEmpty(userName)) {
+			wrapper.like("user_name", userName);
+		}
+		if (!StringUtils.isEmpty(status)) {
+			wrapper.eq("status", status);
+		}
+		if (!StringUtils.isEmpty(beginTime) && !StringUtils.isEmpty(endTime)) {
+			wrapper.between("login_time", beginTime, endTime);
+		}
+		wrapper.orderBy("info_id", false);
+		List<SysLogininfor> SysOperLogS = logininforMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+		Integer count = logininforMapper.selectCount(wrapper);
+		return new Page<SysLogininfor>(SysOperLogS, page, limit, count);
+	}
+
+	@Override
+	public Boolean delete(String infoIds) throws ServiceException {
+		String[] ids = infoIds.split(",");
+		Wrapper<SysLogininfor> wrapper = new EntityWrapper<SysLogininfor>();
+		wrapper.in("info_id", ids);
+		return logininforMapper.delete(wrapper) > 0;
+	}
+
+	@Override
+	public Boolean clean() throws ServiceException {
+		Wrapper<SysLogininfor> wrapper = new EntityWrapper<SysLogininfor>();
+		wrapper.eq("1", 1);
+		return logininforMapper.delete(wrapper) > 0;
+	}
+
+	@Override
+	public String export(String ipaddr, String userName, String status, String beginTime, String endTime)
+			throws ServiceException {
+		Wrapper<SysLogininfor> wrapper = new EntityWrapper<SysLogininfor>();
+		if (!StringUtils.isEmpty(ipaddr)) {
+			wrapper.like("ipaddr", ipaddr);
+		}
+		if (!StringUtils.isEmpty(userName)) {
+			wrapper.like("user_name", userName);
+		}
+		if (!StringUtils.isEmpty(status)) {
+			wrapper.eq("status", status);
+		}
+		if (!StringUtils.isEmpty(beginTime) && !StringUtils.isEmpty(endTime)) {
+			wrapper.between("login_time", beginTime, endTime);
+		}
+		List<SysLogininfor> list = logininforMapper.selectList(wrapper);
+		ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
+		return util.exportExcel(list, "操作日志");
+	}
+
+}

+ 40 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/log/operLog/OperLogService.java

@@ -0,0 +1,40 @@
+package com.iotechn.unimall.admin.api.log.operLog;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.log.SysOperLog;
+import com.iotechn.unimall.data.model.Page;
+
+@HttpOpenApi(group = "admin.log.operlog", description = "操作日志管理")
+public interface OperLogService {
+	@HttpMethod(description = "操作日志列表", permission = "admin:log:operlog:list", permissionParentName = "日志管理", permissionName = "操作日志管理")
+	public Page<SysOperLog> list(
+			@HttpParam(name = "title", type = HttpParamType.COMMON, description = "系统模块") String title,
+			@HttpParam(name = "operName", type = HttpParamType.COMMON, description = "操作人员") String operName,
+			@HttpParam(name = "businessType", type = HttpParamType.COMMON, description = "操作类型") String businessType,
+			@HttpParam(name = "beginTime", type = HttpParamType.COMMON, description = "操作开始时间") String beginTime,
+			@HttpParam(name = "endTime", type = HttpParamType.COMMON, description = "操作结束时间") String endTime,
+			@HttpParam(name = "pageNum", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+			@HttpParam(name = "pageSize", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+			throws ServiceException;
+	@HttpMethod(description = "删除操作日志", permission = "admin:log:operlog:delete", permissionParentName = "日志管理", permissionName = "操作日志管理")
+	public Boolean delete(
+			@NotNull @HttpParam(name = "operIds", type = HttpParamType.COMMON, description = "日志Id") String operIds)
+			throws ServiceException;
+	
+	@HttpMethod(description = "清空操作日志", permission = "admin:log:operlog:clean", permissionParentName = "日志管理", permissionName = "操作日志管理")
+	public Boolean clean()throws ServiceException;
+	
+	@HttpMethod(description = "导出日志列表", permission = "admin:log:operlog:export", permissionParentName = "日志管理", permissionName = "操作日志管理")
+	public String export(
+			@HttpParam(name = "title", type = HttpParamType.COMMON, description = "系统模块") String title,
+			@HttpParam(name = "operName", type = HttpParamType.COMMON, description = "操作人员") String operName,
+			@HttpParam(name = "businessType", type = HttpParamType.COMMON, description = "操作类型") String businessType,
+			@HttpParam(name = "beginTime", type = HttpParamType.COMMON, description = "操作开始时间") String beginTime,
+			@HttpParam(name = "endTime", type = HttpParamType.COMMON, description = "操作结束时间") String endTime)
+			throws ServiceException;
+}

+ 87 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/log/operLog/OperLogServiceImpl.java

@@ -0,0 +1,87 @@
+package com.iotechn.unimall.admin.api.log.operLog;
+
+import java.util.List;
+
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.log.SysOperLog;
+import com.iotechn.unimall.data.mapper.log.SysOperLogMapper;
+import com.iotechn.unimall.data.model.Page;
+import com.iotechn.unimall.data.util.ExcelUtil;
+
+/**
+ * 
+ * @author dyl
+ *
+ */
+@Service
+public class OperLogServiceImpl implements OperLogService {
+
+	@Autowired
+	private SysOperLogMapper operLogMapper;
+
+	@Override
+	public Page<SysOperLog> list(String title, String operName, String businessType, String beginTime, String endTime,
+			Integer page, Integer limit) throws ServiceException {
+		Wrapper<SysOperLog> wrapper = new EntityWrapper<SysOperLog>();
+		if (!StringUtils.isEmpty(title)) {
+			wrapper.like("title", title);
+		}
+		if (!StringUtils.isEmpty(operName)) {
+			wrapper.like("oper_name", operName);
+		}
+		if (!StringUtils.isEmpty(businessType)) {
+			wrapper.eq("business_type", businessType);
+		}
+		if (!StringUtils.isEmpty(beginTime) && !StringUtils.isEmpty(endTime)) {
+			wrapper.between("oper_time", beginTime, endTime);
+		}
+		wrapper.orderBy("oper_id", false);
+		List<SysOperLog> SysOperLogS = operLogMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+		Integer count = operLogMapper.selectCount(wrapper);
+		return new Page<SysOperLog>(SysOperLogS, page, limit, count);
+	}
+
+	@Override
+	public Boolean delete(String operIds) throws ServiceException {
+		String[] ids = operIds.split(",");
+		Wrapper<SysOperLog> wrapper = new EntityWrapper<SysOperLog>();
+		wrapper.in("oper_id", ids);
+		return operLogMapper.delete(wrapper) > 0;
+	}
+
+	@Override
+	public Boolean clean() throws ServiceException {
+		Wrapper<SysOperLog> wrapper = new EntityWrapper<SysOperLog>();
+		wrapper.eq("1", 1);
+		return operLogMapper.delete(wrapper) > 0;
+	}
+
+	@Override
+	public String export(String title, String operName, String businessType, String beginTime, String endTime)
+			throws ServiceException {
+		Wrapper<SysOperLog> wrapper = new EntityWrapper<SysOperLog>();
+		if (!StringUtils.isEmpty(title)) {
+			wrapper.like("title", title);
+		}
+		if (!StringUtils.isEmpty(operName)) {
+			wrapper.like("oper_name", operName);
+		}
+		if (!StringUtils.isEmpty(businessType)) {
+			wrapper.eq("business_type", businessType);
+		}
+		if (!StringUtils.isEmpty(beginTime) && !StringUtils.isEmpty(endTime)) {
+			wrapper.between("oper_time", beginTime, endTime);
+		}
+		List<SysOperLog> list = operLogMapper.selectList(wrapper);
+		ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
+		return util.exportExcel(list, "操作日志");
+	}
+
+}

+ 21 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/monitor/online/UserOnlineService.java

@@ -0,0 +1,21 @@
+package com.iotechn.unimall.admin.api.monitor.online;
+
+import java.util.List;
+
+import com.alibaba.fastjson.JSONObject;
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.exception.ServiceException;
+
+@HttpOpenApi(group = "admin.monitor.online", description = "在线用户管理")
+public interface UserOnlineService {
+	@HttpMethod(description = "在线用户列表", permission = "admin:monitor:online:list", permissionParentName = "系统管理", permissionName = "在线用户管理")
+	public List<JSONObject> list() throws ServiceException;
+	
+	@HttpMethod(description = "强退用户", permission = "admin:monitor:online:forceLogout", permissionParentName = "系统管理", permissionName = "在线用户管理")
+	public Boolean forceLogout(
+			@HttpParam(name = "tokenId", type = HttpParamType.COMMON, description = "用户token") String tokenId)
+			throws ServiceException;
+}

+ 45 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/monitor/online/UserOnlineServiceImpl.java

@@ -0,0 +1,45 @@
+package com.iotechn.unimall.admin.api.monitor.online;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.iotechn.unimall.core.Const;
+import com.iotechn.unimall.core.exception.ServiceException;
+/**
+ * 
+ * @author dyl
+ *
+ */
+@Service
+public class UserOnlineServiceImpl implements UserOnlineService {
+	@Autowired
+	private StringRedisTemplate userRedisTemplate;
+	
+	@Override
+	public List<JSONObject> list() throws ServiceException {
+		List<JSONObject> loginList=new ArrayList<JSONObject>();
+		Set<String> keys = userRedisTemplate.keys(Const.ADMIN_REDIS_PREFIX+"*");
+		Iterator<String> it1 = keys.iterator();
+		while (it1.hasNext()) {
+			String tokenId=it1.next();
+			JSONObject json = JSONObject.parseObject(userRedisTemplate.opsForValue().get(tokenId));
+			json.put("tokenId", tokenId.split("_")[2]);
+			json.put("expireTime", userRedisTemplate.getExpire(tokenId));
+			loginList.add(json);
+		}
+		return loginList;
+	}
+
+	@Override
+	public Boolean forceLogout(String tokenId) throws ServiceException {
+		return userRedisTemplate.delete(Const.ADMIN_REDIS_PREFIX  + tokenId);
+	}
+
+}

+ 11 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/monitor/server/ServerService.java

@@ -0,0 +1,11 @@
+package com.iotechn.unimall.admin.api.monitor.server;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.data.domain.monitor.Server;
+
+@HttpOpenApi(group = "admin.monitor.server", description = "服务监控数据")
+public interface ServerService {
+	@HttpMethod(description = "获取服务监控数据", permission = "admin:monitor:server:getInfo", permissionParentName = "系统管理", permissionName = "服务监控数据")
+	public Server getInfo()throws Exception;
+}

+ 22 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/monitor/server/ServerServiceImpl.java

@@ -0,0 +1,22 @@
+package com.iotechn.unimall.admin.api.monitor.server;
+
+import org.springframework.stereotype.Service;
+
+import com.iotechn.unimall.data.domain.monitor.Server;
+
+/**
+ * 
+ * @author dyl
+ *
+ */
+@Service
+public class ServerServiceImpl implements ServerService {
+
+	@Override
+	public Server getInfo() throws Exception {
+		Server server = new Server();
+		server.copyTo();
+		return server;
+	}
+
+}

+ 57 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/order/AdminOrderService.java

@@ -0,0 +1,57 @@
+package com.iotechn.unimall.admin.api.order;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.annotation.param.Range;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.OrderDO;
+import com.iotechn.unimall.data.dto.order.OrderDTO;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.List;
+
+/**
+ * Created by rize on 2019/7/10.
+ */
+@HttpOpenApi(group = "admin.order", description = "管理员订单服务")
+public interface AdminOrderService {
+
+    @HttpMethod(description = "列表", permission = "operation:order:list", permissionParentName = "运营管理", permissionName = "订单管理")
+    public Page<OrderDO> list(
+            @HttpParam(name = "page", type = HttpParamType.COMMON, description = "订单页码", valueDef = "1") Integer page,
+            @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit,
+            @HttpParam(name = "status", type = HttpParamType.COMMON, description = "订单状态") Integer status,
+            @HttpParam(name = "orderNo", type = HttpParamType.COMMON, description = "订单号") String orderNo,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "退款", permission = "operation:order:refund", permissionParentName = "运营管理", permissionName = "订单管理")
+    public String refund(
+            @NotNull @HttpParam(name = "orderNo", type = HttpParamType.COMMON, description = "订单号") String orderNo,
+            @NotNull @HttpParam(name = "type", type = HttpParamType.COMMON, description = "0.拒绝退款 1.同意退款") Integer type,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "发货", permission = "operation:order:ship", permissionParentName = "运营管理", permissionName = "订单管理")
+    public String ship(
+            @NotNull @HttpParam(name = "orderNo", type = HttpParamType.COMMON, description = "订单号") String orderNo,
+            @NotNull @HttpParam(name = "shipCode", type = HttpParamType.COMMON, description = "承运商Code") String shipCode,
+            @HttpParam(name = "shipNo", type = HttpParamType.COMMON, description = "运单号") String shipNo,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId) throws ServiceException;
+
+    @HttpMethod(description = "详情", permission = "operation:order:detail", permissionParentName = "运营管理", permissionName = "订单管理")
+    public OrderDTO detail(
+            @NotNull @HttpParam(name = "orderId", type = HttpParamType.COMMON, description = "订单Id") Long orderNo,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "根据传入时间和订单状态查询订单信息")
+    public List<OrderDTO> queryToExcel(
+            @HttpParam(name = "gmtStart", type = HttpParamType.COMMON, description = "查询开始时间") Long gmtStart,
+            @HttpParam(name = "gmtEnd", type = HttpParamType.COMMON, description = "查询结束时间") Long gmtEnd,
+            @HttpParam(name = "status", type = HttpParamType.COMMON, description = "订单状态", valueDef = "20") Integer status,
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员Id") Long adminId) throws ServiceException;
+}

+ 196 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/order/AdminOrderServiceImpl.java

@@ -0,0 +1,196 @@
+package com.iotechn.unimall.admin.api.order;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
+import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.component.LockComponent;
+import com.iotechn.unimall.data.domain.OrderDO;
+import com.iotechn.unimall.data.domain.OrderSkuDO;
+import com.iotechn.unimall.data.domain.UserDO;
+import com.iotechn.unimall.data.dto.order.OrderDTO;
+import com.iotechn.unimall.data.enums.OrderStatusType;
+import com.iotechn.unimall.data.enums.UserLoginType;
+import com.iotechn.unimall.data.mapper.OrderMapper;
+import com.iotechn.unimall.data.mapper.OrderSkuMapper;
+import com.iotechn.unimall.data.mapper.UserMapper;
+import com.iotechn.unimall.data.model.Page;
+import org.apache.ibatis.session.RowBounds;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by rize on 2019/7/10.
+ */
+@Service
+public class AdminOrderServiceImpl implements AdminOrderService {
+
+    private static final Logger logger = LoggerFactory.getLogger(AdminOrderServiceImpl.class);
+
+
+
+
+    @Autowired
+    private OrderMapper orderMapper;
+
+    @Autowired
+    private OrderSkuMapper orderSkuMapper;
+
+    @Autowired
+    private LockComponent lockComponent;
+
+    @Autowired
+    private UserMapper userMapper;
+
+    @Value("${com.iotechn.unimall.wx.mini.app-id}")
+    private String wxMiNiAppid;
+
+    @Value("${com.iotechn.unimall.wx.app.app-id}")
+    private String wxAppAppid;
+
+    @Override
+    public Page<OrderDO> list(Integer pageNo, Integer pageSize, Integer status, String orderNo, Long adminId) throws ServiceException {
+        Wrapper<OrderDO> wrapper = new EntityWrapper<OrderDO>();
+        wrapper.orderBy("id", false);
+        if (!StringUtils.isEmpty(orderNo)) {
+            wrapper.eq("order_no", orderNo);
+        }
+        if (status != null) {
+            wrapper.eq("status", status);
+        }
+        List<OrderDO> orderDOS = orderMapper.selectPage(new RowBounds((pageNo - 1) * pageSize, pageSize), wrapper);
+        Integer count = orderMapper.selectCount(wrapper);
+        return new Page<OrderDO>(orderDOS, pageNo, pageSize, count);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public String refund(String orderNo, Integer type, Long adminId) throws ServiceException {
+        return null;
+//        if (lockComponent.tryLock(OrderBizService.ORDER_REFUND_LOCK + orderNo, 30)) {
+//            try {
+//                //1.校验订单状态是否处于退款中
+//                OrderDO orderDO = orderBizService.checkOrderExist(orderNo, null);
+//                if (orderDO.getStatus() != OrderStatusType.REFUNDING.getCode()) {
+//                    throw new AdminServiceException(ExceptionDefinition.ORDER_STATUS_NOT_SUPPORT_REFUND);
+//                }
+//                //2.退款处理
+//                if (type == 0) {
+//                    //2.1 店主拒绝退款
+//                    OrderDO updateOrderDO = new OrderDO();
+//                    updateOrderDO.setStatus(OrderStatusType.WAIT_CONFIRM.getCode());
+//                    updateOrderDO.setGmtUpdate(new Date());
+//                    orderBizService.changeOrderStatus(orderNo, OrderStatusType.REFUNDING.getCode(), updateOrderDO);
+//                    return "ok";
+//                } else if (type == 1) {
+//                    //2.2 店主同意退款
+//                    //2.2.1 先流转状态
+//                    OrderDO updateOrderDO = new OrderDO();
+//                    updateOrderDO.setStatus(OrderStatusType.REFUNDED.getCode());
+//                    updateOrderDO.setGmtUpdate(new Date());
+//                    orderBizService.changeOrderStatus(orderNo, OrderStatusType.REFUNDING.getCode(), updateOrderDO);
+//                    Long userId = orderDO.getUserId();
+//                    UserDO userDO = userMapper.selectById(userId);
+//                    Integer loginType = userDO.getLoginType();
+//                    //2.2.2 向微信支付平台发送退款请求
+//                    WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
+//                    wxPayRefundRequest.setAppid(loginType == UserLoginType.MP_WEIXIN.getCode() ? wxMiNiAppid : wxAppAppid);
+//                    wxPayRefundRequest.setOutTradeNo(orderNo);
+//                    wxPayRefundRequest.setOutRefundNo("refund_" + orderNo);
+//                    wxPayRefundRequest.setTotalFee(orderDO.getPayPrice() - orderDO.getFreightPrice());
+//                    wxPayRefundRequest.setRefundFee(orderDO.getPayPrice() - orderDO.getFreightPrice());
+//                    WxPayRefundResult wxPayRefundResult = wxPayService.refund(wxPayRefundRequest);
+//                    if (!wxPayRefundResult.getReturnCode().equals("SUCCESS")) {
+//                        logger.warn("[微信退款] 失败 : " + wxPayRefundResult.getReturnMsg());
+//                        throw new AdminServiceException(wxPayRefundResult.getReturnMsg(),
+//                                ExceptionDefinition.THIRD_PART_SERVICE_EXCEPTION.getCode());
+//                    }
+//                    if (!wxPayRefundResult.getResultCode().equals("SUCCESS")) {
+//                        logger.warn("[微信退款] 失败 : " + wxPayRefundResult.getReturnMsg());
+//                        throw new AdminServiceException(wxPayRefundResult.getReturnMsg(),
+//                                ExceptionDefinition.THIRD_PART_SERVICE_EXCEPTION.getCode());
+//                    }
+//                    return "ok";
+//                } else {
+//                    throw new AdminServiceException(ExceptionDefinition.PARAM_CHECK_FAILED);
+//                }
+//            } catch (ServiceException e) {
+//                throw e;
+//            } catch (Exception e) {
+//                logger.error("[微信退款] 异常", e);
+//                throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
+//            } finally {
+//                lockComponent.release(OrderBizService.ORDER_REFUND_LOCK + orderNo);
+//            }
+//        } else {
+//            throw new AdminServiceException(ExceptionDefinition.SYSTEM_BUSY);
+//        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public String ship(String orderNo, String shipCode, String shipNo, Long adminId) throws ServiceException {
+//        orderBizService.checkOrderExist(orderNo, null);
+//        OrderDO updateOrderDO = new OrderDO();
+//        Date now = new Date();
+//        updateOrderDO.setGmtUpdate(now);
+//        updateOrderDO.setGmtShip(now);
+//        updateOrderDO.setStatus(OrderStatusType.WAIT_CONFIRM.getCode());
+//        if (!"NONE".equals(shipCode)) {
+//            updateOrderDO.setShipCode(shipCode);
+//            updateOrderDO.setShipNo(shipNo);
+//        }
+//        //流转订单状态
+//        orderBizService.changeOrderStatus(orderNo, OrderStatusType.WAIT_STOCK.getCode(), updateOrderDO);
+        return "ok";
+    }
+
+    @Override
+    public OrderDTO detail(Long orderId, Long adminId) throws ServiceException {
+//        return orderBizService.getOrderDetail(orderId, null);
+        return null;
+    }
+
+    @Override
+    public List<OrderDTO> queryToExcel(Long gmtStart, Long gmtEnd, Integer status, Long adminId) throws ServiceException {
+        EntityWrapper wrapper = new EntityWrapper();
+        if(gmtStart != null && gmtEnd != null){
+            if(gmtStart > gmtStart){
+                throw new AdminServiceException(ExceptionDefinition.ORDER_EXCEL_PARAM_ERROR);
+            }
+            wrapper.between("gmt_create",new Date(gmtStart) ,new Date(gmtEnd));
+        }
+        if(status != null){
+            wrapper.eq("status", status);
+        }
+        List<OrderDO> orderDOS = orderMapper.selectList(wrapper);
+        if(orderDOS == null || orderDOS.size() == 0){
+            return null;
+        }
+        List<OrderDTO> orderDTOList = new ArrayList<>();
+        for (OrderDO temp: orderDOS ) {
+            OrderDTO orderDTO = new OrderDTO();
+            BeanUtils.copyProperties(temp, orderDTO);
+            orderDTOList.add(orderDTO);
+        }
+        for (OrderDTO orderDTO:orderDTOList) {
+                List<OrderSkuDO> orderSkuDOList =  orderSkuMapper.selectList(new EntityWrapper<OrderSkuDO>().eq("order_no",orderDTO.getOrderNo() ));
+                orderDTO.setSkuList(orderSkuDOList);
+        }
+        return orderDTOList;
+    }
+}

+ 54 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/recommend/AdminRecommendService.java

@@ -0,0 +1,54 @@
+package com.iotechn.unimall.admin.api.recommend;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.annotation.param.Range;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.RecommendDO;
+import com.iotechn.unimall.data.dto.RecommendDTO;
+import com.iotechn.unimall.data.model.Page;
+import org.apache.ibatis.annotations.Param;
+
+import java.rmi.ServerException;
+import java.util.List;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-08
+ * Time: 下午3:42
+ */
+
+@HttpOpenApi(group = "admin.recommend", description = "推荐商品")
+public interface AdminRecommendService {
+
+    @HttpMethod(description = "创建", permission = "promote:recommend:create", permissionParentName = "推广管理", permissionName = "推荐管理")
+    public Boolean addRecommend(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "spuId", type = HttpParamType.COMMON, description = "商品Id") Long spuId,
+            @NotNull @HttpParam(name = "recommendType", type = HttpParamType.COMMON, description = "推荐类型") Integer recommendType) throws ServiceException;
+
+    @HttpMethod(description = "删除", permission = "promote:recommend:delete", permissionParentName = "推广管理", permissionName = "推荐管理")
+    public Boolean deleteRecommend(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "推荐id") Long id,
+            @NotNull @HttpParam(name = "recommendType", type = HttpParamType.COMMON, description = "推荐类型") Integer recommendType) throws ServiceException;
+
+    @HttpMethod(description = "查询", permission = "promote:recommend:query", permissionParentName = "推广管理", permissionName = "推荐管理")
+    public Page<RecommendDTO> queryRecommendByType(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @HttpParam(name = "recommendType", type = HttpParamType.COMMON, description = "推荐类型") Integer recommendType,
+            @Range(min = 1) @HttpParam(name = "pageNo", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer pageNo,
+            @Range(min = 1) @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页面长度", valueDef = "10") Integer pageSize) throws ServiceException;
+
+    @HttpMethod(description = "查询", permission = "promote:recommend:query", permissionParentName = "推广管理", permissionName = "推荐管理")
+    public Page<RecommendDTO> queryAllRecommend(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @Range(min = 1) @HttpParam(name = "pageNo", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer pageNo,
+            @Range(min = 1) @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页面长度", valueDef = "10") Integer pageSize) throws ServiceException;
+
+}

+ 94 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/recommend/AdminRecommendServiceImpl.java

@@ -0,0 +1,94 @@
+package com.iotechn.unimall.admin.api.recommend;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.component.CacheComponent;
+import com.iotechn.unimall.data.domain.RecommendDO;
+import com.iotechn.unimall.data.domain.SpuDO;
+import com.iotechn.unimall.data.dto.RecommendDTO;
+import com.iotechn.unimall.data.mapper.RecommendMapper;
+import com.iotechn.unimall.data.mapper.SpuMapper;
+import com.iotechn.unimall.data.model.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-08
+ * Time: 下午5:47
+ */
+@Service
+public class AdminRecommendServiceImpl implements AdminRecommendService {
+
+    @Autowired
+    private CacheComponent cacheComponent;
+    @Autowired
+    private RecommendMapper recommendMapper;
+    @Autowired
+    private SpuMapper spuMapper;
+
+    private final static String RECOMMEND_NAME = "RECOMMEND_TYPE_";
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean addRecommend(Long adminId, Long spuId, Integer recommendType) throws ServiceException {
+
+        if (!(spuMapper.selectCount(new EntityWrapper<SpuDO>().eq("id", spuId)) > 0)) {
+            throw new AdminServiceException(ExceptionDefinition.RECOMMEND_SPU_NO_HAS);
+        }
+
+        if (recommendMapper.selectCount(new EntityWrapper<RecommendDO>()
+                .eq("spu_id", spuId)
+                .eq("recommend_type", recommendType)) > 0) {
+            throw new AdminServiceException(ExceptionDefinition.RECOMMEND_ALREADY_HAS);
+        }
+        RecommendDO recommendDO = new RecommendDO(spuId, recommendType);
+        Date now = new Date();
+        recommendDO.setGmtCreate(now);
+        recommendDO.setGmtUpdate(now);
+        if (!(recommendMapper.insert(recommendDO) > 0)) {
+            throw new AdminServiceException(ExceptionDefinition.RECOMMEND_SQL_ADD_FAILED);
+        }
+        cacheComponent.delPrefixKey(RECOMMEND_NAME+recommendType);
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean deleteRecommend(Long adminId, Long id, Integer recommendType) throws ServiceException {
+
+        Integer judgeSQL = recommendMapper.delete(new EntityWrapper<RecommendDO>()
+                .eq("id", id)
+                .eq("recommend_type",recommendType));
+
+        if(judgeSQL > 0){
+            cacheComponent.delPrefixKey(RECOMMEND_NAME + recommendType);
+            return true;
+        }
+
+        throw new AdminServiceException(ExceptionDefinition.RECOMMEND_SQL_DELETE_FAILED);
+    }
+
+    @Override
+    public Page<RecommendDTO> queryRecommendByType(Long adminId, Integer recommendType, Integer pageNo, Integer pageSize) throws ServiceException {
+
+
+        Integer count = recommendMapper.selectCount(new EntityWrapper<RecommendDO>().eq("recommend_type",recommendType));
+        List<RecommendDTO> recommendDTOList = recommendMapper.getRecommendByType(recommendType,(pageNo-1)*pageSize,pageSize);
+        Page<RecommendDTO> page = new Page<>(recommendDTOList,pageNo,pageSize,count);
+        return page;
+    }
+
+    @Override
+    public Page<RecommendDTO> queryAllRecommend(Long adminId, Integer pageNo, Integer pageSize) throws ServiceException {
+        return null;
+    }
+}

+ 65 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/role/RoleService.java

@@ -0,0 +1,65 @@
+package com.iotechn.unimall.admin.api.role;
+
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.RoleDO;
+import com.iotechn.unimall.data.dto.RoleSetPermissionDTO;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by rize on 2019/4/11.
+ */
+@HttpOpenApi(group = "admin.role", description = "角色服务")
+public interface RoleService {
+
+    @HttpMethod(description = "列表", permission = "admin:role:list", permissionParentName = "系统管理", permissionName = "角色管理")
+    public Page<RoleDO> list(
+            @HttpParam(name = "name", type = HttpParamType.COMMON, description = "搜索名称") String name,
+            @HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+            @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit,
+            @HttpParam(name = "adminId", type = HttpParamType.USER_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "添加", permission = "admin:role:create", permissionParentName = "系统管理", permissionName = "角色管理")
+    public RoleDO create(
+            @NotNull @HttpParam(name = "role", type = HttpParamType.COMMON, description = "角色对象") RoleDO roleDO,
+            @HttpParam(name = "adminId", type = HttpParamType.USER_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "删除", permission = "admin:role:delete", permissionParentName = "系统管理", permissionName = "角色管理")
+    public String delete(
+            @NotNull @HttpParam(name = "roleId", type = HttpParamType.COMMON, description = "角色Id") Long roleId,
+            @HttpParam(name = "adminId", type = HttpParamType.USER_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "更新", permission = "admin:role:update", permissionParentName = "系统管理", permissionName = "角色管理")
+    public RoleDO update(
+            @NotNull @HttpParam(name = "role", type = HttpParamType.COMMON, description = "角色对象") RoleDO roleDO,
+            @HttpParam(name = "adminId", type = HttpParamType.USER_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "角色授权", permission = "admin:role:permissionList",  permissionParentName = "系统管理", permissionName = "角色管理")
+    public String permissionSet(
+            @NotNull @HttpParam(name = "roleSetPermissionDTO", type = HttpParamType.COMMON, description = "设置DTO") RoleSetPermissionDTO roleSetPermissionDTO,
+            @HttpParam(name = "adminId", type = HttpParamType.USER_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "权限列表", permission = "admin:permission:list", permissionParentName = "系统管理", permissionName = "角色管理")
+    public Map<String,Object> permissionList(
+            @NotNull @HttpParam(name = "roleId", type = HttpParamType.COMMON, description = "角色ID") Long roleId,
+            @HttpParam(name = "adminId", type = HttpParamType.USER_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+
+    @HttpMethod(description = "角色枚举")
+    public List<Map<String,Object>> options(
+            @HttpParam(name = "adminId", type = HttpParamType.USER_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+}

+ 141 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/role/RoleServiceImpl.java

@@ -0,0 +1,141 @@
+package com.iotechn.unimall.admin.api.role;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.RoleDO;
+import com.iotechn.unimall.data.domain.RolePermissionDO;
+import com.iotechn.unimall.data.dto.PermissionPointDTO;
+import com.iotechn.unimall.data.dto.RoleSetPermissionDTO;
+import com.iotechn.unimall.data.enums.RoleStatusType;
+import com.iotechn.unimall.data.mapper.RoleMapper;
+import com.iotechn.unimall.data.mapper.RolePermissionMapper;
+import com.iotechn.unimall.data.model.Page;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.*;
+
+/**
+ * Created by rize on 2019/4/11.
+ */
+@Service
+public class RoleServiceImpl implements RoleService {
+
+    @Autowired
+    private RoleMapper roleMapper;
+
+    @Autowired
+    private RolePermissionMapper rolePermissionMapper;
+
+    public static List<PermissionPointDTO> permDTOs = new LinkedList<>();
+
+    public static Set<String> allPermPoint = new HashSet<>();
+
+    @Override
+    public Page<RoleDO> list(String name, Integer page, Integer limit, Long adminId) throws ServiceException {
+        Wrapper<RoleDO> wrapper = new EntityWrapper<RoleDO>();
+        if (!StringUtils.isEmpty(name)) {
+            wrapper.like("name", name);
+        }
+        List<RoleDO> roleDOS = roleMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+        Integer count = roleMapper.selectCount(wrapper);
+        return new Page<RoleDO>(roleDOS, page, limit, count);
+    }
+
+    @Override
+    public RoleDO create(RoleDO roleDO, Long adminId) throws ServiceException {
+        Date now = new Date();
+        roleDO.setStatus(RoleStatusType.ACTIVE.getCode());
+        roleDO.setGmtUpdate(now);
+        roleDO.setGmtCreate(now);
+        if (roleMapper.insert(roleDO) > 0) {
+            return roleDO;
+        }
+        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
+    }
+
+    @Override
+    public String delete(Long roleId, Long adminId) throws ServiceException {
+        if (roleMapper.deleteById(roleId) > 0) {
+            return "ok";
+        }
+        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
+    }
+
+    @Override
+    public RoleDO update(RoleDO roleDO, Long adminId) throws ServiceException {
+        if (roleMapper.updateById(roleDO) > 0) {
+            return roleDO;
+        }
+        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public String permissionSet(RoleSetPermissionDTO roleSetPermissionDTO, Long adminId) throws ServiceException {
+        Long roleId = roleSetPermissionDTO.getRoleId();
+        if (roleId == null) {
+            throw new AdminServiceException(ExceptionDefinition.PARAM_CHECK_FAILED);
+        }
+        rolePermissionMapper.delete(new EntityWrapper<RolePermissionDO>().eq("role_id", roleId));
+        //构建插入
+        List<String> permissions = roleSetPermissionDTO.getPermissions();
+        if (!CollectionUtils.isEmpty(permissions)) {
+            Date now = new Date();
+            for (String permission : permissions) {
+                RolePermissionDO rolePermissionDO = new RolePermissionDO();
+                rolePermissionDO.setRoleId(roleId);
+                rolePermissionDO.setDeleted(0);
+                rolePermissionDO.setPermission(permission);
+                rolePermissionDO.setGmtCreate(now);
+                rolePermissionDO.setGmtUpdate(now);
+                rolePermissionMapper.insert(rolePermissionDO);
+            }
+        }
+        return "ok";
+    }
+
+    @Override
+    public Map<String,Object> permissionList(Long roleId, Long adminId) throws ServiceException {
+        List<RolePermissionDO> rolePermissionDOList =
+                rolePermissionMapper.selectList(
+                        new EntityWrapper<RolePermissionDO>()
+                                .eq("role_id", roleId));
+
+        Map<String,Object> map = new HashMap<>();
+        Set<String> permissionPoint = new HashSet<>();
+        for (RolePermissionDO permissionDO : rolePermissionDOList) {
+            if ("*".equals(permissionDO.getPermission())) {
+                //若为超级管理员,则直接push所有权限进去
+                permissionPoint.addAll(allPermPoint);
+                break;
+            } else {
+                permissionPoint.add(permissionDO.getPermission());
+            }
+        }
+        map.put("systemPermissions", permDTOs);
+        map.put("assignedPermissions", permissionPoint);
+        return map;
+    }
+
+    @Override
+    public List<Map<String, Object>> options(Long adminId) throws ServiceException {
+        List<RoleDO> roleDOS = roleMapper.selectList(new EntityWrapper<>());
+        List<Map<String,Object>> list = new LinkedList<>();
+        roleDOS.forEach(item -> {
+            Map<String,Object> map = new HashMap<>();
+            map.put("value", item.getId());
+            map.put("label", item.getName());
+            list.add(map);
+        });
+        return list;
+    }
+
+}

+ 76 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/IShopAccountService.java

@@ -0,0 +1,76 @@
+package com.iotechn.unimall.admin.api.shop;
+
+
+import com.iotechn.unimall.data.domain.shop.ShopAccount;
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 电商账户表Service接口
+ *
+ * @author jlb
+ * @date 2022-05-28
+ */
+@HttpOpenApi(group = "admin.shop.shopAccount", description = "电商账户表")
+public interface IShopAccountService {
+    @HttpMethod(description = "新增", permission = "admin:shop:shopAccount:add", permissionParentName = "账户管理", permissionName = "电商账户表管理")
+    public Boolean add(@NotNull @HttpParam(name = "shopAccount", type = HttpParamType.COMMON, description = "电商账户表") ShopAccount shopAccount,
+                       @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "adminId") Long adminId) throws ServiceException;
+
+    @HttpMethod(description = "列表", permission = "admin:shop:shopAccount:list", permissionParentName = "账户管理", permissionName = "电商账户表管理")
+    public Page<ShopAccount> list(
+            @HttpParam(name = "dangAccount", type = HttpParamType.COMMON, description = "当当账号") String dangAccount,
+            @HttpParam(name = "dangPassword", type = HttpParamType.COMMON, description = "当当密码") String dangPassword,
+            @HttpParam(name = "fuziAccount", type = HttpParamType.COMMON, description = "夫子账号") String fuziAccount,
+            @HttpParam(name = "fuziPassword", type = HttpParamType.COMMON, description = "夫子密码") String fuziPassword,
+            @HttpParam(name = "fuziCookie", type = HttpParamType.COMMON, description = "夫子cookie") String fuziCookie,
+            @HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Integer deleteFlag,
+            @HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+            @HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+            @HttpParam(name = "userId", type = HttpParamType.COMMON, description = "") Long userId,
+            @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "") Long adminId,
+            @HttpParam(name = "pageNum", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+            @HttpParam(name = "pageSize", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+            throws ServiceException;
+
+    @HttpMethod(description = "删除", permission = "admin:shop:shopAccount:delete", permissionParentName = "账户管理", permissionName = "电商账户表管理")
+    public Boolean delete(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "") Long id) throws ServiceException;
+
+    @HttpMethod(description = "修改", permission = "admin:shop:shopAccount:update", permissionParentName = "账户管理", permissionName = "电商账户表管理")
+    public Boolean update(@NotNull @HttpParam(name = "shopAccount", type = HttpParamType.COMMON, description = "电商账户表") ShopAccount shopAccount,
+                          @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "adminId") Long adminId) throws ServiceException;
+    @HttpMethod(description = "修改", permission = "admin:shop:shopAccount:edit", permissionParentName = "账户管理", permissionName = "电商账户表管理")
+    public Boolean edit(@NotNull @HttpParam(name = "shopAccount", type = HttpParamType.COMMON, description = "电商账户表") ShopAccount shopAccount,
+                          @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "adminId") Long adminId) throws ServiceException;
+
+    @HttpMethod(description = "查询", permission = "admin:shop:shopAccount:get", permissionParentName = "账户管理", permissionName = "电商账户表管理")
+    public ShopAccount get(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "") Long id) throws ServiceException;
+
+    @HttpMethod(description = "导出excl表", permission = "admin:shop:shopAccount:export", permissionParentName = "账户管理", permissionName = "电商账户表管理")
+    public String export(
+            @HttpParam(name = "dangAccount", type = HttpParamType.COMMON, description = "当当账号") String dangAccount,
+            @HttpParam(name = "dangPassword", type = HttpParamType.COMMON, description = "当当密码") String dangPassword,
+            @HttpParam(name = "fuziAccount", type = HttpParamType.COMMON, description = "夫子账号") String fuziAccount,
+            @HttpParam(name = "fuziPassword", type = HttpParamType.COMMON, description = "夫子密码") String fuziPassword,
+            @HttpParam(name = "fuziCookie", type = HttpParamType.COMMON, description = "夫子cookie") String fuziCookie,
+            @HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Integer deleteFlag,
+            @HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+            @HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+            @HttpParam(name = "userId", type = HttpParamType.COMMON, description = "") Long userId,
+            @HttpParam(name = "adminId", type = HttpParamType.COMMON, description = "") Long adminId,
+            @HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+            @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit) throws ServiceException;
+    @HttpMethod(description = "角色枚举")
+    public List<Map<String,Object>> options(
+            @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId) throws ServiceException;
+
+}

+ 61 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/IShopLogService.java

@@ -0,0 +1,61 @@
+package com.iotechn.unimall.admin.api.shop;
+
+
+import com.iotechn.unimall.data.domain.shop.ShopLog;
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.model.Page;
+import java.util.Date;
+
+/**
+ * 同步日志Service接口
+ * 
+ * @author jlb
+ * @date 2022-06-08
+ */
+@HttpOpenApi(group = "admin.shop.shopLog", description = "同步日志")
+public interface IShopLogService{
+	@HttpMethod(description = "新增", permission = "admin:shop:shopLog:add", permissionParentName = "同步日志", permissionName = "同步日志管理")
+	public Boolean add(@NotNull @HttpParam(name = "shopLog", type = HttpParamType.COMMON, description = "同步日志") ShopLog shopLog,
+						   @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "adminId") Long adminId)throws ServiceException;
+
+	@HttpMethod(description = "列表", permission = "admin:shop:shopLog:list",permissionParentName = "同步日志", permissionName = "同步日志管理")
+	public Page<ShopLog> list(
+								@HttpParam(name = "title", type = HttpParamType.COMMON, description = "标题") String title,
+							@HttpParam(name = "content", type = HttpParamType.COMMON, description = "内容") String content,
+										@HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Long deleteFlag,
+							@HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+							@HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+							@HttpParam(name = "userId", type = HttpParamType.COMMON, description = "") Long userId,
+							@HttpParam(name = "adminId", type = HttpParamType.COMMON, description = "") Long adminId,
+					@HttpParam(name = "pageNum", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+		@HttpParam(name = "pageSize", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+		throws ServiceException;
+
+	@HttpMethod(description = "删除", permission = "admin:shop:shopLog:delete",permissionParentName = "同步日志", permissionName = "同步日志管理")
+	public Boolean delete(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "")Long id)throws ServiceException;
+
+	@HttpMethod(description = "修改", permission = "admin:shopLog:shopLog:update",permissionParentName = "同步日志", permissionName = "同步日志管理")
+	public Boolean update(@NotNull @HttpParam(name = "shopLog", type = HttpParamType.COMMON, description = "同步日志") ShopLog shopLog,
+						  @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "adminId") Long adminId)throws ServiceException;
+
+	@HttpMethod(description = "查询", permission = "admin:shop:shopLog:get",permissionParentName = "同步日志", permissionName = "同步日志管理")
+	public ShopLog get(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "")Long id)throws ServiceException;
+	
+	@HttpMethod(description = "导出excl表", permission = "admin:shop:shopLog:export",permissionParentName = "同步日志", permissionName = "同步日志管理")
+	public String export(
+								@HttpParam(name = "title", type = HttpParamType.COMMON, description = "标题") String title,
+							@HttpParam(name = "content", type = HttpParamType.COMMON, description = "内容") String content,
+										@HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Long deleteFlag,
+							@HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+							@HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+							@HttpParam(name = "userId", type = HttpParamType.COMMON, description = "") Long userId,
+							@HttpParam(name = "adminId", type = HttpParamType.COMMON, description = "") Long adminId,
+				@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+	@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)throws ServiceException;
+	
+}

+ 97 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/IShopOrderService.java

@@ -0,0 +1,97 @@
+package com.iotechn.unimall.admin.api.shop;
+
+
+import com.iotechn.unimall.data.domain.shop.ShopOrder;
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.dto.shop.ShopDTO;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.Date;
+
+/**
+ * 电商订单表Service接口
+ *
+ * @author jlb
+ * @date 2022-05-28
+ */
+@HttpOpenApi(group = "admin.shop.shopOrder", description = "电商订单表")
+public interface IShopOrderService {
+    @HttpMethod(description = "新增", permission = "admin:shop:shopOrder:add", permissionParentName = "电商管理", permissionName = "电商订单表管理")
+    public Boolean add(@NotNull @HttpParam(name = "shopOrder", type = HttpParamType.COMMON, description = "电商订单表") ShopOrder shopOrder,
+                       @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "adminId") Long adminId) throws ServiceException;
+
+    @HttpMethod(description = "列表", permission = "admin:shop:shopOrder:list", permissionParentName = "电商管理", permissionName = "电商订单表管理")
+    public Page<ShopOrder> list(
+            @HttpParam(name = "accountId", type = HttpParamType.COMMON, description = "账户表id") Long accountId,
+            @HttpParam(name = "orderId", type = HttpParamType.COMMON, description = "当当订单号") String orderId,
+            @HttpParam(name = "dangOrder", type = HttpParamType.COMMON, description = "夫子订单号") String dangOrder,
+            @HttpParam(name = "dangOrderStatus", type = HttpParamType.COMMON, description = "当当发货状态") String dangOrderStatus,
+            @HttpParam(name = "address", type = HttpParamType.COMMON, description = "详细地址") String address,
+            @HttpParam(name = "provName", type = HttpParamType.COMMON, description = "省") String provName,
+            @HttpParam(name = "cityName", type = HttpParamType.COMMON, description = "市") String cityName,
+            @HttpParam(name = "areaName", type = HttpParamType.COMMON, description = "区") String areaName,
+            @HttpParam(name = "orderStatus", type = HttpParamType.COMMON, description = "订单状态") String orderStatus,
+            @HttpParam(name = "orderStatusName", type = HttpParamType.COMMON, description = "订单状态") String orderStatusName,
+            @HttpParam(name = "payStatus", type = HttpParamType.COMMON, description = "付款状态") String payStatus,
+            @HttpParam(name = "payName", type = HttpParamType.COMMON, description = "付款状态") String payName,
+            @HttpParam(name = "receiverName", type = HttpParamType.COMMON, description = "收件人") String receiverName,
+            @HttpParam(name = "mobile", type = HttpParamType.COMMON, description = "收件人电话") String mobile,
+            @HttpParam(name = "receiver", type = HttpParamType.COMMON, description = "收件人详细信息") String receiver,
+            @HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Integer deleteFlag,
+            @HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+            @HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+            @HttpParam(name = "userId", type = HttpParamType.COMMON, description = "") Long userId,
+            @HttpParam(name = "adminId", type = HttpParamType.COMMON, description = "") Long adminId,
+            @HttpParam(name = "shopName", type = HttpParamType.COMMON, description = "店铺名称") String shopName,
+            @HttpParam(name = "pageNum", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+            @HttpParam(name = "pageSize", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+            throws ServiceException;
+
+    @HttpMethod(description = "删除", permission = "admin:shop:shopOrder:delete", permissionParentName = "电商管理", permissionName = "电商订单表管理")
+    public Boolean delete(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "") String id) throws ServiceException;
+
+    @HttpMethod(description = "修改", permission = "admin:shopOrder:shopOrder:update", permissionParentName = "电商管理", permissionName = "电商订单表管理")
+    public Boolean update(@NotNull @HttpParam(name = "shopOrder", type = HttpParamType.COMMON, description = "电商订单表") ShopOrder shopOrder,
+                          @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "adminId") Long adminId) throws ServiceException;
+
+    @HttpMethod(description = "查询", permission = "admin:shop:shopOrder:get", permissionParentName = "电商管理", permissionName = "电商订单表管理")
+    public ShopOrder get(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "") Long id) throws ServiceException;
+
+    @HttpMethod(description = "导出excl表", permission = "admin:shop:shopOrder:export", permissionParentName = "电商管理", permissionName = "电商订单表管理")
+    public String export(
+            @HttpParam(name = "accountId", type = HttpParamType.COMMON, description = "账户表id") Long accountId,
+            @HttpParam(name = "orderId", type = HttpParamType.COMMON, description = "当当订单号") String orderId,
+            @HttpParam(name = "dangOrder", type = HttpParamType.COMMON, description = "夫子订单号") String dangOrder,
+            @HttpParam(name = "address", type = HttpParamType.COMMON, description = "详细地址") String address,
+            @HttpParam(name = "provName", type = HttpParamType.COMMON, description = "省") String provName,
+            @HttpParam(name = "cityName", type = HttpParamType.COMMON, description = "市") String cityName,
+            @HttpParam(name = "areaName", type = HttpParamType.COMMON, description = "区") String areaName,
+            @HttpParam(name = "orderStatus", type = HttpParamType.COMMON, description = "订单状态") String orderStatus,
+            @HttpParam(name = "orderStatusName", type = HttpParamType.COMMON, description = "订单状态") String orderStatusName,
+            @HttpParam(name = "payStatus", type = HttpParamType.COMMON, description = "付款状态") String payStatus,
+            @HttpParam(name = "payName", type = HttpParamType.COMMON, description = "付款状态") String payName,
+            @HttpParam(name = "receiverName", type = HttpParamType.COMMON, description = "收件人") String receiverName,
+            @HttpParam(name = "mobile", type = HttpParamType.COMMON, description = "收件人电话") String mobile,
+            @HttpParam(name = "receiver", type = HttpParamType.COMMON, description = "收件人详细信息") String receiver,
+            @HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Integer deleteFlag,
+            @HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+            @HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+            @HttpParam(name = "userId", type = HttpParamType.COMMON, description = "") Long userId,
+            @HttpParam(name = "adminId", type = HttpParamType.COMMON, description = "") Long adminId,
+            @HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+            @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit) throws ServiceException;
+    @HttpMethod(description = "同步订单信息")
+    public String syncOrderInfoList(
+            @NotNull @HttpParam(name = "shopDTO", type = HttpParamType.COMMON, description = "参数列表") ShopDTO shopDTO) throws Exception;
+    @HttpMethod(description = "获取订单信息")
+    public ShopOrder syncOrderInfo(
+            @NotNull @HttpParam(name = "orderId", type = HttpParamType.COMMON, description = "夫子订单编号") String orderId,
+            @NotNull @HttpParam(name = "dangId", type = HttpParamType.COMMON, description = "当当店铺id") String dangId,
+            @NotNull @HttpParam(name = "dangOrder", type = HttpParamType.COMMON, description = "当当订单编号") String dangOrder) throws Exception;
+
+}

+ 65 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/IShopTranService.java

@@ -0,0 +1,65 @@
+package com.iotechn.unimall.admin.api.shop;
+
+
+import com.iotechn.unimall.data.domain.shop.ShopTran;
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.model.Page;
+import java.util.Date;
+
+/**
+ * 物流公司Service接口
+ * 
+ * @author jlb
+ * @date 2022-05-29
+ */
+@HttpOpenApi(group = "admin.shop.shopTran", description = "物流公司")
+public interface IShopTranService{
+	@HttpMethod(description = "新增", permission = "admin:shop:shopTran:add", permissionParentName = "宠物管理", permissionName = "物流公司管理")
+	public Boolean add(@NotNull @HttpParam(name = "shopTran", type = HttpParamType.COMMON, description = "物流公司") ShopTran shopTran,
+						   @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "adminId") Long adminId)throws ServiceException;
+
+	@HttpMethod(description = "列表", permission = "admin:shop:shopTran:list",permissionParentName = "宠物管理", permissionName = "物流公司管理")
+	public Page<ShopTran> list(
+								@HttpParam(name = "name", type = HttpParamType.COMMON, description = "物流公司名称") String name,
+							@HttpParam(name = "code1", type = HttpParamType.COMMON, description = "物流公司编码") String code1,
+							@HttpParam(name = "code2", type = HttpParamType.COMMON, description = "物流公司编码") String code2,
+							@HttpParam(name = "phone", type = HttpParamType.COMMON, description = "物流公司电话") String phone,
+										@HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Integer deleteFlag,
+							@HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+							@HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+							@HttpParam(name = "userId", type = HttpParamType.COMMON, description = "") Long userId,
+							@HttpParam(name = "adminId", type = HttpParamType.COMMON, description = "") Long adminId,
+					@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+		@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+		throws ServiceException;
+
+	@HttpMethod(description = "删除", permission = "admin:shop:shopTran:delete",permissionParentName = "宠物管理", permissionName = "物流公司管理")
+	public Boolean delete(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "")Long id)throws ServiceException;
+
+	@HttpMethod(description = "修改", permission = "admin:shopTran:shopTran:update",permissionParentName = "宠物管理", permissionName = "物流公司管理")
+	public Boolean update(@NotNull @HttpParam(name = "shopTran", type = HttpParamType.COMMON, description = "物流公司") ShopTran shopTran,
+						  @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "adminId") Long adminId)throws ServiceException;
+
+	@HttpMethod(description = "查询", permission = "admin:shop:shopTran:get",permissionParentName = "宠物管理", permissionName = "物流公司管理")
+	public ShopTran get(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "")Long id)throws ServiceException;
+	
+	@HttpMethod(description = "导出excl表", permission = "admin:shop:shopTran:export",permissionParentName = "宠物管理", permissionName = "物流公司管理")
+	public String export(
+								@HttpParam(name = "name", type = HttpParamType.COMMON, description = "物流公司名称") String name,
+							@HttpParam(name = "code1", type = HttpParamType.COMMON, description = "物流公司编码") String code1,
+							@HttpParam(name = "code2", type = HttpParamType.COMMON, description = "物流公司编码") String code2,
+							@HttpParam(name = "phone", type = HttpParamType.COMMON, description = "物流公司电话") String phone,
+										@HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Integer deleteFlag,
+							@HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+							@HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+							@HttpParam(name = "userId", type = HttpParamType.COMMON, description = "") Long userId,
+							@HttpParam(name = "adminId", type = HttpParamType.COMMON, description = "") Long adminId,
+				@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+	@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)throws ServiceException;
+	
+}

+ 177 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/impl/ShopAccountServiceImpl.java

@@ -0,0 +1,177 @@
+package com.iotechn.unimall.admin.api.shop.impl;
+
+import java.util.*;
+
+import com.iotechn.unimall.data.domain.AdminDO;
+import com.iotechn.unimall.data.domain.RoleDO;
+import com.iotechn.unimall.data.mapper.AdminMapper;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.util.ExcelUtil;
+import com.iotechn.unimall.data.mapper.shop.ShopAccountMapper;
+import com.iotechn.unimall.data.domain.shop.ShopAccount;
+import com.iotechn.unimall.admin.api.shop.IShopAccountService;
+import com.iotechn.unimall.data.model.Page;
+
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 电商账户表Service业务层处理
+ *
+ * @author jlb
+ * @date 2022-05-28
+ */
+@Service
+public class ShopAccountServiceImpl implements IShopAccountService {
+    @Autowired
+    private ShopAccountMapper shopAccountMapper;
+    @Autowired
+    private AdminMapper adminMapper;
+
+    @Override
+    public Boolean add(ShopAccount shopAccount, Long adminId) throws ServiceException {
+        Date now = new Date();
+        shopAccount.setGmtCreate(now);
+        shopAccount.setGmtUpdate(now);
+        shopAccount.setAdminId(adminId);
+        return shopAccountMapper.insert(shopAccount) > 0;
+    }
+
+    @Override
+    public Page<ShopAccount> list(String dangAccount, String dangPassword, String fuziAccount, String fuziPassword, String fuziCookie, Integer deleteFlag, Date gmtCreate, Date gmtUpdate, Long userId, Long adminId, Integer page, Integer limit) throws ServiceException {
+        Wrapper<ShopAccount> wrapper = new EntityWrapper<ShopAccount>();
+        if (!StringUtils.isEmpty(dangAccount)) {
+            wrapper.eq("dang_account", dangAccount);
+        }
+        if (!StringUtils.isEmpty(dangPassword)) {
+            wrapper.eq("dang_password", dangPassword);
+        }
+        if (!StringUtils.isEmpty(fuziAccount)) {
+            wrapper.eq("fuzi_account", fuziAccount);
+        }
+        if (!StringUtils.isEmpty(fuziPassword)) {
+            wrapper.eq("fuzi_password", fuziPassword);
+        }
+        if (!StringUtils.isEmpty(fuziCookie)) {
+            wrapper.eq("fuzi_cookie", fuziCookie);
+        }
+        if (!StringUtils.isEmpty(deleteFlag)) {
+            wrapper.eq("delete_flag", deleteFlag);
+        }
+        if (!StringUtils.isEmpty(gmtCreate)) {
+            wrapper.eq("gmt_create", gmtCreate);
+        }
+        if (!StringUtils.isEmpty(gmtUpdate)) {
+            wrapper.eq("gmt_update", gmtUpdate);
+        }
+        if (!StringUtils.isEmpty(userId)) {
+            wrapper.eq("user_id", userId);
+        }
+        if (adminId != 1) {
+            wrapper.eq("user_id", adminId);
+        }
+        wrapper.eq("delete_flag", 0);
+        List<ShopAccount> list = shopAccountMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+        for (ShopAccount shopAccount:list
+             ) {
+            if(shopAccount.getUserId() != null){
+                AdminDO adminDO = adminMapper.selectById(shopAccount.getUserId());
+                if(adminDO != null){
+                    shopAccount.setUserName(adminDO.getUsername());
+                }
+            }
+        }
+        Integer count = shopAccountMapper.selectCount(wrapper);
+        return new Page<ShopAccount>(list, page, limit, count);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean delete(Long id) {
+        String[] ids = String.valueOf(id).split(",");
+        for (String tt : ids) {
+            ShopAccount tmp = shopAccountMapper.selectById(Long.parseLong(tt));
+            if (tmp != null) {
+                tmp.setDeleteFlag(1);
+                shopAccountMapper.updateById(tmp);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean update(ShopAccount shopAccount, Long adminId) throws ServiceException {
+        Date now = new Date();
+        shopAccount.setGmtUpdate(now);
+        shopAccount.setAdminId(adminId);
+        return shopAccountMapper.updateById(shopAccount) > 0;
+    }
+    @Override
+    public Boolean edit(ShopAccount shopAccount, Long adminId) throws ServiceException {
+        Date now = new Date();
+        shopAccount.setGmtUpdate(now);
+        shopAccount.setAdminId(adminId);
+        return shopAccountMapper.updateById(shopAccount) > 0;
+    }
+    @Override
+    public ShopAccount get(Long id) throws ServiceException {
+        return shopAccountMapper.selectById(id);
+    }
+
+    @Override
+    public String export(String dangAccount, String dangPassword, String fuziAccount, String fuziPassword, String fuziCookie, Integer deleteFlag, Date gmtCreate, Date gmtUpdate, Long userId, Long adminId, Integer page, Integer limit) throws ServiceException {
+        Wrapper<ShopAccount> wrapper = new EntityWrapper<ShopAccount>();
+        if (!StringUtils.isEmpty(dangAccount)) {
+            wrapper.eq("dang_account", dangAccount);
+        }
+        if (!StringUtils.isEmpty(dangPassword)) {
+            wrapper.eq("dang_password", dangPassword);
+        }
+        if (!StringUtils.isEmpty(fuziAccount)) {
+            wrapper.eq("fuzi_account", fuziAccount);
+        }
+        if (!StringUtils.isEmpty(fuziPassword)) {
+            wrapper.eq("fuzi_password", fuziPassword);
+        }
+        if (!StringUtils.isEmpty(fuziCookie)) {
+            wrapper.eq("fuzi_cookie", fuziCookie);
+        }
+        if (!StringUtils.isEmpty(deleteFlag)) {
+            wrapper.eq("delete_flag", deleteFlag);
+        }
+        if (!StringUtils.isEmpty(gmtCreate)) {
+            wrapper.eq("gmt_create", gmtCreate);
+        }
+        if (!StringUtils.isEmpty(gmtUpdate)) {
+            wrapper.eq("gmt_update", gmtUpdate);
+        }
+        if (!StringUtils.isEmpty(userId)) {
+            wrapper.eq("user_id", userId);
+        }
+        if (!StringUtils.isEmpty(adminId)) {
+            wrapper.eq("admin_id", adminId);
+        }
+        List<ShopAccount> list = shopAccountMapper.selectList(wrapper);
+        ExcelUtil<ShopAccount> util = new ExcelUtil<ShopAccount>(ShopAccount.class);
+        return util.exportExcel(list, "操作日志");
+    }
+    @Override
+    public List<Map<String, Object>> options(Long adminId) throws ServiceException {
+        List<AdminDO> roleDOS = adminMapper.selectList(new EntityWrapper<>());
+        List<Map<String,Object>> list = new LinkedList<>();
+        roleDOS.forEach(item -> {
+            Map<String,Object> map = new HashMap<>();
+            map.put("value", item.getId());
+            map.put("label", item.getUsername());
+            list.add(map);
+        });
+        return list;
+    }
+
+}

+ 129 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/impl/ShopLogServiceImpl.java

@@ -0,0 +1,129 @@
+package com.iotechn.unimall.admin.api.shop.impl;
+
+import java.util.List;
+
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.util.ExcelUtil;
+import com.iotechn.unimall.data.mapper.shop.ShopLogMapper;
+import com.iotechn.unimall.data.domain.shop.ShopLog;
+import com.iotechn.unimall.admin.api.shop.IShopLogService;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.Date;
+
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 同步日志Service业务层处理
+ *
+ * @author jlb
+ * @date 2022-06-08
+ */
+@Service
+public class ShopLogServiceImpl implements IShopLogService {
+    @Autowired
+    private ShopLogMapper shopLogMapper;
+
+    @Override
+    public Boolean add(ShopLog shopLog, Long adminId) throws ServiceException {
+        Date now = new Date();
+        shopLog.setGmtCreate(now);
+        shopLog.setGmtUpdate(now);
+        shopLog.setAdminId(adminId);
+        return shopLogMapper.insert(shopLog) > 0;
+    }
+
+    @Override
+    public Page<ShopLog> list(String title, String content, Long deleteFlag, Date gmtCreate, Date gmtUpdate, Long userId, Long adminId, Integer page, Integer limit) throws ServiceException {
+        Wrapper<ShopLog> wrapper = new EntityWrapper<ShopLog>();
+        if (!StringUtils.isEmpty(title)) {
+            wrapper.like("title", title);
+        }
+        if (!StringUtils.isEmpty(content)) {
+            wrapper.like("content", content);
+        }
+        if (!StringUtils.isEmpty(deleteFlag)) {
+            wrapper.eq("delete_flag", deleteFlag);
+        }
+        if (!StringUtils.isEmpty(gmtCreate)) {
+            wrapper.eq("gmt_create", gmtCreate);
+        }
+        if (!StringUtils.isEmpty(gmtUpdate)) {
+            wrapper.eq("gmt_update", gmtUpdate);
+        }
+        if (!StringUtils.isEmpty(userId)) {
+            wrapper.eq("user_id", userId);
+        }
+        if (!StringUtils.isEmpty(adminId)) {
+            wrapper.eq("admin_id", adminId);
+        }
+        wrapper.eq("delete_flag", 0);
+		wrapper.orderBy("gmt_create", false);
+        List<ShopLog> list = shopLogMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+        Integer count = shopLogMapper.selectCount(wrapper);
+        return new Page<ShopLog>(list, page, limit, count);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean delete(Long id) {
+        String[] ids = String.valueOf(id).split(",");
+        for (String tt : ids) {
+            ShopLog tmp = shopLogMapper.selectById(Long.parseLong(tt));
+            if (tmp != null) {
+                tmp.setDeleteFlag(1);
+                shopLogMapper.updateById(tmp);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean update(ShopLog shopLog, Long adminId) throws ServiceException {
+        Date now = new Date();
+        shopLog.setGmtUpdate(now);
+        shopLog.setAdminId(adminId);
+        return shopLogMapper.updateById(shopLog) > 0;
+    }
+
+    @Override
+    public ShopLog get(Long id) throws ServiceException {
+        return shopLogMapper.selectById(id);
+    }
+
+    @Override
+    public String export(String title, String content, Long deleteFlag, Date gmtCreate, Date gmtUpdate, Long userId, Long adminId, Integer page, Integer limit) throws ServiceException {
+        Wrapper<ShopLog> wrapper = new EntityWrapper<ShopLog>();
+        if (!StringUtils.isEmpty(title)) {
+            wrapper.eq("title", title);
+        }
+        if (!StringUtils.isEmpty(content)) {
+            wrapper.eq("content", content);
+        }
+        if (!StringUtils.isEmpty(deleteFlag)) {
+            wrapper.eq("delete_flag", deleteFlag);
+        }
+        if (!StringUtils.isEmpty(gmtCreate)) {
+            wrapper.eq("gmt_create", gmtCreate);
+        }
+        if (!StringUtils.isEmpty(gmtUpdate)) {
+            wrapper.eq("gmt_update", gmtUpdate);
+        }
+        if (!StringUtils.isEmpty(userId)) {
+            wrapper.eq("user_id", userId);
+        }
+        if (!StringUtils.isEmpty(adminId)) {
+            wrapper.eq("admin_id", adminId);
+        }
+        List<ShopLog> list = shopLogMapper.selectList(wrapper);
+        ExcelUtil<ShopLog> util = new ExcelUtil<ShopLog>(ShopLog.class);
+        return util.exportExcel(list, "操作日志");
+    }
+}

+ 567 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/impl/ShopOrderServiceImpl.java

@@ -0,0 +1,567 @@
+package com.iotechn.unimall.admin.api.shop.impl;
+
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import com.dangdang.openplatform.openapi.sdk.ApiException;
+import com.dangdang.openplatform.openapi.sdk.SdkClient;
+import com.dangdang.openplatform.openapi.sdk.internal.util.FileItem;
+import com.dangdang.openplatform.openapi.sdk.request.order.*;
+import com.dangdang.openplatform.openapi.sdk.requestmodel.order.EncryptDTO;
+import com.dangdang.openplatform.openapi.sdk.requestmodel.order.OrderDetailsGet;
+import com.dangdang.openplatform.openapi.sdk.response.order.*;
+import com.dangdang.openplatform.openapi.sdk.responsemodel.order.*;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.iotechn.unimall.data.domain.shop.ShopAccount;
+import com.iotechn.unimall.data.domain.shop.ShopLog;
+import com.iotechn.unimall.data.domain.shop.ShopTran;
+import com.iotechn.unimall.data.dto.shop.FuziDTO;
+import com.iotechn.unimall.data.dto.shop.ShopDTO;
+import com.iotechn.unimall.data.dto.shop.XmlObject.OrderDetail;
+import com.iotechn.unimall.data.dto.shop.XmlObject.SendGood;
+import com.iotechn.unimall.data.dto.shop.XmlObject.SendGoodsInfo;
+import com.iotechn.unimall.data.mapper.shop.ShopAccountMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopLogMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopTranMapper;
+import com.iotechn.unimall.data.util.XMLUtil;
+import org.apache.commons.httpclient.Cookie;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.cookie.CookiePolicy;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.util.ExcelUtil;
+import com.iotechn.unimall.data.mapper.shop.ShopOrderMapper;
+import com.iotechn.unimall.data.domain.shop.ShopOrder;
+import com.iotechn.unimall.admin.api.shop.IShopOrderService;
+import com.iotechn.unimall.data.model.Page;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 电商订单表Service业务层处理
+ *
+ * @author jlb
+ * @date 2022-05-28
+ */
+@Service
+public class ShopOrderServiceImpl implements IShopOrderService {
+    @Autowired
+    private ShopOrderMapper shopOrderMapper;
+    @Autowired
+    private ShopAccountMapper shopAccountMapper;
+    @Autowired
+    private ShopTranMapper shopTranMapper;
+
+    @Autowired
+    private ShopLogMapper shopLogMapper;
+
+    @Override
+    public Boolean add(ShopOrder shopOrder, Long adminId) throws ServiceException {
+        Date now = new Date();
+        shopOrder.setGmtCreate(now);
+        shopOrder.setGmtUpdate(now);
+        shopOrder.setAdminId(adminId);
+        return shopOrderMapper.insert(shopOrder) > 0;
+    }
+
+    @Override
+    public Page<ShopOrder> list(Long accountId, String orderId, String dangOrder,String dangOrderStatus, String address, String provName, String cityName, String areaName, String orderStatus, String orderStatusName, String payStatus, String payName, String receiverName, String mobile, String receiver, Integer deleteFlag, Date gmtCreate, Date gmtUpdate, Long userId, Long adminId,String shopName, Integer page, Integer limit) throws ServiceException {
+        Wrapper<ShopOrder> wrapper = new EntityWrapper<ShopOrder>();
+        List<Long> param = new ArrayList<>();
+        if(!StringUtils.isEmpty(shopName)){
+            Wrapper<ShopAccount> wrapper1 = new EntityWrapper<ShopAccount>();
+            wrapper1.like("dang_name",shopName);
+            List<ShopAccount> list = shopAccountMapper.selectList(wrapper1);
+            for (ShopAccount shopAccount:list
+                 ) {
+                param.add(shopAccount.getId());
+            }
+            wrapper.in("account_id", param);
+        }
+        if (!StringUtils.isEmpty(orderId)) {
+            wrapper.eq("order_id", orderId);
+        }
+        if (!StringUtils.isEmpty(dangOrder)) {
+            wrapper.eq("dang_order", dangOrder);
+        }
+        if (!StringUtils.isEmpty(address)) {
+            wrapper.eq("address", address);
+        }
+        if (!StringUtils.isEmpty(provName)) {
+            wrapper.eq("prov_name", provName);
+        }
+        if (!StringUtils.isEmpty(cityName)) {
+            wrapper.eq("city_name", cityName);
+        }
+        if (!StringUtils.isEmpty(areaName)) {
+            wrapper.eq("area_name", areaName);
+        }
+        if (!StringUtils.isEmpty(orderStatus)) {
+            wrapper.eq("order_status", orderStatus);
+        }
+        if (!StringUtils.isEmpty(orderStatusName)) {
+            wrapper.like("order_status_name", orderStatusName);
+        }
+        if (!StringUtils.isEmpty(payStatus)) {
+            wrapper.eq("pay_status", payStatus);
+        }
+        if (!StringUtils.isEmpty(payName)) {
+            wrapper.eq("pay_name", payName);
+        }
+        if (!StringUtils.isEmpty(receiverName)) {
+            wrapper.eq("receiver_name", receiverName);
+        }
+        if (!StringUtils.isEmpty(mobile)) {
+            wrapper.eq("mobile", mobile);
+        }
+        if (!StringUtils.isEmpty(receiver)) {
+            wrapper.eq("receiver", receiver);
+        }
+        if (!StringUtils.isEmpty(deleteFlag)) {
+            wrapper.eq("delete_flag", deleteFlag);
+        }
+        if (!StringUtils.isEmpty(gmtCreate)) {
+            wrapper.eq("gmt_create", gmtCreate);
+        }
+        if (!StringUtils.isEmpty(gmtUpdate)) {
+            wrapper.eq("gmt_update", gmtUpdate);
+        }
+        if (!StringUtils.isEmpty(userId)) {
+            wrapper.eq("user_id", userId);
+        }
+        if (!StringUtils.isEmpty(adminId)) {
+            wrapper.eq("admin_id", adminId);
+        }
+        if (!StringUtils.isEmpty(dangOrderStatus)) {
+            wrapper.like("dang_order_status", dangOrderStatus);
+        }
+        wrapper.eq("delete_flag", 0);
+        wrapper.orderBy("created_time",false);
+        List<ShopOrder> list = shopOrderMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+        for (ShopOrder shopOrder: list
+             ) {
+            ShopAccount shopAccount = shopAccountMapper.selectById(shopOrder.getAccountId());
+            shopOrder.setShopAccount(shopAccount);
+        }
+        Integer count = shopOrderMapper.selectCount(wrapper);
+        return new Page<ShopOrder>(list, page, limit, count);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean delete(String id) {
+        String[] ids = String.valueOf(id).split(",");
+        for (String tt : ids) {
+            ShopOrder tmp = shopOrderMapper.selectById(Long.parseLong(tt));
+            if (tmp != null) {
+                tmp.setDeleteFlag(1);
+                shopOrderMapper.updateById(tmp);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean update(ShopOrder shopOrder, Long adminId) throws ServiceException {
+        Date now = new Date();
+        shopOrder.setGmtUpdate(now);
+        shopOrder.setAdminId(adminId);
+        return shopOrderMapper.updateById(shopOrder) > 0;
+    }
+
+    @Override
+    public ShopOrder get(Long id) throws ServiceException {
+        return shopOrderMapper.selectById(id);
+    }
+
+    @Override
+    public String export(Long accountId, String orderId, String dangOrder, String address, String provName, String cityName, String areaName, String orderStatus, String orderStatusName, String payStatus, String payName, String receiverName, String mobile, String receiver, Integer deleteFlag, Date gmtCreate, Date gmtUpdate, Long userId, Long adminId, Integer page, Integer limit) throws ServiceException {
+        Wrapper<ShopOrder> wrapper = new EntityWrapper<ShopOrder>();
+        if (!StringUtils.isEmpty(accountId)) {
+            wrapper.eq("account_id", accountId);
+        }
+        if (!StringUtils.isEmpty(orderId)) {
+            wrapper.eq("order_id", orderId);
+        }
+        if (!StringUtils.isEmpty(dangOrder)) {
+            wrapper.eq("dang_order", dangOrder);
+        }
+        if (!StringUtils.isEmpty(address)) {
+            wrapper.eq("address", address);
+        }
+        if (!StringUtils.isEmpty(provName)) {
+            wrapper.eq("prov_name", provName);
+        }
+        if (!StringUtils.isEmpty(cityName)) {
+            wrapper.eq("city_name", cityName);
+        }
+        if (!StringUtils.isEmpty(areaName)) {
+            wrapper.eq("area_name", areaName);
+        }
+        if (!StringUtils.isEmpty(orderStatus)) {
+            wrapper.eq("order_status", orderStatus);
+        }
+        if (!StringUtils.isEmpty(orderStatusName)) {
+            wrapper.like("order_status_name", orderStatusName);
+        }
+        if (!StringUtils.isEmpty(payStatus)) {
+            wrapper.eq("pay_status", payStatus);
+        }
+        if (!StringUtils.isEmpty(payName)) {
+            wrapper.eq("pay_name", payName);
+        }
+        if (!StringUtils.isEmpty(receiverName)) {
+            wrapper.eq("receiver_name", receiverName);
+        }
+        if (!StringUtils.isEmpty(mobile)) {
+            wrapper.eq("mobile", mobile);
+        }
+        if (!StringUtils.isEmpty(receiver)) {
+            wrapper.eq("receiver", receiver);
+        }
+        if (!StringUtils.isEmpty(deleteFlag)) {
+            wrapper.eq("delete_flag", deleteFlag);
+        }
+        if (!StringUtils.isEmpty(gmtCreate)) {
+            wrapper.eq("gmt_create", gmtCreate);
+        }
+        if (!StringUtils.isEmpty(gmtUpdate)) {
+            wrapper.eq("gmt_update", gmtUpdate);
+        }
+        if (!StringUtils.isEmpty(userId)) {
+            wrapper.eq("user_id", userId);
+        }
+        if (!StringUtils.isEmpty(adminId)) {
+            wrapper.eq("admin_id", adminId);
+        }
+        List<ShopOrder> list = shopOrderMapper.selectList(wrapper);
+        ExcelUtil<ShopOrder> util = new ExcelUtil<ShopOrder>(ShopOrder.class);
+        return util.exportExcel(list, "操作日志");
+    }
+
+    @Override
+    public String syncOrderInfoList(ShopDTO shopDTO) throws Exception {
+        for (ShopDTO tmp:shopDTO.getShopDTOS()
+             ) {
+            syncOrderInfo(tmp.getOrderId(),tmp.getDangId(),tmp.getDangOrder());
+        }
+        return "ok";
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public ShopOrder syncOrderInfo(String orderId,String dangId,String dangOrder) throws Exception {
+        try{
+
+            ShopAccount shopAccount = new ShopAccount();
+            if(dangId != null){
+                shopAccount.setDangId(dangId);
+            }
+    //        if(fuziId != null){
+    //            shopAccount.setFuziId(fuziId);
+    //        }
+            shopAccount = shopAccountMapper.selectOne(shopAccount);
+            flushCookie(shopAccount);
+            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+            HttpGet get = new HttpGet("https://shop.kongfz.com/buyer/order/getOrderInfo/?orderId="+orderId);
+            //这里可以设置请求参数,token等
+            get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+            get.addHeader("cookie",shopAccount.getFuziCookie());
+            HttpResponse response = httpClient.execute(get);//执行获取响应
+            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){//根据状态码处理
+                //返回字符串
+                String res = unicodeToString(EntityUtils.toString(response.getEntity(),"UTF-8"));
+                System.out.println(res);
+                JSONObject datas = JSONObject.parseObject(res);//转换成JSON格式
+                Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                ShopOrder data = JSONObject.parseObject(datas.get("data").toString(),ShopOrder.class);//"data"是根据返回值设定
+                ShopOrder tmp = new ShopOrder();
+                tmp.setOrderId(data.getOrderId());
+                tmp = shopOrderMapper.selectOne(tmp);
+                data.setAccountId(shopAccount.getId());
+                if(tmp == null){
+                    data.setDangOrder(dangOrder);
+                    data.setGmtCreate(new Date());
+                    data.setGmtUpdate(new Date());
+                    shopOrderMapper.insert(data);
+                }
+                else{
+                    data.setDangOrder(dangOrder);
+                    data.setGmtUpdate(new Date());
+                    shopOrderMapper.update(data,new EntityWrapper<ShopOrder>().eq("order_id",tmp.getOrderId()));
+                }
+                tmp = new ShopOrder();
+                tmp.setOrderId(data.getOrderId());
+                tmp = shopOrderMapper.selectOne(tmp);
+                if(tmp.getOrderStatusName().equals("卖家已发货")&&tmp.getDangOrderStatus().equals("未发货")){
+                    //调用当当API 更新发货状态
+                    dangOrderDeal(shopAccount,tmp);
+                }
+                return tmp;
+            }
+            else{
+                return null;
+            }
+
+        } catch (Exception e) {
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("浏览器插件调用异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+            e.printStackTrace();
+            return null;
+        }
+
+    }
+    public void flushCookie(ShopAccount shopAccount){
+        try{
+            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+            HttpGet getMethod = new HttpGet("https://shop.kongfz.com/buyer/order/index/?pageCurr=1&pageShow=30");
+            getMethod.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+            getMethod.addHeader("cookie",shopAccount.getFuziCookie());
+
+            httpClient.execute(getMethod);
+            CloseableHttpResponse response = httpClient.execute(getMethod);//执行获取响应
+            try{
+                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//根据状态码处理
+                    String strTmp= EntityUtils.toString(response.getEntity(),"UTF-8");
+                    //返回字符串
+                    String res = unicodeToString(strTmp);
+                    JSONObject datas = JSONObject.parseObject(res);//转换成JSON格式
+                    Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                    if(status){
+                        return;
+                    }
+                }
+            }
+            catch (Exception exception){
+
+            }
+            finally {
+                response.close();
+                httpClient.close();
+            }
+
+            System.out.println("原cookies = "+shopAccount.getFuziCookie());
+
+            // 登陆 Url
+            String loginUrl = "https://login.kongfz.com/Pc/Login/account";
+            BasicCookieStore store= new BasicCookieStore();
+            httpClient = HttpClients.custom().setDefaultCookieStore(store).build();
+            // 模拟登陆,按实际服务器端要求选用 Post 或 Get 请求方式
+            HttpPost httpPost = new HttpPost(loginUrl);
+
+            // 装填参数
+            List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();
+            nvps.add(new BasicNameValuePair("loginName", shopAccount.getFuziAccount()));
+            nvps.add(new BasicNameValuePair("loginPass", shopAccount.getFuziPassword()));
+            // 设置参数到请求对象中
+            httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
+
+            // 设置header信息
+            // 指定报文头【Content-type】、【User-Agent】
+            httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
+
+            // 执行请求操作,并拿到结果(同步阻塞)
+            response = httpClient.execute(httpPost);
+            if(response.getStatusLine().getStatusCode() == 302){
+                List<org.apache.http.cookie.Cookie> cookielist = store.getCookies();
+                String nCookie = "";
+                for(org.apache.http.cookie.Cookie cookie: cookielist){
+                    String name=cookie.getName();
+                    String value=cookie.getValue();
+                    nCookie += name + "="+value+";";
+                }
+                System.out.println("nCookie:" + nCookie);
+                shopAccount.setFuziCookie(nCookie);
+                shopAccountMapper.updateById(shopAccount);
+            }
+            // 释放链接
+            response.close();
+
+        }catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public void dangOrderDeal(ShopAccount shopAccount,ShopOrder shopOrder) throws Exception {
+        /**
+         * 获取一下店铺的所有静态参数
+         */
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        SdkClient sdkClient = new SdkClient(shopAccount.getDangAppKey(),shopAccount.getDangAppSecret(),shopAccount.getDangSession(),shopAccount.getDangVersion());
+
+        OrderDetailsGetRequest ss = new OrderDetailsGetRequest();
+        OrderDetailsGet orderDetailsGet = new OrderDetailsGet();
+        orderDetailsGet.setO(shopOrder.getDangOrder());
+        ss.setOrderDetailsGet(orderDetailsGet);
+        OrderDetailsGetResponse resultt = null;
+        try {
+            resultt = sdkClient.excute(ss);
+        } catch (ApiException e) {
+            e.printStackTrace();
+
+        }
+
+        /**
+         * 从当当获取订单内应当有的所有图书
+         */
+        OrderDetailsGetRequest odgr = new OrderDetailsGetRequest();
+        OrderDetailsGet ogg = new OrderDetailsGet();
+        ogg.setO(shopOrder.getDangOrder());
+        odgr.setOrderDetailsGet(ogg);
+        OrderDetailsGetResponse odgrp = null;
+        try {
+            odgrp = sdkClient.excute(odgr);
+        } catch (ApiException e) {
+            e.printStackTrace();
+        }
+        SdkClient jiemi = new SdkClient(shopAccount.getDangAppKey(),shopAccount.getDangAppSecret(),shopAccount.getDangSession(),shopAccount.getDangVersion());
+        OrdersContentDecryptRequest ordersContentDecryptRequest=new OrdersContentDecryptRequest();
+
+        List<EncryptDTO> encryptVOS = new ArrayList<EncryptDTO>();
+
+        EncryptDTO encryptVO1 = new EncryptDTO();
+        encryptVO1.setO(resultt.getOrderID().toString());
+        encryptVO1.setEncrypt_content(resultt.getEncrypt_content());
+        encryptVOS.add(encryptVO1);
+
+        ordersContentDecryptRequest.setO_cryptStr(JSON.toJSONString(encryptVOS));
+        OrdersContentDecryptResponse ordersContentDecryptResponse = null;
+        try {
+            ordersContentDecryptResponse=jiemi.excute(ordersContentDecryptRequest);
+        } catch (ApiException e) {
+            e.printStackTrace();
+        }
+        List<OrdersContentDecryptDTO> data = ordersContentDecryptResponse.getData();
+        CryptUserInfo cryptUserInfo = data.get(0).getCryptUserInfo();
+
+
+
+        OrderDetail o = (OrderDetail) XMLUtil.convertXmlStrToObject(OrderDetail.class, odgrp.getBody());
+        SendGoodsInfo sgi = new SendGoodsInfo();
+        sgi.setConsigneeAddr(cryptUserInfo.getConsigneeAddr());
+        sgi.setConsigneeMobileTel(cryptUserInfo.getConsigneeMobileTel());
+        sgi.setConsigneeTel(cryptUserInfo.getConsigneeTel());
+        sgi.setConsigneeName(cryptUserInfo.getConsigneeName());
+        o.setSendGoodsInfo(sgi);
+        List<com.iotechn.unimall.data.dto.shop.XmlObject.ItemInfo> itemInfo = o.getItemsList().getItemInfo();
+        /**
+         * 将多个图书拼接XML
+         */
+        String itemsStr = "";
+        for (com.iotechn.unimall.data.dto.shop.XmlObject.ItemInfo ii : itemInfo) {
+            Map<String, Object> hashMap = new HashMap<>();
+            hashMap.put("DANG_DANG_ITEM_ID", ii.getItemID());
+            hashMap.put("SHU_LIANG", ii.getOrderCount());
+            hashMap.put("PRODUCT_ID", ii.getProductItemId());
+            itemsStr += SendGood.processTemplate(SendGood.ONE_ITEM, hashMap);
+        }
+
+
+        /**
+         * 组成OrderInfo
+         */
+        Wrapper wrapper = new EntityWrapper();
+        wrapper.like("fuzi_name",shopOrder.getShippingComName());
+        List<ShopTran> list = shopTranMapper.selectList(wrapper);
+        if(list.size() == 0 ){
+            throw new Exception("物流公司不存在");
+        }
+        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+        stringObjectHashMap.put("DANG_DANG_ORDER", shopOrder.getDangOrder());
+        stringObjectHashMap.put("KUAI_DI_GONG_SI", list.get(0).getName());
+        stringObjectHashMap.put("KUAI_DI_BIANMA", list.get(0).getCode1());
+        stringObjectHashMap.put("KUAI_DI_GONG_SI_DIAN_HUA", list.get(0).getPhone());
+        stringObjectHashMap.put("KUAI_DI_DAN_HAO", shopOrder.getShipmentNum());
+        stringObjectHashMap.put("SEND_ITEMS", itemsStr);
+
+        String orderListStr = SendGood.processTemplate(SendGood.ONE_ORDER, stringObjectHashMap);
+        HashMap<String, Object> tmplHash = new HashMap<>();
+        tmplHash.put("SEND_TIME", dateFormat.format(new Date()));
+        tmplHash.put("ORDER_LIST", orderListStr);
+
+        String xmlFileStr = SendGood.processTemplate(SendGood.TMPL, tmplHash);
+        System.out.println(xmlFileStr);
+        PrintWriter out = null;
+        try {
+            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("sendGoodNotPlat.xml"), "GBK")));
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        out.write(xmlFileStr);
+        out.close();
+        System.out.println("XML文件创建成功!");
+
+
+        /**
+         * 发货!!
+         */
+        OrderGoodsSendRequest sendGoodsRequest = new OrderGoodsSendRequest();
+        sendGoodsRequest.setSendGoodsFile(new FileItem(new File("sendGoodNotPlat.xml")));
+        OrderGoodsSendResponse result = null;
+        try {
+            result = sdkClient.excute(sendGoodsRequest);
+        } catch (ApiException e) {
+            e.printStackTrace();
+        }
+        System.out.println(result.toString());
+        if(result.getResult().getOrdersList().get(0).getOrderOperCode() == 0){
+            shopOrder.setDangOrderStatus("已发货");
+            shopOrderMapper.update(shopOrder,new EntityWrapper<ShopOrder>().eq("order_id",shopOrder.getOrderId()));
+        }
+    }
+    /**
+     * Unicode转 汉字字符串
+     *
+     * @param str
+     *            \u6728
+     * @return '木' 26408
+     */
+    public static String unicodeToString(String str) {
+
+        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
+        Matcher matcher = pattern.matcher(str);
+        char ch;
+        while (matcher.find()) {
+            // group 6728
+            String group = matcher.group(2);
+            // ch:'木' 26408
+            ch = (char) Integer.parseInt(group, 16);
+            // group1 \u6728
+            String group1 = matcher.group(1);
+            str = str.replace(group1, ch + "");
+        }
+        return str;
+    }
+}

+ 138 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/shop/impl/ShopTranServiceImpl.java

@@ -0,0 +1,138 @@
+package com.iotechn.unimall.admin.api.shop.impl;
+
+import java.util.List;
+
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.util.ExcelUtil;
+import com.iotechn.unimall.data.mapper.shop.ShopTranMapper;
+import com.iotechn.unimall.data.domain.shop.ShopTran;
+import com.iotechn.unimall.admin.api.shop.IShopTranService;
+import com.iotechn.unimall.data.model.Page;
+import java.util.Date;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 物流公司Service业务层处理
+ * 
+ * @author jlb
+ * @date 2022-05-29
+ */
+@Service
+public class ShopTranServiceImpl implements IShopTranService{
+	@Autowired
+	private ShopTranMapper shopTranMapper;
+	
+	@Override
+	public Boolean add(ShopTran shopTran,Long adminId) throws ServiceException {
+		Date now = new Date();
+		shopTran.setGmtCreate(now);
+		shopTran.setGmtUpdate(now);
+		shopTran.setAdminId(adminId);
+		return shopTranMapper.insert(shopTran)>0;
+	}
+
+	@Override
+	public Page<ShopTran> list(String name,String code1,String code2,String phone,Integer deleteFlag,Date gmtCreate,Date gmtUpdate,Long userId,Long adminId, Integer page, Integer limit)throws ServiceException {
+		Wrapper<ShopTran> wrapper = new EntityWrapper<ShopTran>();
+														if (!StringUtils.isEmpty(name)) {
+					wrapper.eq("name", name);
+				}
+												if (!StringUtils.isEmpty(code1)) {
+					wrapper.eq("code1", code1);
+				}
+												if (!StringUtils.isEmpty(code2)) {
+					wrapper.eq("code2", code2);
+				}
+												if (!StringUtils.isEmpty(phone)) {
+					wrapper.eq("phone", phone);
+				}
+																	if (!StringUtils.isEmpty(deleteFlag)) {
+					wrapper.eq("delete_flag", deleteFlag);
+				}
+												if (!StringUtils.isEmpty(gmtCreate)) {
+					wrapper.eq("gmt_create", gmtCreate);
+				}
+												if (!StringUtils.isEmpty(gmtUpdate)) {
+					wrapper.eq("gmt_update", gmtUpdate);
+				}
+												if (!StringUtils.isEmpty(userId)) {
+					wrapper.eq("user_id", userId);
+				}
+												if (!StringUtils.isEmpty(adminId)) {
+					wrapper.eq("admin_id", adminId);
+				}
+							wrapper.eq("delete_flag", 0);
+		List<ShopTran> list = shopTranMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+		Integer count = shopTranMapper.selectCount(wrapper);
+		return new Page<ShopTran>(list, page, limit, count);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public Boolean delete(Long id) {
+		String[] ids = String.valueOf(id).split(",");
+		for (String tt:ids) {
+			ShopTran tmp =  shopTranMapper.selectById(Long.parseLong(tt));
+			if(tmp != null){
+				tmp.setDeleteFlag(1);
+				shopTranMapper.updateById(tmp);
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public Boolean update(ShopTran shopTran,Long adminId) throws ServiceException {
+		Date now = new Date();
+		shopTran.setGmtUpdate(now);
+		shopTran.setAdminId(adminId);
+		return shopTranMapper.updateById(shopTran)>0;
+	}
+
+	@Override
+	public ShopTran get(Long id) throws ServiceException {
+		return shopTranMapper.selectById(id);
+	}
+	
+	@Override
+	public String export(String name,String code1,String code2,String phone,Integer deleteFlag,Date gmtCreate,Date gmtUpdate,Long userId,Long adminId, Integer page, Integer limit)throws ServiceException {
+		Wrapper<ShopTran> wrapper = new EntityWrapper<ShopTran>();
+														if (!StringUtils.isEmpty(name)) {
+					wrapper.eq("name", name);
+				}
+												if (!StringUtils.isEmpty(code1)) {
+					wrapper.eq("code1", code1);
+				}
+												if (!StringUtils.isEmpty(code2)) {
+					wrapper.eq("code2", code2);
+				}
+												if (!StringUtils.isEmpty(phone)) {
+					wrapper.eq("phone", phone);
+				}
+																	if (!StringUtils.isEmpty(deleteFlag)) {
+					wrapper.eq("delete_flag", deleteFlag);
+				}
+												if (!StringUtils.isEmpty(gmtCreate)) {
+					wrapper.eq("gmt_create", gmtCreate);
+				}
+												if (!StringUtils.isEmpty(gmtUpdate)) {
+					wrapper.eq("gmt_update", gmtUpdate);
+				}
+												if (!StringUtils.isEmpty(userId)) {
+					wrapper.eq("user_id", userId);
+				}
+												if (!StringUtils.isEmpty(adminId)) {
+					wrapper.eq("admin_id", adminId);
+				}
+							List<ShopTran> list = shopTranMapper.selectList(wrapper);
+		ExcelUtil<ShopTran> util = new ExcelUtil<ShopTran>(ShopTran.class);
+		return util.exportExcel(list, "操作日志");
+	}
+}

+ 74 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/tools/gen/GenTableService.java

@@ -0,0 +1,74 @@
+package com.iotechn.unimall.admin.api.tools.gen;
+
+import java.util.List;
+
+import com.alibaba.fastjson.JSONObject;
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.tools.gen.GenTable;
+import com.iotechn.unimall.data.domain.tools.gen.GenTableColumn;
+import com.iotechn.unimall.data.model.Page;
+
+/**
+ * 
+ * @author dyl
+ *
+ */
+@HttpOpenApi(group = "admin.tools.gen", description = "代码生成")
+public interface GenTableService {
+	@HttpMethod(description = "代码生成列表", permission = "admin:tools:gen:list", permissionParentName = "系统工具", permissionName = "代码生成")
+	public Page<GenTable> list(
+			@HttpParam(name = "tableName", type = HttpParamType.COMMON, description = "表名称") String tableName,
+			@HttpParam(name = "tableComment", type = HttpParamType.COMMON, description = "表描述") String tableComment,
+			@HttpParam(name = "beginTime", type = HttpParamType.COMMON, description = "开始时间") String beginTime,
+			@HttpParam(name = "endTime", type = HttpParamType.COMMON, description = "结束时间") String endTime,
+			@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+			@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+			throws ServiceException;
+
+	@HttpMethod(description = "数据表列表", permission = "admin:tools:gen:dbList", permissionParentName = "系统工具", permissionName = "代码生成")
+	public Page<GenTable> getDbList(
+			@HttpParam(name = "tableName", type = HttpParamType.COMMON, description = "表名称") String tableName,
+			@HttpParam(name = "tableComment", type = HttpParamType.COMMON, description = "表描述") String tableComment,
+			@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+			@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+			throws ServiceException;
+
+	@HttpMethod(description = "查询数据表详情", permission = "admin:tools:gen:get", permissionParentName = "系统工具", permissionName = "代码生成")
+	public JSONObject get(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "表ID") String id)
+			throws ServiceException;
+
+	@HttpMethod(description = "查询数据表字段详情", permission = "admin:tools:genTable:getColumn", permissionParentName = "系统工具", permissionName = "代码生成")
+	public List<GenTableColumn> getColumn(
+			@HttpParam(name = "talbleId", type = HttpParamType.COMMON, description = "表ID") String talbleId)
+			throws ServiceException;
+
+	@HttpMethod(description = "导入表结构", permission = "admin:tools:gen:import", permissionParentName = "系统工具", permissionName = "代码生成")
+	public Boolean importTableSave(
+			@HttpParam(name = "tables", type = HttpParamType.COMMON, description = "表名") String tables)
+			throws ServiceException;
+
+	@HttpMethod(description = "修改表生成信息", permission = "admin:tools:gen:update", permissionParentName = "系统工具", permissionName = "代码生成")
+	public Boolean update(
+			@NotNull @HttpParam(name = "genTable", type = HttpParamType.COMMON, description = "表信息") GenTable genTable)
+			throws ServiceException;
+
+	@HttpMethod(description = "修改表字段生成信息", permission = "admin:tools:gen:updateColumn", permissionParentName = "系统工具", permissionName = "代码生成")
+	public Boolean updateColumn(
+			@NotNull @HttpParam(name = "genTableColumn", type = HttpParamType.COMMON, description = "表字段信息") GenTableColumn genTableColumn)
+			throws ServiceException;
+
+	@HttpMethod(description = "删除", permission = "admin:tools:gen:delete", permissionParentName = "系统工具", permissionName = "代码生成")
+	public Boolean delete(
+			@NotNull @HttpParam(name = "tableIds", type = HttpParamType.COMMON, description = "表Id") String tableIds)
+			throws ServiceException;
+
+	@HttpMethod(description = "代码预览", permission = "admin:tools:gen:preview", permissionParentName = "系统工具", permissionName = "代码生成")
+	public JSONObject preview(
+			@NotNull @HttpParam(name = "tableId", type = HttpParamType.COMMON, description = "表Id") String tableId)
+			throws ServiceException;
+}

+ 179 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/tools/gen/GenTableServiceImpl.java

@@ -0,0 +1,179 @@
+package com.iotechn.unimall.admin.api.tools.gen;
+
+import java.io.StringWriter;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ibatis.session.RowBounds;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.core.util.StringUtils;
+import com.iotechn.unimall.data.domain.tools.gen.GenTable;
+import com.iotechn.unimall.data.domain.tools.gen.GenTableColumn;
+import com.iotechn.unimall.data.mapper.tools.gen.GenTableColumnMapper;
+import com.iotechn.unimall.data.mapper.tools.gen.GenTableMapper;
+import com.iotechn.unimall.data.model.Page;
+import com.iotechn.unimall.data.util.GenUtils;
+import com.iotechn.unimall.data.util.SessionUtil;
+import com.iotechn.unimall.data.util.VelocityInitializer;
+import com.iotechn.unimall.data.util.VelocityUtils;
+
+/**
+ * 
+ * @author dyl
+ *
+ */
+@Service
+public class GenTableServiceImpl implements GenTableService {
+
+	@Autowired
+	private GenTableMapper tableMapper;
+
+	@Autowired
+	private GenTableColumnMapper tableColumnMapper;
+
+	@Override
+	public Page<GenTable> list(String tableName, String tableComment, String beginTime, String endTime, Integer page,
+			Integer limit) throws ServiceException {
+		Wrapper<GenTable> wrapper = new EntityWrapper<GenTable>();
+		if (!StringUtils.isEmpty(tableName)) {
+			wrapper.eq("table_name", tableName);
+		}
+		if (!StringUtils.isEmpty(tableComment)) {
+			wrapper.like("table_comment", tableComment);
+		}
+		if (!StringUtils.isEmpty(beginTime) && !StringUtils.isEmpty(endTime)) {
+			wrapper.between("create_time", beginTime, endTime);
+		}
+		List<GenTable> GenTableS = tableMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+		Integer count = tableMapper.selectCount(wrapper);
+		return new Page<GenTable>(GenTableS, page, limit, count);
+	}
+
+	@Override
+	public Page<GenTable> getDbList(String tableName, String tableComment, Integer page, Integer limit)
+			throws ServiceException {
+		GenTable genTable = new GenTable();
+		genTable.setTableName(tableName);
+		genTable.setTableComment(tableComment);
+		List<GenTable> GenTableS = tableMapper.selectDbTableList(new RowBounds((page - 1) * limit, limit), genTable);
+		Integer count = tableMapper.selectDbTableCount(genTable);
+		return new Page<GenTable>(GenTableS, page, limit, count);
+	}
+
+	@Override
+	public JSONObject get(String id) throws ServiceException {
+		JSONObject result = new JSONObject();
+		Wrapper<GenTableColumn> wrapper = new EntityWrapper<GenTableColumn>();
+		wrapper.eq("table_id", id);
+
+		GenTable table = tableMapper.selectById(id);
+		List<GenTableColumn> list = tableColumnMapper.selectList(wrapper);
+
+		result.put("info", table);
+		result.put("rows", list);
+		return result;
+	}
+
+	@Override
+	public List<GenTableColumn> getColumn(String talbleId) throws ServiceException {
+		Wrapper<GenTableColumn> wrapper = new EntityWrapper<GenTableColumn>();
+		wrapper.eq("table_id", talbleId);
+		List<GenTableColumn> list = tableColumnMapper.selectList(wrapper);
+		return list;
+	}
+
+	@Override
+	public Boolean importTableSave(String tables) throws ServiceException {
+		String[] ids = tables.split(",");
+		List<GenTable> tableList = tableMapper.selectDbTableListByNames(ids);
+		String operName = SessionUtil.getAdmin().getUsername();
+		for (GenTable table : tableList) {
+			try {
+				String tableName = table.getTableName();
+				GenUtils.initTable(table, operName);
+				int row = tableMapper.insert(table);
+				if (row > 0) {
+					// 保存列信息
+					List<GenTableColumn> genTableColumns = tableColumnMapper.selectDbTableColumnsByName(tableName);
+					for (GenTableColumn column : genTableColumns) {
+						GenUtils.initColumnField(column, table);
+						tableColumnMapper.insert(column);
+					}
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new AdminServiceException(ExceptionDefinition.TABLE_IMPORT_ERROR);
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public Boolean update(GenTable genTable) throws ServiceException {
+		return tableMapper.updateById(genTable) > 0;
+	}
+
+	@Override
+	public Boolean updateColumn(GenTableColumn genTableColumn) throws ServiceException {
+		return tableColumnMapper.updateById(genTableColumn) > 0;
+	}
+
+	@Override
+	public Boolean delete(String tableIds) throws ServiceException {
+		String[] ids = tableIds.split(",");
+		Wrapper<GenTable> wrapper = new EntityWrapper<GenTable>();
+		wrapper.in("table_id", ids);
+		return tableMapper.delete(wrapper) > 0;
+	}
+
+	@Override
+	public JSONObject preview(String tableId) throws ServiceException {
+		Map<String, String> dataMap = new LinkedHashMap<>();
+		// 查询表信息
+		GenTable table = tableMapper.selectById(tableId);
+		Wrapper<GenTableColumn> wrapper = new EntityWrapper<GenTableColumn>();
+		wrapper.eq("table_id", table.getTableId());
+		// 查询列信息
+		List<GenTableColumn> columns =tableColumnMapper.selectList(wrapper);
+		table.setColumns(columns);
+		setPkColumn(table, columns);
+		VelocityInitializer.initVelocity();
+
+		VelocityContext context = VelocityUtils.prepareContext(table);
+
+		// 获取模板列表
+		List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
+		for (String template : templates) {
+			// 渲染模板
+			StringWriter sw = new StringWriter();
+			Template tpl = Velocity.getTemplate(template, "UTF-8");
+			tpl.merge(context, sw);
+			dataMap.put(template, sw.toString());
+		}
+		return JSONObject.parseObject(JSONObject.toJSONString(dataMap));
+	}
+
+	public void setPkColumn(GenTable table, List<GenTableColumn> columns) {
+		for (GenTableColumn column : columns) {
+			if (column.isPk()) {
+				table.setPkColumn(column);
+				break;
+			}
+		}
+		if (StringUtils.isNull(table.getPkColumn())) {
+			table.setPkColumn(columns.get(0));
+		}
+	}
+}

+ 62 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/user/AdminUserService.java

@@ -0,0 +1,62 @@
+package com.iotechn.unimall.admin.api.user;
+
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.annotation.param.Range;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.UserDO;
+import com.iotechn.unimall.data.model.Page;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-11
+ * Time: 下午7:30
+ */
+
+@HttpOpenApi(group = "admin.user", description = "用户管理")
+public interface AdminUserService {
+
+    @HttpMethod(description = "创建", permission = "system:user:create", permissionParentName = "系统管理", permissionName = "用户管理")
+    public Boolean addUser(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "user", type = HttpParamType.COMMON, description = "用户信息") UserDO user) throws ServiceException;
+
+    @HttpMethod(description = "删除", permission = "system:user:delete", permissionParentName = "系统管理", permissionName = "用户管理")
+    public Boolean deleteUser(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "用户Id") Long id,
+            @NotNull @HttpParam(name = "nickname", type = HttpParamType.COMMON, description = "用户Id") String nickname) throws ServiceException;
+
+    @HttpMethod(description = "修改", permission = "system:user:update", permissionParentName = "系统管理", permissionName = "用户管理")
+    public Boolean updateUser(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "user", type = HttpParamType.COMMON, description = "用户信息") UserDO user) throws ServiceException;
+
+    @HttpMethod(description = "激活冻结", permission = "system:user:update", permissionParentName = "系统管理", permissionName = "用户管理")
+    public Boolean updateStatus(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @NotNull @HttpParam(name = "userId", type = HttpParamType.COMMON, description = "用户信息") Long userId,
+            @NotNull @HttpParam(name = "status", type = HttpParamType.COMMON, description = "用户信息") Integer status) throws ServiceException;
+
+
+    @HttpMethod(description = "查询", permission = "system:user:query", permissionParentName = "系统管理", permissionName = "用户管理")
+    public Page<UserDO> getUser(
+            @NotNull @HttpParam(name = "adminId", type = HttpParamType.ADMIN_ID, description = "管理员ID") Long adminId,
+            @HttpParam(name = "id", type = HttpParamType.COMMON, description = "用户ID") Long id,
+            @HttpParam(name = "nickname", type = HttpParamType.COMMON, description = "用户昵称") String nickname,
+            @HttpParam(name = "level", type = HttpParamType.COMMON, description = "用户等级") Integer level,
+            @HttpParam(name = "gender", type = HttpParamType.COMMON, description = "用户性别") Integer gender,
+            @HttpParam(name = "status", type = HttpParamType.COMMON, description = "用户状态") Integer status,
+            @Range(min = 1) @HttpParam(name = "pageNo", type = HttpParamType.COMMON, description = "当前页码") Integer pageNo,
+            @Range(min = 1) @HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度") Integer limit) throws ServiceException;
+    @HttpMethod(description = "测试")
+    public String test(
+            @HttpParam(name = "param", type = HttpParamType.COMMON, description = "参数") String nickname,
+            @HttpParam(name = "param1", type = HttpParamType.COMMON, description = "参数") String nickname1) throws Exception;
+
+}

+ 686 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/user/AdminUserServiceImpl.java

@@ -0,0 +1,686 @@
+package com.iotechn.unimall.admin.api.user;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.dangdang.openplatform.openapi.sdk.ApiException;
+import com.dangdang.openplatform.openapi.sdk.SdkClient;
+import com.dangdang.openplatform.openapi.sdk.internal.util.FileItem;
+import com.dangdang.openplatform.openapi.sdk.request.order.OrderDetailsGetRequest;
+import com.dangdang.openplatform.openapi.sdk.request.order.OrderGoodsSendRequest;
+import com.dangdang.openplatform.openapi.sdk.request.order.OrdersContentDecryptRequest;
+import com.dangdang.openplatform.openapi.sdk.requestmodel.order.EncryptDTO;
+import com.dangdang.openplatform.openapi.sdk.requestmodel.order.OrderDetailsGet;
+import com.dangdang.openplatform.openapi.sdk.response.order.OrderDetailsGetResponse;
+import com.dangdang.openplatform.openapi.sdk.response.order.OrderGoodsSendResponse;
+import com.dangdang.openplatform.openapi.sdk.response.order.OrdersContentDecryptResponse;
+import com.dangdang.openplatform.openapi.sdk.responsemodel.order.CryptUserInfo;
+import com.dangdang.openplatform.openapi.sdk.responsemodel.order.OrdersContentDecryptDTO;
+import com.iotechn.unimall.admin.AdminCheckQuartz;
+import com.iotechn.unimall.data.domain.shop.ShopAccount;
+import com.iotechn.unimall.data.domain.shop.ShopLog;
+import com.iotechn.unimall.data.domain.shop.ShopOrder;
+import com.iotechn.unimall.data.domain.shop.ShopTran;
+import com.iotechn.unimall.data.dto.shop.XmlObject.OrderDetail;
+import com.iotechn.unimall.data.dto.shop.XmlObject.SendGood;
+import com.iotechn.unimall.data.dto.shop.XmlObject.SendGoodsInfo;
+import com.iotechn.unimall.data.mapper.shop.ShopAccountMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopLogMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopOrderMapper;
+import com.iotechn.unimall.data.mapper.shop.ShopTranMapper;
+import com.iotechn.unimall.data.util.XMLUtil;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.iotechn.unimall.core.exception.AdminServiceException;
+import com.iotechn.unimall.core.exception.ExceptionDefinition;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.domain.UserDO;
+import com.iotechn.unimall.data.dto.shop.FuziDTO;
+import com.iotechn.unimall.data.mapper.UserMapper;
+import com.iotechn.unimall.data.model.Page;
+import okhttp3.*;
+import org.apache.commons.codec.digest.Md5Crypt;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.io.*;
+import java.net.CookieStore;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created with IntelliJ IDEA.
+ * Description:
+ * User: kbq
+ * Date: 2019-07-11
+ * Time: 下午7:57
+ */
+@Service
+public class AdminUserServiceImpl implements AdminUserService {
+
+    @Autowired
+    private UserMapper userMapper;
+
+    @Autowired
+    private ShopAccountMapper shopAccountMapper;
+
+    @Autowired
+    private ShopLogMapper shopLogMapper;
+    @Autowired
+    private ShopOrderMapper shopOrderMapper;
+    @Autowired
+    private ShopTranMapper shopTranMapper;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean addUser(Long adminId, UserDO user) throws ServiceException {
+        if (user == null) {
+            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
+        }
+        if (user.getPhone() == null) {
+            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
+        }
+        if (userMapper.selectCount(new EntityWrapper<UserDO>().eq("phone", user.getPhone())) > 0) {
+            throw new AdminServiceException(ExceptionDefinition.USER_PHONE_ALREADY_EXIST);
+        }
+        Date now = new Date();
+        user.setId(null);
+        user.setPassword(Md5Crypt.md5Crypt(user.getPassword().getBytes(), "$1$" + user.getPhone().substring(0, 7)));
+        user.setGmtCreate(now);
+        user.setGmtUpdate(now);
+        return userMapper.insert(user) > 0;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean deleteUser(Long adminId, Long id, String nickname) throws ServiceException {
+        return userMapper.delete(new EntityWrapper<UserDO>()
+                .eq("id", id)
+                .eq("nickname", nickname)) > 0;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean updateUser(Long adminId, UserDO user) throws ServiceException {
+        if (user == null || user.getId() == null) {
+            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
+        }
+        if (user.getPhone() == null) {
+            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
+        }
+        if (userMapper.selectCount(new EntityWrapper<UserDO>().eq("phone", user.getPhone()).notIn("id", user.getId())) > 0) {
+            throw new AdminServiceException(ExceptionDefinition.USER_PHONE_ALREADY_EXIST);
+        }
+        Date now = new Date();
+        user.setGmtUpdate(now);
+        UserDO userDO = userMapper.selectById(user.getId());
+        if (userDO.getPassword().equals(user.getPassword())) {
+            return userMapper.updateById(user) > 0;
+        }
+        if (user.getPassword() != null) {
+            user.setPassword(Md5Crypt.md5Crypt(user.getPassword().getBytes(), "$1$" + user.getPhone().substring(0, 7)));
+        }
+        return userMapper.updateById(user) > 0;
+    }
+
+    @Override
+    public Boolean updateStatus(Long adminId, Long userId, Integer status) throws ServiceException {
+        if (userId == null || status == null || (status != 0 && status != 1)) {
+            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
+        }
+        UserDO userDO = new UserDO();
+        userDO.setId(userId);
+        userDO.setStatus(status);
+        userDO.setGmtUpdate(new Date());
+        if (userMapper.updateById(userDO) > 0) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Page<UserDO> getUser(Long adminId, Long id, String nickname, Integer level, Integer gender, Integer status, Integer pageNo, Integer limit) throws ServiceException {
+        Integer count = userMapper.countUser(id, nickname, level, gender, status);
+        List<UserDO> userDOList = userMapper.getUserList(id, nickname, level, gender, status, limit * (pageNo - 1), limit);
+        Page<UserDO> page = new Page<UserDO>(userDOList, pageNo, limit, count);
+        return page;
+    }
+
+    @Override
+    public String test(String param, String param1) throws Exception {
+        if(param.equals("1")){
+            new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    doSomething1();
+                }
+            }).start();
+        }
+        else{
+            new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    doSomething2();
+                }
+            }).start();
+        }
+
+//        try{
+//            List<ShopOrder> shopOrders = shopOrderMapper.selectList(new EntityWrapper<ShopOrder>()
+//                    .eq("dang_order_status","未发货")
+////                    .eq("account_id",param)
+//                    .eq("order_status_name","卖家已发货"));
+//            for (ShopOrder qqq:shopOrders
+//            ) {
+//                ShopAccount shopAccount = shopAccountMapper.selectById(qqq.getAccountId());
+//                dangOrderDeal(shopAccount,qqq);
+//            }
+//        }
+//        catch (Exception e) {
+//            ShopLog shopLog = new ShopLog();
+//            shopLog.setGmtCreate(new Date());
+//            shopLog.setTitle("同步定时任务异常");
+//            shopLog.setContent(e.getMessage());
+//            shopLogMapper.insert(shopLog);
+//            e.printStackTrace();
+//        }
+        return "";
+
+    }
+
+    public void dangOrderDeal(ShopAccount shopAccount, ShopOrder shopOrder) throws Exception {
+        try {
+            /**
+             * 获取一下店铺的所有静态参数
+             */
+            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+            SdkClient sdkClient = new SdkClient(shopAccount.getDangAppKey(), shopAccount.getDangAppSecret(), shopAccount.getDangSession(), shopAccount.getDangVersion());
+
+            OrderDetailsGetRequest ss = new OrderDetailsGetRequest();
+            OrderDetailsGet orderDetailsGet = new OrderDetailsGet();
+            orderDetailsGet.setO(shopOrder.getDangOrder());
+            ss.setOrderDetailsGet(orderDetailsGet);
+            OrderDetailsGetResponse resultt = null;
+            try {
+                resultt = sdkClient.excute(ss);
+                if (resultt.getOrderID() == null) {
+                    shopOrder.setDangOrderStatus("订单错误");
+                    shopOrderMapper.updateById(shopOrder);
+                    ShopLog shopLog = new ShopLog();
+                    shopLog.setGmtCreate(new Date());
+                    shopLog.setTitle("当当订单编号错误");
+                    shopLog.setContent("店铺:" + shopAccount.getDangName() + ",孔网订单:" + shopOrder.getOrderId() + ",当当订单:" + shopOrder.getDangOrder());
+                    shopLogMapper.insert(shopLog);
+                    return;
+                }
+            } catch (ApiException e) {
+                throw e;
+            }
+
+            /**
+             * 从当当获取订单内应当有的所有图书
+             */
+            OrderDetailsGetRequest odgr = new OrderDetailsGetRequest();
+            OrderDetailsGet ogg = new OrderDetailsGet();
+            ogg.setO(shopOrder.getDangOrder());
+            odgr.setOrderDetailsGet(ogg);
+            OrderDetailsGetResponse odgrp = null;
+            try {
+                odgrp = sdkClient.excute(odgr);
+            } catch (ApiException e) {
+                throw e;
+            }
+            SdkClient jiemi = new SdkClient(shopAccount.getDangAppKey(), shopAccount.getDangAppSecret(), shopAccount.getDangSession(), shopAccount.getDangVersion());
+            OrdersContentDecryptRequest ordersContentDecryptRequest = new OrdersContentDecryptRequest();
+
+            List<EncryptDTO> encryptVOS = new ArrayList<EncryptDTO>();
+
+            EncryptDTO encryptVO1 = new EncryptDTO();
+            encryptVO1.setO(resultt.getOrderID().toString());
+            encryptVO1.setEncrypt_content(resultt.getEncrypt_content());
+            encryptVOS.add(encryptVO1);
+
+            ordersContentDecryptRequest.setO_cryptStr(JSON.toJSONString(encryptVOS));
+            OrdersContentDecryptResponse ordersContentDecryptResponse = null;
+            try {
+                ordersContentDecryptResponse = jiemi.excute(ordersContentDecryptRequest);
+            } catch (ApiException e) {
+                throw e;
+            }
+            List<OrdersContentDecryptDTO> data = ordersContentDecryptResponse.getData();
+            CryptUserInfo cryptUserInfo = data.get(0).getCryptUserInfo();
+
+
+            OrderDetail o = (OrderDetail) XMLUtil.convertXmlStrToObject(OrderDetail.class, odgrp.getBody());
+            SendGoodsInfo sgi = new SendGoodsInfo();
+            sgi.setConsigneeAddr(cryptUserInfo.getConsigneeAddr());
+            sgi.setConsigneeMobileTel(cryptUserInfo.getConsigneeMobileTel());
+            sgi.setConsigneeTel(cryptUserInfo.getConsigneeTel());
+            sgi.setConsigneeName(cryptUserInfo.getConsigneeName());
+            o.setSendGoodsInfo(sgi);
+            List<com.iotechn.unimall.data.dto.shop.XmlObject.ItemInfo> itemInfo = o.getItemsList().getItemInfo();
+            /**
+             * 将多个图书拼接XML
+             */
+            String itemsStr = "";
+            for (com.iotechn.unimall.data.dto.shop.XmlObject.ItemInfo ii : itemInfo) {
+                Map<String, Object> hashMap = new HashMap<>();
+                hashMap.put("DANG_DANG_ITEM_ID", ii.getItemID());
+                hashMap.put("SHU_LIANG", ii.getOrderCount());
+                hashMap.put("PRODUCT_ID", ii.getProductItemId());
+                itemsStr += SendGood.processTemplate(SendGood.ONE_ITEM, hashMap);
+            }
+
+
+            /**
+             * 组成OrderInfo
+             */
+            Wrapper wrapper = new EntityWrapper();
+            wrapper.like("fuzi_name", shopOrder.getShippingComName());
+            wrapper.eq("delete_flag", 0);
+            List<ShopTran> list = shopTranMapper.selectList(wrapper);
+            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
+            stringObjectHashMap.put("DANG_DANG_ORDER", shopOrder.getDangOrder());
+            if (list.size() == 0) {
+//                throw new Exception("物流公司不存在");
+                System.out.println("物流公司不存在");
+                stringObjectHashMap.put("KUAI_DI_GONG_SI", "99999");
+                stringObjectHashMap.put("KUAI_DI_BIANMA", "99999");
+                stringObjectHashMap.put("KUAI_DI_GONG_SI_DIAN_HUA", "99999");
+            } else {
+                stringObjectHashMap.put("KUAI_DI_GONG_SI", list.get(0).getName());
+                stringObjectHashMap.put("KUAI_DI_BIANMA", list.get(0).getCode1());
+                stringObjectHashMap.put("KUAI_DI_GONG_SI_DIAN_HUA", list.get(0).getPhone());
+            }
+            stringObjectHashMap.put("KUAI_DI_DAN_HAO", shopOrder.getShipmentNum());
+            stringObjectHashMap.put("SEND_ITEMS", itemsStr);
+
+            String orderListStr = SendGood.processTemplate(SendGood.ONE_ORDER, stringObjectHashMap);
+            HashMap<String, Object> tmplHash = new HashMap<>();
+            tmplHash.put("SEND_TIME", dateFormat.format(new Date()));
+            tmplHash.put("ORDER_LIST", orderListStr);
+
+            String xmlFileStr = SendGood.processTemplate(SendGood.TMPL, tmplHash);
+            System.out.println(xmlFileStr);
+            PrintWriter out = null;
+            try {
+                out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("sendGoodNotPlat.xml"), "GBK")));
+            } catch (Exception e) {
+                throw e;
+            }
+            out.write(xmlFileStr);
+            out.close();
+            System.out.println("XML文件创建成功!");
+
+
+            /**
+             * 发货!!
+             */
+            OrderGoodsSendRequest sendGoodsRequest = new OrderGoodsSendRequest();
+            sendGoodsRequest.setSendGoodsFile(new FileItem(new File("sendGoodNotPlat.xml")));
+            OrderGoodsSendResponse result = null;
+            try {
+                result = sdkClient.excute(sendGoodsRequest);
+            } catch (ApiException e) {
+                throw e;
+            }
+            System.out.println(result.toString());
+            if (result.getResult().getOrdersList().get(0).getOrderOperCode() == 0 || result.getResult().getOrdersList().get(0).getOrderOperCode() == 605) {
+                ShopLog shopLog = new ShopLog();
+                shopLog.setGmtCreate(new Date());
+                shopLog.setTitle("当当订单发货成功");
+                shopLog.setContent("店铺:" + shopAccount.getDangName() + ",孔网订单:" + shopOrder.getOrderId() + ",当当订单:" + shopOrder.getDangOrder());
+                shopLogMapper.insert(shopLog);
+                shopOrder.setDangOrderStatus("已发货");
+                shopOrderMapper.update(shopOrder, new EntityWrapper<ShopOrder>().eq("order_id", shopOrder.getOrderId()));
+            } else {
+                ShopLog shopLog = new ShopLog();
+                shopLog.setGmtCreate(new Date());
+                shopLog.setTitle("当当订单发货失败");
+                shopLog.setContent("店铺:" + shopAccount.getDangName() + ",孔网订单:" + shopOrder.getOrderId() + ",当当订单:" + shopOrder.getDangOrder() + ",快递:" + shopOrder.getShippingComName());
+                shopLogMapper.insert(shopLog);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("当当发货异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+        }
+
+    }
+
+    public void flushCookie(ShopAccount shopAccount) {
+        try {
+            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+            HttpGet getMethod = new HttpGet("https://shop.kongfz.com/buyer/order/index/?pageCurr=1&pageShow=30");
+            getMethod.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+            getMethod.addHeader("cookie", shopAccount.getFuziCookie());
+
+            httpClient.execute(getMethod);
+            CloseableHttpResponse response = httpClient.execute(getMethod);//执行获取响应
+            try {
+                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//根据状态码处理
+                    String strTmp = EntityUtils.toString(response.getEntity(), "UTF-8");
+                    JSONObject datas = JSONObject.parseObject(strTmp);//转换成JSON格式
+                    Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                    if (status) {
+                        return;
+                    }
+                }
+            } catch (Exception e) {
+                throw e;
+            } finally {
+                response.close();
+                httpClient.close();
+            }
+
+            System.out.println("原cookies = " + shopAccount.getFuziCookie());
+
+            // 登陆 Url
+            String loginUrl = "https://login.kongfz.com/Pc/Login/account";
+            BasicCookieStore store = new BasicCookieStore();
+            httpClient = HttpClients.custom().setDefaultCookieStore(store).build();
+            // 模拟登陆,按实际服务器端要求选用 Post 或 Get 请求方式
+            HttpPost httpPost = new HttpPost(loginUrl);
+
+            // 装填参数
+            List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();
+            nvps.add(new BasicNameValuePair("loginName", shopAccount.getFuziAccount()));
+            nvps.add(new BasicNameValuePair("loginPass", shopAccount.getFuziPassword()));
+            // 设置参数到请求对象中
+            httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
+
+            // 设置header信息
+            // 指定报文头【Content-type】、【User-Agent】
+            httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
+
+            // 执行请求操作,并拿到结果(同步阻塞)
+            response = httpClient.execute(httpPost);
+            if (response.getStatusLine().getStatusCode() == 302) {
+                List<org.apache.http.cookie.Cookie> cookielist = store.getCookies();
+                String nCookie = "";
+                for (org.apache.http.cookie.Cookie cookie : cookielist) {
+                    String name = cookie.getName();
+                    String value = cookie.getValue();
+                    nCookie += name + "=" + value + ";";
+                }
+                System.out.println("nCookie:" + nCookie);
+                shopAccount.setFuziCookie(nCookie);
+                shopAccountMapper.updateById(shopAccount);
+                ShopLog shopLog = new ShopLog();
+                shopLog.setGmtCreate(new Date());
+                shopLog.setTitle("更新cookie成功");
+                shopLog.setContent("账号:" + shopAccount.getFuziAccount() + ",cookie:" + nCookie);
+                shopLogMapper.insert(shopLog);
+            } else {
+                ShopLog shopLog = new ShopLog();
+                shopLog.setGmtCreate(new Date());
+                shopLog.setTitle("更新cookie失败");
+                shopLog.setContent(response.toString());
+                shopLogMapper.insert(shopLog);
+            }
+            // 释放链接
+            response.close();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("更新cookie异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+        }
+
+    }
+
+
+    /**
+     * Unicode转 汉字字符串
+     *
+     * @param str \u6728
+     * @return '木' 26408
+     */
+    public static String unicodeToString(String str) {
+
+        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
+        Matcher matcher = pattern.matcher(str);
+        char ch;
+        while (matcher.find()) {
+            // group 6728
+            String group = matcher.group(2);
+            // ch:'木' 26408
+            ch = (char) Integer.parseInt(group, 16);
+            // group1 \u6728
+            String group1 = matcher.group(1);
+            str = str.replace(group1, ch + "");
+        }
+        return str;
+    }
+
+    public static Response postData(String url, Headers headers, RequestBody body) {
+        OkHttpClient client = new OkHttpClient().newBuilder()
+                .build();
+
+        Request request = new Request.Builder()
+                .url(url)
+                .method("POST", body)
+                .headers(headers)
+                .build();
+        Response response = null;
+        try {
+            response = client.newCall(request).execute();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return response;
+    }
+    private void doSomething1() {
+        try{
+            List<ShopAccount> list = shopAccountMapper.selectList(new EntityWrapper<>());
+            for (ShopAccount shopAccount:list
+            ) {
+                flushCookie(shopAccount);
+                List<ShopOrder> shopOrders = shopOrderMapper.selectList(new EntityWrapper<ShopOrder>()
+                        .eq("dang_order_status","未发货")
+                        .eq("account_id",shopAccount.getId())
+                        .eq("order_status_name","卖家已发货"));
+                for (ShopOrder qqq:shopOrders
+                ) {
+                    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+                    HttpGet get = new HttpGet("https://shop.kongfz.com/buyer/order/index/?pageCurr=1&pageShow=9999&orderId="+qqq.getOrderId());
+                    //这里可以设置请求参数,token等
+                    get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+                    get.addHeader("cookie",shopAccount.getFuziCookie());
+                    get.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
+                    CloseableHttpResponse response = httpClient.execute(get);//执行获取响应
+                    try{
+
+                        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){//根据状态码处理
+                            String strTmp= EntityUtils.toString(response.getEntity(),"UTF-8");
+                            //返回字符串
+                            String res = unicodeToString(strTmp);
+                            JSONObject datas = JSONObject.parseObject(res);//转换成JSON格式
+                            Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                            List<ShopOrder> data = JSONArray.parseArray(datas.get("data").toString(),ShopOrder.class);//"data"是根据返回值设定
+                            for (ShopOrder tmp: data
+                            ) {
+                                //正则表达式,用于匹配非数字串,+号用于匹配出多个非数字串
+                                String regEx="[^0-9]+";
+                                Pattern pattern = Pattern.compile(regEx);
+                                //用定义好的正则表达式拆分字符串,把字符串中的数字留出来
+                                String[] cs = pattern.split(tmp.getRemarkText());
+                                String dangOrder = "";
+                                for (String str:cs
+                                ) {
+                                    if(dangOrder.length()>= 11 || str.equals("*")){
+                                        break;
+                                    }
+                                    dangOrder += str;
+                                }
+                                tmp.setDangOrder(dangOrder);
+                                tmp.setAccountId(shopAccount.getId());
+                                Long time  = Long.parseLong(tmp.getShippingTime())+8*60*60;
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                                String time1 = sdf.format(new Date(time * 1000));
+                                tmp.setShippingTime(time1);
+                                tmp.setDeleteFlag(0);
+                                tmp.setGmtUpdate(new Date());
+                                tmp.setGmtCreate(new Date());
+                                if(tmp.getShippingComName().equals("快递包裹")||tmp.getShippingComName().equals("挂号印刷品")){
+                                    tmp.setShippingComName("中国邮政");
+                                }
+                                ShopOrder tt = new ShopOrder();
+                                tt.setOrderId(tmp.getOrderId());
+                                tt =  shopOrderMapper.selectOne(tt);
+                                if(tt == null){
+                                    shopOrderMapper.insert(tmp);
+                                }
+                                else{
+                                    if(!tt.getDangOrder().equals(tmp.getDangOrder())||!tt.getShippingComName().equals(tmp.getShippingComName())){
+                                        shopOrderMapper.update(tmp,new EntityWrapper<ShopOrder>().eq("order_id",tt.getOrderId()));
+                                    }
+                                    dangOrderDeal(shopAccount,qqq);
+                                }
+                            }
+
+                        }
+
+
+                    } catch (IOException e) {
+                        throw e;
+                    }
+                    finally {
+                        response.close();
+                        httpClient.close();
+                    }
+                }
+            }
+
+        }
+        catch (Exception e) {
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("同步定时任务异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+            e.printStackTrace();
+        }
+
+    }
+    private void doSomething2() {
+        try{
+            List<ShopAccount> list = shopAccountMapper.selectList(new EntityWrapper<ShopAccount>().orderBy("id",false));
+            for (ShopAccount shopAccount:list
+            ) {
+                flushCookie(shopAccount);
+                for (int i = 1; i <= 5; i++) {
+                    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+                    HttpGet get = new HttpGet("https://shop.kongfz.com/buyer/order/index/?pageCurr=" + i + "&pageShow=300&orderStatus=ShippedToReceipt");
+                    //这里可以设置请求参数,token等
+                    get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
+                    get.addHeader("cookie", shopAccount.getFuziCookie());
+
+                    CloseableHttpResponse response = httpClient.execute(get);//执行获取响应
+                    try {
+                        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//根据状态码处理
+                            String strTmp = EntityUtils.toString(response.getEntity(), "UTF-8");
+                            //返回字符串
+                            String res = unicodeToString(strTmp);
+                            JSONObject datas = JSONObject.parseObject(res);//转换成JSON格式
+                            Boolean status = (Boolean) datas.get("status");//获取返回数据状态,get获取的字段需要根据提供的返回值去获取
+                            List<ShopOrder> data = JSONArray.parseArray(datas.get("data").toString(), ShopOrder.class);//"data"是根据返回值设定
+                            if (data.size() == 0) {
+                                break;
+                            }
+                            for (ShopOrder tmp : data
+                            ) {
+                                //正则表达式,用于匹配非数字串,+号用于匹配出多个非数字串
+                                String regEx = "[^0-9]+";
+                                Pattern pattern = Pattern.compile(regEx);
+                                //用定义好的正则表达式拆分字符串,把字符串中的数字留出来
+                                String[] cs = pattern.split(tmp.getRemarkText());
+                                String dangOrder = "";
+                                for (String str : cs
+                                ) {
+                                    if (dangOrder.length() >= 11 || str.equals("*")) {
+                                        break;
+                                    }
+                                    dangOrder += str;
+                                }
+                                tmp.setDangOrder(dangOrder);
+                                tmp.setAccountId(shopAccount.getId());
+                                Long time  = Long.parseLong(tmp.getShippingTime())+8*60*60;
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                                sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
+                                String time1 = sdf.format(new Date(time * 1000));
+                                tmp.setShippingTime(time1);
+                                tmp.setDeleteFlag(0);
+                                tmp.setGmtUpdate(new Date());
+                                tmp.setGmtCreate(new Date());
+                                if (tmp.getShippingComName().equals("快递包裹") || tmp.getShippingComName().equals("挂号印刷品")) {
+                                    tmp.setShippingComName("中国邮政");
+                                }
+                                ShopOrder tt = new ShopOrder();
+                                tt.setOrderId(tmp.getOrderId());
+                                tt = shopOrderMapper.selectOne(tt);
+                                if (tt == null) {
+                                    shopOrderMapper.insert(tmp);
+                                } else {
+                                    if (tt.getDangOrderStatus().equals("未发货") && !tt.getDangOrder().equals(tmp.getDangOrder())) {
+                                        shopOrderMapper.update(tmp, new EntityWrapper<ShopOrder>().eq("order_id", tt.getOrderId()));
+                                    }
+                                }
+                            }
+                        }
+                    } catch (IOException e) {
+                        throw e;
+                    } finally {
+                        response.close();
+                        httpClient.close();
+                    }
+                }
+            }
+//            doSomething2();
+        }
+        catch (Exception e){
+            ShopLog shopLog = new ShopLog();
+            shopLog.setGmtCreate(new Date());
+            shopLog.setTitle("爬取定时任务异常");
+            shopLog.setContent(e.getMessage());
+            shopLogMapper.insert(shopLog);
+            e.printStackTrace();
+        }
+
+    }
+
+}

BIN
unimall-admin-api/src/main/lib/dangdang-open-sdk.jar


+ 1 - 0
unimall-admin-api/src/main/resources/application.properties

@@ -0,0 +1 @@
+

BIN
unimall-admin/.DS_Store


+ 17 - 0
unimall-admin/.babelrc

@@ -0,0 +1,17 @@
+{
+  "presets": [
+    ["env", {
+      "modules": false,
+      "targets": {
+        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
+      }
+    }],
+    "stage-2"
+  ],
+  "plugins": ["transform-vue-jsx", "transform-runtime"],
+  "env": {
+    "development":{
+      "plugins": ["dynamic-import-node"]
+    }
+  }
+}

+ 3 - 0
unimall-admin/.eslintignore

@@ -0,0 +1,3 @@
+build/*.js
+config/*.js
+src/assets

+ 185 - 0
unimall-admin/.eslintrc.js

@@ -0,0 +1,185 @@
+module.exports = {
+  root: true,
+  parserOptions: {
+    parser: 'babel-eslint',
+    sourceType: 'module'
+  },
+  env: {
+    browser: true,
+    node: true,
+    es6: true,
+  },
+  extends: ['plugin:vue/recommended', 'eslint:recommended'],
+
+  // add your custom rules here
+  //it is base on https://github.com/vuejs/eslint-config-vue
+  rules: {
+    "indent": ["off", 0],
+    "vue/max-attributes-per-line": [2, {
+      "singleline": 10,
+      "multiline": {
+        "max": 1,
+        "allowFirstLine": false
+      }
+    }],
+    "vue/name-property-casing": ["error", "PascalCase"],
+    'accessor-pairs': 2,
+    'arrow-spacing': [2, {
+      'before': true,
+      'after': true
+    }],
+    'block-spacing': [2, 'always'],
+    'brace-style': "off",
+    'camelcase': [0, {
+      'properties': 'always'
+    }],
+    'comma-dangle': [2, 'never'],
+    'comma-spacing': [2, {
+      'before': false,
+      'after': true
+    }],
+    'comma-style': [2, 'last'],
+    'constructor-super': 2,
+    'curly': [2, 'multi-line'],
+    'dot-location': [2, 'property'],
+    'eol-last': 2,
+    'eqeqeq': "off",
+    'generator-star-spacing': [2, {
+      'before': true,
+      'after': true
+    }],
+    'handle-callback-err': [2, '^(err|error)$'],
+    'indent': [2, 2, {
+      'SwitchCase': 1
+    }],
+    'jsx-quotes': [2, 'prefer-single'],
+    'key-spacing': [2, {
+      'beforeColon': false,
+      'afterColon': true
+    }],
+    'keyword-spacing': [2, {
+      'before': true,
+      'after': true
+    }],
+    'new-cap': "off",
+    'new-parens': 2,
+    'no-array-constructor': 2,
+    'no-caller': "off",
+    'no-console': 'off',
+    'no-class-assign': 2,
+    'no-cond-assign': "off",
+    'no-const-assign': 2,
+    'no-constant-condition': "off",
+    'no-control-regex': 0,
+    'no-delete-var': 2,
+    'no-dupe-args': 2,
+    'no-dupe-class-members': 2,
+    'no-dupe-keys': 2,
+    'no-duplicate-case': 2,
+    'no-empty': "off",
+    'no-empty-character-class': "off",
+    'no-empty-pattern': "off",
+    'no-eval': "off",
+    'no-ex-assign': 2,
+    'no-extend-native': 2,
+    'no-extra-bind': 2,
+    'no-extra-boolean-cast': 2,
+    'no-extra-parens': [2, 'functions'],
+    'no-fallthrough': "off",
+    'no-floating-decimal': 2,
+    'no-func-assign': "off",
+    'no-implied-eval': 2,
+    'no-inner-declarations': "off",
+    'no-invalid-regexp': 2,
+    'no-irregular-whitespace': 2,
+    'no-iterator': 2,
+    'no-label-var': 2,
+    'no-labels': [2, {
+      'allowLoop': false,
+      'allowSwitch': false
+    }],
+    'no-lone-blocks': 2,
+    'no-mixed-spaces-and-tabs': 2,
+    'no-multi-spaces': 2,
+    'no-multi-str': 2,
+    'no-multiple-empty-lines': [2, {
+      'max': 1
+    }],
+    'no-native-reassign': 2,
+    'no-negated-in-lhs': 2,
+    'no-new-object': 2,
+    'no-new-require': 2,
+    'no-new-symbol': 2,
+    'no-new-wrappers': 2,
+    'no-obj-calls': 2,
+    'no-octal': 2,
+    'no-octal-escape': 2,
+    'no-path-concat': 2,
+    'no-proto': 2,
+    'no-redeclare': "off",
+    'no-regex-spaces': 2,
+    'no-return-assign': "off",
+    'no-self-assign': 2,
+    'no-self-compare': 2,
+    'no-sequences': "off",
+    'no-shadow-restricted-names': 2,
+    'no-spaced-func': 2,
+    'no-sparse-arrays': 2,
+    'no-this-before-super': 2,
+    'no-throw-literal': "off",
+    'no-trailing-spaces': 2,
+    'no-undef': "off",
+    'no-undef-init': "off",
+    'no-unexpected-multiline': "off",
+    'no-unmodified-loop-condition': "off",
+    'no-unneeded-ternary': "off",
+    'no-unreachable': "off",
+    'no-unsafe-finally': 2,
+    'no-unused-vars': [2, {
+      'vars': 'all',
+      'args': 'none'
+    }],
+    'no-useless-call': 2,
+    'no-useless-computed-key': 2,
+    'no-useless-constructor': 2,
+    'no-useless-escape': 0,
+    'no-whitespace-before-property': 2,
+    'no-with': 2,
+    "no-tabs":"off",
+    'one-var': "off",
+    'operator-linebreak': [2, 'after', {
+      'overrides': {
+        '?': 'before',
+        ':': 'before'
+      }
+    }],
+    'padded-blocks': [2, 'never'],
+    'quotes': [2, 'single', {
+      'avoidEscape': true,
+      'allowTemplateLiterals': true
+    }],
+    'semi': [2, 'never'],
+    'semi-spacing': [2, {
+      'before': false,
+      'after': true
+    }],
+    'space-before-blocks': [2, 'always'],
+    'space-before-function-paren':  0,
+    'spaced-comment': [2, 'always', {
+      'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
+    }],
+    'template-curly-spacing': [2, 'never'],
+    'use-isnan': 2,
+    'valid-typeof': 2,
+    'wrap-iife': [2, 'any'],
+    'yield-star-spacing': [2, 'both'],
+    'yoda': [2, 'never'],
+    'prefer-const': 2,
+    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
+    'object-curly-spacing': [2, 'always', {
+      objectsInObjects: false
+    }],
+    'array-bracket-spacing': [2, 'never'],
+    "no-unused-vars": "off",
+  }
+}

+ 10 - 0
unimall-admin/.postcssrc.js

@@ -0,0 +1,10 @@
+// https://github.com/michael-ciniawsky/postcss-load-config
+
+module.exports = {
+  "plugins": {
+    "postcss-import": {},
+    "postcss-url": {},
+    // to edit target browsers: use "browserslist" field in package.json
+    "autoprefixer": {}
+  }
+}

+ 67 - 0
unimall-admin/build/build.js

@@ -0,0 +1,67 @@
+'use strict'
+require('./check-versions')()
+
+const ora = require('ora')
+const rm = require('rimraf')
+const path = require('path')
+const chalk = require('chalk')
+const webpack = require('webpack')
+const config = require('../config')
+const webpackConfig = require('./webpack.prod.conf')
+var connect = require('connect')
+var serveStatic = require('serve-static')
+
+const spinner = ora(
+  'building for ' + process.env.env_config + ' environment...'
+)
+spinner.start()
+
+rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
+  if (err) throw err
+  webpack(webpackConfig, (err, stats) => {
+    spinner.stop()
+    if (err) throw err
+    process.stdout.write(
+      stats.toString({
+        colors: true,
+        modules: false,
+        children: false,
+        chunks: false,
+        chunkModules: false
+      }) + '\n\n'
+    )
+
+    if (stats.hasErrors()) {
+      console.log(chalk.red(' Build failed with errors.\n'))
+      process.exit(1)
+    }
+
+    console.log(chalk.cyan(' Build complete.\n'))
+    console.log(
+      chalk.yellow(
+        ' Tip: built files are meant to be served over an HTTP server.\n' +
+          " Opening index.html over file:// won't work.\n"
+      )
+    )
+
+    if (process.env.npm_config_preview) {
+      const port = 9526
+      const host = 'http://localhost:' + port
+      const basePath = config.build.assetsPublicPath
+      const app = connect()
+
+      app.use(
+        basePath,
+        serveStatic('./dist', {
+          index: ['index.html', '/']
+        })
+      )
+
+      app.listen(port, function() {
+        console.log(
+          chalk.green(`> Listening at  http://localhost:${port}${basePath}`)
+        )
+      })
+    }
+  })
+})

+ 64 - 0
unimall-admin/build/check-versions.js

@@ -0,0 +1,64 @@
+'use strict'
+const chalk = require('chalk')
+const semver = require('semver')
+const packageConfig = require('../package.json')
+const shell = require('shelljs')
+
+function exec(cmd) {
+  return require('child_process')
+    .execSync(cmd)
+    .toString()
+    .trim()
+}
+
+const versionRequirements = [
+  {
+    name: 'node',
+    currentVersion: semver.clean(process.version),
+    versionRequirement: packageConfig.engines.node
+  }
+]
+
+if (shell.which('npm')) {
+  versionRequirements.push({
+    name: 'npm',
+    currentVersion: exec('npm --version'),
+    versionRequirement: packageConfig.engines.npm
+  })
+}
+
+module.exports = function() {
+  const warnings = []
+
+  for (let i = 0; i < versionRequirements.length; i++) {
+    const mod = versionRequirements[i]
+
+    if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
+      warnings.push(
+        mod.name +
+          ': ' +
+          chalk.red(mod.currentVersion) +
+          ' should be ' +
+          chalk.green(mod.versionRequirement)
+      )
+    }
+  }
+
+  if (warnings.length) {
+    console.log('')
+    console.log(
+      chalk.yellow(
+        'To use this template, you must update following to modules:'
+      )
+    )
+    console.log()
+
+    for (let i = 0; i < warnings.length; i++) {
+      const warning = warnings[i]
+      console.log('  ' + warning)
+    }
+
+    console.log()
+    process.exit(1)
+  }
+}

BIN
unimall-admin/build/logo.png


+ 108 - 0
unimall-admin/build/utils.js

@@ -0,0 +1,108 @@
+'use strict'
+const path = require('path')
+const config = require('../config')
+const MiniCssExtractPlugin = require('mini-css-extract-plugin')
+const packageConfig = require('../package.json')
+
+exports.assetsPath = function(_path) {
+  const assetsSubDirectory =
+    process.env.NODE_ENV === 'production'
+      ? config.build.assetsSubDirectory
+      : config.dev.assetsSubDirectory
+
+  return path.posix.join(assetsSubDirectory, _path)
+}
+
+exports.cssLoaders = function(options) {
+  options = options || {}
+
+  const cssLoader = {
+    loader: 'css-loader',
+    options: {
+      sourceMap: options.sourceMap
+    }
+  }
+
+  const postcssLoader = {
+    loader: 'postcss-loader',
+    options: {
+      sourceMap: options.sourceMap
+    }
+  }
+
+  // generate loader string to be used with extract text plugin
+  function generateLoaders(loader, loaderOptions) {
+    const loaders = []
+
+    // Extract CSS when that option is specified
+    // (which is the case during production build)
+    if (options.extract) {
+      loaders.push(MiniCssExtractPlugin.loader)
+    } else {
+      loaders.push('vue-style-loader')
+    }
+
+    loaders.push(cssLoader)
+
+    if (options.usePostCSS) {
+      loaders.push(postcssLoader)
+    }
+
+    if (loader) {
+      loaders.push({
+        loader: loader + '-loader',
+        options: Object.assign({}, loaderOptions, {
+          sourceMap: options.sourceMap
+        })
+      })
+    }
+
+    return loaders
+  }
+  // https://vue-loader.vuejs.org/en/configurations/extract-css.html
+  return {
+    css: generateLoaders(),
+    postcss: generateLoaders(),
+    less: generateLoaders('less'),
+    sass: generateLoaders('sass', {
+      indentedSyntax: true
+    }),
+    scss: generateLoaders('sass'),
+    stylus: generateLoaders('stylus'),
+    styl: generateLoaders('stylus')
+  }
+}
+
+// Generate loaders for standalone style files (outside of .vue)
+exports.styleLoaders = function(options) {
+  const output = []
+  const loaders = exports.cssLoaders(options)
+
+  for (const extension in loaders) {
+    const loader = loaders[extension]
+    output.push({
+      test: new RegExp('\\.' + extension + '$'),
+      use: loader
+    })
+  }
+
+  return output
+}
+
+exports.createNotifierCallback = () => {
+  const notifier = require('node-notifier')
+
+  return (severity, errors) => {
+    if (severity !== 'error') return
+
+    const error = errors[0]
+    const filename = error.file && error.file.split('!').pop()
+
+    notifier.notify({
+      title: packageConfig.name,
+      message: severity + ': ' + error.name,
+      subtitle: filename || '',
+      icon: path.join(__dirname, 'logo.png')
+    })
+  }
+}

+ 5 - 0
unimall-admin/build/vue-loader.conf.js

@@ -0,0 +1,5 @@
+'use strict'
+
+module.exports = {
+  //You can set the vue-loader configuration by yourself.
+}

+ 107 - 0
unimall-admin/build/webpack.base.conf.js

@@ -0,0 +1,107 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const config = require('../config')
+const { VueLoaderPlugin } = require('vue-loader')
+const vueLoaderConfig = require('./vue-loader.conf')
+
+function resolve(dir) {
+  return path.join(__dirname, '..', dir)
+}
+
+const createLintingRule = () => ({
+  test: /\.(js|vue)$/,
+  loader: 'eslint-loader',
+  enforce: 'pre',
+  include: [resolve('src'), resolve('test')],
+  options: {
+    formatter: require('eslint-friendly-formatter'),
+    emitWarning: !config.dev.showEslintErrorsInOverlay
+  }
+})
+
+module.exports = {
+  context: path.resolve(__dirname, '../'),
+  entry: {
+    app: './src/main.js'
+  },
+  output: {
+    path: config.build.assetsRoot,
+    filename: '[name].js',
+    publicPath:
+      process.env.NODE_ENV === 'production'
+        ? config.build.assetsPublicPath
+        : config.dev.assetsPublicPath
+  },
+  resolve: {
+    extensions: ['.js', '.vue', '.json'],
+    alias: {
+      '@': resolve('src')
+    }
+  },
+  module: {
+    rules: [
+      ...(config.dev.useEslint ? [createLintingRule()] : []),
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        options: vueLoaderConfig
+      },
+      {
+        test: /\.js$/,
+        loader: 'babel-loader?cacheDirectory',
+        include: [
+          resolve('src'),
+          resolve('test'),
+          resolve('node_modules/webpack-dev-server/client')
+        ]
+      },
+      {
+        test: /\.svg$/,
+        loader: 'svg-sprite-loader',
+        include: [resolve('src/icons')],
+        options: {
+          symbolId: 'icon-[name]'
+        }
+      },
+      {
+        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
+        loader: 'url-loader',
+        exclude: [resolve('src/icons')],
+        options: {
+          limit: 10000,
+          name: utils.assetsPath('img/[name].[hash:7].[ext]')
+        }
+      },
+      {
+        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
+        loader: 'url-loader',
+        options: {
+          limit: 10000,
+          name: utils.assetsPath('media/[name].[hash:7].[ext]')
+        }
+      },
+      {
+        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
+        loader: 'url-loader',
+        options: {
+          limit: 10000,
+          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
+        }
+      }
+    ]
+  },
+  plugins: [new VueLoaderPlugin()],
+  node: {
+    // prevent webpack from injecting useless setImmediate polyfill because Vue
+    // source contains it (although only uses it if it's native).
+    setImmediate: false,
+    // prevent webpack from injecting mocks to Node native modules
+    // that does not make sense for the client
+    dgram: 'empty',
+    fs: 'empty',
+    net: 'empty',
+    tls: 'empty',
+    child_process: 'empty'
+  }
+}

+ 98 - 0
unimall-admin/build/webpack.dev.conf.js

@@ -0,0 +1,98 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const webpack = require('webpack')
+const config = require('../config')
+const merge = require('webpack-merge')
+const baseWebpackConfig = require('./webpack.base.conf')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
+const portfinder = require('portfinder')
+
+function resolve(dir) {
+  return path.join(__dirname, '..', dir)
+}
+
+const HOST = process.env.HOST
+const PORT = process.env.PORT && Number(process.env.PORT)
+
+const devWebpackConfig = merge(baseWebpackConfig, {
+  mode: 'development',
+  module: {
+    rules: utils.styleLoaders({
+      sourceMap: config.dev.cssSourceMap,
+      usePostCSS: true
+    })
+  },
+  // cheap-module-eval-source-map is faster for development
+  devtool: config.dev.devtool,
+
+  // these devServer options should be customized in /config/index.js
+  devServer: {
+    clientLogLevel: 'warning',
+    historyApiFallback: true,
+    hot: true,
+    compress: true,
+    host: HOST || config.dev.host,
+    port: PORT || config.dev.port,
+    open: config.dev.autoOpenBrowser,
+    overlay: config.dev.errorOverlay
+      ? { warnings: false, errors: true }
+      : false,
+    publicPath: config.dev.assetsPublicPath,
+    proxy: config.dev.proxyTable,
+    quiet: true, // necessary for FriendlyErrorsPlugin
+    watchOptions: {
+      poll: config.dev.poll
+    }
+  },
+  plugins: [
+    new webpack.DefinePlugin({
+      'process.env': require('../config/dev.env')
+    }),
+    new webpack.HotModuleReplacementPlugin(),
+    // https://github.com/ampedandwired/html-webpack-plugin
+    new HtmlWebpackPlugin({
+      filename: 'index.html',
+      template: 'index.html',
+      inject: true,
+      favicon: resolve('favicon.ico'),
+      title: 'vue-element-admin',
+      templateParameters: {
+        BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory,
+      },
+    }),
+  ]
+})
+
+module.exports = new Promise((resolve, reject) => {
+  portfinder.basePort = process.env.PORT || config.dev.port
+  portfinder.getPort((err, port) => {
+    if (err) {
+      reject(err)
+    } else {
+      // publish the new Port, necessary for e2e tests
+      process.env.PORT = port
+      // add port to devServer config
+      devWebpackConfig.devServer.port = port
+
+      // Add FriendlyErrorsPlugin
+      devWebpackConfig.plugins.push(
+        new FriendlyErrorsPlugin({
+          compilationSuccessInfo: {
+            messages: [
+              `Your application is running here: http://${
+                devWebpackConfig.devServer.host
+              }:${port}`
+            ]
+          },
+          onErrors: config.dev.notifyOnErrors
+            ? utils.createNotifierCallback()
+            : undefined
+        })
+      )
+
+      resolve(devWebpackConfig)
+    }
+  })
+})

+ 188 - 0
unimall-admin/build/webpack.prod.conf.js

@@ -0,0 +1,188 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const webpack = require('webpack')
+const config = require('../config')
+const merge = require('webpack-merge')
+const baseWebpackConfig = require('./webpack.base.conf')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
+const MiniCssExtractPlugin = require('mini-css-extract-plugin')
+const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
+
+function resolve(dir) {
+  return path.join(__dirname, '..', dir)
+}
+
+const env = require('../config/' + process.env.env_config + '.env')
+
+// For NamedChunksPlugin
+const seen = new Set()
+const nameLength = 4
+
+const webpackConfig = merge(baseWebpackConfig, {
+  mode: 'production',
+  module: {
+    rules: utils.styleLoaders({
+      sourceMap: config.build.productionSourceMap,
+      extract: true,
+      usePostCSS: true
+    })
+  },
+  devtool: config.build.productionSourceMap ? config.build.devtool : false,
+  output: {
+    path: config.build.assetsRoot,
+    filename: utils.assetsPath('js/[name].[chunkhash:8].js'),
+    chunkFilename: utils.assetsPath('js/[name].[chunkhash:8].js')
+  },
+  plugins: [
+    // http://vuejs.github.io/vue-loader/en/workflow/production.html
+    new webpack.DefinePlugin({
+      'process.env': env
+    }),
+    // extract css into its own file
+    new MiniCssExtractPlugin({
+      filename: utils.assetsPath('css/[name].[contenthash:8].css'),
+      chunkFilename: utils.assetsPath('css/[name].[contenthash:8].css')
+    }),
+    // generate dist index.html with correct asset hash for caching.
+    // you can customize output by editing /index.html
+    // see https://github.com/ampedandwired/html-webpack-plugin
+    new HtmlWebpackPlugin({
+      filename: config.build.index,
+      template: 'index.html',
+      inject: true,
+      favicon: resolve('favicon.ico'),
+      title: 'vue-element-admin',
+      templateParameters: {
+        BASE_URL: config.build.assetsPublicPath + config.build.assetsSubDirectory,
+      },
+      minify: {
+        removeComments: true,
+        collapseWhitespace: true,
+        removeAttributeQuotes: true
+        // more options:
+        // https://github.com/kangax/html-minifier#options-quick-reference
+      }
+      // default sort mode uses toposort which cannot handle cyclic deps
+      // in certain cases, and in webpack 4, chunk order in HTML doesn't
+      // matter anyway
+    }),
+    new ScriptExtHtmlWebpackPlugin({
+      //`runtime` must same as runtimeChunk name. default is `runtime`
+      inline: /runtime\..*\.js$/
+    }),
+    // keep chunk.id stable when chunk has no name
+    new webpack.NamedChunksPlugin(chunk => {
+      if (chunk.name) {
+        return chunk.name
+      }
+      const modules = Array.from(chunk.modulesIterable)
+      if (modules.length > 1) {
+        const hash = require('hash-sum')
+        const joinedHash = hash(modules.map(m => m.id).join('_'))
+        let len = nameLength
+        while (seen.has(joinedHash.substr(0, len))) len++
+        seen.add(joinedHash.substr(0, len))
+        return `chunk-${joinedHash.substr(0, len)}`
+      } else {
+        return modules[0].id
+      }
+    }),
+    // keep module.id stable when vender modules does not change
+    new webpack.HashedModuleIdsPlugin(),
+    // copy custom static assets
+    new CopyWebpackPlugin([
+      {
+        from: path.resolve(__dirname, '../static'),
+        to: config.build.assetsSubDirectory,
+        ignore: ['.*']
+      }
+    ])
+  ],
+  optimization: {
+    splitChunks: {
+      chunks: 'all',
+      cacheGroups: {
+        libs: {
+          name: 'chunk-libs',
+          test: /[\\/]node_modules[\\/]/,
+          priority: 10,
+          chunks: 'initial' // 只打包初始时依赖的第三方
+        },
+        elementUI: {
+          name: 'chunk-elementUI', // 单独将 elementUI 拆包
+          priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
+          test: /[\\/]node_modules[\\/]element-ui[\\/]/
+        },
+        commons: {
+          name: 'chunk-commons',
+          test: resolve('src/components'), // 可自定义拓展你的规则
+          minChunks: 3, // 最小公用次数
+          priority: 5,
+          reuseExistingChunk: true
+        }
+      }
+    },
+    runtimeChunk: 'single',
+    minimizer: [
+      new UglifyJsPlugin({
+        uglifyOptions: {
+          mangle: {
+            safari10: true
+          }
+        },
+        sourceMap: config.build.productionSourceMap,
+        cache: true,
+        parallel: true
+      }),
+      // Compress extracted CSS. We are using this plugin so that possible
+      // duplicated CSS from different components can be deduped.
+      new OptimizeCSSAssetsPlugin()
+    ]
+  }
+})
+
+if (config.build.productionGzip) {
+  const CompressionWebpackPlugin = require('compression-webpack-plugin')
+
+  webpackConfig.plugins.push(
+    new CompressionWebpackPlugin({
+      asset: '[path].gz[query]',
+      algorithm: 'gzip',
+      test: new RegExp(
+        '\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
+      ),
+      threshold: 10240,
+      minRatio: 0.8
+    })
+  )
+}
+
+if (config.build.generateAnalyzerReport || config.build.bundleAnalyzerReport) {
+  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
+    .BundleAnalyzerPlugin
+
+  if (config.build.bundleAnalyzerReport) {
+    webpackConfig.plugins.push(
+      new BundleAnalyzerPlugin({
+        analyzerPort: 8080,
+        generateStatsFile: false
+      })
+    )
+  }
+
+  if (config.build.generateAnalyzerReport) {
+    webpackConfig.plugins.push(
+      new BundleAnalyzerPlugin({
+        analyzerMode: 'static',
+        reportFilename: 'bundle-report.html',
+        openAnalyzer: false
+      })
+    )
+  }
+}
+
+module.exports = webpackConfig

+ 6 - 0
unimall-admin/config/dep.env.js

@@ -0,0 +1,6 @@
+module.exports = {
+	NODE_ENV: '"production"',
+  ENV_CONFIG: '"dep"',
+  HOST: '"http://localhost:8081"',
+  BASE_API: '"http://localhost:8081/m.api"'
+}

+ 6 - 0
unimall-admin/config/dev.env.js

@@ -0,0 +1,6 @@
+module.exports = {
+	NODE_ENV: '"development"',
+  ENV_CONFIG: '"dev"',
+    HOST: '"http://localhost:8081"',
+    BASE_API: '"http://localhost:8081/m.api"'
+}

+ 88 - 0
unimall-admin/config/index.js

@@ -0,0 +1,88 @@
+'use strict'
+// Template version: 1.2.6
+// see http://vuejs-templates.github.io/webpack for documentation.
+
+const path = require('path')
+
+module.exports = {
+  dev: {
+    // Paths
+    assetsSubDirectory: 'static',
+    assetsPublicPath: '/',
+    proxyTable: {},
+
+    // Various Dev Server settings
+
+    // can be overwritten by process.env.HOST
+    // if you want dev by ip, please set host: '0.0.0.0'
+    host: 'localhost',
+    port: 9527, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
+    autoOpenBrowser: true,
+    errorOverlay: true,
+    notifyOnErrors: false,
+    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
+
+    // Use Eslint Loader?
+    // If true, your code will be linted during bundling and
+    // linting errors and warnings will be shown in the console.
+    useEslint: true,
+    // If true, eslint errors and warnings will also be shown in the error overlay
+    // in the browser.
+    showEslintErrorsInOverlay: false,
+
+    /**
+     * Source Maps
+     */
+
+    // https://webpack.js.org/configuration/devtool/#development
+    devtool: 'source-map',
+
+    // CSS Sourcemaps off by default because relative paths are "buggy"
+    // with this option, according to the CSS-Loader README
+    // (https://github.com/webpack/css-loader#sourcemaps)
+    // In our experience, they generally work as expected,
+    // just be aware of this issue when enabling this option.
+    cssSourceMap: false
+  },
+
+  build: {
+    // Template for index.html
+    index: path.resolve(__dirname, '../dist/index.html'),
+
+    // Paths
+    assetsRoot: path.resolve(__dirname, '../dist'),
+    assetsSubDirectory: 'static',
+
+    /**
+     * You can set by youself according to actual condition
+     * You will need to set this if you plan to deploy your site under a sub path,
+     * for example GitHub pages. If you plan to deploy your site to https://foo.github.io/bar/,
+     * then assetsPublicPath should be set to "/bar/".
+     * In most cases please use '/' !!!
+     */
+    assetsPublicPath: '/',
+
+    /**
+     * Source Maps
+     */
+    productionSourceMap: false,
+    // https://webpack.js.org/configuration/devtool/#production
+    devtool: 'source-map',
+
+    // Gzip off by default as many popular static hosts such as
+    // Surge or Netlify already gzip all static assets for you.
+    // Before setting to `true`, make sure to:
+    // npm install --save-dev compression-webpack-plugin
+    productionGzip: false,
+    productionGzipExtensions: ['js', 'css'],
+
+    // Run the build command with an extra argument to
+    // View the bundle analyzer report after build finishes:
+    // `npm run build:prod --report`
+    // Set to `true` or `false` to always turn it on or off
+    bundleAnalyzerReport: process.env.npm_config_report || false,
+
+    // `npm run build:prod --generate_report`
+    generateAnalyzerReport: process.env.npm_config_generate_report || false
+  }
+}

+ 6 - 0
unimall-admin/config/prod.env.js

@@ -0,0 +1,6 @@
+module.exports = {
+	NODE_ENV: '"production"',
+  	ENV_CONFIG: '"prod"',
+    HOST: '"http://101.227.51.94:8081"',
+    BASE_API: '"http://101.227.51.94:8081/m.api"'
+}

BIN
unimall-admin/dist/favicon.ico


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
unimall-admin/dist/index.html


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
unimall-admin/dist/static/css/app.b4173d64.css


+ 1 - 0
unimall-admin/dist/static/css/chunk-0042.f12b97fc.css

@@ -0,0 +1 @@
+.avatar-uploader .el-upload{border:1px dashed #d9d9d9;border-radius:6px;cursor:pointer;position:relative;overflow:hidden}.avatar-uploader .el-upload:hover{border-color:#20a0ff}.avatar-uploader-icon{font-size:28px;color:#8c939d;width:120px;height:120px;line-height:120px;text-align:center}.avatar{width:145px;height:145px;display:block}

+ 1 - 0
unimall-admin/dist/static/css/chunk-0661.05e63149.css

@@ -0,0 +1 @@
+.back-to-ceiling[data-v-6172f71e]{position:fixed;display:inline-block;text-align:center;cursor:pointer}.back-to-ceiling[data-v-6172f71e]:hover{background:#d5dbe7}.fade-enter-active[data-v-6172f71e],.fade-leave-active[data-v-6172f71e]{-webkit-transition:opacity .5s;transition:opacity .5s}.fade-enter[data-v-6172f71e],.fade-leave-to[data-v-6172f71e]{opacity:0}.back-to-ceiling .Icon[data-v-6172f71e]{fill:#9aaabf;background:none}

+ 1 - 0
unimall-admin/dist/static/css/chunk-0e44.b126e1c1.css

@@ -0,0 +1 @@
+.el-card{margin-bottom:10px}.el-tag+.el-tag{margin-left:10px}.input-new-keyword{width:90px;margin-left:10px;vertical-align:bottom}.avatar-uploader .el-upload{border:1px dashed #d9d9d9;border-radius:6px;cursor:pointer;position:relative;overflow:hidden}.avatar-uploader .el-upload:hover{border-color:#20a0ff}.avatar-uploader-icon{font-size:28px;color:#8c939d;width:120px;height:120px;line-height:120px;text-align:center}.avatar{width:145px;height:145px;display:block}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
unimall-admin/dist/static/css/chunk-1220.b4ab4382.css


+ 1 - 0
unimall-admin/dist/static/css/chunk-14e1.9f405cf9.css

@@ -0,0 +1 @@
+.errPage-container[data-v-a0d57418]{width:800px;max-width:100%;margin:100px auto}.errPage-container .pan-back-btn[data-v-a0d57418]{background:#008489;color:#fff;border:none!important}.errPage-container .pan-gif[data-v-a0d57418]{margin:0 auto;display:block}.errPage-container .pan-img[data-v-a0d57418]{display:block;margin:0 auto;width:100%}.errPage-container .text-jumbo[data-v-a0d57418]{font-size:60px;font-weight:700;color:#484848}.errPage-container .list-unstyled[data-v-a0d57418]{font-size:14px}.errPage-container .list-unstyled li[data-v-a0d57418]{padding-bottom:5px}.errPage-container .list-unstyled a[data-v-a0d57418]{color:#008489;text-decoration:none}.errPage-container .list-unstyled a[data-v-a0d57418]:hover{text-decoration:underline}

+ 0 - 0
unimall-admin/dist/static/css/chunk-192f.02e44736.css


+ 0 - 0
unimall-admin/dist/static/css/chunk-1ee7.f42c833d.css


+ 0 - 0
unimall-admin/dist/static/css/chunk-1f81.6c259890.css


+ 1 - 0
unimall-admin/dist/static/css/chunk-21ca.7473bdb6.css

@@ -0,0 +1 @@
+.avatar-uploader .el-upload{border:1px dashed #d9d9d9;border-radius:6px;cursor:pointer;position:relative;overflow:hidden}.avatar-uploader .el-upload:hover{border-color:#20a0ff}.avatar-uploader-icon{font-size:28px;color:#8c939d;width:120px;height:120px;line-height:120px;text-align:center}.avatar{width:145px;height:145px;display:block}

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio