mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-07-23 15:41:17 +08:00
接入运营商提现开票待办闭环
This commit is contained in:
33
docs/sql/clearing_withdraw_invoice.sql
Normal file
33
docs/sql/clearing_withdraw_invoice.sql
Normal file
@@ -0,0 +1,33 @@
|
||||
-- 运营商提现向平台开票信息表
|
||||
-- 执行前请确认 sys_todo_task、待办菜单权限 SQL 已部署。
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `clearing_withdraw_invoice` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`withdraw_code` varchar(64) NOT NULL COMMENT '提现编号',
|
||||
`merchant_id` varchar(64) NOT NULL COMMENT '运营商ID',
|
||||
`invoice_status` varchar(20) NOT NULL DEFAULT 'PENDING' COMMENT '状态:PENDING待提交、SUBMITTED已提交、CLOSED已关闭',
|
||||
`invoice_number` varchar(100) DEFAULT NULL COMMENT '发票号码',
|
||||
`voucher_url` varchar(1000) DEFAULT NULL COMMENT '发票凭证地址',
|
||||
`submitted_by` bigint DEFAULT NULL COMMENT '提交人用户ID',
|
||||
`submitted_name` varchar(64) DEFAULT NULL COMMENT '提交人账号',
|
||||
`submitted_time` datetime DEFAULT NULL COMMENT '提交时间',
|
||||
`closed_by` bigint DEFAULT NULL COMMENT '关闭人用户ID',
|
||||
`closed_name` varchar(64) DEFAULT NULL COMMENT '关闭人账号',
|
||||
`closed_time` datetime DEFAULT NULL COMMENT '关闭时间',
|
||||
`close_reason` varchar(500) DEFAULT NULL COMMENT '关闭原因',
|
||||
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
`del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0正常 1删除)',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_withdraw_invoice_code` (`withdraw_code`),
|
||||
KEY `idx_withdraw_invoice_merchant_status` (`merchant_id`, `invoice_status`, `create_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='运营商提现向平台开票信息表';
|
||||
|
||||
-- 完成权限分配给运营商管理员角色,取消权限只分配给平台任务关闭角色。
|
||||
-- INSERT INTO sys_role_menu (role_id, menu_id)
|
||||
-- SELECT <运营商管理员角色ID>, menu_id FROM sys_menu WHERE perms = 'system:todo:complete';
|
||||
-- INSERT INTO sys_role_menu (role_id, menu_id)
|
||||
-- SELECT <平台任务关闭角色ID>, menu_id FROM sys_menu WHERE perms = 'system:todo:cancel';
|
||||
@@ -124,6 +124,9 @@ public class OrderService {
|
||||
@Autowired
|
||||
private ClearingWithdrawInfoService clearingWithdrawInfoService;
|
||||
|
||||
@Autowired
|
||||
private MerchantWithdrawInvoiceService merchantWithdrawInvoiceService;
|
||||
|
||||
@Autowired
|
||||
private MemberAdapayRecordService memberAdapayRecordService;
|
||||
|
||||
@@ -1464,22 +1467,7 @@ public class OrderService {
|
||||
log.info("取现成功 data:{}", JSON.toJSONString(data));
|
||||
JSONObject jsonObject = JSON.parseObject(data);
|
||||
String withdrawCode = jsonObject.getString("id");
|
||||
// 通过取现id查询取现数据
|
||||
ClearingWithdrawInfo clearingWithdrawInfo = clearingWithdrawInfoService.selectByWithdrawCode(withdrawCode);
|
||||
if (clearingWithdrawInfo != null) {
|
||||
clearingWithdrawInfo.setWithdrawStatus(Constants.ONE);
|
||||
clearingWithdrawInfo.setUpdateTime(DateUtils.getNowDate());
|
||||
clearingWithdrawInfoService.updateByPrimaryKeySelective(clearingWithdrawInfo);
|
||||
}
|
||||
|
||||
// 清分账单数据更新
|
||||
List<ClearingBillInfo> clearingBillInfos = clearingBillInfoService.selectByWithdrawCode(withdrawCode);
|
||||
if (CollectionUtils.isNotEmpty(clearingBillInfos)) {
|
||||
for (ClearingBillInfo clearingBillInfo : clearingBillInfos) {
|
||||
clearingBillInfo.setBillStatus("4");
|
||||
}
|
||||
clearingBillInfoService.updateBatchSelective(clearingBillInfos);
|
||||
}
|
||||
merchantWithdrawInvoiceService.handleWithdrawSucceeded(withdrawCode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.jsowell.web.controller.pile;
|
||||
|
||||
import com.jsowell.common.annotation.Log;
|
||||
import com.jsowell.common.core.controller.BaseController;
|
||||
import com.jsowell.common.core.domain.AjaxResult;
|
||||
import com.jsowell.common.enums.BusinessType;
|
||||
import com.jsowell.pile.dto.WithdrawInvoiceCloseRequest;
|
||||
import com.jsowell.pile.dto.WithdrawInvoiceSubmitRequest;
|
||||
import com.jsowell.pile.service.MerchantWithdrawInvoiceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 运营商提现向平台开票接口。
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pile/withdrawInvoice")
|
||||
public class MerchantWithdrawInvoiceController extends BaseController {
|
||||
@Autowired
|
||||
private MerchantWithdrawInvoiceService merchantWithdrawInvoiceService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('system:todo:query')")
|
||||
@GetMapping("/{withdrawCode}")
|
||||
public AjaxResult getInfo(@PathVariable String withdrawCode, @RequestParam Long todoId) {
|
||||
return AjaxResult.success(merchantWithdrawInvoiceService.getForAssignee(
|
||||
withdrawCode, todoId, getUserId()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('system:todo:complete')")
|
||||
@Log(title = "运营商提现开票", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/{withdrawCode}/submit")
|
||||
public AjaxResult submit(@PathVariable String withdrawCode,
|
||||
@Validated @RequestBody WithdrawInvoiceSubmitRequest request) {
|
||||
return toAjax(merchantWithdrawInvoiceService.submit(withdrawCode, request,
|
||||
getUserId(), getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('system:todo:cancel')")
|
||||
@Log(title = "运营商提现开票", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/{withdrawCode}/close")
|
||||
public AjaxResult close(@PathVariable String withdrawCode,
|
||||
@Validated @RequestBody WithdrawInvoiceCloseRequest request) {
|
||||
return toAjax(merchantWithdrawInvoiceService.close(withdrawCode, request.getReason(),
|
||||
getUserId(), getUsername()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package com.jsowell.pile.service;
|
||||
|
||||
import com.jsowell.common.constant.Constants;
|
||||
import com.jsowell.pile.constant.MerchantWithdrawInvoiceConstants;
|
||||
import com.jsowell.pile.domain.ClearingBillInfo;
|
||||
import com.jsowell.pile.domain.ClearingWithdrawInfo;
|
||||
import com.jsowell.pile.domain.ClearingWithdrawInvoice;
|
||||
import com.jsowell.pile.domain.PileMerchantInfo;
|
||||
import com.jsowell.pile.dto.WithdrawInvoiceSubmitRequest;
|
||||
import com.jsowell.pile.mapper.ClearingWithdrawInfoMapper;
|
||||
import com.jsowell.pile.mapper.ClearingWithdrawInvoiceMapper;
|
||||
import com.jsowell.pile.service.impl.MerchantWithdrawInvoiceServiceImpl;
|
||||
import com.jsowell.system.domain.SysTodoTask;
|
||||
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 java.util.Collections;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class MerchantWithdrawInvoiceServiceImplTest {
|
||||
@Test
|
||||
void handleSucceeded_shouldUpdateWithdrawAndCreateAdminTodos() {
|
||||
Dependencies dependencies = new Dependencies();
|
||||
MerchantWithdrawInvoiceServiceImpl service = dependencies.createService();
|
||||
ClearingWithdrawInfo withdrawInfo = withdrawInfo(Constants.ZERO);
|
||||
when(dependencies.withdrawInfoMapper.selectByWithdrawCode("W100")).thenReturn(withdrawInfo);
|
||||
when(dependencies.invoiceMapper.selectByWithdrawCode("W100")).thenReturn(null);
|
||||
when(dependencies.invoiceMapper.insertSelective(any(ClearingWithdrawInvoice.class))).thenReturn(1);
|
||||
ClearingBillInfo billInfo = new ClearingBillInfo();
|
||||
billInfo.setId(5);
|
||||
when(dependencies.clearingBillInfoService.selectByWithdrawCode("W100"))
|
||||
.thenReturn(Collections.singletonList(billInfo));
|
||||
PileMerchantInfo merchantInfo = new PileMerchantInfo();
|
||||
merchantInfo.setDeptId("200");
|
||||
when(dependencies.pileMerchantInfoService.selectPileMerchantInfoById(100L)).thenReturn(merchantInfo);
|
||||
when(dependencies.assigneeService.findActiveOperatorAdminUserIdsByDeptTree(200L))
|
||||
.thenReturn(Arrays.asList(8L, 9L));
|
||||
|
||||
service.handleWithdrawSucceeded("W100");
|
||||
|
||||
verify(dependencies.withdrawInfoMapper).updateByPrimaryKeySelective(withdrawInfo);
|
||||
assertEquals(Constants.ONE, withdrawInfo.getWithdrawStatus());
|
||||
assertEquals("4", billInfo.getBillStatus());
|
||||
verify(dependencies.clearingBillInfoService).updateBatchSelective(Collections.singletonList(billInfo));
|
||||
ArgumentCaptor<TodoTaskCreateCommand> captor = ArgumentCaptor.forClass(TodoTaskCreateCommand.class);
|
||||
verify(dependencies.todoTaskService, times(2)).createTask(captor.capture());
|
||||
assertEquals(Arrays.asList(8L, 9L), Arrays.asList(
|
||||
captor.getAllValues().get(0).getAssigneeUserId(),
|
||||
captor.getAllValues().get(1).getAssigneeUserId()));
|
||||
assertEquals(MerchantWithdrawInvoiceConstants.TASK_TYPE, captor.getValue().getTaskType());
|
||||
assertEquals(MerchantWithdrawInvoiceConstants.BUSINESS_TYPE, captor.getValue().getBusinessType());
|
||||
assertEquals("financeDetail", captor.getValue().getRouteName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void handleSucceeded_shouldNotRecreateTodoAfterInvoiceSubmitted() {
|
||||
Dependencies dependencies = new Dependencies();
|
||||
MerchantWithdrawInvoiceServiceImpl service = dependencies.createService();
|
||||
when(dependencies.withdrawInfoMapper.selectByWithdrawCode("W100"))
|
||||
.thenReturn(withdrawInfo(Constants.ONE));
|
||||
ClearingWithdrawInvoice invoice = invoice(MerchantWithdrawInvoiceConstants.STATUS_SUBMITTED);
|
||||
when(dependencies.invoiceMapper.selectByWithdrawCode("W100")).thenReturn(invoice);
|
||||
when(dependencies.clearingBillInfoService.selectByWithdrawCode("W100"))
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
service.handleWithdrawSucceeded("W100");
|
||||
|
||||
verify(dependencies.todoTaskService, never()).createTask(any(TodoTaskCreateCommand.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void submit_shouldCompleteAllBusinessTodos() {
|
||||
Dependencies dependencies = new Dependencies();
|
||||
MerchantWithdrawInvoiceServiceImpl service = dependencies.createService();
|
||||
when(dependencies.todoTaskService.getForAssignee(20L, 8L)).thenReturn(todoTask());
|
||||
when(dependencies.invoiceMapper.selectByWithdrawCode("W100"))
|
||||
.thenReturn(invoice(MerchantWithdrawInvoiceConstants.STATUS_PENDING));
|
||||
when(dependencies.invoiceMapper.markSubmitted(any(ClearingWithdrawInvoice.class))).thenReturn(1);
|
||||
WithdrawInvoiceSubmitRequest request = new WithdrawInvoiceSubmitRequest();
|
||||
request.setTodoId(20L);
|
||||
request.setInvoiceNumber("INV-100");
|
||||
request.setVoucherUrl("/profile/upload/invoice.pdf");
|
||||
|
||||
assertTrue(service.submit("W100", request, 8L, "operator"));
|
||||
|
||||
verify(dependencies.todoTaskService).completeByBusiness(
|
||||
MerchantWithdrawInvoiceConstants.BUSINESS_TYPE, "W100", null, 8L, "operator");
|
||||
}
|
||||
|
||||
@Test
|
||||
void close_shouldCancelAllBusinessTodos() {
|
||||
Dependencies dependencies = new Dependencies();
|
||||
MerchantWithdrawInvoiceServiceImpl service = dependencies.createService();
|
||||
when(dependencies.invoiceMapper.selectByWithdrawCode("W100"))
|
||||
.thenReturn(invoice(MerchantWithdrawInvoiceConstants.STATUS_PENDING));
|
||||
when(dependencies.invoiceMapper.markClosed(any(ClearingWithdrawInvoice.class))).thenReturn(1);
|
||||
|
||||
assertTrue(service.close("W100", "无需开票", 1L, "admin"));
|
||||
|
||||
verify(dependencies.todoTaskService).cancelByBusiness(
|
||||
MerchantWithdrawInvoiceConstants.BUSINESS_TYPE, "W100", null, "admin", "无需开票");
|
||||
}
|
||||
|
||||
private static ClearingWithdrawInfo withdrawInfo(String status) {
|
||||
ClearingWithdrawInfo withdrawInfo = new ClearingWithdrawInfo();
|
||||
withdrawInfo.setId(1);
|
||||
withdrawInfo.setMerchantId("100");
|
||||
withdrawInfo.setWithdrawCode("W100");
|
||||
withdrawInfo.setWithdrawStatus(status);
|
||||
return withdrawInfo;
|
||||
}
|
||||
|
||||
private static ClearingWithdrawInvoice invoice(String status) {
|
||||
ClearingWithdrawInvoice invoice = new ClearingWithdrawInvoice();
|
||||
invoice.setId(10L);
|
||||
invoice.setMerchantId("100");
|
||||
invoice.setWithdrawCode("W100");
|
||||
invoice.setInvoiceStatus(status);
|
||||
return invoice;
|
||||
}
|
||||
|
||||
private static SysTodoTask todoTask() {
|
||||
SysTodoTask task = new SysTodoTask();
|
||||
task.setTodoId(20L);
|
||||
task.setTaskType(MerchantWithdrawInvoiceConstants.TASK_TYPE);
|
||||
task.setBusinessType(MerchantWithdrawInvoiceConstants.BUSINESS_TYPE);
|
||||
task.setBusinessId("W100");
|
||||
task.setTaskStatus("PENDING");
|
||||
return task;
|
||||
}
|
||||
|
||||
private static void setField(Object target, String fieldName, Object value) {
|
||||
try {
|
||||
Field field = MerchantWithdrawInvoiceServiceImpl.class.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(target, value);
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Dependencies {
|
||||
private final ClearingWithdrawInfoMapper withdrawInfoMapper = mock(ClearingWithdrawInfoMapper.class);
|
||||
private final ClearingWithdrawInvoiceMapper invoiceMapper = mock(ClearingWithdrawInvoiceMapper.class);
|
||||
private final ClearingBillInfoService clearingBillInfoService = mock(ClearingBillInfoService.class);
|
||||
private final PileMerchantInfoService pileMerchantInfoService = mock(PileMerchantInfoService.class);
|
||||
private final TodoTaskAssigneeService assigneeService = mock(TodoTaskAssigneeService.class);
|
||||
private final TodoTaskService todoTaskService = mock(TodoTaskService.class);
|
||||
|
||||
private MerchantWithdrawInvoiceServiceImpl createService() {
|
||||
MerchantWithdrawInvoiceServiceImpl service = new MerchantWithdrawInvoiceServiceImpl();
|
||||
setField(service, "clearingWithdrawInfoMapper", withdrawInfoMapper);
|
||||
setField(service, "clearingWithdrawInvoiceMapper", invoiceMapper);
|
||||
setField(service, "clearingBillInfoService", clearingBillInfoService);
|
||||
setField(service, "pileMerchantInfoService", pileMerchantInfoService);
|
||||
setField(service, "todoTaskAssigneeService", assigneeService);
|
||||
setField(service, "todoTaskService", todoTaskService);
|
||||
return service;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.jsowell.web.controller.pile;
|
||||
|
||||
import com.jsowell.common.core.domain.AjaxResult;
|
||||
import com.jsowell.pile.dto.WithdrawInvoiceSubmitRequest;
|
||||
import com.jsowell.pile.service.MerchantWithdrawInvoiceService;
|
||||
import com.jsowell.pile.vo.web.MerchantWithdrawInvoiceVO;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class MerchantWithdrawInvoiceControllerTest {
|
||||
@Test
|
||||
void getInfo_shouldUseCurrentLoginUser() {
|
||||
MerchantWithdrawInvoiceService service = mock(MerchantWithdrawInvoiceService.class);
|
||||
TestController controller = newController(service, 8L, "operator");
|
||||
MerchantWithdrawInvoiceVO view = new MerchantWithdrawInvoiceVO();
|
||||
when(service.getForAssignee("W100", 20L, 8L)).thenReturn(view);
|
||||
|
||||
AjaxResult result = controller.getInfo("W100", 20L);
|
||||
|
||||
assertSame(view, result.get(AjaxResult.DATA_TAG));
|
||||
verify(service).getForAssignee("W100", 20L, 8L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void submit_shouldPassCurrentUserAndOperator() {
|
||||
MerchantWithdrawInvoiceService service = mock(MerchantWithdrawInvoiceService.class);
|
||||
TestController controller = newController(service, 8L, "operator");
|
||||
WithdrawInvoiceSubmitRequest request = new WithdrawInvoiceSubmitRequest();
|
||||
request.setTodoId(20L);
|
||||
request.setInvoiceNumber("INV-100");
|
||||
request.setVoucherUrl("/invoice.pdf");
|
||||
when(service.submit("W100", request, 8L, "operator")).thenReturn(true);
|
||||
|
||||
controller.submit("W100", request);
|
||||
|
||||
verify(service).submit("W100", request, 8L, "operator");
|
||||
}
|
||||
|
||||
private static TestController newController(MerchantWithdrawInvoiceService service,
|
||||
Long userId, String username) {
|
||||
TestController controller = new TestController(userId, username);
|
||||
try {
|
||||
Field field = MerchantWithdrawInvoiceController.class
|
||||
.getDeclaredField("merchantWithdrawInvoiceService");
|
||||
field.setAccessible(true);
|
||||
field.set(controller, service);
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
return controller;
|
||||
}
|
||||
|
||||
private static class TestController extends MerchantWithdrawInvoiceController {
|
||||
private final Long userId;
|
||||
private final String username;
|
||||
|
||||
private TestController(Long userId, String username) {
|
||||
this.userId = userId;
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.jsowell.pile.constant;
|
||||
|
||||
/**
|
||||
* 运营商提现开票常量。
|
||||
*/
|
||||
public final class MerchantWithdrawInvoiceConstants {
|
||||
public static final String TASK_TYPE = "MERCHANT_WITHDRAW_INVOICE";
|
||||
public static final String BUSINESS_TYPE = "CLEARING_WITHDRAW_INVOICE";
|
||||
public static final String ROUTE_NAME = "financeDetail";
|
||||
|
||||
public static final String STATUS_PENDING = "PENDING";
|
||||
public static final String STATUS_SUBMITTED = "SUBMITTED";
|
||||
public static final String STATUS_CLOSED = "CLOSED";
|
||||
|
||||
private MerchantWithdrawInvoiceConstants() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.jsowell.pile.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.jsowell.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 运营商提现开票信息 clearing_withdraw_invoice。
|
||||
*/
|
||||
@Data
|
||||
public class ClearingWithdrawInvoice extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
private String withdrawCode;
|
||||
private String merchantId;
|
||||
private String invoiceStatus;
|
||||
private String invoiceNumber;
|
||||
private String voucherUrl;
|
||||
private Long submittedBy;
|
||||
private String submittedName;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date submittedTime;
|
||||
|
||||
private Long closedBy;
|
||||
private String closedName;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date closedTime;
|
||||
|
||||
private String closeReason;
|
||||
private String delFlag;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.jsowell.pile.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* 平台关闭提现开票任务请求。
|
||||
*/
|
||||
@Data
|
||||
public class WithdrawInvoiceCloseRequest {
|
||||
@NotBlank(message = "关闭原因不能为空")
|
||||
@Size(max = 500, message = "关闭原因不能超过500个字符")
|
||||
private String reason;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.jsowell.pile.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* 提交提现发票信息请求。
|
||||
*/
|
||||
@Data
|
||||
public class WithdrawInvoiceSubmitRequest {
|
||||
@NotNull(message = "待办任务 ID 不能为空")
|
||||
private Long todoId;
|
||||
|
||||
@NotBlank(message = "发票号码不能为空")
|
||||
@Size(max = 100, message = "发票号码不能超过100个字符")
|
||||
private String invoiceNumber;
|
||||
|
||||
@NotBlank(message = "发票凭证不能为空")
|
||||
@Size(max = 1000, message = "发票凭证地址不能超过1000个字符")
|
||||
private String voucherUrl;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.jsowell.pile.mapper;
|
||||
|
||||
import com.jsowell.pile.domain.ClearingWithdrawInvoice;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 运营商提现开票信息 Mapper。
|
||||
*/
|
||||
public interface ClearingWithdrawInvoiceMapper {
|
||||
ClearingWithdrawInvoice selectByWithdrawCode(@Param("withdrawCode") String withdrawCode);
|
||||
|
||||
int insertSelective(ClearingWithdrawInvoice invoice);
|
||||
|
||||
int markSubmitted(ClearingWithdrawInvoice invoice);
|
||||
|
||||
int markClosed(ClearingWithdrawInvoice invoice);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.jsowell.pile.service;
|
||||
|
||||
import com.jsowell.pile.dto.WithdrawInvoiceSubmitRequest;
|
||||
import com.jsowell.pile.vo.web.MerchantWithdrawInvoiceVO;
|
||||
|
||||
/**
|
||||
* 运营商提现向平台开票服务。
|
||||
*/
|
||||
public interface MerchantWithdrawInvoiceService {
|
||||
void handleWithdrawSucceeded(String withdrawCode);
|
||||
|
||||
MerchantWithdrawInvoiceVO getForAssignee(String withdrawCode, Long todoId, Long userId);
|
||||
|
||||
boolean submit(String withdrawCode, WithdrawInvoiceSubmitRequest request,
|
||||
Long userId, String operatorName);
|
||||
|
||||
boolean close(String withdrawCode, String reason, Long operatorId, String operatorName);
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
package com.jsowell.pile.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.jsowell.common.constant.Constants;
|
||||
import com.jsowell.common.exception.ServiceException;
|
||||
import com.jsowell.common.util.DateUtils;
|
||||
import com.jsowell.common.util.StringUtils;
|
||||
import com.jsowell.pile.constant.MerchantWithdrawInvoiceConstants;
|
||||
import com.jsowell.pile.domain.ClearingBillInfo;
|
||||
import com.jsowell.pile.domain.ClearingWithdrawInfo;
|
||||
import com.jsowell.pile.domain.ClearingWithdrawInvoice;
|
||||
import com.jsowell.pile.domain.PileMerchantInfo;
|
||||
import com.jsowell.pile.dto.WithdrawInvoiceSubmitRequest;
|
||||
import com.jsowell.pile.mapper.ClearingWithdrawInfoMapper;
|
||||
import com.jsowell.pile.mapper.ClearingWithdrawInvoiceMapper;
|
||||
import com.jsowell.pile.service.ClearingBillInfoService;
|
||||
import com.jsowell.pile.service.MerchantWithdrawInvoiceService;
|
||||
import com.jsowell.pile.service.PileMerchantInfoService;
|
||||
import com.jsowell.pile.vo.web.MerchantWithdrawInvoiceVO;
|
||||
import com.jsowell.system.constant.TodoTaskConstants;
|
||||
import com.jsowell.system.domain.SysTodoTask;
|
||||
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.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 运营商提现向平台开票服务实现。
|
||||
*/
|
||||
@Service
|
||||
public class MerchantWithdrawInvoiceServiceImpl implements MerchantWithdrawInvoiceService {
|
||||
private static final Logger log = LoggerFactory.getLogger(MerchantWithdrawInvoiceServiceImpl.class);
|
||||
|
||||
@Resource
|
||||
private ClearingWithdrawInfoMapper clearingWithdrawInfoMapper;
|
||||
|
||||
@Resource
|
||||
private ClearingWithdrawInvoiceMapper clearingWithdrawInvoiceMapper;
|
||||
|
||||
@Autowired
|
||||
private ClearingBillInfoService clearingBillInfoService;
|
||||
|
||||
@Autowired
|
||||
private PileMerchantInfoService pileMerchantInfoService;
|
||||
|
||||
@Autowired
|
||||
private TodoTaskAssigneeService todoTaskAssigneeService;
|
||||
|
||||
@Autowired
|
||||
private TodoTaskService todoTaskService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void handleWithdrawSucceeded(String withdrawCode) {
|
||||
String safeWithdrawCode = normalizeRequired(withdrawCode, "提现编号", 64);
|
||||
ClearingWithdrawInfo withdrawInfo = clearingWithdrawInfoMapper.selectByWithdrawCode(safeWithdrawCode);
|
||||
if (withdrawInfo == null) {
|
||||
throw new ServiceException("提现记录不存在,无法创建开票待办");
|
||||
}
|
||||
|
||||
Date now = DateUtils.getNowDate();
|
||||
if (!Constants.ONE.equals(withdrawInfo.getWithdrawStatus()) || withdrawInfo.getArrivalTime() == null) {
|
||||
withdrawInfo.setWithdrawStatus(Constants.ONE);
|
||||
withdrawInfo.setArrivalTime(now);
|
||||
withdrawInfo.setUpdateTime(now);
|
||||
clearingWithdrawInfoMapper.updateByPrimaryKeySelective(withdrawInfo);
|
||||
}
|
||||
completeClearingBills(safeWithdrawCode);
|
||||
|
||||
ClearingWithdrawInvoice invoice = getOrCreateInvoice(withdrawInfo);
|
||||
if (!MerchantWithdrawInvoiceConstants.STATUS_PENDING.equals(invoice.getInvoiceStatus())) {
|
||||
return;
|
||||
}
|
||||
createTodos(withdrawInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerchantWithdrawInvoiceVO getForAssignee(String withdrawCode, Long todoId, Long userId) {
|
||||
String safeWithdrawCode = normalizeRequired(withdrawCode, "提现编号", 64);
|
||||
validateTodo(safeWithdrawCode, todoId, userId);
|
||||
ClearingWithdrawInvoice invoice = requireInvoice(safeWithdrawCode);
|
||||
ClearingWithdrawInfo withdrawInfo = clearingWithdrawInfoMapper.selectByWithdrawCode(safeWithdrawCode);
|
||||
return buildView(invoice, withdrawInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean submit(String withdrawCode, WithdrawInvoiceSubmitRequest request,
|
||||
Long userId, String operatorName) {
|
||||
if (request == null) {
|
||||
throw new ServiceException("发票提交参数不能为空");
|
||||
}
|
||||
String safeWithdrawCode = normalizeRequired(withdrawCode, "提现编号", 64);
|
||||
SysTodoTask todoTask = validateTodo(safeWithdrawCode, request.getTodoId(), userId);
|
||||
|
||||
ClearingWithdrawInvoice invoice = requireInvoice(safeWithdrawCode);
|
||||
if (MerchantWithdrawInvoiceConstants.STATUS_SUBMITTED.equals(invoice.getInvoiceStatus())) {
|
||||
return true;
|
||||
}
|
||||
if (!TodoTaskConstants.isActiveStatus(todoTask.getTaskStatus())) {
|
||||
throw new ServiceException("当前待办状态不允许提交发票");
|
||||
}
|
||||
if (!MerchantWithdrawInvoiceConstants.STATUS_PENDING.equals(invoice.getInvoiceStatus())) {
|
||||
throw new ServiceException("当前提现开票状态不允许提交");
|
||||
}
|
||||
|
||||
Date now = DateUtils.getNowDate();
|
||||
invoice.setInvoiceStatus(MerchantWithdrawInvoiceConstants.STATUS_SUBMITTED);
|
||||
invoice.setInvoiceNumber(normalizeRequired(request.getInvoiceNumber(), "发票号码", 100));
|
||||
invoice.setVoucherUrl(normalizeRequired(request.getVoucherUrl(), "发票凭证", 1000));
|
||||
invoice.setSubmittedBy(userId);
|
||||
invoice.setSubmittedName(normalizeOperator(operatorName, userId));
|
||||
invoice.setSubmittedTime(now);
|
||||
invoice.setUpdateBy(invoice.getSubmittedName());
|
||||
invoice.setUpdateTime(now);
|
||||
if (clearingWithdrawInvoiceMapper.markSubmitted(invoice) == 0) {
|
||||
ClearingWithdrawInvoice current = requireInvoice(safeWithdrawCode);
|
||||
if (MerchantWithdrawInvoiceConstants.STATUS_SUBMITTED.equals(current.getInvoiceStatus())) {
|
||||
return true;
|
||||
}
|
||||
throw new ServiceException("当前提现开票状态不允许提交");
|
||||
}
|
||||
|
||||
todoTaskService.completeByBusiness(MerchantWithdrawInvoiceConstants.BUSINESS_TYPE,
|
||||
safeWithdrawCode, null, userId, invoice.getSubmittedName());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean close(String withdrawCode, String reason, Long operatorId, String operatorName) {
|
||||
String safeWithdrawCode = normalizeRequired(withdrawCode, "提现编号", 64);
|
||||
if (operatorId == null || operatorId <= 0) {
|
||||
throw new ServiceException("关闭操作人不能为空");
|
||||
}
|
||||
ClearingWithdrawInvoice invoice = requireInvoice(safeWithdrawCode);
|
||||
if (MerchantWithdrawInvoiceConstants.STATUS_CLOSED.equals(invoice.getInvoiceStatus())) {
|
||||
return true;
|
||||
}
|
||||
if (!MerchantWithdrawInvoiceConstants.STATUS_PENDING.equals(invoice.getInvoiceStatus())) {
|
||||
throw new ServiceException("当前提现开票状态不允许关闭");
|
||||
}
|
||||
|
||||
Date now = DateUtils.getNowDate();
|
||||
String safeOperator = normalizeOperator(operatorName, operatorId);
|
||||
String safeReason = normalizeRequired(reason, "关闭原因", 500);
|
||||
invoice.setInvoiceStatus(MerchantWithdrawInvoiceConstants.STATUS_CLOSED);
|
||||
invoice.setClosedBy(operatorId);
|
||||
invoice.setClosedName(safeOperator);
|
||||
invoice.setClosedTime(now);
|
||||
invoice.setCloseReason(safeReason);
|
||||
invoice.setUpdateBy(safeOperator);
|
||||
invoice.setUpdateTime(now);
|
||||
if (clearingWithdrawInvoiceMapper.markClosed(invoice) == 0) {
|
||||
ClearingWithdrawInvoice current = requireInvoice(safeWithdrawCode);
|
||||
if (MerchantWithdrawInvoiceConstants.STATUS_CLOSED.equals(current.getInvoiceStatus())) {
|
||||
return true;
|
||||
}
|
||||
throw new ServiceException("当前提现开票状态不允许关闭");
|
||||
}
|
||||
|
||||
todoTaskService.cancelByBusiness(MerchantWithdrawInvoiceConstants.BUSINESS_TYPE,
|
||||
safeWithdrawCode, null, safeOperator, safeReason);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void completeClearingBills(String withdrawCode) {
|
||||
List<ClearingBillInfo> billInfos = clearingBillInfoService.selectByWithdrawCode(withdrawCode);
|
||||
if (CollectionUtils.isEmpty(billInfos)) {
|
||||
return;
|
||||
}
|
||||
for (ClearingBillInfo billInfo : billInfos) {
|
||||
billInfo.setBillStatus("4");
|
||||
}
|
||||
clearingBillInfoService.updateBatchSelective(billInfos);
|
||||
}
|
||||
|
||||
private ClearingWithdrawInvoice getOrCreateInvoice(ClearingWithdrawInfo withdrawInfo) {
|
||||
ClearingWithdrawInvoice invoice = clearingWithdrawInvoiceMapper.selectByWithdrawCode(withdrawInfo.getWithdrawCode());
|
||||
if (invoice != null) {
|
||||
return invoice;
|
||||
}
|
||||
|
||||
invoice = new ClearingWithdrawInvoice();
|
||||
invoice.setWithdrawCode(withdrawInfo.getWithdrawCode());
|
||||
invoice.setMerchantId(withdrawInfo.getMerchantId());
|
||||
invoice.setInvoiceStatus(MerchantWithdrawInvoiceConstants.STATUS_PENDING);
|
||||
invoice.setCreateBy("adapay-callback");
|
||||
invoice.setDelFlag("0");
|
||||
try {
|
||||
clearingWithdrawInvoiceMapper.insertSelective(invoice);
|
||||
return invoice;
|
||||
} catch (DuplicateKeyException exception) {
|
||||
invoice = clearingWithdrawInvoiceMapper.selectByWithdrawCode(withdrawInfo.getWithdrawCode());
|
||||
if (invoice != null) {
|
||||
return invoice;
|
||||
}
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
private void createTodos(ClearingWithdrawInfo withdrawInfo) {
|
||||
if (StringUtils.isBlank(withdrawInfo.getMerchantId())) {
|
||||
log.warn("提现记录缺少运营商,无法创建开票待办,withdrawCode={}", withdrawInfo.getWithdrawCode());
|
||||
return;
|
||||
}
|
||||
|
||||
PileMerchantInfo merchantInfo;
|
||||
try {
|
||||
merchantInfo = pileMerchantInfoService.selectPileMerchantInfoById(Long.parseLong(withdrawInfo.getMerchantId()));
|
||||
} catch (NumberFormatException exception) {
|
||||
log.warn("提现记录运营商 ID 非法,无法创建开票待办,withdrawCode={}, merchantId={}",
|
||||
withdrawInfo.getWithdrawCode(), withdrawInfo.getMerchantId());
|
||||
return;
|
||||
}
|
||||
if (merchantInfo == null || StringUtils.isBlank(merchantInfo.getDeptId())) {
|
||||
log.warn("提现记录运营商未配置部门,无法创建开票待办,withdrawCode={}, merchantId={}",
|
||||
withdrawInfo.getWithdrawCode(), withdrawInfo.getMerchantId());
|
||||
return;
|
||||
}
|
||||
|
||||
Long deptId;
|
||||
try {
|
||||
deptId = Long.parseLong(merchantInfo.getDeptId());
|
||||
} catch (NumberFormatException exception) {
|
||||
log.warn("提现记录运营商部门 ID 非法,无法创建开票待办,withdrawCode={}, deptId={}",
|
||||
withdrawInfo.getWithdrawCode(), merchantInfo.getDeptId());
|
||||
return;
|
||||
}
|
||||
List<Long> assigneeUserIds = todoTaskAssigneeService.findActiveOperatorAdminUserIdsByDeptTree(deptId);
|
||||
if (CollectionUtils.isEmpty(assigneeUserIds)) {
|
||||
log.warn("提现记录运营商部门下没有正常管理员,无法创建开票待办,withdrawCode={}, deptId={}",
|
||||
withdrawInfo.getWithdrawCode(), deptId);
|
||||
return;
|
||||
}
|
||||
|
||||
String routeParams = buildRouteParams(withdrawInfo);
|
||||
for (Long assigneeUserId : assigneeUserIds) {
|
||||
String idempotentKey = MerchantWithdrawInvoiceConstants.TASK_TYPE + ":"
|
||||
+ MerchantWithdrawInvoiceConstants.BUSINESS_TYPE + ":"
|
||||
+ withdrawInfo.getWithdrawCode() + ":" + assigneeUserId;
|
||||
todoTaskService.createTask(TodoTaskCreateCommand.builder()
|
||||
.taskType(MerchantWithdrawInvoiceConstants.TASK_TYPE)
|
||||
.title("运营商提现向平台开票")
|
||||
.summary("提现已成功,请向平台提交发票,提现编号:" + withdrawInfo.getWithdrawCode())
|
||||
.businessType(MerchantWithdrawInvoiceConstants.BUSINESS_TYPE)
|
||||
.businessId(withdrawInfo.getWithdrawCode())
|
||||
.routeName(MerchantWithdrawInvoiceConstants.ROUTE_NAME)
|
||||
.routeParams(routeParams)
|
||||
.assigneeUserId(assigneeUserId)
|
||||
.assigneeMerchantId(withdrawInfo.getMerchantId())
|
||||
.priority(TodoTaskConstants.PRIORITY_IMPORTANT)
|
||||
.idempotentKey(idempotentKey)
|
||||
.createBy("adapay-callback")
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
private String buildRouteParams(ClearingWithdrawInfo withdrawInfo) {
|
||||
Map<String, Object> query = new HashMap<>(2);
|
||||
query.put("merchantId", withdrawInfo.getMerchantId());
|
||||
query.put("withdrawCode", withdrawInfo.getWithdrawCode());
|
||||
Map<String, Object> routeParams = new HashMap<>(1);
|
||||
routeParams.put("query", query);
|
||||
return JSON.toJSONString(routeParams);
|
||||
}
|
||||
|
||||
private SysTodoTask validateTodo(String withdrawCode, Long todoId, Long userId) {
|
||||
SysTodoTask todoTask = todoTaskService.getForAssignee(todoId, userId);
|
||||
if (!MerchantWithdrawInvoiceConstants.TASK_TYPE.equals(todoTask.getTaskType())
|
||||
|| !MerchantWithdrawInvoiceConstants.BUSINESS_TYPE.equals(todoTask.getBusinessType())
|
||||
|| !withdrawCode.equals(todoTask.getBusinessId())) {
|
||||
throw new ServiceException("待办任务与提现开票信息不匹配");
|
||||
}
|
||||
return todoTask;
|
||||
}
|
||||
|
||||
private ClearingWithdrawInvoice requireInvoice(String withdrawCode) {
|
||||
ClearingWithdrawInvoice invoice = clearingWithdrawInvoiceMapper.selectByWithdrawCode(withdrawCode);
|
||||
if (invoice == null) {
|
||||
throw new ServiceException("提现开票信息不存在");
|
||||
}
|
||||
return invoice;
|
||||
}
|
||||
|
||||
private MerchantWithdrawInvoiceVO buildView(ClearingWithdrawInvoice invoice,
|
||||
ClearingWithdrawInfo withdrawInfo) {
|
||||
MerchantWithdrawInvoiceVO view = new MerchantWithdrawInvoiceVO();
|
||||
BeanUtils.copyProperties(invoice, view);
|
||||
if (withdrawInfo != null) {
|
||||
view.setWithdrawAmt(withdrawInfo.getWithdrawAmt());
|
||||
view.setFeeAmt(withdrawInfo.getFeeAmt());
|
||||
view.setCreditedAmt(withdrawInfo.getCreditedAmt());
|
||||
view.setApplicationTime(withdrawInfo.getApplicationTime());
|
||||
view.setArrivalTime(withdrawInfo.getArrivalTime());
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
private String normalizeRequired(String value, String fieldName, int maxLength) {
|
||||
String safeValue = StringUtils.trim(value);
|
||||
if (StringUtils.isEmpty(safeValue)) {
|
||||
throw new ServiceException(fieldName + "不能为空");
|
||||
}
|
||||
if (safeValue.length() > maxLength) {
|
||||
throw new ServiceException(fieldName + "不能超过" + maxLength + "个字符");
|
||||
}
|
||||
return safeValue;
|
||||
}
|
||||
|
||||
private String normalizeOperator(String operatorName, Long operatorId) {
|
||||
String safeOperator = StringUtils.isNotEmpty(operatorName)
|
||||
? operatorName.trim() : String.valueOf(operatorId);
|
||||
if (safeOperator.length() > 64) {
|
||||
throw new ServiceException("操作人名称不能超过64个字符");
|
||||
}
|
||||
return safeOperator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.jsowell.pile.vo.web;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 运营商提现开票详情。
|
||||
*/
|
||||
@Data
|
||||
public class MerchantWithdrawInvoiceVO {
|
||||
private Long id;
|
||||
private String withdrawCode;
|
||||
private String merchantId;
|
||||
private String invoiceStatus;
|
||||
private String invoiceNumber;
|
||||
private String voucherUrl;
|
||||
private Long submittedBy;
|
||||
private String submittedName;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date submittedTime;
|
||||
|
||||
private String closedName;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date closedTime;
|
||||
|
||||
private String closeReason;
|
||||
private BigDecimal withdrawAmt;
|
||||
private BigDecimal feeAmt;
|
||||
private BigDecimal creditedAmt;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date applicationTime;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date arrivalTime;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.jsowell.pile.mapper.ClearingWithdrawInvoiceMapper">
|
||||
<resultMap id="BaseResultMap" type="com.jsowell.pile.domain.ClearingWithdrawInvoice">
|
||||
<id column="id" property="id" />
|
||||
<result column="withdraw_code" property="withdrawCode" />
|
||||
<result column="merchant_id" property="merchantId" />
|
||||
<result column="invoice_status" property="invoiceStatus" />
|
||||
<result column="invoice_number" property="invoiceNumber" />
|
||||
<result column="voucher_url" property="voucherUrl" />
|
||||
<result column="submitted_by" property="submittedBy" />
|
||||
<result column="submitted_name" property="submittedName" />
|
||||
<result column="submitted_time" property="submittedTime" />
|
||||
<result column="closed_by" property="closedBy" />
|
||||
<result column="closed_name" property="closedName" />
|
||||
<result column="closed_time" property="closedTime" />
|
||||
<result column="close_reason" property="closeReason" />
|
||||
<result column="create_by" property="createBy" />
|
||||
<result column="create_time" property="createTime" />
|
||||
<result column="update_by" property="updateBy" />
|
||||
<result column="update_time" property="updateTime" />
|
||||
<result column="remark" property="remark" />
|
||||
<result column="del_flag" property="delFlag" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="BaseColumnList">
|
||||
id, withdraw_code, merchant_id, invoice_status, invoice_number, voucher_url,
|
||||
submitted_by, submitted_name, submitted_time, closed_by, closed_name, closed_time,
|
||||
close_reason, create_by, create_time, update_by, update_time, remark, del_flag
|
||||
</sql>
|
||||
|
||||
<select id="selectByWithdrawCode" resultMap="BaseResultMap">
|
||||
select <include refid="BaseColumnList" />
|
||||
from clearing_withdraw_invoice
|
||||
where withdraw_code = #{withdrawCode}
|
||||
and del_flag = '0'
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<insert id="insertSelective" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
|
||||
insert into clearing_withdraw_invoice (
|
||||
withdraw_code, merchant_id, invoice_status, create_by, create_time, del_flag
|
||||
) values (
|
||||
#{withdrawCode}, #{merchantId}, #{invoiceStatus}, #{createBy}, sysdate(), #{delFlag}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="markSubmitted">
|
||||
update clearing_withdraw_invoice
|
||||
set invoice_status = #{invoiceStatus},
|
||||
invoice_number = #{invoiceNumber},
|
||||
voucher_url = #{voucherUrl},
|
||||
submitted_by = #{submittedBy},
|
||||
submitted_name = #{submittedName},
|
||||
submitted_time = #{submittedTime},
|
||||
update_by = #{updateBy},
|
||||
update_time = #{updateTime}
|
||||
where id = #{id}
|
||||
and invoice_status = 'PENDING'
|
||||
and del_flag = '0'
|
||||
</update>
|
||||
|
||||
<update id="markClosed">
|
||||
update clearing_withdraw_invoice
|
||||
set invoice_status = #{invoiceStatus},
|
||||
closed_by = #{closedBy},
|
||||
closed_name = #{closedName},
|
||||
closed_time = #{closedTime},
|
||||
close_reason = #{closeReason},
|
||||
update_by = #{updateBy},
|
||||
update_time = #{updateTime}
|
||||
where id = #{id}
|
||||
and invoice_status = 'PENDING'
|
||||
and del_flag = '0'
|
||||
</update>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user