Преглед изворни кода

Merge remote-tracking branch 'origin/master'

jlutt@163.com пре 2 година
родитељ
комит
cec7b90667
34 измењених фајлова са 1824 додато и 78 уклоњено
  1. 13 0
      conf/KeyCode.xml
  2. 72 0
      conf/KeyId.xml
  3. 19 6
      conf/application-ddWebOne.xml
  4. 4 0
      conf/esTemplate/orderdeliveryinfo.json
  5. 9 0
      conf/esTemplate/platforminfo.json
  6. 84 9
      conf/esTemplate/storeinfo.json
  7. 17 1
      conf/esTemplate/storeinvoiceinfo.json
  8. 17 1
      conf/esTemplate/storeplatform.json
  9. 24 2
      conf/esTemplate/storeplatformrequire.json
  10. 7 0
      conf/platform.properties
  11. 4 0
      conf/rediskeys.properties
  12. 96 0
      conf/script/1000/orderApi/BE_Order_CreateOrder_Douyin.groovy
  13. 2 2
      conf/sqlroot/com/dderp/business/dao/PlatformDao.dql
  14. 10 8
      conf/sqlroot/com/dderp/business/dao/StoreDao.dql
  15. 124 22
      conf/初始化业务表.sql
  16. 10 2
      ddBusiness/src/main/java/com/dderp/business/dao/StoreDao.java
  17. 546 16
      ddBusiness/src/main/java/com/dderp/business/service/StoreServiceImpl.java
  18. 176 0
      ddBusiness/src/main/java/com/dderp/business/service/flycat/DouyinServiceImpl.java
  19. 14 2
      ddCommon/src/main/java/com/dderp/common/api/StoreService.java
  20. 11 0
      ddCommon/src/main/java/com/dderp/common/api/flycat/DouyinService.java
  21. 42 0
      ddCommon/src/main/java/com/dderp/common/datas/BusinessOrderStatus.java
  22. 3 1
      ddCommon/src/main/java/com/dderp/common/datas/ERPModule.java
  23. 10 0
      ddCommon/src/main/java/com/dderp/common/datas/RedisKeys.java
  24. 43 0
      ddCommon/src/main/java/com/dderp/common/entity/invoke/douyin/DouyinTokenData.java
  25. 59 0
      ddCommon/src/main/java/com/dderp/common/entity/invoke/douyin/DouyinTokenRequest.java
  26. 23 0
      ddCommon/src/main/java/com/dderp/common/entity/invoke/douyin/DouyinTokenResponse.java
  27. 12 0
      ddCommon/src/main/java/com/dderp/common/entity/order/OrderDeliveryInfo.java
  28. 12 1
      ddCommon/src/main/java/com/dderp/common/entity/platform/PlatformInfo.java
  29. 10 1
      ddCommon/src/main/java/com/dderp/common/entity/platform/PlatformRequire.java
  30. 17 1
      ddCommon/src/main/java/com/dderp/common/entity/store/StoreInfo.java
  31. 6 1
      ddCommon/src/main/java/com/dderp/common/servlet/file/FileUploadServlet.java
  32. 0 2
      ddWebCore/src/main/java/com/dderp/webcore/rest/PlatformRest.java
  33. 254 0
      ddWebCore/src/main/java/com/dderp/webcore/rest/StoreRest.java
  34. 74 0
      ddWebCore/src/main/java/com/dderp/webcore/servlet/OrderCallServlet.java

+ 13 - 0
conf/KeyCode.xml

@@ -51,4 +51,17 @@
         <CodeLength>4</CodeLength>
         <TableWhere/>
     </Item>
+
+    <Item>
+        <CodeName>deBusinessOrder.code</CodeName>
+        <TableName>v_deBusinessOrder</TableName>
+        <CodeFieldName>orderCode</CodeFieldName>
+        <CodePrefix>BS</CodePrefix>
+        <CodeYear>true</CodeYear>
+        <YearLength>4</YearLength>
+        <CodeMonth>true</CodeMonth>
+        <CodeDay>true</CodeDay>
+        <CodeLength>4</CodeLength>
+        <TableWhere/>
+    </Item>
 </Items>

+ 72 - 0
conf/KeyId.xml

@@ -316,4 +316,76 @@
             <TableWhere/>
         </Table>
     </Item>
+
+    <Item>
+        <IDName>tbStoreInfo.id</IDName>
+        <Table>
+            <TableName>tbStoreInfo</TableName>
+            <IDFieldName>id</IDFieldName>
+            <TableWhere/>
+        </Table>
+    </Item>
+
+    <Item>
+        <IDName>tbStoreInvoiceInfo.id</IDName>
+        <Table>
+            <TableName>tbStoreInvoiceInfo</TableName>
+            <IDFieldName>id</IDFieldName>
+            <TableWhere/>
+        </Table>
+    </Item>
+
+    <Item>
+        <IDName>tbStorePlatform.id</IDName>
+        <Table>
+            <TableName>tbStorePlatform</TableName>
+            <IDFieldName>id</IDFieldName>
+            <TableWhere/>
+        </Table>
+    </Item>
+
+    <Item>
+        <IDName>tbStorePlatformRequire.id</IDName>
+        <Table>
+            <TableName>tbStorePlatformRequire</TableName>
+            <IDFieldName>id</IDFieldName>
+            <TableWhere/>
+        </Table>
+    </Item>
+
+    <Item>
+        <IDName>deBusinessOrder.id</IDName>
+        <Table>
+            <TableName>v_debusinessorder</TableName>
+            <IDFieldName>id</IDFieldName>
+            <TableWhere/>
+        </Table>
+    </Item>
+
+    <Item>
+        <IDName>deOrderFinances.id</IDName>
+        <Table>
+            <TableName>v_deorderfinances</TableName>
+            <IDFieldName>id</IDFieldName>
+            <TableWhere/>
+        </Table>
+    </Item>
+
+    <Item>
+        <IDName>deOrderDeliveryInfo.id</IDName>
+        <Table>
+            <TableName>v_deorderdeliveryinfo</TableName>
+            <IDFieldName>id</IDFieldName>
+            <TableWhere/>
+        </Table>
+    </Item>
+
+    <Item>
+        <IDName>deOrderDetailItem.id</IDName>
+        <Table>
+            <TableName>v_deorderdetailitem</TableName>
+            <IDFieldName>id</IDFieldName>
+            <TableWhere/>
+        </Table>
+    </Item>
 </Items>

+ 19 - 6
conf/application-ddWebOne.xml

@@ -7,7 +7,7 @@
             <node addr="127.0.0.1" port="52101"/>
         </group>
 
-        <properties load="redis.properties;workProcess.properties;sftc.properties">
+        <properties load="redis.properties;workProcess.properties;sftc.properties;platform.properties">
             <property name="orderFileRoot" value="${APP_HOME}/orderFiles"/>
             <!--注入sql脚本的目录-->
             <property name="sqlroot" value="${APP_HOME}/conf/sqlroot/"/>
@@ -46,13 +46,13 @@
             <property name="orderImportRoot" value="${APP_HOME}/importOrder"/>
 
             <!--支付超时分钟-->
-            <property name="payTimeOutMinutes" value="30" />
+            <property name="payTimeOutMinutes" value="30"/>
 
             <!--系统运行模式,区分ERP和商城完全靠脚本理论是可行的,就是一些档案增删改的代码也需要调整到脚本执行,前期懒得处理,用此字段区分一下算了-->
             <!--ERP:印刷ERP-->
             <!--Mall:印刷商城-->
             <!--ProductCenter:产品中心-->
-            <property name="sysRunMode" value="ERP" />
+            <property name="sysRunMode" value="ERP"/>
         </properties>
     </resources>
 
@@ -91,7 +91,7 @@
         <!--管理提供给管理用户的接口-->
         <rest autoload="false" base="com.dderp.common.base.ERPAdminHttpServlet">
             <service value="com.dderp.webcore.rest.ERPRest"/>
-            <service value="com.dderp.webcore.rest.AdminRest" >
+            <service value="com.dderp.webcore.rest.AdminRest">
                 <isUseScriptService value="true"/>
             </service>
             <service value="com.dderp.webcore.rest.ERPUpdateRest"/>
@@ -106,7 +106,14 @@
         </rest>
 
         <servlets autoload="false">
-            <servlet value="com.dderp.webcore.servlet.ExpressCallServlet" />
+            <servlet value="com.dderp.common.servlet.apidoc.ApiDocServlet">
+                <environment value="dev"/>
+            </servlet>
+
+            <servlet value="com.dderp.common.servlet.file.FileUploadServlet"/>
+
+            <servlet value="com.dderp.webcore.servlet.ExpressCallServlet"/>
+            <servlet value="com.dderp.webcore.servlet.OrderCallServlet"/>
         </servlets>
     </server>
 
@@ -176,7 +183,7 @@
             <service value="com.dderp.business.service.SupplierInitImpl" groups="DELIVER_SERVICE_REMOTE">
                 <master value="true"/>
                 <environment value="dev"/>
-                <clearESData value="false" />
+                <clearESData value="false"/>
             </service>
 
             <service value="com.dderp.business.service.ERPServiceImpl" groups="DELIVER_SERVICE_REMOTE">
@@ -256,6 +263,12 @@
                 <master value="true"/>
                 <isUseScriptService value="true"/>
             </service>
+
+            <service value="com.dderp.business.service.flycat.DouyinServiceImpl" groups="DELIVER_SERVICE_REMOTE">
+                <master value="true"/>
+                <environment value="release"/>
+                <isUseScriptService value="false"/>
+            </service>
         </services>
     </server>
 </application>

+ 4 - 0
conf/esTemplate/orderdeliveryinfo.json

@@ -26,6 +26,10 @@
         "type": "text",
         "index": "not_analyzed"
       },
+      "geoLocationSerial": {
+        "type": "text",
+        "index": "not_analyzed"
+      },
       "receiveMan": {
         "type": "text",
         "index": "not_analyzed"

+ 9 - 0
conf/esTemplate/platforminfo.json

@@ -4,6 +4,15 @@
       "id": {
         "type": "long"
       },
+      "platformCode": {
+        "type": "text",
+        "analyzer": "index_ansj",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          }
+        }
+      },
       "platformName": {
         "type": "text",
         "analyzer": "index_ansj",

+ 84 - 9
conf/esTemplate/storeinfo.json

@@ -6,14 +6,46 @@
       },
       "storeName": {
         "type": "text",
-        "index": "not_analyzed"
+        "analyzer": "index_ansj",
+        "search_analyzer": "query_ansj",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          },
+          "number": {
+            "type": "text",
+            "index": "analyzed",
+            "analyzer": "number_analyzer"
+          },
+          "letter": {
+            "type": "text",
+            "index": "analyzed",
+            "analyzer": "letter_analyzer"
+          }
+        }
       },
       "idBrand": {
         "type": "long"
       },
       "brandName": {
         "type": "text",
-        "index": "not_analyzed"
+        "analyzer": "index_ansj",
+        "search_analyzer": "query_ansj",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          },
+          "number": {
+            "type": "text",
+            "index": "analyzed",
+            "analyzer": "number_analyzer"
+          },
+          "letter": {
+            "type": "text",
+            "index": "analyzed",
+            "analyzer": "letter_analyzer"
+          }
+        }
       },
       "idStoreType": {
         "type": "long"
@@ -23,34 +55,71 @@
       },
       "storeCodeInput": {
         "type": "text",
-        "index": "not_analyzed"
+        "index": "analyzed",
+        "analyzer": "codefull_analyzer",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          }
+        }
       },
       "storeProvince": {
         "type": "text",
-        "index": "not_analyzed"
+        "index": "not_analyzed",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          }
+        }
       },
       "storeCity": {
         "type": "text",
-        "index": "not_analyzed"
+        "index": "not_analyzed",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          }
+        }
       },
       "storeDistrict": {
         "type": "text",
-        "index": "not_analyzed"
+        "index": "not_analyzed",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          }
+        }
       },
       "storeAddress": {
         "type": "text",
         "index": "not_analyzed"
       },
