1. 派单记录

This commit is contained in:
zhaowenyuan 2024-07-11 16:49:48 +08:00
parent c42bf49c05
commit d8e52ade54
13 changed files with 585 additions and 62 deletions

View File

@ -1,19 +0,0 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.chushang.common.core.cache;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface CacheNameSpase {
String value() default "";
}

View File

@ -1,36 +0,0 @@
package com.chushang.common.core.web;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.StandardCharsets;
/**
* by zhaowenyuan create 2021/12/30 11:42
*/
@Slf4j
@UtilityClass
public class TokenUtils {
private final String TOKEN_SIGN = "sane_cloud_token";
public String decryptStr(String sanyiToken){
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, TOKEN_SIGN.getBytes(StandardCharsets.UTF_8));
try {
return aes.decryptStr(sanyiToken);
}catch (Exception ignored){
}
return null;
}
public static String decryptStr(String sanyiToken, String signType) {
// SymmetricAlgorithm.valueof() 必定不为空, 并且不会异常
try {
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.valueOf(signType), TOKEN_SIGN.getBytes(StandardCharsets.UTF_8));
return aes.decryptStr(sanyiToken);
}catch (Exception ignored){
}
return null;
}
}

View File

@ -0,0 +1,32 @@
package com.chushang.common.core.web.advice;
import java.io.Serial;
import java.util.LinkedHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @auther: zhao
* @date: 2024/7/4 18:20
*/
public class CacheLRUMap<K,V> extends LinkedHashMap<K,V> {
@Serial
private static final long serialVersionUID = 1L;
private final AtomicInteger initialCapacity;
public CacheLRUMap(){
super(10000, 0.75f, true);
initialCapacity = new AtomicInteger(10000);
}
public CacheLRUMap(Integer initialCapacity){
super(initialCapacity, 0.75f, true);
this.initialCapacity = new AtomicInteger(initialCapacity);
}
@Override
protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
return size() > initialCapacity.get();
}
}

View File

@ -0,0 +1,54 @@
package com.chushang.common.core.web.advice;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.alibaba.fastjson2.JSON;
import com.chushang.common.core.exception.utils.AssertUtil;
import com.chushang.common.core.util.IPUtils;
import com.chushang.common.core.util.StringUtils;
import com.chushang.common.core.web.annotation.AutoIdempotent;
import lombok.RequiredArgsConstructor;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Type;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
@RestControllerAdvice
@SuppressWarnings("all")
@RequiredArgsConstructor
public class IdempotentAdvice extends RequestBodyAdviceAdapter {
private static final CacheLRUMap<String, Byte> CACHE_KEY_MAP = new CacheLRUMap<>();
private static final byte val = '1';
@Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return methodParameter.hasMethodAnnotation(AutoIdempotent.class);
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
String value = JSON.toJSONString(body);
if (StrUtil.isEmpty(value)) {
return body;
}
HttpServletRequest request = IPUtils.getRequest();
String key = StrUtil.format("{}_{}", ServletUtil.getClientIP(request), request.getRequestURI());
Byte val = CACHE_KEY_MAP.get(key);
AssertUtil.invalidate(null != val || val.equals(this.val), "请勿重复提交");
AutoIdempotent idempotent = parameter.getMethodAnnotation(AutoIdempotent.class);
if (idempotent != null) {
CACHE_KEY_MAP.put(key, this.val);
}
return body;
}
}

View File

@ -0,0 +1,17 @@
package com.chushang.common.core.web.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 幂等性注解
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoIdempotent {
/** 时间(秒) */
long expireTime() default 5;
}

View File

