Browse Source

代码更新

lei.chen@allpayx.com 4 years ago
parent
commit
63d640beb3
100 changed files with 1699 additions and 210 deletions
  1. 11 0
      pom.xml
  2. 2 0
      src/main/java/com/qrservice/admin/QrServerApplication.java
  3. 1 0
      src/main/java/com/qrservice/admin/annotation/AIQuery.java
  4. 23 0
      src/main/java/com/qrservice/admin/config/MailConfig.java
  5. 29 0
      src/main/java/com/qrservice/admin/config/ServiceProperties.java
  6. 15 3
      src/main/java/com/qrservice/admin/controller/CommonController.java
  7. 60 0
      src/main/java/com/qrservice/admin/controller/admin/LoginController.java
  8. 12 0
      src/main/java/com/qrservice/admin/controller/merchant/MerchantTerminalController.java
  9. 36 2
      src/main/java/com/qrservice/admin/controller/settle/ClearSceneController.java
  10. 24 4
      src/main/java/com/qrservice/admin/controller/settle/SettleTaskController.java
  11. 2 2
      src/main/java/com/qrservice/admin/controller/trans/TransRealController.java
  12. 4 3
      src/main/java/com/qrservice/admin/controller/trans/TransSettleController.java
  13. 51 0
      src/main/java/com/qrservice/admin/controller/transStatistics/StatisticsController.java
  14. 0 2
      src/main/java/com/qrservice/admin/dao/BaseDao.java
  15. 1 6
      src/main/java/com/qrservice/admin/dao/impl/BaseDaoImpl.java
  16. 2 2
      src/main/java/com/qrservice/admin/dao/online/ChannelMerchantDao.java
  17. 8 0
      src/main/java/com/qrservice/admin/dao/online/MerchantStoreDao.java
  18. 2 0
      src/main/java/com/qrservice/admin/dao/online/TransLogDao.java
  19. 12 0
      src/main/java/com/qrservice/admin/dao/online/TransStatisticsDao.java
  20. 2 1
      src/main/java/com/qrservice/admin/filter/AccessLogFilter.java
  21. 16 0
      src/main/java/com/qrservice/admin/model/admin/UserSdInfo.java
  22. 20 0
      src/main/java/com/qrservice/admin/model/admin/UserUpInfo.java
  23. 4 0
      src/main/java/com/qrservice/admin/model/batch/ClearSceneLog.java
  24. 5 0
      src/main/java/com/qrservice/admin/model/batch/SettleTasks.java
  25. 22 0
      src/main/java/com/qrservice/admin/model/bussiness/InstitutionInfo.java
  26. 2 0
      src/main/java/com/qrservice/admin/model/bussiness/MerchantTerminal.java
  27. 0 1
      src/main/java/com/qrservice/admin/model/dto/merchant/MerchantInfoDto.java
  28. 0 1
      src/main/java/com/qrservice/admin/model/dto/merchant/MerchantStoreFdDto.java
  29. 4 0
      src/main/java/com/qrservice/admin/model/dto/merchant/MerchantTerminalDto.java
  30. 1 1
      src/main/java/com/qrservice/admin/model/dto/merchant/MerchantTerminalFdDto.java
  31. 2 0
      src/main/java/com/qrservice/admin/model/dto/merchant/MerchantTerminalUpDto.java
  32. 7 0
      src/main/java/com/qrservice/admin/model/dto/sso/SsoPwdDto.java
  33. 2 3
      src/main/java/com/qrservice/admin/model/dto/trans/TransFdDto.java
  34. 35 0
      src/main/java/com/qrservice/admin/model/dto/trans/TransSettleFdDto.java
  35. 1 1
      src/main/java/com/qrservice/admin/model/param/CommonInfo.java
  36. 16 0
      src/main/java/com/qrservice/admin/model/param/StoreInfo.java
  37. 2 0
      src/main/java/com/qrservice/admin/model/param/Trans.java
  38. 22 0
      src/main/java/com/qrservice/admin/model/statistics/Statistics.java
  39. 19 0
      src/main/java/com/qrservice/admin/model/statistics/StatisticsFdDto.java
  40. 19 0
      src/main/java/com/qrservice/admin/model/statistics/StatisticsInfo.java
  41. 5 0
      src/main/java/com/qrservice/admin/model/transactions/TransLog.java
  42. 116 0
      src/main/java/com/qrservice/admin/schedule/ScheduleTask.java
  43. 6 1
      src/main/java/com/qrservice/admin/service/ClearSceneService.java
  44. 6 1
      src/main/java/com/qrservice/admin/service/CommonService.java
  45. 2 0
      src/main/java/com/qrservice/admin/service/MerchantTerminalService.java
  46. 14 0
      src/main/java/com/qrservice/admin/service/MsgService.java
  47. 4 1
      src/main/java/com/qrservice/admin/service/SettleTaskService.java
  48. 20 0
      src/main/java/com/qrservice/admin/service/StatisticsService.java
  49. 1 1
      src/main/java/com/qrservice/admin/service/TransRealService.java
  50. 3 2
      src/main/java/com/qrservice/admin/service/TransSettleService.java
  51. 10 0
      src/main/java/com/qrservice/admin/service/UserService.java
  52. 5 4
      src/main/java/com/qrservice/admin/service/impl/ChannelServiceImpl.java
  53. 4 7
      src/main/java/com/qrservice/admin/service/impl/ChannelSubServiceImpl.java
  54. 43 4
      src/main/java/com/qrservice/admin/service/impl/ClearSceneServiceImpl.java
  55. 56 12
      src/main/java/com/qrservice/admin/service/impl/CommonServiceImpl.java
  56. 3 3
      src/main/java/com/qrservice/admin/service/impl/MerchantFeeServiceImpl.java
  57. 4 4
      src/main/java/com/qrservice/admin/service/impl/MerchantRouterServiceImpl.java
  58. 31 6
      src/main/java/com/qrservice/admin/service/impl/MerchantServiceImpl.java
  59. 11 4
      src/main/java/com/qrservice/admin/service/impl/MerchantStoreServiceImpl.java
  60. 34 8
      src/main/java/com/qrservice/admin/service/impl/MerchantTerminalServiceImpl.java
  61. 4 4
      src/main/java/com/qrservice/admin/service/impl/MerchantUserServiceImpl.java
  62. 0 5
      src/main/java/com/qrservice/admin/service/impl/ReportInfServiceImpl.java
  63. 33 8
      src/main/java/com/qrservice/admin/service/impl/SettleTaskServiceImpl.java
  64. 18 5
      src/main/java/com/qrservice/admin/service/impl/SsoServiceImpl.java
  65. 142 0
      src/main/java/com/qrservice/admin/service/impl/StatisticsServiceImpl.java
  66. 72 14
      src/main/java/com/qrservice/admin/service/impl/TransRealServiceImpl.java
  67. 24 12
      src/main/java/com/qrservice/admin/service/impl/TransSettleServiceImpl.java
  68. 1 1
      src/main/java/com/qrservice/admin/service/impl/UserGroupServiceImpl.java
  69. 0 2
      src/main/java/com/qrservice/admin/service/impl/UserOperateServiceImpl.java
  70. 132 2
      src/main/java/com/qrservice/admin/service/impl/UserServiceImpl.java
  71. 86 0
      src/main/java/com/qrservice/admin/util/EmailUtils.java
  72. 55 63
      src/main/java/com/qrservice/admin/util/QueryHelp.java
  73. 43 0
      src/main/java/com/qrservice/admin/util/SpringUtil.java
  74. 6 1
      src/main/resources/application-local.yml
  75. 21 1
      src/main/resources/application.yml
  76. 77 0
      src/main/resources/templates/email/common.html
  77. 41 0
      src/main/resources/templates/email/forgetPwd.html
  78. 43 0
      src/test/java/test.java
  79. 6 1
      target/classes/application-local.yml
  80. 21 1
      target/classes/application.yml
  81. BIN
      target/classes/com/qrservice/admin/QrServerApplication.class
  82. BIN
      target/classes/com/qrservice/admin/annotation/AIQuery$Type.class
  83. BIN
      target/classes/com/qrservice/admin/config/ServiceProperties.class
  84. BIN
      target/classes/com/qrservice/admin/controller/CommonController.class
  85. BIN
      target/classes/com/qrservice/admin/controller/admin/LoginController.class
  86. BIN
      target/classes/com/qrservice/admin/controller/merchant/MerchantTerminalController.class
  87. BIN
      target/classes/com/qrservice/admin/controller/settle/ClearSceneController.class
  88. BIN
      target/classes/com/qrservice/admin/controller/settle/SettleTaskController.class
  89. BIN
      target/classes/com/qrservice/admin/controller/trans/TransRealController.class
  90. BIN
      target/classes/com/qrservice/admin/controller/trans/TransSettleController.class
  91. BIN
      target/classes/com/qrservice/admin/dao/BaseDao.class
  92. BIN
      target/classes/com/qrservice/admin/dao/impl/BaseDaoImpl.class
  93. BIN
      target/classes/com/qrservice/admin/dao/online/ChannelMerchantDao.class
  94. BIN
      target/classes/com/qrservice/admin/dao/online/MerchantStoreDao.class
  95. BIN
      target/classes/com/qrservice/admin/dao/online/TransLogDao.class
  96. BIN
      target/classes/com/qrservice/admin/filter/AccessLogFilter$1.class
  97. BIN
      target/classes/com/qrservice/admin/filter/AccessLogFilter$2.class
  98. BIN
      target/classes/com/qrservice/admin/filter/AccessLogFilter.class
  99. BIN
      target/classes/com/qrservice/admin/model/batch/ClearSceneLog.class
  100. 0 0
      target/classes/com/qrservice/admin/model/batch/SettleTasks.class

+ 11 - 0
pom.xml

@@ -95,6 +95,17 @@
             <artifactId>nimbus-jose-jwt</artifactId>
             <version>4.23</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-mail</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+        </dependency>
+
     </dependencies>
 
 

+ 2 - 0
src/main/java/com/qrservice/admin/QrServerApplication.java

@@ -4,6 +4,7 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
 import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
+import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.web.bind.annotation.RestController;
 
 /**
@@ -12,6 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
  * @Date: 2020/8/7 10:09
  */
 @RestController
