Kaynağa Gözat

卡消费整合完成

yq 2 yıl önce
ebeveyn
işleme
2079171d20

+ 89 - 53
src/main/java/com/usky/dxtop/MysqlGenerator.java

@@ -1,53 +1,89 @@
-//package com.usky.dxtop;
-//
-//import com.baomidou.mybatisplus.generator.AutoGenerator;
-//import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
-//import com.baomidou.mybatisplus.generator.config.GlobalConfig;
-//import com.baomidou.mybatisplus.generator.config.PackageConfig;
-//import com.baomidou.mybatisplus.generator.config.StrategyConfig;
-//import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
-//
-//public class MysqlGenerator {
-//
-//
-//    public static void main(String[] args) {
-//        AutoGenerator mpg = new AutoGenerator();
-//        //1、全局配置
-//        GlobalConfig gc = new GlobalConfig();
-//        String projectPath = System.getProperty("user.dir");
-//        gc.setOutputDir(projectPath + "/src/main");  //生成路径(一般都是生成在此项目的src/main/java下面)
-//        gc.setAuthor("yq"); //设置作者
-//        gc.setOpen(false);
-//        gc.setFileOverride(true); //第二次生成会把第一次生成的覆盖掉
-//        gc.setServiceName("%sService"); //生成的service接口名字首字母是否为I,这样设置就没有
-//        gc.setBaseResultMap(true); //生成resultMap
-//        mpg.setGlobalConfig(gc);
-//
-//        //2、数据源配置
-//        DataSourceConfig dsc = new DataSourceConfig();
-//        dsc.setUrl("jdbc:mysql://124.71.145.219:3306/dxtop?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
-//        dsc.setDriverName("com.mysql.jdbc.Driver");
-//        dsc.setUsername("root");
-//        dsc.setPassword("Wjzn2021Db");
-//        mpg.setDataSource(dsc);
-//
-//        // 3、包配置
-//        PackageConfig pc = new PackageConfig();
-//        pc.setModuleName("dxtop");
-//        pc.setParent("com.usky.dxtop");
-//        mpg.setPackageInfo(pc);
-//
-//        // 4、策略配置
-//        StrategyConfig strategy = new StrategyConfig();
-//        strategy.setNaming(NamingStrategy.underline_to_camel);
-//        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
-//        // strategy.setTablePrefix("t_"); // 表名前缀
-//        strategy.setEntityLombokModel(true); //使用lombok
-//        strategy.setInclude("msg_log");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
-//        mpg.setStrategy(strategy);
-//
-//        //5、执行
-//        mpg.execute();
-//    }
-//
-//}
+package com.usky.dxtop;
+
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.generator.AutoGenerator;
+import com.baomidou.mybatisplus.generator.InjectionConfig;
+import com.baomidou.mybatisplus.generator.config.*;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MysqlGenerator {
+
+
+    public static void main(String[] args) {
+        AutoGenerator mpg = new AutoGenerator();
+        //1、全局配置
+        GlobalConfig gc = new GlobalConfig();
+        String projectPath = System.getProperty("user.dir");
+        gc.setOutputDir(projectPath + "/src/main/java");  //生成路径(一般都是生成在此项目的src/main/java下面)
+        gc.setAuthor("yq"); //设置作者
+        gc.setOpen(false);
+        gc.setFileOverride(true); //第二次生成会把第一次生成的覆盖掉
+        gc.setServiceName("%sService"); //生成的service接口名字首字母是否为I,这样设置就没有
+        gc.setBaseResultMap(true); //生成resultMap
+        mpg.setGlobalConfig(gc);
+
+        //2、数据源配置
+        DataSourceConfig dsc = new DataSourceConfig();
+        dsc.setUrl("jdbc:mysql://101.133.214.75:3306/dxtop?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
+        dsc.setDriverName("com.mysql.jdbc.Driver");
+        dsc.setUsername("usky");
+        dsc.setPassword("Yt#75Usky");
+        mpg.setDataSource(dsc);
+
+        // 3、包配置
+        PackageConfig pc = new PackageConfig();
+        pc.setParent("com.usky.dxtop");
+        pc.setController("controller.web");
+        pc.setEntity("model");
+        pc.setMapper("mapper");
+        pc.setService("service");
+        pc.setServiceImpl("service.impl");
+        mpg.setPackageInfo(pc);
+
+        // 4、策略配置
+        StrategyConfig strategy = new StrategyConfig();
+        strategy.setNaming(NamingStrategy.underline_to_camel);
+        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
+        // strategy.setTablePrefix("t_"); // 表名前缀
+        strategy.setEntityLombokModel(true); //使用lombok
+        strategy.setInclude("product_period");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
+
+        mpg.setStrategy(strategy);
+        // 关闭默认 xml 生成,调整生成 至 根目录
+        //修改对应的模块名称
+        TemplateConfig tc = new TemplateConfig();
+        // 自定义配置
+        InjectionConfig cfg = new InjectionConfig() {
+            @Override
+            public void initMap() {
+                // to do nothing
+            }
+        };
+        //如果模板引擎是 velocity
+        String templatePath = "/templates/mapper.xml.vm";
+        // 自定义输出配置
+        List<FileOutConfig> focList = new ArrayList<>();
+        // 自定义配置会被优先输出
+        String finalProjectPath = projectPath;
+        focList.add(new FileOutConfig(templatePath) {
+            @Override
+            public String outputFile(TableInfo tableInfo) {
+                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
+                return finalProjectPath + "/src/main/resources/mapper" + "/"
+                        + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
+            }
+        });
+        cfg.setFileOutConfigList(focList);
+        mpg.setCfg(cfg);
+        tc.setXml(null);
+        mpg.setTemplate(tc);
+
+        //5、执行
+        mpg.execute();
+    }
+
+}

+ 11 - 0
src/main/java/com/usky/dxtop/common/utils/ExcelUtils.java

@@ -1,12 +1,22 @@
 package com.usky.dxtop.common.utils;
 
+import cn.afterturn.easypoi.excel.ExcelExportUtil;
+import cn.afterturn.easypoi.excel.entity.ExportParams;
+import com.usky.dxtop.common.core.page.CommonPage;
+import com.usky.dxtop.model.Order;
+import com.usky.dxtop.service.emun.AsyncResultType;
+import com.usky.dxtop.service.vo.OrderExport;
 import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.context.annotation.Configuration;
 import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.stereotype.Component;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.util.stream.Collectors;
 
 /**
  * @author yq
@@ -22,4 +32,5 @@ public class ExcelUtils {
         return new MockMultipartFile(fileName,fileName,fileName,is);
     }
 
+
 }

+ 16 - 11
src/main/java/com/usky/dxtop/controller/web/business/TestController.java

@@ -8,6 +8,8 @@ import com.usky.dxtop.service.OrderService;
 import com.usky.dxtop.service.StaffService;
 import com.usky.dxtop.service.api.OneCardApi;
 import com.usky.dxtop.service.api.SmApi;
+import com.usky.dxtop.service.job.CardDishJob;
+import com.usky.dxtop.service.job.FpJob;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -30,19 +32,22 @@ public class TestController {
     @Autowired
     private OrderService orderService;
 
-    @GetMapping("/sendStaff")
-    public String sendStaff(@RequestParam Long staffId,@RequestParam String card,@RequestParam Integer type){
-        Staff staff = staffService.getById(staffId);
-        staff.setCardId(card);
-        staffService.personSendMessage(staff,type);
-        return "";
+
+    @Autowired
+    private FpJob fpJob;
+
+    @Autowired
+    private CardDishJob cardDishJob;
+    @RequestMapping("/get1")
+    public void get1(){
+        cardDishJob.execute(null);
     }
 
 
-    @GetMapping("/orderSuccess")
-    public String testOrderSuccess(@RequestParam Long orderId){
-        Order byId = orderService.getById(orderId);
-        orderService.paySuccess(byId);
-        return "";
+    @RequestMapping("/get2")
+    public void get2(){
+        fpJob.execute(null);
     }
 }
+
+

+ 2 - 0
src/main/java/com/usky/dxtop/service/CallApiLogService.java

@@ -2,6 +2,7 @@ package com.usky.dxtop.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.usky.dxtop.model.CallApiLog;
+import com.usky.dxtop.model.MsgLog;
 
 
 /**
@@ -25,6 +26,7 @@ public interface CallApiLogService extends IService<CallApiLog> {
      */
     void saveOrUpdate(String orderNumber,String apiName,String url,String param,String result);
 
+    CallApiLog getApiLog(String orderNumber,String apiName,String url,String param,String result);
 
     CallApiLog one(String orderNumber,String apiName);
 }