-      "contractPhone": {
+      "locationStr": {
         "type": "text",
         "index": "not_analyzed"
       },
+      "contractPhone": {
+        "type": "text",
+        "index": "analyzed",
+        "analyzer": "codefull_analyzer",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          }
+        }
+      },
       "storeBossId": {
         "type": "long"
       },
       "companyLicenseNo": {
         "type": "text",
-        "index": "not_analyzed"
+        "index": "analyzed",
+        "analyzer": "codefull_analyzer",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          }
+        }
       },
       "companyLicensePicUrl": {
         "type": "text",
@@ -58,7 +127,13 @@
       },
       "legalPersonIdNo": {
         "type": "text",
-        "index": "not_analyzed"
+        "index": "analyzed",
+        "analyzer": "codefull_analyzer",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          }
+        }
       },
       "legalPersonName": {
         "type": "text",

+ 17 - 1
conf/esTemplate/storeinvoiceinfo.json

@@ -16,7 +16,23 @@
       },
       "companyName": {
         "type": "text",
-        "index": "not_analyzed"
+        "analyzer": "index_ansj",
+        "search_analyzer": "query_ansj",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          },
+          "number": {
+            "type": "text",
+            "index": "analyzed",
+            "analyzer": "number_analyzer"
+          },
+          "letter": {
+            "type": "text",
+            "index": "analyzed",
+            "analyzer": "letter_analyzer"
+          }
+        }
       },
       "defaultTaxItemName": {
         "type": "text",

+ 17 - 1
conf/esTemplate/storeplatform.json

@@ -12,7 +12,23 @@
       },
       "platformName": {
         "type": "text",
-        "index": "not_analyzed"
+        "analyzer": "index_ansj",
+        "search_analyzer": "query_ansj",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          },
+          "number": {
+            "type": "text",
+            "index": "analyzed",
+            "analyzer": "number_analyzer"
+          },
+          "letter": {
+            "type": "text",
+            "index": "analyzed",
+            "analyzer": "letter_analyzer"
+          }
+        }
       },
       "platformType": {
         "type": "integer"

+ 24 - 2
conf/esTemplate/storeplatformrequire.json

@@ -18,11 +18,33 @@
       },
       "platformRequireCode": {
         "type": "text",
-        "index": "not_analyzed"
+        "index": "analyzed",
+        "analyzer": "codefull_analyzer",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          }
+        }
       },
       "platformRequireName": {
         "type": "text",
-        "index": "not_analyzed"
+        "analyzer": "index_ansj",
+        "search_analyzer": "query_ansj",
+        "fields": {
+          "raw": {
+            "type": "keyword"
+          },
+          "number": {
+            "type": "text",
+            "index": "analyzed",
+            "analyzer": "number_analyzer"
+          },
+          "letter": {
+            "type": "text",
+            "index": "analyzed",
+            "analyzer": "letter_analyzer"
+          }
+        }
       },
       "itemValue": {
         "type": "text",

+ 7 - 0
conf/platform.properties

@@ -0,0 +1,7 @@
+#抖音来客
+#请求地址
+douyin.reqUrl=https://open.douyin.com
+#appId
+douyin.appId=awd61ulpox5tdzhe
+#appSecret
+douyin.appSecret=ab3e8b197052198143df8cdcba350fb6

+ 4 - 0
conf/rediskeys.properties

@@ -114,6 +114,10 @@ redis.deliver.platforminfo = dydeliver:deliver:platforminfo
 redis.deliver.platformrequire = dydeliver:deliver:platformrequire
 #门店品牌
 redis.deliver.storebrand = dydeliver:deliver:storebrand
+#抖音上一次刷新token的时间
+redis.douyin.lasttokendate = dydeliver:douyin:lasttokendate
+#抖音当前的token
+redis.douyin.accesstoken = dydeliver:douyin:accesstoken
 
 redis.erp.working.order = dydeliver:erp:working:order
 redis.erp.working.express.sf.order = dydeliver:erp:working:express:sf:order

+ 96 - 0
conf/script/1000/orderApi/BE_Order_CreateOrder_Douyin.groovy

@@ -0,0 +1,96 @@
+import com.alibaba.fastjson2.JSON
+import com.dderp.common.api.BusinessExecutor
+import com.dderp.common.datas.BusinessOrderStatus
+import com.dderp.common.datas.ERPModule
+import com.dderp.common.entity.base.ProcessStringItem
+import com.dderp.common.entity.express.SFCreateOrderResult
+import com.dderp.common.entity.express.SFOrder
+import com.dderp.common.entity.express.SFOrderDetail
+import com.dderp.common.entity.express.SFOrderProductDetail
+import com.dderp.common.entity.express.SFOrderReceive
+import com.dderp.common.entity.order.BusinessOrder
+import com.dderp.common.entity.order.OrderFinances
+import com.dderp.common.http.HttpTools
+import com.dySweetFishPlugin.sql.TableIdService
+import com.sweetfish.convert.json.JsonConvert
+import com.sweetfish.service.RetResult
+import groovy.json.JsonSlurper
+import org.apache.logging.log4j.LogManager
+import org.apache.logging.log4j.Logger
+
+import javax.annotation.Resource
+import java.math.RoundingMode
+import java.nio.charset.StandardCharsets
+import java.time.LocalDateTime
+import java.time.ZoneOffset
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.TimeoutException
+
+@SuppressWarnings("unused")
+class BE_Order_CreateOrder_Douyin implements BusinessExecutor<ProcessStringItem, BusinessOrder> {
+
+    private final Logger logger = LogManager.getLogger(this.getClass().getSimpleName())
+
+    @Resource
+    private JsonConvert jsonConvert
+
+    @Resource
+    private TableIdService tableIdService
+
+    @Override
+    String scriptName() {
+        return "抖音来客创建订单"
+    }
+
+    @Override
+    ERPModule module() {
+        return ERPModule.ORDER_API
+    }
+
+    RetResult<BusinessOrder> execute(ProcessStringItem source) {
+        //秒级时间戳,groovy里面不让用system
+        long currentTime = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8))
+        String dataSourceId = source.dataSourceId
+        long supplierCode = source.supplierCode
+
+        def jsonSlurper = new JsonSlurper()
+        def invokeOrder = jsonSlurper.parseText(source.itemValue)
+
+        BusinessOrder businessOrder = new BusinessOrder()
+        businessOrder.setId(tableIdService.getTableIdMulti("deBusinessOrder.id", 1, dataSourceId, String.valueOf(supplierCode)))
+        businessOrder.setOrderName(invokeOrder["merchant"]["account_name"] as String)
+        businessOrder.setOrderCode(tableIdService.getTableCodeMulti("deBusinessOrder.code", dataSourceId, String.valueOf(supplierCode)))
+        businessOrder.setOrderStatus(BusinessOrderStatus.init.value)
+        //todo 商户平台需求一个绑定逻辑,用以判断该平台适用于哪一个脚本
+        //businessOrder.setIncomePlatformId(0)
+        //businessOrder.setIncomePlatformName("")
+        businessOrder.setIncomePlatformOrderCode(invokeOrder["order"]["order_id"] as String)
+        businessOrder.setIncomePlatformOrderTimeLong(invokeOrder["order"]["pay_time"] as long * 1000)//抖音传过来的时间戳单位是秒
+        businessOrder.setIncomePlatformOrderTime(new Date(businessOrder.incomePlatformOrderTimeLong))
+        //抖音传过来的格式为起始时间戳(单位秒)- 截止时间戳(单位秒),示例:1669370006-1669371206,目前先取起始时间
+        long suggestTimeLong = (invokeOrder["order"]["sys_expect_time"] as String).split("-")[0] as long
+        businessOrder.setSuggestDeliverTimeLong(suggestTimeLong * 1000)
+        businessOrder.setSuggestDeliverTime(new Date(businessOrder.suggestDeliverTimeLong))
+        //todo 商户id同上
+        //businessOrder.setIdStore(0)
+        //businessOrder.setStoreName("")
+        BigDecimal deliverFee = new BigDecimal((invokeOrder["amount_info"]["freight_pay_amount"] as int) / 100).setScale(2, RoundingMode.CEILING)
+        businessOrder.setDeliverFee(deliverFee)
+        String address = "[" + invokeOrder["receiver_info"]["city"] + "]" + invokeOrder["receiver_info"]["province"] +
+                invokeOrder["receiver_info"]["city"] +
+                invokeOrder["receiver_info"]["district"] +
+                invokeOrder["receiver_info"]["location_address"] +
+                invokeOrder["receiver_info"]["location_name"] + "-" +
+                invokeOrder["receiver_info"]["receiver_name"]
+        businessOrder.setDeliverAddressAll(address)
+
+        //订单金额类信息
+        OrderFinances orderFinances = new OrderFinances()
+//        orderFinances.setId(tableIdService.)
+
+
+        return null;
+    }
+}

+ 2 - 2
conf/sqlroot/com/dderp/business/dao/PlatformDao.dql

@@ -14,10 +14,10 @@ order by #{orderBy}
 ;
 
 -- [addPlatformInfo]
