Browse Source

Merge remote-tracking branch 'origin/master'

xl37192053 2 years ago
parent
commit
1f7d98c4ca
23 changed files with 789 additions and 35 deletions
  1. 13 0
      conf/KeyCode.xml
  2. 36 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. 7 0
      conf/platform.properties
  7. 4 0
      conf/rediskeys.properties
  8. 96 0
      conf/script/1000/orderApi/BE_Order_CreateOrder_Douyin.groovy
  9. 2 2
      conf/sqlroot/com/dderp/business/dao/PlatformDao.dql
  10. 124 22
      conf/初始化业务表.sql
  11. 176 0
      ddBusiness/src/main/java/com/dderp/business/service/flycat/DouyinServiceImpl.java
  12. 11 0
      ddCommon/src/main/java/com/dderp/common/api/flycat/DouyinService.java
  13. 42 0
      ddCommon/src/main/java/com/dderp/common/datas/BusinessOrderStatus.java
  14. 3 1
      ddCommon/src/main/java/com/dderp/common/datas/ERPModule.java
  15. 10 0
      ddCommon/src/main/java/com/dderp/common/datas/RedisKeys.java
  16. 43 0
      ddCommon/src/main/java/com/dderp/common/entity/invoke/douyin/DouyinTokenData.java
  17. 59 0
      ddCommon/src/main/java/com/dderp/common/entity/invoke/douyin/DouyinTokenRequest.java
  18. 23 0
      ddCommon/src/main/java/com/dderp/common/entity/invoke/douyin/DouyinTokenResponse.java
  19. 12 0
      ddCommon/src/main/java/com/dderp/common/entity/order/OrderDeliveryInfo.java
  20. 12 1
      ddCommon/src/main/java/com/dderp/common/entity/platform/PlatformInfo.java
  21. 10 1
      ddCommon/src/main/java/com/dderp/common/entity/platform/PlatformRequire.java
  22. 0 2
      ddWebCore/src/main/java/com/dderp/webcore/rest/PlatformRest.java
  23. 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>

+ 36 - 0
conf/KeyId.xml

@@ -352,4 +352,40 @@
             <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",

+ 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.express.sf.order = dydeliver:erp:working:express:sf:order
 redis.erp.working.express.sf.store = dydeliver:erp:working:express:sf:store

+ 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} );

+ 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`;

+ 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()
+        );
+    }
+}

+ 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

@@ -313,6 +313,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() {

+ 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;

+ 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();
+        }
+
+         */
+    }
+}