+@EnableScheduling
 @SpringBootApplication(scanBasePackages = {"com.qrservice.admin"},exclude =
         {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
 public class QrServerApplication {

+ 1 - 0
src/main/java/com/qrservice/admin/annotation/AIQuery.java

@@ -41,6 +41,7 @@ public @interface AIQuery {
         , GREATER_THAN_AND_LESS_THAN
         /* 或者*/
         ,OR
+        ,IS_NULL
     }
 
 

+ 23 - 0
src/main/java/com/qrservice/admin/config/MailConfig.java

@@ -0,0 +1,23 @@
+package com.qrservice.admin.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ *
+ * 配置文件转化为实体类
+ * Created by skf
+ * Date 2018/5/15.
+ */
+@Component
+@ConfigurationProperties(prefix = "spring.mail")
+@Data
+public class MailConfig {
+
+    private String host;
+    private String username;
+    private String password;
+    private String subjectenv;
+
+}

+ 29 - 0
src/main/java/com/qrservice/admin/config/ServiceProperties.java

@@ -36,6 +36,8 @@ public class ServiceProperties {
 
     private String storeCode;
 
+    private String statusFail;
+
     private String pwd;
 
     private String userName;
@@ -52,4 +54,31 @@ public class ServiceProperties {
 
     private List<String> currencyList;
 
+    private String country;
+
+    private String propertyGroup;
+
+    private String settleRedoUrl;
+
+    private String settleConfirmUrl;
+
+    private String clearIgnoreUrl;
+
+    private String clearRedoUrl;
+
+    private String emailUrl;
+
+    private String loginKey;
+
+    private String institutionCode;
+
+    private String  entityTypeAcquirer;
+
+    private String  entityTypeMerchant;
+
+    private String  statusSuccess;
+
+    private String consume;
+
+    private String refund;
 }

+ 15 - 3
src/main/java/com/qrservice/admin/controller/CommonController.java

@@ -2,6 +2,7 @@ package com.qrservice.admin.controller;
 
 import com.qrservice.admin.model.bussiness.ConfigInfo;
 import com.qrservice.admin.model.bussiness.Mcc;
+import com.qrservice.admin.model.bussiness.MerchantInfo;
 import com.qrservice.admin.model.bussiness.SpecificationInfo;
 import com.qrservice.admin.model.dto.ConfigInfoDTO;
 import com.qrservice.admin.model.dto.channel.ChannelMerchantDto;
@@ -43,12 +44,23 @@ public class CommonController {
      */
     @RequestMapping(value = "findMid",method = RequestMethod.GET)
     public ResultVO findMid(HttpServletRequest request){
-        CommonInfo info=service.findMid(request);
+        List<MerchantInfo> info=service.finMidName(request);
         ResultVO vo = new ResultVO();
         vo.setData(info);
         return vo;
     }
 
+    /**
+     * 查询所有商户ID(除集团商户)
+     * @return
+     */
+    @RequestMapping(value = "findMidExGroup",method = RequestMethod.GET)
+    public ResultVO findMidExGroup(HttpServletRequest request){
+        List<MerchantInfo> info=service.findMidExGroup(request);
+        ResultVO vo = new ResultVO();
+        vo.setData(info);
+        return vo;
+    }
 
     /**
      * 查询所有商户ID
@@ -119,8 +131,8 @@ public class CommonController {
      * @return
      */
     @RequestMapping(value = "channelSubMerchant",method = RequestMethod.GET)
-    public ResultVO channelSubMerchant(String specification) {
-        List<ChannelSubMerchantDto> info=service.channelSubMerchant(specification);
+    public ResultVO channelSubMerchant(String specification,HttpServletRequest request) {
+        List<ChannelSubMerchantDto> info=service.channelSubMerchant(specification,request);
         ResultVO vo = new ResultVO();
         vo.setData(info);
         return vo;

+ 60 - 0
src/main/java/com/qrservice/admin/controller/admin/LoginController.java

@@ -2,8 +2,11 @@ package com.qrservice.admin.controller.admin;
 
 import com.qrservice.admin.model.admin.LoginToken;
 import com.qrservice.admin.model.admin.UserInfo;
+import com.qrservice.admin.model.admin.UserSdInfo;
+import com.qrservice.admin.model.admin.UserUpInfo;
 import com.qrservice.admin.model.vo.ResultVO;
 import com.qrservice.admin.service.UserService;
+import com.qrservice.admin.util.EmailUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -58,4 +61,61 @@ public class LoginController {
         return vo;
     }
 
+    /**
+     * 修改密码
+     *
+     * @return
+     */
+    @RequestMapping(value = "/admin/pwd/update", method = RequestMethod.POST)
+    public ResultVO updatePwd(HttpServletRequest request,@RequestBody UserUpInfo info) {
+        String title = userService.updatePwd(request,info);
+        ResultVO vo = new ResultVO();
+        vo.setMessage("密码修改成功");
+        vo.setTitle(title);
+        return vo;
+    }
+
+
+    /**
+     * 发送忘记密码邮件
+     *
+     * @return
+     */
+    @RequestMapping(value = "/admin/pwd/email/send", method = RequestMethod.POST)
+    public ResultVO sendPwdEmail(HttpServletRequest request ,@RequestBody UserSdInfo info) {
+       userService.sendPwdEmail(request,info);
+       ResultVO vo = new ResultVO();
+       vo.setMessage("Email sent successfully");
+       return vo;
+    }
+
+    /**
+     * 邮箱回调验证
+     *
+     * @return
+     */
+    @RequestMapping(value = "/admin/email/verify/send", method = RequestMethod.GET)
+    public ResultVO verifyPwdEmail(HttpServletRequest request ,@RequestParam("token") String token) {
+        userService.verifyPwdEmail(request,token);
+        ResultVO vo = new ResultVO();
+        vo.setMessage("邮件有效性验证正确");
+        return vo;
+    }
+
+
+    /**
+     * 邮箱回调地址密码修改
+     *
+     * @return
+     */
+    @RequestMapping(value = "/admin/update/pwd/send", method = RequestMethod.GET)
+    public ResultVO updatePwdEmail(HttpServletRequest request ,UserUpInfo info) {
+        userService.updatePwdEmail(request,info);
+        ResultVO vo = new ResultVO();
+        vo.setMessage("The password has been changed");
+        return vo;
+    }
+
+
+
 }

+ 12 - 0
src/main/java/com/qrservice/admin/controller/merchant/MerchantTerminalController.java

@@ -76,6 +76,18 @@ public class MerchantTerminalController {
     }
 
 
+    /**
+     * 重新生成终端激活码
+     * @return
+     */
+    @RequestMapping(value = "code/update",method = RequestMethod.GET)
+    public ResultVO updateMerchantTerminal(String terminalId) {
+        String title=service.updateMerchantTerminalCode(terminalId);
+        ResultVO vo = new ResultVO();
+        vo.setTitle(title);
+        return vo;
+    }
+
 
     /**
      * 查询终端信息

+ 36 - 2
src/main/java/com/qrservice/admin/controller/settle/ClearSceneController.java

@@ -1,5 +1,6 @@
 package com.qrservice.admin.controller.settle;
 
+import com.alibaba.fastjson.JSON;
 import com.qrservice.admin.model.batch.ClearSceneLog;
 import com.qrservice.admin.model.vo.ResultVO;
 import com.qrservice.admin.service.ClearSceneService;
@@ -15,6 +16,8 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @Company: AllPay
@@ -43,9 +46,40 @@ public class ClearSceneController {
      */
     @RequestMapping(value = "find",method = RequestMethod.GET)
     public ResultVO findClearScene(@PageableDefault( sort = { "createTime" }, direction = Sort.Direction.DESC) Pageable pageable, HttpServletRequest request){
-        Page<ClearSceneLog> page = service.findClearScene(pageable,request);
+        List<ClearSceneLog> list = service.findClearScene(pageable,request);
         ResultVO vo = new ResultVO();
-        vo.setData(page);
+        vo.setData(list);
         return vo;
     }
+
+
+    /**
+     * 清分场次忽略
+     * @return
+     */
+    @RequestMapping(value = "ignore/update",method = RequestMethod.GET)
+    public ResultVO clearIgnore(String id, HttpServletRequest request){
+        String response=service.clearIgnore(id,request);
+        ResultVO vo = new ResultVO();
+        Map map = JSON.parseObject(response, Map.class);
+        vo.setMessage((String) map.get("message"));
+        vo.setStatus((String) map.get("status"));
+        return vo;
+    }
+
+
+    /**
+     * 清分场次重跑
+     * @return
+     */
+    @RequestMapping(value = "redo/update",method = RequestMethod.GET)
+    public ResultVO clearRedo(String id, HttpServletRequest request){
+        String response=service.clearRedo(id,request);
+        ResultVO vo = new ResultVO();
+        Map map = JSON.parseObject(response, Map.class);
+        vo.setMessage((String) map.get("message"));
+        vo.setStatus((String) map.get("status"));
+        return vo;
+    }
+
 }

+ 24 - 4
src/main/java/com/qrservice/admin/controller/settle/SettleTaskController.java

@@ -1,5 +1,6 @@
 package com.qrservice.admin.controller.settle;
 
+import com.alibaba.fastjson.JSON;
 import com.qrservice.admin.model.batch.SettleTasks;
 import com.qrservice.admin.model.dto.settle.SettleTaskAdDto;
 import com.qrservice.admin.model.vo.ResultVO;
@@ -13,6 +14,9 @@ import org.springframework.data.web.PageableDefault;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @Company: AllPay
@@ -41,7 +45,7 @@ public class SettleTaskController {
      */
     @RequestMapping(value = "find",method = RequestMethod.GET)
     public ResultVO findSettleTask(@PageableDefault( sort = { "createTime" }, direction = Sort.Direction.DESC) Pageable pageable, HttpServletRequest request){
-        Page<SettleTasks> page = service.findSettleTask(pageable,request);
+        List<SettleTasks> page = service.findSettleTask(pageable,request);
         ResultVO vo = new ResultVO();
         vo.setData(page);
         return vo;
@@ -52,7 +56,7 @@ public class SettleTaskController {
      * @return
      */
     @RequestMapping(value = "add",method = RequestMethod.POST)
-    public ResultVO addSettleTask(@RequestBody SettleTaskAdDto dto, HttpServletRequest request){
+    public ResultVO addSettleTask(@RequestBody @Valid SettleTaskAdDto dto, HttpServletRequest request){
         String title=service.addSettleTask(dto,request);
         ResultVO vo = new ResultVO();
         vo.setTitle(title);
@@ -66,9 +70,25 @@ public class SettleTaskController {
      */
     @RequestMapping(value = "update",method = RequestMethod.GET)
     public ResultVO updateSettleTask(String id, HttpServletRequest request){
-        String title=service.updateSettleTask(id,request);
+        String response=service.updateSettleTask(id,request);
         ResultVO vo = new ResultVO();
-        vo.setTitle(title);
+        Map map = JSON.parseObject(response, Map.class);
+        vo.setMessage((String) map.get("message"));
+        vo.setStatus((String) map.get("status"));
+        return vo;
+    }
+
+    /**
+     * 确认报表正确
+     * @return
+     */
+    @RequestMapping(value = "report/update",method = RequestMethod.GET)
+    public ResultVO confirmReport(String id, HttpServletRequest request){
+        String response=service.confirmReport(id,request);
+        ResultVO vo = new ResultVO();
+        Map map = JSON.parseObject(response, Map.class);
+        vo.setMessage((String) map.get("message"));
+        vo.setStatus((String) map.get("status"));
         return vo;
     }
 }

+ 2 - 2
src/main/java/com/qrservice/admin/controller/trans/TransRealController.java

@@ -71,8 +71,8 @@ public class TransRealController {
      * @return
      */
     @RequestMapping(value = "refund",method = RequestMethod.POST)
-    public ResultVO refund(@Valid @RequestBody TransDto dto) {
-        String response = service.refund(dto);
+    public ResultVO refund(@Valid @RequestBody TransDto dto,HttpServletRequest request) {
+        String response = service.refund(dto,request);
         ResultVO vo = new ResultVO();
         Map map = JSON.parseObject(response, Map.class);
         vo.setMessage((String) map.get("message"));

+ 4 - 3
src/main/java/com/qrservice/admin/controller/trans/TransSettleController.java

@@ -3,6 +3,7 @@ package com.qrservice.admin.controller.trans;
 import com.alibaba.fastjson.JSON;
 import com.qrservice.admin.model.dto.trans.TransDto;
 import com.qrservice.admin.model.dto.trans.TransFdDto;
+import com.qrservice.admin.model.dto.trans.TransSettleFdDto;
 import com.qrservice.admin.model.param.TransDetail;
 import com.qrservice.admin.model.settletransaction.SettleTransLogHis;
 import com.qrservice.admin.model.transactions.TransLog;
@@ -46,7 +47,7 @@ public class TransSettleController {
      */
     @RequestMapping(value = "find",method = RequestMethod.GET)
     public ResultVO findSettleTrans(@PageableDefault( sort = { "orderTime" }, direction = Sort.Direction.DESC) Pageable pageable,
-                                    @Valid TransFdDto dto, HttpServletRequest request) throws Exception {
+                                    @Valid TransSettleFdDto dto, HttpServletRequest request) throws Exception {
         Page<SettleTransLogHis> page = service.findSettleTrans(pageable, dto,request);
         ResultVO vo = new ResultVO();
         vo.setData(page);
@@ -70,8 +71,8 @@ public class TransSettleController {
      * @return
      */
     @RequestMapping(value = "refund",method = RequestMethod.POST)
-    public ResultVO refund(@Valid @RequestBody TransDto dto) {
-        String response = service.refund(dto);
+    public ResultVO refund(@Valid @RequestBody TransDto dto,HttpServletRequest request) {
+        String response = service.refund(dto,request);
         ResultVO vo = new ResultVO();
         Map map = JSON.parseObject(response, Map.class);
         vo.setMessage((String) map.get("message"));

+ 51 - 0
src/main/java/com/qrservice/admin/controller/transStatistics/StatisticsController.java

@@ -0,0 +1,51 @@
+package com.qrservice.admin.controller.transStatistics;
+
+import com.qrservice.admin.model.dto.sso.SsoUserAdDto;
+import com.qrservice.admin.model.statistics.StatisticsFdDto;
+import com.qrservice.admin.model.statistics.StatisticsInfo;
+import com.qrservice.admin.model.transactions.TransStatistics;
+import com.qrservice.admin.model.vo.ResultVO;
+import com.qrservice.admin.service.SsoService;
+import com.qrservice.admin.service.StatisticsService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/10/10 9:47
+ */
+@RestController
+@RequestMapping("statistics")
+@Slf4j
+@CrossOrigin
+public class StatisticsController {
+
+
+
+    private final StatisticsService service;
+
+    @Autowired
+    public StatisticsController(StatisticsService service) {
+        this.service = service;
+    }
+
+
+    /**
+     * 查询交易统计记录
+     * @return
+     */
+    @RequestMapping(value = "find",method = RequestMethod.POST)
+    public ResultVO findStatisticsRecord(@Valid @RequestBody StatisticsFdDto dto, HttpServletRequest request){
+        Map<String, StatisticsInfo> data= service.findStatisticsRecord(dto, request);
+        ResultVO vo = new ResultVO();
+        vo.setData(data);
+        return vo;
+    }
+}

+ 0 - 2
src/main/java/com/qrservice/admin/dao/BaseDao.java

@@ -42,8 +42,6 @@ public interface BaseDao<T, ID extends Serializable> extends MongoRepository<T,I
 
     long updateMulti(Query query, Update update);
 
-    List<T> findByCondition(Document condition);
-
     long updateFirst(Query query, Update update);
 
     void saveAll(List<T> reconlist);

+ 1 - 6
src/main/java/com/qrservice/admin/dao/impl/BaseDaoImpl.java

@@ -114,6 +114,7 @@ public class BaseDaoImpl<T, ID extends Serializable> extends SimpleMongoReposito
         return updateResult.getModifiedCount();
     }
 
+
     private void checkUpdateObject(Update update) {
         Document updateObject = update.getUpdateObject();
         if(CollUtil.isEmpty(updateObject)) {
@@ -122,12 +123,6 @@ public class BaseDaoImpl<T, ID extends Serializable> extends SimpleMongoReposito
     }
 
     @Override
-    public List<T> findByCondition(Document condition) {
-        BasicQuery query = new BasicQuery(condition);
-        return mongoTemplate.find(query,clazz);
-    }
-
-    @Override
     public long updateFirst(Query query, Update update) {
         checkUpdateObject(update);
         return mongoTemplate.updateFirst(query,update,clazz).getModifiedCount();

+ 2 - 2
src/main/java/com/qrservice/admin/dao/online/ChannelMerchantDao.java

@@ -19,8 +19,8 @@ public interface ChannelMerchantDao extends BaseDao<ChannelMerchant, String> {
 
     @Query("{ 'institutionCode' : ?0 }")
     List<ChannelMerchantDto> findAllId(String institutionCode);
-    @Query("{ 'specification' : ?0 }")
-    List<ChannelSubMerchantDto> findBySpecification(String specification);
+    @Query("{ 'specification' : ?0 ,'institutionCode' : ?1 }")
+    List<ChannelSubMerchantDto> findBySpecification(String specification,String institutionCode);
     @Query("{ 'institutionCode' : ?0 }")
     List<ChannelMerchantDto> findByInstitutionCode(String institutionCode);
 }

+ 8 - 0
src/main/java/com/qrservice/admin/dao/online/MerchantStoreDao.java

@@ -2,6 +2,11 @@ package com.qrservice.admin.dao.online;
 
 import com.qrservice.admin.dao.BaseDao;
 import com.qrservice.admin.model.bussiness.MerchantStore;
+import com.qrservice.admin.model.dto.channel.ChannelMerchantDto;
+import com.qrservice.admin.model.param.StoreInfo;
+import org.springframework.data.mongodb.repository.Query;
+
+import java.util.List;
 
 /**
  * @Company: AllPay
@@ -9,4 +14,7 @@ import com.qrservice.admin.model.bussiness.MerchantStore;
  * @Date: 2020/8/14 13:43
  */
 public interface MerchantStoreDao extends BaseDao<MerchantStore,String> {
+
+    @Query("{ 'merchantId' : ?0 }")
+    List<StoreInfo> findAllSid(String merchantId);
 }

+ 2 - 0
src/main/java/com/qrservice/admin/dao/online/TransLogDao.java

@@ -17,4 +17,6 @@ public interface TransLogDao extends BaseDao<TransLog,String> {
     @Query("{ 'orderId' : ?0 ,'transType':{$ne:?1} }")
     List<Trans> findOrder(String orderId, String transType);
 
+    @Query("{ 'originOrderId':?0 ,'transType':{$ne:?1} }")
+    List<Trans> findRefundOrder(String orderId, String transType);
 }

+ 12 - 0
src/main/java/com/qrservice/admin/dao/online/TransStatisticsDao.java

@@ -0,0 +1,12 @@
+package com.qrservice.admin.dao.online;
+
+import com.qrservice.admin.dao.BaseDao;
+import com.qrservice.admin.model.transactions.TransStatistics;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/9/30 9:14
+ */
+public interface TransStatisticsDao extends BaseDao<TransStatistics,String> {
+}

+ 2 - 1
src/main/java/com/qrservice/admin/filter/AccessLogFilter.java

@@ -46,7 +46,7 @@ import java.util.TreeMap;
  * @date 2019/07/24
  **/
 @Slf4j
-//@Component
+@Component
 public class AccessLogFilter extends OncePerRequestFilter implements Ordered {
     private Integer payloadMaxLength = 2048;
     /**
@@ -76,6 +76,7 @@ public class AccessLogFilter extends OncePerRequestFilter implements Ordered {
             // 得到用户个人相关的信息(登陆的用户,用户的语言)
             if(!request.getRequestURI().contains("login") && !request.getMethod().equals("OPTIONS")
                     &&!request.getRequestURI().contains("export")
+                    &&!request.getRequestURI().contains("send")
                     &&!request.getRequestURI().contains("downLoad")){
                 fillUserInfo(request);
             }

+ 16 - 0
src/main/java/com/qrservice/admin/model/admin/UserSdInfo.java

@@ -0,0 +1,16 @@
+package com.qrservice.admin.model.admin;
+
+import lombok.Data;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/9/25 9:53
+ */
+@Data
+public class UserSdInfo {
+
+    private String userId;
+
+    private String email;
+}

+ 20 - 0
src/main/java/com/qrservice/admin/model/admin/UserUpInfo.java

@@ -0,0 +1,20 @@
+package com.qrservice.admin.model.admin;
+
+import lombok.Data;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/9/24 8:39
+ */
+@Data
+public class UserUpInfo {
+
+    private String token;
+
+    private String originPwd;
+
+    private String password;
+
+
+}

+ 4 - 0
src/main/java/com/qrservice/admin/model/batch/ClearSceneLog.java

@@ -1,6 +1,7 @@
 package com.qrservice.admin.model.batch;
 
 import lombok.Data;
+import org.springframework.data.annotation.Id;
 import org.springframework.data.mongodb.core.mapping.Document;
 
 import java.util.Date;
@@ -14,6 +15,9 @@ import java.util.Date;
 @Document
 public class ClearSceneLog {
 
+    @Id
+    private String id;
+
     /**
      * 机构代码
      */

+ 5 - 0
src/main/java/com/qrservice/admin/model/batch/SettleTasks.java

@@ -1,6 +1,7 @@
 package com.qrservice.admin.model.batch;
 
 import lombok.Data;
+import org.springframework.data.annotation.Id;
 import org.springframework.data.mongodb.core.mapping.Document;
 
 import java.util.Date;
@@ -14,6 +15,9 @@ import java.util.Date;
 @Document
 public class SettleTasks {
 
+    @Id
+    private String id;
+
     /**
      * 机构代码
      */
@@ -71,4 +75,5 @@ public class SettleTasks {
     private Date updateTime;
 
     private Date createTime;
+
 }

+ 22 - 0
src/main/java/com/qrservice/admin/model/bussiness/InstitutionInfo.java

@@ -72,6 +72,28 @@ public class InstitutionInfo {
      */
     private List<String> listMid;
 
+    /**
+     * 机构平台名称
+     */
+    private String acquirerPortalName;
+
+    /**
+     * 机构平台地址
+     */
+    private String acquirerPortalUrl;
+
+    /**
+     * 商户平台名称
+     */
+    private String merchantPortalName;
+
+    /**
+     * 商户平台地址
+     */
+    private String merchantPortalUrl;
+
+
+    private String iconUrl;
 
     private Date updateTime;
 

+ 2 - 0
src/main/java/com/qrservice/admin/model/bussiness/MerchantTerminal.java

@@ -69,6 +69,8 @@ public class MerchantTerminal {
      */
     private String terminalStatus;
 
+    private String telephone;
+
     /**
      *别名,商户下唯一
      */

+ 0 - 1
src/main/java/com/qrservice/admin/model/dto/merchant/MerchantInfoDto.java

@@ -19,7 +19,6 @@ public class MerchantInfoDto {
     private String createStart;
     @NotNull
     private String createEnd;
-    @AIQuery(alias = {"merchantId","merchantName.englishName","merchantName.fullName"},type = AIQuery.Type.OR)
     private String keyWord;
     @AIQuery
     private String merchantStatus;

+ 0 - 1
src/main/java/com/qrservice/admin/model/dto/merchant/MerchantStoreFdDto.java

@@ -11,7 +11,6 @@ import lombok.Data;
 @Data
 public class MerchantStoreFdDto {
 
-    @AIQuery(alias = {"merchantId","storeName","storeId"},type = AIQuery.Type.OR)
     private String keyWord;
 
     private String institutionCode;

+ 4 - 0
src/main/java/com/qrservice/admin/model/dto/merchant/MerchantTerminalDto.java

@@ -22,4 +22,8 @@ public class MerchantTerminalDto {
     private String transCurrency;
     private String remarks;
 
+    private String telephone;
+
+    private String password;
+
 }

+ 1 - 1
src/main/java/com/qrservice/admin/model/dto/merchant/MerchantTerminalFdDto.java

@@ -13,7 +13,7 @@ import javax.validation.constraints.NotNull;
 @Data
 public class MerchantTerminalFdDto {
 
-    @AIQuery(alias = {"terminalId","merchantId","storeId"},type = AIQuery.Type.OR)
+
     private String keyWord;
 
     private String institutionCode;

+ 2 - 0
src/main/java/com/qrservice/admin/model/dto/merchant/MerchantTerminalUpDto.java

@@ -27,4 +27,6 @@ public class MerchantTerminalUpDto {
 
     private String terminalStatus;
 
+    private String telephone;
+
 }

+ 7 - 0
src/main/java/com/qrservice/admin/model/dto/sso/SsoPwdDto.java

@@ -14,5 +14,12 @@ public class SsoPwdDto {
 
     private String password;
 
+    private String userStatus;
+
+    private String contactEmail;
+
+    private String contactPhoneNo;
+
     private String userGroup;
+
 }

+ 2 - 3
src/main/java/com/qrservice/admin/model/dto/trans/TransFdDto.java

@@ -13,15 +13,12 @@ import javax.validation.constraints.NotNull;
 @Data
 public class TransFdDto {
 
-    @AIQuery(alias = {"transId","merchantId","terminalId","channelOrderNum","orderId"},type = AIQuery.Type.OR)
     private String keyWord;
     @NotNull
     private String orderTimeStart;
     @NotNull
     private String orderTimeEnd;
     @AIQuery
-    private String scene;
-    @AIQuery
     private String brand;
     @AIQuery
     private String institutionCode;
@@ -31,4 +28,6 @@ public class TransFdDto {
     private String currency;
 
 
+
+
 }

+ 35 - 0
src/main/java/com/qrservice/admin/model/dto/trans/TransSettleFdDto.java

@@ -0,0 +1,35 @@
+package com.qrservice.admin.model.dto.trans;
+
+import com.qrservice.admin.annotation.AIQuery;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/9/28 18:13
+ */
+@Data
+public class TransSettleFdDto {
+
+
+    private String keyWord;
+    @NotNull
+    private String settleDateStart;
+    @NotNull
+    private String settleDateEnd;
+
+    private String orderTimeStart;
+    private String orderTimeEnd;
+    @AIQuery
+    private String brand;
+    @AIQuery
+    private String transType;
+    @AIQuery
+    private String institutionCode;
+    @AIQuery
+    private String channelMerchantId;
+    @AIQuery
+    private String channelSubMerchantId;
+}

+ 1 - 1
src/main/java/com/qrservice/admin/model/param/CommonInfo.java

@@ -14,5 +14,5 @@ public class CommonInfo {
 
     private List<String> listMid;
 
-    private List<String> listSid;
+    private  List<StoreInfo> listSid;
 }

+ 16 - 0
src/main/java/com/qrservice/admin/model/param/StoreInfo.java

@@ -0,0 +1,16 @@
+package com.qrservice.admin.model.param;
+
+import lombok.Data;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/10/9 10:12
+ */
+@Data
+public class StoreInfo {
+
+    private String storeId;
+
+    private String storeName;
+}

+ 2 - 0
src/main/java/com/qrservice/admin/model/param/Trans.java

@@ -15,6 +15,8 @@ public class Trans {
 
     private String transId;
 
+    private String orderId;
+
     private String transType;
 
     private String scene;

+ 22 - 0
src/main/java/com/qrservice/admin/model/statistics/Statistics.java

@@ -0,0 +1,22 @@
+package com.qrservice.admin.model.statistics;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/10/12 10:02
+ */
+@Data
+public class Statistics {
+
+    private List<String> transDate;
+
+    private List<BigDecimal> amount;
+
+    private List<Integer> count;
+
+}

+ 19 - 0
src/main/java/com/qrservice/admin/model/statistics/StatisticsFdDto.java

@@ -0,0 +1,19 @@
+package com.qrservice.admin.model.statistics;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/10/10 9:52
+ */
+@Data
+public class StatisticsFdDto {
+
+    @NotNull
+    private String transDateStart;
+    @NotNull
+    private String transDateEnd;
+}

+ 19 - 0
src/main/java/com/qrservice/admin/model/statistics/StatisticsInfo.java

@@ -0,0 +1,19 @@
+package com.qrservice.admin.model.statistics;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/10/12 10:03
+ */
+@Data
+public class StatisticsInfo {
+
+    private Statistics refund;
+
+    private Statistics consume;
+
+}

+ 5 - 0
src/main/java/com/qrservice/admin/model/transactions/TransLog.java

@@ -62,6 +62,11 @@ public class TransLog {
     private String orderId;
 
     /**
+     * 原始订单号
+     */
+    private String originOrderId;
+
+    /**
      * 订单号,商户上送的订单号
      */
     private String orderNum;

+ 116 - 0
src/main/java/com/qrservice/admin/schedule/ScheduleTask.java

@@ -0,0 +1,116 @@
+package com.qrservice.admin.schedule;
+
+import com.qrservice.admin.config.ServiceProperties;
+import com.qrservice.admin.dao.online.*;
+import com.qrservice.admin.model.bussiness.appendix.Amount;
+import com.qrservice.admin.model.transactions.TransLog;
+import com.qrservice.admin.model.transactions.TransStatistics;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import org.springframework.data.mongodb.core.query.Query;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/9/27 17:08
+ */
+@Slf4j
+@Component
+@Profile("prod")
+public class ScheduleTask {
+
+    private final TransStatisticsDao dao;
+
+    private final TransLogDao transLogDao;
+
+    private final ServiceProperties properties;
+
+
+    @Autowired
+    public ScheduleTask(ServiceProperties properties, TransStatisticsDao dao, TransLogDao transLogDao) {
+        this.dao = dao;
+        this.transLogDao = transLogDao;
+        this.properties = properties;
+    }
+
+    /**
+     * 日交易统计,每一小时统计一次
+     */
+    @Scheduled(cron = "* 0/60 * * * *")
+    public void store_forward() {
+        //查询当日的所有交易
+        log.info("交易开始统计");
+        Query query = new Query();
+        query.addCriteria(Criteria.where("createTime").gte(getStartDate()).lte(new Date()));
+        //删除今日交易统计
+        dao.remove(query);
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        String transDate = sdf.format(new Date());
+        query.addCriteria(Criteria.where("paymentStatus").is(properties.getStatusSuccess()));
+        List<TransLog> list = transLogDao.findByCondition(query);
+        //交易归类(按机构)
+        Map<String, List<TransLog>> icList = list.stream().collect(Collectors.groupingBy(TransLog::getInstitutionCode));
+        dealTrans(transDate, icList,properties.getEntityTypeAcquirer());
+        //交易归类(按商户)
+        Map<String, List<TransLog>> infoList = list.stream().collect(Collectors.groupingBy(TransLog::getMerchantId));
+        dealTrans(transDate, infoList,properties.getEntityTypeMerchant());
+        log.info("交易统计结束");
+    }
+
+    private void dealTrans(String transDate, Map<String, List<TransLog>> icList,String type) {
+        if(icList.size()>0){
+            TransStatistics info = new TransStatistics();
+            info.setEntityType(type);
+            info.setCreateTime(new Date());
+            info.setUpdateTime(new Date());
+            icList.forEach((k,v)->{
+                info.setEntityCode(k);
+                info.setTransDate(transDate);
+                //按品牌再进行区分
+                Map<String, List<TransLog>> brandList = v.stream().collect(Collectors.groupingBy(TransLog::getBrand));
+                brandList.forEach((brand,val)->{
+                    info.setBrand(brand);
+                    //按交易类型再进行区分
+                    Map<String, List<TransLog>> typeList = v.stream().collect(Collectors.groupingBy(TransLog::getTransType));
+                    typeList.forEach((tansType,value)->{
+                        info.setTransType(tansType);
+                        //按币种再进行区分
+                        Map<String, List<TransLog>> finalList = value.stream().collect(Collectors.groupingBy(t -> (t.getTransAmount().getCurrency())));
+                        finalList.forEach((cuy,last)->{
+                            Amount amount = new Amount();
+                            amount.setCurrency(cuy);
+                            int sum = last.stream().mapToInt(t -> (t.getTransAmount().getValue())).sum();
+                            amount.setValue(sum);
+                            info.setCount(last.size());
+                            info.setTransAmount(amount);
+                            dao.insert(info);
+                        });
+                    });
+                });
+            });
+        }
+    }
+
+    public Date getStartDate() {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
+        String transDate = sdf.format(new Date());
+        Date dayStart=null;
+        try {
+            dayStart = sdf.parse(transDate);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return dayStart;
+    }
+
+}

+ 6 - 1
src/main/java/com/qrservice/admin/service/ClearSceneService.java

@@ -5,6 +5,7 @@ import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.List;
 
 /**
  * @Company: AllPay
@@ -13,6 +14,10 @@ import javax.servlet.http.HttpServletRequest;
  */
 public interface ClearSceneService {
 
-    Page<ClearSceneLog> findClearScene(Pageable pageable, HttpServletRequest request);
+    List<ClearSceneLog> findClearScene(Pageable pageable, HttpServletRequest request);
+
+    String clearIgnore(String id, HttpServletRequest request);
+
+    String clearRedo(String id, HttpServletRequest request);
 
 }

+ 6 - 1
src/main/java/com/qrservice/admin/service/CommonService.java

@@ -2,6 +2,7 @@ package com.qrservice.admin.service;
 
 import com.qrservice.admin.model.bussiness.ConfigInfo;
 import com.qrservice.admin.model.bussiness.Mcc;
+import com.qrservice.admin.model.bussiness.MerchantInfo;
 import com.qrservice.admin.model.bussiness.SpecificationInfo;
 import com.qrservice.admin.model.dto.ConfigInfoDTO;
 import com.qrservice.admin.model.dto.channel.ChannelMerchantDto;
@@ -32,11 +33,15 @@ public interface CommonService {
 
     List<ChannelMerchantDto> channelMerchant(HttpServletRequest request) throws Exception;
 
-    List<ChannelSubMerchantDto> channelSubMerchant(String specification);
+    List<ChannelSubMerchantDto> channelSubMerchant(String specification,HttpServletRequest request);
 
     List<String> findCy(String merchantId);
 
     List<UserGroup> findGp(HttpServletRequest request);
 
     List<PermissionGroup> findPgp(HttpServletRequest request);
+
+    List<MerchantInfo> finMidName(HttpServletRequest request);
+
+    List<MerchantInfo> findMidExGroup(HttpServletRequest request);
 }

+ 2 - 0
src/main/java/com/qrservice/admin/service/MerchantTerminalService.java

@@ -25,4 +25,6 @@ public interface MerchantTerminalService {
     Page<MerchantTerminal> findMerchantTerminal(Pageable pageable, MerchantTerminalFdDto dto, HttpServletRequest request);
 
     void export(MerchantTerminalFdDto dto, HttpServletResponse response) throws IOException;
+
+    String updateMerchantTerminalCode(String terminalId);
 }

+ 14 - 0
src/main/java/com/qrservice/admin/service/MsgService.java

@@ -0,0 +1,14 @@
+package com.qrservice.admin.service;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/9/25 15:42
+ */
+@Service
+@Slf4j
+public class MsgService {
+}

+ 4 - 1
src/main/java/com/qrservice/admin/service/SettleTaskService.java

@@ -6,6 +6,7 @@ import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.List;
 
 /**
  * @Company: AllPay
@@ -14,10 +15,12 @@ import javax.servlet.http.HttpServletRequest;
  */
 public interface SettleTaskService {
 
-    Page<SettleTasks> findSettleTask(Pageable pageable, HttpServletRequest request);
+    List<SettleTasks> findSettleTask(Pageable pageable, HttpServletRequest request);
 
     String addSettleTask(SettleTaskAdDto dto, HttpServletRequest request);
 
     String updateSettleTask(String id, HttpServletRequest request);
 
+    String confirmReport(String id, HttpServletRequest request);
+
 }

+ 20 - 0
src/main/java/com/qrservice/admin/service/StatisticsService.java

@@ -0,0 +1,20 @@
+package com.qrservice.admin.service;
+
+import com.qrservice.admin.model.statistics.StatisticsFdDto;
+import com.qrservice.admin.model.statistics.StatisticsInfo;
+import com.qrservice.admin.model.transactions.TransStatistics;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/10/10 9:51
+ */
+public interface StatisticsService {
+
+    Map<String, StatisticsInfo> findStatisticsRecord(StatisticsFdDto dto, HttpServletRequest request);
+
+}

+ 1 - 1
src/main/java/com/qrservice/admin/service/TransRealService.java

@@ -21,5 +21,5 @@ public interface TransRealService {
 
     TransDetail findRealTransDetail(String orderId) throws Exception;
 
-    String refund(TransDto dto);
+    String refund(TransDto dto,HttpServletRequest request);
 }

+ 3 - 2
src/main/java/com/qrservice/admin/service/TransSettleService.java

@@ -2,6 +2,7 @@ package com.qrservice.admin.service;
 
 import com.qrservice.admin.model.dto.trans.TransDto;
 import com.qrservice.admin.model.dto.trans.TransFdDto;
+import com.qrservice.admin.model.dto.trans.TransSettleFdDto;
 import com.qrservice.admin.model.param.TransDetail;
 import com.qrservice.admin.model.settletransaction.SettleTransLogHis;
 import com.qrservice.admin.model.transactions.TransLog;
@@ -19,9 +20,9 @@ import java.text.ParseException;
 
 public interface TransSettleService {
 
-    Page<SettleTransLogHis> findSettleTrans(Pageable pageable, TransFdDto dto, HttpServletRequest request) throws ParseException;
+    Page<SettleTransLogHis> findSettleTrans(Pageable pageable, TransSettleFdDto dto, HttpServletRequest request) throws ParseException;
 
     TransDetail findSettleTransDetail(String transId) throws Exception;
 
-    String refund(TransDto dto);
+    String refund(TransDto dto,HttpServletRequest request);
 }

+ 10 - 0
src/main/java/com/qrservice/admin/service/UserService.java

@@ -2,6 +2,8 @@ package com.qrservice.admin.service;
 
 import com.qrservice.admin.model.admin.LoginToken;
 import com.qrservice.admin.model.admin.UserInfo;
+import com.qrservice.admin.model.admin.UserSdInfo;
+import com.qrservice.admin.model.admin.UserUpInfo;
 import com.qrservice.admin.model.manage.InstitutionUser;
 
 import javax.servlet.http.HttpServletRequest;
@@ -24,4 +26,12 @@ public interface UserService {
     Object getMenuInfo(HttpServletRequest request);
 
     List<String> getSupportList(HttpServletRequest request);
+
+    String updatePwd(HttpServletRequest request, UserUpInfo info);
+
+    String sendPwdEmail(HttpServletRequest request, UserSdInfo info);
+
+    void verifyPwdEmail(HttpServletRequest request, String token);
+
+    void updatePwdEmail(HttpServletRequest request, UserUpInfo info);
 }

+ 5 - 4
src/main/java/com/qrservice/admin/service/impl/ChannelServiceImpl.java

@@ -6,7 +6,6 @@ import com.qrservice.admin.dao.online.InstitutionInfoDao;
 import com.qrservice.admin.dao.online.SpecificationInfoDao;
 import com.qrservice.admin.exception.CheckException;
 import com.qrservice.admin.model.bussiness.ChannelMerchant;
-import com.qrservice.admin.model.bussiness.InstitutionInfo;
 import com.qrservice.admin.model.bussiness.SpecificationInfo;
 import com.qrservice.admin.model.bussiness.appendix.TransSettleCurrency;
 import com.qrservice.admin.model.dto.channel.ChannelDto;
@@ -62,11 +61,11 @@ public class ChannelServiceImpl implements ChannelService {
         SpecificationInfo specification = spInfoDao.findOne(new Query().addCriteria(
                 Criteria.where("specification").is(dto.getSpecification())).addCriteria(Criteria.where("supportBrand").in(dto.getBrand())));
         if(specification == null){
-            throw new CheckException("查询无此接口代码");
+            throw new CheckException("No Specification");
         }
         ChannelMerchant one = dao.findOne(new Query(Criteria.where("channelMerchantId").is(dto.getChannelMerchantId())).addCriteria(Criteria.where("institutionCode").is(request.getHeader("institutionCode"))));
         if(one !=null){
-            throw new CheckException("渠道商户号已存在");
+            throw new CheckException("Channel Merchant Id is exists");
         }
         ChannelMerchant channelMerchant = new ChannelMerchant();
         CopyUtils.Copy(dto,channelMerchant);
@@ -75,6 +74,8 @@ public class ChannelServiceImpl implements ChannelService {
         channelMerchant.setChannelMerchantPk(UUID.randomUUID().toString().replace("-", ""));
         channelMerchant.setUpdateTime(new Date());
         channelMerchant.setCreateTime(new Date());
+        //mdr转化
+
         dao.insert(channelMerchant);
     }
 
@@ -83,7 +84,7 @@ public class ChannelServiceImpl implements ChannelService {
         Query query = new Query().addCriteria(Criteria.where("channelMerchantPk").is(dto.getChannelMerchantPk()));
         ChannelMerchant one = dao.findOne(query);
         if(one == null){
-            throw new CheckException("查询无此渠道商户信息");
+            throw new CheckException("Channel Merchant is not exists");
         }
         Update update = new Update();
         String title="ChannelMerchant "+one.getChannelMerchantId()+"/"+one.getChannelMerchantName()+" updated";

+ 4 - 7
src/main/java/com/qrservice/admin/service/impl/ChannelSubServiceImpl.java

@@ -4,8 +4,6 @@ import com.alibaba.fastjson.JSON;
 import com.qrservice.admin.config.ServiceProperties;
 import com.qrservice.admin.dao.online.ChannelMerchantDao;
 import com.qrservice.admin.dao.online.ChannelSubMerchantDao;
-import com.qrservice.admin.dao.online.InstitutionInfoDao;
-import com.qrservice.admin.dao.online.SpecificationInfoDao;
 import com.qrservice.admin.exception.CheckException;
 import com.qrservice.admin.model.bussiness.ChannelMerchant;
 import com.qrservice.admin.model.bussiness.ChannelSubMerchant;
@@ -27,7 +25,6 @@ import org.springframework.data.mongodb.core.query.Update;
 import org.springframework.stereotype.Service;
 
 import javax.servlet.http.HttpServletRequest;
-import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -61,13 +58,13 @@ public class ChannelSubServiceImpl implements ChannelSubService {
         ChannelMerchant one = cmDao.findOne(new Query().addCriteria(Criteria.where("channelMerchantPk").is(dto.getChannelMerchantPk()))
                 .addCriteria(Criteria.where("channelMerchantId").is(dto.getChannelMerchantId())));
         if(one == null){
-            throw new CheckException("查无此渠道商户");
+            throw new CheckException("No Channel Merchant Id");
         }
         Query query = new Query().addCriteria(Criteria.where("channelSubMerchantId").is(dto.getChannelSubMerchantId()));
         query.addCriteria(Criteria.where("channelMerchantPk").is(dto.getChannelMerchantPk()));
         ChannelSubMerchant channelSubMerchant = dao.findOne(query);
         if(channelSubMerchant !=null){
-            throw new CheckException("渠道子商户号已存在");
+            throw new CheckException("Channel Sub Merchant Id is exists");
         }
         ChannelSubMerchant csMer = new ChannelSubMerchant();
         CopyUtils.Copy(dto,csMer);
@@ -82,13 +79,13 @@ public class ChannelSubServiceImpl implements ChannelSubService {
         Query query = new Query().addCriteria(Criteria.where("channelSubMerchantPk").is(dto.getChannelSubMerchantPk()));
         ChannelSubMerchant one = dao.findOne(query);
         if(one == null){
-            throw new CheckException("查无此渠道子商户");
+            throw new CheckException("No Channel Sub Merchant Id");
         }
         String string = JSON.toJSONString(dto);
         Document parse = Document.parse(string);
         Update update = new BasicUpdate(new Document("$set",parse));
         if(parse == null || parse.size()==0){
-            throw new CheckException("更新异常!");
+            throw new CheckException("Update error!");
         }
         dao.updateMulti(query,update);
         update.set("updateTime",new Date());

+ 43 - 4
src/main/java/com/qrservice/admin/service/impl/ClearSceneServiceImpl.java

@@ -1,18 +1,26 @@
 package com.qrservice.admin.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.qrservice.admin.config.ServiceProperties;
 import com.qrservice.admin.dao.settle.ClearSceneLogDao;
 import com.qrservice.admin.model.batch.ClearSceneLog;
+import com.qrservice.admin.model.batch.SettleTasks;
 import com.qrservice.admin.service.ClearSceneService;
+import com.qrservice.admin.util.HttpUtil;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageImpl;
 import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
 import org.springframework.data.mongodb.core.query.Criteria;
 import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.stereotype.Service;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @Company: AllPay
@@ -20,6 +28,7 @@ import javax.servlet.http.HttpServletRequest;
  * @Date: 2020/9/2 10:41
  */
 @Service
+@Slf4j
 public class ClearSceneServiceImpl implements ClearSceneService {
 
 
@@ -34,10 +43,40 @@ public class ClearSceneServiceImpl implements ClearSceneService {
     }
 
     @Override
-    public Page<ClearSceneLog> findClearScene(Pageable pageable, HttpServletRequest request) {
+    public List<ClearSceneLog> findClearScene(Pageable pageable, HttpServletRequest request) {
         Query query = new Query().addCriteria(Criteria.where("institutionCode").is(request.getHeader("institutionCode")));
-        query.fields().include("clearDate").include("sceneCode").include("sceneName").include("startTime").include("endTime").include("status");
-        PageImpl<ClearSceneLog> page = dao.findByPageAndSort(pageable, query);
-        return page;
+        query.limit(10);
+        query.with(new Sort(Sort.Direction.DESC, "createTime"));
+        query.fields().include("clearDate").include("sceneCode").include("sceneName").include("startTime").include("endTime").include("status").include("id");
+        List<ClearSceneLog> list = dao.findByCondition(query);
+        return list;
+    }
+
+    @Override
+    public String clearIgnore(String id, HttpServletRequest request) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("_id").is(id));
+        query.fields().include("institutionCode").include("clearDate").include("sceneCode");
+        ClearSceneLog one = dao.findOne(query);
+        Map<String,String> map = JSON.parseObject(JSON.toJSONString(one), Map.class);
+        map.put("sceneCode",one.getSceneCode().toString());
+        Map<String, String> headers = new HashMap<>(16);
+        log.info("清分场次忽略");
+        String response = HttpUtil.get(properties.getClearIgnoreUrl(),map,headers);
+        return response;
+    }
+
+    @Override
+    public String clearRedo(String id, HttpServletRequest request) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("_id").is(id));
+        query.fields().include("institutionCode").include("clearDate").include("sceneCode");
+        ClearSceneLog one = dao.findOne(query);
+        Map<String,String> map = JSON.parseObject(JSON.toJSONString(one), Map.class);
+        map.put("sceneCode",one.getSceneCode().toString());
+        Map<String, String> headers = new HashMap<>(16);
+        log.info("清分场次忽略");
+        String response = HttpUtil.get(properties.getClearRedoUrl(),map,headers);
+        return response;
     }
 }

+ 56 - 12
src/main/java/com/qrservice/admin/service/impl/CommonServiceImpl.java

@@ -1,5 +1,9 @@
 package com.qrservice.admin.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.parser.Feature;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.qrservice.admin.config.ServiceProperties;
 import com.qrservice.admin.dao.online.*;
 import com.qrservice.admin.dao.online.ConfigInfoDao;
 import com.qrservice.admin.dao.settle.PermissionGroupDao;
@@ -13,17 +17,17 @@ import com.qrservice.admin.model.dto.channel.ChannelSubMerchantIdDto;
 import com.qrservice.admin.model.manage.PermissionGroup;
 import com.qrservice.admin.model.manage.UserGroup;
 import com.qrservice.admin.model.param.CommonInfo;
+import com.qrservice.admin.model.param.StoreInfo;
 import com.qrservice.admin.service.CommonService;
-import com.qrservice.admin.util.CopyUtils;
-import com.qrservice.admin.util.QueryHelp;
+
 import javax.servlet.http.HttpServletRequest;
+
+import com.qrservice.admin.util.QueryHelp;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Sort;
 import org.springframework.data.mongodb.core.query.Criteria;
 import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -52,17 +56,23 @@ public class CommonServiceImpl implements CommonService {
 
     private final UserGroupDao ugDao;
 
+    private final ServiceProperties properties;
+
+    private final MerchantStoreDao storeDao;
+
 
     @Autowired
-    public CommonServiceImpl(InstitutionInfoDao insDao,MerchantInfoDao infoDao,ConfigInfoDao configInfoDao,MccDao mccDao,SpecificationInfoDao spInfoDao,ChannelMerchantDao cmDao,ChannelSubMerchantDao cmsDao,PermissionGroupDao pgDao,UserGroupDao ugDao) {
+    public CommonServiceImpl(InstitutionInfoDao insDao,MerchantInfoDao infoDao,ConfigInfoDao configInfoDao,MccDao mccDao,SpecificationInfoDao spInfoDao,ChannelMerchantDao cmDao,ChannelSubMerchantDao cmsDao,PermissionGroupDao pgDao,UserGroupDao ugDao,ServiceProperties properties,MerchantStoreDao storeDao) {
         this.cmDao = cmDao;
         this.pgDao = pgDao;
         this.ugDao = ugDao;
         this.cmsDao = cmsDao;
+        this.storeDao = storeDao;
         this.insDao = insDao;
         this.mccDao = mccDao;
         this.infoDao = infoDao;
         this.spInfoDao = spInfoDao;
+        this.properties = properties;
         this.configInfoDao = configInfoDao;
     }
 
@@ -72,7 +82,7 @@ public class CommonServiceImpl implements CommonService {
         Query query = new Query(Criteria.where("institutionCode").is(request.getHeader("institutionCode")));
         InstitutionInfo one = insDao.findOne(query);
         if(one==null){
-            throw new CheckException("查询无此机构号");
+            throw new CheckException("No Institution Code");
         }
         CommonInfo commonInfo = new CommonInfo();
         commonInfo.setListMid(one.getListMid());
@@ -84,17 +94,26 @@ public class CommonServiceImpl implements CommonService {
         Query query = new Query(Criteria.where("merchantId").is(merchantId));
         MerchantInfo one = infoDao.findOne(query);
         if(one==null){
-            throw new CheckException("查询无此商户号");
+            throw new CheckException("No Merchant Id");
         }
+        List<StoreInfo> allSid = storeDao.findAllSid(merchantId);
         CommonInfo commonInfo = new CommonInfo();
-        commonInfo.setListSid(one.getListSid());
+        commonInfo.setListSid(allSid);
         return commonInfo;
     }
 
     @Override
     public ConfigInfo configInfos(ConfigInfoDTO dto) {
         Query query = QueryHelp.getQuery(dto, new Query());
-        return configInfoDao.findOne(query);
+        ConfigInfo one = configInfoDao.findOne(query);
+        //国家地区排序
+        if(dto.getKey().equals(properties.getCountry())){
+            JSONObject list = one.getData();
+            String string = JSONObject.toJSONString(list, SerializerFeature.MapSortField);
+            JSONObject jsonObject = JSONObject.parseObject(string, Feature.OrderedField);
+            one.setData(jsonObject);
+        }
+        return one;
     }
 
     @Override
@@ -114,8 +133,8 @@ public class CommonServiceImpl implements CommonService {
     }
 
     @Override
-    public List<ChannelSubMerchantDto> channelSubMerchant(String specification) {
-        List<ChannelSubMerchantDto> list=cmDao.findBySpecification(specification);
+    public List<ChannelSubMerchantDto> channelSubMerchant(String specification,HttpServletRequest request) {
+        List<ChannelSubMerchantDto> list=cmDao.findBySpecification(specification,request.getHeader("institutionCode"));
         list.forEach((mer)->{
             String channelMerchantPk = mer.getChannelMerchantPk();
             List<ChannelSubMerchantIdDto> subMerchantIdDtoList=cmsDao.findByChannelMerchantPk(channelMerchantPk);
@@ -131,7 +150,7 @@ public class CommonServiceImpl implements CommonService {
         Query query = new Query(Criteria.where("merchantId").is(merchantId));
         MerchantInfo one = infoDao.findOne(query);
         if(one==null){
-            throw new CheckException("查询无此商户号");
+            throw new CheckException("No Merchant Id");
         }
         return one.getTransCurrency();
     }
@@ -151,4 +170,29 @@ public class CommonServiceImpl implements CommonService {
         List<PermissionGroup> list = pgDao.findByCondition(query);
         return list;
     }
+
+    @Override
+    public List<MerchantInfo> finMidName(HttpServletRequest request) {
+        Query query = new Query(Criteria.where("institutionCode").is(request.getHeader("institutionCode")));
+        InstitutionInfo one = insDao.findOne(query);
+        if(one==null){
+            throw new CheckException("No Institution Code");
+        }
+        query.fields().include("merchantId").include("merchantName.fullName").exclude("id");
+        List<MerchantInfo> list = infoDao.findByCondition(query);
+        return list;
+    }
+
+    @Override
+    public List<MerchantInfo> findMidExGroup(HttpServletRequest request) {
+        Query query = new Query(Criteria.where("institutionCode").is(request.getHeader("institutionCode")));
+        query.addCriteria(Criteria.where("merchantProperty").ne(properties.getPropertyGroup()));
+        InstitutionInfo one = insDao.findOne(query);
+        if(one==null){
+            throw new CheckException("No Institution Code");
+        }
+        query.fields().include("merchantId").include("merchantName.fullName").exclude("id");
+        List<MerchantInfo> list = infoDao.findByCondition(query);
+        return list;
+    }
 }

+ 3 - 3
src/main/java/com/qrservice/admin/service/impl/MerchantFeeServiceImpl.java

@@ -68,7 +68,7 @@ public class MerchantFeeServiceImpl implements MerchantFeeService {
         query.addCriteria(Criteria.where("transType").is(info.getTransType()));
         MerchantChargeFee one = dao.findOne(query);
         if(one !=null){
-            throw new CheckException("重复添加");
+            throw new CheckException("Repeat to add");
         }
         //主键拼接
         info.setMerchantChargeFeePK(info.getMerchantId()+new Date().getTime());
@@ -83,7 +83,7 @@ public class MerchantFeeServiceImpl implements MerchantFeeService {
         Query query = new Query(Criteria.where("merchantChargeFeePK").is(dto.getMerchantChargeFeePK()));
         MerchantChargeFee one = dao.findOne(query);
         if(one ==null){
-            throw new CheckException("查询无此费率信息");
+            throw new CheckException("No Merchant Charge Fee");
         }
         Update update = new Update();
         update.set("mdr",dto.getMdr());
@@ -98,7 +98,7 @@ public class MerchantFeeServiceImpl implements MerchantFeeService {
         Query query = new Query(Criteria.where("merchantChargeFeePK").is(merchantChargeFeePK));
         MerchantChargeFee one = dao.findOne(query);
         if(one ==null){
-            throw new CheckException("查询无此费率信息");
+            throw new CheckException("No Merchant Charge Fee");
         }
         dao.deleteById(one.getId());
         return "Merchant change fee "+one.getMerchantId()+"/"+one.getBrand()+" deleted";

+ 4 - 4
src/main/java/com/qrservice/admin/service/impl/MerchantRouterServiceImpl.java

@@ -47,7 +47,6 @@ public class MerchantRouterServiceImpl implements MerchantRouterService {
 
     @Override
     public void addMerchantRouter(MerchantRouterDto dto) throws Exception {
-
         //信息转移
         MerchantRouter info = new MerchantRouter();
         CopyUtils.Copy(dto,info);
@@ -70,8 +69,9 @@ public class MerchantRouterServiceImpl implements MerchantRouterService {
         query.addCriteria(Criteria.where("transCurrency").is(info.getTransCurrency()));
         MerchantRouter one = dao.findOne(query);
         if(one !=null){
-            throw new CheckException("重复添加");
+            throw new CheckException("Repeat to add");
         }
+
         //主键拼接
         info.setMerchantRouterPK(info.getMerchantId()+new Date().getTime());
         //商户路由信息存储
@@ -85,7 +85,7 @@ public class MerchantRouterServiceImpl implements MerchantRouterService {
         Query query = new Query(Criteria.where("merchantRouterPK").is(dto.getMerchantRouterPK()));
         MerchantRouter one = dao.findOne(query);
         if(one ==null){
-            throw new CheckException("查询无此路由信息");
+            throw new CheckException("No Merchant Router");
         }
         Update update = new Update();
         update.set("transCurrency",dto.getTransCurrency());
@@ -99,7 +99,7 @@ public class MerchantRouterServiceImpl implements MerchantRouterService {
         Query query = new Query(Criteria.where("merchantRouterPK").is(merchantRouterPK));
         MerchantRouter one = dao.findOne(query);
         if(one ==null){
-            throw new CheckException("查询无此路由信息");
+            throw new CheckException("No Merchant Router");
         }
         dao.deleteById(one.getId());
         return"Merchant router "+one.getMerchantId()+"/"+one.getBrand()+" deleted";

+ 31 - 6
src/main/java/com/qrservice/admin/service/impl/MerchantServiceImpl.java

@@ -15,7 +15,6 @@ import com.qrservice.admin.model.manage.MerchantUser;
 import com.qrservice.admin.model.param.Merchant;
 import com.qrservice.admin.service.MerchantService;
 import com.qrservice.admin.util.CopyUtils;
-import com.qrservice.admin.util.EncryptUtil;
 import com.qrservice.admin.util.QueryHelp;
 import com.qrservice.admin.util.SHA256Util;
 import org.apache.catalina.servlet4preview.http.HttpServletRequest;
@@ -99,7 +98,7 @@ public class MerchantServiceImpl implements MerchantService {
         Query query = new Query(Criteria.where("institutionCode").is(info.getInstitutionCode()));
         InstitutionInfo institutionCode = insDao.findOne(query);
         if(institutionCode==null){
-            throw new CheckException("查无此机构");
+            throw new CheckException("No Institution Code");
         }
         Integer activityMerchantId = institutionCode.getActivityMerchantId();
         info.setMerchantId(activityMerchantId.toString());
@@ -130,6 +129,7 @@ public class MerchantServiceImpl implements MerchantService {
         info.setMerchantStatus(properties.getStatusInitial());
         info.setBusinessType(properties.getBusinessTypeOff());
         info.setSettleCycle(1);
+        info.setSettleInterval(1);
         info.setCreateTime(new Date());
         info.setUpdateTime(new Date());
         dao.insert(info);
@@ -142,7 +142,15 @@ public class MerchantServiceImpl implements MerchantService {
            dto.setInstitutionCode(code);
            Query query = QueryHelp.getQuery(dto, new Query());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-           query.addCriteria(Criteria.where("createTime").gte(sdf.parse(dto.getCreateStart())).lte(sdf.parse(dto.getCreateEnd())));
+           Criteria criteria = Criteria.where("createTime").gte(sdf.parse(dto.getCreateStart())).lte(sdf.parse(dto.getCreateEnd()));
+           if(dto.getKeyWord()!=null && !dto.getKeyWord().equals("")){
+               criteria.orOperator(
+                       Criteria.where("merchantName.englishName").regex(".*?"+dto.getKeyWord()+".*"),
+                       Criteria.where("merchantName.fullName").regex(".*?"+dto.getKeyWord()+".*"),
+                       Criteria.where("merchantId").is(dto.getKeyWord()),
+                       Criteria.where("groupMerchantId").is(dto.getKeyWord()));
+        }
+           query.addCriteria(criteria);
            query.fields().include("merchantId").include("merchantName").include("merchantStatus")
            .include("merchantProperty").include("updateTime").include("createTime");
            Page<MerchantInfo> pageInfo = dao.findByPageAndSort(pageable, query);
@@ -154,13 +162,30 @@ public class MerchantServiceImpl implements MerchantService {
         Query query = new Query(Criteria.where("merchantId").is(dto.getMerchantId()));
         MerchantInfo one = dao.findOne(query);
         if(one ==null){
-            throw new CheckException("查询无此商户号");
+            throw new CheckException("No Merchant Id");
         }
+        //划款手续费代码转换
+        String transferFeeCode = dto.getTransferFeeCode();
+        String settleCurrency =null;
+        if(dto.getSettleCurrency()==null ){
+            settleCurrency = one.getSettleCurrency();
+        }else {
+            settleCurrency = dto.getSettleCurrency();
+        }
+        if(transferFeeCode !=null){
+            if(properties.getCurrencyList().contains(settleCurrency)){
+                transferFeeCode = String.valueOf(Integer.valueOf(transferFeeCode) + 3000000);
+            }else {
+                BigDecimal bd = new BigDecimal(String.valueOf(Double.valueOf(transferFeeCode)*100 + 3000000));
+                transferFeeCode = bd.stripTrailingZeros().toPlainString();
+            }
+        }
+        dto.setTransferFeeCode(transferFeeCode);
         String string = JSON.toJSONString(dto);
         Document parse = Document.parse(string);
         Update update = new BasicUpdate(new Document("$set",parse));
         if(parse == null || parse.size()==0){
-            throw new CheckException("更新异常!");
+            throw new CheckException("Update Error!");
         }
         dao.updateMulti(query,update);
         update.set("updateTime",new Date());
@@ -216,7 +241,7 @@ public class MerchantServiceImpl implements MerchantService {
             row.put("清算周期",txn.getSettleCycle());
             row.put("清算间隔",txn.getSettleInterval());
             row.put("渠道",txn.getBusinessType());
-            row.put("收款账户",txn.getSettleAccount());
+            row.put("收款账户",txn.getSettleAccount().getBankAccountNo());
             rows.add(row);
         }
         ExcelWriter writer = ExcelUtil.getWriter(true);

+ 11 - 4
src/main/java/com/qrservice/admin/service/impl/MerchantStoreServiceImpl.java

@@ -76,7 +76,7 @@ public class MerchantStoreServiceImpl implements MerchantStoreService {
         Query query = new Query(Criteria.where("merchantId").is(dto.getMerchantId()));
         MerchantInfo one = infoDao.findOne(query);
         if(one == null){
-            throw new CheckException("查询无此商户号");
+            throw new CheckException("No Merchant Id");
         }
         MerchantStore store = new MerchantStore();
         CopyUtils.Copy(dto,store);
@@ -115,13 +115,13 @@ public class MerchantStoreServiceImpl implements MerchantStoreService {
         query.addCriteria(Criteria.where("merchantId").in(mid.getListMid()));
         MerchantStore store = dao.findOne(query);
         if(store == null){
-            throw new CheckException("查询无此门店");
+            throw new CheckException("No Merchant Store");
         }
         String string = JSON.toJSONString(dto);
         Document parse = Document.parse(string);
         Update update = new BasicUpdate(new Document("$set",parse));
         if(parse == null || parse.size()==0){
-            throw new CheckException("更新异常!");
+            throw new CheckException("Update Error!");
         }
         dao.updateMulti(query,update);
         update.set("updateTime",new Date());
@@ -133,7 +133,14 @@ public class MerchantStoreServiceImpl implements MerchantStoreService {
     public Page<MerchantStore> findMerchantStore(Pageable pageable, MerchantStoreFdDto dto,HttpServletRequest request) {
         Query query = QueryHelp.getQuery(dto, new Query());
         CommonInfo mid = service.findMid(request);
-        query.addCriteria(Criteria.where("merchantId").in(mid.getListMid()));
+        Criteria criteria = Criteria.where("merchantId").in(mid.getListMid());
+        if(dto.getKeyWord()!=null && !dto.getKeyWord().equals("")){
+            criteria.orOperator(
+                    Criteria.where("storeName").regex(".*?"+dto.getKeyWord()+".*"),
+                    Criteria.where("merchantId").is(dto.getKeyWord()),
+                    Criteria.where("storeId").is(dto.getKeyWord()));
+        }
+        query.addCriteria(criteria);
         PageImpl<MerchantStore> page = dao.findByPageAndSort(pageable, query);
         return page;
     }

+ 34 - 8
src/main/java/com/qrservice/admin/service/impl/MerchantTerminalServiceImpl.java

@@ -4,6 +4,7 @@ import cn.hutool.core.io.IoUtil;
 import cn.hutool.poi.excel.ExcelUtil;
 import cn.hutool.poi.excel.ExcelWriter;
 import com.alibaba.fastjson.JSON;
+import com.qrservice.admin.annotation.AIQuery;
 import com.qrservice.admin.config.ServiceProperties;
 import com.qrservice.admin.dao.online.*;
 import com.qrservice.admin.exception.CheckException;
@@ -70,12 +71,12 @@ public class MerchantTerminalServiceImpl implements MerchantTerminalService {
         //判断门店号是否存在
         MerchantStore store = storeDao.findOne(new Query().addCriteria(Criteria.where("storeId").is(dto.getStoreId())).addCriteria(Criteria.where("merchantId").is(dto.getMerchantId())));
         if(store ==null){
-            throw new CheckException("根据商户号查询无此门店号");
+            throw new CheckException("There is no such store id according to the merchant id");
         }
         //判断别名是否重复
         MerchantTerminal one = dao.findOne(new Query().addCriteria(Criteria.where("alias").is(dto.getAlias())).addCriteria(Criteria.where("merchantId").is(dto.getMerchantId())));
         if(one!=null){
-            throw new CheckException("商户别名重复");
+            throw new CheckException("Terminal alias repetition");
         }
         MerchantTerminal terminal = new MerchantTerminal();
         CopyUtils.Copy(dto,terminal);
@@ -84,15 +85,18 @@ public class MerchantTerminalServiceImpl implements MerchantTerminalService {
         SystemParameter code = sypDao.findOne(query);
         String value = code.getValue();
         terminal.setTerminalId(value);
-        terminal.setActivationCode(UUID.randomUUID().toString().replace("-", "").substring(0, 8));
+        terminal.setActivationCode(UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase());
         //修改系统活跃终端号
         Update update = new Update();
         update.set("modifierTime",new Date());
         update.set("value",String.valueOf(Integer.valueOf(value)+1));
         sypDao.updateMulti(query,update);
-        terminal.setTerminalStatus(properties.getStatusInitial());
+        terminal.setTerminalStatus(properties.getStatusNormal());
         terminal.setCreateTime(new Date());
         terminal.setUpdateTime(new Date());
+        if(terminal.getPassword()!=null){
+            terminal.setPasswordUpdateDate(new Date());
+        }
         dao.insert(terminal);
         return "Terminal "+dto.getMerchantId()+"/"+terminal.getTerminalId()+" added";
     }
@@ -103,20 +107,23 @@ public class MerchantTerminalServiceImpl implements MerchantTerminalService {
         Query query = new Query().addCriteria(Criteria.where("terminalId").is(dto.getTerminalId()));
         MerchantTerminal merchantTerminal = dao.findOne(query);
         if(merchantTerminal ==null){
-            throw new CheckException("查询无此终端");
+            throw new CheckException("No Terminal Id");
         }
         //判断别名是否重复
         MerchantTerminal one = dao.findOne(new Query().addCriteria(Criteria.where("alias").is(dto.getAlias())).addCriteria(Criteria.where("merchantId").is(merchantTerminal.getMerchantId())));
         if(one!=null){
-            throw new CheckException("终端别名重复");
+            throw new CheckException("Terminal alias repetition");
         }
         String string = JSON.toJSONString(dto);
         Document parse = Document.parse(string);
         Update update = new BasicUpdate(new Document("$set",parse));
         if(parse == null || parse.size()==0){
-            throw new CheckException("更新异常!");
+            throw new CheckException("Update Error!");
         }
         dao.updateMulti(query,update);
+        if(dto.getPassword()!=null){
+            update.set("passwordUpdateDate",new Date());
+        }
         update.set("updateTime",new Date());
         dao.updateMulti(query,update);
         return "Terminal "+merchantTerminal.getMerchantId()+"/"+merchantTerminal.getTerminalId()+" updated";
@@ -126,7 +133,15 @@ public class MerchantTerminalServiceImpl implements MerchantTerminalService {
     public Page<MerchantTerminal> findMerchantTerminal(Pageable pageable, MerchantTerminalFdDto dto, HttpServletRequest request) {
         Query query = QueryHelp.getQuery(dto, new Query());
         CommonInfo mid = service.findMid(request);
-        query.addCriteria(Criteria.where("merchantId").in(mid.getListMid()));
+        Criteria criteria = Criteria.where("merchantId").in(mid.getListMid());
+        if(dto.getKeyWord()!=null && !dto.getKeyWord().equals("")){
+            criteria.orOperator(
+                    Criteria.where("alias").regex(".*?"+dto.getKeyWord()+".*"),
+                    Criteria.where("merchantId").is(dto.getKeyWord()),
+                    Criteria.where("storeId").is(dto.getKeyWord()));
+                    Criteria.where("terminalId").is(dto.getKeyWord());
+        }
+        query.addCriteria(criteria);
         PageImpl<MerchantTerminal> pageInfo = dao.findByPageAndSort(pageable, query);
         return pageInfo;
     }
@@ -163,4 +178,15 @@ public class MerchantTerminalServiceImpl implements MerchantTerminalService {
         IoUtil.close(out);
     }
 
+    @Override
+    public String updateMerchantTerminalCode(String terminalId) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("terminalId").is(terminalId));
+        Update update = new Update();
+        update.set("updateTime",new Date());
+        update.set("activationCode",UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase());
+        dao.updateFirst(query,update);
+        return null;
+    }
+
 }

+ 4 - 4
src/main/java/com/qrservice/admin/service/impl/MerchantUserServiceImpl.java

@@ -61,12 +61,12 @@ public class MerchantUserServiceImpl implements MerchantUserService {
                 Criteria.where("userName.fullName").is(dto.getUserName().getFullName())
         ));
         if(one != null){
-            throw new CheckException("商户用户已存在");
+            throw new CheckException("The merchant user already exists");
         }
         //查询用户商户的基本信息填充用户信息
         MerchantInfo merchant = infoDao.findOne(new Query().addCriteria(Criteria.where("merchantId").is(dto.getMerchantId())));
         if(merchant == null ){
-            throw new CheckException("商户号不存在");
+            throw new CheckException("No Merchant Id");
         }
         MerchantUser merchantUser = new MerchantUser();
         CopyUtils.Copy(dto,merchantUser);
@@ -100,12 +100,12 @@ public class MerchantUserServiceImpl implements MerchantUserService {
         Query query = new Query().addCriteria(Criteria.where("merchantId").is(dto.getMerchantId()));
         MerchantUser one = dao.findOne(query);
         if(one == null){
-            throw new CheckException("商户号不存在");
+            throw new CheckException("No Merchant Id");
         }
         Document parse = Document.parse(string);
         Update update = new BasicUpdate(new Document("$set",parse));
         if(parse == null || parse.size()==0){
-            throw new CheckException("更新异常!");
+            throw new CheckException("Update Error!");
         }
         dao.updateMulti(query,update);
         update.set("updateTime",new Date());

+ 0 - 5
src/main/java/com/qrservice/admin/service/impl/ReportInfServiceImpl.java

@@ -1,10 +1,7 @@
 package com.qrservice.admin.service.impl;
 
 import com.qrservice.admin.config.ServiceProperties;
-import com.qrservice.admin.dao.settle.ClearSceneLogDao;
 import com.qrservice.admin.dao.settle.MgtFileInfDao;
-import com.qrservice.admin.exception.CheckException;
-import com.qrservice.admin.model.bussiness.MerchantInfo;
 import com.qrservice.admin.model.dto.settle.ReportInfoDto;
 import com.qrservice.admin.model.settletransaction.MgtFileInf;
 import com.qrservice.admin.service.ReportInfService;
@@ -19,8 +16,6 @@ import org.springframework.stereotype.Service;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.*;
-import java.net.URLEncoder;
-import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;

+ 33 - 8
src/main/java/com/qrservice/admin/service/impl/SettleTaskServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qrservice.admin.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.qrservice.admin.config.ServiceProperties;
 import com.qrservice.admin.dao.settle.InstitutionUserDao;
 import com.qrservice.admin.dao.settle.SettleTaskDao;
@@ -8,11 +9,14 @@ import com.qrservice.admin.model.batch.SettleTasks;
 import com.qrservice.admin.model.dto.settle.SettleTaskAdDto;
 import com.qrservice.admin.model.manage.InstitutionUser;
 import com.qrservice.admin.service.SettleTaskService;
+import com.qrservice.admin.util.HttpUtil;
 import com.qrservice.admin.util.jwtUtil;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageImpl;
 import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
 import org.springframework.data.mongodb.core.query.Criteria;
 import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.data.mongodb.core.query.Update;
@@ -20,6 +24,9 @@ import org.springframework.stereotype.Service;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @Company: AllPay
@@ -27,6 +34,7 @@ import java.util.Date;
  * @Date: 2020/9/2 9:48
  */
 @Service
+@Slf4j
 public class SettleTaskServiceImpl implements SettleTaskService {
 
 
@@ -44,11 +52,13 @@ public class SettleTaskServiceImpl implements SettleTaskService {
     }
 
     @Override
-    public Page<SettleTasks> findSettleTask(Pageable pageable, HttpServletRequest request) {
+    public List<SettleTasks> findSettleTask(Pageable pageable, HttpServletRequest request) {
         Query query = new Query().addCriteria(Criteria.where("institutionCode").is(request.getHeader("institutionCode")));
+        query.limit(10);
+        query.with(new Sort(Sort.Direction.DESC, "createTime"));
         query.fields().include("settleDate").include("clearDate").include("status").include("backupStatus").include("id").include("startTime").include("endTime");
-        PageImpl<SettleTasks> page = dao.findByPageAndSort(pageable, query);
-        return page;
+        List<SettleTasks> list = dao.findByCondition(query);
+        return list;
     }
 
     @Override
@@ -80,10 +90,25 @@ public class SettleTaskServiceImpl implements SettleTaskService {
     public String updateSettleTask(String id, HttpServletRequest request) {
         Query query = new Query();
         query.addCriteria(Criteria.where("_id").is(id));
-        Update update = new Update();
-        update.set("updateTime",new Date());
-        update.set("status",properties.getStatusInitial());
-        dao.updateFirst(query,update);
-        return null;
+        query.fields().include("institutionCode").include("clearDate").include("settleDate").include("lastClearDate");
+        SettleTasks one = dao.findOne(query);
+        Map<String,String> map = JSON.parseObject(JSON.toJSONString(one), Map.class);
+        Map<String, String> headers = new HashMap<>(16);
+        log.info("重做清算处理");
+        String response = HttpUtil.get(properties.getSettleRedoUrl(),map,headers);
+        return response;
+    }
+
+    @Override
+    public String confirmReport(String id, HttpServletRequest request) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("_id").is(id));
+        query.fields().include("institutionCode").include("clearDate").include("settleDate").include("lastClearDate");
+        SettleTasks one = dao.findOne(query);
+        Map<String,String> map = JSON.parseObject(JSON.toJSONString(one), Map.class);
+        Map<String, String> headers = new HashMap<>(16);
+        log.info("确认报表正确");
+        String response = HttpUtil.get(properties.getSettleConfirmUrl(),map,headers);
+        return response;
     }
 }

+ 18 - 5
src/main/java/com/qrservice/admin/service/impl/SsoServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qrservice.admin.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.qrservice.admin.config.ServiceProperties;
 import com.qrservice.admin.dao.settle.InstitutionUserDao;
 import com.qrservice.admin.exception.CheckException;
@@ -9,10 +10,12 @@ import com.qrservice.admin.model.dto.sso.SsoUserDto;
 import com.qrservice.admin.model.manage.InstitutionUser;
 import com.qrservice.admin.service.SsoService;
 import com.qrservice.admin.util.QueryHelp;
+import org.bson.Document;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageImpl;
 import org.springframework.data.domain.Pageable;
+import org.springframework.data.mongodb.core.query.BasicUpdate;
 import org.springframework.data.mongodb.core.query.Criteria;
 import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.data.mongodb.core.query.Update;
@@ -57,7 +60,7 @@ public class SsoServiceImpl implements SsoService {
                 addCriteria(Criteria.where("userId").is(userId));
         InstitutionUser one = dao.findOne(query);
         if(one == null){
-            throw new CheckException("机构用户不存在");
+            throw new CheckException("Institutional user does not exist");
         }
         Update update = new Update();
         update.set("userStatus",properties.getStatusNormal());
@@ -84,6 +87,11 @@ public class SsoServiceImpl implements SsoService {
         if(one!=null){
          throw new CheckException("User Id is exists");
         }
+        //判断邮箱唯一
+        InstitutionUser email = dao.findOne(new Query(Criteria.where("userContact.contactEmail").is(dto.getContact().getContactEmail())));
+        if(email !=null){
+            throw new CheckException("Email is exists");
+        }
         InstitutionUser institutionUser = new InstitutionUser();
         institutionUser.setPassword(dto.getPassword());
         institutionUser.setPasswordUpdateDate(new Date());
@@ -105,12 +113,17 @@ public class SsoServiceImpl implements SsoService {
                 addCriteria(Criteria.where("userId").is(dto.getUserId()));
         InstitutionUser one = dao.findOne(query);
         if(one == null){
-            throw new CheckException("机构用户不存在");
+            throw new CheckException("Institutional user does not exist");
         }
-        Update update = new Update();
-        update.set("userGroup",dto.getUserGroup());
+        String string = JSON.toJSONString(dto);
+        Document parse = Document.parse(string);
+        Update update = new BasicUpdate(new Document("$set",parse));
+        if(parse == null || parse.size()==0){
+            throw new CheckException("Update Error!");
+        };
+        dao.updateMulti(query,update);
         update.set("updateTime",new Date());
-        dao.updateFirst(query,update);
+        dao.updateMulti(query,update);
         return "InstitutionCode user "+one.getUserId()+"/"+one.getUserName().getFullName()+" updated";
     }
 }

+ 142 - 0
src/main/java/com/qrservice/admin/service/impl/StatisticsServiceImpl.java

@@ -0,0 +1,142 @@
+package com.qrservice.admin.service.impl;
+
+import com.qrservice.admin.config.ServiceProperties;
+import com.qrservice.admin.dao.online.*;
+import com.qrservice.admin.model.bussiness.appendix.Amount;
+import com.qrservice.admin.model.statistics.Statistics;
+import com.qrservice.admin.model.statistics.StatisticsFdDto;
+import com.qrservice.admin.model.statistics.StatisticsInfo;
+import com.qrservice.admin.model.transactions.TransStatistics;
+import com.qrservice.admin.service.StatisticsService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.stereotype.Service;
+
+import org.springframework.data.mongodb.core.query.Query;
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toList;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/10/10 9:51
+ */
+@Service
+@Slf4j
+public class StatisticsServiceImpl implements StatisticsService {
+
+
+
+    private final TransStatisticsDao dao;
+
+    private final ServiceProperties properties;
+
+
+    @Autowired
+    public StatisticsServiceImpl(TransStatisticsDao dao, ServiceProperties properties){
+        this.dao = dao;
+        this.properties = properties;
+    }
+
+
+    @Override
+    public Map<String,StatisticsInfo> findStatisticsRecord(StatisticsFdDto dto, HttpServletRequest request) {
+        //获取日期区间时间集合
+        List<String> dates = getDates(dto.getTransDateStart(), dto.getTransDateEnd());
+        //查询交易
+        Query query = new Query();
+        query.addCriteria(Criteria.where("entityCode").is(request.getHeader("institutionCode")));
+        query.addCriteria(Criteria.where("transDate").gte(dto.getTransDateStart()).lte(dto.getTransDateEnd()));
+        query.fields().exclude("createTime").exclude("updateTime").exclude("brand").exclude("entityCode").exclude("entityType");
+        List<TransStatistics> list = dao.findByCondition(query);
+        //币种集合分离
+        Map<String, List<TransStatistics>> collect = list.stream().collect(Collectors.groupingBy(t -> (t.getTransAmount().getCurrency())));
+        Map<String,StatisticsInfo> map = new HashMap();
+        collect.forEach((k,v)->{
+            StatisticsInfo statisticsInfo = new StatisticsInfo();
+            //根据交易类型区分
+            Map<String, List<TransStatistics>> transType = v.stream().collect(Collectors.groupingBy(TransStatistics::getTransType));
+            transType.forEach((key,value)->{
+                //获取交易日期
+                List<String> tansDate=value.stream().map(TransStatistics::getTransDate).collect(toList());
+                List<Integer> count=value.stream().map(TransStatistics::getCount).collect(toList());
+                Statistics statistics = new Statistics();
+                statistics.setTransDate(dates);
+                statistics.setCount(count);
+                //获取交易金额并进行转化判断去除小数点
+                List<Amount> amount=value.stream().map(TransStatistics::getTransAmount).collect(toList());
+                List<BigDecimal> amountList = new ArrayList();
+                amount.forEach(a ->{
+                    BigDecimal bigDecimal = new BigDecimal(a.getValue());
+                    if(!properties.getCurrencyList().contains(a.getCurrency())){
+                        bigDecimal = bigDecimal.divide(new BigDecimal("100"));
+                        amountList.add(bigDecimal);
+                    }else {
+                        amountList.add(bigDecimal);
+                    }
+                });
+                // 获取实际日期差集
+                List<String> dateReduce = dates.stream().filter(item -> !tansDate.contains(item)).collect(toList());
+                dateReduce.forEach((d)->{
+                    int i = dates.indexOf(d);
+                    amountList.add(i,new BigDecimal("0"));
+                    count.add(i,0);
+                });
+                statistics.setAmount(amountList);
+                //根据类型获取交易金额
+                if(key.equals(properties.getConsume())){
+                    statisticsInfo.setConsume(statistics);
+                }
+                if(key.equals(properties.getRefund())){
+                    statisticsInfo.setRefund(statistics);
+                }
+                map.put(k,statisticsInfo);
+            });
+        });
+        return map;
+    }
+
+
+    /**
+     * 获取两个日期之间的所有日期
+     *
+     * @param startDate  开始日期
+     * @param endDate   结束日期
+     * @return  List集合
+     */
+    public static List<String> getDates(String startDate, String endDate) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        List<String> list = new ArrayList<String>(); //保存日期的集合
+        Date date_start = null;
+        try {
+            date_start = sdf.parse(startDate);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        Date date_end = null;
+        try {
+            date_end = sdf.parse(endDate);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        Date date =date_start;
+        Calendar cd = Calendar.getInstance();//用Calendar 进行日期比较判断
+        while (date.getTime() <= date_end.getTime()){
+            list.add(sdf.format(date));
+            cd.setTime(date);
+            cd.add(Calendar.DATE, 1);//增加一天 放入集合
+            date=cd.getTime();
+        }
+        return list ;
+
+    }
+}

+ 72 - 14
src/main/java/com/qrservice/admin/service/impl/TransRealServiceImpl.java

@@ -1,13 +1,13 @@
 package com.qrservice.admin.service.impl;
 
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.TypeReference;
-import com.alibaba.fastjson.parser.Feature;
 import com.qrservice.admin.config.ServiceProperties;
 import com.qrservice.admin.dao.online.*;
+import com.qrservice.admin.exception.CheckException;
 import com.qrservice.admin.model.bussiness.MerchantInfo;
 import com.qrservice.admin.model.bussiness.MerchantStore;
 import com.qrservice.admin.model.bussiness.MerchantTerminal;
+import com.qrservice.admin.model.bussiness.appendix.Amount;
 import com.qrservice.admin.model.dto.trans.TransDto;
 import com.qrservice.admin.model.dto.trans.TransFdDto;
 import com.qrservice.admin.model.param.Trans;
@@ -26,12 +26,11 @@ import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.stereotype.Service;
 
 import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @Company: AllPay
@@ -68,14 +67,19 @@ public class TransRealServiceImpl implements TransRealService {
         dto.setInstitutionCode(request.getHeader("institutionCode"));
         Query query = QueryHelp.getQuery(dto, new Query());
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-        query.addCriteria(Criteria.where("orderTime").gte(sdf.parse(dto.getOrderTimeStart())).lte(sdf.parse(dto.getOrderTimeEnd())));
+        Criteria criteria = Criteria.where("orderTime").gte(sdf.parse(dto.getOrderTimeStart())).lte(sdf.parse(dto.getOrderTimeEnd()));
+        if(dto.getKeyWord()!=null && !dto.getKeyWord().equals("")){
+            criteria.orOperator(Criteria.where("orderId").is(dto.getKeyWord()),
+                    Criteria.where("storeName").regex(".*?"+dto.getKeyWord()+".*"),
+                    Criteria.where("shortName").regex(".*?"+dto.getKeyWord()+".*"),
+                    Criteria.where("merchantId").is(dto.getKeyWord()),
+                    Criteria.where("storeId").is(dto.getKeyWord()),
+                    Criteria.where("channelOrderNum").is(dto.getKeyWord()));
+        }
+        query.addCriteria(criteria);
         query.fields().include("orderTime").include("orderId").include("merchantId")
-                .include("storeId").include("terminalId").include("brand").include("scene").include("transType").include("paymentStatus").include("transAmount");
+                .include("terminalId").include("brand").include("transType").include("paymentStatus").include("transAmount").include("storeName");
         Page<TransLog> pageInfo = dao.findByPageAndSort(pageable, query);
-        pageInfo.forEach((v)->{
-            MerchantStore store = storeDao.findOne(new Query(Criteria.where("storeId").is(v.getStoreId())));
-            v.setStoreName(store.getStoreName());
-        });
         return pageInfo;
     }
 
@@ -98,17 +102,71 @@ public class TransRealServiceImpl implements TransRealService {
         String merchantId = transDetail.getMerchantId();
         MerchantInfo merchant = infoDao.findOne(new Query(Criteria.where("merchantId").is(merchantId)));
         transDetail.setMerchantName(merchant.getMerchantName());
-        List<Trans> listTrans=dao.findOrder(orderId,transDetail.getTransType());
+        //查询关联交易
+        List<Trans> listTrans=new ArrayList<>();
+        if(trans.getOriginOrderId()==null){
+            //交易关联退款
+            listTrans=dao.findRefundOrder(orderId,transDetail.getTransType());
+            //获取最大可退金额
+            Amount amount = new Amount();
+            //过滤失败的交易
+            List<Trans> transList = listTrans.stream()
+                    .filter(Trans -> (Trans.getTransType().equals(properties.getStatusFail())))
+                    .collect(Collectors.toList());
+            //获取退款成功和处理中的金额
+            int sum = transList.stream().mapToInt(t -> (t.getTransAmount().getValue())).sum();
+            amount.setCurrency(transDetail.getTransAmount().getCurrency());
+            amount.setValue(transDetail.getTransAmount().getValue()-sum);
+            transDetail.setRefundMaxAmount(amount);
+        }else {
+            //退款关联交易
+            listTrans=dao.findOrder(trans.getOriginOrderId(),transDetail.getTransType());
+        }
         transDetail.setTransList(listTrans);
         return transDetail;
     }
 
     @Override
-    public String refund(TransDto dto) {
+    public String refund(TransDto dto,HttpServletRequest request) {
+        //校验退款密码
+        String transId = dto.getTransId();
+        TransLog trans = dao.findOne(new Query(Criteria.where("transId").is(transId)));
+        String merchantId = trans.getMerchantId();
+        MerchantInfo merchant = infoDao.findOne(new Query(Criteria.where("merchantId").is(merchantId)));
+        if(!merchant.getRefundPwd().equals(dto.getAuthPassword())){
+            throw new CheckException("password is not correct");
+        }
+        //退款金额转换
+        //日币和韩币不需要乘以100
+        String currency = trans.getTransAmount().getCurrency();
+         String amount = dto.getAmount();
+        if(!properties.getCurrencyList().contains(currency)){
+            //amount根据位数前面补充0至12位
+            BigDecimal bigDecimal = new BigDecimal(amount);
+            BigDecimal multiply = bigDecimal.multiply(new BigDecimal("100")).setScale(0);;
+            amount = addZero(12, multiply.toString());
+        }else {
+            amount = addZero(12, amount);
+        }
+        dto.setAmount(amount);
         Map<String,String> map = JSON.parseObject(JSON.toJSONString(dto), Map.class);
         Map<String, String> headers = new HashMap<>(16);
         log.info("交易开始退款");
         String response = HttpUtil.get(properties.getRefundUrl(),map,headers);
         return response;
     }
+
+    /**
+     * 在字符串前面补0
+     * @param length:字符串固定长度
+     * @return
+     */
+    public static String addZero(int length, String str){
+        char[] data = new char[length];
+        for (int i = 0; i < length; ++i){
+            data[i] = '0';
+        }
+        String zero = new String(data);
+        return zero.substring(0, length - str.length()) + str;
+    }
 }

+ 24 - 12
src/main/java/com/qrservice/admin/service/impl/TransSettleServiceImpl.java

@@ -2,17 +2,14 @@ package com.qrservice.admin.service.impl;
 
 import com.qrservice.admin.config.ServiceProperties;
 import com.qrservice.admin.dao.online.MerchantInfoDao;
-import com.qrservice.admin.dao.online.MerchantStoreDao;
-import com.qrservice.admin.dao.online.MerchantTerminalDao;
-import com.qrservice.admin.dao.online.TransLogDao;
 import com.qrservice.admin.dao.settle.ChannelSettleLogHisDao;
 import com.qrservice.admin.dao.settle.SettleTransLogHisDao;
 import com.qrservice.admin.model.dto.trans.TransDto;
 import com.qrservice.admin.model.dto.trans.TransFdDto;
+import com.qrservice.admin.model.dto.trans.TransSettleFdDto;
 import com.qrservice.admin.model.param.TransDetail;
 import com.qrservice.admin.model.settletransaction.ChannelSettleLogHis;
 import com.qrservice.admin.model.settletransaction.SettleTransLogHis;
-import com.qrservice.admin.model.transactions.TransLog;
 import com.qrservice.admin.service.TransRealService;
 import com.qrservice.admin.service.TransSettleService;
 import com.qrservice.admin.util.QueryHelp;
@@ -45,8 +42,11 @@ public class TransSettleServiceImpl implements TransSettleService {
 
     private final ChannelSettleLogHisDao channelSettleDao;
 
+    private final MerchantInfoDao infoDao;
+
     @Autowired
-    public TransSettleServiceImpl(ServiceProperties properties,TransRealService realService,SettleTransLogHisDao settleTranDao,ChannelSettleLogHisDao channelSettleDao) {
+    public TransSettleServiceImpl(ServiceProperties properties,TransRealService realService,SettleTransLogHisDao settleTranDao,ChannelSettleLogHisDao channelSettleDao,MerchantInfoDao infoDao) {
+        this.infoDao = infoDao;
         this.properties = properties;
         this.realService = realService;
         this.settleTranDao = settleTranDao;
@@ -54,13 +54,25 @@ public class TransSettleServiceImpl implements TransSettleService {
     }
 
     @Override
-    public Page<SettleTransLogHis> findSettleTrans(Pageable pageable, TransFdDto dto, HttpServletRequest request) throws ParseException {
+    public Page<SettleTransLogHis> findSettleTrans(Pageable pageable, TransSettleFdDto dto, HttpServletRequest request) throws ParseException {
         dto.setInstitutionCode(request.getHeader("institutionCode"));
         Query query = QueryHelp.getQuery(dto, new Query());
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-        query.addCriteria(Criteria.where("orderTime").gte(sdf.parse(dto.getOrderTimeStart())).lte(sdf.parse(dto.getOrderTimeEnd())));
-        query.fields().include("orderTime").include("orderId").include("merchantId")
-                .include("storeId").include("terminalId").include("brand").include("scene").include("transType").include("paymentStatus").include("transAmount");
+        Criteria criteria = Criteria.where("settleDate").gte(dto.getSettleDateStart()).lte(dto.getSettleDateEnd());
+        if(dto.getOrderTimeStart()!=null){
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            query.addCriteria(Criteria.where("orderTime").gte(sdf.parse(dto.getOrderTimeStart())).lte(sdf.parse(dto.getOrderTimeEnd())));
+        }
+        if(dto.getKeyWord()!=null && !dto.getKeyWord().equals("")){
+            criteria.orOperator(Criteria.where("orderId").is(dto.getKeyWord()),
+                    Criteria.where("storeName").regex(".*?"+dto.getKeyWord()+".*"),
+                    Criteria.where("shortName").regex(".*?"+dto.getKeyWord()+".*"),
+                    Criteria.where("merchantId").is(dto.getKeyWord()),
+                    Criteria.where("storeId").is(dto.getKeyWord()),
+                    Criteria.where("channelOrderNum").is(dto.getKeyWord()));
+        }
+        query.addCriteria(criteria);
+        query.fields().include("orderTime").include("orderId").include("settleDate")
+                .include("merchantId").include("storeName").include("brand").include("merchantSettleAmount").include("transType").include("paymentStatus").include("transAmount");
         PageImpl<SettleTransLogHis> page = settleTranDao.findByPageAndSort(pageable, query);
         return page;
     }
@@ -84,8 +96,8 @@ public class TransSettleServiceImpl implements TransSettleService {
     }
 
     @Override
-    public String refund(TransDto dto) {
-        return realService.refund(dto);
+    public String refund(TransDto dto,HttpServletRequest request) {
+        return realService.refund(dto,request);
     }
 
 

+ 1 - 1
src/main/java/com/qrservice/admin/service/impl/UserGroupServiceImpl.java

@@ -110,7 +110,7 @@ public class UserGroupServiceImpl implements UserGroupService {
         Document parse = Document.parse(string);
         Update update = new BasicUpdate(new Document("$set",parse));
         if(parse == null || parse.size()==0){
-            throw new CheckException("更新异常!");
+            throw new CheckException("Update Error!");
         };
         dao.updateMulti(query,update);
         update.set("updateTime",new Date());

+ 0 - 2
src/main/java/com/qrservice/admin/service/impl/UserOperateServiceImpl.java

@@ -2,11 +2,9 @@ package com.qrservice.admin.service.impl;
 
 
 import com.qrservice.admin.dao.settle.UserOperateLogDao;
-import com.qrservice.admin.model.bussiness.MerchantInfo;
 import com.qrservice.admin.model.dto.sso.UserOperateLogDto;
 import com.qrservice.admin.model.manage.UserOperateLog;
 import com.qrservice.admin.service.UserOperateService;
-import com.qrservice.admin.util.QueryHelp;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;

+ 132 - 2
src/main/java/com/qrservice/admin/service/impl/UserServiceImpl.java

@@ -2,10 +2,14 @@ package com.qrservice.admin.service.impl;
 
 import com.alibaba.fastjson.JSON;
 import com.qrservice.admin.config.ServiceProperties;
+import com.qrservice.admin.dao.online.InstitutionInfoDao;
 import com.qrservice.admin.dao.settle.*;
 import com.qrservice.admin.exception.CheckException;
 import com.qrservice.admin.model.admin.LoginToken;
 import com.qrservice.admin.model.admin.UserInfo;
+import com.qrservice.admin.model.admin.UserSdInfo;
+import com.qrservice.admin.model.admin.UserUpInfo;
+import com.qrservice.admin.model.bussiness.InstitutionInfo;
 import com.qrservice.admin.model.manage.InstitutionUser;
 import com.qrservice.admin.model.manage.Menu;
 import com.qrservice.admin.model.manage.PermissionGroup;
@@ -15,6 +19,8 @@ import com.qrservice.admin.model.param.MenuInfo;
 import com.qrservice.admin.model.param.MenuRouter;
 import com.qrservice.admin.service.UserService;
 import com.qrservice.admin.util.CacheUtil;
+import com.qrservice.admin.util.EmailUtils;
+import com.qrservice.admin.util.EncryptUtil;
 import com.qrservice.admin.util.jwtUtil;
 import org.apache.poi.hpsf.Array;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -24,8 +30,16 @@ import org.springframework.data.mongodb.core.query.Criteria;
 import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.data.mongodb.core.query.Update;
 import org.springframework.stereotype.Service;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.thymeleaf.TemplateEngine;
+import org.thymeleaf.context.Context;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.time.LocalDate;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -46,17 +60,23 @@ public class UserServiceImpl implements UserService {
 
     private final ServiceProperties properties;
 
+    private final InstitutionInfoDao inInfoDao;
+
     private final UserGroupDao ugDao;
 
     private final UserOperateLogDao uglogDao;
 
+    private final TemplateEngine templateEngine;
+
     @Autowired
-    public UserServiceImpl(InstitutionUserDao dao, MenuDao menuDao,ServiceProperties properties,UserGroupDao ugDao,PermissionGroupDao pgDao,UserOperateLogDao uglogDao) {
+    public UserServiceImpl(InstitutionUserDao dao, MenuDao menuDao,ServiceProperties properties,UserGroupDao ugDao,PermissionGroupDao pgDao,UserOperateLogDao uglogDao,TemplateEngine templateEngine, InstitutionInfoDao inInfoDao) {
         this.dao = dao;
         this.ugDao = ugDao;
         this.pgDao = pgDao;
         this.menuDao = menuDao;
         this.properties = properties;
+        this.inInfoDao = inInfoDao;
+        this.templateEngine = templateEngine;
         this.uglogDao = uglogDao;
     }
 
@@ -77,7 +97,9 @@ public class UserServiceImpl implements UserService {
         //判断用户是否超过密码有效期
         int days = (int) ((new Date().getTime() - user.getPasswordUpdateDate().getTime()) / (1000*3600*24));
         if(days > Integer.valueOf(properties.getPwdTime())){
-            throw new CheckException("Password expired, please change",throwable);
+            //密码过期跳转修改密码页面
+            String token = EncryptUtil.encryptHex(dto.getUsername(), properties.getLoginKey());
+            throw new CheckException("Password expired, please change",new Throwable(token));
         }
         query.addCriteria(Criteria.where("password").is(dto.getPassword()));
         dao.findOne(query);
@@ -107,6 +129,7 @@ public class UserServiceImpl implements UserService {
         CacheUtil.getCache().cleanUp();
         return loginToken;
     }
+
     public static Date getTodayStartTime() {
         Calendar todayStart = Calendar.getInstance();
         todayStart.set(Calendar.HOUR_OF_DAY, 0);
@@ -191,6 +214,106 @@ public class UserServiceImpl implements UserService {
         return listAllDistinct;
     }
 
+    @Override
+    public String updatePwd(HttpServletRequest request, UserUpInfo info) {
+        //判断用户原密码是否正确
+        String token = request.getHeader("Authorization");
+        String userId = jwtUtil.getUserId(token);
+        Query query = new Query();
+        query.addCriteria(Criteria.where("userId").is(userId));
+        query.addCriteria(Criteria.where("password").is(info.getOriginPwd()));
+        InstitutionUser user = dao.findOne(query);
+        Throwable throwable = new Throwable("InstitutionCode user "+ userId+" updatePassword");
+        if (user == null) {
+            throw new CheckException("Origin password is not correct ",throwable);
+        }
+        //修改密码
+        Update update = new Update();
+        update.set("passwordUpdateDate",new Date());
+        update.set("updateTime",new Date());
+        update.set("password",info.getPassword());
+        dao.updateFirst(query,update);
+        return "InstitutionCode user "+ userId+" updatePassword";
+    }
+
+    @Override
+    public String sendPwdEmail(HttpServletRequest request, UserSdInfo info) {
+        //验证用户信息填写是否正确
+        InstitutionUser user = dao.findOne(new Query(Criteria.where("userId").is(info.getUserId())).addCriteria(Criteria.where("userContact.contactEmail").is(info.getEmail())));
+        if(user == null ){
+            throw new CheckException("UserName or Email is not correct");
+        }
+        String institutionCode = user.getInstitutionCode();
+        InstitutionInfo institutionInfo = inInfoDao.findOne(new Query(Criteria.where("institutionCode").is(institutionCode)));
+        if(institutionInfo.getAcquirerPortalName() ==null ||institutionInfo.getAcquirerPortalName().equals("")){
+            institutionInfo = inInfoDao.findOne(new Query(Criteria.where("institutionCode").is(properties.getInstitutionCode())));
+        }
+        //信息加密
+        String token = EncryptUtil.encryptHex(info.getUserId(), properties.getKey());
+        Map<String, String> emailParam = new HashMap<>();
+        emailParam.put("localDate", LocalDate.now().toString());
+        emailParam.put("url",properties.getEmailUrl()+"?token="+token);
+        emailParam.put("userId",info.getUserId());
+        //邮件发送
+        String content = buildEmailContent(emailParam, "email/forgetPwd");
+        EmailUtils.sendSimpleHtmlMail("Forgot Password-"+institutionInfo.getAcquirerPortalName(),content,
+                info.getEmail(),
+                null
+        );
+        return "InstitutionCode user "+ user.getUserId()+" sendPwdEmail";
+    }
+
+    @Override
+    public void verifyPwdEmail(HttpServletRequest request, String token) {
+        String userId = EncryptUtil.decryptHex(token, properties.getKey());
+        InstitutionUser user = dao.findOne(new Query(Criteria.where("userId").is(userId)));
+        if(user == null ){
+            throw new CheckException("token is not correct");
+        }
+        String institutionCode = user.getInstitutionCode();
+        InstitutionInfo institutionInfo = inInfoDao.findOne(new Query(Criteria.where("institutionCode").is(institutionCode)));
+        if(institutionInfo.getAcquirerPortalName().equals("") || institutionInfo.getAcquirerPortalName() ==null){
+            institutionInfo = inInfoDao.findOne(new Query(Criteria.where("institutionCode").is(properties.getInstitutionCode())));
+        }
+        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
+        try {
+            response.sendRedirect(institutionInfo.getAcquirerPortalUrl()+"?token="+token);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return;
+    }
+
+    @Override
+    public void updatePwdEmail(HttpServletRequest request, UserUpInfo info) {
+        //密码过期的修改处理
+        if(info.getOriginPwd()!=null && !info.getOriginPwd().equals("")){
+            String userId = EncryptUtil.decryptHex(info.getToken(), properties.getLoginKey());
+            Query query = new Query(Criteria.where("userId").is(userId)).addCriteria(Criteria.where("password").is(info.getOriginPwd()));
+            InstitutionUser user = dao.findOne(query);
+            if(user == null ){
+                throw new CheckException("password is not correct");
+            }
+            Update update = new Update();
+            update.set("password",info.getPassword());
+            update.set("passwordUpdateDate",new Date());
+            update.set("updateTime",new Date());
+            dao.updateFirst(query,update);
+            return;
+        }
+        //邮件修改密码的处理
+        String userId = EncryptUtil.decryptHex(info.getToken(), properties.getKey());
+        Query query = new Query(Criteria.where("userId").is(userId));
+        InstitutionUser user = dao.findOne(query);
+        if(user == null ){
+            throw new CheckException("token is not correct");
+        }
+        Update update = new Update();
+        update.set("password",info.getPassword());
+        update.set("passwordUpdateDate",new Date());
+        update.set("updateTime",new Date());
+        dao.updateFirst(query,update);
+    }
 
     @Override
     public String loginOut(HttpServletRequest request,String token) {
@@ -201,4 +324,11 @@ public class UserServiceImpl implements UserService {
         return title;
     }
 
+
+    public String buildEmailContent(Map<String, String> emailParam, String templateName) {
+        Context ctx = new Context();
+        ctx.setVariable("emailParam", emailParam);
+        return templateEngine.process(templateName, ctx);
+    }
+
 }

+ 86 - 0
src/main/java/com/qrservice/admin/util/EmailUtils.java

@@ -0,0 +1,86 @@
+package com.qrservice.admin.util;
+
+import com.qrservice.admin.config.MailConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Created by lei
+ * Date 2020/9/25.
+ */
+@Slf4j
+public class EmailUtils {
+
+
+
+    private static JavaMailSender mailSender = SpringUtil.getBean(JavaMailSender.class);
+    private static MailConfig config = SpringUtil.getBean(MailConfig.class);
+
+    static {
+        System.setProperty("mail.mime.splitlongparameters","false");
+    }
+
+    /**
+     *  发送简单的html邮件
+     * @param subject 主题
+     * @param content 内容
+     * @param to 发给谁
+     * @param cc 抄送
+     */
+    public static void sendSimpleHtmlMail(String subject, String content,String to,String[] cc)  {
+        MimeMessage mimeMessage = null;
+        try {
+            mimeMessage = mailSender.createMimeMessage();
+            MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage,true,"UTF-8");
+            messageHelper.setFrom(config.getUsername()); //设置发件人Email
+            messageHelper.setSubject(subject); //设置邮件主题
+            messageHelper.setText(content,true);   //设置邮件主题内容
+            messageHelper.setTo(to);          //设定收件人Email
+            if(cc != null){
+                messageHelper.setCc(cc);     //设定抄送人
+            }
+        } catch (MessagingException e) {
+            e.printStackTrace();
+        }
+        mailSender.send(mimeMessage);    //发送HTML邮件
+    }
+
+    /**
+     * 发送带有附件的邮件
+     * @param subject 主题
+     * @param content 内容
+     * @param to 收件人
+     * @param cc 抄送人
+     * @param filePaths 文件路径
+     */
+    public static void sendAnnexMail(String subject, String content, String to, String [] cc, String [] filePaths) throws MessagingException, UnsupportedEncodingException {
+        MimeMessage mimeMessage = mailSender.createMimeMessage();
+        MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage,true,"UTF-8");
+        messageHelper.setFrom(config.getUsername()); //设置发件人Email
+        messageHelper.setSubject(config.getSubjectenv()+subject); //设置邮件主题
+        messageHelper.setText(content,true);   //设置邮件主题内容
+        messageHelper.setTo(to);          //设定收件人Email
+        if(cc != null){
+            messageHelper.setCc(cc);     //设定抄送人
+        }
+
+        for (String filePath : filePaths) {
+            messageHelper.addAttachment(filePath.substring(filePath.lastIndexOf(File
+                    .separator)+1),new File(filePath));
+        }
+        mailSender.send(mimeMessage);    //发送HTML邮件
+    }
+
+    public static void sendErrorHtmlMail(Exception e,String transDate, String to, String[] cc) {
+        StackTraceElement[] stackTrace = e.getStackTrace();
+        StackTraceElement element = stackTrace[0];
+         EmailUtils.sendSimpleHtmlMail("清算异常",
+                "交易日期:"+transDate+"<br>错误类型:"+e.toString()+",错误地址:"+element,to,null);
+    }
+
+}

+ 55 - 63
src/main/java/com/qrservice/admin/util/QueryHelp.java

@@ -5,15 +5,15 @@ import cn.hutool.core.util.ObjectUtil;
 import com.qrservice.admin.annotation.AIQuery;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.CriteriaDefinition;
 import org.springframework.data.mongodb.core.query.Query;
-import org.springframework.util.StringUtils;
 
 import java.lang.reflect.Field;
 import java.util.*;
 
 
-/**
- * @Description :
+/**  you can't add a second 'null' criteria
+ * @Description : $and 和 $or 都会生成一个null key值的criteria ,需要在同一个criteria里面添加条件
  * @Author : Simon.shi
  * @Date : 2019/8/14 17:48
  * @Version : V0.0.1
@@ -21,95 +21,87 @@ import java.util.*;
 @Slf4j
 public class QueryHelp {
 
-    public static <Q> Query getQuery(Q query, Query queryCol) {
+    public static <Q> Query getQuery(Q query,Query queryCol) {
         if(query == null){
             return queryCol;
         }
         Criteria criteria = null;
         try {
-            List<Field> fields = getAllFields(query.getClass(), new ArrayList<>());
-            criteria = new Criteria();
-            HashSet<Criteria> set = new HashSet<>();
-            for (Field field : fields) {
-                boolean accessible = field.isAccessible();
-                field.setAccessible(true);
-                AIQuery q = field.getAnnotation(AIQuery.class);
-                if (q != null) {
+                List<Field> fields = getAllFields(query.getClass(), new ArrayList<>());
+                criteria = new Criteria();
+                HashSet<Criteria> set = new HashSet<>();
+                for (Field field : fields) {
+                  boolean accessible = field.isAccessible();
+                  field.setAccessible(true);
+                  AIQuery q = field.getAnnotation(AIQuery.class);
+                  if (q != null) {
                     String propName = q.propName();
                     String attributeName = isBlank(propName) ? field.getName() : propName;
                     Object val = field.get(query);
-                    if (ObjectUtil.isNull(val) || val.equals("")) {
-                        continue;
+                    if (val==null || val.equals("")) {
+                      continue;
                     }
                     switch (q.type()) {
-                        case EQUAL:
-                            criteria.and(attributeName).is(val);
-                            break;
-                        case GREATER_THAN:
-                        case LESS_THAN:
-                        case LESS_THAN_NQ:
-                        case GREATER_THAN_NQ:
-                            mongoLimitations(set,criteria, attributeName, val,q);
-                            break;
-                        case INNER_LIKE:
-                            criteria.and(attributeName).regex(val+"","i");
-                            break;
-                        case IN:
-                            if (CollUtil.isNotEmpty((Collection)val)) {
-                                criteria.and(attributeName).in((Collection) val);
-                            }
-                            break;
-                        case OR:
-                            String[] alias = q.alias();
-                            Criteria[] orCriteria = new Criteria[alias.length+1];
-                            for (int i = 0; i < alias.length; i++) {
-                                orCriteria[i] = Criteria.where(alias[i]).is(val);
-                            }
-                            orCriteria[alias.length] = Criteria.where(attributeName).is(val);
-                            criteria.orOperator(orCriteria);
+                      case EQUAL:
+                          queryCol.addCriteria(Criteria.where(attributeName).is(val));
+                        break;
+                      case GREATER_THAN:
+                      case LESS_THAN:
+                      case LESS_THAN_NQ:
+                      case GREATER_THAN_NQ:
+                        mongoLimitations(set, criteria, attributeName, val, q);
+                        break;
+                      case INNER_LIKE:
+                          queryCol.addCriteria(Criteria.where(attributeName).regex(val + "", "i"));
+                        break;
+                      case IN:
+                        if (CollUtil.isNotEmpty((Collection) val)) {
+                            queryCol.addCriteria((Criteria.where(attributeName).in((Collection) val)));
+                        }
+                        break;
+                      case OR:
+                        String[] alias = q.alias();
+                        Criteria[] orCriteria = new Criteria[alias.length + 1];
+                        for (int i = 0; i < alias.length; i++) {
+                          orCriteria[i] = Criteria.where(alias[i]).is(val);
+                        }
+                        orCriteria[alias.length] = Criteria.where(attributeName).is(val);
+                        criteria.orOperator(orCriteria);
+                        break;
+                        case IS_NULL:
+                            queryCol.addCriteria(Criteria.where(attributeName).exists(false));
+                          break;
+                      default:
+                        break;
                     }
+                  }
+                  field.setAccessible(accessible);
+                }
+                if (set.size() > 0) {
+                  Criteria[] array = set.toArray(new Criteria[] {});
+                  criteria.andOperator(array);
                 }
-                field.setAccessible(accessible);
-            }
-            if(set.size()>0){
-                Criteria[] array = set.toArray(new Criteria[]{});
-                criteria.andOperator(array);
-            }
         } catch (Exception e) {
             log.error(e.getMessage(), e);
         }
         return queryCol.addCriteria(criteria);
     }
 
-    private static void mongoLimitations(HashSet<Criteria> set, Criteria criteria, String attributeName, Object val, AIQuery q) {
+    private static void mongoLimitations(HashSet<Criteria> set,Criteria criteria, String attributeName, Object val,AIQuery q) {
         switch (q.type()) {
             case GREATER_THAN:
-                if(ObjectUtil.isNotNull(criteria.getCriteriaObject().get(attributeName))){
                     set.add(Criteria.where(attributeName).gte(val));
-                }else{
-                    criteria.and(attributeName).gte(val);
-                }
                 break;
             case LESS_THAN:
-                if(ObjectUtil.isNotNull(criteria.getCriteriaObject().get(attributeName))){
                     set.add(Criteria.where(attributeName).lte(val));
-                }else{
-                    criteria.and(attributeName).lte(val);
-                }
                 break;
             case LESS_THAN_NQ:
-                if(ObjectUtil.isNotNull(criteria.getCriteriaObject().get(attributeName))){
                     set.add(Criteria.where(attributeName).lt(val));
-                }else{
-                    criteria.and(attributeName).lt(val);
-                }
                 break;
             case GREATER_THAN_NQ:
-                if(ObjectUtil.isNotNull(criteria.getCriteriaObject().get(attributeName))){
                     set.add(Criteria.where(attributeName).gt(val));
-                }else{
-                    criteria.and(attributeName).gt(val);
-                }
+                break;
+            default:
                 break;
         }
 
@@ -131,7 +123,7 @@ public class QueryHelp {
     }
 
     @SuppressWarnings("unchecked")
-    private static List<Field> getAllFields(Class clazz, List<Field> fields) {
+    public static List<Field> getAllFields(Class clazz, List<Field> fields) {
         if (clazz != null) {
             fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
             getAllFields(clazz.getSuperclass(), fields);

+ 43 - 0
src/main/java/com/qrservice/admin/util/SpringUtil.java

@@ -0,0 +1,43 @@
+package com.qrservice.admin.util;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by skf
+ * Date 2018/5/11.
+ */
+@Component
+public class SpringUtil implements ApplicationContextAware {
+
+    private static ApplicationContext applicationContext = null;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        if(SpringUtil.applicationContext == null){
+           SpringUtil.applicationContext = applicationContext;
+        }
+    }
+
+    //获取applicationContext
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+
+    //通过name获取 Bean.
+    public static Object getBean(String name){
+        return getApplicationContext().getBean(name);
+    }
+
+    //通过class获取Bean.
+    public static <T> T getBean(Class<T> clazz){
+        return getApplicationContext().getBean(clazz);
+    }
+
+    //通过name,以及Clazz返回指定的Bean
+    public static <T> T getBean(String name,Class<T> clazz){
+        return getApplicationContext().getBean(name, clazz);
+    }
+}

+ 6 - 1
src/main/resources/application-local.yml

@@ -8,4 +8,9 @@ spring:
       settle:
         uri: mongodb://root:root@192.168.50.213:27017/settle
 service:
-  refundUrl: http://192.168.50.88:9016/platform/refund
+  refundUrl: http://192.168.50.213:9016/platform/refund
+  settleRedoUrl: http://192.168.50.213:9017/settle/redo
+  settleConfirmUrl: http://192.168.50.213:9017/settle/confirm
+  clearIgnoreUrl: http://192.168.50.213:9017/clear/ignore
+  clearRedoUrl: http://192.168.50.213:9017/clear/redo
+  emailUrl: http://192.168.50.213:9015/admin/email/verify/send

+ 21 - 1
src/main/resources/application.yml

@@ -5,11 +5,14 @@ spring:
     default-property-inclusion: non_null
 service:
   key: asdbnasdjandaknaksda98sd
+  loginKey: sdanjlakdnskmdakmdaskl
   statusInitial: INITIAL
   statusNormal: NORMAL
   statusClose: CLOSE
   statusLock: LOCK
   statusDelete: status
+  statusSuccess: SUCCESS
+  statusFail: FAILURE
   businessTypeOff : OFFLINE
   businessTypeOn : ONLINE
   terminalCode: TERMINAL_ID
@@ -21,8 +24,25 @@ service:
   pwdTime: 30
   loginNumber: 4
   currencyList: ['JPY',"KRW"]
+  country: country
+  propertyGroup: GROUP
+  institutionCode: '000000'
+  entityTypeAcquirer : A
+  entityTypeMerchant : M
+  consume: PURC
+  refund: REFD
 logging:
   level:
     org.springframework.data.mongodb.core: debug
-
+#email
+spring.mail.host: smtp.exmail.qq.com
+spring.mail.username: web@allpayx.com
+spring.mail.password: Allpay123$%^
+spring.mail.subjectenv: local
+spring.mail.properties.mail.smtp.auth: true
+spring.mail.properties.mail.smtp.starttls.enable: false
+spring.mail.properties.mail.smtp.starttls.required: false
+spring.mail.properties.mail.debug: true
+spring.mail.properties.mail.smtp.socketFactory.class: javax.net.ssl.SSLSocketFactory
+spring.mail.properties.mail.smtp.socketFactory.port: 465
 

+ 77 - 0
src/main/resources/templates/email/common.html

@@ -0,0 +1,77 @@
+<html lang="en"
+      xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:th="http://www.thymeleaf.org">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>email</title>
+</head>
+
+<body>
+<table width="800px" align="center" cellspacing="0" cellpadding="0"
+       style="font-family: Microsoft YaHei;border-collapse: collapse;font-size: 16px; color: #333333">
+    <tbody>
+    <tr th:fragment="head">
+        <td width="700" style="padding: 20px 50px;color: #ffffff;background-color: #2274ec">
+            <table border="0" cellspacing="0" cellpadding="0" width="700">
+                <tr>
+                    <td style="line-height: 30px">
+                        <img style="height: 30px;vertical-align: middle"
+                             src="https://allpay-sh-email.oss-cn-shanghai.aliyuncs.com/logo_orange.png"/>
+                    </td>
+                    <td style="line-height: 26px" align="right">
+                        安全 • 高效 • 低成本
+                    </td>
+                </tr>
+            </table>
+        </td>
+    </tr>
+    <tr>
+        <td width="700" style="padding: 40px 50px 15px;">
+            <table border="0" cellspacing="0" cellpadding="0" width="700">
+                <tr>
+                    <td style="line-height: 44px;font-weight: bold">尊敬的用户:</td>
+                </tr>
+                <tr>
+                    <td style="line-height: 24px;font-size: 13px;text-indent: 30px">
+                        <p style="margin: 0;"> 您好,您的GoAllPay账户有新交易入账。</p>
+                    </td>
+                </tr>
+                <tr>
+                    <td style="line-height: 40px;font-size: 14px;font-weight:600;text-align: right;">
+                        GoAllPay团队
+                    </td>
+                </tr>
+                <tr>
+                    <td th:text="${emailParam['localDate']}"
+                        style="line-height: 24px;font-size: 14px;text-align: right;">
+                        2020年04月28日
+                    </td>
+                </tr>
+            </table>
+        </td>
+    </tr>
+    <tr th:fragment="footer">
+        <td width="700" style="padding: 0 50px">
+            <table width="700" border="0" cellspacing="0" cellpadding="0">
+                <tr>
+                    <td style="border-top: 1px solid #dedfe0;padding-bottom: 20px" colspan="3"></td>
+                </tr>
+                <tr>
+                    <td width="60%" style=" font-size: 14px; color: #797979;line-height: 24px;margin: 0;">
+                        <ul style="padding-left: 20px">
+                            <li style="margin: 10px 0;">您收到此邮件是因为您 (或其他人) 使用这个邮箱创建 扫码账号, 如果您对此不知情,请忽略此邮件。</li>
+                            <li style="margin: 10px 0;">此邮件为系统邮件,请勿回复</li>
+                            <li style="margin: 10px 0;">如需帮助,请点击
+                                <a style="color: #797979;font-weight: 600"
+                                   href="https://www.goallpayx.com/cn/contact.html">联系我们</a>,或拨打
+                                400-832-9009
+                            </li>
+                        </ul>
+                </tr>
+            </table>
+        </td>
+    </tr>
+    </tbody>
+</table>
+</body>
+</html>

+ 41 - 0
src/main/resources/templates/email/forgetPwd.html

@@ -0,0 +1,41 @@
+<html lang="en"
+      xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:th="http://www.thymeleaf.org">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>email</title>
+</head>
+
+<body>
+<table width="800px" align="center" cellspacing="0" cellpadding="0"
+       style="font-family: Microsoft YaHei;border-collapse: collapse;font-size: 16px; color: #4c4949">
+    <tbody>
+<!--    <tr th:include="email/common :: head">-->
+<!--    </tr>-->
+    <tr>
+        <td width="700" style="padding: 40px 50px 15px;">
+            <table border="0" cellspacing="0" cellpadding="0" width="700">
+                <tr>
+                    <td style="line-height: 44px;font-weight: bold">Dear <span th:text="${emailParam['userId']}" style="font-weight: 600">userId</span>
+                        <p style="margin: 0;"> You have forgot your password of <span th:text="${emailParam['localDate']}" style="font-weight: 600">2020-09-07</span>. Please click the following link to change your password.</p>
+                        <p><span th:text="${emailParam['url']}" style="font-weight: 600">http://www.baidu.com</span></p>
+                        <p>If the above link cannot be clicked, you can also copy the link, paste it into your browser, and press enter to open the reset password page.</p>
+                        <p>Do not click the above link and ignore this message if you have not done so.</p>
+                        <p>Thank you very much!</p>
+                    </td>
+                </tr>
+                <tr>
+                    <td th:text="${emailParam['localDate']}"
+                        style="line-height: 24px;font-size: 14px;text-align: right;">
+                        2019年08月02日
+                    </td>
+                </tr>
+            </table>
+        </td>
+    </tr>
+<!--    <tr th:include="email/common :: footer">-->
+<!--    </tr>-->
+    </tbody>
+</table>
+</body>
+</html>

+ 43 - 0
src/test/java/test.java

@@ -0,0 +1,43 @@
+
+import java.math.BigDecimal;
+
+/**
+ * @Company: AllPay
+ * @Author: lei.chen
+ * @Date: 2020/9/24 11:00
+ */
+
+public class test {
+
+
+    public static void main(String[] args) {
+        String amount ="10";
+        BigDecimal bigDecimal = new BigDecimal(amount);
+        BigDecimal multiply = bigDecimal.multiply(new BigDecimal("100")).setScale(0);
+        String String = addZero(12, multiply.toString());
+        System.out.println(String);
+    }
+
+    /**
+     * 在字符串前面补0
+     * @param length:字符串固定长度
+     * @return
+     */
+    public static String addZero(int length, String str){
+        char[] data = new char[length];
+        for (int i = 0; i < length; ++i){
+            data[i] = '0';
+        }
+        String zero = new String(data);
+        return zero.substring(0, length - str.length()) + str;
+    }
+
+//    @Test
+//    public void sendEmail(){
+//        EmailUtils.sendSimpleHtmlMail("【紧急】Sapi获取美金汇率异常","获取美金汇率失败,汇率日期",
+//               "lei.chen@allpayx.com",
+//                //        properties.getCc_test()
+//                null
+//        );
+//    }
+}

+ 6 - 1
target/classes/application-local.yml

@@ -8,4 +8,9 @@ spring:
       settle:
         uri: mongodb://root:root@192.168.50.213:27017/settle
 service:
-  refundUrl: http://192.168.50.88:9016/platform/refund
+  refundUrl: http://192.168.50.213:9016/platform/refund
+  settleRedoUrl: http://192.168.50.213:9017/settle/redo
+  settleConfirmUrl: http://192.168.50.213:9017/settle/confirm
+  clearIgnoreUrl: http://192.168.50.213:9017/clear/ignore
+  clearRedoUrl: http://192.168.50.213:9017/clear/redo
+  emailUrl: http://192.168.50.213:9015/admin/email/verify/send

+ 21 - 1
target/classes/application.yml

@@ -5,11 +5,14 @@ spring:
     default-property-inclusion: non_null
 service:
   key: asdbnasdjandaknaksda98sd
+  loginKey: sdanjlakdnskmdakmdaskl
   statusInitial: INITIAL
   statusNormal: NORMAL
   statusClose: CLOSE
   statusLock: LOCK
   statusDelete: status
+  statusSuccess: SUCCESS
+  statusFail: FAILURE
   businessTypeOff : OFFLINE
   businessTypeOn : ONLINE
   terminalCode: TERMINAL_ID
@@ -21,8 +24,25 @@ service:
   pwdTime: 30
   loginNumber: 4
   currencyList: ['JPY',"KRW"]
+  country: country
+  propertyGroup: GROUP
+  institutionCode: '000000'
+  entityTypeAcquirer : A
+  entityTypeMerchant : M
+  consume: PURC
+  refund: REFD
 logging:
   level:
     org.springframework.data.mongodb.core: debug
-
+#email
+spring.mail.host: smtp.exmail.qq.com
+spring.mail.username: web@allpayx.com
+spring.mail.password: Allpay123$%^
+spring.mail.subjectenv: local
+spring.mail.properties.mail.smtp.auth: true
+spring.mail.properties.mail.smtp.starttls.enable: false
+spring.mail.properties.mail.smtp.starttls.required: false
+spring.mail.properties.mail.debug: true
+spring.mail.properties.mail.smtp.socketFactory.class: javax.net.ssl.SSLSocketFactory
+spring.mail.properties.mail.smtp.socketFactory.port: 465
 

BIN
target/classes/com/qrservice/admin/QrServerApplication.class


BIN
target/classes/com/qrservice/admin/annotation/AIQuery$Type.class


BIN
target/classes/com/qrservice/admin/config/ServiceProperties.class


BIN
target/classes/com/qrservice/admin/controller/CommonController.class


BIN
target/classes/com/qrservice/admin/controller/admin/LoginController.class


BIN
target/classes/com/qrservice/admin/controller/merchant/MerchantTerminalController.class


BIN
target/classes/com/qrservice/admin/controller/settle/ClearSceneController.class


BIN
target/classes/com/qrservice/admin/controller/settle/SettleTaskController.class


BIN
target/classes/com/qrservice/admin/controller/trans/TransRealController.class


BIN
target/classes/com/qrservice/admin/controller/trans/TransSettleController.class


BIN
target/classes/com/qrservice/admin/dao/BaseDao.class


BIN
target/classes/com/qrservice/admin/dao/impl/BaseDaoImpl.class


BIN
target/classes/com/qrservice/admin/dao/online/ChannelMerchantDao.class


BIN
target/classes/com/qrservice/admin/dao/online/MerchantStoreDao.class


BIN
target/classes/com/qrservice/admin/dao/online/TransLogDao.class


BIN
target/classes/com/qrservice/admin/filter/AccessLogFilter$1.class


BIN
target/classes/com/qrservice/admin/filter/AccessLogFilter$2.class


BIN
target/classes/com/qrservice/admin/filter/AccessLogFilter.class


BIN
target/classes/com/qrservice/admin/model/batch/ClearSceneLog.class


+ 0 - 0
target/classes/com/qrservice/admin/model/batch/SettleTasks.class


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