@ -213,7 +213,6 @@ public class WrapperUtils {
continue; continue;
} }
String name = condition.name(); String name = condition.name();
String tableName = condition.tableName();
String[] split = name.split(","); String[] split = name.split(",");
Condition.ConditionType conditionType = condition.type(); Condition.ConditionType conditionType = condition.type();
if (null != conditionType) { if (null != conditionType) {

View File

@ -0,0 +1,48 @@
package com.chushang.inspection.work.dto;
import cn.hutool.core.date.DatePattern;
import com.chushang.common.mybatis.annotation.Condition;
import com.chushang.common.mybatis.page.CommonParam;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.*;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class BankDispatchQuery extends CommonParam {
/**
* 状态
*/
@Condition(name = "status")
@Range(min = 1, max = 4, message = "状态只有1 下发 2 派单成功 3 推送成功 4 推送失败)")
private Integer status;
/**
* 下发时间
*/
@JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
@Condition(name = "req_date", type = Condition.ConditionType.between)
private List<LocalDateTime> reqDate;
/**
* 是否为银行派单 (1 2否)
*/
@Condition(name ="is_bank")
@Range(min = 1,max = 2,message = "状态只有 (1 是 2否)")
private Integer isBank;
/**
* 商户名称或者编号
*/
@Condition(name ="mer_id,mer_name", type = Condition.ConditionType.or_like)
@Size(max = 128,message = "商户名称或编号不能超过128字符")
private String blurry;
}

View File

@ -0,0 +1,115 @@
package com.chushang.inspection.work.dto;
import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class WrkIcbcJsReceive implements Serializable {
/**
* 交易码
*/
private String transCode;
/**
* 商户 id
*/
private String merId;
/**
* 商户名
*/
private String merName;
/**
* 终端编号
*/
private String termId;
/**
* 工单编号
*/
private String orderNo;
/**
* 工单类型 001-新装机003-撤机004-换机
* 005-低效激活006-合规巡检007-
* 日常维护
*/
private String orderType;
/**
* 联系人
*/
private String linkName;
/**
* 联系方式
*/
private String contactWay;
/**
* 商户地址
*/
private String merAddress;
/**
* 设备类型
* 001-POS 设备002-MIS 手柄003-
* 云音响004-其他
*/
private String deviceType;
/**
* 设备序列号
*/
private String deviceNo;
/**
* 商户类型
* 1-POS 商户2-条码支付商户
*/
private String merType;
/**
* 备注信息
*/
private String noteMsg;
/**
* 服务商编号
*/
private String agentId;
/**
* 请求日期
*/
@JsonFormat(pattern = DatePattern.PURE_DATE_PATTERN)
private LocalDate reqDate;
/**
* 请求时间
*/
@JsonFormat(pattern = DatePattern.PURE_TIME_PATTERN)
private LocalTime reqTime;
/**
* 工单状态
*/
private String orderStatus;
/**
* 分行地区号
*/
private String area;
}

View File

@ -0,0 +1,116 @@
package com.chushang.inspection.work.vo;
import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.time.LocalDate;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BankDispatchDTO implements Serializable {
/**
* 主键
*/
@NotNull(message = "id不能为空")
private Long id;
/**
* 商户编号
*/
@Size(max = 12, message = "商户编号不能超过12位")
private String merId;
/**
* 商户名
*/
@Size(max = 100, message = "商户名不能超过100位")
private String merName;
/**
* 终端编号
*/
@Size(max = 15, message = "终端编号不能超过15位")
private String termId;
/**
* 工单类型01-新装机003-撤机004-换机005-低效激活006-合规巡检007- 日常维护008-新拓户
*/
@NotNull(message = "工单类型不能为空")
@Size(min = 3, max = 4, message = "工单类型只支持01-新装机003-撤机004-换机005-低效激活006-合规巡检007- 日常维护008-新拓户)")
private String orderType;
/**
* 联系人
*/
@Size(max = 20, message = "联系人不能超过20位")
private String linkName;
/**
* 联系方式
*/
@Size(max = 20, message = "联系方式不能超过20位")
private String contactWay;
/**
* 商户地址
*/
@Size(max = 200, message = "商户地址不能超过200位")
private String merAddress;
/**
* 商户类型
*/
@Size(min = 1, max = 1, message = "商户类型只支持1-POS 商户2-条码支付商户)")
private String merType;
/**
* 设备类型
*/
@Size(min = 3, max = 4, message = "设备类型只支持001-POS 设备002-MIS 手柄003- 云音响004-其他)")
private String deviceType;
/**
* 设备序列号
*/
@Size(max = 64, message = "设备序列号不能超过64位")
private String deviceNo;
/**
* 备注信息
*/
@Size(max = 100, message = "备注信息不能超过100位")
private String noteMsg;
/**
* 分行地区号
*/
@Size(max = 100, message = "分行地区号只支持(4301 南京分行 1102 苏州分行 1103 无锡分行 1104 镇江分行\n" +
"1105 常州分行 1106 徐州分行 1107 连云港分行 1108 扬州分行 1109 盐城分行 1110 淮安分行\n" +
"1111 南通分行 1115 泰州分行 1116 宿迁分)")
private String area;
/**
* 请求日期
*/
@JsonFormat(pattern = DatePattern.NORM_DATE_PATTERN)
private LocalDate reqDate;
/**
* 状态1 下发 2 派单成功 3 推送成功 4 推送失败
*/
private Integer status;
private Integer isBank;
private String respMssg;
}

View File

@ -0,0 +1,55 @@
package com.chushang.inspection.work.vo;
import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalTime;
@Data
@NoArgsConstructor
public class Result implements Serializable {
/**
* 交易码
*/
private String transCode = "1010";
/**
* 响应日期
*/
@JsonFormat(pattern = DatePattern.PURE_DATE_PATTERN)
private LocalDate respDate = LocalDate.now();
/**
* 响应时间
*/
@JsonFormat(pattern = DatePattern.PURE_TIME_PATTERN)
private LocalTime respTime = LocalTime.now();
/**
* 响应码
*/
private String respCode;
/**
* 响应信息
*/
private String respMssg;
public Result(String respCode, String respMssg) {
this.respCode = respCode;
this.respMssg = respMssg;
}
public static Result success() {
return new Result("00", "处理成功");
}
public static Result error() {
return new Result("FF", "业务处理出现异常");
}
}

View File

@ -1,12 +1,107 @@
package com.chushang.inspection.work.controller; package com.chushang.inspection.work.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.chushang.common.core.web.AjaxResult;
import com.chushang.common.core.web.annotation.AutoIdempotent;
import com.chushang.common.log.annotation.SysLog;
import com.chushang.common.log.enums.BusinessType;
import com.chushang.inspection.work.dto.BankDispatchQuery;
import com.chushang.inspection.work.dto.WrkIcbcJsReceive;
import com.chushang.inspection.work.po.WrkIcbcJs;
import com.chushang.inspection.work.service.WrkIcbcJsService;
import com.chushang.inspection.work.vo.BankDispatchDTO;
import com.chushang.inspection.work.vo.Result;
import com.chushang.security.annotation.RequiresPermissions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.Map;
/** /**
* 江苏工行数据推送(wrk_icbc_js)表控制层 * 江苏工行数据推送(wrk_icbc_js)表控制层
* *
* @author xxxxx * @author xxxxx
*/ */
@Slf4j
@RestController @RestController
@RequestMapping("/wrk_icbc_js") @RequestMapping("/wrk/icbc/js")
public class WrkIcbcJsController { public class WrkIcbcJsController {
@Resource
private WrkIcbcJsService wrkIcbcJsService;
@SysLog("江苏工行数据接收")
@PostMapping("/receive")
public Result receive(@RequestBody WrkIcbcJsReceive dto) {
try {
Assert.notNull(dto, "接收数据为空");
wrkIcbcJsService.receive(dto);
return Result.success();
} catch (Exception e) {
log.error("数据接受失败", e);
return Result.error();
}
}
/**
* 查询银行派单列表
*/
@SysLog(value = "查询银行派单列表", businessType = BusinessType.QUERY)
@PostMapping("/page")
@RequiresPermissions("icbc:js:page")
public AjaxResult queryDispatchPage(@RequestBody @Validated BankDispatchQuery query) {
return AjaxResult.success(wrkIcbcJsService.queryDispatchPage(query));
}
/**
* 查询银行派单详情
*/
@SysLog(value = "查询银行派单详情", businessType = BusinessType.QUERY)
@PostMapping("/info")
@RequiresPermissions("icbc:js:info")
public AjaxResult info(@RequestBody @NotNull(message = "id不能为空") Long id) {
return AjaxResult.success(wrkIcbcJsService.info(id));
}
/**
* 银行派单数据更新
*/
@AutoIdempotent
@SysLog(value = "银行派单数据更新", businessType = BusinessType.UPDATE)
@PostMapping("/update")
@RequiresPermissions("icbc:js:update")
public void update(@RequestBody @Validated BankDispatchDTO dispatch) {
wrkIcbcJsService.update(dispatch);
}
/**
* 手工派单
*/
@AutoIdempotent
@SysLog(value = "手工派单", businessType = BusinessType.INSERT)
@PostMapping("/dispatch")
@RequiresPermissions("icbc:js:dispatch")
public void dispatchOrder(@RequestBody Map<String, Long> data) {
Assert.isTrue(CollUtil.isNotEmpty(data) && data.containsKey("id") && data.containsKey("userId"),
"id或用户id不能位空");
WrkIcbcJs entity = new WrkIcbcJs();
entity.setId(data.get("id"));
wrkIcbcJsService.dispatchOrder(entity, data.get("userId"));
}
/**
* 自动推送失败手动推送
*/
@AutoIdempotent
@SysLog(value = "自动推送失败手动推送", businessType = BusinessType.OTHER)
@PostMapping("/push")
@RequiresPermissions("icbc:js:push")
public void push(@RequestBody Map<String, Long> data) {
Assert.isTrue(data != null && data.containsKey("id"), "id不能位空");
wrkIcbcJsService.manualPush(data.get("id"));
}
} }

View File

@ -1,12 +1,26 @@
package com.chushang.inspection.work.service; package com.chushang.inspection.work.service;
import com.chushang.common.mybatis.utils.PageResult;
import com.chushang.inspection.work.dto.BankDispatchQuery;
import com.chushang.inspection.work.dto.WrkIcbcJsReceive;
import com.chushang.inspection.work.po.WrkIcbcJs; import com.chushang.inspection.work.po.WrkIcbcJs;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
/** import com.chushang.inspection.work.vo.BankDispatchDTO;
* @auther: zhao
* @date: 2024/6/28 15:38
*/
public interface WrkIcbcJsService extends IService<WrkIcbcJs>{
/**
* @auther: zhao
* @date: 2024/6/28 15:38
*/
public interface WrkIcbcJsService extends IService<WrkIcbcJs> {
void receive(WrkIcbcJsReceive dto);
PageResult queryDispatchPage(BankDispatchQuery query);
BankDispatchDTO info(Long id);
void update(BankDispatchDTO dispatch);
void dispatchOrder(WrkIcbcJs entity, Long userId);
void manualPush(Long id);
} }

View File

@ -1,6 +1,10 @@
package com.chushang.inspection.work.service.impl; package com.chushang.inspection.work.service.impl;
import com.chushang.common.mybatis.utils.PageResult;
import com.chushang.inspection.work.dto.BankDispatchQuery;
import com.chushang.inspection.work.dto.WrkIcbcJsReceive;
import com.chushang.inspection.work.service.WrkIcbcJsService; import com.chushang.inspection.work.service.WrkIcbcJsService;
import com.chushang.inspection.work.vo.BankDispatchDTO;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chushang.inspection.work.mapper.WrkIcbcJsMapper; import com.chushang.inspection.work.mapper.WrkIcbcJsMapper;
@ -13,4 +17,33 @@ import com.chushang.inspection.work.po.WrkIcbcJs;
@Service @Service
public class WrkIcbcJsServiceImpl extends ServiceImpl<WrkIcbcJsMapper, WrkIcbcJs> implements WrkIcbcJsService { public class WrkIcbcJsServiceImpl extends ServiceImpl<WrkIcbcJsMapper, WrkIcbcJs> implements WrkIcbcJsService {
@Override
public void receive(WrkIcbcJsReceive dto) {
}
@Override
public PageResult queryDispatchPage(BankDispatchQuery query) {
return null;
}
@Override
public BankDispatchDTO info(Long id) {
return null;
}
@Override
public void update(BankDispatchDTO dispatch) {
}
@Override
public void dispatchOrder(WrkIcbcJs entity, Long userId) {
}
@Override
public void manualPush(Long id) {
}
} }