From efc63cc3731157d71abc604c8ccb247cc20995e3 Mon Sep 17 00:00:00 2001 From: duLingLing Date: Thu, 14 Nov 2019 18:05:44 +0800 Subject: [PATCH] R-service --- pom.xml | 1 + .../system/ClientIncrementalMapper.java | 36 ++++++ .../manage/merchants/core/ClientManager.java | 22 ++++ .../core/impls/ClientManagerImpl.java | 76 +++++++++++ .../web/PartnerManageController.java | 30 +++++ .../merchants/web/PartnerViewController.java | 12 ++ src/main/ui/index.html | 4 + src/main/ui/static/boot/index-boot.js | 3 +- src/main/ui/static/images/yangmatou.jpg | Bin 0 -> 19149 bytes .../partner-incremental-service.js | 46 +++++++ .../partner_incremental_service.html | 20 +++ .../partner_incremental_service_info.html | 10 ++ .../static/payment/partner/partner-manage.js | 121 ++++++++++++++++++ .../templates/incremental_service.html | 38 ++++++ .../templates/incremental_service_dialog.html | 68 ++++++++++ .../partner/templates/partner_detail.html | 3 + 16 files changed, 489 insertions(+), 1 deletion(-) create mode 100644 src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientIncrementalMapper.java create mode 100644 src/main/ui/static/images/yangmatou.jpg create mode 100644 src/main/ui/static/incrementalService/partner-incremental-service.js create mode 100644 src/main/ui/static/incrementalService/templates/partner_incremental_service.html create mode 100644 src/main/ui/static/incrementalService/templates/partner_incremental_service_info.html create mode 100644 src/main/ui/static/payment/partner/templates/incremental_service.html create mode 100644 src/main/ui/static/payment/partner/templates/incremental_service_dialog.html diff --git a/pom.xml b/pom.xml index f4271e834..6e23517f4 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,7 @@ au.com.royalpay.payment payment-core + 1.1.6 au.com.royalpay.payment diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientIncrementalMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientIncrementalMapper.java new file mode 100644 index 000000000..8ba1c6a5f --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientIncrementalMapper.java @@ -0,0 +1,36 @@ +package au.com.royalpay.payment.manage.mappers.system; + +import cn.yixblog.support.mybatis.autosql.annotations.AdvanceSelect; +import cn.yixblog.support.mybatis.autosql.annotations.AutoMapper; +import cn.yixblog.support.mybatis.autosql.annotations.AutoSql; +import cn.yixblog.support.mybatis.autosql.annotations.SqlType; +import com.alibaba.fastjson.JSONObject; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator; + +import java.util.List; + +/** + * @Author DuLingLing + * @create 2019/11/13 0013 14:49 + */ +@AutoMapper(tablename = "sys_client_incremental", pkName = "incremental_id", keyGenerator = Jdbc3KeyGenerator.class) +public interface ClientIncrementalMapper { + + /** + * 获取商户所有增值渠道信息 + * @param clientId + * @return + */ + @AutoSql(type = SqlType.SELECT) + List findAllByclientMoniker(@Param("client_id") int clientId); + + @AutoSql(type = SqlType.SELECT) + JSONObject findByClinetIdAndChannel(@Param("client_id")int clinet_id, @Param("channel")String channel); + + @AutoSql(type = SqlType.INSERT) + void save(JSONObject saveIncrementalService); + + @AutoSql(type = SqlType.UPDATE) + void update(JSONObject saveIncrementalService); +} diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java index 17bbd4737..10968500a 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java @@ -475,4 +475,26 @@ public interface ClientManager { JSONObject getClientInfoByAggree(JSONObject account); JSONObject getComplianceFilesForBD(JSONObject account); + + /** + * 获取商户所有增值服务 + * + * @param clientMoniker + * @return + */ + JSONObject partnerIncrementalService(String clientMoniker); + + /** + * 保存/修改增值服务配置 + * @param clientMoniker + * @param incrementalService + */ + void changePartnerIncrementalService(String clientMoniker, JSONObject incrementalService,JSONObject manager); + + /** + * 禁用/启用增值服务 + * @param clientMoniker + * @param incrementalService + */ + void changeSwitchIncrementalService(String clientMoniker, JSONObject incrementalService,JSONObject manager); } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index e58eae0a9..676b9adb7 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -17,6 +17,7 @@ import au.com.royalpay.payment.core.PaymentChannelApi; import au.com.royalpay.payment.core.exceptions.EmailException; import au.com.royalpay.payment.core.exceptions.InvalidShortIdException; import au.com.royalpay.payment.core.mappers.SysClientMapper; +import au.com.royalpay.payment.core.surcharge.IncrementalChannel; import au.com.royalpay.payment.core.utils.OrderExpiryRuleResolver; import au.com.royalpay.payment.manage.analysis.mappers.TransactionAnalysisMapper; import au.com.royalpay.payment.manage.appclient.beans.AppClientBean; @@ -105,6 +106,7 @@ import org.springframework.ui.Model; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.thymeleaf.context.Context; import org.thymeleaf.spring5.SpringTemplateEngine; @@ -162,6 +164,8 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid private StringRedisTemplate stringRedisTemplate; @Resource private ClientComplianceApply clientComplianceApply; + @Resource + private ClientIncrementalMapper clientIncrementalMapper; @Value("${app.redis.prefix}") private String redisPrefix; @@ -5891,4 +5895,76 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid return key; } + public JSONObject partnerIncrementalService(String clientMoniker){ + JSONObject client = clientMapper.findClientByMoniker(clientMoniker); + if(client==null){ + throw new InvalidShortIdException(); + } + List service = clientIncrementalMapper.findAllByclientMoniker(client.getInteger("client_id")); + List incrementalChannels = new ArrayList<>(); + for (IncrementalChannel e : IncrementalChannel.values()) { + boolean exist = false; + for(JSONObject s : service){ + exist = e.getChannel().equals(s.getString("channel")); + if(exist){ + break; + } + } + if(!exist){ + incrementalChannels.add(e.getChannel()); + } + } + incrementalChannels.remove("system"); + return new JSONObject(){{ + put("all_service",service); + put("incremental_channel",incrementalChannels); + }}; + } + + public void changePartnerIncrementalService(String clientMoniker, JSONObject incrementalService,JSONObject manager){ + JSONObject client = clientMapper.findClientByMoniker(clientMoniker); + if(client==null){ + throw new InvalidShortIdException(); + } + JSONObject existIncrementalService = clientIncrementalMapper.findByClinetIdAndChannel(client.getInteger("client_id"),incrementalService.getString("channel")); + JSONObject saveIncrementalService = new JSONObject(); + if(existIncrementalService==null){ + saveIncrementalService.put("incremental_id",UUID.randomUUID().toString()); + saveIncrementalService.put("channel",incrementalService.getString("channel")); + saveIncrementalService.put("create_time",new Date()); + saveIncrementalService.put("update_time",new Date()); + saveIncrementalService.put("is_valid",1); + }else{ + saveIncrementalService.put("incremental_id",incrementalService.getString("incremental_id")); + saveIncrementalService.put("update_time",new Date()); + } + saveIncrementalService.put("client_id",client.getInteger("client_id")); + saveIncrementalService.put("operator",manager.getString("display_name")); + saveIncrementalService.put("incremental_mode",incrementalService.getInteger("incremental_mode")); + saveIncrementalService.put("incremental_rate_value",incrementalService.getInteger("incremental_mode")==1?incrementalService.getString("incremental_rate_value"):0); + saveIncrementalService.put("total_incremental_amount",incrementalService.getInteger("incremental_mode")!=1?incrementalService.getString("total_incremental_amount"):0); + if(existIncrementalService==null){ + clientIncrementalMapper.save(saveIncrementalService); + }else{ + clientIncrementalMapper.update(saveIncrementalService); + } + + } + + public void changeSwitchIncrementalService(String clientMoniker, JSONObject incrementalService, JSONObject manager){ + JSONObject client = clientMapper.findClientByMoniker(clientMoniker); + if(client==null){ + throw new InvalidShortIdException(); + } + JSONObject existIncrementalService = clientIncrementalMapper.findByClinetIdAndChannel(client.getInteger("client_id"),incrementalService.getString("channel")); + if(existIncrementalService==null){ + throw new BadRequestException("Incremental service is not exist"); + } + + existIncrementalService.put("update_time",new Date()); + existIncrementalService.put("incremental_id",incrementalService.getString("incremental_id")); + existIncrementalService.put("is_valid",incrementalService.getInteger("is_valid")); + existIncrementalService.put("operator",manager.getString("display_name")); + clientIncrementalMapper.update(existIncrementalService); + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java index d88feea7e..6e56ad12f 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java @@ -809,4 +809,34 @@ public class PartnerManageController { public void switchPartnerCBChannelConfig(@PathVariable String clientMoniker, @PathVariable String channelKey, @RequestBody JSONObject channel) { clientManager.partnerCBChannelConfig(clientMoniker, channelKey, channel.getString("channel_id")); } + + /** + * 获取商户所有增值服务 + * @param clientMoniker + * @return + */ + @ManagerMapping(value = "/{clientMoniker}/incremental_service", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) + public JSONObject getClientIncrementalService(@PathVariable String clientMoniker){ + return clientManager.partnerIncrementalService(clientMoniker); + } + + /** + * 保存/修改增值服务配置 + * @param clientMoniker + * @param incrementalService + */ + @ManagerMapping(value = "/{clientMoniker}/incremental_service", method = RequestMethod.POST, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) + public void updateClientIncrementalService(@PathVariable("clientMoniker") String clientMoniker,@RequestBody JSONObject incrementalService, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager){ + clientManager.changePartnerIncrementalService(clientMoniker,incrementalService,manager); + } + + /** + * 禁用/启用增值服务 + * @param clientMoniker + * @param incrementalService + */ + @ManagerMapping(value = "/{clientMoniker}/incremental_service/status", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) + public void switchClientIncrementalService(@PathVariable("clientMoniker") String clientMoniker,@RequestBody JSONObject incrementalService, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager){ + clientManager.changeSwitchIncrementalService(clientMoniker,incrementalService,manager); + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerViewController.java b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerViewController.java index 188fd1031..0f11c4479 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerViewController.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerViewController.java @@ -602,4 +602,16 @@ public class PartnerViewController { public void deleteAuthFiles(@PathVariable String fileId, @ModelAttribute(CommonConsts.PARTNER_STATUS) JSONObject account) { clientManager.deleteAuthFiles(fileId); } + + /** + * 获取商户所有增值服务 + * @param clientMoniker + * @return + */ + @PartnerMapping(value = "/{clientMoniker}/incremental_service", method = RequestMethod.GET, roles = {PartnerRole.ADMIN, PartnerRole.MANAGER}) + @ResponseBody + public JSONObject getClientIncrementalService(@PathVariable String clientMoniker){ + return clientManager.partnerIncrementalService(clientMoniker); + } + } diff --git a/src/main/ui/index.html b/src/main/ui/index.html index c36725df8..826a7ec1e 100644 --- a/src/main/ui/index.html +++ b/src/main/ui/index.html @@ -1035,6 +1035,10 @@ margin-bottom: 10%;"/> +
  • + R Service +
  • + diff --git a/src/main/ui/static/boot/index-boot.js b/src/main/ui/static/boot/index-boot.js index c0dba0173..63d340672 100644 --- a/src/main/ui/static/boot/index-boot.js +++ b/src/main/ui/static/boot/index-boot.js @@ -78,7 +78,8 @@ var modules = [ {path: 'static/payment/surchargeaccount/partner-surcharge-account', module: 'surchargeAccountApp', roles: [1,2,3]}, {path: 'static/integralmall/coupon_cancellation', module: 'couponCancellation', roles: [1,2]}, {path: 'static/invoice/invoice_assistant', module: 'partnerInvoice', roles: [1]}, - {path: 'static/payment/billqrcode/bill-qrcode-manage', module: 'billQrCodeManagement', roles: [1,2,3]} + {path: 'static/payment/billqrcode/bill-qrcode-manage', module: 'billQrCodeManagement', roles: [1,2,3]}, + {path: 'static/incrementalService/partner-incremental-service', module: 'partnerIncrementalService', roles: [1,2,3]} ]; require(['angular', 'jquery'], function (angular, $) { diff --git a/src/main/ui/static/images/yangmatou.jpg b/src/main/ui/static/images/yangmatou.jpg new file mode 100644 index 0000000000000000000000000000000000000000..90e55f643f3a7f8a8a7504653bab554e761698fa GIT binary patch literal 19149 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 +

    {{serviceAll.length>0?'已开通增值服务':'您尚未开通任何增值服务'}}

    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/main/ui/static/incrementalService/templates/partner_incremental_service_info.html b/src/main/ui/static/incrementalService/templates/partner_incremental_service_info.html new file mode 100644 index 000000000..566549bdf --- /dev/null +++ b/src/main/ui/static/incrementalService/templates/partner_incremental_service_info.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index 7021bc4e5..571f4e043 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -197,6 +197,10 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter url: '/permission_client', templateUrl: 'static/payment/partner/templates/partner_permission.html', controller: 'permissionClientCtrl' + }).state('partners.detail.incremental_service', { + url: '/incremental_service', + templateUrl: 'static/payment/partner/templates/incremental_service.html', + controller: 'incrementalServiceCtrl' }); }]); app.controller('partnerListCtrl', ['$scope', '$sce', '$http', '$filter', '$uibModal', 'businessStructuresMap', 'industryMap', 'stateMap', 'sectorMap', 'countryMap', @@ -5186,6 +5190,123 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }; }]); + app.controller('incrementalServiceCtrl',['$scope', '$http', '$uibModal', '$state', '$filter', 'commonDialog',function($scope, $http, $uibModal, $state, $filter, commonDialog){ + $scope.serviceAll = {}; + $scope.channelOptions=[]; + $scope.initData = function(){ + $http.get('/sys/partners/' + $scope.partner.client_moniker+'/incremental_service').then(function(res){ + $scope.serviceAll = res.data.all_service; + $scope.serviceAll.forEach(function(service){ + service.logo_url = '/static/images/'+service.channel+'.jpg' + }) + $scope.channelOptions=res.data.incremental_channel; + }) + } + $scope.initData(); + $scope.newServiceChannelDialog = function (){ + $uibModal.open({ + templateUrl: '/static/payment/partner/templates/incremental_service_dialog.html', + controller: 'incrementalServiceDialogCtrl', + resolve: { + params: function(){ + return { + isCreate:true, + clientMoniker:$scope.partner.client_moniker, + channelOptions:$scope.channelOptions, + serviceChannel:null + } + } + } + }).result.then(function () { + $scope.initData(); + }); + } + $scope.editServiceChannelDialog = function (serviceChannel){ + $uibModal.open({ + templateUrl: '/static/payment/partner/templates/incremental_service_dialog.html', + controller: 'incrementalServiceDialogCtrl', + resolve: { + params: function(){ + return { + isCreate:false, + clientMoniker:$scope.partner.client_moniker, + channelOptions:$scope.channelOptions, + serviceChannel:serviceChannel + } + } + } + }).result.then(function () { + $scope.initData(); + }); + } + $scope.updateStatus = function(service){ + commonDialog.confirm({ + title: 'Update '+service.channel+ ' Incremental Service Status', + content: 'Are you sure update ' + service.channel + ' status?', + choises: [ + {label: 'Submit', className: 'btn-success', key: 1}, + {label: 'Cancel', className: 'btn-warning', key: 0, dismiss: true} + ] + }).then(function (choice) { + if (choice == 1) { + service.is_valid = !service.is_valid; + $http.put('/sys/partners/'+$scope.partner.client_moniker+'/incremental_service/status',service).then(function(res){ + commonDialog.alert({ + title: 'Success', + content: 'Update Service Successful!', + type: 'success' + }); + $scope.initData(); + },function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + $scope.initData(); + }) + } + }) + + } + }]); + app.controller('incrementalServiceDialogCtrl',['$scope','$http','params','commonDialog',function($scope ,$http,params,commonDialog){ + $scope.model ={}; + $scope.ctrl = {sending: false}; + $scope.isCreate = true; + $scope.initData =function(){ + $scope.isCreate = angular.copy(params.isCreate); + if($scope.isCreate ){ + $scope.model.incremental_mode = "1" + $scope.model.channel= angular.copy(params.channelOptions[0]) + $scope.model.channelOptions= angular.copy(params.channelOptions) + }else{ + $scope.model = angular.copy(params.serviceChannel); + $scope.model.incremental_mode = $scope.model.incremental_mode.toString() + } + } + $scope.initData(); + $scope.save = function(form){ + if (form.$invalid) { + angular.forEach(form, function (item, key) { + if (key.indexOf('$') < 0) { + item.$dirty = true; + } + }); + return; + } + $scope.ctrl.sending = true; + $http.post('/sys/partners/'+params.clientMoniker+'/incremental_service',$scope.model).then(function(res){ + commonDialog.alert({ + title: 'Success', + content: $scope.isCreate?'Create':'Update'+' Service Successful!', + type: 'success' + }); + $scope.ctrl.sending = false; + $scope.$close(); + },function (resp) { + $scope.ctrl.sending = false; + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }) + + } + }]) app.filter('bdOrg', function () { diff --git a/src/main/ui/static/payment/partner/templates/incremental_service.html b/src/main/ui/static/payment/partner/templates/incremental_service.html new file mode 100644 index 000000000..764ee448b --- /dev/null +++ b/src/main/ui/static/payment/partner/templates/incremental_service.html @@ -0,0 +1,38 @@ +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    LogoChannelModeRate ValueTotal AmountOperatorCreate TimeUpdate TimeOperation
    {{service.channel}}{{service.incremental_mode==1?'固定手续费':'固定金额扣款' }}{{service.incremental_rate_value!=null?service.incremental_rate_value+'%':'-'}}{{service.total_incremental_amount}}{{service.operator}}{{service.create_time}}{{service.update_time}} + | + {{service.is_valid?'Disabled':'Enable'}} +
    +
    +
    +
    diff --git a/src/main/ui/static/payment/partner/templates/incremental_service_dialog.html b/src/main/ui/static/payment/partner/templates/incremental_service_dialog.html new file mode 100644 index 000000000..2dd5e9ec9 --- /dev/null +++ b/src/main/ui/static/payment/partner/templates/incremental_service_dialog.html @@ -0,0 +1,68 @@ + + + \ No newline at end of file diff --git a/src/main/ui/static/payment/partner/templates/partner_detail.html b/src/main/ui/static/payment/partner/templates/partner_detail.html index 42063210f..d0c9800e6 100644 --- a/src/main/ui/static/payment/partner/templates/partner_detail.html +++ b/src/main/ui/static/payment/partner/templates/partner_detail.html @@ -295,6 +295,9 @@
  • Permissions
  • +
  • + Incremental Service +