risk control: chargeback

master
yixian 4 years ago
parent aa2e3acbb4
commit f837766573

@ -5,11 +5,11 @@
<parent>
<groupId>au.com.royalpay.payment</groupId>
<artifactId>payment-parent</artifactId>
<version>2.2.9</version>
<version>2.2.10</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>manage</artifactId>
<version>2.3.48</version>
<version>2.3.49</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jib-maven-plugin.version>2.4.0</jib-maven-plugin.version>

@ -5,9 +5,7 @@ import au.com.royalpay.payment.manage.risk.bean.*;
import au.com.royalpay.payment.manage.risk.core.RiskMerchantService;
import au.com.royalpay.payment.tools.CommonConsts;
import au.com.royalpay.payment.tools.permission.enums.ManagerRole;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -47,7 +45,7 @@ public class RiskController {
riskMerchantService.dealRiskRecordDirectly(manager, record_id);
}
@RequestMapping(value = "/records/{record_id}/deal",method = RequestMethod.PUT)
@PutMapping("/records/{record_id}/deal")
public void dealRecord(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String record_id, @RequestBody DealRiskRecord dealRiskRecord) {
dealRiskRecord.setRecordId(record_id);
riskMerchantService.dealRiskRecord(manager, dealRiskRecord);
@ -56,8 +54,6 @@ public class RiskController {
@GetMapping("/orders")
public JSONObject getRiskOrders(QueryRiskOrder queryRiskOrder) {
return riskMerchantService.getRiskOrders(queryRiskOrder);
}
@PostMapping("/white/{clientMoniker}")

@ -1,7 +1,7 @@
package au.com.royalpay.payment.manage.riskbusiness.core;
import au.com.royalpay.payment.core.beans.ChargebackStatus;
import com.alibaba.fastjson.JSONObject;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@ -143,5 +143,7 @@ public interface RiskBusinessService {
void completeOrderAmount();
void UpdateRiskEventRemark(String riskId, String remark);
void updateRiskEventRemark(String riskId, String remark);
void markChargebackStatus(String riskId, JSONObject manager, ChargebackStatus status);
}

@ -1,8 +1,9 @@
package au.com.royalpay.payment.manage.riskbusiness.core.impl;
import au.com.royalpay.payment.core.CardSecureService;
import au.com.royalpay.payment.core.beans.ChargebackStatus;
import au.com.royalpay.payment.core.exceptions.EmailException;
import au.com.royalpay.payment.core.exceptions.InvalidShortIdException;
import au.com.royalpay.payment.core.exceptions.OrderNotExistsException;
import au.com.royalpay.payment.core.exceptions.OrderNotMatchException;
import au.com.royalpay.payment.manage.mappers.log.AppMessageLogMapper;
import au.com.royalpay.payment.manage.mappers.payment.OrderMapper;
@ -20,11 +21,11 @@ import au.com.royalpay.payment.manage.riskbusiness.core.RiskMaterialService;
import au.com.royalpay.payment.manage.riskbusiness.core.RiskProcessLogService;
import au.com.royalpay.payment.manage.riskbusiness.core.RiskUploadService;
import au.com.royalpay.payment.manage.riskbusiness.enums.RiskEmailStatusEnum;
import au.com.royalpay.payment.manage.riskbusiness.enums.RiskOrderTypeEnum;
import au.com.royalpay.payment.manage.riskbusiness.enums.RiskResultTypeEnum;
import au.com.royalpay.payment.manage.signin.beans.TodoNotice;
import au.com.royalpay.payment.manage.signin.core.ManagerTodoNoticeProvider;
import au.com.royalpay.payment.manage.tradelog.core.TradeLogService;
import au.com.royalpay.payment.manage.riskbusiness.enums.RiskOrderTypeEnum;
import au.com.royalpay.payment.tools.connections.mpsupport.MpWechatApi;
import au.com.royalpay.payment.tools.connections.mpsupport.MpWechatApiProvider;
import au.com.royalpay.payment.tools.connections.mpsupport.beans.TemplateMessage;
@ -34,23 +35,28 @@ import au.com.royalpay.payment.tools.device.message.AppMsgSender;
import au.com.royalpay.payment.tools.env.PlatformEnvironment;
import au.com.royalpay.payment.tools.env.SysConfigManager;
import au.com.royalpay.payment.tools.exceptions.BadRequestException;
import au.com.royalpay.payment.tools.exceptions.NotFoundException;
import au.com.royalpay.payment.tools.exceptions.ServerErrorException;
import au.com.royalpay.payment.tools.exceptions.event.WechatExceptionEvent;
import au.com.royalpay.payment.tools.locale.LocaleSupport;
import au.com.royalpay.payment.tools.mappers.CommonRiskEventMapper;
import au.com.royalpay.payment.tools.mappers.RiskEventDAO;
import au.com.royalpay.payment.tools.permission.enums.ManagerRole;
import au.com.royalpay.payment.tools.exceptions.ServerErrorException;
import au.com.royalpay.payment.tools.risk.RiskEvent;
import au.com.royalpay.payment.tools.threadpool.RoyalThreadPoolExecutor;
import au.com.royalpay.payment.tools.utils.PageListUtils;
import com.alibaba.fastjson.JSON;
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.codec.binary.Base64;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -62,17 +68,19 @@ import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.ParseException;
import java.util.*;
import javax.annotation.Resource;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.util.concurrent.TimeUnit;
/**
* @Author lvjian
@ -80,12 +88,20 @@ import java.util.concurrent.TimeUnit;
*/
@Service
public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodoNoticeProvider, ApplicationEventPublisherAware {
public static final int RISK_ORDER_TYPE_WX = 1;
public static final int RISK_ORDER_TYPE_ALIPAY = 2;
public static final int RISK_ORDER_TYPE_RP = 3;
public static final int RISK_ORDER_TYPE_WARN = 4;
public static final int RISK_ORDER_TYPE_COMMON_MID = 5;
public static final int RISK_ORDER_TYPE_CHARGEBACK = 6;
private Logger logger = LoggerFactory.getLogger(RiskBusinessServiceImpl.class);
@Resource
private RiskEventMapper riskEventMapper;
@Resource
private CommonRiskEventMapper commonRiskEventMapper;
@Resource
private ClientMapper clientMapper;
@Resource
private ClientBDMapper clientBDMapper;
@ -123,11 +139,13 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
@Resource
private AppMessageLogMapper appMessageLogMapper;
private Map<String, AppMsgSender> senderMap = new HashMap<>();
private final Map<String, AppMsgSender> senderMap = new HashMap<>();
@Resource
private APNSMessageHelper apnsMessageHelper;
@Resource
private CardSecureService cardSecureService;
@Resource
private ManagerMapper managerMapper;
@Resource
private ClientAccountMapper clientAccountMapper;
@ -144,7 +162,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
Arrays.stream(senders).forEach(appMsgSender -> senderMap.put(appMsgSender.devType(), appMsgSender));
}
private ThreadPoolExecutor sendingAppleMsgPool = new ThreadPoolExecutor(10, 30, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
private final ThreadPoolExecutor sendingAppleMsgPool = new ThreadPoolExecutor(10, 30, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
@Override
public List<JSONObject> getRiskEvents(JSONObject params) {
@ -176,8 +194,10 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
* royalpay
*
*/
Date currentDate = new Date(), replyDate;
Integer resultType, orderType;
Date currentDate = new Date();
Date replyDate;
Integer resultType;
Integer orderType;
boolean isPassTimeout = false;
for (JSONObject riskEvent : riskEvents) {
try {
@ -278,13 +298,13 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
*
*/
if (riskEvent.getIntValue("order_type") == 3) {
for (int i = 0; i < orderIdArray.length; i++) {
orderInfo = tradeLogService.getOrderDetail(new JSONObject(), riskEvent.getString("client_moniker"), orderIdArray[i], null);
for (String orderId : orderIdArray) {
orderInfo = tradeLogService.getOrderDetail(new JSONObject(), riskEvent.getString("client_moniker"), orderId, null);
tradeLogs.add(orderInfo);
}
} else {
for (int i = 0; i < orderIdArray.length; i++) {
orderInfo = orderMapper.findOrderById(orderIdArray[i],client.getIntValue("client_id"));
for (String orderId : orderIdArray) {
orderInfo = orderMapper.findOrderById(orderId, client.getIntValue("client_id"));
tradeLogs.add(orderInfo);
}
}
@ -322,7 +342,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
PageList<JSONObject> transactionList = transactionMapper.findByClientIdAndSystemTransactionId(client.getIntValue("client_id"), orderIdArray[i], new PageBounds(Order.formString("transaction_time.desc")));
// 判断该笔订单是否存在,是否属于该商户
// 由于查询订单时已经关联商户了,所以只会抛出订单不匹配的异常
if (transactionList == null || transactionList.size() <= 0)
if (transactionList == null || transactionList.isEmpty())
throw new OrderNotMatchException();
/*
else {
@ -349,6 +369,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
*
* risk_orders
*
*
* @param params
* @param manager
*/
@ -364,6 +385,19 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
RiskResultTypeEnum.NOT_HANDLED.getRemark(),
RiskResultTypeEnum.NOT_HANDLED.getResultType(),
RiskResultTypeEnum.NOT_HANDLED.getResultType());
int orderType = params.getIntValue("order_type");
if (orderType == RISK_ORDER_TYPE_CHARGEBACK) {
logger.info("Chargeback event");
RiskEvent evt = getRiskEvent(params.getString("risk_id"));
if (evt == null) {
return;
}
cardSecureService.submitChargeBackReport(evt);
}
}
private RiskEvent getRiskEvent(String riskId) {
return Optional.ofNullable(commonRiskEventMapper.findById(riskId)).map(RiskEventDAO::convert).orElse(null);
}
private void setRiskOrders(JSONObject params) {
@ -411,12 +445,12 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
public void sendWxMess(JSONObject params, String channel, int result_type) {
String type = "禁用";
if (params.get("temporary_close_merchant") != null) {
if (params.getBoolean("temporary_close_merchant")) {
if (params.getBooleanValue("temporary_close_merchant")) {
type = "临时禁用";
}
}
if (params.get("temporary_close_channel") != null) {
if (params.getBoolean("temporary_close_channel")) {
if (params.getBooleanValue("temporary_close_channel")) {
type = "临时禁用";
}
}
@ -444,7 +478,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
TemplateMessage msg = initSendBDCloseChannelAndPartnerTemplate(bd.getString("wx_openid"), paymentApi.getTemplateId("risk-forbidden-channelAndPartner"), client);
paymentApi.sendTemplateMessage(msg);
} catch (WechatException e) {
logger.error("Wechat Message Error,风控关闭通道" + e.getMessage());
logger.error("Wechat Message Error,风控关闭通道{}", e.getMessage());
publisher.publishEvent(new WechatExceptionEvent(this, e, "风控关闭通道"));
}
}
@ -462,7 +496,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
TemplateMessage msg = initSendPartnerCloseChannelAndPartnerTemplate(account.getString("wechat_openid"), paymentApi.getTemplateId("risk-forbidden-channelAndPartner"), client);
paymentApi.sendTemplateMessage(msg);
} catch (WechatException e) {
logger.error("Wechat Message Error,风控关闭通道" + e.getMessage());
logger.error("Wechat Message Error,风控关闭通道,{}", e.getMessage());
publisher.publishEvent(new WechatExceptionEvent(this, e, "风控关闭通道"));
}
}
@ -486,6 +520,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
msg.put("remark", "请联系商户尽快配合风控部门上传相应资料,以免影响支付", "#0000FF");
return msg;
}
private TemplateMessage initSendPartnerCloseChannelAndPartnerTemplate(String wxopenid, String templateId, JSONObject client) {
TemplateMessage msg = new TemplateMessage(wxopenid, templateId, null);
//1:关闭渠道;2:关闭商户
@ -507,6 +542,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
/**
*
*
* @param riskId
* @param response
*/
@ -551,6 +587,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
*
*
* App
*
* @param riskId
* @throws IOException
*/
@ -597,11 +634,12 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
/**
* App
* risk
*
* @param event
*/
private void sendAppRiskMessage(JSONObject event) {
JSONObject client = clientMapper.findClientByMoniker(event.getString("client_moniker"));
logger.debug("sendRiskAppMessage-" + client.getString("client_moniker") + "-" + "risk_id:"+event.getString("risk_id"));
logger.debug("sendRiskAppMessage-{}-risk_id:{}", client.getString("client_moniker"), event.getString("risk_id"));
List<JSONObject> tokens = clientDeviceTokenMapper.listTokensByClient_id(client.getIntValue("client_id"));
for (JSONObject devToken : tokens) {
Runnable task = () -> {
@ -634,7 +672,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
log.put("status", 2);
appMessageLogMapper.update(log);
} catch (Exception e) {
logger.error("出错了:" + e.getMessage());
logger.error("出错了:{}", e.getMessage());
appMessageLogMapper.updateStatus(log.getString("send_id"), 1, e.getMessage());
throw new ServerErrorException("Send App " + devToken.getString("client_type") + " Failed" + ",token" + token, e);
}
@ -645,6 +683,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
/**
*
*
* @param dev_id
* @param client_id
* @param messageType
@ -670,6 +709,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
*
*
*
*
* @param riskId
* @param refuseDescription
* @throws IOException
@ -721,6 +761,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
/**
*
*
* @param riskId
* @throws IOException
*/
@ -754,12 +795,6 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
codeKey = RandomStringUtils.random(20, true, true);
}
String codeKeyValue = RandomStringUtils.random(10, true, true);
/*
String expireDay = "7";
if(event.getIntValue("order_type")>2){
expireDay = "3";
}
)*/
// 原来设定的过期时间是7天
String expireDay = "3650";
stringRedisTemplate.boundValueOps(getRiskUploadKey(codeKey)).set(codeKeyValue, Long.parseLong(expireDay), TimeUnit.DAYS);
@ -887,24 +922,20 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
orders.add(order);
}
ctx.setVariable("orders", orders);
// List<JSONObject> attachList = new ArrayList<>();
// JSONObject file = new JSONObject();
// file.put("name", client.getString("short_name")+ "被查单号相关信息.xlsx");
// file.put("content", Base64.encodeBase64String(generateRiskOrders(event)));
// attachList.add(file);
// ctx.setVariable("files",attachList);
case 4:
ctx.setVariable("title", "RoyalPay风控调查 — " + client.getString("short_name"));
break;
}
return ctx;
}
private String getRiskUploadKey(String codeKey) {
return UPLOAD_MAIL_PREFIX + codeKey;
}
/**
*
*
* @param param
* @return
*/
@ -1031,6 +1062,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
bos.flush();
return bos.toByteArray();
}
private String getGateWay(int gateWay) {
switch (gateWay) {
case 0:
@ -1091,6 +1123,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
/**
*
*
* @param manager
* @param notices
*/
@ -1138,6 +1171,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
/**
*
*
* @param clientId
* @return
*/
@ -1168,6 +1202,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
*
*
*
*
* @param riskId
* @return
*/
@ -1230,6 +1265,9 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
case 3:
materialsRemark = getStudyTemplate();
break;
case 4:
materialsRemark = getChargebackTemplate();
break;
default:
break;
}
@ -1319,8 +1357,8 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
if (riskEvent.getIntValue("order_type") == 4 || StringUtils.isBlank(riskEvent.getString("real_order_ids"))) {
continue;
}
String[] order_ids=riskEvent.getString("real_order_ids").split(",");
for(String orderId : order_ids){
String[] orderIds = riskEvent.getString("real_order_ids").split(",");
for (String orderId : orderIds) {
JSONObject transaction = transactionMapper.findByOrderId(orderId);
JSONObject riskOrder = new JSONObject();
riskOrder.put("risk_id", riskEvent.getString("risk_id"));
@ -1332,12 +1370,33 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
}
@Override
public void UpdateRiskEventRemark(String riskId, String remark) {
public void updateRiskEventRemark(String riskId, String remark) {
JSONObject event = riskEventMapper.findById(riskId);
event.put("remark", remark);
riskEventMapper.update(event);
}
@Override
public void markChargebackStatus(String riskId, JSONObject manager, ChargebackStatus status) {
RiskEvent risk = getRiskEvent(riskId);
if (risk == null) {
throw new NotFoundException("Risk Event not found");
}
if (risk.getOrderType() != RISK_ORDER_TYPE_CHARGEBACK) {
throw new BadRequestException("Not Chargeback event");
}
if (status == null || status == ChargebackStatus.PROCESSING) {
throw new BadRequestException("Invalid status");
}
riskProcessLogService.addRiskProcessLog(riskId,
manager.getString("manager_id"),
manager.getString("display_name"),
RiskResultTypeEnum.ALREADY_HANDLED.getRemark(),
RiskResultTypeEnum.ALREADY_HANDLED.getResultType(),
RiskResultTypeEnum.ALREADY_HANDLED.getResultType());
cardSecureService.changeChargebackReportStatus(riskId, status);
}
private List<String> getShopTemplate() {
return Arrays.asList("1.与调查交易金额对应的购物小票/发票存根照片 要求:照片应清晰,必须显示商户名称、商户地址、购物时间、物品名称、购物金额等;\n" +
"Photos of shopping receipts/ invoice stubs Requirement corresponding with the investigated orders Requirement: The photos should be clear and must show Merchant name, Business address, Transaction time, Product information, Quantity purchased, etc;",
@ -1375,4 +1434,19 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
"Other materials including onboarding materials as task description requiredExplanation of business model for your merchant including actual selling-goods or services, per customer transaction, business hours, etc;"
);
}
private List<String> getChargebackTemplate() {
return Arrays.asList("1.A legible copy of the signed authority and/or receipts from the Cardholder. \n" +
"持卡人签名授权书和/或收据的清晰副本。",
"2.Copy of any tax invoice/s and/or signed disclosure of cancellation policy. \n" +
"任何税务发票和/或签署的披露取消政策的副本。",
"3.Any transaction Information relating to the sale of any digital goods purchased online.\n" +
"与在线购买的任何数字商品的销售有关的任何交易信息。",
"4.Description of the goods/services supplied and/or proof of delivery/collection of goods.\n" +
"提供的商品/服务的说明和/或交付/收货的证明。(消费者买了什么,商家卖了什么,消费者收没收到货,如何收到的)",
"5.Copy of Mail Order/telephone order transaction receipt.\n" +
"邮件订单/电话订单交易收据的副本。",
"6.Cardholder identification or any form of communication with the Cardholder, including email correspondence. \n" +
"持卡人身份或与持卡人的任何形式的通信,包括电子邮件通信。");
}
}

@ -1,5 +1,8 @@
package au.com.royalpay.payment.manage.riskbusiness.web;
import au.com.royalpay.payment.core.CardSecureService;
import au.com.royalpay.payment.core.beans.ChargebackStatus;
import au.com.royalpay.payment.core.beans.ChargebackTransaction;
import au.com.royalpay.payment.manage.merchants.beans.PartnerQuery;
import au.com.royalpay.payment.manage.merchants.core.ClientManager;
import au.com.royalpay.payment.manage.permission.manager.ManagerMapping;
@ -14,13 +17,14 @@ import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
*
*
* @Author lvjian
* @Date 2018/10/10 1:12
*/
@ -33,7 +37,8 @@ public class RiskBusinessController {
@Autowired
private RiskMaterialService riskMaterialService;
@Resource
private CardSecureService cardSecureService;
@Autowired
private ClientManager clientManager;
@ -41,7 +46,6 @@ public class RiskBusinessController {
private RiskProcessLogService riskProcessLogService;
@GetMapping(value = "events")
public JSONObject getRiskEvents(RiskEventQuery riskEventQuery, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) {
JSONObject params = riskEventQuery.toJSON();
@ -73,12 +77,17 @@ public class RiskBusinessController {
@GetMapping(value = "events/{risk_id}/detail")
public JSONObject getRiskEventDetailWithoutTradelogs(@PathVariable("risk_id") String riskId,
@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) {
JSONObject riskEvent = riskBusinessService.getRiskEventDetail(riskId);
return riskEvent;
return riskBusinessService.getRiskEventDetail(riskId);
}
@GetMapping("/chargeback_orders")
public List<ChargebackTransaction> searchForChargeback(@RequestParam("channel_order_id") String channelOrderId) {
return cardSecureService.queryOrdersForChargeBack(channelOrderId);
}
@PostMapping(value = "events")
public void RegisterRiskEvent(@RequestBody JSONObject params,
public void registerRiskEvent(@RequestBody JSONObject params,
@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) {
params.put("fillin_id", manager.getString("manager_id"));
params.put("fillin_person", manager.getString("display_name"));
@ -86,7 +95,7 @@ public class RiskBusinessController {
}
@PutMapping(value = "events")
public void UpdateRiskEvent(@RequestBody JSONObject params,@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) {
public void updateRiskEvent(@RequestBody JSONObject params, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) {
riskBusinessService.updateRiskEvent(params, manager);
}
@ -97,7 +106,7 @@ public class RiskBusinessController {
}
@GetMapping(value = "/{risk_id}/download/materialsAsZIP")
public void downloadComplianceZip(@PathVariable("risk_id") String riskId, HttpServletResponse response) throws Exception {
public void downloadComplianceZip(@PathVariable("risk_id") String riskId, HttpServletResponse response) {
riskBusinessService.downloadAuditMaterialZiP(riskId, response);
}
@ -152,20 +161,25 @@ public class RiskBusinessController {
if (temporaryCloseMerchant != 1) {
params.put("result_type", RiskResultTypeEnum.ALREADY_HANDLED.getResultType());
}
}
else {
} else {
clientManager.revertClient(clientMoniker, manager);
params.put("result_type", RiskResultTypeEnum.ALREADY_HANDLED.getResultType());
}
riskBusinessService.updateRiskEvent(params, manager);
}
@RequestMapping(value = "/{risk_id}/urge",method = RequestMethod.PUT)
@PutMapping("/{risk_id}/urge")
public void urgeEmail(@PathVariable String risk_id) throws IOException {
riskBusinessService.sendUrgeEmail(risk_id);
}
@RequestMapping(value = "/ban/{risk_id}",method = RequestMethod.DELETE)
@PutMapping("/chargebacks/{riskId}/mark_status")
public void markChargebackStatus(@PathVariable String riskId, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,
@RequestBody JSONObject status) {
riskBusinessService.markChargebackStatus(riskId, manager, status.getObject("status", ChargebackStatus.class));
}
@DeleteMapping("/ban/{risk_id}")
public void banEvent(@PathVariable String risk_id) {
riskBusinessService.banRiskEvent(risk_id);
}
@ -205,8 +219,8 @@ public class RiskBusinessController {
@PutMapping(value = "{risk_id}/remark")
@ResponseBody
public void UpdateRiskEventRemark(@PathVariable("risk_id") String riskId, @RequestBody JSONObject remark) {
riskBusinessService.UpdateRiskEventRemark(riskId, remark.getString("remark"));
public void updateRiskEventRemark(@PathVariable("risk_id") String riskId, @RequestBody JSONObject remark) {
riskBusinessService.updateRiskEventRemark(riskId, remark.getString("remark"));
}
}

@ -5,38 +5,40 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
function (angular, $) {
'use strict';
var mailTemplate = {
let mailTemplate = {
"1": "代购、综合商城类",
"2": "飞机票、旅行社类",
"3": "教育类、中介类"
"3": "教育类、中介类",
"4": "Chargeback"
};
var orderTypesMap = {
let orderTypesMap = {
"1": "微信调单",
"2": "支付宝调单",
"3": "RoyalPay调单",
"4": "警告",
"5": "通用号调单"
"5": "通用号调单",
"6": "卡支付ChargeBack"
};
var orderTypesMapForBD = {
let orderTypesMapForBD = {
"1": "微信调单",
"2": "支付宝调单",
"3": "RoyalPay调单"
};
var royalpayOrderTypesMap = {
let royalpayOrderTypesMap = {
"0": "正常调单",
"1": "单纯大金额频繁刷单"
};
var warningOrderTypesMap = {
let warningOrderTypesMap = {
"0": "单人多次大金额交易",
"1": "退款频繁"
};
var resultTypesMap = {
let resultTypesMap = {
"0": "未处理",
"1": "已发送邮件",
"2": "已提交材料,等待审核",
@ -45,7 +47,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
"5": "已处理"
};
var resultTypeSearchMap = {
let resultTypeSearchMap = {
"0": "未处理",
"1": "资料完善中",
"2": "等待风控",
@ -54,7 +56,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
"5": "已处理"
};
var resultTypeSearchMapForBD = {
let resultTypeSearchMapForBD = {
"1": "材料待上传",
"2": "材料已提交",
"3": "风控初审完成,渠道方审核中",
@ -62,14 +64,14 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
"5": "已处理"
};
var emailStatusMap = {
let emailStatusMap = {
"0": "未发送",
"1": "已发送",
"2": "打回并已发送",
"3": "已发送催促邮件"
};
var amountSectionMap = {
let amountSectionMap = {
"0-500": "0-500",
"500-1000": "500-1000",
"1000-1500": "1000-1500",
@ -81,7 +83,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
"4000-4500": "4000-4500"
};
var channelResultArray = [
let channelResultArray = [
"关闭支付",
"恢复支付",
"单日10",
@ -95,7 +97,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
"其他"
];
var app = angular.module('riskBusinessApp', ['ui.router']);
let app = angular.module('riskBusinessApp', ['ui.router']);
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('analysis_monitoring.risk_business', {
url: '/risk_business',
@ -148,7 +150,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
$scope.amountSection = amountSectionMap;
$scope.pagination = {};
$scope.params = {};
var industries = new Array();
let industries = [];
angular.forEach($scope.industries, function (industry) {
industries.push(industry.label);
});
@ -160,14 +162,14 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
// console.log(industries);
// 加载风险注册事件
$scope.loadRiskEvents = function (page) {
var params = angular.copy($scope.params);
let params = angular.copy($scope.params);
params.page = page || $scope.pagination.page || 1;
params.replyEmailDateBegin = $filter('date')(params.replyEmailDateBegin, 'yyyy-MM-dd');
params.replyEmailDateEnd = $filter('date')(params.replyEmailDateEnd, 'yyyy-MM-dd');
params.receiveEmailDateBegin = $filter('date')(params.receiveEmailDateBegin, 'yyyy-MM-dd');
params.receiveEmailDateEnd = $filter('date')(params.receiveEmailDateEnd, 'yyyy-MM-dd');
if (params.section != null) {
var sectionArray = params.section.split('-');
let sectionArray = params.section.split('-');
params.startAmount = sectionArray[0];
params.endAmount = sectionArray[1];
}
@ -186,7 +188,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
};
var industryAmount = function (industries) {
let industryAmount = function (industries) {
return {
chart: {
tooltip: {
@ -229,7 +231,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
}
};
var intervalsAmount = function () {
let intervalsAmount = function () {
return {
chart: {
tooltip: {
@ -286,7 +288,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
$scope.mailTemplate = mailTemplate;
$scope.resultTypes = resultTypesMap;
$scope.channelResults = channelResultArray;
if (riskEvent.data.is_send_client == 1)
if (riskEvent.data.is_send_client === 1)
riskEvent.data.is_send_client = true;
$scope.riskEvent = riskEvent.data;
@ -299,7 +301,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
};
$scope.checkTemplate = function () {
var url = "";
let url = "";
switch ($scope.riskEvent.mail_template) {
case "1":
url = "https://file.royalpay.com.au/open/2019/03/27/1553658222567_BzfAtsEgsBdMQLl3jGOAlfcYmFUL1F.png";
@ -323,13 +325,13 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
// 编辑表格的数据保存对象,重新从源数据复制,从而取消保存操作时不会更新视图
$scope.riskEventEdit = angular.copy(riskEvent.data);
//var index = $scope.riskEvent.order_ids.lastIndexOf(",");
//let index = $scope.riskEvent.order_ids.lastIndexOf(",");
//$scope.riskEvent.order_ids = $scope.riskEvent.order_ids.substring(0, index) + "" + $scope.riskEvent.order_ids.substring(index + 1);
// 获取数据库中对应的渠道字段
var orderChannel = 'enable_';
if ($scope.riskEvent.order_type == 1) {
let orderChannel = 'enable_';
if ($scope.riskEvent.order_type === 1) {
orderChannel += 'wechat';
} else if ($scope.riskEvent.order_type == 2) {
} else if ($scope.riskEvent.order_type === 2) {
orderChannel += 'alipay';
} else {
orderChannel = null;
@ -342,7 +344,11 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
}).then(function () {
$http.delete('/risk/business/ban/' + $scope.riskEvent.risk_id).then(function () {
$state.go('analysis_monitoring.risk_business');
commonDialog.alert({title: 'Delete', content: 'Risk Event Already Disabled', type: 'error'});
commonDialog.alert({
title: 'Delete',
content: 'Risk Event Already Disabled',
type: 'error'
});
}, function (resp) {
commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'});
})
@ -350,10 +356,10 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
};
$scope.commitWaitRiskStatus = function () {
var index = $scope.riskEvent.submit_url.lastIndexOf('=');
let index = $scope.riskEvent.submit_url.lastIndexOf('=');
if (index < 0)
index = $scope.riskEvent.submit_url.lastIndexOf('/');
var codeKey = $scope.riskEvent.submit_url.substring(index + 1);
let codeKey = $scope.riskEvent.submit_url.substring(index + 1);
commonDialog.confirm({
title: '确认已提交资料',
content: '确认已收到商户资料,更新风控状态为等待风控审核?'
@ -368,6 +374,18 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
})
};
$scope.commitChargebackStatus = function (std) {
commonDialog.confirm({title: '确认操作', content: '当前操作不可逆,并会将风控项标记为办结状态,确认操作?'}).then(function () {
$http.put('/risk/business/chargebacks/' + $scope.riskEvent.risk_id + '/status', {status: std}).then(function () {
$state.reload();
commonDialog.alert({title: 'Success', content: '修改成功', type: success})
}, function (res) {
commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'})
})
})
}
/**
* order_ids在指定位置换行
* @param str
@ -375,15 +393,15 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
* @returns {*}
*/
$scope.splitStr = function (str, position) {
if (str == null || str == '')
if (str == null || str === '')
return;
var strArr = str.split(",");
var resultStr = '';
for (var i = 0; i < strArr.length; i++) {
let strArr = str.split(",");
let resultStr = '';
for (let i = 0; i < strArr.length; i++) {
resultStr += strArr[i];
if (i == (strArr.length - 1))
if (i === (strArr.length - 1))
break;
if ((i + 1) % position == 0)
if ((i + 1) % position === 0)
resultStr += ", ";
else
resultStr += ",";
@ -454,10 +472,10 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
* @param temporaryFlag 是否临时关停
*/
$scope.updateChannel = function (orderType, channelFlag, temporaryFlag) {
var channel;
if (orderType == "1")
let channel;
if (orderType === "1")
channel = 'wechat';
else if (orderType == "2")
else if (orderType === "2")
channel = 'alipay';
$scope.riskEvent.temporary_close_channel = temporaryFlag;
commonDialog.confirm({
@ -497,8 +515,8 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
title: 'Warning',
content: 'Please confirm sending mail.'
}).then(function () {
var url = '/risk/business/' + $scope.riskEvent.risk_id + '/upload_mail';
if ($scope.riskEvent.result_type == 1)
let url = '/risk/business/' + $scope.riskEvent.risk_id + '/upload_mail';
if ($scope.riskEvent.result_type === 1)
url = '/risk/business/' + $scope.riskEvent.risk_id + '/urge';
$http.put(url).then(function () {
$state.reload();
@ -517,11 +535,11 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
$scope.material = {};
$scope.uploadFile = function (files, index) {
if (files && files.length) {
var urls = new Array();
var value = 0;
let urls = [];
let value = 0;
$scope.allMaterialInfo.material[index].fileProgressValue = 0;
for (var i = 0; i < files.length; i++) {
var file = files[i];
for (let i = 0; i < files.length; i++) {
let file = files[i];
Upload.upload({
url: '/attachment/riskFiles',
data: {file: file}
@ -540,11 +558,11 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
};
$scope.submit = function (form) {
var codeKey = $scope.riskEvent.submit_url.substring($scope.riskEvent.submit_url.lastIndexOf('=') + 1) || $scope.riskEvent.submit_url.substring($scope.riskEvent.submit_url.lastIndexOf('/') + 1);
let codeKey = $scope.riskEvent.submit_url.substring($scope.riskEvent.submit_url.lastIndexOf('=') + 1) || $scope.riskEvent.submit_url.substring($scope.riskEvent.submit_url.lastIndexOf('/') + 1);
$scope.material.update_time = $filter('date')(new Date(), 'yyyy-MM-dd HH:mm:ss');
$scope.material.risk_id = $scope.riskEvent.risk_id;
for (var i = 0; i < $scope.allMaterialInfo.material.length; i++) {
var key = 'file' + (i + 1) + "_url";
for (let i = 0; i < $scope.allMaterialInfo.material.length; i++) {
let key = 'file' + (i + 1) + "_url";
$scope.material[key] = $scope.allMaterialInfo.material[i].uploadFile;
}
$scope.material.description = $scope.allMaterialInfo.description;
@ -579,7 +597,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
};
// BD是否可上传
$scope.uploadShowFlag = ($scope.riskEvent.result_type == 1 || $scope.riskEvent.result_type == 3 || $scope.riskEvent.result_type == 4) ? true : false;
$scope.uploadShowFlag = ($scope.riskEvent.result_type === 1 || $scope.riskEvent.result_type === 3 || $scope.riskEvent.result_type === 4);
//if (!$scope.uploadShowFlag)
$scope.loadRiskMaterial();
}
@ -605,8 +623,8 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
// $scope.file5 = resp.data.file5;
// $scope.file6 = resp.data.file6;
//
// // for (var i = 1; i <= 10; i++) {
// // var key = "file" + i;
// // for (let i = 1; i <= 10; i++) {
// // let key = "file" + i;
// // if (riskMaterial[key + '_url'] != null)
// // $scope.fileObject[key] = riskMaterial[key + '_url'];
// // }
@ -620,16 +638,16 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
$scope.loadRiskMaterial();
//审核通过也要可以传图片
$scope.uploadShowFlag = ($scope.riskEvent.result_type == 1 || $scope.riskEvent.result_type == 3 || $scope.riskEvent.result_type == 4) ? true : false;
$scope.uploadShowFlag = ($scope.riskEvent.result_type === 1 || $scope.riskEvent.result_type === 3 || $scope.riskEvent.result_type === 4);
// 材料上传
$scope.uploadFile = function (files, index) {
if (files && files.length) {
var urls = new Array();
var value = 0;
let urls = [];
let value = 0;
$scope.riskMaterial.material[index].fileProgressValue = 0;
for (var i = 0; i < files.length; i++) {
var file = files[i];
for (let i = 0; i < files.length; i++) {
let file = files[i];
Upload.upload({
url: '/attachment/riskFiles',
data: {file: file}
@ -649,14 +667,14 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
};
$scope.submit = function (form) {
var index = $scope.riskEvent.submit_url.lastIndexOf('=');
let index = $scope.riskEvent.submit_url.lastIndexOf('=');
if (index < 0)
index = $scope.riskEvent.submit_url.lastIndexOf('/');
var codeKey = $scope.riskEvent.submit_url.substring(index + 1);
let codeKey = $scope.riskEvent.submit_url.substring(index + 1);
$scope.material.update_time = $filter('date')(new Date(), 'yyyy-MM-dd HH:mm:ss');
$scope.material.risk_id = $scope.riskEvent.risk_id;
for (var i = 0; i < $scope.riskMaterial.material.length; i++) {
var key = 'file' + (i + 1) + "_url";
for (let i = 0; i < $scope.riskMaterial.material.length; i++) {
let key = 'file' + (i + 1) + "_url";
$scope.material[key] = $scope.riskMaterial.material[i].file;
}
$scope.material.description = $scope.riskMaterial.description;
@ -679,9 +697,9 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
// 材料审核
$scope.auditMaterial = function (auditType) {
var url = '/risk/business/events/pass';
var warningMessageHTML = '是否确定<span style="color: green; font-weight: bolder; font-size: 20px;">通过</span>该材料?';
if (auditType == 3) {
let url = '/risk/business/events/pass';
let warningMessageHTML = '是否确定<span style="color: green; font-weight: bolder; font-size: 20px;">通过</span>该材料?';
if (auditType === 3) {
commonDialog.confirm({
title: 'Warning',
contentHtml: $sce.trustAsHtml(warningMessageHTML)
@ -698,8 +716,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
});
});
});
}
else if (auditType == 4) {
} else if (auditType === 4) {
url = '/risk/business/' + $scope.riskEvent.risk_id + '/refuse';
//warningMessageHTML = '是否确定<span style="color: red; font-weight: bolder; font-size: 20px;">拒绝</span>该材料?'
commonDialog.inputText({title: 'Input Refuse Description', size: 'lg'}).then(function (text) {
@ -732,8 +749,21 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
$scope.materials = [{key: 0, value: ""}];
$scope.canMinus = false;
$scope.riskEvent = {};
$scope.searchForChargeback = function () {
$scope.riskEvent.order_ids = null;
let channelOrderId = $scope.riskEvent.channel_order_id;
$http.get('/risk/business/chargeback_orders', {channel_order_id: channelOrderId}).then(function (res) {
$scope.channel_orders = res.data;
}, function (res) {
commonDialog.alert({type: 'error', title: 'Error', content: res.data.message})
});
};
$scope.chooseOrderForChargeback = function (chargebackOrder) {
$scope.riskEvent.order_ids = chargebackOrder.channel_order_id;
$scope.riskEvent.client_moniker = chargebackOrder.client_moniker;
}
$scope.checkTemplate = function () {
var url = "";
let url = "";
switch ($scope.riskEvent.mail_template) {
case "1":
url = "https://file.royalpay.com.au/open/2019/03/27/1553658222567_BzfAtsEgsBdMQLl3jGOAlfcYmFUL1F.png";
@ -763,23 +793,23 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
$scope.materials.splice($index, 1);
}
// 如果回复数为1不允许删除
if ($scope.materials.length == 1) {
if ($scope.materials.length === 1) {
$scope.canMinus = false;
}
};
var array=new Array();
var validIndex = 0;
let array = [];
let validIndex = 0;
$scope.combineMaterials = function () {
for (var i = 0; i < $scope.materials.length; i++) {
var value = $scope.materials[i].value;
if (value == '')
for (let i = 0; i < $scope.materials.length; i++) {
let value = $scope.materials[i].value;
if (value === '')
continue;
var cr = {};
let cr = {};
cr['question' + (validIndex + 1)] = $scope.materials[i].value;
array[validIndex] = cr;
validIndex++;
}
if (array.length == 0)
if (array.length === 0)
return null;
return JSON.stringify(array);
};
@ -803,7 +833,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
if ($scope.riskEvent.receive_email_date == null)
$scope.riskEvent.receive_email_date = new Date();
// 默认设置邮件回复截止日期为收到邮件的七天后,如果是内部调单,设置三天后
var replyDeadline = angular.copy($scope.riskEvent.receive_email_date);
let replyDeadline = angular.copy($scope.riskEvent.receive_email_date);
if ($scope.riskEvent.order_type > 2)
replyDeadline.setDate(replyDeadline.getDate() + 3);
else
@ -818,8 +848,8 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
$scope.riskEvent.send_clean_days = $scope.send_clean_days;
var saveRiskBtn = document.getElementById('save-risk-btn');
var saveRiskBtnInnerHtmlBak = saveRiskBtn.innerHTML;
let saveRiskBtn = document.getElementById('save-risk-btn');
let saveRiskBtnInnerHtmlBak = saveRiskBtn.innerHTML;
saveRiskBtn.disabled = true;
saveRiskBtn.innerHTML = "<i class='fa fa-spinner fa-spin '></i> Processing";
$http.post('/risk/business/events', $scope.riskEvent).then(function (resp) {
@ -848,10 +878,9 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
$scope.partners = resp.data;
if ($scope.partners != null && $scope.partners.length > 0) {
// 由于通用号调单可能无法提供商户client_moniker,所以后台无法查询到订单
if ($scope.partners.length == 1 || $scope.riskEvent.order_type != 5)
if ($scope.partners.length === 1 || $scope.riskEvent.order_type !== 5)
$scope.riskEvent.client_moniker = $scope.partners[0].client_moniker;
}
else {
} else {
commonDialog.confirm({
title: 'Warning',
content: '该微信子商户号下暂时没有商户或者商户被禁用,是否继续?'
@ -863,7 +892,7 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
$scope.riskEvent.sub_merchant_id = '';
});
}
if ($scope.partners != null && $scope.partners.length > 1 && $scope.riskEvent.order_type != 5)
if ($scope.partners != null && $scope.partners.length > 1 && $scope.riskEvent.order_type !== 5)
commonDialog.confirm({
title: 'Warning',
content: '该微信子商户号下有多个商户,是否将调单类型改为通用号调单?'

@ -25,6 +25,9 @@
<li class="list-group-item" ng-class="{'active':regionActive('AU_NSW')}"
ng-click="toggleRegion('AU_NSW')">AU NSW
</li>
<li class="list-group-item" ng-class="{'active':regionActive('AU_QLD')}"
ng-click="toggleRegion('AU_QLD')">AU QLD
</li>
</ul>
</div>
</div>

@ -1,4 +1,3 @@
<section class="content-header">
<h1>New RiskEvent</h1>
</section>
@ -56,7 +55,8 @@
</div>
</div>
</div>
<div class="form-group" ng-if="riskEvent.order_type ==3 && riskEvent.royalpay_order_type==1">
<div class="form-group"
ng-if="riskEvent.order_type ==3 && riskEvent.royalpay_order_type==1">
<label class="control-label col-sm-2">是否发送清算周期变更</label>
<div class="col-xs-6">
<input type="checkbox"
@ -111,7 +111,8 @@
</div>
</div>
<div class="form-group" ng-if="(partners != null) && (partners.length > 0) && riskEvent.order_type == 1">
<div class="form-group"
ng-if="(partners != null) && (partners.length > 0) && riskEvent.order_type == 1">
<label class="control-label col-sm-2"
for="order-type-input">Company Name
</label>
@ -134,7 +135,7 @@
</div>
<div class="form-group"
ng-if="riskEvent.order_type != 5"
ng-if="riskEvent.order_type != 5 && riskEvent.order_type!=6"
ng-class="{'has-error':riskEventForm.client_moniker.$invalid && riskEventForm.client_moniker.$dirty}">
<label class="control-label col-sm-2"
for="short-id-input">Partner Code
@ -165,7 +166,7 @@
</div>
<div class="form-group"
ng-if="riskEvent.order_type != 4"
ng-if="riskEvent.order_type != 4 && riskEvent.order_type!=6"
ng-class="{'has-error':riskEventForm.order_ids.$invalid && riskEventForm.order_ids.$dirty}">
<label class="control-label col-sm-2"
for="order-ids-input">Platform Transaction IDs</label>
@ -187,6 +188,54 @@
</div>
</div>
</div>
<div class="form-group" ng-if="riskEvent.order_type==6"
ng-class="{'has-error':riskEventForm.channel_order_id.$invalid && riskEventForm.channel_order_id.$dirty}">
<label class="control-label col-sm-2" for="channel-order-id-input">Channel Transaction
ID</label>
<div class="col-sm-8">
<div class="input-group">
<input type="text" name="channel_order_id" id="channel-order-id-input"
class="form-control" ng-model="riskEvent.channel_order_id">
<div class="input-group-btn">
<button type="button" class="btn btn-success"
ng-click="searchForChargeback()"><i class="fa fa-search"></i>
</button>
</div>
</div>
</div>
</div>
<div class="row" ng-if="riskEvent.order_type==6 && channel_orders && !riskEvent.order_ids">
<div class="col-sm-12 table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Merchant</th>
<th>Order ID</th>
<th>Channel</th>
<th>Channel Order ID</th>
<th>Amount</th>
<th>Transaction Time</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="order in channel_orders">
<td ng-bind="order.client_moniker"></td>
<td ng-bind="order.order_id"></td>
<td ng-bind="order.channel"></td>
<td ng-bind="order.channel_order_id"></td>
<td ng-bind="order.amount|currency:'AUD'"></td>
<td ng-bind="order.transaction_time|date:'yyyy-MM-dd HH:mm:ss'"></td>
<td>
<button class="btn btn-link" type="button"
ng-click="chooseOrderForChargeback(order)">Choose
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2"
@ -230,13 +279,15 @@
<input class="form-control"
ng-model="material.value"
type="text"
name="material{{$index+1}}"
ng-input-name="material{{$index+1}}"
id="material{{$index+1}}"
required>
</div>
<div class="col-sm-2">
<a class="text-success" ng-click="increase($index)"><i class="fa fa-plus-circle" style="width: 30px"></i></a>
<a class="text-danger" ng-click="decrease($index)" ng-show="canMinus"><i class="fa fa-minus-circle" style="width: 30px"></i></a>
<a class="text-success" ng-click="increase($index)"><i class="fa fa-plus-circle"
style="width: 30px"></i></a>
<a class="text-danger" ng-click="decrease($index)" ng-show="canMinus"><i
class="fa fa-minus-circle" style="width: 30px"></i></a>
</div>
</div>

@ -252,7 +252,8 @@
<button class="btn btn-info"
ng-if="enableChannel == 0"
type="button"
ng-click="updateChannel(riskEvent.order_type, true, false)">重新启用渠道
ng-click="updateChannel(riskEvent.order_type, true, false)">
重新启用渠道
</button>
</div>
<div class="col-xs-2" ng-if="clientInfo.is_valid == 0">
@ -262,6 +263,18 @@
ng-if="'10000000000'|withRole">重新启用商户
</button>
</div>
<div class="col-xs-2"
ng-if="riskEvent.order_type==6 && ('10000000000'|withRole)">
<button class="btn btn-info" type="button"
ng-click="commitChargebackStatus('ACCEPTED')">放弃申诉
</button>
</div>
<div class="col-xs-2"
ng-if="riskEvent.order_type==6 && ('10000000000'|withRole)">
<button class="btn btn-info" type="button"
ng-click="commitChargebackStatus('DECLINED')">申诉成功
</button>
</div>
</div>
<div class="form-group" ng-if="riskEvent.channel_result != null && ('10000000000'|withRole)">

Loading…
Cancel
Save