mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-08-12 17:23:50 +08:00
接入清分和订单异常待办
This commit is contained in:
@@ -93,6 +93,6 @@ public class OrderAbnormalRecordController extends BaseController {
|
||||
@Log(title = "订单异常记录", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult remove(@PathVariable Integer[] ids) {
|
||||
return toAjax(orderAbnormalRecordService.deleteOrderAbnormalRecordByIds(ids));
|
||||
return toAjax(orderAbnormalRecordService.deleteOrderAbnormalRecordByIds(ids, getUsername()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,4 +219,4 @@ sms:
|
||||
todo:
|
||||
operator-admin-role-id: 3
|
||||
retention-days: 180
|
||||
route-whitelist: invoiceDetail,financeDetail,accountUserInfo
|
||||
route-whitelist: invoiceDetail,financeDetail,accountUserInfo,AbnormalRecord
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.jsowell.pile.service;
|
||||
|
||||
import com.jsowell.pile.constant.AdapayClearingTodoConstants;
|
||||
import com.jsowell.pile.domain.AdapayUnsplitRecord;
|
||||
import com.jsowell.pile.domain.OrderBasicInfo;
|
||||
import com.jsowell.pile.domain.PileMerchantInfo;
|
||||
import com.jsowell.pile.service.impl.AdapayClearingTodoServiceImpl;
|
||||
import com.jsowell.system.domain.dto.TodoTaskCreateCommand;
|
||||
import com.jsowell.system.service.TodoTaskAssigneeService;
|
||||
import com.jsowell.system.service.TodoTaskService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class AdapayClearingTodoServiceImplTest {
|
||||
@Test
|
||||
void failedAndRecovered_shouldCreateThenCompleteTodo() {
|
||||
Dependencies dependencies = new Dependencies();
|
||||
AdapayClearingTodoServiceImpl service = dependencies.createService();
|
||||
OrderBasicInfo orderInfo = OrderBasicInfo.builder().build();
|
||||
orderInfo.setMerchantId("100");
|
||||
when(dependencies.orderService.getOrderInfoByOrderCode("C100")).thenReturn(orderInfo);
|
||||
PileMerchantInfo merchantInfo = new PileMerchantInfo();
|
||||
merchantInfo.setDeptId("200");
|
||||
when(dependencies.merchantService.selectPileMerchantInfoById(100L)).thenReturn(merchantInfo);
|
||||
when(dependencies.assigneeService.findActiveOperatorAdminUserIdsByDeptTree(200L))
|
||||
.thenReturn(Collections.singletonList(8L));
|
||||
AdapayUnsplitRecord record = AdapayUnsplitRecord.builder()
|
||||
.paymentId("payment-100")
|
||||
.orderCode("C100")
|
||||
.refundFlag("SUCCESS")
|
||||
.splitFlag("FAILED")
|
||||
.build();
|
||||
|
||||
service.syncUnsplitRecordTodo(record);
|
||||
|
||||
ArgumentCaptor<TodoTaskCreateCommand> captor = ArgumentCaptor.forClass(TodoTaskCreateCommand.class);
|
||||
verify(dependencies.todoTaskService).createTask(captor.capture());
|
||||
assertEquals(AdapayClearingTodoConstants.TASK_TYPE, captor.getValue().getTaskType());
|
||||
assertEquals(AdapayClearingTodoConstants.BUSINESS_TYPE, captor.getValue().getBusinessType());
|
||||
assertEquals("payment-100", captor.getValue().getBusinessId());
|
||||
assertEquals("financeDetail", captor.getValue().getRouteName());
|
||||
|
||||
record.setSplitFlag("SUCCESS");
|
||||
service.syncUnsplitRecordTodo(record);
|
||||
verify(dependencies.todoTaskService).completeByBusinessAsSystem(
|
||||
AdapayClearingTodoConstants.BUSINESS_TYPE, "payment-100", null, "adapay-clearing");
|
||||
}
|
||||
|
||||
private static void setField(Object target, String fieldName, Object value) {
|
||||
try {
|
||||
Field field = target.getClass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(target, value);
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Dependencies {
|
||||
private final OrderBasicInfoService orderService = mock(OrderBasicInfoService.class);
|
||||
private final PileMerchantInfoService merchantService = mock(PileMerchantInfoService.class);
|
||||
private final TodoTaskAssigneeService assigneeService = mock(TodoTaskAssigneeService.class);
|
||||
private final TodoTaskService todoTaskService = mock(TodoTaskService.class);
|
||||
|
||||
private AdapayClearingTodoServiceImpl createService() {
|
||||
AdapayClearingTodoServiceImpl service = new AdapayClearingTodoServiceImpl();
|
||||
setField(service, "orderBasicInfoService", orderService);
|
||||
setField(service, "pileMerchantInfoService", merchantService);
|
||||
setField(service, "todoTaskAssigneeService", assigneeService);
|
||||
setField(service, "todoTaskService", todoTaskService);
|
||||
return service;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.jsowell.pile.service;
|
||||
|
||||
import com.jsowell.pile.domain.AdapayUnsplitRecord;
|
||||
import com.jsowell.pile.mapper.AdapayUnsplitRecordMapper;
|
||||
import com.jsowell.web.controller.pile.AdapayUnsplitRecordServiceImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class AdapayUnsplitRecordTodoLinkTest {
|
||||
@Test
|
||||
void flagUpdate_shouldSyncTodoWithPersistedRecord() {
|
||||
AdapayUnsplitRecordMapper mapper = mock(AdapayUnsplitRecordMapper.class);
|
||||
AdapayClearingTodoService todoService = mock(AdapayClearingTodoService.class);
|
||||
AdapayUnsplitRecordServiceImpl service = newService(mapper, todoService);
|
||||
AdapayUnsplitRecord updateRecord = AdapayUnsplitRecord.builder()
|
||||
.id(1)
|
||||
.paymentId("payment-100")
|
||||
.splitFlag("FAILED")
|
||||
.build();
|
||||
AdapayUnsplitRecord persistedRecord = AdapayUnsplitRecord.builder()
|
||||
.id(1)
|
||||
.paymentId("payment-100")
|
||||
.orderCode("C100")
|
||||
.refundFlag("SUCCESS")
|
||||
.splitFlag("FAILED")
|
||||
.build();
|
||||
when(mapper.insertOrUpdateSelective(updateRecord)).thenReturn(1);
|
||||
when(mapper.selectByPrimaryKey(1)).thenReturn(persistedRecord);
|
||||
|
||||
service.insertOrUpdateSelective(updateRecord);
|
||||
|
||||
verify(todoService).syncUnsplitRecordTodo(persistedRecord);
|
||||
}
|
||||
|
||||
@Test
|
||||
void amountOnlyUpdate_shouldNotSyncTodo() {
|
||||
AdapayUnsplitRecordMapper mapper = mock(AdapayUnsplitRecordMapper.class);
|
||||
AdapayClearingTodoService todoService = mock(AdapayClearingTodoService.class);
|
||||
AdapayUnsplitRecordServiceImpl service = newService(mapper, todoService);
|
||||
AdapayUnsplitRecord updateRecord = AdapayUnsplitRecord.builder()
|
||||
.id(1)
|
||||
.paymentId("payment-100")
|
||||
.build();
|
||||
when(mapper.insertOrUpdateSelective(updateRecord)).thenReturn(1);
|
||||
|
||||
service.insertOrUpdateSelective(updateRecord);
|
||||
|
||||
verify(todoService, never()).syncUnsplitRecordTodo(updateRecord);
|
||||
}
|
||||
|
||||
private static AdapayUnsplitRecordServiceImpl newService(AdapayUnsplitRecordMapper mapper,
|
||||
AdapayClearingTodoService todoService) {
|
||||
AdapayUnsplitRecordServiceImpl service = new AdapayUnsplitRecordServiceImpl();
|
||||
setField(service, "adapayUnsplitRecordMapper", mapper);
|
||||
setField(service, "adapayClearingTodoService", todoService);
|
||||
return service;
|
||||
}
|
||||
|
||||
private static void setField(Object target, String fieldName, Object value) {
|
||||
try {
|
||||
Field field = target.getClass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(target, value);
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.jsowell.pile.service;
|
||||
|
||||
import com.jsowell.pile.constant.OrderAbnormalTodoConstants;
|
||||
import com.jsowell.pile.domain.OrderAbnormalRecord;
|
||||
import com.jsowell.pile.domain.PileMerchantInfo;
|
||||
import com.jsowell.pile.mapper.OrderAbnormalRecordMapper;
|
||||
import com.jsowell.pile.service.impl.OrderAbnormalRecordServiceImpl;
|
||||
import com.jsowell.pile.vo.base.PileInfoVO;
|
||||
import com.jsowell.system.domain.dto.TodoTaskCreateCommand;
|
||||
import com.jsowell.system.service.TodoTaskAssigneeService;
|
||||
import com.jsowell.system.service.TodoTaskService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class OrderAbnormalRecordTodoTest {
|
||||
@Test
|
||||
void insert_shouldCreateTodoForEachMerchantAdmin() {
|
||||
Dependencies dependencies = new Dependencies();
|
||||
OrderAbnormalRecordServiceImpl service = dependencies.createService();
|
||||
OrderAbnormalRecord record = new OrderAbnormalRecord();
|
||||
record.setOrderCode("transaction-100");
|
||||
record.setPileSn("pile-100");
|
||||
record.setStopReasonMsg("平台未找到原订单");
|
||||
doAnswer(invocation -> {
|
||||
OrderAbnormalRecord value = invocation.getArgument(0);
|
||||
value.setId(55);
|
||||
return 1;
|
||||
}).when(dependencies.mapper).insertOrderAbnormalRecord(record);
|
||||
when(dependencies.pileBasicInfoService.selectPileInfoBySn("pile-100"))
|
||||
.thenReturn(PileInfoVO.builder().merchantId("100").build());
|
||||
PileMerchantInfo merchantInfo = new PileMerchantInfo();
|
||||
merchantInfo.setDeptId("200");
|
||||
when(dependencies.merchantService.selectPileMerchantInfoById(100L)).thenReturn(merchantInfo);
|
||||
when(dependencies.assigneeService.findActiveOperatorAdminUserIdsByDeptTree(200L))
|
||||
.thenReturn(Arrays.asList(8L, 9L));
|
||||
|
||||
service.insertOrderAbnormalRecord(record);
|
||||
|
||||
ArgumentCaptor<TodoTaskCreateCommand> captor = ArgumentCaptor.forClass(TodoTaskCreateCommand.class);
|
||||
verify(dependencies.todoTaskService, times(2)).createTask(captor.capture());
|
||||
TodoTaskCreateCommand command = captor.getAllValues().get(0);
|
||||
assertEquals(OrderAbnormalTodoConstants.TASK_TYPE, command.getTaskType());
|
||||
assertEquals(OrderAbnormalTodoConstants.BUSINESS_TYPE, command.getBusinessType());
|
||||
assertEquals("55", command.getBusinessId());
|
||||
assertEquals(OrderAbnormalTodoConstants.ROUTE_NAME, command.getRouteName());
|
||||
assertEquals("100", command.getAssigneeMerchantId());
|
||||
assertEquals(8L, command.getAssigneeUserId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void delete_shouldCancelBusinessTodos() {
|
||||
Dependencies dependencies = new Dependencies();
|
||||
OrderAbnormalRecordServiceImpl service = dependencies.createService();
|
||||
Integer[] ids = {55, 56};
|
||||
when(dependencies.mapper.deleteOrderAbnormalRecordByIds(ids)).thenReturn(2);
|
||||
|
||||
service.deleteOrderAbnormalRecordByIds(ids, "admin");
|
||||
|
||||
verify(dependencies.todoTaskService).cancelByBusiness(
|
||||
OrderAbnormalTodoConstants.BUSINESS_TYPE, "55", null, "admin", "订单异常记录已关闭");
|
||||
verify(dependencies.todoTaskService).cancelByBusiness(
|
||||
OrderAbnormalTodoConstants.BUSINESS_TYPE, "56", null, "admin", "订单异常记录已关闭");
|
||||
}
|
||||
|
||||
private static void setField(Object target, String fieldName, Object value) {
|
||||
try {
|
||||
Field field = target.getClass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(target, value);
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Dependencies {
|
||||
private final OrderAbnormalRecordMapper mapper = mock(OrderAbnormalRecordMapper.class);
|
||||
private final PileBasicInfoService pileBasicInfoService = mock(PileBasicInfoService.class);
|
||||
private final PileMerchantInfoService merchantService = mock(PileMerchantInfoService.class);
|
||||
private final TodoTaskAssigneeService assigneeService = mock(TodoTaskAssigneeService.class);
|
||||
private final TodoTaskService todoTaskService = mock(TodoTaskService.class);
|
||||
|
||||
private OrderAbnormalRecordServiceImpl createService() {
|
||||
OrderAbnormalRecordServiceImpl service = new OrderAbnormalRecordServiceImpl();
|
||||
setField(service, "orderAbnormalRecordMapper", mapper);
|
||||
setField(service, "pileBasicInfoService", pileBasicInfoService);
|
||||
setField(service, "pileMerchantInfoService", merchantService);
|
||||
setField(service, "todoTaskAssigneeService", assigneeService);
|
||||
setField(service, "todoTaskService", todoTaskService);
|
||||
return service;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,6 +129,18 @@ class TodoTaskServiceImplTest {
|
||||
verify(mapper, never()).insertTodoTask(any(SysTodoTask.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createTask_shouldAllowOrderAbnormalRoute() {
|
||||
SysTodoTaskMapper mapper = mock(SysTodoTaskMapper.class);
|
||||
TodoTaskServiceImpl service = newService(mapper);
|
||||
TodoTaskCreateCommand command = createCommand();
|
||||
command.setRouteName("AbnormalRecord");
|
||||
|
||||
service.createTask(command);
|
||||
|
||||
verify(mapper).insertTodoTask(any(SysTodoTask.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createTask_shouldRejectNestedRouteParams() {
|
||||
SysTodoTaskMapper mapper = mock(SysTodoTaskMapper.class);
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.jsowell.pile.constant;
|
||||
|
||||
/**
|
||||
* 汇付清分异常待办常量。
|
||||
*/
|
||||
public final class AdapayClearingTodoConstants {
|
||||
public static final String TASK_TYPE = "CLEARING_EXCEPTION";
|
||||
public static final String BUSINESS_TYPE = "ADAPAY_UNSPLIT_RECORD";
|
||||
public static final String ROUTE_NAME = "financeDetail";
|
||||
public static final String HANDLE_FLAG_FAILED = "FAILED";
|
||||
public static final String HANDLE_FLAG_SUCCESS = "SUCCESS";
|
||||
|
||||
private AdapayClearingTodoConstants() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.jsowell.pile.constant;
|
||||
|
||||
/**
|
||||
* 订单异常待办常量。
|
||||
*/
|
||||
public final class OrderAbnormalTodoConstants {
|
||||
public static final String TASK_TYPE = "ORDER_ABNORMAL";
|
||||
public static final String BUSINESS_TYPE = "ORDER_ABNORMAL_RECORD";
|
||||
public static final String ROUTE_NAME = "AbnormalRecord";
|
||||
|
||||
private OrderAbnormalTodoConstants() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.jsowell.pile.service;
|
||||
|
||||
import com.jsowell.pile.domain.AdapayUnsplitRecord;
|
||||
|
||||
/**
|
||||
* 汇付清分状态与待办联动服务。
|
||||
*/
|
||||
public interface AdapayClearingTodoService {
|
||||
void syncUnsplitRecordTodo(AdapayUnsplitRecord record);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ public interface OrderAbnormalRecordService {
|
||||
* @param ids 需要删除的订单异常记录主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteOrderAbnormalRecordByIds(Integer[] ids);
|
||||
public int deleteOrderAbnormalRecordByIds(Integer[] ids, String operatorName);
|
||||
|
||||
/**
|
||||
* 删除订单异常记录信息
|
||||
@@ -57,5 +57,5 @@ public interface OrderAbnormalRecordService {
|
||||
* @param id 订单异常记录主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteOrderAbnormalRecordById(Integer id);
|
||||
public int deleteOrderAbnormalRecordById(Integer id, String operatorName);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
package com.jsowell.pile.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.jsowell.common.util.StringUtils;
|
||||
import com.jsowell.pile.constant.AdapayClearingTodoConstants;
|
||||
import com.jsowell.pile.domain.AdapayUnsplitRecord;
|
||||
import com.jsowell.pile.domain.OrderBasicInfo;
|
||||
import com.jsowell.pile.domain.PileMerchantInfo;
|
||||
import com.jsowell.pile.service.AdapayClearingTodoService;
|
||||
import com.jsowell.pile.service.OrderBasicInfoService;
|
||||
import com.jsowell.pile.service.PileMerchantInfoService;
|
||||
import com.jsowell.system.constant.TodoTaskConstants;
|
||||
import com.jsowell.system.domain.dto.TodoTaskCreateCommand;
|
||||
import com.jsowell.system.service.TodoTaskAssigneeService;
|
||||
import com.jsowell.system.service.TodoTaskService;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 汇付清分失败状态与待办联动服务实现。
|
||||
*/
|
||||
@Service
|
||||
public class AdapayClearingTodoServiceImpl implements AdapayClearingTodoService {
|
||||
private static final Logger log = LoggerFactory.getLogger(AdapayClearingTodoServiceImpl.class);
|
||||
private static final String TODO_OPERATOR = "adapay-clearing";
|
||||
|
||||
@Autowired
|
||||
private OrderBasicInfoService orderBasicInfoService;
|
||||
|
||||
@Autowired
|
||||
private PileMerchantInfoService pileMerchantInfoService;
|
||||
|
||||
@Autowired
|
||||
private TodoTaskAssigneeService todoTaskAssigneeService;
|
||||
|
||||
@Autowired
|
||||
private TodoTaskService todoTaskService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void syncUnsplitRecordTodo(AdapayUnsplitRecord record) {
|
||||
if (record == null || StringUtils.isBlank(record.getPaymentId())) {
|
||||
return;
|
||||
}
|
||||
boolean failed = AdapayClearingTodoConstants.HANDLE_FLAG_FAILED.equals(record.getRefundFlag())
|
||||
|| AdapayClearingTodoConstants.HANDLE_FLAG_FAILED.equals(record.getSplitFlag());
|
||||
boolean succeeded = AdapayClearingTodoConstants.HANDLE_FLAG_SUCCESS.equals(record.getRefundFlag())
|
||||
&& AdapayClearingTodoConstants.HANDLE_FLAG_SUCCESS.equals(record.getSplitFlag());
|
||||
if (!failed && !succeeded) {
|
||||
return;
|
||||
}
|
||||
|
||||
String paymentId = record.getPaymentId().trim();
|
||||
if (succeeded) {
|
||||
todoTaskService.completeByBusinessAsSystem(AdapayClearingTodoConstants.BUSINESS_TYPE,
|
||||
paymentId, null, TODO_OPERATOR);
|
||||
return;
|
||||
}
|
||||
createClearingExceptionTodos(record, paymentId);
|
||||
}
|
||||
|
||||
private void createClearingExceptionTodos(AdapayUnsplitRecord record, String paymentId) {
|
||||
if (StringUtils.isBlank(record.getOrderCode())) {
|
||||
log.warn("清分失败记录缺少订单号,无法创建待办,paymentId={}", paymentId);
|
||||
return;
|
||||
}
|
||||
OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(record.getOrderCode());
|
||||
if (orderInfo == null || StringUtils.isBlank(orderInfo.getMerchantId())) {
|
||||
log.warn("清分失败记录未找到订单运营商,无法创建待办,paymentId={}, orderCode={}",
|
||||
paymentId, record.getOrderCode());
|
||||
return;
|
||||
}
|
||||
|
||||
PileMerchantInfo merchantInfo;
|
||||
try {
|
||||
merchantInfo = pileMerchantInfoService.selectPileMerchantInfoById(
|
||||
Long.parseLong(orderInfo.getMerchantId()));
|
||||
} catch (NumberFormatException exception) {
|
||||
log.warn("清分失败记录运营商 ID 非法,无法创建待办,paymentId={}, merchantId={}",
|
||||
paymentId, orderInfo.getMerchantId());
|
||||
return;
|
||||
}
|
||||
if (merchantInfo == null || StringUtils.isBlank(merchantInfo.getDeptId())) {
|
||||
log.warn("清分失败记录运营商未配置部门,无法创建待办,paymentId={}, merchantId={}",
|
||||
paymentId, orderInfo.getMerchantId());
|
||||
return;
|
||||
}
|
||||
|
||||
Long deptId;
|
||||
try {
|
||||
deptId = Long.parseLong(merchantInfo.getDeptId());
|
||||
} catch (NumberFormatException exception) {
|
||||
log.warn("清分失败记录运营商部门 ID 非法,无法创建待办,paymentId={}, deptId={}",
|
||||
paymentId, merchantInfo.getDeptId());
|
||||
return;
|
||||
}
|
||||
List<Long> assigneeUserIds = todoTaskAssigneeService.findActiveOperatorAdminUserIdsByDeptTree(deptId);
|
||||
if (CollectionUtils.isEmpty(assigneeUserIds)) {
|
||||
log.warn("清分失败记录运营商部门下没有正常管理员,无法创建待办,paymentId={}, deptId={}",
|
||||
paymentId, deptId);
|
||||
return;
|
||||
}
|
||||
|
||||
String summary = buildSummary(record);
|
||||
String content = "退款处理状态:" + displayFlag(record.getRefundFlag())
|
||||
+ ",分账处理状态:" + displayFlag(record.getSplitFlag());
|
||||
for (Long assigneeUserId : assigneeUserIds) {
|
||||
todoTaskService.createTask(TodoTaskCreateCommand.builder()
|
||||
.taskType(AdapayClearingTodoConstants.TASK_TYPE)
|
||||
.title("清分异常待处理")
|
||||
.summary(summary)
|
||||
.content(content)
|
||||
.businessType(AdapayClearingTodoConstants.BUSINESS_TYPE)
|
||||
.businessId(paymentId)
|
||||
.routeName(AdapayClearingTodoConstants.ROUTE_NAME)
|
||||
.routeParams(buildRouteParams(record, orderInfo.getMerchantId()))
|
||||
.assigneeUserId(assigneeUserId)
|
||||
.assigneeMerchantId(orderInfo.getMerchantId())
|
||||
.priority(TodoTaskConstants.PRIORITY_IMPORTANT)
|
||||
.idempotentKey(AdapayClearingTodoConstants.TASK_TYPE + ":"
|
||||
+ AdapayClearingTodoConstants.BUSINESS_TYPE + ":" + paymentId + ":" + assigneeUserId)
|
||||
.createBy(TODO_OPERATOR)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
private String buildSummary(AdapayUnsplitRecord record) {
|
||||
String summary = "订单清分或退款处理失败,需要人工核对,订单号:" + record.getOrderCode().trim();
|
||||
if (AdapayClearingTodoConstants.HANDLE_FLAG_FAILED.equals(record.getRefundFlag())) {
|
||||
summary += ",退款状态失败";
|
||||
}
|
||||
if (AdapayClearingTodoConstants.HANDLE_FLAG_FAILED.equals(record.getSplitFlag())) {
|
||||
summary += ",分账状态失败";
|
||||
}
|
||||
return summary.length() <= 500 ? summary : summary.substring(0, 500);
|
||||
}
|
||||
|
||||
private String buildRouteParams(AdapayUnsplitRecord record, String merchantId) {
|
||||
Map<String, Object> query = new HashMap<>();
|
||||
query.put("merchantId", merchantId);
|
||||
query.put("orderCode", record.getOrderCode());
|
||||
query.put("paymentId", record.getPaymentId());
|
||||
Map<String, Object> routeParams = new HashMap<>();
|
||||
routeParams.put("query", query);
|
||||
return JSON.toJSONString(routeParams);
|
||||
}
|
||||
|
||||
private String displayFlag(String flag) {
|
||||
return StringUtils.isBlank(flag) ? "未确认" : flag;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,29 @@
|
||||
package com.jsowell.pile.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.jsowell.common.util.StringUtils;
|
||||
import com.jsowell.pile.constant.OrderAbnormalTodoConstants;
|
||||
import com.jsowell.pile.domain.OrderAbnormalRecord;
|
||||
import com.jsowell.pile.domain.PileMerchantInfo;
|
||||
import com.jsowell.pile.mapper.OrderAbnormalRecordMapper;
|
||||
import com.jsowell.pile.service.OrderAbnormalRecordService;
|
||||
import com.jsowell.pile.service.PileBasicInfoService;
|
||||
import com.jsowell.pile.service.PileMerchantInfoService;
|
||||
import com.jsowell.pile.vo.base.PileInfoVO;
|
||||
import com.jsowell.system.constant.TodoTaskConstants;
|
||||
import com.jsowell.system.domain.dto.TodoTaskCreateCommand;
|
||||
import com.jsowell.system.service.TodoTaskAssigneeService;
|
||||
import com.jsowell.system.service.TodoTaskService;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 订单异常记录Service业务层处理
|
||||
@@ -16,9 +33,25 @@ import java.util.List;
|
||||
*/
|
||||
@Service
|
||||
public class OrderAbnormalRecordServiceImpl implements OrderAbnormalRecordService {
|
||||
private static final Logger log = LoggerFactory.getLogger(OrderAbnormalRecordServiceImpl.class);
|
||||
private static final String TODO_OPERATOR = "order-abnormal-system";
|
||||
private static final String CANCEL_REASON = "订单异常记录已关闭";
|
||||
|
||||
@Autowired
|
||||
private OrderAbnormalRecordMapper orderAbnormalRecordMapper;
|
||||
|
||||
@Autowired
|
||||
private PileBasicInfoService pileBasicInfoService;
|
||||
|
||||
@Autowired
|
||||
private PileMerchantInfoService pileMerchantInfoService;
|
||||
|
||||
@Autowired
|
||||
private TodoTaskAssigneeService todoTaskAssigneeService;
|
||||
|
||||
@Autowired
|
||||
private TodoTaskService todoTaskService;
|
||||
|
||||
/**
|
||||
* 查询订单异常记录
|
||||
*
|
||||
@@ -48,9 +81,13 @@ public class OrderAbnormalRecordServiceImpl implements OrderAbnormalRecordServic
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int insertOrderAbnormalRecord(OrderAbnormalRecord orderAbnormalRecord) {
|
||||
// orderAbnormalRecord.setCreateTime(DateUtils.getNowDate());
|
||||
return orderAbnormalRecordMapper.insertOrderAbnormalRecord(orderAbnormalRecord);
|
||||
int rows = orderAbnormalRecordMapper.insertOrderAbnormalRecord(orderAbnormalRecord);
|
||||
if (rows > 0) {
|
||||
createOrderAbnormalTodo(orderAbnormalRecord);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,8 +108,15 @@ public class OrderAbnormalRecordServiceImpl implements OrderAbnormalRecordServic
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteOrderAbnormalRecordByIds(Integer[] ids) {
|
||||
return orderAbnormalRecordMapper.deleteOrderAbnormalRecordByIds(ids);
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int deleteOrderAbnormalRecordByIds(Integer[] ids, String operatorName) {
|
||||
int rows = orderAbnormalRecordMapper.deleteOrderAbnormalRecordByIds(ids);
|
||||
if (rows > 0 && ids != null) {
|
||||
for (Integer id : ids) {
|
||||
cancelOrderAbnormalTodo(id, operatorName);
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,7 +126,123 @@ public class OrderAbnormalRecordServiceImpl implements OrderAbnormalRecordServic
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteOrderAbnormalRecordById(Integer id) {
|
||||
return orderAbnormalRecordMapper.deleteOrderAbnormalRecordById(id);
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int deleteOrderAbnormalRecordById(Integer id, String operatorName) {
|
||||
int rows = orderAbnormalRecordMapper.deleteOrderAbnormalRecordById(id);
|
||||
if (rows > 0) {
|
||||
cancelOrderAbnormalTodo(id, operatorName);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
private void createOrderAbnormalTodo(OrderAbnormalRecord record) {
|
||||
if (record == null || record.getId() == null || StringUtils.isBlank(record.getPileSn())) {
|
||||
log.warn("订单异常记录缺少主键或桩号,无法创建待办,recordId={}, pileSn={}",
|
||||
record == null ? null : record.getId(), record == null ? null : record.getPileSn());
|
||||
return;
|
||||
}
|
||||
|
||||
PileInfoVO pileInfo = pileBasicInfoService.selectPileInfoBySn(record.getPileSn());
|
||||
if (pileInfo == null || StringUtils.isBlank(pileInfo.getMerchantId())) {
|
||||
log.warn("订单异常记录未找到桩所属运营商,无法创建待办,recordId={}, pileSn={}",
|
||||
record.getId(), record.getPileSn());
|
||||
return;
|
||||
}
|
||||
|
||||
Long merchantId;
|
||||
try {
|
||||
merchantId = Long.parseLong(pileInfo.getMerchantId());
|
||||
} catch (NumberFormatException exception) {
|
||||
log.warn("订单异常记录运营商 ID 非法,无法创建待办,recordId={}, merchantId={}",
|
||||
record.getId(), pileInfo.getMerchantId());
|
||||
return;
|
||||
}
|
||||
PileMerchantInfo merchantInfo = pileMerchantInfoService.selectPileMerchantInfoById(merchantId);
|
||||
if (merchantInfo == null || StringUtils.isBlank(merchantInfo.getDeptId())) {
|
||||
log.warn("订单异常记录运营商未配置部门,无法创建待办,recordId={}, merchantId={}",
|
||||
record.getId(), pileInfo.getMerchantId());
|
||||
return;
|
||||
}
|
||||
|
||||
Long deptId;
|
||||
try {
|
||||
deptId = Long.parseLong(merchantInfo.getDeptId());
|
||||
} catch (NumberFormatException exception) {
|
||||
log.warn("订单异常记录运营商部门 ID 非法,无法创建待办,recordId={}, deptId={}",
|
||||
record.getId(), merchantInfo.getDeptId());
|
||||
return;
|
||||
}
|
||||
List<Long> assigneeUserIds = todoTaskAssigneeService.findActiveOperatorAdminUserIdsByDeptTree(deptId);
|
||||
if (CollectionUtils.isEmpty(assigneeUserIds)) {
|
||||
log.warn("订单异常记录运营商部门下没有正常管理员,无法创建待办,recordId={}, deptId={}",
|
||||
record.getId(), deptId);
|
||||
return;
|
||||
}
|
||||
|
||||
String businessId = String.valueOf(record.getId());
|
||||
String summary = buildSummary(record);
|
||||
String content = StringUtils.isBlank(record.getStopReasonMsg())
|
||||
? null : truncate(record.getStopReasonMsg(), 20000);
|
||||
for (Long assigneeUserId : assigneeUserIds) {
|
||||
todoTaskService.createTask(TodoTaskCreateCommand.builder()
|
||||
.taskType(OrderAbnormalTodoConstants.TASK_TYPE)
|
||||
.title("订单异常待处理")
|
||||
.summary(summary)
|
||||
.content(content)
|
||||
.businessType(OrderAbnormalTodoConstants.BUSINESS_TYPE)
|
||||
.businessId(businessId)
|
||||
.routeName(OrderAbnormalTodoConstants.ROUTE_NAME)
|
||||
.routeParams(buildRouteParams(record))
|
||||
.assigneeUserId(assigneeUserId)
|
||||
.assigneeMerchantId(pileInfo.getMerchantId())
|
||||
.priority(TodoTaskConstants.PRIORITY_IMPORTANT)
|
||||
.idempotentKey(OrderAbnormalTodoConstants.TASK_TYPE + ":"
|
||||
+ OrderAbnormalTodoConstants.BUSINESS_TYPE + ":" + businessId + ":" + assigneeUserId)
|
||||
.createBy(TODO_OPERATOR)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelOrderAbnormalTodo(Integer id, String operatorName) {
|
||||
if (id == null) {
|
||||
return;
|
||||
}
|
||||
todoTaskService.cancelByBusiness(OrderAbnormalTodoConstants.BUSINESS_TYPE, String.valueOf(id), null,
|
||||
normalizeOperator(operatorName), CANCEL_REASON);
|
||||
}
|
||||
|
||||
private String buildSummary(OrderAbnormalRecord record) {
|
||||
String summary = "发现需要人工核对的异常充电订单";
|
||||
if (StringUtils.isNotBlank(record.getOrderCode())) {
|
||||
summary += ",交易流水号:" + record.getOrderCode().trim();
|
||||
}
|
||||
if (StringUtils.isNotBlank(record.getStopReasonMsg())) {
|
||||
summary += ",停止原因:" + record.getStopReasonMsg().trim();
|
||||
}
|
||||
return truncate(summary, 500);
|
||||
}
|
||||
|
||||
private String buildRouteParams(OrderAbnormalRecord record) {
|
||||
Map<String, Object> query = new HashMap<>();
|
||||
if (StringUtils.isNotBlank(record.getOrderCode())) {
|
||||
query.put("orderCode", record.getOrderCode().trim());
|
||||
}
|
||||
if (StringUtils.isNotBlank(record.getPileSn())) {
|
||||
query.put("pileSn", record.getPileSn().trim());
|
||||
}
|
||||
Map<String, Object> routeParams = new HashMap<>();
|
||||
routeParams.put("query", query);
|
||||
return JSON.toJSONString(routeParams);
|
||||
}
|
||||
|
||||
private String truncate(String value, int maxLength) {
|
||||
if (value == null || value.length() <= maxLength) {
|
||||
return value;
|
||||
}
|
||||
return value.substring(0, maxLength);
|
||||
}
|
||||
|
||||
private String normalizeOperator(String operatorName) {
|
||||
return StringUtils.isBlank(operatorName) ? TODO_OPERATOR : operatorName.trim();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3386,6 +3386,7 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService {
|
||||
public void saveAbnormalOrder(TransactionRecordsData data) {
|
||||
OrderAbnormalRecord record = new OrderAbnormalRecord();
|
||||
BeanUtils.copyBeanProp(record, data);
|
||||
record.setOrderCode(data.getTransactionCode());
|
||||
orderAbnormalRecordService.insertOrderAbnormalRecord(record);
|
||||
|
||||
// 保存到订单主表
|
||||
|
||||
@@ -2,10 +2,13 @@ package com.jsowell.web.controller.pile;
|
||||
|
||||
import com.jsowell.pile.domain.AdapayUnsplitRecord;
|
||||
import com.jsowell.pile.mapper.AdapayUnsplitRecordMapper;
|
||||
import com.jsowell.pile.service.AdapayClearingTodoService;
|
||||
import com.jsowell.pile.service.AdapayUnsplitRecordService;
|
||||
import com.jsowell.pile.vo.AdapayUnsplitRecordVO;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -15,6 +18,9 @@ public class AdapayUnsplitRecordServiceImpl implements AdapayUnsplitRecordServic
|
||||
@Autowired
|
||||
private AdapayUnsplitRecordMapper adapayUnsplitRecordMapper;
|
||||
|
||||
@Autowired
|
||||
private AdapayClearingTodoService adapayClearingTodoService;
|
||||
|
||||
@Override
|
||||
public int deleteByPrimaryKey(Integer id) {
|
||||
return adapayUnsplitRecordMapper.deleteByPrimaryKey(id);
|
||||
@@ -31,8 +37,15 @@ public class AdapayUnsplitRecordServiceImpl implements AdapayUnsplitRecordServic
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int insertOrUpdateSelective(AdapayUnsplitRecord record) {
|
||||
return adapayUnsplitRecordMapper.insertOrUpdateSelective(record);
|
||||
int rows = adapayUnsplitRecordMapper.insertOrUpdateSelective(record);
|
||||
if (rows > 0 && record != null
|
||||
&& (record.getRefundFlag() != null || record.getSplitFlag() != null)) {
|
||||
AdapayUnsplitRecord currentRecord = loadCurrentRecord(record);
|
||||
adapayClearingTodoService.syncUnsplitRecordTodo(currentRecord);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,4 +111,16 @@ public class AdapayUnsplitRecordServiceImpl implements AdapayUnsplitRecordServic
|
||||
return adapayUnsplitRecordMapper.queryFailedList(startTime, endTime);
|
||||
}
|
||||
|
||||
private AdapayUnsplitRecord loadCurrentRecord(AdapayUnsplitRecord record) {
|
||||
if (record.getId() != null) {
|
||||
return adapayUnsplitRecordMapper.selectByPrimaryKey(record.getId());
|
||||
}
|
||||
if (record.getPaymentId() == null) {
|
||||
return record;
|
||||
}
|
||||
List<AdapayUnsplitRecord> records = adapayUnsplitRecordMapper.selectByPaymentIds(
|
||||
Collections.singletonList(record.getPaymentId()));
|
||||
return CollectionUtils.isEmpty(records) ? record : records.get(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.jsowell.common.util.StringUtils;
|
||||
import com.jsowell.pile.domain.AdapayUnsplitRecord;
|
||||
import com.jsowell.pile.domain.OrderBasicInfo;
|
||||
import com.jsowell.pile.dto.ApplyRefundDTO;
|
||||
import com.jsowell.pile.service.AdapayClearingTodoService;
|
||||
import com.jsowell.pile.service.AdapayUnsplitRecordService;
|
||||
import com.jsowell.pile.service.OrderBasicInfoService;
|
||||
import com.jsowell.pile.vo.AdapayUnsplitRecordVO;
|
||||
@@ -65,6 +66,9 @@ public class AdapayUnsplitRecordHandleServiceImpl implements AdapayUnsplitRecord
|
||||
@Autowired
|
||||
private AdapayUnsplitRecordService adapayUnsplitRecordService;
|
||||
|
||||
@Autowired
|
||||
private AdapayClearingTodoService adapayClearingTodoService;
|
||||
|
||||
@Override
|
||||
public void processUnSettledOrder() {
|
||||
for (int i = 0; i < 35; i++) {
|
||||
@@ -377,9 +381,10 @@ public class AdapayUnsplitRecordHandleServiceImpl implements AdapayUnsplitRecord
|
||||
+ "expectedSplitAmount:{}, confirmedSplitAmount:{}, remainingSplitAmount:{}, refundFlag:{}, splitFlag:{}",
|
||||
paymentId, orderCode, dueRefundAmount, refundResult.refundedAmount,
|
||||
expectedSplitAmount, splitResult.confirmedSplitAmount, remaining, refundFlag, splitFlag);
|
||||
return true;
|
||||
} else {
|
||||
adapayClearingTodoService.syncUnsplitRecordTodo(record);
|
||||
}
|
||||
return false;
|
||||
return needUpdate;
|
||||
}
|
||||
|
||||
private RefundAmountResult queryRefundAmountFromAdapay(String paymentId, String wechatAppId) {
|
||||
|
||||
@@ -33,9 +33,9 @@ public class TodoTaskServiceImpl implements TodoTaskService {
|
||||
private static final String SYSTEM_OPERATOR = "system";
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
private static final Set<String> DEFAULT_ROUTE_WHITELIST = new HashSet<>(
|
||||
Arrays.asList("invoiceDetail", "financeDetail", "accountUserInfo"));
|
||||
Arrays.asList("invoiceDetail", "financeDetail", "accountUserInfo", "AbnormalRecord"));
|
||||
|
||||
@Value("${todo.route-whitelist:invoiceDetail,financeDetail,accountUserInfo}")
|
||||
@Value("${todo.route-whitelist:invoiceDetail,financeDetail,accountUserInfo,AbnormalRecord}")
|
||||
private String routeWhitelist;
|
||||
|
||||
@Autowired
|
||||
|
||||
Reference in New Issue
Block a user