散户余额流水明细功能接口

wxpay
LI-CCONG\李聪聪 8 months ago
parent 79e42a44b6
commit 5c37cb6526

@ -0,0 +1,140 @@
package cc.yunxi.common.domain;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.springframework.util.StringUtils;
import java.util.Collection;
/**
* MyBatis Plus QueryWrapper
* <p>
* 1. xxxIfPresent
*
* @param <T>
*/
public class LambdaQueryWrapperX<T> extends LambdaQueryWrapper<T> {
public LambdaQueryWrapperX<T> likeIfPresent(SFunction<T, ?> column, String val) {
if (StringUtils.hasText(val)) {
return (LambdaQueryWrapperX<T>) super.like(column, val);
}
return this;
}
public LambdaQueryWrapperX<T> inIfPresent(SFunction<T, ?> column, Collection<?> values) {
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
return (LambdaQueryWrapperX<T>) super.in(column, values);
}
return this;
}
public LambdaQueryWrapperX<T> inIfPresent(SFunction<T, ?> column, Object... values) {
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
return (LambdaQueryWrapperX<T>) super.in(column, values);
}
return this;
}
public LambdaQueryWrapperX<T> eqIfPresent(SFunction<T, ?> column, Object val) {
if (ObjectUtil.isNotEmpty(val)) {
return (LambdaQueryWrapperX<T>) super.eq(column, val);
}
return this;
}
public LambdaQueryWrapperX<T> neIfPresent(SFunction<T, ?> column, Object val) {
if (ObjectUtil.isNotEmpty(val)) {
return (LambdaQueryWrapperX<T>) super.ne(column, val);
}
return this;
}
public LambdaQueryWrapperX<T> gtIfPresent(SFunction<T, ?> column, Object val) {
if (val != null) {
return (LambdaQueryWrapperX<T>) super.gt(column, val);
}
return this;
}
public LambdaQueryWrapperX<T> geIfPresent(SFunction<T, ?> column, Object val) {
if (val != null) {
return (LambdaQueryWrapperX<T>) super.ge(column, val);
}
return this;
}
public LambdaQueryWrapperX<T> ltIfPresent(SFunction<T, ?> column, Object val) {
if (val != null) {
return (LambdaQueryWrapperX<T>) super.lt(column, val);
}
return this;
}
public LambdaQueryWrapperX<T> leIfPresent(SFunction<T, ?> column, Object val) {
if (val != null) {
return (LambdaQueryWrapperX<T>) super.le(column, val);
}
return this;
}
public LambdaQueryWrapperX<T> betweenIfPresent(SFunction<T, ?> column, Object val1, Object val2) {
if (val1 != null && val2 != null) {
return (LambdaQueryWrapperX<T>) super.between(column, val1, val2);
}
if (val1 != null) {
return (LambdaQueryWrapperX<T>) ge(column, val1);
}
if (val2 != null) {
return (LambdaQueryWrapperX<T>) le(column, val2);
}
return this;
}
public LambdaQueryWrapperX<T> betweenIfPresent(SFunction<T, ?> column, Object[] values) {
Object val1 = ArrayUtil.get(values, 0);
Object val2 = ArrayUtil.get(values, 1);
return betweenIfPresent(column, val1, val2);
}
// ========== 重写父类方法,方便链式调用 ==========
@Override
public LambdaQueryWrapperX<T> eq(boolean condition, SFunction<T, ?> column, Object val) {
super.eq(condition, column, val);
return this;
}
@Override
public LambdaQueryWrapperX<T> eq(SFunction<T, ?> column, Object val) {
super.eq(column, val);
return this;
}
@Override
public LambdaQueryWrapperX<T> last(String lastSql) {
super.last(lastSql);
return this;
}
@Override
public LambdaQueryWrapperX<T> in(SFunction<T, ?> column, Collection<?> coll) {
super.in(column, coll);
return this;
}
public LambdaQueryWrapperX<T> orderByDesc(SFunction<T, ?> column) {
super.orderByDesc(true, column);
return this;
}
public LambdaQueryWrapperX<T> orderByAsc(SFunction<T, ?> column) {
super.orderByAsc(true, column);
return this;
}
}

