diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/riskbusiness/RiskEventMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/riskbusiness/RiskEventMapper.java index f50922022..d27b4351b 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/riskbusiness/RiskEventMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/riskbusiness/RiskEventMapper.java @@ -26,7 +26,6 @@ public interface RiskEventMapper { @AutoSql(type = SqlType.SELECT) List findAll(JSONObject params); - @AutoSql(type = SqlType.SELECT) PageList listRisksByPage(JSONObject params, PageBounds pageBounds); @AutoSql(type = SqlType.SELECT) diff --git a/src/main/java/au/com/royalpay/payment/manage/riskbusiness/core/RiskBusinessService.java b/src/main/java/au/com/royalpay/payment/manage/riskbusiness/core/RiskBusinessService.java index 78588077a..63c011a69 100644 --- a/src/main/java/au/com/royalpay/payment/manage/riskbusiness/core/RiskBusinessService.java +++ b/src/main/java/au/com/royalpay/payment/manage/riskbusiness/core/RiskBusinessService.java @@ -3,6 +3,7 @@ package au.com.royalpay.payment.manage.riskbusiness.core; import com.alibaba.fastjson.JSONObject; import com.github.miemiedev.mybatis.paginator.domain.PageBounds; +import javax.servlet.http.HttpServletResponse; import java.util.List; /** @@ -32,6 +33,13 @@ public interface RiskBusinessService { */ JSONObject getRiskEventDetail(String riskId); + /** + * 获取风险事件的调单信息 + * @param orderIds + * @return + */ + List getRiskEventOrderList(String orderIds); + /** * 新增风险事件 * @param params @@ -43,4 +51,10 @@ public interface RiskBusinessService { * @param params */ void updateRiskEvent(JSONObject params); + + /** + * 下载审核材料(zip) + * @param riskId + */ + void downloadAuditMaterialZiP(String riskId, HttpServletResponse response); } diff --git a/src/main/java/au/com/royalpay/payment/manage/riskbusiness/core/impl/RiskBusinessServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/riskbusiness/core/impl/RiskBusinessServiceImpl.java index d87f93bb5..c88d23c00 100644 --- a/src/main/java/au/com/royalpay/payment/manage/riskbusiness/core/impl/RiskBusinessServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/riskbusiness/core/impl/RiskBusinessServiceImpl.java @@ -1,16 +1,28 @@ package au.com.royalpay.payment.manage.riskbusiness.core.impl; +import au.com.royalpay.payment.core.exceptions.InvalidShortIdException; +import au.com.royalpay.payment.manage.mappers.payment.OrderMapper; import au.com.royalpay.payment.manage.mappers.riskbusiness.RiskEventMapper; +import au.com.royalpay.payment.manage.mappers.system.ClientMapper; import au.com.royalpay.payment.manage.riskbusiness.core.RiskBusinessService; import au.com.royalpay.payment.tools.utils.PageListUtils; import com.alibaba.fastjson.JSONObject; import com.github.miemiedev.mybatis.paginator.domain.Order; import com.github.miemiedev.mybatis.paginator.domain.PageBounds; import com.github.miemiedev.mybatis.paginator.domain.PageList; +import org.apache.commons.lang3.time.DateFormatUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Date; import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * @Author lvjian @@ -22,6 +34,12 @@ public class RiskBusinessServiceImpl implements RiskBusinessService { @Autowired private RiskEventMapper riskEventMapper; + @Autowired + private OrderMapper orderMapper; + + @Autowired + private ClientMapper clientMapper; + @Override public List getRiskEvents(JSONObject params) { return riskEventMapper.findAll(params); @@ -36,7 +54,35 @@ public class RiskBusinessServiceImpl implements RiskBusinessService { @Override public JSONObject getRiskEventDetail(String riskId) { - return riskEventMapper.findById(riskId); + JSONObject riskEventDetail = riskEventMapper.findById(riskId); + + // 获取商户信息 + String clientMoniker = riskEventDetail.getString("client_moniker"); + JSONObject client = clientMapper.findClientByMonikerAll(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } else { + riskEventDetail.put("clientInfo", client); + } + + return riskEventDetail; + } + + @Override + public List getRiskEventOrderList(String orderIds) { + String[] orderIdArray = orderIds.trim().split(","); + JSONObject query = new JSONObject(); + List tradeLogs = new ArrayList<>(); + + // 获取每笔订单的信息 + for (int i = 0; i < orderIdArray.length; i++) { + query.put("order_id", orderIdArray[i]); + PageList logs = orderMapper.listOrders(query, new PageBounds()); + if (logs != null && logs.size() != 0) { + tradeLogs.add(logs.get(0)); + } + } + return tradeLogs; } @Override @@ -48,4 +94,33 @@ public class RiskBusinessServiceImpl implements RiskBusinessService { public void updateRiskEvent(JSONObject params) { riskEventMapper.update(params); } + + @Override + public void downloadAuditMaterialZiP(String riskId, HttpServletResponse response) { + + JSONObject riskEvent = riskEventMapper.findById(riskId); + String clientMoniker = riskEvent.getString("client_moniker"); + try { + String downloadFilename = clientMoniker + "_audit_materials_" + DateFormatUtils.format(new Date(), "dd/MM/yyyy HH:mm:ss").toString() + ".zip";// 文件的名称 + response.setContentType("application/octet-stream"); + response.setHeader("Content-Disposition", "attachment;filename=" + downloadFilename); + ZipOutputStream zos = new ZipOutputStream(response.getOutputStream()); + String filePath = "https://file.royalpay.com.au/open/2018/09/20/1537438083143_tqIYPEDYPr40Y9Cyj4Ps1xgSRrDrVb.jpg"; + zos.putNextEntry(new ZipEntry(filePath.substring(filePath.lastIndexOf("/")))); + InputStream inputStream = new URL(filePath).openConnection().getInputStream(); + byte[] buffer = new byte[1024]; + int result = 0; + while ((result = inputStream.read(buffer)) != -1) { + zos.write(buffer, 0, result); + } + inputStream.close(); + zos.flush(); + zos.close(); + + zos.flush(); + zos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/riskbusiness/web/RiskBusinessController.java b/src/main/java/au/com/royalpay/payment/manage/riskbusiness/web/RiskBusinessController.java index ad3859114..8ed299654 100644 --- a/src/main/java/au/com/royalpay/payment/manage/riskbusiness/web/RiskBusinessController.java +++ b/src/main/java/au/com/royalpay/payment/manage/riskbusiness/web/RiskBusinessController.java @@ -9,10 +9,7 @@ import com.alibaba.fastjson.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; +import javax.servlet.http.HttpServletResponse; import java.util.List; /** @@ -34,8 +31,12 @@ public class RiskBusinessController { } @GetMapping(value = "events/{risk_id}") - public JSONObject getRiskEventDetail(@PathVariable("risk_id") String riskId) { - return riskBusinessService.getRiskEventDetail(riskId); + public JSONObject getRiskEventDetail(@PathVariable("risk_id") String riskId, + @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + JSONObject riskEvent = riskBusinessService.getRiskEventDetail(riskId); + List tradeLogs = riskBusinessService.getRiskEventOrderList(riskEvent.getString("order_ids")); + riskEvent.put("tradeLogs", tradeLogs); + return riskEvent; } @PostMapping(value = "events") @@ -49,5 +50,10 @@ public class RiskBusinessController { public void UpdateRiskEvent(@RequestBody JSONObject params) { riskBusinessService.updateRiskEvent(params); } + + @GetMapping(value = "/{risk_id}/download/materialsAsZIP") + public void downloadComplianceZip(@PathVariable("risk_id") String riskId, HttpServletResponse response) throws Exception { + riskBusinessService.downloadAuditMaterialZiP(riskId, response); + } } diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/riskbusiness/RiskEventMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/riskbusiness/RiskEventMapper.xml new file mode 100644 index 000000000..6f8274362 --- /dev/null +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/riskbusiness/RiskEventMapper.xml @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/src/main/ui/static/analysis/risk_business.js b/src/main/ui/static/analysis/risk_business.js index ffb178b8e..b09684270 100644 --- a/src/main/ui/static/analysis/risk_business.js +++ b/src/main/ui/static/analysis/risk_business.js @@ -4,13 +4,28 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'], function (angular, $) { 'use strict'; - var orderTypes = { + var orderTypesMap = { "1": "微信调单", "2": "支付宝调单", "3": "RoyalPay调单", "4": "警告", "5": "通用号调单" }; + + var resultTypesMap = { + "0": "未处理", + "1": "已发送邮件至BD", + "2": "BD已提交材料,等待审核", + "3": "材料审核通过", + "4": "材料审核不通过,已打回", + "5": "已处理()", + }; + + var emailStatusMap = { + "0": "未发送", + "1": "已发送" + }; + var app = angular.module('riskBusinessApp', ['ui.router']); app.config(['$stateProvider', function ($stateProvider) { $stateProvider.state('analysis_monitoring.risk_business', { @@ -31,13 +46,17 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'], url: '/new_riskEvent', templateUrl: '/static/analysis/templates/new_riskEvent.html', controller: 'newRiskEventCtrl' + }).state('analysis_monitoring.riskEvent_detail.audit_material', { + url: '/audit_material', + templateUrl: '/static/analysis/templates/audit_material.html', + controller: 'auditMaterialCtrl' }); }]); app.controller('riskBusinessCtrl', ['$scope', '$state', '$http', '$uibModal', 'commonDialog', function ($scope, $state, $http, $uibModal, commonDialog) { - $scope.orderTypes = orderTypes; + $scope.orderTypes = orderTypesMap; $scope.pagination = {}; $scope.params = {}; @@ -51,18 +70,36 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'], }; $scope.loadRiskEvents(1); - } ]); app.controller('riskEventDetailCtrl', ['$scope', '$state', '$http', '$uibModal', '$filter', 'commonDialog', 'riskEvent', function ($scope, $state, $http, $uibModal, $filter, commonDialog, riskEvent) { + + $scope.orderTypes = orderTypesMap; + $scope.riskEvent = riskEvent.data; + + // 编辑表格的数据保存对象,重新从源数据复制,从而取消保存操作时不会更新视图 + $scope.riskEventEdit = angular.copy(riskEvent.data); + + // order_type转换为string类型是因为前端select控件这样才会显示初值 + $scope.riskEventEdit.order_type += ""; + + // 调单信息 + $scope.tradeLogs = $scope.riskEvent.tradeLogs; + + // 商户信息 + $scope.clientInfo = $scope.riskEvent.clientInfo; + + // 控制编辑表格的显示 $scope.editFlag = false; $scope.changeEditFlag = function(editFlag) { $scope.editFlag = !editFlag; + // 如果是在编辑状态,需要将日期转换为date类型(前端控件需要) + // 如果是在非编辑状态,需要将日期转换为yyyy-MM-dd格式 if ($scope.editFlag) { - $scope.riskEvent.reply_email_date = new Date($scope.riskEvent.reply_email_date.replace(/-/g, "/")); + $scope.riskEventEdit.reply_email_date = new Date($scope.riskEventEdit.reply_email_date.replace(/-/g, "/")); } else { $scope.riskEvent.reply_email_date = $filter('date')($scope.riskEvent.reply_email_date, 'yyyy-MM-dd'); } @@ -78,8 +115,9 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'], return; } - $scope.riskEvent.reply_email_date = $filter('date')($scope.riskEvent.reply_email_date, 'yyyy-MM-dd'); - $http.put('/risk/business/events', $scope.riskEvent).then(function (resp) { + // 保存时需要重新将日期转换为yyyy-MM-dd格式传入后端 + $scope.riskEventEdit.reply_email_date = $filter('date')($scope.riskEventEdit.reply_email_date, 'yyyy-MM-dd'); + $http.put('/risk/business/events', $scope.riskEventEdit).then(function (resp) { commonDialog.alert({ title: 'Success', content: 'Update riskEvent successfully', @@ -93,13 +131,64 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'], type: 'error' }); }); + }; + + // 关停渠道 + $scope.updateChannel = function (orderType) { + var channel; + if (orderType == "1") + channel = 'wechat'; + else if (orderType == "2") + channel = 'alipay'; + $http.put('/sys/partners/' + $scope.riskEvent.client_moniker + '/channels/' + channel + '/permission', {allow: $scope.clientInfo['enable_' + channel]}).then(function () { + $state.reload('analysis_monitoring.riskEvent_detail'); + }, function (resp) { + commonDialog.alert({ + title: 'Failed to change ' + channel + ' channel permission status', + content: resp.data.message, + type: 'error' + }) + }); + }; + + // 关停商户 + $scope.updateClient = function(isValid) { + if (isValid) { + $http.put('/sys/partners/' + $scope.riskEvent.client_moniker + '/revert').then(function () { + $state.reload('analysis_monitoring.riskEvent_detail'); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }) + } else { + $http.delete('/sys/partners/' + $scope.riskEvent.client_moniker).then(function () { + $state.reload('analysis_monitoring.riskEvent_detail'); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }) + } + + }; + + // 获取riskEvent详细信息 + $scope.loadRiskEventDetail = function(riskId) { + $http.get('/risk/business/events/' + riskId) } } ]); + app.controller('auditMaterialCtrl', ['$scope', '$state', '$http', '$uibModal', '$filter', 'commonDialog', + function ($scope, $state, $http, $uibModal, $filter, commonDialog) { + $scope.downloadAsZip = function () { + var url = '/risk/business/' + $scope.riskEvent.risk_id + '/download/materialsAsZIP'; + return url; + }; + } + ]); + app.controller('newRiskEventCtrl', ['$scope', '$state', '$http', '$uibModal', '$filter', 'commonDialog', function ($scope, $state, $http, $uibModal, $filter, commonDialog) { - $scope.orderTypes = orderTypes; + + $scope.orderTypes = orderTypesMap; $scope.save = function(form) { if (form.$invalid) { @@ -111,6 +200,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'], return; } + // 默认设置邮件回复截止日期为七天后 var replyDeadline = new Date(); replyDeadline.setDate(replyDeadline.getDate() + 7); $scope.riskEvent.reply_email_date = $filter('date')(replyDeadline, 'yyyy-MM-dd'); @@ -133,5 +223,26 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'], } ]); + // 调单类型过滤器 + app.filter('orderType', function() { + return function(type) { + return orderTypesMap[type]; + } + }); + + // 处理结果过滤器 + app.filter('resultType', function() { + return function(type) { + return resultTypesMap[type]; + } + }); + + // 邮件发送状态过滤器 + app.filter('emailStatus', function() { + return function(status) { + return emailStatusMap[status]; + } + }); + return app; }); diff --git a/src/main/ui/static/analysis/templates/audit_material.html b/src/main/ui/static/analysis/templates/audit_material.html new file mode 100644 index 000000000..028c8b6e4 --- /dev/null +++ b/src/main/ui/static/analysis/templates/audit_material.html @@ -0,0 +1,35 @@ +
+
Audit Files     + + + 一键下载 + +
+
+
+
+ +
+
+ + + +
+
+
+

Example:请保证图片信息清晰可见,如下图

+ +
+
+
+
+
+
+ check +
+
+ + + + \ No newline at end of file diff --git a/src/main/ui/static/analysis/templates/new_riskEvent.html b/src/main/ui/static/analysis/templates/new_riskEvent.html index 33d45128d..f5d337e82 100644 --- a/src/main/ui/static/analysis/templates/new_riskEvent.html +++ b/src/main/ui/static/analysis/templates/new_riskEvent.html @@ -12,23 +12,30 @@
- +
-
-

Required - Field

-

Less - Than 6 Letters

-

Only - Uppercase Letters and - Numbers are allowed

+

Required Field +

+

Less Than 6 Letters +

+

+ Only Uppercase Letters and Numbers are allowed +

@@ -36,18 +43,21 @@
+ for="order-type-input">Order Type +
-
-

- required field +

required field

@@ -55,40 +65,46 @@
- +
-
-

- required field +

required field

- +
-
-
- -
-
diff --git a/src/main/ui/static/analysis/templates/riskEvent_detail.html b/src/main/ui/static/analysis/templates/riskEvent_detail.html index 21490a250..5461723fc 100644 --- a/src/main/ui/static/analysis/templates/riskEvent_detail.html +++ b/src/main/ui/static/analysis/templates/riskEvent_detail.html @@ -1,230 +1,306 @@ -
+
+ +
+
+ \ No newline at end of file