-insert into $table$ (id, platformName, platformType, requireListSerial,
+insert into $table$ (id, platformCode, platformName, platformType, requireListSerial,
 voidFlag, createBy, createTime,
 createTimeLong, updateBy, updateTime,
-updateTimeLong ) values ( #{id}, #{platformname}, #{platformtype}, #{requirelistserial},
+updateTimeLong ) values ( #{id}, #{platformcode}, #{platformname}, #{platformtype}, #{requirelistserial},
 #{voidflag}, #{createby}, #{createtime},
 #{createtimelong}, #{updateby}, #{updatetime},
 #{updatetimelong} );

+ 10 - 8
conf/sqlroot/com/dderp/business/dao/StoreDao.dql

@@ -50,26 +50,28 @@ brandMemo = #{brandmemo},updateBy = #{updateby},updateTime = #{updatetime},updat
  insert into $table$ (id, storeName, idBrand, brandName,
  idStoreType, deliverSettleKind, storeCodeInput,
  storeProvince, storeCity, storeDistrict,
- storeAddress, contractPhone, storeBossId,
+ storeAddress, locationStr, contractPhone, storeBossId,
  companyLicenseNo, companyLicensePicUrl, legalPersonIdNo,
  legalPersonName, voidFlag, enableInvoice,
  createBy, createTime, createTimeLong,
  updateBy, updateTime, updateTimeLong ) values ( #{id}, #{storename}, #{idbrand}, #{brandname},
  #{idstoretype}, #{deliversettlekind}, #{storecodeinput},
  #{storeprovince}, #{storecity}, #{storedistrict},
- #{storeaddress}, #{contractphone}, #{storebossid},
+ #{storeaddress}, #{locationstr}, #{contractphone}, #{storebossid},
  #{companylicenseno}, #{companylicensepicurl}, #{legalpersonidno},
  #{legalpersonname}, #{voidflag}, #{enableinvoice},
  #{createby}, #{createtime}, #{createtimelong},
  #{updateby}, #{updatetime}, #{updatetimelong} );
 
  -- [updateStoreInfo]
- update $table$ set storeName = #{storename},idBrand = #{idbrand},brandName = #{brandname},idStoreType = #{idstoretype},
- deliverSettleKind = #{deliversettlekind},storeCodeInput = #{storecodeinput},storeProvince = #{storeprovince},storeCity = #{storecity},
- storeDistrict = #{storedistrict},storeAddress = #{storeaddress},contractPhone = #{contractphone},storeBossId = #{storebossid},
- companyLicenseNo = #{companylicenseno},companyLicensePicUrl = #{companylicensepicurl},legalPersonIdNo = #{legalpersonidno},legalPersonName = #{legalpersonname},
- enableInvoice = #{enableinvoice},updateBy = #{updateby},updateTime = #{updatetime},updateTimeLong = #{updatetimelong}
-  where id = #{id};
+ update $table$ set storeName = #{storename},idBrand = #{idbrand}, brandName = #{brandname},
+ idStoreType = #{idstoretype}, deliverSettleKind = #{deliversettlekind},storeCodeInput = #{storecodeinput},
+ storeProvince = #{storeprovince},storeCity = #{storecity}, storeDistrict = #{storedistrict},
+ storeAddress = #{storeaddress},locationStr = #{locationstr},contractPhone = #{contractphone},
+ storeBossId = #{storebossid}, companyLicenseNo = #{companylicenseno},companyLicensePicUrl = #{companylicensepicurl},
+ legalPersonIdNo = #{legalpersonidno},legalPersonName = #{legalpersonname},enableInvoice = #{enableinvoice},
+ updateBy = #{updateby},updateTime = #{updatetime},updateTimeLong = #{updatetimelong}
+ where id = #{id};
 
  -- [updateStoreEnableInvoice]
   update $table$ set enableInvoice = #{enableinvoice},updateBy = #{updateby},

+ 124 - 22
conf/初始化业务表.sql

@@ -218,26 +218,6 @@ create table tbStoreInfo1000(
     DEFAULT CHARSET = utf8
     COMMENT = '';
 
-drop table if exists tbStoreInvoiceInfo1000;
-create table tbStoreInvoiceInfo1000(
-                                       id	bigint  default 0,
-                                       taxIdNo	varchar(100) default '',
-                                       companyName	varchar(50) default '',
-                                       defaultTaxItemName	varchar(50) default '',
-                                       defaultTaxItemCode	varchar(100) default '',
-                                       taxRate	decimal(18,4) default 0,
-                                       createBy	bigint  default 0,
-                                       createTime	datetime default NOW(),
-                                       createTimeLong	bigint  default 0,
-                                       updateBy	bigint  default 0,
-                                       updateTime	datetime default NOW(),
-                                       updateTimeLong	bigint  default 0,
-                                       primary key (id)
-)
-    ENGINE = INNODB
-    AUTO_INCREMENT = 1
-    DEFAULT CHARSET = utf8
-    COMMENT = '';
 
 drop table if exists tbStorePlatform1000;
 create table tbStorePlatform1000(
@@ -283,8 +263,8 @@ create table tbStorePlatformRequire1000(
     DEFAULT CHARSET = utf8
     COMMENT = '';
 
-drop table if exists tbStoreInvoiceInfo1000_current;
-create table tbStoreInvoiceInfo1000_current(
+drop table if exists tbStoreInvoiceInfo1000;
+create table tbStoreInvoiceInfo1000(
                                                id	bigint  default 0,
                                                idStore	bigint  default 0,
                                                taxIdNo	varchar(100) default '',
@@ -304,3 +284,125 @@ create table tbStoreInvoiceInfo1000_current(
     AUTO_INCREMENT = 1
     DEFAULT CHARSET = utf8
     COMMENT = '';
+
+
+ALTER TABLE `tbplatforminfo1000`
+    ADD COLUMN `platformCode` varchar(50) NULL AFTER `id`;
+
+
+drop table if exists deBusinessOrder1000_current;
+create table deBusinessOrder1000_current(
+                                            id	bigint  default 0,
+                                            orderName	varchar(50) default '',
+                                            orderCode	varchar(100) default '',
+                                            orderStatus	int default 0,
+                                            incomePlatformId	bigint  default 0,
+                                            incomePlatformName	varchar(50) default '',
+                                            incomePlatformOrderCode	varchar(100) default '',
+                                            incomePlatformOrderTime	datetime default NOW(),
+                                            incomePlatformOrderTimeLong	bigint  default 0,
+                                            suggestDeliverTime	datetime default NOW(),
+                                            suggestDeliverTimeLong	bigint  default 0,
+                                            idStore	bigint  default 0,
+                                            storeName	varchar(50) default '',
+                                            deliverFee	decimal(18,4) default 0,
+                                            deliverDistance	decimal(18,4) default 0,
+                                            deliverAddressAll	varchar(500) default '',
+                                            outGoingPlatformId	bigint  default 0,
+                                            outGoingPlatformName	varchar(50) default '',
+                                            voidFlag	int default 0,
+                                            createBy	bigint  default 0,
+                                            createTime	datetime default NOW(),
+                                            createTimeLong	bigint  default 0,
+                                            updateBy	bigint  default 0,
+                                            updateTime	datetime default NOW(),
+                                            updateTimeLong	bigint  default 0,
+                                            primary key (id)
+)
+    ENGINE = INNODB
+    AUTO_INCREMENT = 1
+    DEFAULT CHARSET = utf8
+    COMMENT = '';
+
+
+
+drop table if exists deOrderFinances1000_current;
+create table deOrderFinances1000_current(
+                                            id	bigint  default 0,
+                                            idOrder	bigint  default 0,
+                                            orderMoney	decimal(18,4) default 0,
+                                            deliverFee	decimal(18,4) default 0,
+                                            orderPlatformSubsidy	decimal(18,4) default 0,
+                                            storeDiscount	decimal(18,4) default 0,
+                                            customerPaid	decimal(18,4) default 0,
+                                            platformServiceFee	decimal(18,4) default 0,
+                                            storeRealCollection	decimal(18,4) default 0,
+                                            createBy	bigint  default 0,
+                                            createTime	datetime default NOW(),
+                                            createTimeLong	bigint  default 0,
+                                            updateBy	bigint  default 0,
+                                            updateTime	datetime default NOW(),
+                                            updateTimeLong	bigint  default 0,
+                                            primary key (id)
+)
+    ENGINE = INNODB
+    AUTO_INCREMENT = 1
+    DEFAULT CHARSET = utf8
+    COMMENT = '';
+
+
+drop table if exists deOrderDeliveryInfo1000_currnet;
+create table deOrderDeliveryInfo1000_currnet(
+                                                id	bigint  default 0,
+                                                idOrder	bigint  default 0,
+                                                deliverProvince	varchar(50) default '',
+                                                deliverCity	varchar(50) default '',
+                                                deliverDistract	varchar(100) default '',
+                                                deliverAddress	varchar(500) default '',
+                                                geoLocationSerial	varchar(100) default '',
+                                                receiveMan	varchar(100) default '',
+                                                contractPhone	varchar(100) default '',
+                                                deliverTimeliness	int default 0,
+                                                bookingDeliverTime	datetime default NOW(),
+                                                customerInvoiceInfo	varchar(100) default '',
+                                                customerMemo	varchar(2000) default '',
+                                                createBy	bigint  default 0,
+                                                createTime	datetime default NOW(),
+                                                createTimeLong	bigint  default 0,
+                                                updateBy	bigint  default 0,
+                                                updateTime	datetime default NOW(),
+                                                updateTimeLong	bigint  default 0,
+                                                primary key (id)
+)
+    ENGINE = INNODB
+    AUTO_INCREMENT = 1
+    DEFAULT CHARSET = utf8
+    COMMENT = '';
+
+
+drop table if exists deOrderDetailItem1000_current;
+create table deOrderDetailItem1000_current(
+                                              id	bigint  default 0,
+                                              idOrder	bigint  default 0,
+                                              itemName	varchar(50) default '',
+                                              itemPrice	decimal(18,4) default 0,
+                                              itemCount	int default 0,
+                                              itemMoney	decimal(18,4) default 0,
+                                              createBy	bigint  default 0,
+                                              createTime	datetime default NOW(),
+                                              createTimeLong	bigint  default 0,
+                                              updateBy	bigint  default 0,
+                                              updateTime	datetime default NOW(),
+                                              updateTimeLong	bigint  default 0,
+                                              primary key (id)
+)
+    ENGINE = INNODB
+    AUTO_INCREMENT = 1
+    DEFAULT CHARSET = utf8
+    COMMENT = '';
+
+
+CREATE OR REPLACE ALGORITHM = UNDEFINED DEFINER = `dbadmin`@`%` SQL SECURITY DEFINER VIEW `v_debusinessorder1000` AS select `debusinessorder1000_current`.`id` AS `id`,`debusinessorder1000_current`.`orderCode` AS `orderCode` from `debusinessorder1000_current` ;
+CREATE OR REPLACE ALGORITHM = UNDEFINED DEFINER = `dbadmin`@`%` SQL SECURITY DEFINER VIEW `v_deorderfinances1000` AS select `deorderfinances1000_current`.`id` AS `id` from `deorderfinances1000_current` ;
+CREATE OR REPLACE ALGORITHM = UNDEFINED DEFINER = `dbadmin`@`%` SQL SECURITY DEFINER VIEW `v_deorderdetailitem1000` AS  select `deorderdetailitem1000_current`.`id` AS `id` from `deorderdetailitem1000_current`;
+CREATE OR REPLACE ALGORITHM = UNDEFINED DEFINER = `dbadmin`@`%` SQL SECURITY DEFINER VIEW `v_deorderdeliveryinfo1000` AS  select `deorderdeliveryinfo1000_currnet`.`id` AS `id` from `deorderdeliveryinfo1000_currnet`;

+ 10 - 2
ddBusiness/src/main/java/com/dderp/business/dao/StoreDao.java

@@ -51,6 +51,7 @@ public interface StoreDao extends DaoRepository {
     @DAOMethod(operator = OperatorType.UPDATE, owait = OperatorWait.ASNYC)
     @SqlId(clazz = StoreDao.class, sql = "voidStoreInfo", table = "tbStoreInfo", params = {1})
     int voidStoreInfo(StoreInfo storeInfo, @DatabaseShardingBy String dataSourceId, @TableShardingBy Long supplierCode);
+
     //endregion
 
     //region 门店发票档案
@@ -62,12 +63,19 @@ public interface StoreDao extends DaoRepository {
     @Sharding(databaseShardingStrategy = SupplierDataBaseShardingStrategy.class, tableShardingStrategy = SupplierTableShardingStrategy.class)
     @DAOMethod(operator = OperatorType.UPDATE, owait = OperatorWait.ASNYC)
     @SqlId(clazz = StoreDao.class, sql = "addStoreInvoiceInfo", table = "tbStoreInvoiceInfo", params = {1})
-    int addStoreInvoiceInfo(StoreInvoiceInfo storeInvoiceInfo, @DatabaseShardingBy String dataSourceId, @TableShardingBy Long supplierCode);
+    @SqlId(clazz = StoreDao.class, sql = "updateStoreEnableInvoice", table = "tbStoreInfo", params = {2})
+    int addStoreInvoiceInfo(StoreInvoiceInfo storeInvoiceInfo,StoreInfo storeInfo, @DatabaseShardingBy String dataSourceId, @TableShardingBy Long supplierCode);
 
     @Sharding(databaseShardingStrategy = SupplierDataBaseShardingStrategy.class, tableShardingStrategy = SupplierTableShardingStrategy.class)
     @DAOMethod(operator = OperatorType.UPDATE, owait = OperatorWait.ASNYC)
     @SqlId(clazz = StoreDao.class, sql = "updateStoreInvoiceInfo", table = "tbStoreInvoiceInfo", params = {1})
-    int updateStoreInvoiceInfo(StoreInvoiceInfo storeInvoiceInfo, @DatabaseShardingBy String dataSourceId, @TableShardingBy Long supplierCode);
+    @SqlId(clazz = StoreDao.class, sql = "updateStoreEnableInvoice", table = "tbStoreInfo", params = {2})
+    int updateStoreInvoiceInfo(StoreInvoiceInfo storeInvoiceInfo,StoreInfo storeInfo, @DatabaseShardingBy String dataSourceId, @TableShardingBy Long supplierCode);
+
+    @Sharding(databaseShardingStrategy = SupplierDataBaseShardingStrategy.class, tableShardingStrategy = SupplierTableShardingStrategy.class)
+    @DAOMethod(operator = OperatorType.UPDATE, owait = OperatorWait.ASNYC)
+    @SqlId(clazz = StoreDao.class, sql = "updateStoreEnableInvoice", table = "tbStoreInfo", params = {1})
+    int updateStoreEnableInvoice(StoreInfo storeInfo, @DatabaseShardingBy String dataSourceId, @TableShardingBy Long supplierCode);
 
     //endregion
 

+ 546 - 16
ddBusiness/src/main/java/com/dderp/business/service/StoreServiceImpl.java

@@ -3,6 +3,7 @@ package com.dderp.business.service;
 import com.dderp.business.dao.StoreDao;
 import com.dderp.common.api.NoSqlKeysService;
 import com.dderp.common.api.PlatformService;
+import com.dderp.common.api.SortBuilderExecutor;
 import com.dderp.common.api.StoreService;
 import com.dderp.common.base.BaseService;
 import com.dderp.common.datas.ESKeys;
@@ -12,6 +13,7 @@ import com.dderp.common.entity.site.ERPTokenUser;
 import com.dderp.common.entity.store.*;
 import com.dderp.common.tool.ERPUtils;
 import com.dySweetFishPlugin.elasticsearch.ESClient;
+import com.dySweetFishPlugin.sql.RMapUtils;
 import com.dySweetFishPlugin.sql.TableIdService;
 import com.dySweetFishPlugin.sql.dao.TunaService;
 import com.sweetfish.convert.json.JsonConvert;
@@ -22,19 +24,32 @@ import com.sweetfish.util.AnyValue;
 import com.sweetfish.util.AutoLoad;
 import com.sweetfish.util.ResourceType;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.lucene.search.join.ScoreMode;
 import org.elasticsearch.action.DocWriteResponse;
+import org.elasticsearch.action.bulk.BulkRequestBuilder;
+import org.elasticsearch.action.bulk.BulkResponse;
+import org.elasticsearch.action.index.IndexRequestBuilder;
 import org.elasticsearch.action.index.IndexResponse;
 import org.elasticsearch.action.support.WriteRequest;
+import org.elasticsearch.action.update.UpdateRequest;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.index.query.BoolQueryBuilder;
 import org.elasticsearch.index.query.Operator;
 import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.index.reindex.DeleteByQueryAction;
+import org.elasticsearch.join.query.JoinQueryBuilders;
 import org.elasticsearch.search.sort.SortBuilders;
 import org.elasticsearch.search.sort.SortOrder;
 import org.rex.RMap;
 
 import javax.annotation.Resource;
-import java.util.List;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+
+import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
 
 @AutoLoad(value = false)
 @Local
@@ -63,9 +78,10 @@ public class StoreServiceImpl extends BaseService implements StoreService {
         storeDao = tunaService.generate(StoreDao.class);
     }
 
+    //region 门店品牌档案
     @Override
     public List<StoreBrand> queryStoreBrandList(RMap params, PageFlipper pageFlipper, long supplierCode) {
-        List<StoreBrand> storeBrandList = searchESList(esClient, jsonConvert,
+        return searchESList(esClient, jsonConvert,
                 StoreBrand.class,
                 null,
                 ((sd) -> {
@@ -89,8 +105,6 @@ public class StoreServiceImpl extends BaseService implements StoreService {
                 }),
                 keysService.getESKey(ESKeys.ES_DELIVER_STORE_BRAND_TYPE, supplierCode),
                 (() -> SortBuilders.fieldSort("id").order(SortOrder.DESC)));
-
-        return storeBrandList;
     }
 
     @Override
@@ -134,7 +148,7 @@ public class StoreServiceImpl extends BaseService implements StoreService {
         if (itemResponse.getResult() == DocWriteResponse.Result.CREATED) {
             storeDao.addStoreBrand(storeBrand, dataSourceId, supplierCode);
         } else {
-            return RetResult.<StoreBrand>errorT().retinfo("创建平台档案失败");
+            return RetResult.<StoreBrand>errorT().retinfo("创建门店品牌失败");
         }
 
         return RetResult.<StoreBrand>successT().result(storeBrand);
@@ -143,55 +157,571 @@ public class StoreServiceImpl extends BaseService implements StoreService {
     @Override
     public RetResult<StoreBrand> uploadBrandLogo(long idStoreBrand, ERPTokenUser currentUser, String dataSourceId, long supplierCode) {
         return null;
+
     }
 
     @Override
     public RetResult<StoreBrand> updateStoreBrand(StoreBrand storeBrand, ERPTokenUser currentUser, String dataSourceId, long supplierCode) {
-        return null;
+        if (StringUtils.isBlank(storeBrand.getBrandName()))
+            return RetResult.<StoreBrand>errorT().retinfo("门店品牌名称不可为空");
+
+        StoreBrand esInfo = this.getStoreBrand(storeBrand.getId(), supplierCode);
+        if (esInfo == null)
+            return RetResult.<StoreBrand>errorT().retinfo("未找到此门店品牌");
+
+        //先查一下有没有重名的平台信息(防止修改名称改重)
+        StoreBrand checkNameInfo = this.getESOneInfo(esClient, jsonConvert,
+                StoreBrand.class,
+                (a) -> {
+                    BoolQueryBuilder qb = QueryBuilders.boolQuery().must(QueryBuilders.typeQuery(ESKeys.ES_DELIVER_STORE_BRAND_TYPE));
+                    qb.must(QueryBuilders.termQuery("brandName.raw", storeBrand.getBrandName()))
+                            .mustNot(QueryBuilders.idsQuery(String.valueOf(storeBrand.getId())));
+
+                    return qb;
+                },
+                keysService.getESKey(ESKeys.ES_DELIVER_STORE_BRAND_INDEX, supplierCode),
+                null);
+
+        if (checkNameInfo != null) return RetResult.<StoreBrand>errorT().retinfo("已存在同名的门店品牌");
+
+        esInfo.setBrandName(storeBrand.getBrandName());
+        esInfo.setStartingPrice(storeBrand.getStartingPrice());
+        esInfo.setPackagingFee(storeBrand.getPackagingFee());
+        esInfo.setBrandMemo(storeBrand.getBrandMemo());
+        StoreBrand.update(esInfo, currentUser.getId());
+        try {
+            UpdateRequest updateRequest = new UpdateRequest(keysService.getESKey(ESKeys.ES_DELIVER_STORE_BRAND_INDEX, supplierCode),
+                    ESKeys.ES_DELIVER_STORE_BRAND_TYPE, String.valueOf(esInfo.getId()))
+                    .doc(jsonBuilder()
+                            .startObject()
+                            .field("brandName", esInfo.getBrandName())
+                            .field("startingPrice", esInfo.getStartingPrice())
+                            .field("packagingFee", esInfo.getPackagingFee())
+                            .field("brandMemo", esInfo.getBrandMemo())
+                            .field("updateTimeLong", esInfo.getUpdateTimeLong())
+                            .field("updateBy", esInfo.getUpdateBy())
+                            .endObject())
+                    .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
+
+            esClient.getClient().update(updateRequest).get();
+        } catch (IOException | InterruptedException | ExecutionException e) {
+            logger.error("修改门店品牌[" + esInfo.getId() + "出错:" + e.getMessage(), e);
+        }
+        storeDao.updateStoreBrand(esInfo, dataSourceId, supplierCode);
+        return RetResult.successT();
     }
 
     @Override
     public RetResult<StoreBrand> voidStoreBrand(StoreBrand storeBrand, ERPTokenUser currentUser, String dataSourceId, long supplierCode) {
-        return null;
+        StoreBrand esInfo = this.getStoreBrand(storeBrand.getId(), supplierCode);
+        if (esInfo == null) {
+            return RetResult.<StoreBrand>errorT().retinfo("未找到此门店品牌");
+        }
+        esInfo.setVoidFlag(storeBrand.getVoidFlag());
+        StoreBrand.update(esInfo, currentUser.getId());
+        try {
+            UpdateRequest updateRequest = new UpdateRequest(keysService.getESKey(ESKeys.ES_DELIVER_STORE_BRAND_INDEX, supplierCode),
+                    ESKeys.ES_DELIVER_STORE_BRAND_TYPE, String.valueOf(esInfo.getId()))
+                    .doc(jsonBuilder()
+                            .startObject()
+                            .field("voidFlag", esInfo.getVoidFlag())
+                            .field("updateTimeLong", esInfo.getUpdateTimeLong())
+                            .field("updateBy", esInfo.getUpdateBy())
+                            .endObject())
+                    .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
+
+            esClient.getClient().update(updateRequest).get();
+        } catch (IOException | InterruptedException | ExecutionException e) {
+            logger.error("禁用或启用门店品牌[" + esInfo.getId() + "出错:" + e.getMessage(), e);
+        }
+        storeDao.voidStoreBrand(esInfo, dataSourceId, supplierCode);
+        return RetResult.successT();
     }
+    //endregion
 
     @Override
     public List<ViewStoreInfo> queryViewStoreInfo(RMap params, PageFlipper pageFlipper, long supplierCode) {
-        return null;
+        Set<Long> idStores = new HashSet<>();
+        List<StoreInfo> storeInfoList = searchESList(esClient, jsonConvert,
+                StoreInfo.class,
+                null,
+                ((sd) -> {
+                    BoolQueryBuilder qb = QueryBuilders.boolQuery();
+                    qb = qb.must(QueryBuilders.typeQuery(ESKeys.ES_DELIVER_STORE_INFO_TYPE));
+
+                    if (ERPUtils.mapContainKey(params, "storeName")) {
+                        String storeName = params.getString("storeName");
+                        BoolQueryBuilder qbStoreName = QueryBuilders.boolQuery()
+                                .should(QueryBuilders.matchQuery("storeName", storeName).analyzer("query_ansj").operator(Operator.AND))
+                                .should(QueryBuilders.termQuery("storeName.number", storeName.toLowerCase()))
+                                .should(QueryBuilders.matchQuery("storeName.letter", storeName.toLowerCase()).operator(Operator.AND));
+                        qb = qb.must(qbStoreName);
+                    }
+
+                    if (ERPUtils.mapContainKey(params, "idBrand")) {
+                        qb = qb.must(QueryBuilders.termQuery("idBrand", params.getLong("idBrand")));
+                    }
+
+                    if (ERPUtils.mapContainKey(params, "idStoreType")) {
+                        qb = qb.must(QueryBuilders.termQuery("idStoreType", params.getLong("idStoreType")));
+                    }
+
+                    if (ERPUtils.mapContainKey(params, "deliverSettleKind")) {
+                        qb = qb.must(QueryBuilders.termQuery("deliverSettleKind", params.getInt("deliverSettleKind")));
+                    }
+
+                    if (ERPUtils.mapContainKey(params, "storeCodeInput")) {
+                        String storeCodeInput = params.getString("storeCodeInput");
+                        BoolQueryBuilder qbStoreCode = QueryBuilders.boolQuery()
+                                .should(QueryBuilders.matchQuery("storeCodeInput", storeCodeInput).analyzer("query_ansj").operator(Operator.AND))
+                                .should(QueryBuilders.termQuery("storeCodeInput.number", storeCodeInput.toLowerCase()))
+                                .should(QueryBuilders.matchQuery("storeCodeInput.letter", storeCodeInput.toLowerCase()).operator(Operator.AND));
+                        qb = qb.must(qbStoreCode);
+                    }
+
+                    if (ERPUtils.mapContainKey(params, "contractPhone")) {
+                        String phone = params.getString("contractPhone");
+                        qb = qb.must(QueryBuilders.termQuery("contractPhone", phone));
+                    }
+
+                    if (ERPUtils.mapContainKey(params, "voidFlag")) {
+                        qb = qb.must(QueryBuilders.termQuery("voidFlag", params.getInt("voidFlag")));
+                    }
+
+                    return qb;
+                }),
+                ((op) -> {
+                    idStores.add(op.getId());
+                }),
+                keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_INDEX, supplierCode),
+                pageFlipper,
+                (() -> SortBuilders.fieldSort("id").order(SortOrder.DESC))
+        );
+
+        long[] idStoreArray = idStores.stream().mapToLong(Long::valueOf).toArray();
+        String idStoreStr = idStores.stream().map(String::valueOf).collect(Collectors.joining(","));
+        Map<Long, List<StorePlatform>> storePlatformMap = searchESMapList(idStoreArray, esClient, jsonConvert,
+                StorePlatform.class,
+                null,
+                ((sd) -> {
+                    BoolQueryBuilder qb = QueryBuilders.boolQuery();
+                    qb = qb.must(QueryBuilders.typeQuery(ESKeys.ES_DELIVER_STORE_PLATFORM_TYPE))
+                            .must(QueryBuilders.termsQuery("idStore", idStoreStr.split(",")));
+
+                    return qb;
+                }),
+                (StorePlatform::getIdStore),
+                new String[]{keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_INDEX, supplierCode)},
+                (SortBuilderExecutor) null);
+
+        List<ViewStoreInfo> viewStoreInfoList = new ArrayList<>();
+
+        storeInfoList.forEach(x -> {
+            x.setPlatformList(storePlatformMap.get(x.getId()));
+            ViewStoreInfo viewStoreInfo = new ViewStoreInfo(x);
+            viewStoreInfoList.add(viewStoreInfo);
+        });
+
+        return viewStoreInfoList;
     }
 
     @Override
-    public ViewStoreInfo getViewStoreInfo(long idStore, long supplierCode, int withInvoice) {
-        return null;
+    public ViewStoreInfo getViewStoreInfo(long idStore, long supplierCode, boolean readInvoice, boolean readEmployee, boolean readPlatform) {
+        StoreInfo storeInfo = getESOneInfo(esClient, jsonConvert, StoreInfo.class,
+                String.valueOf(idStore),
+                keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_INDEX, supplierCode),
+                ESKeys.ES_DELIVER_STORE_INFO_TYPE,
+                null
+        );
+
+        if (readInvoice) {
+            StoreInvoiceInfo storeInvoiceInfo = this.getStoreInvoiceInfo(idStore,supplierCode);
+            storeInfo.setInvoiceInfo(storeInvoiceInfo);
+        }
+
+        if (readEmployee) { //先不用
+
+        }
+
+        if (readPlatform) {
+            List<StorePlatform> platformList = searchESList(esClient,jsonConvert,StorePlatform.class,
+                    null,
+                    ((sd) -> {
+                        BoolQueryBuilder qb = QueryBuilders.boolQuery();
+                        qb = qb.must(QueryBuilders.typeQuery(ESKeys.ES_DELIVER_STORE_PLATFORM_TYPE))
+                                .must(QueryBuilders.termQuery("idStore",idStore));
+
+                        return qb;
+                    }),
+                    keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_INDEX, supplierCode),
+                    (SortBuilderExecutor) null
+            );
+            storeInfo.setPlatformList(platformList);
+        }
+
+        return new ViewStoreInfo(storeInfo);
     }
 
     @Override
     public RetResult<StoreInfo> addStoreInfo(StoreInfo storeInfo, ERPTokenUser currentUser, String dataSourceId, long supplierCode) {
-        return null;
+        if (StringUtils.isBlank(storeInfo.getStoreName()))
+            return RetResult.<StoreInfo>errorT().retinfo("门店名称不可为空");
+
+        //其他是否必须输入 前端判断
+        //先查一下有没有重名的平台信息
+        StoreBrand esInfo = this.getESOneInfo(esClient, jsonConvert,
+                StoreBrand.class,
+                (a) -> {
+                    BoolQueryBuilder qb = QueryBuilders.boolQuery().must(QueryBuilders.typeQuery(ESKeys.ES_DELIVER_STORE_INFO_TYPE));
+                    qb.must(QueryBuilders.termQuery("storeName.raw", storeInfo.getStoreName()));
+
+                    return qb;
+                },
+                keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_INDEX, supplierCode),
+                null);
+
+        if (esInfo != null) return RetResult.<StoreInfo>errorT().retinfo("已存在同名的门店");
+
+        storeInfo.setId(tableIdService.getTableIdMulti("tbStoreInfo.id", 1, dataSourceId, String.valueOf(supplierCode)));
+        StoreInfo.create(storeInfo, currentUser.getId());
+        storeInfo.setEnableInvoice(0);
+
+        IndexResponse itemResponse = esClient.getClient()
+                .prepareIndex(keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_TYPE, supplierCode), ESKeys.ES_DELIVER_STORE_INFO_INDEX)
+                .setId(String.valueOf(storeInfo.getId()))
+                .setSource(jsonConvert.convertTo(storeInfo), XContentType.JSON)
+                .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
+                .get();
+
+        if (itemResponse.getResult() == DocWriteResponse.Result.CREATED) {
+            storeDao.addStoreInfo(storeInfo, dataSourceId, supplierCode);
+        } else {
+            return RetResult.<StoreInfo>errorT().retinfo("创建门店失败");
+        }
+
+        return RetResult.successT();
+    }
+
+    @Override
+    public StoreInvoiceInfo getStoreInvoiceInfo(long idStore, long supplierCode) {
+        return this.getESOneInfo(esClient, jsonConvert,
+                StoreInvoiceInfo.class,
+                (sd) -> {
+                    BoolQueryBuilder qb = QueryBuilders.boolQuery().must(QueryBuilders.typeQuery(ESKeys.ES_DELIVER_STORE_INVOICE_INFO_TYPE));
+                    qb.must(QueryBuilders.termQuery("idStore", idStore));
+                    return qb;
+                },
+                keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_TYPE, supplierCode),
+                null);
     }
 
     @Override
     public RetResult<StoreInvoiceInfo> configStoreInvoiceInfo(StoreInvoiceInfo invoiceInfo, int enableInvoice, ERPTokenUser currentUser, String dataSourceId, long supplierCode) {
-        return null;
+        StoreInfo esStoreInfo = this.getViewStoreInfo(invoiceInfo.getIdStore(), supplierCode, false, false, false).getStoreInfo();
+        if (esStoreInfo == null)
+            return RetResult.<StoreInvoiceInfo>errorT().retinfo("未找到门店信息");
+        esStoreInfo.setEnableInvoice(enableInvoice);
+        StoreInfo.update(esStoreInfo, currentUser.getId());
+        try {
+            UpdateRequest updateRequest = new UpdateRequest(
+                    keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_INDEX, supplierCode),
+                    ESKeys.ES_DELIVER_STORE_INFO_TYPE, String.valueOf(esStoreInfo.getId()))
+                    .doc(jsonBuilder()
+                            .startObject()
+                            .field("enableInvoice", esStoreInfo.getEnableInvoice())
+                            .field("updateTimeLong", esStoreInfo.getUpdateTimeLong())
+                            .field("updateBy", esStoreInfo.getUpdateBy())
+                            .endObject())
+                    .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
+            esClient.getClient().update(updateRequest).get();
+
+        } catch (IOException | InterruptedException | ExecutionException e) {
+            logger.error("启用或停用门店开票信息[" + esStoreInfo.getId() + "出错:" + e.getMessage(), e);
+            RetResult.<StoreInvoiceInfo>errorT().retinfo("启用或停用门店开票信息[" + esStoreInfo.getId() + "出错:");
+        }
+        if (enableInvoice == 0) { //停用门店开票 不动发票信息
+            storeDao.updateStoreEnableInvoice(esStoreInfo, dataSourceId, supplierCode);
+            return RetResult.successT();
+        }
+        // 启用开票
+        StoreInvoiceInfo esInvoice = getStoreInvoiceInfo(invoiceInfo.getIdStore(), supplierCode);
+        if (esInvoice == null) { // 未设置过发票信息 需要新增
+            invoiceInfo.setId(tableIdService.getTableIdMulti("tbStoreInvoiceInfo.id", 1, dataSourceId, String.valueOf(supplierCode)));
+            StoreInvoiceInfo.create(invoiceInfo, currentUser.getId());
+            IndexResponse itemResponse = esClient.getClient()
+                    .prepareIndex(
+                            keysService.getESKey(ESKeys.ES_DELIVER_STORE_INVOICE_INFO_TYPE, supplierCode), ESKeys.ES_DELIVER_STORE_INFO_INDEX)
+                    .setId(String.valueOf(invoiceInfo.getId()))
+                    .setParent(String.valueOf(invoiceInfo.getIdStore()))
+                    .setSource(jsonConvert.convertTo(invoiceInfo), XContentType.JSON)
+                    .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
+                    .get();
+
+            if (itemResponse.getResult() == DocWriteResponse.Result.CREATED) {
+                storeDao.addStoreInvoiceInfo(invoiceInfo, esStoreInfo, dataSourceId, supplierCode);
+            } else {
+                return RetResult.<StoreInvoiceInfo>errorT().retinfo("门店启用开票失败");
+            }
+        } else {
+            esInvoice.setTaxIdNo(invoiceInfo.getTaxIdNo());
+            esInvoice.setCompanyName(invoiceInfo.getCompanyName());
+            esInvoice.setDefaultTaxItemCode(invoiceInfo.getDefaultTaxItemCode());
+            esInvoice.setDefaultTaxItemName(invoiceInfo.getDefaultTaxItemName());
+            esInvoice.setTaxRate(invoiceInfo.getTaxRate());
+            StoreInvoiceInfo.update(esInvoice, currentUser.getId());
+
+            try {
+                UpdateRequest updateInvoiceRequest = new UpdateRequest(
+                        keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_INDEX, supplierCode),
+                        ESKeys.ES_DELIVER_STORE_INVOICE_INFO_TYPE, String.valueOf(esStoreInfo.getId()))
+                        .doc(jsonBuilder()
+                                .startObject()
+                                .field("taxIdNo", esInvoice.getTaxIdNo())
+                                .field("companyName", esInvoice.getCompanyName())
+                                .field("defaultTaxItemName", esInvoice.getDefaultTaxItemName())
+                                .field("defaultTaxItemCode", esInvoice.getDefaultTaxItemCode())
+                                .field("taxRate", esInvoice.getTaxRate())
+                                .field("updateTimeLong", esInvoice.getUpdateTimeLong())
+                                .field("updateBy", esInvoice.getUpdateBy())
+                                .endObject())
+                        .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
+                esClient.getClient().update(updateInvoiceRequest).get();
+
+            } catch (IOException | InterruptedException | ExecutionException e) {
+                logger.error("门店启用开票信息[" + esStoreInfo.getId() + "出错" + e.getMessage(), e);
+                return RetResult.<StoreInvoiceInfo>errorT().retinfo("门店启用开票失败");
+            }
+            storeDao.updateStoreInvoiceInfo(esInvoice, esStoreInfo, dataSourceId, supplierCode);
+        }
+        return RetResult.successT();
     }
 
     @Override
     public RetResult<StoreInfo> updateStoreInfo(StoreInfo storeInfo, ERPTokenUser currentUser, String dataSourceId, long supplierCode) {
-        return null;
+        if (StringUtils.isBlank(storeInfo.getStoreName()))
+            return RetResult.<StoreInfo>errorT().retinfo("门店名称不可为空");
+
+        StoreInfo esInfo = this.getViewStoreInfo(storeInfo.getId(), supplierCode, false, false, false).getStoreInfo();
+        if (esInfo == null) {
+            return RetResult.<StoreInfo>errorT().retinfo("未找到此门店品牌");
+        }
+        //先查一下有没有重名的门店信息(防止修改名称改重)同行业门店不同地区门店名可以重
+        StoreBrand checkNameInfo = this.getESOneInfo(esClient, jsonConvert,
+                StoreBrand.class,
+                (a) -> {
+                    BoolQueryBuilder qb = QueryBuilders.boolQuery().must(QueryBuilders.typeQuery(ESKeys.ES_DELIVER_STORE_INFO_TYPE));
+                    qb.must(QueryBuilders.termQuery("storeName.raw", esInfo.getStoreName()))
+                            .mustNot(QueryBuilders.idsQuery(String.valueOf(esInfo.getId())));
+
+                    return qb;
+                },
+                keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_INDEX, supplierCode),
+                null);
+
+        if (checkNameInfo != null) return RetResult.<StoreInfo>errorT().retinfo("已存在同名的门店");
+
+        esInfo.setStoreName(storeInfo.getStoreName());
+        esInfo.setIdBrand(storeInfo.getIdBrand());
+        esInfo.setBrandName(storeInfo.getBrandName());
+        esInfo.setIdStoreType(storeInfo.getIdStoreType());
+        esInfo.setDeliverSettleKind(storeInfo.getDeliverSettleKind());
+        esInfo.setStoreCodeInput(storeInfo.getStoreCodeInput());
+        esInfo.setStoreProvince(storeInfo.getStoreProvince());
+        esInfo.setStoreCity(storeInfo.getStoreCity());
+        esInfo.setStoreDistrict(storeInfo.getStoreDistrict());
+        esInfo.setStoreAddress(storeInfo.getStoreAddress());
+        esInfo.setLocationStr(storeInfo.getLocationStr());
+        esInfo.setContractPhone(storeInfo.getContractPhone());
+        esInfo.setStoreBossId(storeInfo.getStoreBossId());
+        StoreInfo.update(esInfo, currentUser.getId());
+        try {
+            UpdateRequest updateRequest = new UpdateRequest(keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_INDEX, supplierCode),
+                    ESKeys.ES_DELIVER_STORE_INFO_TYPE, String.valueOf(esInfo.getId()))
+                    .doc(jsonBuilder()
+                            .startObject()
+                            .field("storeName", esInfo.getStoreName())
+                            .field("idBrand", esInfo.getIdBrand())
+                            .field("brandName", esInfo.getBrandName())
+                            .field("idStoreType", esInfo.getIdStoreType())
+                            .field("deliverSettleKind", esInfo.getDeliverSettleKind())
+                            .field("storeCodeInput", esInfo.getStoreCodeInput())
+                            .field("storeProvince", esInfo.getStoreProvince())
+                            .field("storeCity", esInfo.getStoreCity())
+                            .field("storeDistrict", esInfo.getStoreDistrict())
+                            .field("storeAddress", esInfo.getStoreAddress())
+                            .field("locationStr", esInfo.getLocationStr())
+                            .field("contractPhone", esInfo.getContractPhone())
+                            .field("storeBossId", esInfo.getStoreBossId())
+                            .field("updateTimeLong", esInfo.getUpdateTimeLong())
+                            .field("updateBy", esInfo.getUpdateBy())
+                            .endObject())
+                    .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
+
+            esClient.getClient().update(updateRequest).get();
+        } catch (IOException | InterruptedException | ExecutionException e) {
+            logger.error("修改门店[" + esInfo.getId() + "出错:" + e.getMessage(), e);
+        }
+        storeDao.updateStoreInfo(esInfo, dataSourceId, supplierCode);
+        return RetResult.successT();
     }
 
     @Override
     public RetResult<StoreInfo> voidStoreInfo(StoreInfo storeInfo, ERPTokenUser currentUser, String dataSourceId, long supplierCode) {
-        return null;
+        StoreInfo esInfo = this.getViewStoreInfo(storeInfo.getId(), supplierCode, false, false, false).getStoreInfo();
+        if (esInfo == null) {
+            return RetResult.<StoreInfo>errorT().retinfo("未找到此门店");
+        }
+        esInfo.setVoidFlag(storeInfo.getVoidFlag());
+        StoreInfo.update(esInfo, currentUser.getId());
+        try {
+            UpdateRequest updateRequest = new UpdateRequest(keysService.getESKey(ESKeys.ES_DELIVER_STORE_INFO_INDEX, supplierCode),
+                    ESKeys.ES_DELIVER_STORE_INFO_TYPE, String.valueOf(esInfo.getId()))
+                    .doc(jsonBuilder()
+                            .startObject()
+                            .field("voidFlag", esInfo.getVoidFlag())
+                            .field("updateTimeLong", esInfo.getUpdateTimeLong())
+                            .field("updateBy", esInfo.getUpdateBy())
+                            .endObject())
+                    .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
+
+            esClient.getClient().update(updateRequest).get();
+        } catch (IOException | InterruptedException | ExecutionException e) {
+            logger.error("禁用或启用门店[" + esInfo.getId() + "出错:" + e.getMessage(), e);
+        }
+        storeDao.voidStoreInfo(esInfo, dataSourceId, supplierCode);
+        return RetResult.successT();
+    }
+
+    //region 门店平台
+
+
+    @Override
+    public StorePlatform getStoreStorePlatformInfo(long id, long supplierCode) {
+        return this.getESOneInfo(esClient, jsonConvert, StorePlatform.class,
+                String.valueOf(id),
+                keysService.getESKey(ESKeys.ES_DELIVER_PLATFORM_INFO_INDEX, supplierCode),
+                ESKeys.ES_DELIVER_STORE_PLATFORM_TYPE,
+                null);
     }
 
     @Override
     public RetResult<StorePlatform> addStorePlatform(StorePlatform storePlatform, ERPTokenUser currentUser, String dataSourceId, long supplierCode) {
-        return null;
+        StorePlatform esInfo = this.getESOneInfo(esClient, jsonConvert,
+                StorePlatform.class,
+                (a) -> {
+                    BoolQueryBuilder qb = QueryBuilders.boolQuery().must(QueryBuilders.typeQuery(ESKeys.ES_DELIVER_STORE_PLATFORM_TYPE));
+                    qb.must(QueryBuilders.termQuery("idPlatformInfo", storePlatform.getIdPlatformInfo()));
+                    return qb;
+                },
+                keysService.getESKey(ESKeys.ES_DELIVER_STORE_PLATFORM_INDEX, supplierCode),
+                null);
+        if (esInfo != null)
+            return RetResult.<StorePlatform>errorT().retinfo("此平台已开通:" + storePlatform.getPlatformName());
+
+        storePlatform.setId(tableIdService.getTableIdMulti("tbStorePlatform.id", 1, dataSourceId, String.valueOf(supplierCode)));
+        StorePlatform.create(storePlatform, currentUser.getId());
+        storePlatform.setEnableStatue(0);
+
+        BulkRequestBuilder bulkRequest = esClient.getClient().prepareBulk().setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
+
+        bulkRequest.add(esClient.getClient().prepareIndex(
+                        keysService.getESKey(ESKeys.ES_DELIVER_STORE_PLATFORM_INDEX, supplierCode), ESKeys.ES_DELIVER_STORE_PLATFORM_TYPE)
+                .setId(String.valueOf(storePlatform.getId()))
+                .setSource(jsonConvert.convertTo(storePlatform), XContentType.JSON));
+
+        storePlatform.getRequireList().forEach(x -> {
+            x.setId(tableIdService.getTableIdMulti("tbStorePlatformRequire.id", 1, dataSourceId, String.valueOf(supplierCode)));
+            x.setIdStore(storePlatform.getIdStore());
+            x.setIdStorePlatform(storePlatform.getId());
+            StorePlatformRequire.create(x, currentUser.getId());
+
+            bulkRequest.add(esClient.getClient().prepareIndex(
+                            keysService.getESKey(ESKeys.ES_DELIVER_STORE_PLATFORM_INDEX, supplierCode), ESKeys.ES_DELIVER_STORE_PLATFORM_REQUIRE_TYPE)
+                    .setId(String.valueOf(x.getId()))
+                    .setParent(String.valueOf(storePlatform.getId()))
+                    .setSource(jsonConvert.convertTo(storePlatform), XContentType.JSON));
+        });
+
+        BulkResponse bulkResponse = bulkRequest.get();
+
+        if (bulkResponse.hasFailures()) {
+            logger.error("门店开通平台出错:" + bulkResponse.buildFailureMessage());
+            return RetResult.<StorePlatform>errorT().retinfo("门店开通平台出错:" + storePlatform.getPlatformName());
+        } else {
+            logger.info("门店开通平台成功");
+            //写数据库
+            storeDao.addStorePlatform(storePlatform, storePlatform.getRequireList(), dataSourceId, supplierCode);
+            return RetResult.successT();
+        }
     }
 
     @Override
     public RetResult<StorePlatform> configStorePlatform(StorePlatform storePlatform, ERPTokenUser currentUser, String dataSourceId, long supplierCode) {
-        return null;
+        StorePlatform esInfo = this.getStoreStorePlatformInfo(storePlatform.getId(), supplierCode);
+        if (esInfo == null) {
+            return RetResult.<StorePlatform>errorT().retinfo("未找到此开通平台");
+        }
+
+        esInfo.setIdStore(storePlatform.getIdPlatformInfo());
+        esInfo.setPlatformName(storePlatform.getPlatformName());
+        esInfo.setPlatformType(storePlatform.getPlatformType());
+        esInfo.setEnableStatue(storePlatform.getEnableStatue());
+        StorePlatform.update(esInfo, currentUser.getId());
+
+        BulkRequestBuilder bulkRequest = esClient.getClient().prepareBulk().setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
+        UpdateRequest updateRequest = null;
+        try {
+            updateRequest = new UpdateRequest(keysService.getESKey(ESKeys.ES_DELIVER_STORE_PLATFORM_INDEX, supplierCode),
+                    ESKeys.ES_DELIVER_STORE_PLATFORM_TYPE, String.valueOf(esInfo.getId()))
+                    .doc(jsonBuilder()
+                            .startObject()
+                            .field("idPlatformInfo", esInfo.getIdPlatformInfo())
+                            .field("platformName", esInfo.getPlatformName())
+                            .field("platformType", esInfo.getPlatformType())
+                            .field("enableStatue", esInfo.getEnableStatue())
+                            .field("updateTimeLong", esInfo.getUpdateTimeLong())
+                            .field("updateBy", esInfo.getUpdateBy())
+                            .endObject());
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        bulkRequest.add(updateRequest);
+
+        storePlatform.getRequireList().forEach(x -> {
+            if (x.getId() <= 0) {
+                x.setId(tableIdService.getTableIdMulti("tbStorePlatformRequire.id", 1, dataSourceId, String.valueOf(supplierCode)));
+                StorePlatformRequire.create(x, currentUser.getId());
+            }
+            x.setIdStore(storePlatform.getIdStore());
+            x.setIdStorePlatform(storePlatform.getIdPlatformInfo());
+            StorePlatformRequire.update(x, currentUser.getId());
+            bulkRequest.add(esClient.getClient().prepareIndex(
+                            keysService.getESKey(ESKeys.ES_DELIVER_STORE_PLATFORM_INDEX, supplierCode), ESKeys.ES_DELIVER_STORE_PLATFORM_REQUIRE_TYPE)
+                    .setId(String.valueOf(x.getId()))
+                    .setParent(String.valueOf(storePlatform.getId()))
+                    .setSource(jsonConvert.convertTo(storePlatform), XContentType.JSON));
+        });
+
+        BoolQueryBuilder qbOrderPart = QueryBuilders.boolQuery()
+                .must(QueryBuilders.typeQuery(ESKeys.ES_DELIVER_STORE_PLATFORM_REQUIRE_TYPE))
+                .must(QueryBuilders.termQuery("idStorePlatform", esInfo.getId()));
+        DeleteByQueryAction.INSTANCE.newRequestBuilder(esClient.getClient())
+                .refresh(true)
+                .source(keysService.getESKey(ESKeys.ES_DELIVER_STORE_PLATFORM_INDEX, supplierCode))
+                .filter(qbOrderPart)
+                .get();
+
+        BulkResponse bulkResponse = bulkRequest.get();
+
+        if (bulkResponse.hasFailures()) {
+            logger.error("门店配置平台出错:" + bulkResponse.buildFailureMessage());
+            return RetResult.<StorePlatform>errorT().retinfo("门店配置平台出错:" + storePlatform.getPlatformName());
+        } else {
+            logger.info("门店配置平台成功");
+            //写数据库
+            storeDao.updateStorePlatform(esInfo, storePlatform.getRequireList(), dataSourceId, supplierCode);
+            return RetResult.successT();
+        }
     }
+    //endregion
 }

+ 176 - 0
ddBusiness/src/main/java/com/dderp/business/service/flycat/DouyinServiceImpl.java

@@ -0,0 +1,176 @@
+package com.dderp.business.service.flycat;
+
+import com.dderp.common.api.flycat.DouyinService;
+import com.dderp.common.base.BaseService;
+import com.dderp.common.datas.ERPModule;
+import com.dderp.common.datas.RedisKeys;
+import com.dderp.common.entity.base.ProcessStringItem;
+import com.dderp.common.entity.invoke.douyin.DouyinTokenRequest;
+import com.dderp.common.entity.invoke.douyin.DouyinTokenResponse;
+import com.dderp.common.entity.order.BusinessOrder;
+import com.dderp.common.http.HttpTools;
+import com.dySweetFishPlugin.redis.RedisService;
+import com.dySweetFishPlugin.tool.lang.ThreadFactoryWithNamePrefix;
+import com.sweetfish.convert.json.JsonConvert;
+import com.sweetfish.service.Local;
+import com.sweetfish.service.RetResult;
+import com.sweetfish.util.AnyValue;
+import com.sweetfish.util.AutoLoad;
+import com.sweetfish.util.ResourceType;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.annotation.Resource;
+import java.time.Instant;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.*;
+
+@AutoLoad(false)
+@Local
+@ResourceType(DouyinService.class)
+public class DouyinServiceImpl extends BaseService implements DouyinService {
+
+    @Resource
+    private RedisService redisService;
+
+    private ScheduledThreadPoolExecutor accessTokenThread;
+    private String runEnvironment;
+
+    @Resource
+    private JsonConvert jsonConvert;
+
+    @Resource(name = "property.douyin.appId")
+    private String appId;
+
+    @Resource(name = "property.douyin.appSecret")
+    private String appSecret;
+
+    @Resource(name = "property.douyin.reqUrl")
+    private String reqUrl;
+
+
+    @Override
+    public void start(AnyValue config) {
+        boolean master = false;
+        AnyValue masterValue = config.getAnyValue("master");
+        if (masterValue != null) {
+            master = masterValue.getBoolValue("value");
+        }
+
+        AnyValue environmentValue = config.getAnyValue("environment");
+        if (environmentValue != null) {
+            runEnvironment = environmentValue.getValue("value");
+        } else {
+            runEnvironment = "dev";
+        }
+
+        if (master) {
+            if (StringUtils.equalsIgnoreCase(runEnvironment, "dev")) {
+                //开发环境
+                accessTokenThread = null;
+            } else {
+                //启动的时候10分钟之后获取,然后每隔1个半小时刷新一次token
+                //为什么10分钟,因为企点是每10分钟发送ticket,没有ticket的情况通过ticket是换不到开发商token的
+                accessTokenThread = new ScheduledThreadPoolExecutor(1,
+                        new ThreadFactoryWithNamePrefix("[抖音Access_Token线程池]"));
+
+                long tokenInitialDelay = 30;
+
+                //判断上次刷新token的时间,
+                if (redisService.exists(RedisKeys.KEY_DOUYIN_LASTTOKENDATE)) {
+                    long lastTime = Long.parseLong(redisService.get(RedisKeys.KEY_DOUYIN_LASTTOKENDATE));
+                    int diffSeconds = (int) ((System.currentTimeMillis() - lastTime) / 1000);
+
+                    if (diffSeconds <= 4800) {
+                        tokenInitialDelay = 4800 - diffSeconds;
+                        if (tokenInitialDelay < 30) {
+                            tokenInitialDelay = 30;
+                        }
+                    }
+                }
+
+                accessTokenThread.scheduleWithFixedDelay(() -> {
+                    scanRefreshToken();
+                    //写入当前时间
+                    redisService.set(RedisKeys.KEY_DOUYIN_LASTTOKENDATE, String.valueOf(Date.from(Instant.now()).getTime()));
+                }, tokenInitialDelay, 5400, TimeUnit.SECONDS);
+            }
+        }
+    }
+
+    @Override
+    public void destroy(AnyValue config) {
+        if (accessTokenThread != null) {
+            accessTokenThread.shutdownNow();
+        }
+    }
+
+    private void scanRefreshToken() {
+        DouyinTokenResponse dyToken = null;
+        //抖音有可能获取不到token,这里循环获取,直到有值?
+        do {
+            dyToken = this.requestAccessToken(appId, appSecret);
+
+        } while ((dyToken == null) || (StringUtils.isEmpty(dyToken.getData().getAccess_token())));
+
+        redisService.set(RedisKeys.KEY_DOUYIN_ACCESSTOKEN, dyToken.getData().getAccess_token());
+        logger.info("抖音服务刷新token:" + dyToken.getData().getAccess_token());
+    }
+
+    private DouyinTokenResponse requestAccessToken(String appId, String appSecret) {
+        DouyinTokenRequest tokenRequest = new DouyinTokenRequest.Builder()
+                .client_key(appId)
+                .client_secret(appSecret)
+                .build();
+        Map<String, String> header = new HashMap<>();
+        header.put("Content-Type", "application/json");
+
+        try {
+            String responseStr = HttpTools.postHttpContentAsync(reqUrl + "/oauth/client_token/", header,
+                    jsonConvert.convertTo(tokenRequest)).get(5, TimeUnit.SECONDS);
+
+            return jsonConvert.convertFrom(DouyinTokenResponse.class, responseStr);
+        } catch (InterruptedException | ExecutionException | TimeoutException e) {
+            logger.error(e.getMessage(), e);
+        }
+        return null;
+    }
+
+    private String getAccessToken() {
+        String token = redisService.get(RedisKeys.KEY_DOUYIN_ACCESSTOKEN);
+        if (StringUtils.isBlank(token)) {
+            //token不存在,直接刷新一下
+            this.scanRefreshToken();
+            token = redisService.get(RedisKeys.KEY_DOUYIN_ACCESSTOKEN);
+        }
+
+        return token;
+    }
+
+    private String postInvoker(String subUrl, String body) {
+        Map<String, String> header = new HashMap<>();
+        header.put("access-token", getAccessToken());
+        header.put("log_id", String.valueOf(new Date().getTime()));
+        header.put("Content-Type", "application/json");
+
+        try {
+            return HttpTools.postHttpContentAsync(reqUrl + subUrl, header, body).get(20, TimeUnit.SECONDS);
+        } catch (InterruptedException | ExecutionException | TimeoutException e) {
+            logger.error("请求抖音接口[" + subUrl + "]失败", e);
+            return null;
+        }
+    }
+
+    @Override
+    public RetResult<BusinessOrder> importOrderFromDouyin(String requestContent, String dataSourceId, long supplierCode) {
+        return handleScript("Order_CreateOrder_Douyin", ERPModule.ORDER_API,
+                dataSourceId, supplierCode,
+                () -> ProcessStringItem.newBuilder()
+                        .itemValue(requestContent)
+                        .dataSourceId(dataSourceId)
+                        .supplierCode(supplierCode)
+                        .build()
+        );
+    }
+}

+ 14 - 2
ddCommon/src/main/java/com/dderp/common/api/StoreService.java

@@ -25,18 +25,30 @@ public interface StoreService extends ScriptService {
     RetResult<StoreBrand> voidStoreBrand(StoreBrand storeBrand, ERPTokenUser currentUser, String dataSourceId, long supplierCode);
     //endregion
 
-    //region 门店管理
+    //region 门店档案
     List<ViewStoreInfo> queryViewStoreInfo(RMap params, PageFlipper pageFlipper, long supplierCode);
 
-    ViewStoreInfo getViewStoreInfo(long idStore, long supplierCode, int withInvoice);
+    ViewStoreInfo getViewStoreInfo(long idStore, long supplierCode, boolean readInvoice,boolean readEmployee,boolean readPlatform);
 
     RetResult<StoreInfo> addStoreInfo(StoreInfo storeInfo, ERPTokenUser currentUser, String dataSourceId, long supplierCode);
 
+    /**
+     * 获取门店开票信息
+     */
+    StoreInvoiceInfo getStoreInvoiceInfo(long idStore,long supplierCode);
+
     RetResult<StoreInvoiceInfo> configStoreInvoiceInfo(StoreInvoiceInfo invoiceInfo, int enableInvoice, ERPTokenUser currentUser, String dataSourceId, long supplierCode);
 
     RetResult<StoreInfo> updateStoreInfo(StoreInfo storeInfo, ERPTokenUser currentUser, String dataSourceId, long supplierCode);
 
     RetResult<StoreInfo> voidStoreInfo(StoreInfo storeInfo, ERPTokenUser currentUser, String dataSourceId, long supplierCode);
+    //endregion
+
+    //region 门店平台
+    /**
+     * 获取已开通平台信息
+     */
+    StorePlatform getStoreStorePlatformInfo(long id,long supplierCode);
 
     RetResult<StorePlatform> addStorePlatform(StorePlatform storePlatform, ERPTokenUser currentUser, String dataSourceId, long supplierCode);
 

+ 11 - 0
ddCommon/src/main/java/com/dderp/common/api/flycat/DouyinService.java

@@ -0,0 +1,11 @@
+package com.dderp.common.api.flycat;
+
+import com.dderp.common.entity.order.BusinessOrder;
+import com.sweetfish.service.RetResult;
+import com.sweetfish.service.Service;
+
+public interface DouyinService extends Service {
+    RetResult<BusinessOrder> importOrderFromDouyin(String douyinRequestBody, String dataSourceId, long supplierCode);
+
+
+}

+ 42 - 0
ddCommon/src/main/java/com/dderp/common/datas/BusinessOrderStatus.java

@@ -0,0 +1,42 @@
+package com.dderp.common.datas;
+
+/**
+ * Created by jlutt on 2021-07-11
+ * 订单状态
+ * @author jlutt
+ */
+public enum BusinessOrderStatus {
+
+    init("初始化", 0);
+
+    private String name;
+    private int value;
+
+    BusinessOrderStatus(String name, int value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public static String getName(int value) {
+        for (BusinessOrderStatus p : BusinessOrderStatus.values()) {
+            if (p.getValue() == value) return p.getName();
+        }
+        return null;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public void setValue(int value) {
+        this.value = value;
+    }
+}

+ 3 - 1
ddCommon/src/main/java/com/dderp/common/datas/ERPModule.java

@@ -40,7 +40,9 @@ public enum ERPModule {
 
     ADDRESSPARSER(153, "addressparser", "地址解析", "", "addressparser"),
 
-    EXPRESS_API(200, "expressApi", "配送平台接口", "", "expressApi");
+    EXPRESS_API(200, "expressApi", "配送平台接口", "", "expressApi"),
+
+    ORDER_API(300, "orderApi", "订单平台接口", "", "orderApi");
 
 
     private int value;

+ 10 - 0
ddCommon/src/main/java/com/dderp/common/datas/RedisKeys.java

@@ -315,6 +315,16 @@ public class RedisKeys {
 
     //endregion
 
+    /**
+     * 抖音access-token上次刷新的时间
+     */
+    public static final String KEY_DOUYIN_LASTTOKENDATE = "redis.douyin.lasttokendate";
+
+    /**
+     * 抖音access-token
+     */
+    public static final String KEY_DOUYIN_ACCESSTOKEN = "redis.douyin.accesstoken";
+
     private RedisKeys() {
     }
 }

+ 43 - 0
ddCommon/src/main/java/com/dderp/common/entity/invoke/douyin/DouyinTokenData.java

@@ -0,0 +1,43 @@
+package com.dderp.common.entity.invoke.douyin;
+
+public class DouyinTokenData {
+    private int expires_in;
+
+    private String access_token;
+
+    private String description;
+
+    private int error_code;
+
+    public int getExpires_in() {
+        return expires_in;
+    }
+
+    public void setExpires_in(int expires_in) {
+        this.expires_in = expires_in;
+    }
+
+    public String getAccess_token() {
+        return access_token;
+    }
+
+    public void setAccess_token(String access_token) {
+        this.access_token = access_token;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public int getError_code() {
+        return error_code;
+    }
+
+    public void setError_code(int error_code) {
+        this.error_code = error_code;
+    }
+}

+ 59 - 0
ddCommon/src/main/java/com/dderp/common/entity/invoke/douyin/DouyinTokenRequest.java

@@ -0,0 +1,59 @@
+package com.dderp.common.entity.invoke.douyin;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.sweetfish.convert.ConvertColumn;
+
+public class DouyinTokenRequest {
+    private String client_key;
+
+    private String client_secret;
+
+    private String grant_type = "client_credential";
+
+    private DouyinTokenRequest(Builder builder) {
+        setClient_key(builder.client_key);
+        setClient_secret(builder.client_secret);
+    }
+
+    public String getClient_key() {
+        return client_key;
+    }
+
+    public void setClient_key(String client_key) {
+        this.client_key = client_key;
+    }
+
+    public String getClient_secret() {
+        return client_secret;
+    }
+
+    public void setClient_secret(String client_secret) {
+        this.client_secret = client_secret;
+    }
+
+    public String getGrant_type() {
+        return grant_type;
+    }
+
+    public static final class Builder {
+        private String client_key;
+        private String client_secret;
+
+        public Builder() {
+        }
+
+        public Builder client_key(String val) {
+            client_key = val;
+            return this;
+        }
+
+        public Builder client_secret(String val) {
+            client_secret = val;
+            return this;
+        }
+
+        public DouyinTokenRequest build() {
+            return new DouyinTokenRequest(this);
+        }
+    }
+}

+ 23 - 0
ddCommon/src/main/java/com/dderp/common/entity/invoke/douyin/DouyinTokenResponse.java

@@ -0,0 +1,23 @@
+package com.dderp.common.entity.invoke.douyin;
+
+public class DouyinTokenResponse {
+    private DouyinTokenData data;
+
+    private String message;
+
+    public DouyinTokenData getData() {
+        return data;
+    }
+
+    public void setData(DouyinTokenData data) {
+        this.data = data;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}

+ 12 - 0
ddCommon/src/main/java/com/dderp/common/entity/order/OrderDeliveryInfo.java

@@ -36,6 +36,10 @@ public class OrderDeliveryInfo extends BaseEntity {
     @Comment("配送地的geo信息")
     private GeoPoiLocation geoPoiLocation;
 
+    @Comment("配送地geo信息的序列化,用于持久化")
+    @RColumn("geolocationserial")
+    private String geoLocationSerial;
+
     @RColumn("receiveman")
     @Comment("收货人")
     private String receiveMan;
@@ -163,4 +167,12 @@ public class OrderDeliveryInfo extends BaseEntity {
     public void setCustomerMemo(String customerMemo) {
         this.customerMemo = customerMemo;
     }
+
+    public String getGeoLocationSerial() {
+        return geoLocationSerial;
+    }
+
+    public void setGeoLocationSerial(String geoLocationSerial) {
+        this.geoLocationSerial = geoLocationSerial;
+    }
 }

+ 12 - 1
ddCommon/src/main/java/com/dderp/common/entity/platform/PlatformInfo.java

@@ -1,6 +1,7 @@
 package com.dderp.common.entity.platform;
 
 import com.dderp.common.entity.base.BaseEntity;
+import com.dderp.common.tdoc.ApiPlace;
 import com.sweetfish.util.Comment;
 import org.rex.db.RColumn;
 
@@ -13,6 +14,9 @@ import java.util.List;
 public class PlatformInfo extends BaseEntity {
     @RColumn("id")
     @Comment("")
+    @ApiPlace("/platform/updatePlatformInfo")
+    @ApiPlace("/platform/getPlatformInfo")
+    @ApiPlace("/platform/voidPlatformInfo")
     private long id;
 
     @RColumn("platformcode")
@@ -21,21 +25,28 @@ public class PlatformInfo extends BaseEntity {
 
     @RColumn("platformname")
     @Comment("平台名称")
+    @ApiPlace("/platform/addPlatformInfo")
+    @ApiPlace("/platform/updatePlatformInfo")
     private String platformName;
 
     @RColumn("platformtype")
     @Comment("平台类别 0订单平台/1配送平台")
+    @ApiPlace("/platform/addPlatformInfo")
+    @ApiPlace("/platform/updatePlatformInfo")
     private int platformType;
 
-    @RColumn("requirelistserialization")
+    @RColumn("requirelistserial")
     @Comment("平台接入需求list的序列化字符")
     private String requireListSerial;
 
     @Comment("禁用标记")
     @RColumn("voidflag")
+    @ApiPlace("/platform/voidPlatformInfo")
     private int voidFlag;
 
     @Comment("平台接入需求")
+    @ApiPlace("/platform/addPlatformInfo")
+    @ApiPlace("/platform/updatePlatformInfo")
     private List<PlatformRequire> requireList = new ArrayList<>();
 
     public long getId() {

+ 10 - 1
ddCommon/src/main/java/com/dderp/common/entity/platform/PlatformRequire.java

@@ -1,6 +1,7 @@
 package com.dderp.common.entity.platform;
 
 import com.dderp.common.entity.base.BaseEntity;
+import com.dderp.common.tdoc.ApiPlace;
 import com.sweetfish.util.Comment;
 import org.rex.db.RColumn;
 
@@ -9,22 +10,30 @@ import org.rex.db.RColumn;
  */
 public class PlatformRequire extends BaseEntity {
     @RColumn("id")
+    @ApiPlace("/platform/getPlatformRequire")
+    @ApiPlace("/platform/voidPlatformRequire")
     private long id;
 
     @RColumn("requirename")
     @Comment("接入需求的显示名称")
+    @ApiPlace("/platform/addPlatformRequire")
+    @ApiPlace("/platform/updatePlatformRequire")
     private String requireName;
 
     @RColumn("requirecode")
     @Comment("接入需求唯一code")
+    @ApiPlace("/platform/addPlatformRequire")
     private String requireCode;
 
     @RColumn("valuetype")
-    @Comment("取值的选择类型-取字典数据即可")
+    @Comment("取值的选择类型-取字典数据即可.这里需要一个字典,设置值的选择类型,例如输入框/下拉/radioButton之类")
+    @ApiPlace("/platform/addPlatformRequire")
+    @ApiPlace("/platform/updatePlatformRequire")
     private int valueType;
 
     @Comment("禁用标记")
     @RColumn("voidflag")
+    @ApiPlace("/platform/voidPlatformRequire")
     private int voidFlag;
 
     public long getId() {

+ 17 - 1
ddCommon/src/main/java/com/dderp/common/entity/store/StoreInfo.java

@@ -4,6 +4,7 @@ import com.dderp.common.entity.base.BaseEntity;
 import com.dderp.common.entity.geo.GeoPoiLocation;
 import com.dderp.common.entity.system.LoginUser;
 import com.sweetfish.util.Comment;
+import org.apache.commons.lang3.StringUtils;
 import org.rex.db.RColumn;
 
 import java.util.ArrayList;
@@ -59,6 +60,10 @@ public class StoreInfo extends BaseEntity {
     @Comment("门店geo信息")
     private GeoPoiLocation location;
 
+    @Comment("经度,纬度")
+    @RColumn("locationstr")
+    private String locationStr;
+
     @RColumn("contractphone")
     @Comment("门店联系电话")
     private String contractPhone;
@@ -87,7 +92,7 @@ public class StoreInfo extends BaseEntity {
     @RColumn("voidflag")
     private int voidFlag;
 
-    @Comment("启用开票信息标记")
+    @Comment("启用开票信息标记1启用,0不启用")
     @RColumn("enableinvoice")
     private int enableInvoice;
     @Comment("门店开票信息")
@@ -195,6 +200,14 @@ public class StoreInfo extends BaseEntity {
         this.location = location;
     }
 
+    public String getLocationStr() {
+        return locationStr;
+    }
+
+    public void setLocationStr(String locationStr) {
+        this.locationStr = locationStr;
+    }
+
     public String getContractPhone() {
         return contractPhone;
     }
@@ -282,4 +295,7 @@ public class StoreInfo extends BaseEntity {
     public void setEnableInvoice(int enableInvoice) {
         this.enableInvoice = enableInvoice;
     }
+
+
+
 }

+ 6 - 1
ddCommon/src/main/java/com/dderp/common/servlet/file/FileUploadServlet.java

@@ -18,7 +18,7 @@ import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Paths;
-import java.util.UUID;
+import java.util.*;
 
 import static com.sweetfish.net.Server.RESNAME_SERVER_ROOT;
 
@@ -137,4 +137,9 @@ public class FileUploadServlet extends ERPAdminHttpServlet {
         }
         resp.finish("success");
     }
+
+    @HttpMapping(url = "/upload/uploadStoreBrandLogo", auth = true, comment = "门店品牌logo上传")
+    public void uploadStoreBrandLogo(HttpRequest req, HttpResponse resp) throws IOException {
+        //todo 感觉logo只是展示用,需要记录下存放位置即可,不需要下载,待大哥有空的时候详细问下
+    }
 }

+ 0 - 2
ddWebCore/src/main/java/com/dderp/webcore/rest/PlatformRest.java

@@ -1,11 +1,9 @@
 package com.dderp.webcore.rest;
 
-import com.dderp.business.service.PlatformServiceImpl;
 import com.dderp.common.api.PlatformService;
 import com.dderp.common.base.BaseService;
 import com.dderp.common.datas.ERPHeader;
 import com.dderp.common.datas.HttpCode;
-import com.dderp.common.entity.doc.BusinessScript;
 import com.dderp.common.entity.platform.PlatformInfo;
 import com.dderp.common.entity.platform.PlatformRequire;
 import com.dderp.common.entity.site.ERPTokenUser;

+ 254 - 0
ddWebCore/src/main/java/com/dderp/webcore/rest/StoreRest.java

@@ -0,0 +1,254 @@
+package com.dderp.webcore.rest;
+
+import com.dderp.common.api.PlatformService;
+import com.dderp.common.api.StoreService;
+import com.dderp.common.base.BaseService;
+import com.dderp.common.datas.ERPHeader;
+import com.dderp.common.datas.ERPModule;
+import com.dderp.common.datas.HttpCode;
+import com.dderp.common.entity.platform.PlatformInfo;
+import com.dderp.common.entity.platform.PlatformRequire;
+import com.dderp.common.entity.site.ERPTokenUser;
+import com.dderp.common.entity.store.*;
+import com.dySweetFishPlugin.sql.RMapUtils;
+import com.sweetfish.net.http.*;
+import com.sweetfish.service.Local;
+import com.sweetfish.service.RetResult;
+import com.sweetfish.source.PageFlipper;
+import com.sweetfish.util.AutoLoad;
+import org.rex.RMap;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * @Author: xl Created on 2024-02-28
+ * @Content: 门店
+ */
+
+@AutoLoad(false)
+@Local
+@RestService(name = "store", moduleid = 0, comment = "门店档案模块")
+public class StoreRest extends BaseService {
+    @Resource
+    private StoreService storeService;
+
+    //region 门店品牌档案
+    @RestMapping(name = "queryStoreBrandList", auth = true, sort = 1, comment = "获取门店品牌档案列表", methods = {"GET", "POST"})
+    @WebApiBean(result = true, type = StoreBrand.class)
+    public CompletableFuture<RMap> queryStoreBrandList(
+            @RestParam(name = "params", comment = "搜索内容", required = false) RMap searchData,
+            @RestParam(name = "page", comment = "分页信息", required = false) PageFlipper pageFlipper,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    List<StoreBrand> resultList = storeService.queryStoreBrandList(searchData, pageFlipper, Long.parseLong(supplierCode));
+                    return RMapUtils.successV2(resultList, null, pageFlipper);
+                }, getExecutor()
+        );
+    }
+
+    @RestMapping(name = "getStoreBrand", auth = true, sort = 2, comment = "门店品牌档案", methods = {"GET", "POST"})
+    @WebApiBean(result = true, type = PlatformInfo.class)
+    public CompletableFuture<RMap> getStoreBrand(
+            @RestParam(name = "idStoreBrand", comment = "门店品牌档案id") long idStoreBrand,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    StoreBrand resultObj = storeService.getStoreBrand(idStoreBrand, Long.parseLong(supplierCode));
+                    if (resultObj == null) return RMapUtils.error(HttpCode.BAD_REQUEST.value(), "门店品牌档案不存在");
+                    return RMapUtils.successV2(resultObj, null, null);
+                }, getExecutor()
+        );
+    }
+
+    @RestMapping(name = "addStoreBrand", auth = true, sort = 3, comment = "新增门店品牌", methods = {"POST"})
+    @WebApiBean(result = true, type = StoreBrand.class)
+    public CompletableFuture<RMap> addStoreBrand(
+            @RestParam(name = "storeBrand", comment = "门店品牌档案") StoreBrand storeBrand,
+            @RestParam(name = "&", comment = "当前用户,不需要传入") ERPTokenUser currentUser,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    RetResult<StoreBrand> result = storeService.addStoreBrand(storeBrand, currentUser, dataSourceId, Long.parseLong(supplierCode));
+                    if (!result.isSuccess()) return RMapUtils.error(HttpCode.BAD_REQUEST.value(), result.getRetinfo());
+                    return RMapUtils.successV2(result.getResult(), null, null);
+                }, getExecutor()
+        );
+    }
+
+    @RestMapping(name = "updateStoreBrand", auth = true, sort = 4, comment = "修改门店品牌", methods = {"POST"})
+    @WebApiBean(result = true, type = StoreBrand.class)
+    public CompletableFuture<RMap> updateStoreBrand(
+            @RestParam(name = "storeBrand", comment = "门店品牌档案") StoreBrand storeBrand,
+            @RestParam(name = "&", comment = "当前用户,不需要传入") ERPTokenUser currentUser,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    RetResult<StoreBrand> result = storeService.updateStoreBrand(storeBrand, currentUser, dataSourceId, Long.parseLong(supplierCode));
+                    if (!result.isSuccess()) return RMapUtils.error(HttpCode.BAD_REQUEST.value(), result.getRetinfo());
+                    return RMapUtils.successV2(result.getResult(), null, null);
+                }, getExecutor()
+        );
+    }
+
+    @RestMapping(name = "voidStoreBrand", auth = true, sort = 5, comment = "禁用门店品牌档案", methods = {"POST"})
+    @WebApiBean(result = true, type = StoreBrand.class)
+    public CompletableFuture<RMap> voidStoreBrand(
+            @RestParam(name = "storeBrand", comment = "门店品牌档案") StoreBrand storeBrand,
+            @RestParam(name = "&", comment = "当前用户,不需要传入") ERPTokenUser currentUser,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    RetResult<StoreBrand> result = storeService.voidStoreBrand(storeBrand, currentUser, dataSourceId, Long.parseLong(supplierCode));
+                    if (!result.isSuccess()) return RMapUtils.error(HttpCode.BAD_REQUEST.value(), result.getRetinfo());
+                    return RMapUtils.successV2(result.getResult(), null, null);
+                }, getExecutor()
+        );
+    }
+    //endregion
+
+    //region 门店档案
+    @RestMapping(name = "queryViewStoreInfo", auth = true, sort = 11, comment = "获取门店档案列表", methods = {"GET", "POST"})
+    @WebApiBean(result = true, type = ViewStoreInfo.class)
+    public CompletableFuture<RMap> queryViewStoreInfo(
+            @RestParam(name = "params", comment = "搜索内容", required = false) RMap searchData,
+            @RestParam(name = "page", comment = "分页信息", required = false) PageFlipper pageFlipper,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    List<ViewStoreInfo> platformRequireList = storeService.queryViewStoreInfo(searchData, pageFlipper, Long.parseLong(supplierCode));
+                    return RMapUtils.successV2(platformRequireList, null, pageFlipper);
+                }, getExecutor()
+        );
+    }
+
+    @RestMapping(name = "getViewStoreInfo", auth = true, sort = 12, comment = "获取门店档案", methods = {"GET", "POST"})
+    @WebApiBean(result = true, type = ViewStoreInfo.class)
+    public CompletableFuture<RMap> getViewStoreInfo(
+            @RestParam(name = "idStore", comment = "平台档案id") long idStore,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    ViewStoreInfo resultObj = storeService.getViewStoreInfo(idStore, Long.parseLong(supplierCode), true, true, true);
+                    if (resultObj == null)
+                        return RMapUtils.error(HttpCode.BAD_REQUEST.value(), "门店档案不存在");
+                    return RMapUtils.successV2(resultObj, null, null);
+                }, getExecutor()
+        );
+    }
+
+    @RestMapping(name = "addStoreInfo", auth = true, sort = 13, comment = "新增门店档案", methods = {"POST"})
+    @WebApiBean(result = true, type = StoreInfo.class)
+    public CompletableFuture<RMap> addStoreInfo(
+            @RestParam(name = "storeInfo", comment = "平台需求条件档案") StoreInfo storeInfo,
+            @RestParam(name = "&", comment = "当前用户,不需要传入") ERPTokenUser currentUser,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    RetResult<StoreInfo> resultRet = storeService.addStoreInfo(storeInfo, currentUser, dataSourceId, Long.parseLong(supplierCode));
+                    if (!resultRet.isSuccess())
+                        return RMapUtils.error(HttpCode.BAD_REQUEST.value(), resultRet.getRetinfo());
+                    return RMapUtils.successV2(resultRet.getResult(), null, null);
+                }, getExecutor()
+        );
+    }
+
+    @RestMapping(name = "configStoreInvoiceInfo", auth = true, sort = 14, comment = "开启与关闭门店开票", methods = {"POST"})
+    @WebApiBean(result = true, type = StoreInvoiceInfo.class)
+    public CompletableFuture<RMap> configStoreInvoiceInfo(
+            @RestParam(name = "storeInvoiceInfo", comment = "门店开票信息") StoreInvoiceInfo storeInvoiceInfo,
+            @RestParam(name = "enableInvoice", comment = "1开启0关闭") int enableInvoice,
+            @RestParam(name = "&", comment = "当前用户,不需要传入") ERPTokenUser currentUser,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    RetResult<StoreInvoiceInfo> result = storeService.configStoreInvoiceInfo(storeInvoiceInfo, enableInvoice, currentUser, dataSourceId, Long.parseLong(supplierCode));
+                    if (!result.isSuccess()) return RMapUtils.error(HttpCode.BAD_REQUEST.value(), result.getRetinfo());
+                    return RMapUtils.successV2(result.getResult(), null, null);
+                }, getExecutor()
+        );
+    }
+
+    @RestMapping(name = "updateStoreInfo", auth = true, sort = 15, comment = "修改门店档案", methods = {"POST"})
+    @WebApiBean(result = true, type = StoreInfo.class)
+    public CompletableFuture<RMap> updateStoreInfo(
+            @RestParam(name = "storeInfo", comment = "门店档案") StoreInfo storeInfo,
+            @RestParam(name = "&", comment = "当前用户,不需要传入") ERPTokenUser currentUser,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    RetResult<StoreInfo> result = storeService.updateStoreInfo(storeInfo, currentUser, dataSourceId, Long.parseLong(supplierCode));
+                    if (!result.isSuccess()) return RMapUtils.error(HttpCode.BAD_REQUEST.value(), result.getRetinfo());
+                    return RMapUtils.successV2(result.getResult(), null, null);
+                }, getExecutor()
+        );
+    }
+
+    @RestMapping(name = "voidStoreInfo", auth = true, sort = 16, comment = "禁用门店档案", methods = {"POST"})
+    @WebApiBean(result = true, type = StoreInfo.class)
+    public CompletableFuture<RMap> voidStoreInfo(
+            @RestParam(name = "storeInfo", comment = "门店档案") StoreInfo storeInfo,
+            @RestParam(name = "&", comment = "当前用户,不需要传入") ERPTokenUser currentUser,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    RetResult<StoreInfo> result = storeService.voidStoreInfo(storeInfo, currentUser, dataSourceId, Long.parseLong(supplierCode));
+                    if (!result.isSuccess()) return RMapUtils.error(HttpCode.BAD_REQUEST.value(), result.getRetinfo());
+                    return RMapUtils.successV2(result.getResult(), null, null);
+                }, getExecutor()
+        );
+    }
+
+    //endregion
+
+    //region 门店平台
+    @RestMapping(name = "addStorePlatform", auth = true, sort = 21, comment = "门店开通平台", methods = {"POST"})
+    @WebApiBean(result = true, type = StorePlatform.class)
+    public CompletableFuture<RMap> addStorePlatform(
+            @RestParam(name = "storePlatform", comment = "门店平台信息") StorePlatform storePlatform,
+            @RestParam(name = "&", comment = "当前用户,不需要传入") ERPTokenUser currentUser,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    RetResult<StorePlatform> result = storeService.addStorePlatform(storePlatform, currentUser, dataSourceId, Long.parseLong(supplierCode));
+                    if (!result.isSuccess()) return RMapUtils.error(HttpCode.BAD_REQUEST.value(), result.getRetinfo());
+                    return RMapUtils.successV2(result.getResult(), null, null);
+                }, getExecutor()
+        );
+    }
+
+    @RestMapping(name = "configStorePlatform", auth = true, sort = 22, comment = "修改门店平台", methods = {"POST"})
+    @WebApiBean(result = true, type = StorePlatform.class)
+    public CompletableFuture<RMap> configStorePlatform(
+            @RestParam(name = "storePlatform", comment = "门店平台信息") StorePlatform storePlatform,
+            @RestParam(name = "&", comment = "当前用户,不需要传入") ERPTokenUser currentUser,
+            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
+            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    RetResult<StorePlatform> result = storeService.configStorePlatform(storePlatform, currentUser, dataSourceId, Long.parseLong(supplierCode));
+                    if (!result.isSuccess()) return RMapUtils.error(HttpCode.BAD_REQUEST.value(), result.getRetinfo());
+                    return RMapUtils.successV2(result.getResult(), null, null);
+                }, getExecutor()
+        );
+    }
+
+    //endregion
+
+
+}
+