+ 7 - 0
src/main/java/com/usky/dxtop/service/OrderService.java

@@ -2,6 +2,7 @@ package com.usky.dxtop.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.usky.dxtop.common.core.page.CommonPage;
+import com.usky.dxtop.model.MsgLog;
 import com.usky.dxtop.model.Order;
 import com.usky.dxtop.service.vo.OrderFileVO;
 import com.usky.dxtop.service.vo.OrderReport;
@@ -136,4 +137,10 @@ public interface OrderService extends IService<Order> {
 
 
     List<OrderFileVO> addOrderListByFile(MultipartFile multipartFile);
+
+
+    public MsgLog enhanceMsgLog(Order order);
+
+
+    public void sendMessage(List<Order> orderList,List<MsgLog> msgLogs);
 }

+ 4 - 24
src/main/java/com/usky/dxtop/service/api/FpApi.java

@@ -33,23 +33,6 @@ public class FpApi {
     public static final String DEVICE_PERMISSION_OPERATE_URL = String.format("%s%s",PATH,"devicePermissionOperate");
 
 
-    /**
-     * 获取门禁列表
-     * @return
-     */
-    public List<FpDoorVO> getDoorList(){
-
-        return null;
-    }
-
-    /**
-     * 设置门禁权限
-     * @param params
-     */
-    public void setDoorPermission(Map<String,Object> params){
-        return;
-    }
-
     /**
      * 生成门禁参数
      * @param userId
@@ -57,7 +40,7 @@ public class FpApi {
      * @param operateType
      * @return
      */
-    public Map<String,Object> generateDoorPermissionParam(String userId,List<FpDoorVO> list,String operateType){
+    public static Map<String,Object> generateDoorPermissionParam(String userId,List<FpDoorVO> list,String operateType){
         List<Map<String, Object>> deviceInfoList = list.stream().map(fpDoorVO -> {
             Map<String, Object> deviceInfo = new HashMap<>();
             deviceInfo.put("serialNumber", fpDoorVO.getDeviceId());
@@ -73,13 +56,10 @@ public class FpApi {
     }
 
 
-    public boolean commonResult(String url, String param, Function<JSONObject,Boolean> function){
+    public static String commonResult(String url, String param, Function<JSONObject,Boolean> function){
         String result = HttpUtils.sendPost(url, JSONObject.toJSONString(param), null);
         JSONObject jsonObject = JSONObject.parseObject(result);
-        if ("1".equals(jsonObject.get("result").toString())) {
-            return function.apply(jsonObject);
-        } else {
-            throw new CustomException("接口异常"+jsonObject.get("msg"));
-        }
+        function.apply(jsonObject);
+        return result;
     }
 }

+ 26 - 15
src/main/java/com/usky/dxtop/service/api/OneCardApi.java

@@ -3,9 +3,13 @@ package com.usky.dxtop.service.api;
 
 import com.alibaba.fastjson.JSONObject;
 import com.usky.dxtop.common.exception.CustomException;
+import com.usky.dxtop.common.utils.Arith;
+import com.usky.dxtop.common.utils.DateUtils;
 import com.usky.dxtop.common.utils.StringUtils;
 import com.usky.dxtop.common.utils.http.HttpUtils;
 import com.usky.dxtop.common.utils.sign.Md5Utils;
+import com.usky.dxtop.model.ProductOrder;
+import com.usky.dxtop.model.Staff;
 import org.apache.poi.hssf.record.SSTRecord;
 import org.apache.poi.ss.usermodel.FontUnderline;
 import sun.security.timestamp.TSRequest;
@@ -56,7 +60,7 @@ public class OneCardApi {
         treeMap.put("shop",SHOP);
         treeMap.put("term",TERM);
         treeMap.put("oper",OPER);
-        treeMap.put("d",new Date().toString());
+        treeMap.put("d", DateUtils.format(new Date(),DateUtils.YYYY_MM_DD_HH_MM_SS));
         return treeMap;
     }
 
@@ -93,12 +97,24 @@ public class OneCardApi {
      * 卡消费
      * @return
      */
-    public static TreeMap<String,String> cardPay(){
-        return null;
+    public static TreeMap<String,String> cardPayParam(ProductOrder productOrder){
+        TreeMap<String, String> treeMap = commonParam();
+        treeMap.put("cid",productOrder.getCard());
+        treeMap.put("cno",productOrder.getCard());
+        treeMap.put("account", String.valueOf(new Double(Arith.mul(productOrder.getOrderMoney().doubleValue(), 100)).intValue()));
+        treeMap.put("amt",productOrder.getOrderMoney().toString());
+        treeMap.put("invoice",productOrder.getId().toString());
+        List<String> paramList = getParamList(treeMap);
+        treeMap.put("sig",sign(paramList));
+        return treeMap;
     }
 
-    public static TreeMap<String,String> cardPayBack(Integer seq){
-        return null;
+    public static TreeMap<String,String> cardPayBackParam(Long seq){
+        TreeMap<String, String> treeMap = commonParam();
+        treeMap.put("seq",seq.toString());
+        List<String> paramList = getParamList(treeMap);
+        treeMap.put("sig",sign(paramList));
+        return treeMap;
     }
 
 
@@ -148,21 +164,16 @@ public class OneCardApi {
             if (StringUtils.isNotBlank(entry.getValue())){
                 value = entry.getValue();
             }
-            if (!"sign".equals(entry.getKey())) {
-                buf.append(entry.getKey()).append("=").append(value).append("&");
-            }
+            buf.append(entry.getKey()).append("=").append(value).append("&");
         }
         String changeBuf = buf.toString();
         return changeBuf.substring(0, changeBuf.length() - 1);
     }
 
-    public Boolean commonRequest(String url, String param, Function<JSONObject,Boolean> function){
-        String result = HttpUtils.sendPost(url, JSONObject.toJSONString(param), null);
+    public static String commonRequest(String url, String param,Map<String,String> header, Function<JSONObject,Boolean> function){
+        String result = HttpUtils.sendPost(url, param, header);
         JSONObject jsonObject = JSONObject.parseObject(result);
-        if ("1".equals(jsonObject.get("code").toString())) {
-            return function.apply(jsonObject);
-        } else {
-            throw new CustomException("接口异常"+jsonObject.get("msg"));
-        }
+        function.apply(jsonObject);
+        return result;
     }
 }

+ 55 - 0
src/main/java/com/usky/dxtop/service/emun/ProductOrderStatus.java

@@ -0,0 +1,55 @@
+package com.usky.dxtop.service.emun;
+
+/**
+ * @author yq
+ * @date 2022/7/6 10:25
+ */
+public enum  ProductOrderStatus {
+
+    NO_PAY(0,"待扣费"),
+
+    TAKE(1,"生效中,待开启权限"),
+
+    DISH_ERROR(2,"扣费失败"),
+
+    RUN(3,"进行中"),
+
+    SET_PERMISSION_ERROR(4,"开权限失败"),
+
+    DEL_PERMISSION_ERROR(5,"关权限失败"),
+
+    RETURN_ORDER(6,"退订"),
+
+    RETURN_SUCCESS(7,"退订完成"),
+
+    SUCCESS(8,"完成");
+
+    private Integer code;
+
+    private String name;
+
+    ProductOrderStatus(Integer code,String name){
+        this.code = code;
+        this.name = name;
+    }
+
+    public static ProductOrderStatus parse(Integer code){
+        ProductOrderStatus productOrderStatus = null;
+        for (ProductOrderStatus o:ProductOrderStatus.values()) {
+            if (o.getCode().equals(code)){
+                productOrderStatus = o;
+                break;
+            }
+        }
+        return productOrderStatus;
+    }
+
+
+    public Integer getCode(){
+        return code;
+    }
+
+    public String getName(){
+        return name;
+    }
+}

+ 11 - 0
src/main/java/com/usky/dxtop/service/impl/CallApiLogServiceImpl.java

@@ -44,6 +44,17 @@ public class CallApiLogServiceImpl extends ServiceImpl<CallApiLogMapper, CallApi
         }
     }
 
+    @Override
+    public CallApiLog getApiLog(String orderNumber, String apiName, String url, String param, String result) {
+        CallApiLog callApiLog = new CallApiLog();
+        callApiLog.setApiUrl(url);
+        callApiLog.setApiParam(param);
+        callApiLog.setOrderNumber(orderNumber);
+        callApiLog.setName(apiName);
+        callApiLog.setApiResultData(result);
+        return callApiLog;
+    }
+
     @Override
     public CallApiLog one(String orderNumber, String apiName) {
         LambdaQueryWrapper<CallApiLog> queryWrapper = Wrappers.lambdaQuery();

+ 2 - 0
src/main/java/com/usky/dxtop/service/impl/OrderServiceImpl.java

@@ -783,6 +783,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
      * @param orderList
      * @param msgLogs
      */
+    @Override
     public void sendMessage(List<Order> orderList,List<MsgLog> msgLogs){
         AtomicBoolean b = new AtomicBoolean(true);
         RabbitTemplate rabbitmqTemplate = RabbitmqUtils.getRabbitmqTemplate(RabbitmqBeenCode.CART_CHARGE_CONSUMER);
@@ -916,6 +917,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
      * @param order
      * @return
      */
+    @Override
     public MsgLog enhanceMsgLog(Order order){
         long seq = System.nanoTime();
         ChargeVO chargeVo = new ChargeVO();

+ 79 - 0
src/main/java/com/usky/dxtop/service/job/CardDishJob.java

@@ -0,0 +1,79 @@
+package com.usky.dxtop.service.job;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.dxtop.model.*;
+import com.usky.dxtop.service.*;
+import com.usky.dxtop.service.api.FpApi;
+import com.usky.dxtop.service.api.OneCardApi;
+import com.usky.dxtop.service.emun.ProductOrderStatus;
+import com.usky.dxtop.service.impl.ProductOrderServiceImpl;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * 卡消费
+ * @author yq
+ * @date 2021/9/16 9:31
+ */
+@Slf4j
+@Component("cardJob")
+public class CardDishJob {
+
+
+    @Autowired
+    private ProductOrderService productOrderService;
+
+    @Autowired
+    private CallApiLogService callApiLogService;
+
+
+    public void execute(String param){
+        AtomicReference<String> result = new AtomicReference<>("");
+        List<CallApiLog> logs = new ArrayList<>();
+        List<ProductOrder> data = getData(param);
+        data.forEach(productOrder -> {
+            TreeMap<String, String> treeMap = OneCardApi.cardPayBackParam(productOrder.getId());
+            try {
+                Map<String,String> map = new HashMap<>();
+                map.put("Content-Type","application/x-www-form-urlencoded");
+                result.set(OneCardApi.commonRequest(OneCardApi.CARD_PAYCHECK, OneCardApi.joinParam(treeMap), map, jsonObject -> {
+                    productOrderService.checkCarPayResult(productOrder, jsonObject);
+                    return null;
+                }));
+            }catch (Exception e){
+                result.set(e.getMessage());
+                log.error("雄伟消费记录查询失败,订单编号:"+productOrder.getOrderNumber()+"异常信息"+e);
+            }
+            logs.add(callApiLogService.getApiLog(productOrder.getOrderNumber(),
+                    ProductOrderServiceImpl.FIND_ORDER_INFO,
+                    OneCardApi.CARD_PAYCHECK,
+                    JSONObject.toJSONString(treeMap),
+                    result.get()));
+        });
+        productOrderService.updateBatchById(data);
+        callApiLogService.saveBatch(logs);
+        log.info("---orderJob---处理完成");
+    }
+
+    public List<ProductOrder> getData(String param){
+        CardJobParam cardJobParam = JSON.parseObject(param, CardJobParam.class);
+        LambdaQueryWrapper<ProductOrder> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper
+                .eq(ProductOrder::getOrderFlag, ProductOrderStatus.NO_PAY.getCode());
+        return productOrderService.list(queryWrapper);
+    }
+
+
+    @Data
+    public static class CardJobParam {
+        private String orderNumber;
+    }
+}

+ 0 - 91
src/main/java/com/usky/dxtop/service/job/CardJob.java

@@ -1,91 +0,0 @@
-package com.usky.dxtop.service.job;
-
-import com.alibaba.fastjson.JSON;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
-import com.baomidou.mybatisplus.core.toolkit.StringUtils;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.usky.dxtop.model.Charge;
-import com.usky.dxtop.model.MsgLog;
-import com.usky.dxtop.model.Order;
-import com.usky.dxtop.service.ChargeService;
-import com.usky.dxtop.service.MsgLogService;
-import com.usky.dxtop.service.OrderService;
-import com.usky.dxtop.service.emun.OrderStatus;
-import lombok.Data;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import java.util.List;
-import java.util.TreeMap;
-
-/**
- * @author yq
- * @date 2021/9/16 9:31
- */
-@Slf4j
-@Component("cardJob")
-public class CardJob {
-
-    private TreeMap<String,Integer> treeMap = new TreeMap<>();
-
-    @Autowired
-    private OrderService orderService;
-    @Autowired
-    private ChargeService chargeService;
-    @Autowired
-    private MsgLogService msgLogService;
-
-    public void execute(String param){
-        for (Order order:getData(param)) {
-            try {
-                LambdaQueryWrapper<MsgLog> msgLogLambdaQueryWrapper = Wrappers.lambdaQuery();
-                msgLogLambdaQueryWrapper.eq(MsgLog::getBusinessId,order.getId());
-                List<MsgLog> msgLogs = msgLogService.list(msgLogLambdaQueryWrapper);
-                if (CollectionUtils.isNotEmpty(msgLogs)){
-                    Charge one = chargeService.one(msgLogs.get(0).getId());
-                    if (null == one){
-                        cartError(order);
-                    }else {
-                        order.setOrderFlag(OrderStatus.COMPLETE.getCode());
-                        orderService.updateById(order);
-                    }
-                }
-            }catch (Exception e){
-                log.error("---orderJob---异常"+e.getMessage());
-            }
-        }
-        log.info("---orderJob---处理完成");
-    }
-
-    public List<Order> getData(String param){
-        CardJobParam cardJobParam = JSON.parseObject(param, CardJobParam.class);
-        LambdaQueryWrapper<Order> queryWrapper = Wrappers.lambdaQuery();
-        queryWrapper
-                .eq(StringUtils.isNotBlank(cardJobParam.getOrderNumber()),Order::getOrderNumber,cardJobParam.getOrderNumber())
-                .eq(Order::getOrderFlag,OrderStatus.SUCCESS.getCode());
-        return orderService.list(queryWrapper);
-    }
-
-    public void cartError(Order order){
-        String orderNumber = order.getOrderNumber();
-        if (treeMap.containsKey(orderNumber)){
-            Integer count = treeMap.get(orderNumber);
-            if (count >= 10){
-                order.setOrderFlag(OrderStatus.PAYMENT_ERROR_DEBIT.getCode());
-                orderService.updateById(order);
-            }else {
-                treeMap.put(orderNumber,count+1);
-            }
-        }else {
-            treeMap.put(orderNumber,1);
-        }
-    }
-
-
-    @Data
-    public static class CardJobParam {
-        private String orderNumber;
-    }
-}

+ 204 - 0
src/main/java/com/usky/dxtop/service/job/FpJob.java

@@ -0,0 +1,204 @@
+package com.usky.dxtop.service.job;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.dxtop.common.exception.CustomException;
+import com.usky.dxtop.common.utils.DateUtils;
+import com.usky.dxtop.model.CallApiLog;
+import com.usky.dxtop.model.MsgLog;
+import com.usky.dxtop.model.Order;
+import com.usky.dxtop.model.ProductOrder;
+import com.usky.dxtop.service.CallApiLogService;
+import com.usky.dxtop.service.ProductOrderService;
+import com.usky.dxtop.service.api.FpApi;
+import com.usky.dxtop.service.emun.OrderStatus;
+import com.usky.dxtop.service.emun.ProductOrderStatus;
+import com.usky.dxtop.service.impl.ProductOrderServiceImpl;
+import com.usky.dxtop.service.vo.FpDoorVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.sql.SQLTransactionRollbackException;
+import java.time.LocalTime;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+
+/**
+ * @author yq
+ * @date 2022/7/6 16:17
+ */
+@Slf4j
+@Component("fpJob")
+public class FpJob {
+
+
+    private TreeMap<String,Integer> treeMap = new TreeMap<>();
+
+    @Autowired
+    private CallApiLogService callApiLogService;
+
+    @Autowired
+    private ProductOrderService productOrderService;
+
+    @Transactional(rollbackFor = Exception.class)
+    public void execute(String param){
+        List<FpDoorVO> doorList = getDoorList();
+        if (CollectionUtils.isNotEmpty(doorList)){
+            List<CallApiLog> logs = new ArrayList<>();
+            //处理需要开权限的订单
+            List<ProductOrder> addPerList = getData(ProductOrderStatus.TAKE.getCode());
+            addPerList.forEach(productOrder -> {
+                List<FpDoorVO> listByDeviceId = getListByDeviceId(productOrder.getFpDeviceId(), doorList);
+                if (isAddPermission(productOrder)){
+                    logs.add(sendPermission(listByDeviceId, productOrder, "1",ProductOrderStatus.SET_PERMISSION_ERROR.getCode()));
+                }
+            });
+
+            //处理需要关闭权限的订单
+            List<ProductOrder> delPerList = getData(ProductOrderStatus.RUN.getCode());
+            delPerList.forEach(productOrder -> {
+                List<FpDoorVO> listByDeviceId = getListByDeviceId(productOrder.getFpDeviceId(), doorList);
+                if (isDelPermission(productOrder)){
+                    logs.add(sendPermission(listByDeviceId, productOrder, "1",ProductOrderStatus.DEL_PERMISSION_ERROR.getCode()));
+                }
+            });
+            try {
+                productOrderService.updateBatchById(addPerList);
+                productOrderService.updateBatchById(delPerList);
+                callApiLogService.saveBatch(logs);
+            }catch (Exception e){
+                log.error("费浦定时任务-----数据库异常:"+e.getMessage());
+            }
+        }
+        log.info("---fpJob---处理完成");
+    }
+
+
+    /**
+     * 是否重试
+     * @param productOrder
+     */
+    public boolean isRetry(ProductOrder productOrder){
+        String orderNumber = productOrder.getOrderNumber();
+        if (treeMap.containsKey(orderNumber)){
+            Integer count = treeMap.get(orderNumber);
+            if (count >= 3){
+                treeMap.remove(orderNumber);
+                return false;
+            }else {
+                treeMap.put(orderNumber,count+1);
+            }
+        }else {
+            treeMap.put(orderNumber,1);
+        }
+        return true;
+    }
+
+    public List<FpDoorVO> getListByDeviceId(String deviceId,List<FpDoorVO> list){
+        return list.stream()
+                .filter(fpDoorVO -> fpDoorVO.getDeviceId().equals(deviceId)).collect(Collectors.toList());
+    }
+
+    /**
+     * 获取全部门禁设备
+     * @return
+     */
+    public List<FpDoorVO> getDoorList(){
+        AtomicReference<List<FpDoorVO>> doorVOS = new AtomicReference<>();
+        try {
+            FpApi.commonResult(FpApi.DOOR_LIST_URL,null,jsonObject -> {
+                if ("1".equals(jsonObject.get("result").toString())){
+                    JSONObject data = jsonObject.getJSONObject("data");
+                    JSONArray content = data.getJSONArray("data");
+                    doorVOS.set(content.toJavaList(FpDoorVO.class));
+                }else {
+                    log.error("获取全部门禁里列表异常:"+jsonObject.get("msg"));
+                }
+                return null;
+            });
+        }catch (Exception e){
+            log.error("获取全部门禁里列表异常:"+e.getMessage());
+        }
+        return doorVOS.get();
+    }
+
+    /**
+     * 权限管理
+     * @param list 门禁列表
+     * @param productOrder 订单
+     * @param permission 权限标识
+     * @param orderFlag 达到最大重试次数以后的订单状态
+     * @return
+     */
+    public CallApiLog sendPermission(List<FpDoorVO> list, ProductOrder productOrder,String permission,Integer orderFlag){
+        Map<String, Object> map = FpApi.generateDoorPermissionParam(productOrder.getUserCode(), list, permission);
+        String result;
+        try {
+            result = FpApi.commonResult(FpApi.DEVICE_PERMISSION_OPERATE_URL,null,jsonObject -> {
+                if ("1".equals(jsonObject.get("result").toString())){
+                    productOrder.setOrderFlag(ProductOrderStatus.RUN.getCode());
+                }else {
+                    productOrder.setOrderFlag(ProductOrderStatus.SET_PERMISSION_ERROR.getCode());
+                    log.error("设置门禁权限异常:"+jsonObject.get("msg"));
+                }
+                return true;
+            });
+            treeMap.remove(productOrder.getOrderNumber());
+        }catch (Exception e){
+            if (isRetry(productOrder)){
+                productOrder.setOrderFlag(orderFlag);
+            }
+            result = e.getMessage();
+            log.error("设置门禁权限异常:"+e.getMessage());
+        }
+        return callApiLogService.getApiLog(productOrder.getOrderNumber(),
+                ProductOrderServiceImpl.FP_SET_PERMISSION,
+                FpApi.DEVICE_PERMISSION_OPERATE_URL,
+                JSONObject.toJSONString(map),
+                result);
+    }
+
+
+    public boolean isAddPermission(ProductOrder productOrder){
+        Date now = new Date();
+        Date startDate = getTimeByOrder(productOrder.getAppointmentTime(), productOrder.getStartTime());
+        Date endDate = getTimeByOrder(productOrder.getAppointmentTime(), productOrder.getEndTime());
+        Date date = DateUtils.addMinutes(startDate, -30);
+        if ((now.before(startDate) && now.after(date)) || now.before(endDate)){
+            return true;
+        }else if (now.after(endDate)){
+            productOrder.setOrderFlag(ProductOrderStatus.SUCCESS.getCode());
+            return false;
+        }else {
+            return false;
+        }
+    }
+
+    public boolean isDelPermission(ProductOrder productOrder){
+        Date now = new Date();
+        Date startDate = getTimeByOrder(productOrder.getAppointmentTime(), productOrder.getEndTime());
+        return now.before(startDate);
+    }
+
+
+    public Date getTimeByOrder(Date date, LocalTime addDate){
+        date = DateUtils.addHours(date, addDate.getHour());
+        date = DateUtils.addMinutes(date, addDate.getMinute());
+        date = DateUtils.addSeconds(date, addDate.getSecond());
+        return date;
+    }
+
+    public List<ProductOrder> getData(Integer orderFlag){
+        LambdaQueryWrapper<ProductOrder> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(ProductOrder::getOrderFlag, orderFlag);
+        return productOrderService.list(queryWrapper);
+    }
+}

+ 91 - 0
src/main/java/com/usky/dxtop/service/vo/ProductInfoExport.java

@@ -0,0 +1,91 @@
+package com.usky.dxtop.service.vo;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalTime;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author yq
+ * @date 2022/7/7 15:38
+ */
+@Data
+public class ProductInfoExport {
+
+    /**
+     * 主键
+     */
+    @Excel(name = "序号", height = 6, width = 20)
+    private Long id;
+
+    /**
+     * 商品名称
+     */
+    @Excel(name = "商品名称", height = 6, width = 20)
+    private String productName;
+
+    /**
+     * 商品类别编号
+     */
+    @Excel(name = "商品类别编号", height = 6, width = 20)
+    private Long productTypeId;
+
+    /**
+     * 开始时间
+     */
+    @Excel(name = "开始时间", height = 6, width = 20)
+    private LocalTime startTime;
+
+    /**
+     * 结束时间
+     */
+    @Excel(name = "结束时间", height = 6, width = 20)
+    private LocalTime endTime;
+    /**
+     * 费浦设备类型编号
+     */
+    @Excel(name = "费浦设备编号", height = 6, width = 20)
+    private String fpDeviceId;
+
+    /**
+     * 单价
+     */
+    @Excel(name = "商品单价", height = 6, width = 20)
+    private BigDecimal productPrice;
+
+    /**
+     * 重复周期
+     */
+    @Excel(name = "重复周期", height = 6, width = 20)
+    private String repetitionCysles;
+
+    /**
+     * 是否有效
+     */
+    @Excel(name = "是否有效", height = 6, width = 20)
+    private Long status;
+
+    @Excel(name = "创建时间", height = 6, width = 20)
+    private Date createTime;
+
+    /**
+     * 创建人
+     */
+    @Excel(name = "创建人", height = 6, width = 20)
+    private String createBy;
+
+    @Excel(name = "修改人", height = 6, width = 20)
+    private String updateBy;
+
+    @Excel(name = "修改时间", height = 6, width = 20)
+    private Date updateTime;
+
+    @Excel(name = "商品类别名称", height = 6, width = 20)
+    private String productTypeName;
+}

+ 50 - 0
src/main/java/com/usky/dxtop/service/vo/ProductInfoRequest.java

@@ -0,0 +1,50 @@
+package com.usky.dxtop.service.vo;
+
+import lombok.Data;
+
+import java.time.LocalTime;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author yq
+ * @date 2022/6/27 17:30
+ */
+@Data
+public class ProductInfoRequest {
+
+    /**
+     * 页数
+     */
+    private Integer current;
+    /**
+     * 条数
+     */
+    private Integer size;
+    /**
+     * 开始时间
+     */
+    private LocalTime startTime;
+    /**
+     * 结束时间
+     */
+    private LocalTime endTime;
+    /**
+     * 是否有效
+     */
+    private Boolean status;
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * 商品类型编号
+     */
+    private Long produceTypeId;
+    /**
+     * 周期
+     */
+    private List<String> cys;
+
+
+}

+ 140 - 0
src/main/java/com/usky/dxtop/service/vo/ProductOrderExport.java

@@ -0,0 +1,140 @@
+package com.usky.dxtop.service.vo;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalTime;
+import java.util.Date;
+
+/**
+ * @author yq
+ * @date 2022/7/7 15:42
+ */
+@Data
+public class ProductOrderExport {
+
+
+
+    /**
+     * 主键id
+     */
+    @Excel(name = "序号", height = 6, width = 20)
+    private Long id;
+
+    /**
+     * 订单编号
+     */
+    @Excel(name = "订单编号", height = 6, width = 20)
+    private String orderNumber;
+
+    /**
+     * tOrder订单编号
+     */
+    @Excel(name = "退订订单编号", height = 6, width = 20)
+    private String tOrderNumber;
+
+    /**
+     * 商品名称
+     */
+    @Excel(name = "商品名称", height = 6, width = 20)
+    private String productName;
+
+    /**
+     * 商品详情编号
+     */
+    @Excel(name = "商品详情编号", height = 6, width = 20)
+    private Long productInfoId;
+
+    /**
+     * 商品类型名称
+     */
+    @Excel(name = "商品类别名称", height = 6, width = 20)
+    private String productTypeName;
+
+    /**
+     * 商品类型编号
+     */
+    @Excel(name = "商品类别编号", height = 6, width = 20)
+    private Long productTypeId;
+
+    /**
+     * 订单状态
+     */
+    @Excel(name = "订单状态", height = 6, width = 20)
+    private Integer orderFlag;
+
+    /**
+     * 用户编号
+     */
+    @Excel(name = "用户编号", height = 6, width = 20)
+    private Long userId;
+
+    /**
+     * 用户名称
+     */
+    @Excel(name = "用户名称", height = 6, width = 20)
+    private String userName;
+
+    /**
+     * 订单金额
+     */
+    @Excel(name = "订单金额", height = 6, width = 20)
+    private BigDecimal orderMoney;
+
+    /**
+     * 用户手机号
+     */
+    @Excel(name = "手机号", height = 6, width = 20)
+    private String userPhone;
+    /**
+     * 费浦用户编号
+     */
+    @Excel(name = "费浦用户编号", height = 6, width = 20)
+    private String userCode;
+    /**
+     * 卡号
+     */
+    @Excel(name = "卡号", height = 6, width = 20)
+    private String card;
+    /**
+     * 预约时间
+     */
+    @Excel(name = "预约时间", height = 6, width = 20)
+    private Date appointmentTime;
+
+    /**
+     * 费浦设备类型编号
+     */
+    @Excel(name = "费浦门禁编号", height = 6, width = 20)
+    private String fpDeviceId;
+
+    /**
+     * 开始时间
+     */
+    @Excel(name = "开始时间", height = 6, width = 20)
+    private LocalTime startTime;
+
+    /**
+     * 结束时间
+     */
+    @Excel(name = "结束时间", height = 6, width = 20)
+    private LocalTime endTime;
+
+    @Excel(name = "创建时间", height = 6, width = 20)
+    private Date createTime;
+
+    /**
+     * 创建人
+     */
+    @Excel(name = "创建人", height = 6, width = 20)
+    private String createBy;
+
+    @Excel(name = "修改人", height = 6, width = 20)
+    private String updateBy;
+
+    @Excel(name = "修改时间", height = 6, width = 20)
+    private Date updateTime;
+}

+ 56 - 0
src/main/java/com/usky/dxtop/service/vo/ProductOrderRequest.java

@@ -0,0 +1,56 @@
+package com.usky.dxtop.service.vo;
+
+import lombok.Data;
+import oshi.driver.windows.wmi.Win32Processor;
+
+import java.time.LocalTime;
+import java.util.Date;
+
+/**
+ * @author yq
+ * @date 2022/7/6 10:11
+ */
+@Data
+public class ProductOrderRequest {
+
+    /**
+     * 页数
+     */
+    private Integer current;
+    /**
+     * 条数
+     */
+    private Integer size;
+
+    /**
+     * 预约时间
+     */
+    private Date appointmentTime;
+    /**
+     * 开始时间
+     */
+    private LocalTime startTime;
+    /**
+     * 结束时间
+     */
+    private LocalTime endTime;
+    /**
+     * 商品类别编号
+      */
+    private Long productTypeId;
+
+    /**
+     * 用户名称
+     */
+    private String userName;
+
+    /**
+     * 用户编号
+     */
+    private Long userId;
+
+    /**
+     * 订单状态
+     */
+    private Integer productStatus;
+}