@ -28,11 +28,11 @@ import java.util.stream.Collectors;
public class PageQuery {
public static final Integer DEFAULT_PAGE_SIZE = 20;
public static final Integer DEFAULT_PAGE_NUM = 1;
@ApiModelProperty(value = "页码", required = false, example = "1")
@ApiModelProperty(value = "页码", required = false, example = "1")
@Min(value = 1, message = "页码不能小于1")
private Integer pageNo = DEFAULT_PAGE_NUM;
@ApiModelProperty(value = "每页个数", required = false, example = "10")
@ApiModelProperty(value = "每页个数", required = false, example = "10")
@Min(value = 1, message = "每页查询数量不能小于1")
private Integer pageSize = DEFAULT_PAGE_SIZE;
@ -40,7 +40,12 @@ public class PageQuery {
private LinkedHashSet<SortingField> sortingFields;
// 构建分页
// 忽略构建排序
public <T> Page<T> getPage() {
return Page.of(pageNo, pageSize);
}
// 构建分页排序
public <T> Page<T> buildPage(Class<?> clazz, OrderItem... orderItems) {
Page<T> page = Page.of(pageNo, pageSize);
// 前端排序规则
@ -60,8 +65,8 @@ public class PageQuery {
}).map(sortingField -> {
String column = StringUtils.camelToUnderline(sortingField.getField());
return SortingField.ORDER_ASC.equals(sortingField.getOrder()) ?
OrderItem.asc(column) :
OrderItem.desc(column);
OrderItem.asc(column) :
OrderItem.desc(column);
}).collect(Collectors.toList());
page.addOrder(orderItemList);
}
@ -83,11 +88,12 @@ public class PageQuery {
public <T> Page<T> buildPageByDefaultOrder(SFunction<T> defaultSortByFuc, boolean isAsc) {
OrderItem orderItem = new OrderItem();
orderItem.setAsc(isAsc);
String column = StringUtils.camelToUnderline(LambdaUtil.getFieldName(defaultSortByFuc));
orderItem.setColumn(column);
Class<?> clazz = LambdaUtil.getClazz(defaultSortByFuc);
return buildPage(clazz,orderItem);
String fieldName = LambdaUtil.getFieldName(defaultSortByFuc);
String column = StringUtils.camelToUnderline(fieldName); // @TableField重命名问题 todo
orderItem.setColumn(column);
orderItem.setAsc(isAsc);
return buildPage(clazz, orderItem);
}
@ -113,7 +119,7 @@ public class PageQuery {
/**
*
*/
@ApiModelProperty(value = "是否升序", required = true, allowableValues = "asc,desc")
@ApiModelProperty(value = "是否升序", required = true, allowableValues = "asc,desc", example = "asc")
private String order;

@ -1,14 +1,19 @@
package cc.yunxi.controller;
import cc.yunxi.aspect.UserTypeAnnotation;
import cc.yunxi.common.domain.CommonResult;
import cc.yunxi.common.domain.PageDTO;
import cc.yunxi.common.utils.BeanUtils;
import cc.yunxi.domain.dto.UserDTO;
import cc.yunxi.domain.po.Client;
import cc.yunxi.domain.po.ClientAccountDetail;
import cc.yunxi.domain.query.ClientAccountQuery;
import cc.yunxi.domain.query.ClientQuery;
import cc.yunxi.domain.vo.client.ClientAccountRespVO;
import cc.yunxi.domain.vo.client.ClientRespVO;
import cc.yunxi.domain.vo.client.ClientUpdateVO;
import cc.yunxi.enums.UserTypeEnum;
import cc.yunxi.service.IClientService;
import cc.yunxi.utils.UserContext;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -29,6 +34,7 @@ import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/client")
@RequiredArgsConstructor
@UserTypeAnnotation(UserTypeEnum.CLIENT)
public class ClientController {
private final IClientService clientService;
@ -37,7 +43,7 @@ public class ClientController {
@PostMapping("/page")
public CommonResult<PageDTO<ClientRespVO>> queryClientByPage(@RequestBody ClientQuery clientQuery) {
// 1.分页查询
Page<Client> result = clientService.queryByPage(clientQuery);
Page<Client> result = clientService.queryClientByPage(clientQuery);
// 2.封装并返回
PageDTO<ClientRespVO> clientPageVO = PageDTO.of(result, ClientRespVO.class);
return CommonResult.success(clientPageVO);
@ -64,4 +70,14 @@ public class ClientController {
}
@ApiOperation("账户流水明细")
@PostMapping("/account-statement")
public CommonResult<PageDTO<ClientAccountRespVO>> myAccountStatement(@RequestBody ClientAccountQuery clientAccountQuery) {
UserDTO userDTO = UserContext.getUser();
clientAccountQuery.setClientId(userDTO.getId());
Page<ClientAccountDetail> result = clientService.queryAccountStatementByPage(clientAccountQuery);
PageDTO<ClientAccountRespVO> clientAccountRespVO = PageDTO.of(result, ClientAccountRespVO.class);
return CommonResult.success(clientAccountRespVO);
}
}

@ -0,0 +1,59 @@
package cc.yunxi.domain.po;
import cc.yunxi.enums.BalanceChangeTypeEnum;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* -
* </p>
*
* @author ccongli
* @since 2024-03-07 04:03:37
*/
@Data
@TableName("nx_client_account_detail")
@ApiModel(value = "ClientAccountDetail", description = "散户-账户变动明细")
public class ClientAccountDetail {
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
@ApiModelProperty("散户id")
@TableField("client_id")
private String clientId;
@ApiModelProperty("变更类型")
@TableField("change_type")
private BalanceChangeTypeEnum changeType;
@ApiModelProperty("金额")
@TableField("amount")
private BigDecimal amount;
@ApiModelProperty("账户余额")
@TableField("banlance")
private BigDecimal banlance;
@ApiModelProperty("备注")
@TableField("remark")
private String remark;
@ApiModelProperty("创建时间")
@TableField("f_creator_time")
private LocalDateTime creatorTime;
}

@ -0,0 +1,26 @@
package cc.yunxi.domain.query;
import cc.yunxi.common.domain.PageQuery;
import cc.yunxi.enums.BalanceChangeTypeEnum;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(value = "ClientAccountQuery", description = "散户余额明细查询条件")
public class ClientAccountQuery extends PageQuery {
@ApiModelProperty(value = "散户ID", hidden = true, example = "1763507031581421570")
private String clientId;
@ApiModelProperty(value = "变更类型", required = false, example = "INCOME")
private BalanceChangeTypeEnum changeType;
@ApiModelProperty(value = "时间范围", required = false, example = "[\"2024-03-08 00:00:00\", \"2024-03-09 00:00:00\"]")
private LocalDateTime[] dateRange;
}

@ -0,0 +1,42 @@
package cc.yunxi.domain.vo.client;
import cc.yunxi.enums.BalanceChangeTypeEnum;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
/**
* <p>
* VO
* </p>
*
* @author ccongli
* @since 2024-02-28 16:08:09
*/
@Data
@ApiModel(description = "散户账户明细 Response VO")
public class ClientAccountRespVO {
@ApiModelProperty("余额变更类型")
private BalanceChangeTypeEnum changeType;
@ApiModelProperty("变更金额")
private BigDecimal amount;
@ApiModelProperty("账户余额")
private BigDecimal banlance;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("创建时间")
private LocalDateTime creatorTime;
}

@ -48,14 +48,14 @@ public class ClientRespVO {
@ApiModelProperty("账户余额")
private BigDecimal banlance;
@ApiModelProperty("会员码")
private String membershipNumber;
@ApiModelProperty("会员积分")
// @ApiModelProperty("会员码")
// private String membershipNumber;
//
@ApiModelProperty("积分")
private Integer membershipPoint;
@ApiModelProperty("会员等级")
private Integer membershipLevel;
//
// @ApiModelProperty("会员等级")
// private Integer membershipLevel;
@ApiModelProperty("发票抬头")
private String taxTitle;

@ -0,0 +1,28 @@
package cc.yunxi.enums;
import cc.yunxi.common.enums.BaseEnum;
import cc.yunxi.common.enums.SwaggerDisplayEnum;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*/
@Getter
@AllArgsConstructor
@SwaggerDisplayEnum
public enum BalanceChangeTypeEnum implements BaseEnum {
INCOME("1", "收入"),
CASH_OUT("2", "提现"),
EXPEND("3", "消费");
@EnumValue
private final String code;
private final String desc;
}

@ -27,7 +27,7 @@ public class RequestReaderHttpServletRequestWrapper extends HttpServletRequestWr
private Collection<Part> requestParts;
public RequestReaderHttpServletRequestWrapper(HttpServletRequest request) {
public RequestReaderHttpServletRequestWrapper(HttpServletRequest request) { // RequestFacade
super(request);
//缓存请求body或parts
try {

@ -28,7 +28,7 @@ public class StatsInterceptor implements HandlerInterceptor {
String requestURI = request.getRequestURI();
String method = request.getMethod();
String contentType = request.getContentType();
String data = "不支持其他复杂请求数据读取!";
String data = "其他复杂请求数据不记录!";
if(HttpMethod.POST.name().equals(method) && !contentType.equals(MediaType.MULTIPART_FORM_DATA_VALUE)) {
if (contentType.equals(MediaType.APPLICATION_JSON_VALUE)) {
data = WebUtils.getRequestPostStr(request);

@ -0,0 +1,18 @@
package cc.yunxi.mapper;
import cc.yunxi.domain.po.ClientAccountDetail;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* - Mapper
* </p>
*
* @author ccongli
* @since 2024-03-07 04:03:37
*/
@Mapper
public interface ClientAccountDetailMapper extends BaseMapper<ClientAccountDetail> {
}

@ -1,7 +1,9 @@
package cc.yunxi.service;
import cc.yunxi.domain.po.Client;
import cc.yunxi.domain.po.ClientAccountDetail;
import cc.yunxi.domain.po.Recycler;
import cc.yunxi.domain.query.ClientAccountQuery;
import cc.yunxi.domain.query.ClientQuery;
import cc.yunxi.domain.query.RecyclerQuery;
import cc.yunxi.domain.vo.client.ClientUpdateVO;
@ -21,11 +23,11 @@ import javax.validation.Valid;
public interface IClientService extends IService<Client> {
/**
*
*
* @param clientQuery
* @return Page<Client>
*/
Page<Client> queryByPage(ClientQuery clientQuery);
Page<Client> queryClientByPage(ClientQuery clientQuery);
/**
* id
@ -58,4 +60,12 @@ public interface IClientService extends IService<Client> {
*/
void updateClient(ClientUpdateVO clientUpdateVO);
/**
*
* @param clientAccountQuery
* @return Page<ClientAccountDetail>
*/
Page<ClientAccountDetail> queryAccountStatementByPage(ClientAccountQuery clientAccountQuery);
}

@ -1,15 +1,19 @@
package cc.yunxi.service.impl;
import cc.yunxi.common.domain.LambdaQueryWrapperX;
import cc.yunxi.common.exception.BizIllegalException;
import cc.yunxi.common.exception.DbException;
import cc.yunxi.common.utils.BeanUtils;
import cc.yunxi.domain.dto.UserDTO;
import cc.yunxi.domain.po.Client;
import cc.yunxi.domain.po.ClientAccountDetail;
import cc.yunxi.domain.po.RecycleOrder;
import cc.yunxi.domain.po.Recycler;
import cc.yunxi.domain.query.ClientAccountQuery;
import cc.yunxi.domain.query.ClientQuery;
import cc.yunxi.domain.query.RecyclerQuery;
import cc.yunxi.domain.vo.client.ClientUpdateVO;
import cc.yunxi.mapper.ClientAccountDetailMapper;
import cc.yunxi.mapper.ClientMapper;
import cc.yunxi.mapper.RecyclerMapper;
import cc.yunxi.service.IClientService;
@ -19,6 +23,7 @@ import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -35,14 +40,17 @@ import javax.annotation.Resource;
@Service
public class ClientServiceImpl extends ServiceImpl<ClientMapper, Client> implements IClientService {
@Autowired
private ClientAccountDetailMapper accountDetailMapper;
@Override
public Page<Client> queryByPage(ClientQuery clientQuery) {
public Page<Client> queryClientByPage(ClientQuery clientQuery) {
QueryWrapper<Client> wrapper = new QueryWrapper<>();
wrapper.lambda()
.eq(StrUtil.isNotEmpty(clientQuery.getMobilePhone()), Client::getMobilePhone, clientQuery.getMobilePhone());
// Page<Recycler> recyclerPage = page(
// recyclerQuery.buildPageByDefaultOrder(Recycler.class, "goodTotal", true), wrapper);
Page<Client> clientPage = page(
Page<Client> clientPage = this.page(
clientQuery.buildPageByDefaultOrder(Client::getCreatorTime, true), wrapper);
return clientPage;
}
@ -90,6 +98,20 @@ public class ClientServiceImpl extends ServiceImpl<ClientMapper, Client> impleme
this.updateById(client);
}
@Override
public Page<ClientAccountDetail> queryAccountStatementByPage(ClientAccountQuery clientAccountQuery) {
LambdaQueryWrapperX<ClientAccountDetail> wrapperX = new LambdaQueryWrapperX<>();
wrapperX.eq(ClientAccountDetail::getClientId, clientAccountQuery.getClientId())
.eqIfPresent(ClientAccountDetail::getChangeType, clientAccountQuery.getChangeType())
.betweenIfPresent(ClientAccountDetail::getCreatorTime, clientAccountQuery.getDateRange())
.orderByDesc(ClientAccountDetail::getCreatorTime);
Page<ClientAccountDetail> clientAccountDetailPage = accountDetailMapper.selectPage(
clientAccountQuery.getPage(), wrapperX);
return clientAccountDetailPage;
}
// 校验散户是否存在
private void validateClientExists(String id) {
if (this.getClientById(id) == null) {

@ -0,0 +1,5 @@
<?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="cc.yunxi.mapper.ClientAccountDetailMapper">
</mapper>

@ -7,6 +7,8 @@ import cc.yunxi.domain.po.Recycler;
import cc.yunxi.enums.UserTypeEnum;
import cc.yunxi.service.ITestService;
import cc.yunxi.utils.JwtTool;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@ -49,11 +51,9 @@ public class NxhsApplicationTest {
}
public static void main(String[] args) {
// String property = System.getProperty("user.dir");
// System.out.println(property);
System.out.println(UserTypeEnum.CLIENT.toString());
Class<? extends UserTypeEnum> aClass = UserTypeEnum.CLIENT.getClass();
System.out.println(aClass.getEnumConstants());
// System.out.println(DigestUtil.sha256Hex("123456"));
// System.out.println(DigestUtil.sha1Hex("123456"));
// System.out.println(DigestUtil.md5Hex("123456"));
}
}

Loading…
Cancel
Save