+ 74 - 0
ddWebCore/src/main/java/com/dderp/webcore/servlet/OrderCallServlet.java

@@ -0,0 +1,74 @@
+package com.dderp.webcore.servlet;
+
+import com.dderp.common.entity.site.ERPTokenUser;
+import com.sweetfish.convert.json.JsonConvert;
+import com.sweetfish.net.WorkThread;
+import com.sweetfish.net.http.*;
+import com.sweetfish.util.AnyValue;
+import com.sweetfish.util.AutoLoad;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ForkJoinPool;
+
+@AutoLoad(false)
+@WebServlet(name = "订单回调服务", value = {"/order/*"}, comment = "订单回调服务")
+@HttpUserType(ERPTokenUser.class)
+public class OrderCallServlet extends HttpServlet {
+
+    @Resource
+    private JsonConvert jsonConvert;
+
+    @Resource(name = "property.douyin.appSecret")
+    private String douyinAppSecret;
+
+    private final Logger logger = LogManager.getLogger(this.getClass().getSimpleName());
+
+    private ExecutorService getExecutor() {
+        Thread thread = Thread.currentThread();
+        if (thread instanceof WorkThread) {
+            return ((WorkThread) thread).getExecutor();
+        }
+        return ForkJoinPool.commonPool();
+    }
+
+    @Override
+    public void init(HttpContext context, AnyValue config) {
+        super.init(context, config);
+    }
+
+    @Override
+    public void destroy(HttpContext context, AnyValue config) {
+        super.destroy(context, config);
+    }
+
+    //当前查看顺丰的回调,没有字段体现出顺丰的接口,大概每个快递平台需要不同的地址提供回调,顺丰的回调可以通过url_index来判断回调的业务
+
+    @HttpMapping(url = "/order/douyinCall", methods = {"POST"}, comment = "回调入口")
+    public void sfCall(HttpRequest request, HttpResponse response) {
+        //简单的入口,估计也没多少接口提供出去,这里多加一层方法包一下,是担心后续会修改
+        logger.info(request);
+        String body = request.getBodyUTF8();
+        Map<String, Object> bodyMap = jsonConvert.convertFrom(HashMap.class, body);
+
+        response.finish(bodyMap.get("content"));
+
+        /*  以上为接口接入验证代码,以下为正式带验签代码
+        String douyinSign = request.getHeader("X-Douyin-Signature");
+        String douyinMsgId = request.getHeader("Msg-Id");
+
+        String signData = douyinAppSecret + body;
+        String sign = DigestUtils.sha1Hex(signData);
+        if (!sign.equals(douyinSign)) {
+            logger.error("验签失败");
+            response.finish();
+        }
+
+         */
+    }
+}