This commit is contained in:
韩鹏辉
2024-05-23 15:23:08 +08:00
parent 49fe8fe877
commit d969550aa3
2477 changed files with 340990 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

180
jeepay-manager/pom.xml Normal file
View File

@@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <!-- POM模型版本 -->
<groupId>com.jeequan</groupId> <!-- 组织名, 类似于包名 -->
<artifactId>jeepay-9217-manager</artifactId> <!-- 项目名称 -->
<packaging>jar</packaging> <!-- 项目的最终打包类型/发布形式, 可选[jar, war, pom, maven-plugin]等 -->
<version>${isys.version}</version> <!-- 项目当前版本号 -->
<description>Jeepay计全支付系统 [运营后台管理端]</description> <!-- 项目描述 -->
<parent>
<groupId>com.jeequan</groupId>
<artifactId>jeepay</artifactId>
<version>Final</version>
</parent>
<!-- 项目属性 -->
<properties>
<projectRootDir>${basedir}/../</projectRootDir>
</properties>
<!-- 项目依赖声明 -->
<dependencies>
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
</dependency>
<!-- 依赖[ service ]包, 会自动传递依赖[ core ]包。 -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-components-db</artifactId>
</dependency>
<!-- 依赖[ rpc-thirdparty ]包, 会自动传递依赖[ core , service ]包。 -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-components-3rd</artifactId>
</dependency>
<!-- 依赖[ oss ]包 -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-components-oss</artifactId>
</dependency>
<!-- 依赖[ mq ]包 -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-components-mq</artifactId>
</dependency>
<!-- 依赖[ bizcommons ]包 -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-components-bizcommons</artifactId>
</dependency>
<!-- 依赖 sping-boot-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion> <!-- 删除spring boot默认json映射器 Jackson 引入fastJSON -->
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
</exclusion>
<exclusion> <!-- hibernate.validator插件一般不使用 -->
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- spring-security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<!-- spring-aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- 添加redis支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 引入 jeepay-sdk-java -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-sdk-java</artifactId>
</dependency>
<!--阿里云短信依赖-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
</dependency>
<!-- 阿里大于 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
</dependency>
<!-- webSocket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
</dependency>
</dependencies>
<!-- 作为可执行jar -->
<build>
<finalName>${project.artifactId}</finalName>
<!-- resources资源配置项 -->
<resources>
<!-- 通用资源文件 -->
<resource><directory>src/main/resources</directory><includes><include>**/*.*</include></includes></resource>
<!-- 放置通用配置yml文件 开发时仅配置一套参数即可。 实际生产环境下应在每个项目下 与jar同级目录下新建application.yml覆写对应参数。 -->
<resource>
<directory>../conf/devCommons</directory>
<includes><include>**/*.yml</include></includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
<outputDirectory>${session.executionRootDirectory}/target/</outputDirectory>
</configuration> <!-- 包含本地jar文件 -->
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,154 @@
package com.jeequan.jeepay.mgr.aop;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.beans.RequestKitBean;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.security.JeeUserDetails;
import com.jeequan.jeepay.db.entity.SysLog;
import com.jeequan.jeepay.service.impl.SysLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
/**
* 方法级日志切面组件
*
* @author terrfly
* @modify pangxiaoyu
* @date 2021-06-07 07:15
*/
@Component
@Aspect
public class MethodLogAop {
private static final Logger logger = LoggerFactory.getLogger(MethodLogAop.class);
@Autowired
private SysLogService sysLogService;
@Autowired private RequestKitBean requestKitBean;
/**
* 异步处理线程池
*/
private final static ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);
/**
* 切点
*/
@Pointcut("@annotation(com.jeequan.jeepay.core.aop.MethodLog)")
public void methodCachePointcut() { }
/**
* 切面
* @param point
* @return
* @throws Throwable
*/
@Around("methodCachePointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
final SysLog sysLog = new SysLog();
//处理切面任务 发生异常将向外抛出 不记录日志
Object result = point.proceed();
try {
// 基础日志信息
setBaseLogInfo(point, sysLog, JeeUserDetails.getCurrentUserDetails());
if (result != null) {
sysLog.setOptResInfo(JSONObject.toJSON(result).toString());
}
scheduledThreadPool.execute(() -> sysLogService.save(sysLog));
} catch (Exception e) {
logger.error("methodLogError", e);
}
return result;
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 14:04
* @describe: 记录异常操作请求信息
*/
@AfterThrowing(pointcut = "methodCachePointcut()", throwing="e")
public void doException(JoinPoint joinPoint, Throwable e) throws Exception{
final SysLog sysLog = new SysLog();
// 基础日志信息
setBaseLogInfo(joinPoint, sysLog, JeeUserDetails.getCurrentUserDetails());
sysLog.setOptResInfo(e instanceof BizException ? e.getMessage() : "请求异常");
scheduledThreadPool.execute(() -> sysLogService.save(sysLog));
}
/**
* 获取方法中的中文备注
* @param joinPoint
* @return
* @throws Exception
*/
public static String getAnnotationRemark(JoinPoint joinPoint) throws Exception {
Signature sig = joinPoint.getSignature();
Method m = joinPoint.getTarget().getClass().getMethod(joinPoint.getSignature().getName(), ((MethodSignature) sig).getParameterTypes());
MethodLog methodCache = m.getAnnotation(MethodLog.class);
if (methodCache != null) {
return methodCache.remark();
}
return "";
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 14:12
* @describe: 日志基本信息 公共方法
*/
private void setBaseLogInfo(JoinPoint joinPoint, SysLog sysLog, JeeUserDetails userDetails) throws Exception {
// 使用point.getArgs()可获取request仅限于spring MVC参数包含request改为通过contextHolder获取。
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//请求参数
sysLog.setOptReqParam( requestKitBean.getReqParamJSON().toJSONString() );
//注解备注
sysLog.setMethodRemark(getAnnotationRemark(joinPoint));
//包名 方法名
String methodName = joinPoint.getSignature().getName();
String packageName = joinPoint.getThis().getClass().getName();
if (packageName.indexOf("$$EnhancerByCGLIB$$") > -1 || packageName.indexOf("$$EnhancerBySpringCGLIB$$") > -1) { // 如果是CGLIB动态生成的类
packageName = packageName.substring(0, packageName.indexOf("$$"));
}
sysLog.setMethodName(packageName + "." + methodName);
sysLog.setReqUrl(request.getRequestURL().toString());
sysLog.setUserIp(requestKitBean.getClientIp());
sysLog.setCreatedAt(new Date());
sysLog.setSysType(CS.SYS_ROLE_TYPE.PLATFORM);
if (userDetails != null) {
sysLog.setUserId(userDetails.getSysUser().getSysUserId());
sysLog.setUserName(userDetails.getSysUser().getRealname());
sysLog.setSysType(userDetails.getSysUser().getSysType());
}
}
}

View File

@@ -0,0 +1,70 @@
package com.jeequan.jeepay.mgr.bootstrap;
import cn.hutool.core.date.DatePattern;
import cn.hutool.crypto.SmUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.jeequan.jeepay.mgr.config.SystemYmlConfig;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.Date;
/*
* 项目初始化操作
* 比如初始化配置文件, 读取基础数据, 资源初始化等。 避免在Main函数中写业务代码。
* CommandLineRunner / ApplicationRunner都可以达到要求 只是调用参数有所不同。
*
*
* @author terrfly
*
* @date 2021/6/8 17:04
*/
@Component
public class InitRunner implements CommandLineRunner {
@Autowired private SystemYmlConfig systemYmlConfig;
@Autowired private SysConfigService sysConfigService;
@Override
public void run(String... args) throws Exception {
// 配置是否使用缓存模式
SysConfigService.IS_USE_CACHE = systemYmlConfig.getCacheConfig();
// 初始化系统秘钥
SysConfigService.DB_ENCRYPT_SECRET = systemYmlConfig.getDbEncryptSecret();
SysConfigService.DB_ENCRYPT_SM4 = SmUtil.sm4(SysConfigService.DB_ENCRYPT_SECRET.getBytes());
SysConfigService.HTTP_MESSAGE_ENCRYPT_SECRET = systemYmlConfig.getHttpMessageEncryptSecret();
SysConfigService.HTTP_MESSAGE_ENCRYPT_SM4 = SmUtil.sm4(SysConfigService.HTTP_MESSAGE_ENCRYPT_SECRET.getBytes());
// 检查是否支持服务商
SysConfigService.IS_HAS_AGENT_ENT = sysConfigService.getById(SysConfigService.AGENT_ENT_CONFIG) != null;
// 检查是否支持会员
SysConfigService.IS_HAS_MEMBER_ENT = sysConfigService.getById(SysConfigService.MEMBER_ENT_CONFIG) != null;
// 配置是否通信加密 和 密码修改
SysConfigService.HTTP_MSG_IS_ENCRYPT = sysConfigService.getDBSecurityConfig().httpMsgIsEncrypt();
SysConfigService.PWD_EXPIRED_MUST_RESET = sysConfigService.getDBSecurityConfig().passwordExpiredIsMustModify();
// 配置 平台通信秘钥
SysConfigService.PLATFORM_API_SECRET = sysConfigService.getDBSecurityConfig().getPlatformApiSecret();
//初始化处理fastjson格式
SerializeConfig serializeConfig = SerializeConfig.getGlobalInstance();
serializeConfig.put(Date.class, new SimpleDateFormatSerializer(DatePattern.NORM_DATETIME_PATTERN));
//解决json 序列化时候的 $ref问题
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
}
}

View File

@@ -0,0 +1,86 @@
package com.jeequan.jeepay.mgr.bootstrap;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.util.Arrays;
/*
* spring-boot 主启动程序
*
* @author terrfly
*
* @date 2019/11/7 15:19
*/
@SpringBootApplication
@EnableScheduling
@MapperScan("com.jeequan.jeepay.service.mapper") //Mybatis mapper接口路径
@ComponentScan(basePackages = "com.jeequan.jeepay.*") //由于MainApplication没有在项目根目录 需要配置basePackages属性使得成功扫描所有Spring组件
@Configuration
public class JeepayMgrApplication {
/** main启动函数 **/
public static void main(String[] args) {
//启动项目
SpringApplication.run(JeepayMgrApplication.class, args);
}
/** 支持搜索 {} [] 否则 springboot 提示 HTTP Status 400 Bad Request **/
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory (){
// 修改内置的 tomcat 容器配置
TomcatServletWebServerFactory tomcatServlet = new TomcatServletWebServerFactory();
tomcatServlet.addConnectorCustomizers( connector -> connector.setProperty("relaxedQueryChars", "[]{}") );
return tomcatServlet ;
}
/** fastJson 配置信息 **/
@Bean
public HttpMessageConverters fastJsonConfig(){
// 开启 FastJSON 安全模式!
ParserConfig.getGlobalInstance().setSafeMode(true);
//新建fast-json转换器
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
//fast-json 配置信息
FastJsonConfig config = new FastJsonConfig();
config.setDateFormat("yyyy-MM-dd HH:mm:ss");
converter.setFastJsonConfig(config);
//设置响应的 Content-Type
converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8));
return new HttpMessageConverters(converter);
}
/** Mybatis plus 分页插件 **/
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
}

View File

@@ -0,0 +1,70 @@
package com.jeequan.jeepay.mgr.config;
import com.jeequan.jeepay.core.cache.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
/*
* Redis配置类
*
* @author terrfly
*
* @date 2021/6/8 17:05
*/
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private Integer port;
@Value("${spring.redis.timeout}")
private Integer timeout;
@Value("${spring.redis.database}")
private Integer defaultDatabase;
@Value("${spring.redis.password}")
private String password;
/** 作用:不同系统的前缀。 a.当连接不同的database时可以为空(物理隔离) b.当redis集群时因为必须同一个database所以需通过前缀区分不同系统的业务。 **/
@Value("${spring.redis.sys-prefix-key}")
private String sysPrefixKey;
/** 当前系统的redis缓存操作对象 (主对象) **/
@Primary
@Bean(name = "defaultStringRedisTemplate")
public StringRedisTemplate sysStringRedisTemplate() {
// 赋值前缀key
RedisUtil.SYS_PREFIX_KEY = sysPrefixKey;
StringRedisTemplate template = new StringRedisTemplate();
LettuceConnectionFactory jedisConnectionFactory = new LettuceConnectionFactory();
jedisConnectionFactory.setHostName(host);
jedisConnectionFactory.setPort(port);
jedisConnectionFactory.setTimeout(timeout);
if (!StringUtils.isEmpty(password)) {
jedisConnectionFactory.setPassword(password);
}
if (defaultDatabase != 0) {
jedisConnectionFactory.setDatabase(defaultDatabase);
}
jedisConnectionFactory.afterPropertiesSet();
template.setConnectionFactory(jedisConnectionFactory);
return template;
}
}

View File

@@ -0,0 +1,43 @@
package com.jeequan.jeepay.mgr.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 系统Yml配置参数定义Bean
*
* @author terrfly
*
* @date 2021-04-27 15:50
*/
@Data
@Component
@ConfigurationProperties(prefix="isys")
public class SystemYmlConfig {
/** 是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时应开启此配置或在nginx统一配置允许跨域] **/
private Boolean allowCors;
/** 生成jwt的秘钥。 要求每个系统有单独的秘钥管理机制。 **/
private String jwtSecret;
/** DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!] **/
private String dbEncryptSecret;
/** web传输加解密 秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!] **/
private String httpMessageEncryptSecret;
/** 支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更! **/
private String sysRSA2PrivateKey;
/**支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更! **/
private String sysRSA2PublicKey;
/** 是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常 false表示直接查询DB. **/
private Boolean cacheConfig;
}

View File

@@ -0,0 +1,174 @@
package com.jeequan.jeepay.mgr.ctrl;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.ctrls.AbstractCtrl;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.BaseModel;
import com.jeequan.jeepay.core.model.security.JeeUserDetails;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mgr.config.SystemYmlConfig;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/*
* 定义通用CommonCtrl
*
* @author terrfly
*
* @date 2021/6/8 17:09
*/
public abstract class CommonCtrl extends AbstractCtrl {
@Autowired protected SystemYmlConfig mainConfig;
@Autowired protected PayInterfaceDefineService payInterfaceDefineService;
@Autowired protected MchInfoService mchInfoService;
@Autowired protected MchStoreService mchStoreService;
@Autowired protected AgentInfoService agentInfoService;
@Autowired protected SysConfigService sysConfigService;
@Autowired protected MchApplymentService mchApplymentService;
/** 获取当前用户ID */
protected JeeUserDetails getCurrentUser(){
return (JeeUserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
/**
* 获取当前用户登录IP
* @return
*/
protected String getIp() {
return getClientIp();
}
/** model 存入商户名称 **/
public void setMchName(List<? extends BaseModel> modeList) {
if(modeList == null || modeList.isEmpty()){
return ;
}
ArrayList<String> mchNoList = new ArrayList<>();
for (BaseModel model:modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String mchNo = json.getString("mchNo");
mchNoList.add(mchNo);
}
List<MchApplyment> mchInfoList = mchApplymentService.list(MchApplyment.gw().select(MchApplyment::getMchNo, MchApplyment::getMchFullName,MchApplyment::getMchShortName).in(MchApplyment::getMchNo, mchNoList));
for (BaseModel model:modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String mchNo = json.getString("mchNo");
if(StringUtils.isBlank(mchNo)) {
continue;
}
for (MchApplyment info:mchInfoList) {
if (mchNo.equals(info.getMchNo())) {
model.addExt("mchName", info.getMchFullName());
model.addExt("mchShortName", info.getMchShortName());
}
}
}
}
/** model 存入门店名称 **/
public void setStoreName(List<? extends BaseModel> modeList) {
if(modeList == null || modeList.isEmpty()){
return ;
}
ArrayList<String> storeIdList = new ArrayList<>();
for (BaseModel model:modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String storeId = json.getString("storeId");
storeIdList.add(storeId);
}
List<MchStore> mchInfoList = mchStoreService.list(MchStore.gw().select(MchStore::getStoreId, MchStore::getStoreName).in(MchStore::getStoreId, storeIdList));
for (BaseModel model:modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String storeId = json.getString("storeId");
if(storeId == null) {
continue;
}
for (MchStore store : mchInfoList) {
if (storeId.equals(store.getStoreId())) {
model.addExt("storeName", store.getStoreName());
}
}
}
}
/** model 存入支付接口名称 **/
public void setIfName(List<? extends BaseModel> modeList) {
if(modeList == null || modeList.isEmpty()){
return ;
}
ArrayList<String> ifCodeList = new ArrayList<>();
for (BaseModel model:modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String ifCode = json.getString("ifCode");
ifCodeList.add(ifCode);
}
List<PayInterfaceDefine> defineList = payInterfaceDefineService.list(PayInterfaceDefine.gw().select(PayInterfaceDefine::getIfCode, PayInterfaceDefine::getIfName).in(PayInterfaceDefine::getIfCode, ifCodeList));
for (BaseModel model : modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String ifCode = json.getString("ifCode");
if(StringUtils.isBlank(ifCode)) {
continue;
}
for (PayInterfaceDefine define : defineList) {
if (ifCode.equals(define.getIfCode())) {
model.addExt("ifName", define.getIfName());
}
}
}
}
/** 根据服务商号查询服务商下的商户号List **/
public List<String> getMchNoListByAgentNo(String agentNo) {
if (StringUtils.isBlank(agentNo)) {
return null;
}
AgentInfo agentInfo = agentInfoService.getById(agentNo);
if (agentInfo == null || agentInfo.getState() != CS.YES) {
throw new BizException("服务商不存在或状态不正确");
}
List<MchInfo> list = mchInfoService.list(MchInfo.gw().eq(com.jeequan.jeepay.core.entity.MchInfo::getAgentNo, agentNo));
if (CollUtil.isEmpty(list)) {
return null;
}
List<String> mchNoList = new LinkedList<>();
list.forEach(mchInfo -> mchNoList.add(mchInfo.getMchNo()));
return mchNoList;
}
/** 会员头像地址默认值获取 **/
public String getMemberAvatarDefault() {
Collections.shuffle(CS.MEMBER_AVATAR_ICON);
return CS.MEMBER_AVATAR_ICON.get(0);
}
}

View File

@@ -0,0 +1,214 @@
package com.jeequan.jeepay.mgr.ctrl;
import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.converter.BaseConverter;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.cache.ITokenService;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.security.JeeUserDetails;
import com.jeequan.jeepay.core.utils.TreeDataBuilder;
import com.jeequan.jeepay.core.utils.google.GoogleAuth;
import com.jeequan.jeepay.db.entity.SysEntitlement;
import com.jeequan.jeepay.db.entity.SysUserEntity;
import com.jeequan.jeepay.service.impl.SysConfigService;
import com.jeequan.jeepay.service.impl.SysEntitlementService;
import com.jeequan.jeepay.service.impl.SysUserAuthService;
import com.jeequan.jeepay.service.impl.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
* 当前登录者的信息相关接口
*
* @author terrfly
*
* @date 2021/6/8 17:10
*/
@RestController
@RequestMapping("api/current")
public class CurrentUserController extends CommonCtrl{
@Autowired private SysEntitlementService sysEntitlementService;
@Autowired private SysUserService sysUserService;
@Autowired private SysUserAuthService sysUserAuthService;
@Autowired private BaseConverter baseConverter;
@RequestMapping(value="/user", method = RequestMethod.GET)
public ApiRes currentUserInfo() {
///当前用户信息
JeeUserDetails jeeUserDetails = getCurrentUser();
SysUser user = jeeUserDetails.getSysUser();
//1. 当前用户所有权限ID集合
List<String> entIdList = new ArrayList<>();
jeeUserDetails.getAuthorities().stream().forEach(r->entIdList.add(r.getAuthority()));
List<SysEntitlement> allMenuList = new ArrayList<>(); //所有菜单集合
//2. 查询出用户所有菜单集合 (包含左侧显示菜单 和 其他类型菜单 )
if(!entIdList.isEmpty()){
allMenuList = sysEntitlementService.list(SysEntitlement.gw()
.in(SysEntitlement::getEntId, entIdList)
.in(SysEntitlement::getEntType, Arrays.asList(CS.ENT_TYPE.MENU_LEFT, CS.ENT_TYPE.MENU_OTHER))
.eq(SysEntitlement::getSysType, CS.SYS_ROLE_TYPE.PLATFORM)
.eq(SysEntitlement::getState, CS.PUB_USABLE));
}
//4. 转换为json树状结构
JSONArray jsonArray = (JSONArray) JSON.toJSON(allMenuList);
List<JSONObject> allMenuRouteTree = new TreeDataBuilder(jsonArray,
"entId", "pid", "children", "entSort", true)
.buildTreeObject();
//5. 所有权限ID集合
user.addExt("entIdList", entIdList);
user.addExt("allMenuRouteTree", allMenuRouteTree);
// 6. 程序是否支持服务商
user.addExt("isHasAgentEnt", SysConfigService.IS_HAS_AGENT_ENT);
// 7. 程序是否支持会员
user.addExt("isHasMemberEnt", SysConfigService.IS_HAS_MEMBER_ENT);
return ApiRes.ok(getCurrentUser().getSysUser());
}
/** 修改个人信息 */
@RequestMapping(value="/user", method = RequestMethod.PUT)
@MethodLog(remark = "修改信息")
public ApiRes modifyCurrentUserInfo() {
//修改头像
String avatarUrl = getValString("avatarUrl");
String realname = getValString("realname");
Byte sex = getValByte("sex");
//编辑预留信息
String safeWord = getValString("safeWord");
SysUserEntity updateRecord = new SysUserEntity();
updateRecord.setSysUserId(getCurrentUser().getSysUser().getSysUserId());
if (StringUtils.isNotEmpty(avatarUrl)) {
updateRecord.setAvatarUrl(avatarUrl);
}
if (StringUtils.isNotEmpty(realname)) {
updateRecord.setRealname(realname);
}
if (sex != null) {
updateRecord.setSex(sex);
}
if (StringUtils.isNotEmpty(safeWord)) {
updateRecord.setSafeWord(safeWord);
}
sysUserService.updateById(updateRecord);
SysUserEntity sysUserEntity = sysUserService.getById(getCurrentUser().getSysUser().getSysUserId());
//保存redis最新数据
JeeUserDetails currentUser = getCurrentUser();
currentUser.setSysUser(baseConverter.toModel(sysUserEntity));
ITokenService.refData(currentUser);
return ApiRes.ok();
}
/** 修改密码 */
@RequestMapping(value="modifyPwd", method = RequestMethod.PUT)
@MethodLog(remark = "修改密码")
public ApiRes modifyPwd() throws BizException{
//更改密码,验证当前用户信息
String currentUserPwd = Base64.decodeStr(getValStringRequired("originalPwd")); //当前用户登录密码
//验证当前密码是否正确
if(!sysUserAuthService.validateCurrentUserPwd(currentUserPwd)){
throw new BizException("原密码验证失败!");
}
String opUserPwd = Base64.decodeStr(getValStringRequired("confirmPwd"));
// 验证原密码与新密码是否相同
if (opUserPwd.equals(currentUserPwd)) {
throw new BizException("新密码与原密码不能相同!");
}
sysUserAuthService.resetAuthInfo(getCurrentUser().getSysUser().getSysUserId(), null, null, true, opUserPwd, CS.SYS_ROLE_TYPE.PLATFORM);
//调用登出接口
return logout();
}
// /** 登出 */
// @RequestMapping(value="logout", method = RequestMethod.POST)
// @MethodLog(remark = "登出")
public ApiRes logout() throws BizException{
ITokenService.removeIToken(getCurrentUser().getCacheKey(), getCurrentUser().getSysUser().getSysUserId());
return ApiRes.ok();
}
/** MFA验证信息 */
@GetMapping("/mfaInfo")
@MethodLog(remark = "MFA验证信息")
public ApiRes mfaInfo() throws BizException{
SysUserEntity currentUser = sysUserService.getById(getCurrentUser().getSysUserId());
JSONObject resJson = new JSONObject();
resJson.put("mfaBindState", currentUser.getMfaBindState());
resJson.put("telPhone", currentUser.getTelphone());
// 是否展示MFA绑定信息 [未绑定时显示]
if (currentUser.getMfaBindState() == CS.NO) {
String secretKey = sysUserService.getById(currentUser.getSysUserId()).getMfaSecretKey();
// 更新用户验证秘钥
if (StringUtils.isEmpty(secretKey)) {
secretKey = GoogleAuth.generateSecretKey();
sysUserService.updateMFASecret(currentUser.getSysUserId(), secretKey, null);
}
String qrcodeUrl = GoogleAuth.getQRBarcode(
sysConfigService.getOemConfig().getSysName() + "_运营" +"("+ currentUser.getTelphone() + ")"
, secretKey);
resJson.put("mfaBindUrl", qrcodeUrl);
resJson.put("mfaSecretKey", secretKey);
}
return ApiRes.ok(resJson);
}
/** MFA验证 绑定 */
@RequestMapping(value="mfaBind", method = RequestMethod.PUT)
@MethodLog(remark = "MFA验证绑定")
public ApiRes mfaBind() throws BizException{
String verCode = getValStringRequired("verCode");
Long userId = getCurrentUser().getSysUserId();
// 验证验证码
sysUserService.checkMFACode(userId, verCode);
// 绑定MFA验证
sysUserService.bindMFA(userId);
return ApiRes.ok();
}
/** MFA验证 解绑 */
@RequestMapping(value="mfaRelieve", method = RequestMethod.PUT)
@MethodLog(remark = "MFA验证解除")
public ApiRes mfaRelieve() throws BizException{
String verCode = getValStringRequired("verCode");
Long userId = getCurrentUser().getSysUserId();
// 验证验证码
sysUserService.checkMFACode(userId, verCode);
// 解除MFA验证
sysUserService.relieveMFA(userId, CS.SYS_ROLE_TYPE.PLATFORM);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,45 @@
package com.jeequan.jeepay.mgr.ctrl.account;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.exception.ChannelException;
import com.jeequan.jeepay.core.interfaces.paychannel.IRepayApiService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBPaymentConfig;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.AccountChangeInfo;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.mgr.service.ChannelApiService;
import com.jeequan.jeepay.service.impl.AccountChangeInfoService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/**
* TODO
*
* @author crystal
* @date 2023/12/6 15:11
*/
@RestController
@RequestMapping("/api/accountChange")
public class AccountChangeInfoController extends CommonCtrl {
@Autowired private AccountChangeInfoService accountChangeInfoService;
@Autowired private ChannelApiService channelApiService;
@PreAuthorize("hasAuthority('ENT_ACCOUNT_CHANGE_LIST')")
@GetMapping
public ApiRes list() {
AccountChangeInfo info = getObject(AccountChangeInfo.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<AccountChangeInfo> wrapper = AccountChangeInfo.gw(info);
Page<AccountChangeInfo> pages = accountChangeInfoService.pageList(getIPage(),wrapper,info,paramJSON);
return ApiRes.page(pages);
}
}

View File

@@ -0,0 +1,55 @@
package com.jeequan.jeepay.mgr.ctrl.account;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.AccountFundInfo;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.mgr.service.ChannelApiService;
import com.jeequan.jeepay.service.impl.AccountFundInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* TODO
* 账户资金明细
* @author crystal
* @date 2024/3/28 16:18
*/
@RestController
@RequestMapping("/api/accountFund")
public class AccountFundInfoController extends CommonCtrl {
@Autowired
private AccountFundInfoService accountFundInfoService;
@Autowired private ChannelApiService channelApiService;
// @PreAuthorize("hasAuthority('ENT_ACCOUNT_FUND_LIST')")
@GetMapping
public ApiRes list() {
AccountFundInfo info = getObject(AccountFundInfo.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<AccountFundInfo> wrapper = AccountFundInfo.gw(info);
Page<AccountFundInfo> pages = accountFundInfoService.pageList(getIPage(),wrapper,info,paramJSON);
return ApiRes.page(pages);
}
/**
* 确认操作
* @return
*/
@PreAuthorize("hasAuthority('ENT_ACCOUNT_FUND_CONFIRM')")
@PostMapping("/confirm")
public ApiRes confirm() {
AccountFundInfo info = getObject(AccountFundInfo.class);
channelApiService.confirm(info);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,61 @@
package com.jeequan.jeepay.mgr.ctrl.account;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.ApiField;
import com.jeequan.jeepay.JeepayClient;
import com.jeequan.jeepay.components.mq.model.AccountBalanceMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.cache.RedisUtil;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.AccountOperate;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBApplicationConfig;
import com.jeequan.jeepay.core.model.DBDefaultConfig;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.exception.JeepayException;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.model.DeviceInfo;
import com.jeequan.jeepay.model.JeepayObject;
import com.jeequan.jeepay.request.PayOrderCreateRequest;
import com.jeequan.jeepay.response.PayOrderCreateResponse;
import com.jeequan.jeepay.service.impl.*;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.List;
/**
* TODO
*
* @author crystal
* @date 2023/12/6 15:11
*/
@RestController
@RequestMapping("/api/account")
public class AccountInfoController extends CommonCtrl {
@Autowired private AccountInfoService accountInfoService;
@Autowired private PayOrderService payOrderService;
/**
* 获取订单关联的参数
* @return
*/
@GetMapping("/{payOrderId}")
public ApiRes getOrderAccount(@PathVariable("payOrderId") String payOrderId) {
AccountInfo info = getObject(AccountInfo.class);
PayOrder order = payOrderService.getById(payOrderId);
if(order == null){
throw new BizException("非法参数");
}
List<AccountInfo> res = accountInfoService.getAccountInfo(info,order.getMchNo());
return ApiRes.ok(res);
}
}

View File

@@ -0,0 +1,38 @@
package com.jeequan.jeepay.mgr.ctrl.account;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.InfoAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/***
* 钱包ctrl
*
* @author terrfly
*
* @date 2022/3/24 15:34
*/
@RestController
@RequestMapping("/api/account")
public class InfoAccountController extends CommonCtrl {
@Autowired private InfoAccountService infoAccountService;
/** 平台利润钱包 **/
@PreAuthorize("hasAuthority('ENT_PROFIT_PLATFORM')")
@GetMapping("/platformProfit")
public ApiRes platformProfit() {
JSONObject jsonObject = new JSONObject();
jsonObject.put(CS.INFO_ID_ENUM.PLATFORM_PROFIT, infoAccountService.queryPlatformAccount(CS.INFO_ID_ENUM.PLATFORM_PROFIT));
jsonObject.put(CS.INFO_ID_ENUM.PLATFORM_INACCOUNT, infoAccountService.queryPlatformAccount(CS.INFO_ID_ENUM.PLATFORM_INACCOUNT));
return ApiRes.ok(jsonObject);
}
}

View File

@@ -0,0 +1,53 @@
package com.jeequan.jeepay.mgr.ctrl.account;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.InfoAccountHistory;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.InfoAccountHistoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 钱包流水
*
* @author xiaoyu
*
* @date 2022/3/23 14:20
*/
@RestController
@RequestMapping("/api/accountHistory")
public class InfoAccountHistoryController extends CommonCtrl {
@Autowired private InfoAccountHistoryService infoAccountHistoryService;
/**
* @author: xiaoyu
* @date: 2022/3/23 14:34
* @describe: 钱包流水
*/
@PreAuthorize("hasAuthority('ENT_ACCOUNT_HISTORY_LIST')")
@GetMapping
public ApiRes list() {
InfoAccountHistory history = getObject(InfoAccountHistory.class);
IPage<InfoAccountHistory> pages = infoAccountHistoryService.listByPage(getIPage(), history);
return ApiRes.page(pages);
}
/**
* @author: xiaoyu
* @date: 2022/3/23 14:34
* @describe: 钱包流水详情
*/
@PreAuthorize("hasAuthority('ENT_ACCOUNT_HISTORY_VIEW')")
@GetMapping("/{hid}")
public ApiRes detail(@PathVariable("hid") String hid) {
return ApiRes.ok(infoAccountHistoryService.getById(hid));
}
}

View File

@@ -0,0 +1,252 @@
package com.jeequan.jeepay.mgr.ctrl.agent;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.AgentConfig;
import com.jeequan.jeepay.db.entity.ThirdAuthDataEntity;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.AgentConfigService;
import com.jeequan.jeepay.service.impl.ThirdAuthDataService;
import com.jeequan.jeepay.thirdparty.service.SaasConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* 服务商服务商配置管理类
*
* @author yr
*
* @date 2023-03-30 14:15
*/
@RestController
@RequestMapping("/api/agentConfig")
public class AgentConfigController extends CommonCtrl {
@Autowired
private AgentConfigService agentConfigService;
@Autowired
private SaasConfigService saasConfigService;
@Autowired
private ThirdAuthDataService thirdAuthDataService;
/**
* 查询服务商配置
*/
@PreAuthorize("hasAuthority('ENT_AGENT_CONFIG_PAGE')")
@GetMapping
public ApiRes list() {
String groupKey = getValString("groupKey");
String configKey = getValString("configKey");
LambdaQueryWrapper<AgentConfig> queryWrapper = AgentConfig.gw().eq(AgentConfig::getAgentNo, getValStringRequired("agentNo"));
if (StringUtils.isNotBlank(groupKey)) {
queryWrapper.eq(AgentConfig::getGroupKey, groupKey);
}
if (StringUtils.isNotBlank(configKey)) {
queryWrapper.eq(AgentConfig::getConfigKey, configKey);
}
List<AgentConfig> list = agentConfigService.list(queryWrapper);
return ApiRes.ok(list);
}
/**
* 根据configKey查询服务商配置
*/
@PreAuthorize("hasAuthority('ENT_AGENT_CONFIG_PAGE')")
@GetMapping("/{configKey}")
public ApiRes get(@PathVariable("configKey") String configKey) {
AgentConfig agentConfig = agentConfigService.getOne(AgentConfig.gw().eq(AgentConfig::getAgentNo, getValStringRequired("agentNo")).eq(AgentConfig::getConfigKey, configKey));
return ApiRes.ok(agentConfig);
}
/**
* 批量更新服务商配置信息
*/
@PreAuthorize("hasAuthority('ENT_AGENT_CONFIG_PAGE')")
@MethodLog(remark = "批量更新服务商配置信息")
@PutMapping("/{groupKey}")
public ApiRes updateBatch(@PathVariable("groupKey") String groupKey) {
String params = getValStringRequired("configData");
List<AgentConfig> agentConfigList = JSONArray.parseArray(params, AgentConfig.class);
// 判断是否需要同步当前及下级所有服务商
String ifUpdateAllSubAgent = getValString("updateType");
int update;
if (StringUtils.isNotEmpty(ifUpdateAllSubAgent) && ifUpdateAllSubAgent.equals(AgentConfig.IF_ALL_CURRENT_AND_SUB_AGENT)) {
update = agentConfigService.updateBatchAll(agentConfigList, getValStringRequired("agentNo"), groupKey);
} else {
update = agentConfigService.updateBatch(agentConfigList, getValStringRequired("agentNo"), groupKey);
}
if (update <= 0) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* 服务商贴牌配置信息更新or新增
*/
@MethodLog(remark = "更新服务商贴牌信息")
@PutMapping("/updateOem")
public ApiRes updateOem() {
AgentConfig agentConfig = new AgentConfig();
List<AgentConfig> agentConfigList = new ArrayList<>();
String groupKey = getValStringRequired("groupKey");
//String configKey = getValStringRequired("configKey");
String agentNo = getValStringRequired("agentNo");
JSONObject paramJSON = getReqParamJSON();
Map<String, String> updateMap = new HashMap<>();
//平台配置
if ("oemConfig".equals(groupKey)) {
try {
//paramJSON.put("mgr", paramJSON.getJSONObject("mgr"));
paramJSON.put("mch", paramJSON.getJSONObject("mch"));
paramJSON.put("agent", paramJSON.getJSONObject("agent"));
paramJSON.put("reportIcp", paramJSON.getJSONObject("reportIcp"));
paramJSON.put("reportGa", paramJSON.getJSONObject("reportGa"));
paramJSON.put("reportJh", paramJSON.getJSONObject("reportJh"));
paramJSON.put("reportDx", paramJSON.getJSONObject("reportDx"));
paramJSON.put("copyrightInfo", paramJSON.getJSONObject("copyrightInfo"));
updateMap.put("oemConfig", paramJSON.toJSONString());
agentConfig.setAgentNo(agentNo);
agentConfig.setConfigKey(groupKey);
agentConfig.setGroupKey(groupKey);
agentConfig.setConfigVal(updateMap.get("oemConfig"));
agentConfig.setCreatedAt(new Date());
agentConfig.setUpdatedAt(new Date());
agentConfigList.add(agentConfig);
} catch (Exception e) {
throw new BizException("参数解析错误!");
}
} else if ("treatyConfig".equals(groupKey)) {
paramJSON.remove("groupKey");
paramJSON.remove("agentNo");
Map<String, String> map = JSONObject.toJavaObject(paramJSON, Map.class);
for (String key : map.keySet()) {
// 记录为空 = 不更新
if (StringUtils.isEmpty(map.get(key))) {
continue;
}
agentConfig = new AgentConfig();
agentConfig.setAgentNo(agentNo);
agentConfig.setConfigKey(key);
agentConfig.setGroupKey(groupKey);
agentConfig.setConfigVal(map.get(key));
agentConfig.setCreatedAt(new Date());
agentConfig.setUpdatedAt(new Date());
agentConfigList.add(agentConfig);
}
}
int updateOem = agentConfigService.updateOem(agentConfigList);
if (updateOem <= 0) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
@GetMapping("/siteConfig")
public ApiRes getSiteConfig() {
String agentNo = getValStringRequired("agentNo");
List<AgentConfig> agentSiteConfig = agentConfigService.lambdaQuery()
.eq(AgentConfig::getGroupKey, "agentSiteConfig")
.eq(AgentConfig::getAgentNo, agentNo)
.list();
Map<String, Object> result = new HashMap<>();
agentSiteConfig.forEach(item -> {
result.put(item.getConfigKey(), item.getConfigVal());
});
return ApiRes.ok(result);
}
@PostMapping("/siteConfig")
public ApiRes setSiteConfig() {
String agentNo = getValStringRequired("agentNo");
String agentSiteUrl = getValStringRequired("agentSiteUrl");
String agentSiteCrtUrl = getValStringRequired("agentSiteCrtUrl");
String agentSitePriKeyUrl = getValStringRequired("agentSitePriKeyUrl");
String mchSiteUrl = getValStringRequired("mchSiteUrl");
String mchSiteCrtUrl = getValStringRequired("mchSiteCrtUrl");
String mchSitePriKeyUrl = getValStringRequired("mchSitePriKeyUrl");
saasConfigService.siteConfig(agentNo, agentSiteUrl, agentSiteCrtUrl, agentSitePriKeyUrl, mchSiteUrl, mchSiteCrtUrl, mchSitePriKeyUrl);
return ApiRes.ok();
}
@GetMapping("/authData")
public ApiRes authData() {
Page<ThirdAuthDataEntity> iPage = getIPage();
String agentNo = getValStringRequired("agentNo");
String type = getValStringRequired("type");
Page<ThirdAuthDataEntity> page = thirdAuthDataService.lambdaQuery()
.eq(ThirdAuthDataEntity::getAgentNo, agentNo)
.eq(ThirdAuthDataEntity::getType, type)
.page(iPage);
return ApiRes.ok(page);
}
@DeleteMapping("/authData/{id}")
public ApiRes removeAuthData(@PathVariable("id") Long id) {
thirdAuthDataService.removeById(id);
return ApiRes.ok();
}
@PostMapping("/authData")
public ApiRes addAuthData() {
ThirdAuthDataEntity entity = getObject(ThirdAuthDataEntity.class);
Assert.notNull(entity.getType(), "授权渠道[type]不能为空");
Assert.notNull(entity.getSubType(), "授权类型[subType]不能为空");
Assert.notNull(entity.getAuthFileName(), "文件名称[authFileName]不能为空");
Assert.notNull(entity.getValue(), "文件内容[value]不能为空");
ThirdAuthDataEntity one = thirdAuthDataService.lambdaQuery()
.eq(ThirdAuthDataEntity::getAuthFileName, entity.getAuthFileName())
.one();
if (one != null) {
throw new BizException("数据已存在");
}
thirdAuthDataService.save(entity);
return ApiRes.ok();
}
@PostMapping("/config")
public ApiRes setConfig() {
AgentConfig reqParam = getObject(AgentConfig.class);
Assert.notNull(reqParam, "缺少参数");
Assert.notNull(reqParam.getGroupKey(), "配置分组名称代码[groupKey]不能为空");
Assert.notNull(reqParam.getConfigKey(), "配置名称代码[configKey]不能为空");
Assert.notNull(reqParam.getAgentNo(), "服务商编号[agentNo]不能为空");
Assert.notNull(reqParam.getConfigVal(), "配置项[configVal]未赋值");
agentConfigService.saveOrUpdateConfig(reqParam);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,276 @@
package com.jeequan.jeepay.mgr.ctrl.agent;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.components.mq.model.CleanAgentLoginAuthCacheMQ;
import com.jeequan.jeepay.components.mq.model.ResetIsvMchAppInfoConfigMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.smsconfig.SmsBizDiyContentModel;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.InfoAccount;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.SysUserEntity;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.InfoAccountService;
import com.jeequan.jeepay.service.impl.SysUserAuthService;
import com.jeequan.jeepay.service.impl.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/***
* 服务商管理
*
* @author terrfly
*
* @date 2022/3/15 15:25
*/
@RestController
@RequestMapping("/api/agents")
public class AgentInfoController extends CommonCtrl {
@Autowired
private SysUserAuthService sysUserAuthService;
@Autowired
private InfoAccountService infoAccountService;
@Autowired
private IMQSender mqSender;
@Autowired
private SmsManager smsManager;
@Autowired
private SysUserService sysUserService;
@PreAuthorize("hasAuthority('ENT_AGENT_LIST')")
@RequestMapping(value = "", method = RequestMethod.GET)
public ApiRes list() {
AgentInfo agentInfo = getObject(AgentInfo.class);
LambdaQueryWrapper<AgentInfo> wrapper = AgentInfo.gw();
selectParams(agentInfo, wrapper);
wrapper.orderByDesc(AgentInfo::getCreatedAt);
// 余额查询条件大于该余额服务商
Long balanceAmount = getAmountL("balanceAmount");
if (balanceAmount != null) {
wrapper.exists("select tia.* from t_info_account tia where tia.balance_amount >= " + balanceAmount + " and tia.info_id = t_agent_info.agent_no");
}
IPage<AgentInfo> pages = agentInfoService.page(getIPage(true), wrapper);
Map<Long, AgentInfo> agentInfoMap = new HashMap<>();
List<Long> agentUidList = new ArrayList<>();
// 统计服务商下商户数量
for (AgentInfo info : pages.getRecords()) {
agentInfoMap.put(info.getInitUserId(), info);
// 数据脱敏
info.setContactTel(DesensitizedUtil.mobilePhone(info.getContactTel()));
long count = 0;
if (StringUtils.isEmpty(info.getPid())) {
count = mchInfoService.count(MchInfo.gw().and(i -> {
i.eq(MchInfo::getAgentNo, info.getAgentNo())
.or().eq(MchInfo::getTopAgentNo, info.getAgentNo());
}));
} else {
count = mchInfoService.count(MchInfo.gw().eq(MchInfo::getTopAgentNo, info.getPid()));
}
info.addExt("mchCount", count);
InfoAccount infoAccount = infoAccountService.queryAgentAccount(info.getAgentNo());
info.addExt("balanceAmount", infoAccount == null ? null : infoAccount.getBalanceAmount());
info.addExt("unAmount", infoAccount == null ? null : infoAccount.getUnAmount());
info.addExt("auditProfitAmount", infoAccount == null ? null : infoAccount.getAuditProfitAmount());
agentUidList.add(info.getInitUserId());
}
sysUserService.lambdaQuery()
.in(!CollUtil.isEmpty(agentUidList),SysUserEntity::getSysUserId, agentUidList)
.list().forEach(item -> {
Optional.ofNullable(agentInfoMap.get(item.getSysUserId()))
.ifPresent(agentItem -> {
agentItem.setInviteCode(item.getInviteCode());
});
});
return ApiRes.page(pages);
}
@PreAuthorize("hasAuthority('ENT_AGENT_INFO_ADD')")
@MethodLog(remark = "新增服务商")
@PostMapping
public ApiRes add() {
AgentInfo agentInfo = getObject(AgentInfo.class);
Byte isNotify = getValByteRequired("isNotify");
// 获取传入的服务商登录名、登录密码
String loginPassword = getValString("loginPassword");
if (StringUtils.isBlank(loginPassword)) {
loginPassword = null;
}
agentInfo.setAgentNo("P" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
// 当前登录用户信息
SysUser sysUser = getCurrentUser().getSysUser();
agentInfo.setCreatedUid(sysUser.getSysUserId());
agentInfo.setCreatedBy(sysUser.getRealname());
agentInfoService.addAgentV2(agentInfo, loginPassword, false);
// 发送短信通知
if (isNotify == CS.YES) {
smsManager.sendDiyContentSms(SmsBizDiyContentModel.genUserOpenAccount(agentInfo.getContactTel(), agentInfo.getLoginUsername(), loginPassword));
}
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_AGENT_INFO_DEL')")
@MethodLog(remark = "删除服务商")
@DeleteMapping(value = "/{agentNo}")
public ApiRes delete(@PathVariable("agentNo") String agentNo) {
List<Long> userIdList = agentInfoService.removeByAgentNo(agentNo);
// 推送mq删除redis用户缓存
mqSender.send(CleanAgentLoginAuthCacheMQ.build(userIdList));
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_AGENT_INFO_EDIT')")
@MethodLog(remark = "更新服务商信息")
@PutMapping(value = "/{agentNo}")
public ApiRes update(@PathVariable("agentNo") String agentNo) {
//获取查询条件
AgentInfo agentInfo = getObject(AgentInfo.class);
agentInfo.setAgentNo(agentNo); //设置服务商号主键
agentInfo.setIsvNo(null); // 不允许更改
agentInfo.setLoginUsername(null); // 防止修改用户登录名
boolean resetPass = getReqParamJSON().getBooleanValue("resetPass");
String confirmPwd = null;
if (resetPass) {
confirmPwd = Boolean.TRUE.equals(getReqParamJSON().getBoolean("defaultPass")) ? null : Base64.decodeStr(getValStringRequired("confirmPwd"));
}
// 更新 & 得到需要删除的用户ID的记录
Set<Long> removeCacheUserIdList = agentInfoService.updateAgent(agentInfo, getReqParamJSON(), resetPass, confirmPwd);
// 推送mq删除redis用户认证信息
if (!removeCacheUserIdList.isEmpty()) {
mqSender.send(CleanAgentLoginAuthCacheMQ.build(new ArrayList<>(removeCacheUserIdList)));
}
// 推送mq到目前节点进行更新数据
mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_MCH_INFO, null, agentNo, null));
return ApiRes.ok();
}
@PreAuthorize("hasAnyAuthority('ENT_AGENT_INFO_VIEW', 'ENT_AGENT_INFO_EDIT')")
@RequestMapping(value = "/{agentNo}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("agentNo") String agentNo) {
AgentInfo agentInfo = agentInfoService.getById(agentNo);
if (agentInfo == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
// 服务商钱包信息
InfoAccount account = infoAccountService.queryAgentAccount(agentNo);
if (account != null) {
agentInfo.addExt("balanceAmount", account.getBalanceAmount());
agentInfo.addExt("unAmount", account.getUnAmount());
agentInfo.addExt("auditProfitAmount", account.getAuditProfitAmount());
}
return ApiRes.ok(agentInfo);
}
@PreAuthorize("hasAuthority('ENT_AGENT_BALANCE_CHANGE')")
@MethodLog(remark = "服务商调账")
@RequestMapping(value = "/balanceAmounts/{agentNo}", method = RequestMethod.POST)
public ApiRes balanceAmounts(@PathVariable("agentNo") String agentNo) {
String currentPassword = Base64.decodeStr(getValStringRequired("currentPassword"));
Long changeAmount = getRequiredAmountL("changeAmount");
// 备注
String remark = getValString("remark");
//验证当前密码是否正确
if (!sysUserAuthService.validateCurrentUserPwd(currentPassword)) {
throw new BizException("密码验证失败!");
}
infoAccountService.platformChange(agentNo, CS.SYS_ROLE_TYPE.AGENT, changeAmount, remark);
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_AGENT_INFO_AUDIT')")
@MethodLog(remark = "审核服务商")
@RequestMapping(value = "/audit/{agentNo}", method = RequestMethod.PUT)
public ApiRes audit(@PathVariable("agentNo") String agentNo) {
// 审核备注
String auditRemark = getValString("auditRemark");
// 审核状态
Byte auditState = getValByteDefault("auditState", CS.NO);
// 审核成功/驳回
agentInfoService.auditInfo(agentNo, auditState, auditRemark);
return ApiRes.ok();
}
/**
* 统计
**/
@PreAuthorize("hasAuthority('ENT_AGENT_INFO_COUNT')")
@GetMapping(value = "/count")
public ApiRes count() {
AgentInfo agentInfo = getObject(AgentInfo.class);
LambdaQueryWrapper<AgentInfo> wrapper = AgentInfo.gw();
selectParams(agentInfo, wrapper);
Map<String, Object> result = agentInfoService.countByAccount(wrapper);
return ApiRes.ok(result);
}
/**
* @author: xiaoyu
* @date: 2023/7/10 8:46
* @describe: 查询公共条件
*/
public void selectParams(AgentInfo agentInfo, LambdaQueryWrapper<AgentInfo> wrapper) {
wrapper.eq(StringUtils.isNotEmpty(agentInfo.getAgentNo()), AgentInfo::getAgentNo, agentInfo.getAgentNo());
wrapper.eq(StringUtils.isNotEmpty(agentInfo.getPid()), AgentInfo::getPid, agentInfo.getPid());
wrapper.eq(StringUtils.isNotEmpty(agentInfo.getIsvNo()), AgentInfo::getIsvNo, agentInfo.getIsvNo());
wrapper.like(StringUtils.isNotEmpty(agentInfo.getAgentName()), AgentInfo::getAgentName, agentInfo.getAgentName());
wrapper.eq(agentInfo.getState() != null, AgentInfo::getState, agentInfo.getState());
wrapper.eq(agentInfo.getAddAgentFlag() != null, AgentInfo::getAddAgentFlag, agentInfo.getAddAgentFlag());
wrapper.eq(agentInfo.getAddMchFlag() != null, AgentInfo::getAddMchFlag, agentInfo.getAddMchFlag());
wrapper.like(StringUtils.isNotEmpty(agentInfo.getContactTel()), AgentInfo::getContactTel, agentInfo.getContactTel());
wrapper.like(StringUtils.isNotEmpty(agentInfo.getLoginUsername()), AgentInfo::getLoginUsername, agentInfo.getLoginUsername());
wrapper.eq(agentInfo.getLevel() != null, AgentInfo::getLevel, agentInfo.getLevel());
}
}

View File

@@ -0,0 +1,33 @@
package com.jeequan.jeepay.mgr.ctrl.alipay;
import com.jeequan.jeepay.bizcommons.manage.alipay.AlipayIotDeviceBindManage;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/***
* 支付宝Iot设备-店铺绑定ctrl
*
* @author zx
*
* @date 2023/03/13 15:26
*/
@RestController
@RequestMapping("/api/alipayIot")
public class AlipayIotDeviceBindController extends CommonCtrl {
@Autowired private AlipayIotDeviceBindManage alipayIotDeviceBindManage;
/** 绑定、解绑蚂蚁店铺 **/
@PreAuthorize("hasAuthority('ENT_DEVICE_RUYI_BIND')")
@PostMapping( "/bind/{deviceId}")
public ApiRes bind(@PathVariable("deviceId") Long deviceId) {
return alipayIotDeviceBindManage.bind(null, deviceId, getValByteRequired("alipayBindState"), getValString("storeId"));
}
}

View File

@@ -0,0 +1,54 @@
package com.jeequan.jeepay.mgr.ctrl.alipay;
import com.jeequan.jeepay.bizcommons.manage.alipay.AlipayOpenSpOperationManage;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/***
* 支付宝设备绑定
*
* @author zx
*
* @date 2023/03/13 15:26
*/
@RestController
@RequestMapping("/api/alipaySpOperation")
public class AlipayOpenSpOperationController extends CommonCtrl {
@Autowired private AlipayOpenSpOperationManage alipayOpenSpOperationManage;
/** 获取授权码 **/
@PreAuthorize("hasAnyAuthority('ENT_MCH_ALIPAY_SP_OPERATION')")
@GetMapping( "/queryQrcode")
public ApiRes queryQrcode() {
return alipayOpenSpOperationManage.queryQrcode(getValStringRequired("mchNo"), getValStringRequired("alipayAccount"));
}
/** 发起授权 **/
@PreAuthorize("hasAnyAuthority('ENT_MCH_ALIPAY_SP_OPERATION')")
@PostMapping("/apply")
public ApiRes apply() {
return alipayOpenSpOperationManage.apply(getValStringRequired("mchNo"), getValStringRequired("alipayAccount"));
}
/** 查询支付宝授权结果 **/
@PreAuthorize("hasAnyAuthority('ENT_MCH_ALIPAY_SP_OPERATION')")
@GetMapping("/queryResult")
public ApiRes queryResult() {
return alipayOpenSpOperationManage.queryResult(getValStringRequired("mchNo"));
}
/** 查询当前商户支付宝授权信息 **/
@PreAuthorize("hasAnyAuthority('ENT_MCH_ALIPAY_SP_OPERATION')")
@GetMapping("/authInfo")
public ApiRes authInfo() {
return alipayOpenSpOperationManage.authInfo(getValStringRequired("mchNo"));
}
}

View File

@@ -0,0 +1,61 @@
package com.jeequan.jeepay.mgr.ctrl.alipay;
import com.jeequan.jeepay.bizcommons.manage.alipay.AlipayShopManage;
import com.jeequan.jeepay.core.entity.MchStore;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/***
* 蚂蚁门店ctrl
*
* @author zx
*
* @date 2023/03/13 15:26
*/
@RestController
@RequestMapping("/api/alipayShop")
public class AlipayShopController extends CommonCtrl {
@Autowired private AlipayShopManage alipayShopManage;
/** 查询店铺详情 **/
@PreAuthorize("hasAnyAuthority('ENT_MCH_ALIPAY_SHOP_VIEW', 'ENT_MCH_ALIPAY_SHOP_EDIT')")
@GetMapping( "/{storeId}")
public ApiRes query(@PathVariable("storeId") String storeId) {
return alipayShopManage.query(null, storeId);
}
/** 创建店铺 **/
@PreAuthorize("hasAuthority('ENT_MCH_ALIPAY_SHOP_ADD')")
@PostMapping("/{storeId}")
public ApiRes create(@PathVariable("storeId") String storeId) {
MchStore mchStore = getObject(MchStore.class);
return alipayShopManage.create(null, storeId, mchStore);
}
/** 修改店铺 **/
@PreAuthorize("hasAuthority('ENT_MCH_ALIPAY_SHOP_EDIT')")
@PutMapping("/{storeId}")
public ApiRes update(@PathVariable("storeId") String storeId) {
MchStore mchStore = getObject(MchStore.class);
return alipayShopManage.update(null, storeId, mchStore);
}
/** 关闭店铺 **/
@PreAuthorize("hasAuthority('ENT_MCH_ALIPAY_SHOP_DELETE')")
@DeleteMapping( "/{storeId}")
public ApiRes close(@PathVariable("storeId") String storeId) {
return alipayShopManage.close(null, storeId);
}
/** 根据申请单查询店铺创建结果 **/
@PreAuthorize("hasAuthority('ENT_MCH_ALIPAY_SHOP_STATUS')")
@GetMapping("/createResult/{storeId}")
public ApiRes createResultQuery(@PathVariable("storeId") String storeId) {
return alipayShopManage.createResultQuery(null, storeId);
}
}

View File

@@ -0,0 +1,80 @@
package com.jeequan.jeepay.mgr.ctrl.anon;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.cache.RedisUtil;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.mgr.service.AuthService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/*
* 认证接口
*
* @author terrfly
*
* @date 2021/6/8 17:09
*/
@RestController
@RequestMapping("/api/anon/auth")
public class AuthController extends CommonCtrl {
@Autowired private AuthService authService;
/** 用户信息认证 获取iToken **/
@RequestMapping(value = "/validate", method = RequestMethod.POST)
@MethodLog(remark = "登录认证")
public ApiRes validate() throws BizException {
String account = Base64.decodeStr(getValStringRequired("ia")); //用户名 i account, 已做base64处理
String ipassport = Base64.decodeStr(getValStringRequired("ip")); //密码 i passport, 已做base64处理
String vercode = Base64.decodeStr(getValStringRequired("vc")); //验证码 vercode, 已做base64处理
String vercodeToken = Base64.decodeStr(getValStringRequired("vt")); //验证码token, vercode token , 已做base64处理
String mfaCode = StringUtils.isEmpty(getValString("mc")) ? null : Base64.decodeStr(getValString("mc")); // MFACode, 已做base64处理
// 验证码校验: WEB登录 & 第一次认证MFACode为空的情况
if(StringUtils.isEmpty(mfaCode)){
String cacheCode = RedisUtil.getString(CS.getCacheKeyImgCode(vercodeToken));
if(StringUtils.isEmpty(cacheCode) || !cacheCode.equalsIgnoreCase(vercode)){
throw new BizException("验证码有误!");
}
}
// 返回前端 accessToken
return authService.authByAuthentication(account, ipassport, vercodeToken, mfaCode);
}
/** 图片验证码 **/
@RequestMapping(value = "/vercode", method = RequestMethod.GET)
public ApiRes vercode() throws BizException {
//定义图形验证码的长和宽 // 4位验证码
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(137, 40, 4, 80);
lineCaptcha.createCode(); //生成code
//redis
String vercodeToken = UUID.fastUUID().toString();
RedisUtil.setString(CS.getCacheKeyImgCode(vercodeToken), lineCaptcha.getCode(), CS.VERCODE_CACHE_TIME ); //图片验证码缓存时间: 1分钟
JSONObject result = new JSONObject();
result.put("imageBase64Data", lineCaptcha.getImageBase64Data());
result.put("vercodeToken", vercodeToken);
result.put("expireTime", CS.VERCODE_CACHE_TIME);
return ApiRes.ok(result);
}
}

View File

@@ -0,0 +1,45 @@
package com.jeequan.jeepay.mgr.ctrl.anon;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.model.DBApplicationConfig;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.mgr.websocket.server.WsChannelUserIdServer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 获取用户ID - 回调函数
*
* @author terrfly
*
* @date 2021/8/13 17:54
*/
@Controller
@RequestMapping("/api/anon/channelUserIdCallback")
public class ChannelUserIdNotifyController extends CommonCtrl {
@RequestMapping("")
public String channelUserIdCallback() {
try {
// 静态CDN地址
DBApplicationConfig dbApplicationConfig = sysConfigService.getDBApplicationConfig();
request.setAttribute("staticCdnHost", dbApplicationConfig.getStaticCdnHost());
//请求参数
JSONObject params = getReqParamJSON();
String extParam = params.getString("extParam");
String channelUserId = params.getString("channelUserId");
String appId = params.getString("appId");
//推送到前端
WsChannelUserIdServer.sendMsgByAppAndCid(appId, extParam, channelUserId);
} catch (Exception e) {
request.setAttribute("errMsg", e.getMessage());
}
return "channelUser/getChannelUserIdPage";
}
}

View File

@@ -0,0 +1,85 @@
package com.jeequan.jeepay.mgr.ctrl.anon;
import cn.hutool.core.codec.Base64;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.SysUserEntity;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.SysConfigService;
import com.jeequan.jeepay.service.impl.SysUserAuthService;
import com.jeequan.jeepay.service.impl.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/*
* 登录密码接口
*
* @author xiaoyu
*
* @date 2021/6/8 17:09
*/
@RestController
@RequestMapping("/api/anon/cipher")
public class RetrieveController extends CommonCtrl {
@Autowired private SysUserService sysUserService;
@Autowired private SysUserAuthService sysUserAuthService;
@Autowired private SysConfigService sysConfigService;
@Autowired private SmsManager smsManager;
/** 密码找回接口 **/
@RequestMapping(value = "/retrieve", method = RequestMethod.POST)
@MethodLog(remark = "密码找回")
public ApiRes retrieve() throws BizException {
// 手机号, 已做base64处理
String phone = Base64.decodeStr(getValStringRequired("phone"));
// 验证码, 已做base64处理
String code = Base64.decodeStr(getValStringRequired("code"));
//新密码 password, 已做base64处理
String newPwd = Base64.decodeStr(getValStringRequired("newPwd"));
// 验证手机号
smsManager.checkSmsVercodeThrowBizEx(phone, code, CS.SMS_TYPE_API_ENUM.TYPE_RETRIEVE);
SysUserEntity dbUser = sysUserService.getOne(SysUserEntity.gw().eq(SysUserEntity::getTelphone, phone).eq(SysUserEntity::getSysType, CS.SYS_ROLE_TYPE.PLATFORM));
if (dbUser == null) {
throw new BizException("用户不存在");
}
// 更新用户登录密码
sysUserAuthService.resetAuthInfo(dbUser.getSysUserId(), null, null, true, newPwd, CS.SYS_ROLE_TYPE.PLATFORM);
// TODO mq更新用户密码
return ApiRes.ok();
}
/** 发送短信验证码 **/
@RequestMapping(value = "/smsCode", method = RequestMethod.POST)
public ApiRes smsCode() throws BizException {
// 验证参数 手机号, 已做base64处理
String phone = getValStringRequired("phone");
SysUserEntity dbUser = sysUserService.getOne(SysUserEntity.gw().eq(SysUserEntity::getTelphone, phone).eq(SysUserEntity::getSysType, CS.SYS_ROLE_TYPE.PLATFORM));
if (dbUser == null) {
throw new BizException("用户不存在");
}
smsManager.sendSmsVercode(phone, CS.SMS_TYPE_API_ENUM.TYPE_RETRIEVE);
return ApiRes.ok();
}
/** 获取密码校验规则正则 **/
@RequestMapping(value = "/pwdRulesRegexp", method = RequestMethod.GET)
public ApiRes getPwdRulesRegexp() throws BizException {
return ApiRes.ok(sysConfigService.getDBSecurityConfig().getPasswordRegexp());
}
}

View File

@@ -0,0 +1,49 @@
package com.jeequan.jeepay.mgr.ctrl.anon;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBOEMConfig;
import com.jeequan.jeepay.core.service.ISysConfigService;
import com.jeequan.jeepay.core.utils.JsonKit;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 网站信息ctrl
*
* @author terrfly
*
* @date 2022/2/14 20:56
*/
@RestController
@RequestMapping("/api/anon/siteInfos")
public class SiteInfoController extends CommonCtrl {
@Autowired private ISysConfigService sysConfigService;
@GetMapping(value = "")
public ApiRes getSiteInfos() throws BizException {
// 是否查询配置信息(兼容历史接口)
Byte queryConfig = getValByteDefault("queryConfig", CS.NO);
DBOEMConfig dboemConfig = sysConfigService.getOemConfig();
if(queryConfig == CS.YES){
JSONObject result = new JSONObject();
result.put("siteInfo", dboemConfig);
result.put("sysConfig", JsonKit.newJson("httpMsgIsEncrypt", SysConfigService.HTTP_MSG_IS_ENCRYPT));
return ApiRes.ok(result);
}
return ApiRes.ok(dboemConfig);
}
}

View File

@@ -0,0 +1,393 @@
package com.jeequan.jeepay.mgr.ctrl.aqf;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.response.AlipayFundAccountbookQueryResponse;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.TransferOrder;
import com.jeequan.jeepay.core.entity.TransferSubject;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.tranfer.TransferBasicInfo;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.SysConfigService;
import com.jeequan.jeepay.service.impl.TransferSubjectService;
import com.jeequan.jeepay.service.impl.TransferWalletService;
import com.jeequan.jeepay.thirdparty.channel.alipay.AliAqfV2Service;
import com.jeequan.jeepay.thirdparty.util.ChannelCertConfigKitBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@RestController
@RequestMapping("/api/aqfApi")
public class AqfApiController extends CommonCtrl {
@Autowired
private AliAqfV2Service aliAqfV2Service;
@Autowired
private SysConfigService sysConfigService;
@Autowired
private TransferSubjectService transferSubjectService;
@Autowired
private ChannelCertConfigKitBean channelCertConfigKitBean;
@Autowired
private TransferWalletService transferWalletService;
@Autowired
private SmsManager smsManager;
/**
* 签约
*
* @return
*/
@RequestMapping(value = "/signUrl", method = RequestMethod.GET)
public ApiRes signUrl() {
String subId = getValStringRequired("subId");
String resutUrl = aliAqfV2Service.userAgreementPageSign(subId);
return ApiRes.ok(resutUrl);
}
/**
* 支付宝个人代扣协议查询接口
*
* @return
*/
@RequestMapping(value = "/agreementQuery" , method = RequestMethod.GET)
public ApiRes agreementQuery(){
String subId = getValStringRequired("subId");
JSONObject alipayUserAgreementQueryResponse = aliAqfV2Service.userAgreementQuery(subId);
return ApiRes.ok(alipayUserAgreementQueryResponse);
}
/**
* 解约
*
* @return
*/
@RequestMapping(value = "/userAgreementUnsign" , method = RequestMethod.GET)
public ApiRes userAgreementUnsign(){
String subId = getValStringRequired("subId");
JSONObject alipayUserAgreementUnsignResponse = aliAqfV2Service.userAgreementUnsign(subId);
return ApiRes.ok(alipayUserAgreementUnsignResponse);
}
/**
* 记账本查询
*
* @return
*/
@RequestMapping(value = "/alipayFundAccountbookQuery", method = RequestMethod.GET)
public ApiRes alipayFundAccountbookQuery() {
String subId = getValStringRequired("subId");
// 设计上,一个签约主体可以创建多个记账本,实际使用的时候,尽量保持一个签约主体只有一个账本
String walletApplyId = getValString("walletApplyId");
AlipayFundAccountbookQueryResponse alipayFundAccountbookQueryResponse = aliAqfV2Service.fundAccountbookQuery(walletApplyId);
return ApiRes.ok(JSON.parseObject(alipayFundAccountbookQueryResponse.getBody()).getJSONObject("alipay_fund_accountbook_query_response"));
}
/**
* 资金专款拨入(商户自身给记账本充值)
*
* @return
*/
@RequestMapping(value = "/transPage" , method = RequestMethod.GET)
public ApiRes transPage(){
String subId = getValStringRequired("subId");
String transAmount = getValStringRequired("transAmount");
String transferDesc = getValString("transferDesc");
String transedUrl = aliAqfV2Service.transPage(subId, transAmount ,transferDesc);
return ApiRes.ok(transedUrl);
}
/**
* 单笔生成待发待结算信息
*
* @return
*/
@RequestMapping(value = "/settlementData", method = RequestMethod.POST)
public ApiRes settlementDate() {
String transferSubjectIdFq = getValStringRequired("transferSubjectIdFq");
// String vc = Base64.decodeStr(getValStringRequired("vc"));
// String vt = Base64.decodeStr(getValStringRequired("vt"));
String sipw = Base64.decodeStr(getValStringRequired("sipw"));
// 验证码校验
// String cacheCode = RedisUtil.getString(CS.getCacheKeyImgCode(vt));
// if(StringUtils.isEmpty(cacheCode) || !cacheCode.equalsIgnoreCase(vc)){
// throw new BizException("验证码有误!");
// }
TransferSubjectEntity transferSubject = transferSubjectService.getById(transferSubjectIdFq);
MchInfo mchInfo = mchInfoService.getById(transferSubject.getMchNo());
if (!new BCryptPasswordEncoder().matches(sipw, mchInfo.getSipw())) {
throw new BizException("支付密码验证失败!");
}
String code = Base64.decodeStr(getValStringRequired("code")); // 验证码 code, 已做base64处理
// 校验验证码
smsManager.checkSmsVercodeThrowBizEx(mchInfo.getContactTel(), code, CS.SMS_TYPE_API_ENUM.TYPE_AUTH);
SettlementDataModel object = getObject(SettlementDataModel.class);
String date = aliAqfV2Service.settlementData(object.getTransferSubjectIdFq(), object.getTransferOrders());
return ApiRes.ok(date);
}
@PostMapping("/batchSettlementData")
public ApiRes uploadExcel() {
String transferSubjectIdFq = getValStringRequired("transferSubjectIdFq");
String excelFileName = getValStringRequired("excelFileName");
File excelFile = channelCertConfigKitBean.getCertFile(excelFileName);
SettlementDataModel params = getObject(SettlementDataModel.class);
// String vc = Base64.decodeStr(getValStringRequired("vc"));
// String vt = Base64.decodeStr(getValStringRequired("vt"));
String sipw = Base64.decodeStr(getValStringRequired("sipw"));
// 验证码校验
// String cacheCode = RedisUtil.getString(CS.getCacheKeyImgCode(vt));
// if(StringUtils.isEmpty(cacheCode) || !cacheCode.equalsIgnoreCase(vc)){
// throw new BizException("验证码有误!");
// }
TransferSubjectEntity transferSubject = transferSubjectService.getById(transferSubjectIdFq);
MchInfo mchInfo = mchInfoService.getById(transferSubject.getMchNo());
if (!new BCryptPasswordEncoder().matches(sipw, mchInfo.getSipw())) {
throw new BizException("支付密码验证失败!");
}
String code = Base64.decodeStr(getValStringRequired("code")); // 验证码 code, 已做base64处理
// 校验验证码
smsManager.checkSmsVercodeThrowBizEx(mchInfo.getContactTel(), code, CS.SMS_TYPE_API_ENUM.TYPE_AUTH);
List<SettleBatchExcel> dataList = new ArrayList<>();
List<TransferOrder> transferOrderList = new ArrayList<>();
String batch = "BATCH" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6);
try {
InputStream inputStream = Files.newInputStream(excelFile.toPath());
EasyExcel.read(inputStream, SettleBatchExcel.class, new AnalysisEventListener<SettleBatchExcel>() {
@Override
public void invoke(SettleBatchExcel settleBatchExcel, AnalysisContext analysisContext) {
dataList.add(settleBatchExcel);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 解析完成后的操作,可以在这里进行一些清理工作
}
}).sheet().doRead();
//把数据新增到收款信息中
Assert.notEmpty(params.getInfoId(), "用户类型不能为空");
Assert.notEmpty(params.getInfoType(), "用户ID不能为空");
TransferSubjectEntity sponsor = transferSubjectService.getById(params.getTransferSubjectIdFq());
if (!Objects.equals(sponsor.getState(), TransferSubject.STATE_ENABLE)) {
throw new BizException("付款账户当前状态不可用");
}
if (!Objects.equals(sponsor.getSignState(), (int) TransferSubject.SIGN_STATE_SUCCESS)) {
throw new BizException("付款账户暂未完成签约");
}
TransferWalletEntity transferWallet = transferWalletService.getByApplyId(sponsor.getTransApplyId(), null);
String extCardInfo = transferWallet.getExtCardInfo();
JSONObject extCardJSON = JSONObject.parseObject(extCardInfo);
Assert.notNull(sponsor, "未获取到对应的转账发起方信息");
String infoId = CS.SYS_ROLE_TYPE.AGENT.equals(sponsor.getInfoType())? sponsor.getAgentNo(): sponsor.getMchNo();
for (SettleBatchExcel settleBatchExcel : dataList) {
TransferSubjectEntity receiver = transferSubjectService.getReceiver(sponsor.getIsvNo(),
CS.IF_CODE.ALIAQF, sponsor.getInfoType(), infoId,
settleBatchExcel.getAccountNo(), settleBatchExcel.getEntryType(), settleBatchExcel.getAccountType());
if (receiver == null) {
// 先存储转账接受账户信息
receiver = new TransferSubjectEntity();
receiver.setId("SUB" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
receiver.setAccount(settleBatchExcel.getAccountNo());
receiver.setState(TransferSubject.STATE_ENABLE);
receiver.setSubjectType(TransferSubject.SUBJECT_TYPE_RECEIVER);
receiver.setIsvNo(sponsor.getIsvNo());
receiver.setInfoType(sponsor.getInfoType());
receiver.setMchNo(sponsor.getMchNo());
receiver.setAgentNo(sponsor.getAgentNo());
receiver.setAgentName(sponsor.getAgentName());
receiver.setTopAgentNo(sponsor.getTopAgentNo());
receiver.setTransIfCode(sponsor.getTransIfCode());
receiver.setSignState(sponsor.getSignState());
receiver.setAccountName(settleBatchExcel.getAccountName());
receiver.setAccountType(settleBatchExcel.getAccountType());
receiver.setEntryType(settleBatchExcel.getEntryType());
if (TransferBasicInfo.ENTRY_TYPE_BANK.equalsIgnoreCase(settleBatchExcel.getEntryType())) {
// 保存银联支行信息
JSONObject bankCardBranchInfo = new JSONObject();
if (settleBatchExcel.getInstCity() != null) {
bankCardBranchInfo.put("instName", settleBatchExcel.getInstName());
bankCardBranchInfo.put("instProvince", settleBatchExcel.getInstProvince());
bankCardBranchInfo.put("instCity", settleBatchExcel.getInstCity());
bankCardBranchInfo.put("instBranchName", settleBatchExcel.getInstBranchName());
}
receiver.setAccountMessage(bankCardBranchInfo.toJSONString());
}
transferSubjectService.save(receiver);
}
// 保存一些订单信息
TransferOrder transferOrder = new TransferOrder();
transferOrder.setMchNo(sponsor.getMchNo());
transferOrder.setIsvNo(sponsor.getIsvNo());
transferOrder.setAgentNo(sponsor.getAgentNo());
transferOrder.setTransferSubjectIdFq(params.getTransferSubjectIdFq());
transferOrder.setTransferSubjectIdJs(receiver.getId());
transferOrder.setIfCode(receiver.getTransIfCode());
transferOrder.setWalletId(transferWallet.getId());
transferOrder.setEntryType(settleBatchExcel.getEntryType());
transferOrder.setAccountType(settleBatchExcel.getAccountType());
transferOrder.setAccountName(settleBatchExcel.getAccountName());
transferOrder.setAccountNo(settleBatchExcel.getAccountNo());
transferOrder.setOriginAccountNo(sponsor.getAccount());
transferOrder.setOriginAccountName(sponsor.getAccountName());
transferOrder.setBatchId(batch);
transferOrderList.add(transferOrder);
}
//新增或更新完毕后发起结算
aliAqfV2Service.settlementData(params.getTransferSubjectIdFq(), transferOrderList);
} catch (IOException e) {
logger.info("批量导入安全发代发数据解析失败!");
// 处理异常
}
// 对 dataList 进行后续操作,如存储到数据库等
return ApiRes.ok();
}
// /**
// * 代发到户 --不直接调用
// * @return
// */
// @RequestMapping(value = "/transUniTransfer" , method = RequestMethod.GET)
// public ApiRes transUniTransfer(){
// String ersubId = getValStringRequired("ersubId");
// String eesubId = getValStringRequired("eesubId");
// String transAmount = getValStringRequired("transAmount");
// String taskId = getValStringRequired("taskId");
// String transferDesc = getValString("transferDesc");
// AlipayFundTransUniTransferResponse alipayFundTransUniTransferResponse = aliAqfV2Service.transUniTransfer(ersubId, eesubId, getDefaultIsvConfig(), transAmount,taskId,null,transferDesc);
// return ApiRes.ok(alipayFundTransUniTransferResponse);
// }
// /**
// * 代发到卡 --不直接调用
// * @return
// */
// @RequestMapping(value = "/transUniTransferCard" , method = RequestMethod.GET)
// public ApiRes transUniTransferCard(){
// String ersubId = getValStringRequired("ersubId");
// String eesubId = getValStringRequired("eesubId");
// String transAmount = getValStringRequired("transAmount");
// String taskId = getValStringRequired("taskId");
// String transferDesc = getValString("transferDesc");
// AlipayFundTransUniTransferResponse alipayFundTransUniTransferResponse = aliAqfV2Service.transUniTransferCard(ersubId, eesubId, getDefaultIsvConfig(), transAmount, taskId,null,transferDesc);
// return ApiRes.ok(alipayFundTransUniTransferResponse);
// }
/**
* 账单查询
*
* @return
*/
@RequestMapping(value = "/bizfundagentQuery", method = RequestMethod.GET)
public ApiRes bizfundagentQuery() {
String ersubId = getValStringRequired("ersubId");
String startTime = getValStringRequired("startTime");
String endTime = getValStringRequired("endTime");
String pageNo = getValStringRequired("pageNo");
String pageSize = getValStringRequired("pageSize");
JSONObject alipayDataBillBizfundagentQueryResponse = aliAqfV2Service.bizfundagentQuery(ersubId, startTime, endTime, pageNo, pageSize);
return ApiRes.ok(alipayDataBillBizfundagentQueryResponse);
}
/**
* 电子回单申请
*
* @return
*/
@RequestMapping(value = "/applicationForm", method = RequestMethod.GET)
public ApiRes applicationForm() {
String ersubId = getValStringRequired("ersubId");
String transferId = getValStringRequired("transferId");
JSONObject alipayDataBillEreceiptagentApplyResponse = aliAqfV2Service.applicationForm(ersubId, transferId);
return ApiRes.ok(alipayDataBillEreceiptagentApplyResponse);
}
/**
* 电子回单下载地址获取
*
* @return
*/
@RequestMapping(value = "/applicationFormDownload", method = RequestMethod.GET)
public ApiRes applicationFormDownload() {
String ersubId = getValStringRequired("ersubId");
String transferId = getValStringRequired("transferId");
JSONObject alipayDataBillAccountbookereceiptQueryResponse = aliAqfV2Service.applicationFormDownload(ersubId, transferId);
return ApiRes.ok(alipayDataBillAccountbookereceiptQueryResponse);
}
public String getDefaultIsvConfig() {
SysConfig serviceOne = sysConfigService.getOne(SysConfig.gw().eq(SysConfig::getGroupKey, "defaultConfig")
.eq(SysConfig::getConfigKey, "defaultIsvNo"));
if (serviceOne != null) {
return serviceOne.getConfigVal();
}
return null;
}
/**
* 根据付款人信息id获取详情
*/
public TransferSubjectEntity getSubjectOne(String subId){
TransferSubjectEntity transferSubjectEntity = transferSubjectService.getById(subId);
if (transferSubjectEntity != null){
return transferSubjectEntity;
}else {
throw new BizException("未查询到当前付款人信息!");
}
}
}

View File

@@ -0,0 +1,213 @@
package com.jeequan.jeepay.mgr.ctrl.aqf;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.entity.TransferSubject;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* 转账对象信息
*/
@RestController
@RequestMapping("/api/aqf")
public class AqfController extends CommonCtrl {
@Autowired
private TransferSubjectService transferSubjectService;
@Autowired
private TransferInterfaceConfigService transferInterfaceConfigService;
@Autowired
private IsvInfoService isvInfoService;
@Autowired
private AgentInfoService agentInfoService;
@Autowired
private MchInfoService mchInfoService;
/**
* 新增付款方账户信息
*
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
public ApiRes addTransferSubject() {
TransferSubjectEntity transferSubject = getObject(TransferSubjectEntity.class);
getValStringRequired("mchNo");
// 当前登录用户信息
transferSubject.setId("SUB" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
SysUser sysUser = getCurrentUser().getSysUser();
transferSubject.setSubjectType("FQ");
transferSubject.setTransApplyId(UUID.randomUUID().toString().replace("-", "").substring(0, 32));
if (StringUtils.isEmpty(transferSubject.getAgentNo())) {
//获取服务商信息
MchInfo mchInfo = mchInfoService.getById(transferSubject.getMchNo());
transferSubject.setAgentNo(mchInfo.getAgentNo());
}
if (StringUtils.isEmpty(transferSubject.getIsvNo())){
//获取渠道信息
AgentInfo agentInfo = agentInfoService.getById(transferSubject.getAgentNo());
transferSubject.setIsvNo(agentInfo.getIsvNo());
}
transferSubject.setCreatedUid(sysUser.getSysUserId());
boolean save = transferSubjectService.save(transferSubject);
if (save) {
return ApiRes.ok();
} else {
return ApiRes.customFail("新增失败!");
}
}
/**
* 查询
*/
@GetMapping("/getPageList")
public ApiRes pageTransferSubject() {
TransferSubjectEntity transferSubject = getObject(TransferSubjectEntity.class);
// 时间搜索
transferSubject.buildQueryDateRange();
IPage<TransferSubjectEntity> pageList = transferSubjectService.getPageList(getIPage(), transferSubject);
return ApiRes.page(pageList);
}
/**
* 查询详情
*/
@GetMapping(value = "/{id}")
public ApiRes getByIdTransferSubject(@PathVariable("id") Integer id) {
TransferSubjectEntity byId = transferSubjectService.getById(id);
return ApiRes.ok(byId);
}
/**
* 修改
*/
@PutMapping(value = "/{id}")
public ApiRes updateTransferSubject(@PathVariable("id") String id) {
TransferSubjectEntity transferSubject = getObject(TransferSubjectEntity.class);
getValStringRequired("mchNo");
transferSubject.setId(id);
if (StringUtils.isEmpty(transferSubject.getAgentNo())) {
//获取服务商信息
MchInfo mchInfo = mchInfoService.getById(transferSubject.getMchNo());
transferSubject.setAgentNo(mchInfo.getAgentNo());
}
if (StringUtils.isEmpty(transferSubject.getIsvNo())){
//获取渠道信息
AgentInfo agentInfo = agentInfoService.getById(transferSubject.getAgentNo());
transferSubject.setIsvNo(agentInfo.getIsvNo());
}
boolean resut = transferSubjectService.updateById(transferSubject);
if (resut) {
return ApiRes.ok();
} else {
return ApiRes.customFail("修改失败!");
}
}
/**
* 删除
*/
@DeleteMapping("/{id}")
public ApiRes deleteTransferSubject(@PathVariable("id") Integer id) {
boolean resut = transferSubjectService.removeById(id);
if (resut) {
return ApiRes.ok();
} else {
return ApiRes.customFail("删除失败!");
}
}
/**
* 新增收款方账户信息
*/
@PostMapping("/addJs")
public ApiRes addJsTransferSubject() {
TransferSubjectEntity transferSubject = getObject(TransferSubjectEntity.class);
getValStringRequired("mchNo");
// 当前登录用户信息
transferSubject.setId("SUB" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
SysUser sysUser = getCurrentUser().getSysUser();
transferSubject.setSubjectType("JS");
transferSubject.setCreatedUid(sysUser.getSysUserId());
if (StringUtils.isEmpty(transferSubject.getAgentNo())) {
//获取服务商信息
MchInfo mchInfo = mchInfoService.getById(transferSubject.getMchNo());
transferSubject.setAgentNo(mchInfo.getAgentNo());
}
if (StringUtils.isEmpty(transferSubject.getIsvNo())){
//获取渠道信息
AgentInfo agentInfo = agentInfoService.getById(transferSubject.getAgentNo());
transferSubject.setIsvNo(agentInfo.getIsvNo());
}
boolean save = transferSubjectService.save(transferSubject);
if (save) {
return ApiRes.ok();
} else {
return ApiRes.customFail("新增失败!");
}
}
@GetMapping("/getBatchData")
public ApiRes getBatchData() {
String transferSubjects = getValStringRequired("transferSubjects");
List<TransferSubjectEntity> transferSubjectEntityList = new ArrayList<>();
String[] transferSubjectSpli = transferSubjects.split(",");
for (String transferSubjectId : transferSubjectSpli) {
TransferSubjectEntity transferSubjectEntity = transferSubjectService.getById(transferSubjectId);
if (transferSubjectEntity != null) {
transferSubjectEntityList.add(transferSubjectEntity);
}
}
return ApiRes.ok(transferSubjectEntityList);
}
@PostMapping("/state")
public ApiRes exam() {
JSONObject reqParamJSON = getReqParamJSON();
Integer state = reqParamJSON.getInteger("state");
String id = reqParamJSON.getString("id");
String remark = reqParamJSON.getString("remark");
TransferSubjectEntity transferSubjectEntity = transferSubjectService.getById(id);
Assert.notNull(transferSubjectEntity, "付款账户信息不存在");
if (state == TransferSubject.STATE_DISABLE) {
transferSubjectEntity.setState(TransferSubject.STATE_DISABLE);
transferSubjectEntity.setRemark(remark);
transferSubjectService.updateById(transferSubjectEntity);
} else if (state == TransferSubject.STATE_ENABLE) {
transferSubjectEntity.setState(TransferSubject.STATE_ENABLE);
transferSubjectService.updateById(transferSubjectEntity);
} else if (state == TransferSubject.STATE_ENABLE_REVIEW) {
transferSubjectEntity.setState(TransferSubject.STATE_ENABLE_REVIEW);
transferSubjectService.updateById(transferSubjectEntity);
}
return ApiRes.ok();
}
/**
* 统计收款账户总成交金额和总成交笔数
*/
@GetMapping("/getSubStatistics")
public Map<String, Object> getSubStatistics(){
TransferSubjectEntity subject = getObject(TransferSubjectEntity.class);
return transferSubjectService.getSubStatistics(subject);
}
}

View File

@@ -0,0 +1,110 @@
package com.jeequan.jeepay.mgr.ctrl.aqf;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.TaskList;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.TaskListService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
/**
* 任务
*/
@RestController
@RequestMapping("/api/taskList")
public class TaskListController extends CommonCtrl {
@Autowired
private TaskListService taskListService;
/**
* 新增任务
* @return
*/
@RequestMapping(value = "/add" ,method = RequestMethod.POST)
public ApiRes addTaskList(){
TaskList taskList = getObject(TaskList.class);
getValStringRequired("mchNo");
if (StringUtils.isEmpty(taskList.getAgentNo())) {
//获取服务商信息
MchInfo mchInfo = mchInfoService.getById(taskList.getMchNo());
taskList.setAgentNo(mchInfo.getAgentNo());
}
// 当前登录用户信息
SysUser sysUser = getCurrentUser().getSysUser();
taskList.setId(DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
taskList.setCreatedBy(String.valueOf(sysUser.getSysUserId()));
boolean save = taskListService.save(taskList);
if (save){
return ApiRes.ok();
}else {
return ApiRes.customFail("新增失败!");
}
}
/**
* 查询
* @return
*/
@RequestMapping(value = "/getPageList" ,method = RequestMethod.GET)
public ApiRes getlistTaskList(){
TaskList taskList = getObject(TaskList.class);
// 时间搜索
Date[] searchDateRange = taskList.buildQueryDateRange();
taskList.setFirstDate(searchDateRange[0]);
taskList.setLastDate(searchDateRange[1]);
IPage<TaskList> pageList = taskListService.getPageList(getIPage(), taskList);
//Page<TaskList> page = taskListService.page(getIPage(), TaskList.gw(taskList).orderByDesc(TaskList::getCreatedAt));
return ApiRes.page(pageList);
}
/**
* 查询详情
* @return
*/
@RequestMapping(value = "/{id}" ,method = RequestMethod.GET)
public ApiRes getByIdTaskList(@PathVariable("id") Integer id){
TaskList byId = taskListService.getById(id);
return ApiRes.ok(byId);
}
/**
* 修改
* @return
*/
@RequestMapping(value = "/{id}" ,method = RequestMethod.PUT)
public ApiRes updateTaskList(@PathVariable("id") String id) {
TaskList reqParam = getObject(TaskList.class);
reqParam.setId(id);
boolean resut = taskListService.updateById(reqParam);
if (resut){
return ApiRes.ok();
}else {
return ApiRes.customFail("修改失败!");
}
}
/**
* 删除
* @return
*/
@RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
public ApiRes deleteTaskList(@PathVariable("id") Integer id){
boolean resut = taskListService.removeById(id);
if (resut){
return ApiRes.ok();
}else {
return ApiRes.customFail("删除失败!");
}
}
}

View File

@@ -0,0 +1,112 @@
package com.jeequan.jeepay.mgr.ctrl.aqf;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.converter.TransferConverter;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.interfaces.paychannel.ITransferService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.service.ValidatorService;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.core.validate.Add;
import com.jeequan.jeepay.db.entity.TransferInterfaceConfigEntity;
import com.jeequan.jeepay.db.entity.TransferSubjectEntity;
import com.jeequan.jeepay.db.entity.TransferWalletEntity;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.TransferInterfaceConfigService;
import com.jeequan.jeepay.service.impl.TransferSubjectService;
import com.jeequan.jeepay.service.impl.TransferWalletService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.UUID;
/**
* 代付对象
*
* @author deng
* @since 2024/5/9
*/
@Slf4j
@RestController
@RequestMapping("/api/transferSubject")
public class TransferSubjectController extends CommonCtrl {
@Autowired
private TransferInterfaceConfigService transferInterfaceConfigService;
@Autowired
private ValidatorService validate;
@Autowired
private TransferSubjectService transferSubjectService;
@Autowired
private TransferWalletService transferWalletService;
@Autowired
private TransferConverter transferConverter;
/**
* 新增转账发起方
*/
@PostMapping("/sponsor")
public ApiRes sponsor() {
// TODO 未完善,接入其他代付通道时,再完善
TransferSubjectEntity transferSubject = getObject(TransferSubjectEntity.class);
validate.validate(transferSubject, Add.class);
// 当前登录用户信息
transferSubject.setId("SUB" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
SysUser sysUser = getCurrentUser().getSysUser();
transferSubject.setSubjectType("FQ");
transferSubject.setTransApplyId(UUID.randomUUID().toString().replace("-", "").substring(0, 32));
if (StringUtils.isNotEmpty(transferSubject.getIsvNo())) {
//取对应参数信息
//获取下发金额
TransferInterfaceConfigEntity configEntity = transferInterfaceConfigService.getTransferConfig(transferSubject.getTransIfCode(), transferSubject.getIsvNo(), CS.SYS_ROLE_TYPE.ISV);
if (configEntity != null && StringUtils.isNotEmpty(configEntity.getTransIfParams())) {
String zfbDayMax = JSONObject.parseObject(configEntity.getTransIfParams()).getString("zfbDayMax");
String bankCardDayMax = JSONObject.parseObject(configEntity.getTransIfParams()).getString("bankCardDayMax");
transferSubject.setZfbDayMax(Long.valueOf(zfbDayMax));
transferSubject.setBankCardDayMax(Long.valueOf(bankCardDayMax));
}
}
transferSubject.setCreatedUid(sysUser.getSysUserId());
boolean save = transferSubjectService.save(transferSubject);
if (save) {
return ApiRes.ok();
} else {
return ApiRes.customFail("新增失败!");
}
}
@PostMapping("/refreshBalance")
public ApiRes refreshBalance() {
String transferSubjectId = getValStringRequired("transferSubjectId");
TransferWalletEntity transferWallet = transferWalletService.getByApplyId(transferSubjectId, null);
// 刷新记账本余额
ITransferService transferService = SpringBeansUtil.getBean(transferWallet.getTransIfCode() + "TransferService", ITransferService.class);
MutablePair<String, Long> balanceResult = transferService.queryBalanceAmount(transferConverter.toModel(transferWallet));
// 查询更新余额
transferWallet.setAccountBookBalance(balanceResult.right);
transferWalletService.updateById(transferWallet);
return ApiRes.ok(transferWallet);
}
}

View File

@@ -0,0 +1,135 @@
package com.jeequan.jeepay.mgr.ctrl.article;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.SysArticle;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.SysArticleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
/**
* 文章管理类
*
* @author yurong
*
* @date 2022-07-08 14:15
*/
@RestController
@RequestMapping("api/sysArticles")
public class SysArticleController extends CommonCtrl {
@Autowired private SysArticleService sysArticleService;
/**
* @author: yurong
* @date: 2022-07-08 14:15
* @describe: 文章列表 articleType 1公告
*/
@PreAuthorize("hasAuthority('ENT_NOTICE_LIST')")
@RequestMapping(value = "",method = RequestMethod.GET)
public ApiRes articleList(){
SysArticle sysArticle = getObject(SysArticle.class);
if (sysArticle.getArticleType() == null){
return ApiRes.customFail("文章类型不明确");
}
LambdaQueryWrapper<SysArticle> wrapper = SysArticle.gw();
wrapper.select(SysArticle::getArticleId,SysArticle::getTitle,SysArticle::getSubtitle,SysArticle::getPublisher,SysArticle::getCreatedAt)
.eq(SysArticle::getArticleType,sysArticle.getArticleType())
.eq(sysArticle.getArticleId()!=null,SysArticle::getArticleId,sysArticle.getArticleId())
.like(StringUtils.isNotEmpty(sysArticle.getTitle()),SysArticle::getTitle,sysArticle.getTitle());
// 时间搜索
Date[] searchDateRange = sysArticle.buildQueryDateRange();
wrapper.ge(searchDateRange[0] != null, SysArticle::getPublishTime, searchDateRange[0])
.le(searchDateRange[1] != null, SysArticle::getPublishTime, searchDateRange[1])
.orderByDesc(SysArticle::getPublishTime);
IPage<SysArticle> iPage = sysArticleService.page(getIPage(), wrapper);
return ApiRes.page(iPage);
}
/**
* @author: yurong
* @date: 2022-07-08 14:15
* @describe: 文章详情 articleType 1公告
*/
@PreAuthorize("hasAnyAuthority('ENT_NOTICE_VIEW','ENT_NOTICE_EDIT')")
@RequestMapping(value = "/{articleId}",method = RequestMethod.GET)
public ApiRes detail(@PathVariable("articleId") Long articleId){
SysArticle sysArticle = sysArticleService.getById(articleId);
if (sysArticle == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(sysArticle);
}
/**
* @author: yurong
* @date: 2022-07-08 14:15
* @describe: 新建文章 articleType 1公告
*/
@MethodLog(remark = "新建文章")
@PreAuthorize("hasAuthority('ENT_NOTICE_ADD')")
@RequestMapping(value = "",method = RequestMethod.POST)
public ApiRes add(){
SysArticle sysArticle = getObject(SysArticle.class);
if (sysArticle.getArticleType() == null){
return ApiRes.customFail("文章类型不明确");
}
// 当前登录用户信息
SysUser sysUser = getCurrentUser().getSysUser();
sysArticle.setCreatedUid(sysUser.getSysUserId());
sysArticle.setCreatedBy(sysUser.getRealname());
boolean save = sysArticleService.save(sysArticle);
if(!save){
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
return ApiRes.ok();
}
/**
* @author: yurong
* @date: 2022-07-08 14:15
* @describe: 编辑文章 articleType 1公告
*/
@MethodLog(remark = "编辑文章")
@PreAuthorize("hasAuthority('ENT_NOTICE_EDIT')")
@RequestMapping(value = "/{articleId}",method = RequestMethod.PUT)
public ApiRes update(@PathVariable("articleId") Long articleId){
SysArticle sysArticle = getObject(SysArticle.class);
sysArticle.setArticleId(articleId);
sysArticle.setUpdatedAt(null);
boolean update = sysArticleService.updateById(sysArticle);
if (!update){
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @author: yurong
* @date: 2022-07-08 14:15
* @describe: 删除文章 articleType 1公告
*/
@MethodLog(remark = "删除文章")
@PreAuthorize("hasAuthority('ENT_NOTICE_DEL')")
@RequestMapping(value = "/{articleId}",method = RequestMethod.DELETE)
public ApiRes delete(@PathVariable("articleId") Long articleId){
boolean delete = sysArticleService.removeById(articleId);
if (!delete){
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
}
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,86 @@
package com.jeequan.jeepay.mgr.ctrl.bill;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.CheckChannelBill;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.CheckChannelBillService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
/**
* 渠道账单管理类
*
* @author zx
*
* @date 2021-06-07 07:15
*/
@RestController
@RequestMapping("/api/channel/bill")
public class ChannelBillController extends CommonCtrl {
@Autowired private CheckChannelBillService checkChannelBillService;
/**
* @author: zx
* @describe: 列表
*/
@PreAuthorize("hasAuthority('ENT_CHECK_CHANNEL_BILL_LIST')")
@GetMapping("")
public ApiRes list() {
CheckChannelBill channelBill = getObject(CheckChannelBill.class);
// 时间范围条件
Date[] dateRange = channelBill.buildQueryDateRange();
IPage<CheckChannelBill> pages = checkChannelBillService.page(getIPage(true), CheckChannelBill.gw()
.eq(StringUtils.isNotBlank(channelBill.getBatchNo()), CheckChannelBill::getBatchNo, channelBill.getBatchNo())
.eq(StringUtils.isNotBlank(channelBill.getIfCode()), CheckChannelBill::getIfCode, channelBill.getIfCode())
.eq(StringUtils.isNotBlank(channelBill.getBillType()), CheckChannelBill::getBillType, channelBill.getBillType())
.ge(dateRange[0] != null, CheckChannelBill::getBillDate, dateRange[0])
.le(dateRange[1] != null, CheckChannelBill::getBillDate, dateRange[1])
.orderByDesc(CheckChannelBill::getCreatedAt)
);
setIfName(pages.getRecords());
return ApiRes.page(pages);
}
/**
* @author: zx
* @describe: 统计
*/
@PreAuthorize("hasAuthority('ENT_CHECK_CHANNEL_BILL_COUNT')")
@GetMapping("/count")
public ApiRes count() {
CheckChannelBill channelBill = getObject(CheckChannelBill.class);
JSONObject paramJSON = getReqParamJSON();
JSONObject resJson = checkChannelBillService.billCount(channelBill, paramJSON);
return ApiRes.ok(resJson);
}
/**
* @author: zx
* @describe: 详情
*/
@PreAuthorize("hasAuthority('ENT_CHECK_CHANNEL_BILL_VIEW')")
@GetMapping("/{id}")
public ApiRes detail(@PathVariable("id") Long id) {
CheckChannelBill channelBill = checkChannelBillService.getById(id);
if (channelBill == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(channelBill);
}
}

View File

@@ -0,0 +1,102 @@
package com.jeequan.jeepay.mgr.ctrl.bill;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.interfaces.bill.IReconciliationService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.CheckBatch;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.CheckBatchService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
/**
* 账单批次管理类
*
* @author zx
*
* @date 2021-06-07 07:15
*/
@RestController
@RequestMapping("/api/check/batch")
public class CheckBatchController extends CommonCtrl {
@Autowired private CheckBatchService checkBatchService;
/**
* @author: zx
* @describe: 列表
*/
@PreAuthorize("hasAuthority('ENT_CHECK_BATCH_LIST')")
@GetMapping
public ApiRes list() {
CheckBatch checkBatch = getObject(CheckBatch.class);
// 时间范围条件
Date[] dateRange = checkBatch.buildQueryDateRange();
IPage<CheckBatch> pages = checkBatchService.page(getIPage(true), CheckBatch.gw()
.eq(StringUtils.isNotBlank(checkBatch.getBatchNo()), CheckBatch::getBatchNo, checkBatch.getBatchNo())
.eq(StringUtils.isNotBlank(checkBatch.getIfCode()), CheckBatch::getIfCode, checkBatch.getIfCode())
.eq(checkBatch.getState() != null, CheckBatch::getState, checkBatch.getState())
.eq(checkBatch.getReleaseState() != null, CheckBatch::getReleaseState, checkBatch.getReleaseState())
.ge(dateRange[0] != null, CheckBatch::getBillDate, dateRange[0])
.le(dateRange[1] != null, CheckBatch::getBillDate, dateRange[1])
.orderByDesc(CheckBatch::getCreatedAt)
);
setIfName(pages.getRecords());
return ApiRes.page(pages);
}
/**
* @author: zx
* @describe: 详情
*/
@PreAuthorize("hasAuthority('ENT_CHECK_BATCH_VIEW')")
@GetMapping("/{batchNo}")
public ApiRes detail(@PathVariable("batchNo") String batchNo) {
CheckBatch checkBatch = checkBatchService.getById(batchNo);
if (checkBatch == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(checkBatch);
}
/**
* @author: zx
* @describe: 重新对账
*/
@PreAuthorize("hasAuthority('ENT_CHECK_BATCH_RELOAD')")
@PostMapping("/reload/{batchNo}")
public ApiRes reload(@PathVariable("batchNo") String batchNo) {
CheckBatch checkBatch = checkBatchService.getById(batchNo);
if (checkBatch == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
String reloadType = getValStringRequired("reloadType"); // 重新执行类型release-下载解析对账 check-仅对账
com.jeequan.jeepay.core.entity.CheckBatch coreCheckBatch = new CheckBatch();
BeanUtil.copyProperties(checkBatch, coreCheckBatch);
try {
IReconciliationService reconciliationService = SpringBeansUtil.getBean("reconciliationService", IReconciliationService.class);
reconciliationService.reloadBill4Batch(coreCheckBatch, reloadType);
// 处理差异
reconciliationService.processCheckDiffBills(checkBatch.getBillDate());
return ApiRes.ok();
}catch (Exception e) {
return ApiRes.customFail(e.getMessage());
}
}
}

View File

@@ -0,0 +1,198 @@
package com.jeequan.jeepay.mgr.ctrl.bill;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.CheckChannelBill;
import com.jeequan.jeepay.db.entity.CheckDiff;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.db.entity.RefundOrder;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.mgr.service.PayOrderProcessService;
import com.jeequan.jeepay.service.impl.CheckDiffService;
import com.jeequan.jeepay.service.impl.PayOrderService;
import com.jeequan.jeepay.service.impl.RefundOrderService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* 账单差异管理类
*
* @author zx
*
* @date 2021-06-07 07:15
*/
@RestController
@RequestMapping("/api/check/diff")
public class CheckDiffController extends CommonCtrl {
@Autowired private CheckDiffService checkDiffService;
@Autowired private PayOrderService payOrderService;
@Autowired private RefundOrderService refundOrderService;
@Autowired private PayOrderProcessService payOrderProcessService;
/**
* @author: zx
* @describe: 列表
*/
@PreAuthorize("hasAuthority('ENT_CHECK_DIFF_LIST')")
@GetMapping
public ApiRes list() {
CheckDiff checkDiff = getObject(CheckDiff.class);
// 时间范围条件
Date[] dateRange = checkDiff.buildQueryDateRange();
IPage<CheckDiff> pages = checkDiffService.page(getIPage(true), CheckDiff.gw()
.eq(StringUtils.isNotBlank(checkDiff.getBatchNo()), CheckDiff::getBatchNo, checkDiff.getBatchNo())
.eq(StringUtils.isNotBlank(checkDiff.getIfCode()), CheckDiff::getIfCode, checkDiff.getIfCode())
.eq(StringUtils.isNotBlank(checkDiff.getBillType()), CheckDiff::getBillType, checkDiff.getBillType())
.eq(StringUtils.isNotBlank(checkDiff.getDiffType()), CheckDiff::getDiffType, checkDiff.getDiffType())
.eq(checkDiff.getHandleState() != null, CheckDiff::getHandleState, checkDiff.getHandleState())
.eq(StringUtils.isNotBlank(checkDiff.getOrderId()), CheckDiff::getOrderId, checkDiff.getOrderId())
.eq(StringUtils.isNotBlank(checkDiff.getMchNo()), CheckDiff::getMchNo, checkDiff.getMchNo())
.ge(dateRange[0] != null, CheckDiff::getBillDate, dateRange[0])
.le(dateRange[1] != null, CheckDiff::getBillDate, dateRange[1])
.orderByDesc(CheckDiff::getCreatedAt)
);
// 查询支付订单 退款订单,是否有需要补单操作的
List<CheckDiff> checkDiffs = pages.getRecords();
if(CollUtil.isNotEmpty(checkDiffs)) {
List<String> payOrderIdList = pages.getRecords().stream()
.filter(item -> item.getDiffType().equals(CheckDiff.DIFF_TYPE_CHANNEL) && item.getBillType().equals(CheckChannelBill.BILL_TYPE_PAY))
.map(CheckDiff::getOrderId).collect(Collectors.toList());
List<PayOrder> payOrderList = null;
if (CollUtil.isNotEmpty(payOrderIdList)) {
payOrderList = payOrderService.list(PayOrder.gw().in(PayOrder::getPayOrderId, payOrderIdList).ne(PayOrder::getState, PayOrder.STATE_SUCCESS));
}
List<String> refundOrderIdList = checkDiffs.stream()
.filter(item -> item.getDiffType().equals(CheckDiff.DIFF_TYPE_CHANNEL) && item.getBillType().equals(CheckChannelBill.BILL_TYPE_REFUND))
.map(CheckDiff::getOrderId).collect(Collectors.toList());
List<RefundOrder> refundOrderList = null;
if (CollUtil.isNotEmpty(refundOrderIdList)) {
refundOrderList = refundOrderService.list(RefundOrder.gw().in(RefundOrder::getRefundOrderId, refundOrderIdList).ne(RefundOrder::getState, RefundOrder.STATE_SUCCESS));
}
for (CheckDiff checkDiff1: checkDiffs) {
if (CollUtil.isNotEmpty(payOrderList)) {
for (PayOrder payOrder: payOrderList) {
if (checkDiff1.getOrderId().equals(payOrder.getPayOrderId()) && (payOrder.getState() == PayOrder.STATE_ING || payOrder.getState() == PayOrder.STATE_CLOSED)) {
checkDiff1.addExt("isNeedReissue", 1);
}
}
}
if (CollUtil.isNotEmpty(refundOrderList)) {
for (RefundOrder refundOrder: refundOrderList) {
if (checkDiff1.getOrderId().equals(refundOrder.getRefundOrderId()) && (refundOrder.getState() == RefundOrder.STATE_ING || refundOrder.getState() == RefundOrder.STATE_CLOSED)) {
checkDiff1.addExt("isNeedReissue", 1);
}
}
}
}
}
setIfName(pages.getRecords());
return ApiRes.page(pages);
}
/**
* @author: zx
* @describe: 详情
*/
@PreAuthorize("hasAuthority('ENT_CHECK_DIFF_VIEW')")
@GetMapping("/{id}")
public ApiRes detail(@PathVariable("id") Long id) {
CheckDiff checkDiff = checkDiffService.getById(id);
if (checkDiff == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
if (getValByte("isQueryOrderInfo") != null && getValByte("isQueryOrderInfo") == 1 && StringUtils.isNotBlank(checkDiff.getOrderId())) {
JSONObject orderJSON = new JSONObject();
if (StringUtils.equals(checkDiff.getBillType(), CheckChannelBill.BILL_TYPE_PAY)) {
PayOrder payOrder = payOrderService.getById(checkDiff.getOrderId());
if (payOrder != null) {
orderJSON.put("orderId", payOrder.getPayOrderId());
orderJSON.put("state", payOrder.getState());
orderJSON.put("amount", payOrder.getAmount());
orderJSON.put("feeAmount", payOrder.getMchFeeAmount());
orderJSON.put("channelOrderNo", payOrder.getChannelOrderNo());
orderJSON.put("successTime", payOrder.getSuccessTime());
checkDiff.addExt("localOrder", orderJSON);
}
}else if (StringUtils.equals(checkDiff.getBillType(), CheckChannelBill.BILL_TYPE_REFUND)) {
RefundOrder refundOrder = refundOrderService.getById(checkDiff.getOrderId());
if (refundOrder != null) {
orderJSON.put("orderId", refundOrder.getRefundOrderId());
orderJSON.put("state", refundOrder.getState());
orderJSON.put("amount", refundOrder.getRefundAmount());
orderJSON.put("channelOrderNo", refundOrder.getChannelOrderNo());
orderJSON.put("successTime", refundOrder.getSuccessTime());
checkDiff.addExt("localOrder", orderJSON);
}
}
}
return ApiRes.ok(checkDiff);
}
/**
* @author: zx
* @describe: 忽略差异
*/
@PreAuthorize("hasAuthority('ENT_CHECK_DIFF_IGNORE')")
@PutMapping("/ignore/{id}")
public ApiRes ignore(@PathVariable("id") Long id) {
String ignoreType = getValStringRequired("ignoreType"); // single-单挑忽略 filter-根据筛选条件忽略
CheckDiff checkDiff = getObject(CheckDiff.class);
checkDiffService.ignoreDiff(id, ignoreType, checkDiff, getCurrentUser().getSysUser());
return ApiRes.ok();
}
/**
* @author: zx
* @describe: 差异订单 补单
*/
@PreAuthorize("hasAuthority('ENT_CHECK_DIFF_REISSUE')")
@PutMapping("/reissue/{id}")
public ApiRes reissue(@PathVariable("id") Long id) {
CheckDiff dbRecord = checkDiffService.getById(id);
if (dbRecord == null || (CheckDiff.HANDLE_STATE_WAITING == dbRecord.getHandleState() && CheckDiff.HANDLE_STATE_HANG_UP == dbRecord.getHandleState())) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
checkDiffService.reissue(dbRecord, getCurrentUser().getSysUser());
// 更新订单状态为支付中
if (StringUtils.isNotBlank(dbRecord.getOrderId())) {
// 支付订单
if (StringUtils.equals(dbRecord.getBillType(), CheckChannelBill.BILL_TYPE_PAY)) {
PayOrder dbPayOrder = payOrderService.getById(dbRecord.getOrderId());
if (dbPayOrder != null) {
payOrderProcessService.confirmSuccess(dbRecord.getOrderId(), null);
}
}else if (StringUtils.equals(dbRecord.getBillType(), CheckChannelBill.BILL_TYPE_REFUND)) {
}
}
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,350 @@
package com.jeequan.jeepay.mgr.ctrl.cashout;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.paychannel.IRepayApiService;
import com.jeequan.jeepay.core.interfaces.paychannel.aliaqfbiz.IAliaqfApiService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.df.Account;
import com.jeequan.jeepay.core.model.export.CashoutRecordExportExcel;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.*;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/***
* 提现记录管理类
*
* @author terrfly
*
* @date 2022/3/23 16:45
*/
@RestController
@RequestMapping("/api/cashouts")
public class CashoutRecordController extends CommonCtrl {
@Autowired private CashoutRecordService cashoutRecordService;
@Autowired private MchAppService mchAppService;
@Autowired private PayInterfaceConfigService payInterfaceConfigService;
@Autowired private ConfigContextQueryService configContextQueryService;
@Autowired private RateConfigService rateConfigService;
@Autowired private OrderProfitSettRecordService orderProfitSettRecordService;
@Autowired private MchInfoService mchInfoService;
@PreAuthorize("hasAuthority('ENT_PROFIT_CASHOUT_RECORD_LIST')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
CashoutRecord queryRecord = getObject(CashoutRecord.class);
LambdaQueryWrapper<CashoutRecord> wrapper = CashoutRecord.gw();
// 单号
wrapper.eq(queryRecord.getRid() != null, CashoutRecord::getRid, queryRecord.getRid());
// infoId
wrapper.eq( StringUtils.isNotEmpty(queryRecord.getInfoId() ), CashoutRecord::getInfoId, queryRecord.getInfoId());
// 状态查询
wrapper.eq(queryRecord.getState() != null, CashoutRecord::getState, queryRecord.getState());
// 名称搜索
wrapper.like(StringUtils.isNotEmpty(queryRecord.getInfoName()), CashoutRecord::getInfoName, queryRecord.getInfoName());
// 时间范围条件
Date[] dateRange = queryRecord.buildQueryDateRange();
if (dateRange[0] != null) {
wrapper.ge(CashoutRecord::getCreatedAt, dateRange[0]);
}
if (dateRange[1] != null) {
wrapper.le(CashoutRecord::getCreatedAt, dateRange[1]);
}
wrapper.orderByDesc(CashoutRecord::getCreatedAt);
IPage<CashoutRecord> pages = cashoutRecordService.page(getIPage(), wrapper);
return ApiRes.page(pages);
}
@PreAuthorize("hasAuthority('ENT_PROFIT_CASHOUT_RECORD_VIEW')")
@RequestMapping(value="/{rid}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("rid") Long rid) {
return ApiRes.ok(cashoutRecordService.getById(rid));
}
/** 审核 **/
@PreAuthorize("hasAuthority('ENT_PROFIT_CASHOUT_RECORD_AUDIT')")
@RequestMapping(value="/audit/{rid}", method = RequestMethod.POST)
public ApiRes audit(@PathVariable("rid") Long rid) {
CashoutRecord record = getObject(CashoutRecord.class);
cashoutRecordService.audit(rid, record.getState(), record.getAuditRemark(), record.getTransferCertImg());
return ApiRes.ok();
}
/** 统计 **/
@PreAuthorize("hasAuthority('ENT_PROFIT_CASHOUT_RECORD_COUNT')")
@GetMapping(value="/count")
public ApiRes count() {
CashoutRecord record = getObject(CashoutRecord.class);
Map<String, Object> result = cashoutRecordService.countByCashout(record);
return ApiRes.ok(result);
}
/**
* @author: yr
* @date: 2023/08/30 14:45
* @describe: 服务商提现记录数据导出(佣金提现)
*/
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() {
try {
CashoutRecord cashoutRecord = getObject(CashoutRecord.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<CashoutRecord> wrapper = CashoutRecord.gw();
IPage<CashoutRecord> pages = cashoutRecordService.listByPage(getIPage(true), cashoutRecord, paramJSON, wrapper);
List<JSONObject> newList = new LinkedList<>();
for (CashoutRecord cashout:pages.getRecords()) {
JSONObject object = (JSONObject) JSONObject.toJSON(cashout);
// 申请用户
if (StringUtils.isNotEmpty(cashout.getInfoId())) {
object.put("infoName", cashout.getInfoName() + "(" + cashout.getInfoId() + ")");
}
object.put("settAccountType", cashout.getSettAccountType().replaceAll("_", ""));
object.put("applyAmount", AmountUtil.convertCent2Dollar(cashout.getApplyAmount()));
object.put("settAmount", AmountUtil.convertCent2Dollar(cashout.getSettAmount()));
object.put("settFeeAmount", AmountUtil.convertCent2Dollar(cashout.getSettFeeAmount()));
newList.add(object);
}
List<CashoutRecordExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), CashoutRecordExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "提现记录", "提现记录", CashoutRecordExportExcel.class, "提现记录", response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出订单失败!");
}
}
/** 提现选择 灵活用工渠道时, 查询当前配置的自营商户的应用信息 **/
// @PreAuthorize("hasAuthority('ENT_PROFIT_CASHOUT_RECORD_AUDIT')")
@GetMapping("/platformSelfMchNoAppInfos")
public ApiRes platformSelfMchNoAppInfos() {
// 当前结算信息
CashoutRecord cashoutRecord = cashoutRecordService.getById(getValLongRequired("rid"));
// 订单不存在
if(cashoutRecord == null || cashoutRecord.getState() != CashoutRecord.CASHOUT_STATE_AUDIT_ING){
throw new BizException("审核订单不存在");
}
// 自营商户号
String platformSelfMchNo = sysConfigService.getDBDefaultConfig().getPlatformSelfMchNo();
if(StringUtils.isEmpty(platformSelfMchNo)){
throw new BizException("自营商户未配置, 请前往系统管理进行配置");
}
MchInfo mchInfo = mchInfoService.getById(platformSelfMchNo);
if(mchInfo == null || mchInfo.getState() != CS.YES){
throw new BizException("自营商户不存在或状态不可用");
}
// 查询全部应用信息
List<MchAppEntity> mchAppList = mchAppService.list(MchAppEntity.gw()
.select(MchAppEntity::getAppId, MchAppEntity::getAppName)
.eq(MchAppEntity::getMchNo, platformSelfMchNo).eq(MchAppEntity::getState, CS.YES));
for (MchAppEntity mchApp : mchAppList) {
mchApp.addExt("transIfCodeInfoList", this.packageTransIfCodeItem(cashoutRecord, cashoutRecord.getSettAccountType(), platformSelfMchNo, mchInfo.getType(),mchApp));
}
return ApiRes.ok(mchAppList);
}
// 封装 应用对应的转账渠道列表
private List<InnerTransIfCode> packageTransIfCodeItem(CashoutRecord cashoutRecord, String settAccountType, String mchNo, Byte mchType, MchAppEntity mchApp){
// 支付接口列表
List<InnerTransIfCode> result = new ArrayList<>();
// 微信转账(仅支持普通商户) 查询是否开通了对应渠道
if( TransferOrderEntity.ENTRY_WX_CASH.equals(settAccountType) && mchType == MchInfo.TYPE_NORMAL){
// 是否已正确配置
if(payInterfaceConfigService.mchAppHasAvailableIfCode(mchApp.getAppId(), CS.IF_CODE.WXPAY)){
result.add(new InnerTransIfCode(CS.IF_CODE.WXPAY, "微信支付", null, null, null));
}
}
// 支付宝转账(仅支持普通商户) 查询是否开通了对应渠道
if( TransferOrderEntity.ENTRY_ALIPAY_CASH.equals(settAccountType) && mchType == com.jeequan.jeepay.db.entity.MchInfo.TYPE_NORMAL){
// 是否已正确配置
if(payInterfaceConfigService.mchAppHasAvailableIfCode(mchApp.getAppId(), CS.IF_CODE.ALIPAY)){
result.add(new InnerTransIfCode(CS.IF_CODE.ALIPAY, "支付宝", null, null, null));
}
}
// 支付宝安全发转账产品(仅支持特约商户) 查询是否开通了对应渠道
if( TransferOrderEntity.ENTRY_ALIPAY_CASH.equals(settAccountType) && mchType == MchInfo.TYPE_ISVSUB){
// 是否已正确配置
if(payInterfaceConfigService.mchAppHasAvailableIfCode(mchApp.getAppId(), CS.IF_CODE.ALIAQF)){
try { // 查询余额
IAliaqfApiService aliaqfApiService = SpringBeansUtil.getBean(CS.IF_CODE.ALIAQF + "ApiService", IAliaqfApiService.class);
MchAppConfigContext mchAppConfigContext = configContextQueryService.queryMchInfoAndAppInfoV2(mchNo, mchApp.getAppId(),null);
JSONObject accountBookInfo = aliaqfApiService.fundAccountbookQuery(mchAppConfigContext);
result.add(new InnerTransIfCode(CS.IF_CODE.ALIAQF, "支付宝安全发",
AmountUtil.convertDollar2CentLong(accountBookInfo.getString("available_amount"))
, null
, null
));
} catch (BizException e) {
// 查询接口异常, 不影响页面显示。
result.add(new InnerTransIfCode(CS.IF_CODE.ALIAQF, "支付宝安全发", null, null, null));
logger.error("查询支付宝安全发余额异常!", e);
}
}
//如果打款配置为空
if(result.isEmpty()){
IRepayApiService repayApiService = SpringBeansUtil.getBean(CS.IF_CODE.FLPAY + "RepayApiService", IRepayApiService.class);
if(repayApiService != null){
Account account = repayApiService.queryAccountBalance(mchNo, AccountInfo.Type.REFUND.getType());
result.add(new InnerTransIfCode(CS.IF_CODE.FLPAY, "福穗·灵工",
account.getBalance(), null, 1L
));
}
}
}
// 计算手续费
for (InnerTransIfCode innerTransIfCode : result) {
innerTransIfCode.setTransferPlatformMchfeeAmount(calTransferPlatformMchfeeAmount(cashoutRecord, innerTransIfCode.ifCode, mchNo, mchType, mchApp));
innerTransIfCode.setTransferPlatformCostAmount(calTransferPlatformCostAmount(cashoutRecord, innerTransIfCode.ifCode, mchNo, mchType, mchApp));
}
return result;
}
/** 计算: 结算手续费( 仅商户费率费用 **/
private Long calTransferPlatformMchfeeAmount(CashoutRecord cashoutRecord, String ifCode, String mchNo, Byte mchType, MchAppEntity mchApp){
try {
// 转账手续费, 可以为空。
PaywayFee paywayFee = rateConfigService.queryTransferCreateOrderPaywayFee(mchNo,null, mchApp.getAppId(), ifCode, CS.PAY_WAY_CODE.TRANSFER);
if(paywayFee != null){
MutablePair<String, Long> feeAndSnapshot = paywayFee.calFeeAndSnapshot(cashoutRecord.getSettAmount());
return feeAndSnapshot.right;
}
return null;
} catch (Exception e) {
logger.error("计算手续费异常", e);
return null;
}
}
private Long calTransferPlatformCostAmount(CashoutRecord cashoutRecord, String ifCode, String mchNo, Byte mchType, MchAppEntity mchApp){
// 商户 费率费用
Long transferPlatformMchfeeAmount = calTransferPlatformMchfeeAmount(cashoutRecord, ifCode, mchNo, mchType, mchApp);
try {
if(transferPlatformMchfeeAmount == null){
return null;
}
// 普通商户, 计算商户的费率费用
if(mchType == com.jeequan.jeepay.db.entity.MchInfo.TYPE_NORMAL){
return transferPlatformMchfeeAmount;
}
// 以下为特约商户 ( 参考 转账成功 插入 分润表逻辑 )
MchInfo mchInfo = mchInfoService.getById(mchNo);
// 商户配置费率
PaywayFee paywayFeeByMch = rateConfigService.getPaywayFeeByMch(ifCode, CS.PAY_WAY_CODE.TRANSFER,null,mchApp.getRange(),mchApp.getMccCode(),mchInfo.getIsvNo());
// 平台底价
PaywayFee paywayFeeByIsv = rateConfigService.getPaywayFeeByIsvCost(ifCode, CS.PAY_WAY_CODE.TRANSFER, mchInfo.getIsvNo(),mchApp.getRange(),mchApp.getMccCode());
// 代理商的底价
List<MutablePair<String, PaywayFee>> paywayFeeByAgentList = new ArrayList<>();
// 商户的所属代理商
if(StringUtils.isNotEmpty(mchInfo.getAgentNo())) {
// 全部的代理商号 三级 --》 二级 --》 顶级
List<String> allAgentNo = agentInfoService.queryAllParentAgentNo(mchInfo.getAgentNo());
Collections.reverse(allAgentNo);
for (String agentNo : allAgentNo) {
PaywayFee paywayFeeByAgent = rateConfigService.getPaywayFeeByAgent(ifCode, CS.PAY_WAY_CODE.TRANSFER, agentNo,mchApp.getRange(),mchApp.getMccCode(),mchInfo.getIsvNo());
paywayFeeByAgentList.add(MutablePair.of(agentNo, paywayFeeByAgent));
}
}
// 计算佣金
List<OrderProfitSettRecord> result = orderProfitSettRecordService.calAllRoleProfit(mchNo, cashoutRecord.getSettAmount(), paywayFeeByMch, paywayFeeByIsv, paywayFeeByAgentList,OrderProfitSettRecord.CAL_TYPE_TRANS_ORDER,cashoutRecord.getTransferOrderId());
orderProfitSettRecordService.recordListOrderByInfo(result); // 排序
for (OrderProfitSettRecord orderProfitSettRecord : result) {
// 得到平台利润
if(CS.INFO_ID_ENUM.PLATFORM_PROFIT.equals(orderProfitSettRecord.getInfoId()) && CS.SYS_ROLE_TYPE.PLATFORM.equals(orderProfitSettRecord.getInfoType())){
return AmountUtil.minZero(transferPlatformMchfeeAmount - orderProfitSettRecord.getCalProfitAmount());
}
}
return transferPlatformMchfeeAmount;
} catch (Exception e) {
logger.error("计算手续费异常:", e);
return transferPlatformMchfeeAmount;
}
}
@Data
@AllArgsConstructor
private static class InnerTransIfCode{
private String ifCode;
private String ifCodeName;
private Long balance;
/** 商户手续费 **/
private Long transferPlatformMchfeeAmount;
/** 实际成本 **/
private Long transferPlatformCostAmount;
}
}

View File

@@ -0,0 +1,145 @@
package com.jeequan.jeepay.mgr.ctrl.common;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.ContentType;
import com.google.zxing.WriterException;
import com.jeequan.jeepay.components.oss.config.OssYmlConfig;
import com.jeequan.jeepay.components.oss.model.OssFileConfig;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.thirdparty.util.CodeImgUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
/*
* 静态文件下载/预览 ctrl
*
* @author terrfly
*
* @date 2021/6/8 17:08
*/
@Controller
public class StaticController extends CommonCtrl {
@Autowired private OssYmlConfig ossYmlConfig;
/** 图片预览 **/
@GetMapping("/api/anon/localOssFiles/**/*.*")
public ResponseEntity<InputStreamResource> imgView() {
try {
String pathAndFileName = cleanPath(request.getRequestURI().substring(24));
//查找图片文件
File imgFile = new File(ossYmlConfig.getOss().getFilePublicPath() + File.separator + pathAndFileName);
if(!imgFile.isFile() || !imgFile.exists()) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
//输出文件流(图片格式)
HttpHeaders httpHeaders = new HttpHeaders();
String mediaType = FileUtil.getMimeType(imgFile.getPath());
// 如果获取不到文件类型, 则使用流的形式进行下载。
if(StringUtils.isEmpty(mediaType)){
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
httpHeaders.setContentDisposition(ContentDisposition.attachment().filename(imgFile.getName()).build());
}else{
httpHeaders.setContentType(MediaType.parseMediaType(mediaType));
}
return new ResponseEntity<>(new InputStreamResource(FileUtil.getInputStream(imgFile)), httpHeaders, HttpStatus.OK);
} catch (Exception e) {
logger.error("static file error", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
/**
* 渠道订单号条形码图片预览
* @return
*/
@RequestMapping("/api/anon/localOssFiles/bar/{content}")
@ResponseBody
public void couponCode(@PathVariable("content") String content) throws IOException, WriterException {
int width = getValIntegerDefault("width", 230);
int height = getValIntegerDefault( "height", 75);
CodeImgUtil.writeBarCode(response.getOutputStream(), content, width, height);
}
/** 地址过滤: 1. 非法路径过滤 2.特殊字符过滤。 **/
private String cleanPath(String pathAndFileName){
if(pathAndFileName == null){
return null;
}
// 获取到文件路径地址
String[] fileAndPathArray = pathAndFileName.split("\\/");
// 安全验证是否和读取该文件
if(fileAndPathArray.length < 1 || OssFileConfig.getOssFileConfigByBizType(fileAndPathArray[0]) == null){
throw new BizException("路径不合法");
}
pathAndFileName = pathAndFileName.replaceAll("\\.\\.", "");
String result = "";
for (int i = 0 ; i < pathAndFileName.length(); i++ ){
result += cleanChar(pathAndFileName.charAt(i));
}
return result;
}
private char cleanChar(char ac){
for(int i = 48; i < 58; i++ ){
if(ac == i){
return (char) i;
}
}
for(int i = 65; i < 91; i++ ){
if(ac == i){
return (char) i;
}
}
for(int i = 97; i < 123; i++ ){
if(ac == i){
return (char) i;
}
}
switch (ac){
case '/': return '/';
case '.': return '.';
case '-': return '-';
case '_': return '_';
default: return '?';
}
}
public static void main(String[] args) {
System.out.println(ContentType.build("jpg", Charset.defaultCharset()));
}
}

View File

@@ -0,0 +1,262 @@
package com.jeequan.jeepay.mgr.ctrl.config;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.device.DeviceParams;
import com.jeequan.jeepay.core.model.device.PluginProviderParams;
import com.jeequan.jeepay.core.model.device.PosParams;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.db.entity.DeviceProvideConfig;
import com.jeequan.jeepay.db.entity.MchStoreDevice;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.DeviceProvideConfigService;
import com.jeequan.jeepay.service.impl.MchStoreDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.security.SecureRandom;
/**
* 设备厂商配置管理类
*
* @author zx
*
* @date 2021-12-28 09:15
*/
@Slf4j
@RestController
@RequestMapping("/api/device/provider")
public class DeviceProvideConfigController extends CommonCtrl {
@Autowired private DeviceProvideConfigService deviceProvideConfigService;
@Autowired private MchStoreDeviceService mchStoreDeviceService;
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 厂商配置列表
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_LIST', 'ENT_DEVICE_PRINTER_LIST', 'ENT_DEVICE_POS_LIST', 'ENT_DEVICE_PLUGIN_LIST')")
@GetMapping
public ApiRes pages() {
LambdaQueryWrapper<DeviceProvideConfig> gw = DeviceProvideConfig.gw();
gw.select(DeviceProvideConfig::getConfigId, DeviceProvideConfig::getConfigDesc, DeviceProvideConfig::getDeviceType, DeviceProvideConfig::getProvider,
DeviceProvideConfig::getCreatedAt, DeviceProvideConfig::getAppId, DeviceProvideConfig::getState);
gw.orderByDesc(DeviceProvideConfig::getCreatedAt);
if (null != getValLong("configId")) {
gw.eq(DeviceProvideConfig::getConfigId, getValLong("configId"));
}
if (null != getValByte("deviceType")) {
gw.eq(DeviceProvideConfig::getDeviceType, getValByte("deviceType"));
}
if (StringUtils.isNotBlank(getValString("provider"))) {
gw.eq(DeviceProvideConfig::getProvider, getValString("provider"));
}
if (StringUtils.isNotBlank(getValString("configDesc"))) {
gw.like(DeviceProvideConfig::getConfigDesc, getValString("configDesc"));
}
if (null != getValByte("state")) {
gw.eq(DeviceProvideConfig::getState, getValByte("state"));
}
IPage<DeviceProvideConfig> page = deviceProvideConfigService.page(getIPage(true), gw);
//返回数据
return ApiRes.page(page);
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 新增设备厂商配置
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_ADD', 'ENT_DEVICE_PRINTER_ADD', 'ENT_DEVICE_POS_ADD', 'ENT_DEVICE_PLUGIN_ADD')")
@MethodLog(remark = "新增设备厂商配置")
@PostMapping
public ApiRes add() {
DeviceProvideConfig deviceProvideConfig = getObject(DeviceProvideConfig.class);
deviceProvideConfig.setState(CS.YES);
// 根据不同设别类型,设置其他参数
setOtherParamsByDeviceType(deviceProvideConfig);
if (deviceProvideConfigService.save(deviceProvideConfig)) {
return ApiRes.ok();
}
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 设备厂商配置修改
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_EDIT', 'ENT_DEVICE_PRINTER_EDIT', 'ENT_DEVICE_POS_EDIT', 'ENT_DEVICE_PLUGIN_EDIT')")
@MethodLog(remark = "设备厂商配置修改")
@PutMapping("/{configId}")
public ApiRes update(@PathVariable("configId") Long configId) {
DeviceProvideConfig updateRecord = getObject(DeviceProvideConfig.class);
updateRecord.setConfigId(configId);
DeviceProvideConfig dbRecord = deviceProvideConfigService.getById(configId);
if (dbRecord == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
// 根据不同设别类型,设置其他参数
updateOtherParamsByDeviceType(dbRecord, updateRecord);
if(!deviceProvideConfigService.updateById(updateRecord)) {
return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, "更新失败");
}
return ApiRes.ok();
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 根据ID获取设备厂商配置
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_VIEW', 'ENT_DEVICE_PRINTER_VIEW', 'ENT_DEVICE_POS_VIEW', 'ENT_DEVICE_PLUGIN_VIEW')")
@GetMapping("/{configId}")
public ApiRes get(@PathVariable("configId") Long configId) {
DeviceProvideConfig provideConfig = deviceProvideConfigService.getById(configId);
// POS 参数脱敏特殊处理
if (provideConfig.getDeviceType() == DeviceProvideConfig.DEVICE_TYPE_POS) {
PosParams posParams = JSONObject.parseObject(provideConfig.getProviderParams(), PosParams.class);
provideConfig.setProviderParams(posParams.deSenData());
// 收银插件 参数脱敏特殊处理
} else if (provideConfig.getDeviceType() == DeviceProvideConfig.DEVICE_TYPE_PLUGIN) {
PluginProviderParams posParams = JSONObject.parseObject(provideConfig.getProviderParams(), PluginProviderParams.class);
provideConfig.setProviderParams(posParams.deSenData());
} else {
DeviceParams deviceParams = DeviceParams.factory(provideConfig.getProvider(), provideConfig.getProviderParams());
provideConfig.setProviderParams(deviceParams.deSenData());
}
return ApiRes.ok(provideConfig);
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 删除设备厂商配置
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEL', 'ENT_DEVICE_PRINTER_DEL', 'ENT_DEVICE_POS_DEL', 'ENT_DEVICE_PLUGIN_DEL')")
@MethodLog(remark = "删除设备厂商配置")
@DeleteMapping("/{configId}")
public ApiRes delete(@PathVariable("configId") Long configId) {
if (mchStoreDeviceService.count(MchStoreDevice.gw().eq(MchStoreDevice::getConfigId, configId)) > 0) {
return ApiRes.customFail("已有设备使用此配置,不可删除!");
}
if(deviceProvideConfigService.removeById(configId)) {
return ApiRes.ok();
}
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
}
/** 不同设备类型 单独的参数配置 */
public void setOtherParamsByDeviceType(DeviceProvideConfig deviceProvideConfig) {
// 扫码POS 定义appId和appSecret
if (deviceProvideConfig.getDeviceType() == DeviceProvideConfig.DEVICE_TYPE_POS) {
String appId = IdUtil.fastSimpleUUID();
SecureRandom random = RandomUtil.getSecureRandom();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 128; i++) {
sb.append(RandomUtil.BASE_CHAR_NUMBER.charAt(random.nextInt(RandomUtil.BASE_CHAR_NUMBER.length())));
}
JSONObject posParams = new JSONObject();
posParams.put("appId", appId);
posParams.put("appSecret", sb.toString());
deviceProvideConfig.setAppId(appId);
deviceProvideConfig.setProviderParams(posParams.toJSONString());
}
// 收银插件 定义appSecret
else if (deviceProvideConfig.getDeviceType() == DeviceProvideConfig.DEVICE_TYPE_PLUGIN) {
// SecureRandom random = RandomUtil.getSecureRandom();
// StringBuilder sb = new StringBuilder();
// for (int i = 0; i < 64; i++) {
// sb.append(RandomUtil.BASE_CHAR_NUMBER.charAt(random.nextInt(RandomUtil.BASE_CHAR_NUMBER.length())));
// }
PluginProviderParams providerParams = JSONObject.parseObject(deviceProvideConfig.getProviderParams(), PluginProviderParams.class);
deviceProvideConfig.setAppId(providerParams.getAppSecret());
}
// 校验APPID唯一
if (StringUtils.isNotBlank(deviceProvideConfig.getAppId()) &&
deviceProvideConfigService.count(DeviceProvideConfig.gw().eq(DeviceProvideConfig::getAppId, deviceProvideConfig.getAppId())) > 0) {
throw new BizException("appId已存在");
}
}
/** 不同设备类型 单独的参数配置 */
private void updateOtherParamsByDeviceType(DeviceProvideConfig dbRecord, DeviceProvideConfig updateRecord) {
// 扫码POS 修改appid和appsecret
if (dbRecord.getDeviceType() == DeviceProvideConfig.DEVICE_TYPE_POS) {
// 待更新的参数
PosParams updatePosParams = JSONObject.parseObject(updateRecord.getProviderParams(), PosParams.class);
// 前端未传入appSecret需复制数据库的appSecret 再更新
if (StringUtils.isBlank(updatePosParams.getAppSecret())) {
PosParams dbPosParams = JSONObject.parseObject(dbRecord.getProviderParams(), PosParams.class);
updatePosParams.setAppSecret(dbPosParams.getAppSecret());
updateRecord.setProviderParams(JSON.toJSONString(updatePosParams));
}
updateRecord.setAppId(updatePosParams.getAppId());
}
// 收银插件 修改appid和appsecret
else if (dbRecord.getDeviceType() == DeviceProvideConfig.DEVICE_TYPE_PLUGIN) {
// 待更新的参数
if (StringUtils.isNotBlank(updateRecord.getProviderParams())) {
PluginProviderParams updatePluginParams = JSONObject.parseObject(updateRecord.getProviderParams(), PluginProviderParams.class);
// 前端未传入appSecret需复制数据库的appSecret 再更新
if (StringUtils.isBlank(updatePluginParams.getAppSecret())) {
PluginProviderParams dbPluginParams = JSONObject.parseObject(dbRecord.getProviderParams(), PluginProviderParams.class);
updatePluginParams.setAppSecret(dbPluginParams.getAppSecret());
updateRecord.setProviderParams(JSON.toJSONString(updatePluginParams));
}
updateRecord.setAppId(updatePluginParams.getAppSecret());
}
}
if (StringUtils.isNotBlank(updateRecord.getProviderParams())) {
updateRecord.setProviderParams(StringKit.marge(dbRecord.getProviderParams(), updateRecord.getProviderParams(), null));
}
// 校验APPID唯一
if (StringUtils.isNotBlank(updateRecord.getAppId()) &&
deviceProvideConfigService.count(DeviceProvideConfig.gw()
.eq(DeviceProvideConfig::getAppId, updateRecord.getAppId())
.ne(DeviceProvideConfig::getConfigId, dbRecord.getConfigId())) > 0) {
throw new BizException("appId已存在");
}
}
}

View File

@@ -0,0 +1,181 @@
package com.jeequan.jeepay.mgr.ctrl.config;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.ToDoListModel;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MainChartService;
import com.jeequan.jeepay.service.impl.PayOrderService;
import com.jeequan.jeepay.service.impl.StatsTradeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 首页统计类
*
* @author pangxiaoyu
*
* @date 2021-06-07 07:15
*/
@Slf4j
@RestController
@RequestMapping("/api/mainChart")
public class MainChartController extends CommonCtrl {
@Autowired private PayOrderService payOrderService;
@Autowired private StatsTradeService statsTradeService;
@Autowired private MainChartService mainChartService;
/**
* @author: xiaoyu
* @date: 2021/12/28 14:53
* @describe: 平台商户、服务商数量统计
*/
@PreAuthorize("hasAuthority('ENT_C_MAIN_ISV_MCH_COUNT')")
@RequestMapping(value="/isvAndMchCount", method = RequestMethod.GET)
public ApiRes isvAndMchCount() {
JSONObject resJson = payOrderService.isvAndMchCount();
return ApiRes.ok(resJson);
}
/**
* @author: xiaoyu
* @date: 2021/12/28 14:53
* @describe: 今日/昨日交易统计
*/
@PreAuthorize("hasAuthority('ENT_C_MAIN_PAY_DAY_COUNT')")
@RequestMapping(value="/payDayCount", method = RequestMethod.GET)
public ApiRes payDayCount() {
JSONObject reqParamJSON = getReqParamJSON();
JSONObject resJson = statsTradeService.payDayCount(null, null, reqParamJSON);
return ApiRes.ok(resJson);
}
/**
* @author: xiaoyu
* @date: 2021/12/28 14:53
* @describe: 趋势图数据
*/
@PreAuthorize("hasAuthority('ENT_C_MAIN_PAY_TREND_COUNT')")
@RequestMapping(value="/payTrendCount", method = RequestMethod.GET)
public ApiRes payTrendCount() {
JSONObject paramJSON = getReqParamJSON();
int recentDay = paramJSON.getIntValue("recentDay");
if (recentDay == 0){
recentDay = 30; // 默认30天
}
paramJSON.put("recentDay", recentDay);
JSONObject resJson = payOrderService.payTrendCount(paramJSON, null, null);
return ApiRes.ok(resJson);
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:18
* @describe: 交易统计
*/
@PreAuthorize("hasAuthority('ENT_C_MAIN_PAY_COUNT')")
@RequestMapping(value="/payCount", method = RequestMethod.GET)
public ApiRes payCount() {
JSONObject paramJSON = getReqParamJSON();
JSONObject resJson = payOrderService.mainPagePayCount(null, null, paramJSON);
return ApiRes.ok(resJson);
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:18
* @describe: 支付方式统计
*/
@PreAuthorize("hasAuthority('ENT_C_MAIN_PAY_TYPE_COUNT')")
@RequestMapping(value="/payTypeCount", method = RequestMethod.GET)
public ApiRes payWayCount() {
JSONObject paramJSON = getReqParamJSON();
ArrayList arrayResult = payOrderService.mainPagePayTypeCount(null, null, paramJSON);
return ApiRes.ok(arrayResult);
}
/**
* @author: xiaoyu
* @date: 2022/3/23 16:39
* @describe: 拓展员商户统计数据
*/
@RequestMapping(value="/userChart", method = RequestMethod.GET)
public ApiRes userChart() {
Long sysUserId = getValLongRequired("sysUserId");
String dateRange = getValStringRequired("queryDateRange");
// 返回数据
JSONObject result = new JSONObject();
result.put("mchAllCount", 0);
result.put("mchTodayAddCount", 0);
result.put("mchOnNetCount", 0);
result.put("mchOnNetNewCount", 0);
result.put("payAllAmount", 0);
result.put("payAmount", 0);
// 拓展员邀请的商户
List<MchInfo> list = mchInfoService.list(MchInfo.gw().eq(MchInfo::getCreatedUid, sysUserId));
if (CollUtil.isEmpty(list)) {
return ApiRes.ok(result);
}
// 获取查询时间请求参数 [开始时间, 结束时间]
Date[] queryDateRangeArray = DateKit.getQueryDateRange(dateRange);
String createdStart = DateUtil.formatDateTime(queryDateRangeArray[0]);
String createdEnd = DateUtil.formatDateTime(queryDateRangeArray[1]);
// 商户总数
long mchAllCount = mchInfoService.mchCount(null, sysUserId, null, null);
result.put("mchAllCount", mchAllCount);
// 按时间搜索商户数
long mchTodayAddCount = mchInfoService.mchCount(null, sysUserId, createdStart, createdEnd);
result.put("mchTodayAddCount", mchTodayAddCount);
// 商户入网总数
long mchOnNetCount = mchInfoService.mchApplyCount(null, sysUserId, null, null);
result.put("mchOnNetCount", mchOnNetCount);
// 按时间搜索商户入网数
long mchOnNetNewCount = mchInfoService.mchApplyCount(null, sysUserId, createdStart, createdEnd);
result.put("mchOnNetNewCount", mchOnNetNewCount);
BigDecimal payAllAmount = payOrderService.totalAmount(null, sysUserId, null, null);
result.put("payAllAmount", payAllAmount);
BigDecimal payAmount = payOrderService.totalAmount(null, sysUserId, createdStart, createdEnd);
result.put("payAmount", payAmount);
return ApiRes.ok(result);
}
/**
*
* @describe (待办事项)汇总待审核或者待操作的事件数量
*
* @return
*/
@RequestMapping(value = "/getWaitOperationNumber",method = RequestMethod.GET)
public ApiRes getWaitOperationNumber(){
List<ToDoListModel> waitOperationNumber = mainChartService.getWaitOperationNumber();
return ApiRes.ok(waitOperationNumber);
}
}

View File

@@ -0,0 +1,131 @@
package com.jeequan.jeepay.mgr.ctrl.config;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.SysAdvertConfig;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.SysAdvertConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 系统广告配置
*
* @author xiaoyu
*
* @date 2023/2/20 10:57
*/
@Slf4j
@RestController
@RequestMapping("/api/advert")
public class SysAdvertController extends CommonCtrl {
@Autowired private SysAdvertConfigService advertConfigService;
/**
* @author: xiaoyu
* @date: 2023/2/20 11:06
* @describe: 广告配置列表
*/
@PreAuthorize("hasAnyAuthority('ENT_ADVERT_LIST', 'ENT_ADVERT_VIEW')")
@GetMapping
public ApiRes pages() {
SysAdvertConfig record = getObject(SysAdvertConfig.class);
LambdaQueryWrapper<SysAdvertConfig> condition = SysAdvertConfig.gw();
condition.eq(record.getAdvertId() != null, SysAdvertConfig::getAdvertId, record.getAdvertId());
condition.eq(record.getReleaseState() != null, SysAdvertConfig::getReleaseState, record.getReleaseState());
condition.eq(record.getAdvertType() != null, SysAdvertConfig::getAdvertType, record.getAdvertType());
condition.eq(record.getAppPlace() != null, SysAdvertConfig::getAppPlace, record.getAppPlace());
condition.eq(record.getAppPlaceType() != null, SysAdvertConfig::getAppPlaceType, record.getAppPlaceType());
condition.like(StringUtils.isNotEmpty(record.getTitle()), SysAdvertConfig::getTitle, record.getTitle());
condition.eq(StringUtils.isNotEmpty(record.getMchNo()), SysAdvertConfig::getMchNo, record.getMchNo());
condition.orderByDesc(SysAdvertConfig::getCreatedAt);
IPage<SysAdvertConfig> pages = advertConfigService.page(getIPage(), condition);
for (SysAdvertConfig config: pages.getRecords()) {
if (StringUtils.isNotEmpty(config.getMchNo())) {
MchInfo mchInfo = mchInfoService.getById(config.getMchNo());
if (mchInfo != null) {
config.addExt("infoName", mchInfo.getMchName());
}else {
config.addExt("infoName", "");
}
}
}
//返回数据
return ApiRes.ok(pages);
}
/** detail */
@PreAuthorize("hasAuthority( 'ENT_ADVERT_VIEW' )")
@RequestMapping(value="/{advertId}", method = RequestMethod.GET)
public ApiRes getConfigs(@PathVariable("advertId") Long advertId) {
return ApiRes.ok(advertConfigService.getById(advertId));
}
/**
* @author: xiaoyu
* @date: 2023/2/20 11:06
* @describe: 广告配置修改
*/
@PreAuthorize("hasAnyAuthority('ENT_ADVERT_EDIT')")
@MethodLog(remark = "广告配置修改")
@RequestMapping(value="/{advertId}", method = RequestMethod.PUT)
public ApiRes update(@PathVariable("advertId") Long advertId) {
SysAdvertConfig record = getObject(SysAdvertConfig.class);
record.setAdvertId(advertId);
if (getReqParamJSON().getByte("state") != null) {
record.setReleaseState(getReqParamJSON().getByte("state"));
}
advertConfigService.updateAdvert(record);
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2023/2/20 11:10
* @describe: 广告配置新增
*/
@PreAuthorize("hasAuthority( 'ENT_ADVERT_ADD' )")
@MethodLog(remark = "广告配置新增")
@RequestMapping(value="", method = RequestMethod.POST)
public ApiRes add() {
JSONObject paramJSON = getReqParamJSON();
SysAdvertConfig record = getObject(SysAdvertConfig.class);
String infoIds = paramJSON.getString("infoIds");
record.setCreatedUid(getCurrentUser().getSysUserId());
record.setCreatedBy(getCurrentUser().getSysUser().getRealname());
advertConfigService.addConfig(infoIds, record);
return ApiRes.ok();
}
/** delete */
@PreAuthorize("hasAuthority('ENT_ADVERT_DEL')")
@MethodLog(remark = "广告配置删除")
@DeleteMapping
public ApiRes del() {
String delAdvertIds = getValStringRequired("delAdvertIds");
List<String> advertIdList = Arrays.stream(delAdvertIds.split(",")).collect(Collectors.toList());
if(advertConfigService.removeByIds(advertIdList)) {
return ApiRes.ok();
}
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
}
}

View File

@@ -0,0 +1,140 @@
package com.jeequan.jeepay.mgr.ctrl.config;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.SysClientVersion;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.SysClientVersionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/**
* 版本管理
*
* @author xiaoyu
*
* @date 2021/12/31 11:11
*/
@Slf4j
@RestController
@RequestMapping("api/clientVersion")
public class SysClientVersionController extends CommonCtrl {
@Autowired private SysClientVersionService sysClientVersionService;
/**
* @author: xiaoyu
* @date: 2021/12/31 11:15
* @describe: 版本管理列表查询
*/
@GetMapping
@PreAuthorize("hasAuthority('ENT_CLIENT_VERSION_LIST')")
public ApiRes list() {
SysClientVersion clientVersion = getObject(SysClientVersion.class);
LambdaQueryWrapper<SysClientVersion> wrapper = SysClientVersion.gw();
if (StringUtils.isNotEmpty(clientVersion.getClientType())) {
wrapper.eq(SysClientVersion::getClientType, clientVersion.getClientType());
}
if (StringUtils.isNotEmpty(clientVersion.getVersionSerialNumber())) {
wrapper.eq(SysClientVersion::getVersionSerialNumber, clientVersion.getVersionSerialNumber());
}
wrapper.orderByDesc(SysClientVersion::getVersionId);
IPage clientVersionList = sysClientVersionService.page(getIPage(), wrapper);
return ApiRes.ok(clientVersionList);
}
/**
* @author: xiaoyu
* @date: 2021/12/31 11:19
* @describe: 发布新版本
*/
@MethodLog(remark = "新建版本信息")
@PostMapping
@PreAuthorize("hasAuthority('ENT_CLIENT_VERSION_ADD')")
public ApiRes add() {
SysClientVersion clientVersion = getObject(SysClientVersion.class);
// 查看当前客户端类型 & 版本序列号 是否已经存在
long dbCount = sysClientVersionService.count(
SysClientVersion.gw()
.eq(SysClientVersion::getVersionSerialNumber, clientVersion.getVersionSerialNumber())
.eq(SysClientVersion::getClientType, clientVersion.getClientType())
);
if (dbCount > 0) {
throw new BizException("当前客户端已存在此版本序列号!");
}
boolean result = sysClientVersionService.save(clientVersion);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2021/12/31 16:50
* @describe: 编辑信息
*/
@MethodLog(remark = "编辑信息")
@PreAuthorize("hasAuthority('ENT_CLIENT_VERSION_EDIT')")
@RequestMapping(value="/{recordId}", method = RequestMethod.PUT)
public ApiRes update(@PathVariable("recordId") Integer recordId) {
SysClientVersion clientVersion = getObject(SysClientVersion.class);
//根据 客户端类型 & 版本序列号 查询是否存在
SysClientVersion dbRecord = sysClientVersionService.getOne(new QueryWrapper<SysClientVersion>().lambda()
.eq(SysClientVersion::getClientType, clientVersion.getClientType())
.eq(SysClientVersion::getVersionSerialNumber, clientVersion.getVersionSerialNumber())
);
if(dbRecord != null && !dbRecord.getVersionId().equals(recordId)){
throw new BizException("当前客户端类型已存在该版本序列号!");
}
clientVersion.setVersionId(recordId);
boolean result = sysClientVersionService.updateById(clientVersion);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2021/12/31 11:28
* @describe: 查看详情
*/
@GetMapping("/{recordId}")
@PreAuthorize("hasAuthority('ENT_CLIENT_VERSION_VIEW')")
public ApiRes detail(@PathVariable("recordId") Long recordId) {
SysClientVersion clientVersion = sysClientVersionService.getById(recordId);
return ApiRes.ok(clientVersion);
}
/**
* @author: xiaoyu
* @date: 2021/12/31 11:30
* @describe: 删除信息
*/
@MethodLog(remark = "删除客户端版本")
@DeleteMapping("/{recordId}")
@PreAuthorize("hasAuthority('ENT_CLIENT_VERSION_DEL')")
public ApiRes delete(@PathVariable("recordId") Long recordId) {
boolean result = sysClientVersionService.removeById(recordId);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
}
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,245 @@
package com.jeequan.jeepay.mgr.ctrl.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.components.mq.model.ResetAppConfigMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.db.entity.SysConfig;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.SysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* 系统配置信息类
*
* @author pangxiaoyu
*
* @date 2021-06-07 07:15
*/
@Slf4j
@RestController
@RequestMapping("api/sysConfigs")
public class SysConfigController extends CommonCtrl {
@Autowired private SysConfigService sysConfigService;
@Autowired private IMQSender mqSender;
@Autowired private SmsManager smsManager;
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:19
* @describe: 分组下的配置
*/
@PreAuthorize("hasAnyAuthority('ENT_SYS_CONFIG_INFO', 'ENT_SYS_CONFIG_VIEW', 'ENT_PUSH_CONFIG_VIEW')")
@GetMapping(value = "/{groupKey}")
public ApiRes getConfigs(@PathVariable("groupKey") String groupKey) {
LambdaQueryWrapper<SysConfig> condition = SysConfig.gw();
condition.orderByAsc(SysConfig::getSortNum);
if(StringUtils.isNotEmpty(groupKey)){
condition.eq(SysConfig::getGroupKey, groupKey);
}
List<SysConfig> configList = sysConfigService.list(condition);
// 数据脱敏
this.autoDesen(configList);
//返回数据
return ApiRes.ok(configList);
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:19
* @describe: 系统配置修改
*/
@PreAuthorize("hasAnyAuthority('ENT_SYS_CONFIG_EDIT', 'ENT_PUSH_CONFIG_EDIT')")
@MethodLog(remark = "系统配置修改")
@RequestMapping(value="/{groupKey}", method = RequestMethod.PUT)
public ApiRes update(@PathVariable("groupKey") String groupKey) {
JSONObject paramJSON = getReqParamJSON();
Map<String, String> updateMap = new HashMap<>();
if ("smsConfig".equals(groupKey)) {
// 1. 选择厂商
updateMap.put("smsProvideKey", paramJSON.getString("smsProvideKey"));
// 合并
if(StringUtils.isNotEmpty(paramJSON.getString("aliyundySmsConfigValue"))){
updateMap.put("aliyundySmsConfigValue", StringKit.marge(sysConfigService.getById("aliyundySmsConfigValue").getConfigVal(), paramJSON.getString("aliyundySmsConfigValue"), null));
}
if(StringUtils.isNotEmpty(paramJSON.getString("jeepaydxSmsConfigValue"))){
updateMap.put("jeepaydxSmsConfigValue", StringKit.marge(sysConfigService.getById("jeepaydxSmsConfigValue").getConfigVal(), paramJSON.getString("jeepaydxSmsConfigValue"), null));
}
if(StringUtils.isNotEmpty(paramJSON.getString("juhedxSmsConfigValue"))){
updateMap.put("juhedxSmsConfigValue", StringKit.marge(sysConfigService.getById("juhedxSmsConfigValue").getConfigVal(), paramJSON.getString("juhedxSmsConfigValue"), null));
}
if(StringUtils.isNotEmpty(paramJSON.getString("mocktestSmsConfigValue"))){
// 没有需要加密的数据
updateMap.put("mocktestSmsConfigValue", paramJSON.getString("mocktestSmsConfigValue"));
}
}else if ("ossConfig".equals(groupKey)) {
// 合并
updateMap.put("aliyunOssConfig", StringKit.marge(sysConfigService.getById("aliyunOssConfig").getConfigVal(), paramJSON.getString("aliyunOssConfig"), null));
updateMap.put("ossUseType", paramJSON.getString("ossUseType"));
updateMap.put("ossPublicSiteUrl", paramJSON.getString("ossPublicSiteUrl"));
}else if ("oemConfig".equals(groupKey)) {
paramJSON.put("mgr", paramJSON.getJSONObject("mgr"));
paramJSON.put("mch", paramJSON.getJSONObject("mch"));
paramJSON.put("agent", paramJSON.getJSONObject("agent"));
paramJSON.put("reportIcp", paramJSON.getJSONObject("reportIcp"));
paramJSON.put("reportGa", paramJSON.getJSONObject("reportGa"));
paramJSON.put("reportJh", paramJSON.getJSONObject("reportJh"));
paramJSON.put("reportDx", paramJSON.getJSONObject("reportDx"));
paramJSON.put("copyrightInfo", paramJSON.getJSONObject("copyrightInfo"));
updateMap.put("oemConfig", paramJSON.toJSONString());
}else if ("defaultConfig".equals(groupKey)) {
updateMap = JSONObject.toJavaObject(paramJSON, Map.class);
// 处理 密码格式 解密 + 保存为DB格式,
if(StringUtils.isNotEmpty(updateMap.get("defaultPassword") ) ) {
// 20220406改为 encode格式可以解密通知短信需要查看密码原文
// String defaultPassword = new BCryptPasswordEncoder().encode(Base64.decodeStr(getValStringRequired("defaultPassword")));
// updateMap.put("defaultPassword", defaultPassword);
}else{
updateMap.remove("defaultPassword");
}
}else if ("paymentConfig".equals(groupKey)) {
updateMap.put("paymentConfig", paramJSON.toJSONString());
}else {
Map<String, String> map = JSONObject.toJavaObject(paramJSON, Map.class);
for (String key : map.keySet()) {
// 脱敏数据 && 记录为空 = 不更新
if(desenKeys.contains(key) && StringUtils.isEmpty(map.get(key))){
continue;
}
updateMap.put(key, map.get(key));
}
}
int update = sysConfigService.updateByConfigKey(updateMap);
if(update <= 0) {
return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, "更新失败");
}
// 异步更新到MQ
SpringBeansUtil.getBean(SysConfigController.class).updateSysConfigMQ(groupKey);
return ApiRes.ok();
}
@Async
public void updateSysConfigMQ(String groupKey){
mqSender.send(ResetAppConfigMQ.build(groupKey));
}
/** 过滤脱敏数据 */
private void autoDesen(List<SysConfig> sysConfigList){
if(sysConfigList == null){
return;
}
for (SysConfig sysConfig : sysConfigList) {
if (desenKeys.contains(sysConfig.getConfigKey())){
sysConfig.addExt("configValDesen", StringKit.autoDesensitization(sysConfig.getConfigVal()));
sysConfig.setConfigVal(null);
}
// 短信配置 特殊处理
if("aliyundySmsConfigValue".equals(sysConfig.getConfigKey())){
JSONObject jsonObject = JSON.parseObject(sysConfig.getConfigVal());
jsonObject.put("accessKeySecret", StringKit.autoDesensitization(jsonObject.getString("accessKeySecret")));
// 原始文件删除配置项, 在外层增加加密脱敏数据。
sysConfig.addExt("configValDesen", jsonObject.toJSONString());
jsonObject.remove("accessKeySecret");
sysConfig.setConfigVal(jsonObject.toJSONString());
}// 计全短信 特殊处理
if("jeepaydxSmsConfigValue".equals(sysConfig.getConfigKey())){
JSONObject jsonObject = JSON.parseObject(sysConfig.getConfigVal());
jsonObject.put("accountPwd", StringKit.autoDesensitization(jsonObject.getString("accountPwd")));
// 原始文件删除配置项, 在外层增加加密脱敏数据。
sysConfig.addExt("configValDesen", jsonObject.toJSONString());
jsonObject.remove("accountPwd");
sysConfig.setConfigVal(jsonObject.toJSONString());
}else if("aliyunOssConfig".equals(sysConfig.getConfigKey())){ // OSS 特殊处理
JSONObject jsonObject = JSON.parseObject(sysConfig.getConfigVal());
jsonObject.put("accessKeySecret", StringKit.autoDesensitization(jsonObject.getString("accessKeySecret")));
// 原始文件删除配置项, 在外层增加加密脱敏数据。
sysConfig.addExt("configValDesen", jsonObject.toJSONString());
jsonObject.remove("accessKeySecret");
sysConfig.setConfigVal(jsonObject.toJSONString());
}else if(SysConfigService.PAYMENT_CONFIG.left.equals(sysConfig.getConfigKey())){
JSONObject jsonObject = JSON.parseObject(sysConfig.getConfigVal());
jsonObject.put("secret", StringKit.autoDesensitization(jsonObject.getString("secret")));
// 原始文件删除配置项, 在外层增加加密脱敏数据。
sysConfig.addExt("configValDesen", jsonObject.toJSONString());
// jsonObject.remove("secret");
sysConfig.setConfigVal(jsonObject.toJSONString());
}
}
}
// 脱敏key
private static final Set<String> desenKeys = new HashSet<>();
static{
desenKeys.add("uniPushMasterSecret"); //app推送 uniPush_masterSecret
desenKeys.add("baiduBceAppSecret"); // 百度语音配置
desenKeys.add("wxAppSecret"); // 微信公众号消息配置 微信公众号AppSecret
desenKeys.add("apiMapWebSecret"); //高德地图配置
desenKeys.add("tencentSecretKey"); // 腾讯OCR
desenKeys.add("aliAccessKeySecret"); // 阿里 OCR
desenKeys.add("platformApiSecret"); // 平台通信秘钥
desenKeys.add("secret");
}
/**
* @author: yr
* @date: 2023/8/18 15:19
* @describe: 获取短信余额
*/
@PreAuthorize("hasAnyAuthority('ENT_SYS_CONFIG_INFO', 'ENT_SYS_CONFIG_VIEW', 'ENT_PUSH_CONFIG_VIEW')")
@RequestMapping(value="/smsBalance", method = RequestMethod.GET)
public ApiRes getSmsBalance() {
String bizQueryType = getValString("bizQueryType");
return ApiRes.ok(smsManager.querySmsInfo(bizQueryType));
}
}

View File

@@ -0,0 +1,125 @@
package com.jeequan.jeepay.mgr.ctrl.config;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateRange;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.components.mq.model.CleanTnDayCacheMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.SysLegalDay;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.SysLegalDayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* 系统节假日管理类
*
* @author zx
*
* @date 2023-09-26 09:15
*/
@Slf4j
@RestController
@RequestMapping("/api/sysLegelDay")
public class SysLegalDayController extends CommonCtrl {
@Autowired private SysLegalDayService sysLegalDayService;
@Autowired private IMQSender mqSender;
/**
* @Author: zx
* @Description: 列表
* @Date: 2023-09-26 09:15
*/
@PreAuthorize("hasAuthority('ENT_LEGAL_DAY_LIST')")
@GetMapping
public ApiRes list() {
SysLegalDay sysLegalDay = getObject(SysLegalDay.class);
Page<SysLegalDay> pages = sysLegalDayService.page(getIPage(), SysLegalDay.gw()
.eq(StringUtils.isNotBlank(sysLegalDay.getDateType()), SysLegalDay::getDateType, sysLegalDay.getDateType())
.orderByDesc(SysLegalDay::getDateValue)
);
return ApiRes.ok(pages);
}
/**
* @Author: zx
* @Description: 新增
* @Date: 2023-09-26 09:15
*/
@PreAuthorize("hasAuthority('ENT_LEGAL_DAY_ADD')")
@PostMapping
public ApiRes add() {
String dateType = getValStringRequired("dateType");
JSONArray dateValueArr = JSON.parseArray(getValStringRequired("dateValueArr"));
if (CollUtil.isEmpty(dateValueArr) || dateValueArr.size() != 2) {
return ApiRes.customFail("请选择日期区间");
}
DateRange range = DateUtil.range(dateValueArr.getDate(0), dateValueArr.getDate(1), DateField.DAY_OF_YEAR);
List<DateTime> dateValueList = new ArrayList<>();
while (range.hasNext()) {
dateValueList.add(range.next());
}
if (sysLegalDayService.count(SysLegalDay.gw().in(SysLegalDay::getDateValue, dateValueList)) > 0) {
throw new BizException("选择的日期区间包含已创建日期");
}
List<SysLegalDay> insertList = new LinkedList<>();
for (DateTime dateValue : dateValueList) {
SysLegalDay record = new SysLegalDay();
record.setDateType(dateType);
record.setDateValue(dateValue);
insertList.add(record);
}
boolean saveResult = sysLegalDayService.saveBatch(insertList);
if(!saveResult) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
// 清空T+N缓存日期
mqSender.send(CleanTnDayCacheMQ.build());
return ApiRes.ok();
}
/**
* @Author: zx
* @Description: 删除
* @Date: 2023-09-26 09:15
*/
@PreAuthorize("hasAuthority('ENT_LEGAL_DAY_DEL')")
@DeleteMapping("/{recordId}")
public ApiRes delete(@PathVariable("recordId") String recordId) {
boolean result = sysLegalDayService.removeById(recordId);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
}
// 清空T+N缓存日期
mqSender.send(CleanTnDayCacheMQ.build());
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,129 @@
package com.jeequan.jeepay.mgr.ctrl.config;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.bizcommons.manage.MchStoreTerminalManage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchStoreTerminal;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchStoreTerminalService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/***
* 终端设备管理
*
* @author terrfly
*
* @date 2022/4/26 17:34
*/
@Slf4j
@RestController
@RequestMapping("/api/mchTerminals")
public class TerminalController extends CommonCtrl {
@Autowired private MchStoreTerminalService mchStoreTerminalService;
@Autowired private MchStoreTerminalManage mchStoreTerminalManage;
@PreAuthorize("hasAuthority('ENT_TERMINAL_LIST')")
@GetMapping
public ApiRes pages() {
// 请求参数
MchStoreTerminal queryObject = getObject(MchStoreTerminal.class);
IPage<MchStoreTerminal> page = mchStoreTerminalService.getMchStoreTerminalList(getIPage(), queryObject);
return ApiRes.page(page);
}
/** detail */
@PreAuthorize("hasAuthority( 'ENT_TERMINAL_VIEW' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") String recordId) {
return ApiRes.ok(mchStoreTerminalService.getById(recordId));
}
/** add */
@PreAuthorize("hasAuthority( 'ENT_TERMINAL_ADD' )")
@MethodLog(remark = "添加商户终端信息")
@RequestMapping(value="", method = RequestMethod.POST)
public ApiRes add() {
return mchStoreTerminalManage.add(getObject(MchStoreTerminal.class));
}
/** update */
@PreAuthorize("hasAuthority( 'ENT_TERMINAL_EDIT' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.PUT)
@MethodLog(remark = "更新商户终端信息")
public ApiRes update(@PathVariable("recordId") Long recordId) {
MchStoreTerminal record = getObject(MchStoreTerminal.class);
record.setTrmId(recordId);
return mchStoreTerminalManage.update(record);
}
/** update */
@PreAuthorize("hasAuthority( 'ENT_TERMINAL_EDIT' )")
@RequestMapping(value="/trmDefaults", method = RequestMethod.PUT)
@MethodLog(remark = "更新商户终端默认状态")
public ApiRes updateDefault() {
return mchStoreTerminalManage.updateDefault(getValLongRequired("trmId"), getValByteRequired("defaultFlag"));
}
/** delete */
@PreAuthorize("hasAuthority('ENT_TERMINAL_DEL')")
@MethodLog(remark = "删除终端")
@RequestMapping(value="/{recordId}", method = RequestMethod.DELETE)
public ApiRes del(@PathVariable("recordId") String recordId) {
mchStoreTerminalService.removeById(recordId);
return ApiRes.ok();
}
/** 报备列表 */
@PreAuthorize("hasAuthority('ENT_TERMINAL_SENDUP')")
@RequestMapping(value="channelBindInfos/{recordId}", method = RequestMethod.GET)
public ApiRes channelBindInfos(@PathVariable("recordId") Long recordId) {
return mchStoreTerminalManage.getChannelBindInfos(recordId);
}
/** 终端报备 */
@PreAuthorize("hasAuthority('ENT_TERMINAL_SENDUP')")
@MethodLog(remark = "终端报备")
@RequestMapping(value="channelSendup/{recordId}", method = RequestMethod.POST)
public ApiRes channelSendup(@PathVariable("recordId") Long recordId) {
String ifCode = getValStringRequired("ifCode");
Byte state = getValByteRequired("state"); // 0 - 取消报备, 1- 申请报备
return mchStoreTerminalManage.channelSendup(recordId, ifCode, state);
}
/** 修改终端报备信息 */
@PreAuthorize("hasAuthority('ENT_TERMINAL_SENDUP')")
@MethodLog(remark = "自定义终端报备信息")
@RequestMapping(value="channelBindInfos/{recordId}", method = RequestMethod.POST)
public ApiRes updChannelBindInfos(@PathVariable("recordId") Long recordId) {
String ifCode = getValStringRequired("ifCode");
String channelTrmNo = getValStringDefault("channelTrmNo", ""); // 报备信息
Byte state = getValByteRequired("state");
return mchStoreTerminalManage.updChannelBindInfos(recordId, ifCode, channelTrmNo, state);
}
}

View File

@@ -0,0 +1,64 @@
package com.jeequan.jeepay.mgr.ctrl.division;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBApplicationConfig;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.db.entity.MchAppEntity;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 商户通道API
*
* @author xiaoyu
*
* @date 2022/1/5 17:56
*/
@RestController
@RequestMapping("/api/mchChannel")
public class MchChannelUserController extends CommonCtrl {
@Autowired private MchAppService mchAppService;
@Autowired private SysConfigService sysConfigService;
/** 获取渠道侧用户ID **/
@PreAuthorize("hasAuthority('ENT_DIVISION_CHANNEL_USER')")
@GetMapping("/channelUserId")
public ApiRes channelUserId() {
String appId = getValStringRequired("appId");
MchAppEntity mchAppEntity = mchAppService.getById(appId);
if(mchAppEntity == null || mchAppEntity.getState() != CS.PUB_USABLE){
throw new BizException("商户应用不存在或不可用");
}
JSONObject param = getReqParamJSON();
param.put("mchNo", mchAppEntity.getMchNo());
param.put("appId", appId);
param.put("ifCode", getValStringRequired("ifCode"));
param.put("extParam", getValStringRequired("extParam"));
param.put("reqTime", DateKit.currentTimeMillis() + "");
param.put("version", "1.0");
param.put("signType", "MD5");
DBApplicationConfig dbApplicationConfig = sysConfigService.getDBApplicationConfig();
param.put("redirectUrl", dbApplicationConfig.getMgrSiteUrl() + "/api/anon/channelUserIdCallback");
param.put("sign", JeepayKit.getSign(param, mchAppEntity.getAppSecret()));
String url = StringKit.appendUrlQuery(dbApplicationConfig.getPaySiteUrl() + "/api/channelUserId/jump", param);
return ApiRes.ok(url);
}
}

View File

@@ -0,0 +1,236 @@
package com.jeequan.jeepay.mgr.ctrl.division;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.JeepayClient;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchAppEntity;
import com.jeequan.jeepay.db.entity.MchDivisionReceiver;
import com.jeequan.jeepay.exception.JeepayException;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.model.DivisionReceiverBindReqModel;
import com.jeequan.jeepay.model.DivisionReceiverChannelBalanceCashoutReqModel;
import com.jeequan.jeepay.model.DivisionReceiverChannelBalanceQueryReqModel;
import com.jeequan.jeepay.request.DivisionReceiverBindRequest;
import com.jeequan.jeepay.request.DivisionReceiverChannelBalanceCashoutRequest;
import com.jeequan.jeepay.request.DivisionReceiverChannelBalanceQueryRequest;
import com.jeequan.jeepay.response.DivisionReceiverBindResponse;
import com.jeequan.jeepay.response.DivisionReceiverChannelBalanceCashoutResponse;
import com.jeequan.jeepay.response.DivisionReceiverChannelBalanceQueryResponse;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.MchDivisionReceiverService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
/**
* 商户分账接收者账号关系维护
*
* @author terrfly
*
* @date 2021-08-23 11:50
*/
@RestController
@RequestMapping("api/divisionReceivers")
public class MchDivisionReceiverController extends CommonCtrl {
@Autowired
private MchDivisionReceiverService mchDivisionReceiverService;
@Autowired
private MchAppService mchAppService;
@Autowired
private SysConfigService sysConfigService;
/**
* list
*/
@PreAuthorize("hasAnyAuthority( 'ENT_DIVISION_RECEIVER_LIST' )")
@RequestMapping(value = "", method = RequestMethod.GET)
public ApiRes list() {
MchDivisionReceiver queryObject = getObject(MchDivisionReceiver.class);
IPage<MchDivisionReceiver> records = mchDivisionReceiverService.listByPage(getIPage(true), queryObject);
// 商户名称存入
setMchName(records.getRecords());
return ApiRes.page(records);
}
/**
* detail
*/
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECEIVER_VIEW' )")
@RequestMapping(value = "/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") Long recordId) {
MchDivisionReceiver record = mchDivisionReceiverService
.getOne(MchDivisionReceiver.gw()
.eq(MchDivisionReceiver::getReceiverId, recordId));
if (record == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(record);
}
/**
* add
*/
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECEIVER_ADD' )")
@RequestMapping(value = "", method = RequestMethod.POST)
@MethodLog(remark = "新增分账接收账号")
public ApiRes add() {
DivisionReceiverBindReqModel model = getObject(DivisionReceiverBindReqModel.class);
model.setPas(SysConfigService.PLATFORM_API_SECRET); // 通信秘钥
if (StringUtils.isEmpty(model.getMchNo())) {
throw new BizException("商户号不能为空");
}
MchAppEntity mchAppEntity = mchAppService.getById(model.getAppId());
if (mchAppEntity == null || mchAppEntity.getState() != CS.PUB_USABLE || !mchAppEntity.getMchNo().equals(model.getMchNo())) {
throw new BizException("商户应用不存在或不可用");
}
DivisionReceiverBindRequest request = new DivisionReceiverBindRequest();
request.setBizModel(model);
model.setMchNo(model.getMchNo());
model.setAppId(mchAppEntity.getAppId());
model.setDivisionProfit(new BigDecimal(model.getDivisionProfit()).divide(new BigDecimal(100)).toPlainString());
JeepayClient jeepayClient = new JeepayClient(sysConfigService.getDBApplicationConfig().getPaySiteUrl(), mchAppEntity.getAppSecret());
try {
DivisionReceiverBindResponse response = jeepayClient.execute(request);
if (response.getCode() != 0) {
throw new BizException(response.getMsg());
}
return ApiRes.ok(response.get());
} catch (JeepayException e) {
throw new BizException(e.getMessage());
}
}
/**
* update
*/
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECEIVER_EDIT' )")
@RequestMapping(value = "/{recordId}", method = RequestMethod.PUT)
@MethodLog(remark = "更新分账接收账号")
public ApiRes update(@PathVariable("recordId") Long recordId) {
// 请求参数
MchDivisionReceiver reqReceiver = getObject(MchDivisionReceiver.class);
reqReceiver.setReceiverId(recordId);
mchDivisionReceiverService.updateReceiver(reqReceiver);
return ApiRes.ok();
}
/**
* delete
*/
@PreAuthorize("hasAuthority('ENT_DIVISION_RECEIVER_DELETE')")
@RequestMapping(value = "/{recordId}", method = RequestMethod.DELETE)
@MethodLog(remark = "删除分账接收账号")
public ApiRes del(@PathVariable("recordId") Long recordId) {
MchDivisionReceiver record = mchDivisionReceiverService.getOne(MchDivisionReceiver.gw()
.eq(MchDivisionReceiver::getReceiverGroupId, recordId));
if (record == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
mchDivisionReceiverService.removeById(recordId);
return ApiRes.ok();
}
/**
* 查询账户余额
*/
@PreAuthorize("hasAuthority('ENT_DIVISION_RECEIVER_EDIT')")
@RequestMapping(value = "/channelBalances/{recordId}", method = RequestMethod.GET)
public ApiRes channelBalances(@PathVariable("recordId") Long recordId) {
MchDivisionReceiver record = mchDivisionReceiverService.getById(recordId);
if (record == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
MchAppEntity mchAppEntity = mchAppService.getById(record.getAppId());
if (mchAppEntity == null || mchAppEntity.getState() != CS.PUB_USABLE || !mchAppEntity.getMchNo().equals(record.getMchNo())) {
throw new BizException("商户应用不存在或不可用");
}
DivisionReceiverChannelBalanceQueryRequest request = new DivisionReceiverChannelBalanceQueryRequest();
DivisionReceiverChannelBalanceQueryReqModel model = new DivisionReceiverChannelBalanceQueryReqModel();
model.setPas(SysConfigService.PLATFORM_API_SECRET); // 通信秘钥
model.setReceiverId(recordId);
model.setMchNo(record.getMchNo());
model.setAppId(mchAppEntity.getAppId());
request.setBizModel(model);
JeepayClient jeepayClient = new JeepayClient(sysConfigService.getDBApplicationConfig().getPaySiteUrl(), mchAppEntity.getAppSecret());
try {
DivisionReceiverChannelBalanceQueryResponse response = jeepayClient.execute(request);
if (response.getCode() != 0) {
throw new BizException(response.getMsg());
}
return ApiRes.ok(response.get());
} catch (JeepayException e) {
throw new BizException(e.getMessage());
}
}
/**
* 发起提现
*/
@PreAuthorize("hasAuthority('ENT_DIVISION_RECEIVER_EDIT')")
@RequestMapping(value = "/channelCashout/{recordId}", method = RequestMethod.POST)
@MethodLog(remark = "分账账户发起提现")
public ApiRes channelCashout(@PathVariable("recordId") Long recordId) {
MchDivisionReceiver record = mchDivisionReceiverService.getById(recordId);
if (record == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
MchAppEntity mchAppEntity = mchAppService.getById(record.getAppId());
if (mchAppEntity == null || mchAppEntity.getState() != CS.PUB_USABLE || !mchAppEntity.getMchNo().equals(record.getMchNo())) {
throw new BizException("商户应用不存在或不可用");
}
DivisionReceiverChannelBalanceCashoutRequest request = new DivisionReceiverChannelBalanceCashoutRequest();
DivisionReceiverChannelBalanceCashoutReqModel model = new DivisionReceiverChannelBalanceCashoutReqModel();
model.setPas(SysConfigService.PLATFORM_API_SECRET); // 通信秘钥
model.setReceiverId(recordId);
model.setCashoutAmount(getRequiredAmountL("cashoutAmount"));
model.setMchNo(record.getMchNo());
model.setAppId(mchAppEntity.getAppId());
request.setBizModel(model);
JeepayClient jeepayClient = new JeepayClient(sysConfigService.getDBApplicationConfig().getPaySiteUrl(), mchAppEntity.getAppSecret());
try {
DivisionReceiverChannelBalanceCashoutResponse response = jeepayClient.execute(request);
if (response.getCode() != 0) {
throw new BizException(response.getMsg());
}
return ApiRes.ok(response.get());
} catch (JeepayException e) {
throw new BizException(e.getMessage());
}
}
}

View File

@@ -0,0 +1,88 @@
package com.jeequan.jeepay.mgr.ctrl.division;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchDivisionReceiverGroup;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchDivisionReceiverGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* 商户分账接收者账号组
*
* @author terrfly
*
* @date 2021-08-23 11:50
*/
@RestController
@RequestMapping("api/divisionReceiverGroups")
public class MchDivisionReceiverGroupController extends CommonCtrl {
@Autowired private MchDivisionReceiverGroupService mchDivisionReceiverGroupService;
/** list */
@PreAuthorize("hasAnyAuthority( 'ENT_DIVISION_RECEIVER_GROUP_LIST' )")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
MchDivisionReceiverGroup queryObject = getObject(MchDivisionReceiverGroup.class);
IPage<MchDivisionReceiverGroup> records = mchDivisionReceiverGroupService.listByPage(getIPage(true), queryObject);
// 商户名称存入
setMchName(records.getRecords());
return ApiRes.page(records);
}
/** detail */
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECEIVER_GROUP_VIEW' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") Long recordId) {
MchDivisionReceiverGroup record = mchDivisionReceiverGroupService
.getOne(MchDivisionReceiverGroup.gw()
.eq(MchDivisionReceiverGroup::getReceiverGroupId, recordId));
if (record == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(record);
}
/** add */
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECEIVER_GROUP_ADD' )")
@RequestMapping(value="", method = RequestMethod.POST)
@MethodLog(remark = "新增分账账号组")
public ApiRes add() {
MchDivisionReceiverGroup record = getObject(MchDivisionReceiverGroup.class);
record.setCreatedUid(getCurrentUser().getSysUser().getSysUserId());
record.setCreatedBy(getCurrentUser().getSysUser().getRealname());
mchDivisionReceiverGroupService.add(record);
return ApiRes.ok();
}
/** update */
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECEIVER_GROUP_EDIT' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.PUT)
@MethodLog(remark = "更新分账账号组")
public ApiRes update(@PathVariable("recordId") Long recordId) {
MchDivisionReceiverGroup reqRecord = getObject(MchDivisionReceiverGroup.class);
reqRecord.setReceiverGroupId(recordId);
mchDivisionReceiverGroupService.updateGroup(reqRecord);
return ApiRes.ok();
}
/** delete */
@PreAuthorize("hasAuthority('ENT_DIVISION_RECEIVER_GROUP_DELETE')")
@RequestMapping(value="/{recordId}", method = RequestMethod.DELETE)
@MethodLog(remark = "删除分账账号组")
public ApiRes del(@PathVariable("recordId") Long recordId) {
mchDivisionReceiverGroupService.removeGroup(recordId, null);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,124 @@
package com.jeequan.jeepay.mgr.ctrl.division;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.components.mq.model.PayOrderDivisionMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.IConfigContextQueryService;
import com.jeequan.jeepay.core.interfaces.paychannel.IDivisionService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.PayOrderDivisionRecord;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.PayOrderDivisionRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
/**
* 分账记录
*
* @author terrfly
*
* @date 2021-08-25 11:50
*/
@RestController
@RequestMapping("api/division/records")
public class PayOrderDivisionRecordController extends CommonCtrl {
@Autowired private PayOrderDivisionRecordService payOrderDivisionRecordService;
@Autowired private IMQSender mqSender;
@Autowired private IConfigContextQueryService configContextQueryService;
/** list */
@PreAuthorize("hasAnyAuthority( 'ENT_DIVISION_RECORD_LIST' )")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
PayOrderDivisionRecord queryObject = getObject(PayOrderDivisionRecord.class);
IPage<PayOrderDivisionRecord> records = payOrderDivisionRecordService.listByPage(getIPage(true), queryObject);
return ApiRes.page(records);
}
/** detail */
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECORD_VIEW' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") Long recordId) {
PayOrderDivisionRecord record = payOrderDivisionRecordService
.getOne(PayOrderDivisionRecord.gw()
.eq(PayOrderDivisionRecord::getRecordId, recordId));
if (record == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(record);
}
/** 分账接口重试 */
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECORD_RESEND' )")
@RequestMapping(value="/resend", method = RequestMethod.POST)
public ApiRes resend() {
List<String> recordIds = Arrays.asList(getValStringRequired("recordIds").split(","));
// 筛选分账失败的账单
List<PayOrderDivisionRecord> recordList = payOrderDivisionRecordService.list(
PayOrderDivisionRecord.gw()
.in(PayOrderDivisionRecord::getRecordId, recordIds)
.eq(PayOrderDivisionRecord::getState, PayOrderDivisionRecord.STATE_FAIL)
);
if (CollUtil.isEmpty(recordList)) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
// 是否重新计算订单金额
boolean isResendAndRecalAmount = (CS.YES == getValByteDefault("isResendAndRecalAmount", CS.NO));
// 重发到MQ
for (PayOrderDivisionRecord record: recordList) {
mqSender.send(PayOrderDivisionMQ.build(record.getPayOrderId(), null, null, true, isResendAndRecalAmount));
}
return ApiRes.ok();
}
/** 分账完结 */
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECORD_RESEND' )")
@RequestMapping(value="/finish", method = RequestMethod.POST)
public ApiRes finish() {
List<String> recordIds = Arrays.asList(getValStringRequired("recordIds").split(","));
// 筛选分账成功的账单
List<PayOrderDivisionRecord> recordList = payOrderDivisionRecordService.list(
PayOrderDivisionRecord.gw()
.in(PayOrderDivisionRecord::getRecordId, recordIds)
.eq(PayOrderDivisionRecord::getState, PayOrderDivisionRecord.STATE_SUCCESS)
.eq(com.jeequan.jeepay.core.entity.PayOrderDivisionRecord::getIfCode, CS.IF_CODE.WXPAY)
);
if (CollUtil.isEmpty(recordList)) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
//调起上游接口
IDivisionService divisionService = SpringBeansUtil.getBean("wxpayDivisionService", IDivisionService.class);
if(divisionService == null){
throw new BizException("系统不支持该分账接口");
}
for(PayOrderDivisionRecord record : recordList) {
divisionService.divisionFinishAfterDivision(record, configContextQueryService.queryMchInfoAndAppInfoV2(record.getMchNo(), record.getAppId(),record.getMchExtNo()));
}
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,53 @@
package com.jeequan.jeepay.mgr.ctrl.division;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PayOrderDivisionRefundRecord;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.PayOrderDivisionRefundRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* 分账回退记录
*
* @author terrfly
*
* @date 2022-06-10 17:50
*/
@RestController
@RequestMapping("api/division/refunds/records")
public class PayOrderDivisionRefundRecordController extends CommonCtrl {
@Autowired private PayOrderDivisionRefundRecordService payOrderDivisionRefundRecordService;
/** list */
@PreAuthorize("hasAnyAuthority( 'ENT_DIVISION_REFUND_RECORD_LIST' )")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
PayOrderDivisionRefundRecord queryObject = getObject(PayOrderDivisionRefundRecord.class);
IPage<PayOrderDivisionRefundRecord> pages = payOrderDivisionRefundRecordService.listByPage(getIPage(), queryObject);
return ApiRes.page(pages);
}
/** detail */
@PreAuthorize("hasAuthority( 'ENT_DIVISION_REFUND_RECORD_VIEW' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") String recordId) {
PayOrderDivisionRefundRecord record = payOrderDivisionRefundRecordService
.getOne(PayOrderDivisionRefundRecord.gw()
.eq(PayOrderDivisionRefundRecord::getDivisionRefundId, recordId));
if (record == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(record);
}
}

View File

@@ -0,0 +1,236 @@
package com.jeequan.jeepay.mgr.ctrl.isv;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.components.mq.model.ResetIsvMchAppInfoConfigMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.IsvInfo;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.PrefixConfig;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.IsvInfoEntity;
import com.jeequan.jeepay.db.entity.MchConfig;
import com.jeequan.jeepay.db.entity.RateConfig;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.IsvInfoService;
import com.jeequan.jeepay.service.impl.PayInterfaceConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* 渠道商管理类
*/
@RestController
@RequestMapping("/api/isvInfo")
public class IsvInfoController extends CommonCtrl {
@Autowired
private IsvInfoService isvInfoService;
@Autowired
private IMQSender mqSender;
@Autowired
private PrefixConfig prefixConfig;
@Autowired
private PayInterfaceConfigService payInterfaceConfigService;
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:12
* @describe: 查询渠道商信息列表 ( 渠道商列表 和 新增商户都可查询 )
*/
@PreAuthorize("hasAnyAuthority('ENT_ISV_LIST', 'ENT_MCH_INFO_ADD')")
@GetMapping
public ApiRes list() {
IsvInfoEntity isvInfoEntity = getObject(IsvInfoEntity.class);
LambdaQueryWrapper<IsvInfoEntity> wrapper = IsvInfoEntity.gw();
if (StringUtils.isNotEmpty(isvInfoEntity.getIsvNo())) {
wrapper.eq(IsvInfoEntity::getIsvNo, isvInfoEntity.getIsvNo());
}
if (StringUtils.isNotEmpty(isvInfoEntity.getIsvName())) {
wrapper.eq(IsvInfoEntity::getIsvName, isvInfoEntity.getIsvName());
}
if (isvInfoEntity.getState() != null) {
wrapper.eq(IsvInfoEntity::getState, isvInfoEntity.getState());
}
wrapper.orderByDesc(IsvInfoEntity::getCreatedAt);
IPage<IsvInfoEntity> pages = isvInfoService.page(getIPage(true), wrapper);
return ApiRes.page(pages);
}
/**
* 新增渠道商信息
*/
@PreAuthorize("hasAuthority('ENT_ISV_INFO_ADD')")
@MethodLog(remark = "新增渠道商")
@PostMapping
public ApiRes add() {
IsvInfoEntity isvInfoEntity = getObject(IsvInfoEntity.class);
isvInfoEntity.setIsvNo(SeqKit.genIsvNo());
isvInfoEntity.setCreatedUid(getCurrentUser().getSysUser().getSysUserId());
isvInfoEntity.setCreatedBy(getCurrentUser().getSysUser().getRealname());
boolean result = isvInfoService.save(isvInfoEntity);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
return ApiRes.ok();
}
/**
* 删除渠道商信息
*/
@PreAuthorize("hasAuthority('ENT_ISV_INFO_DEL')")
@MethodLog(remark = "删除渠道商")
@DeleteMapping("/{isvNo}")
public ApiRes delete(@PathVariable("isvNo") String isvNo) {
isvInfoService.removeByIsvNo(isvNo);
// 推送mq到目前节点进行更新数据
mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_ISV_INFO, isvNo, null, null));
return ApiRes.ok();
}
/**
* 更新渠道商信息
*/
@PreAuthorize("hasAuthority('ENT_ISV_INFO_EDIT')")
@MethodLog(remark = "更新渠道商信息")
@PutMapping("/{isvNo}")
public ApiRes update(@PathVariable("isvNo") String isvNo) {
IsvInfoEntity isvInfoEntity = getObject(IsvInfoEntity.class);
isvInfoEntity.setIsvNo(isvNo);
boolean result = isvInfoService.updateById(isvInfoEntity);
// 推送mq到目前节点进行更新数据
mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_ISV_INFO, isvNo, null, null));
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
@PreAuthorize("hasAnyAuthority('ENT_ISV_INFO_VIEW', 'ENT_ISV_INFO_EDIT')")
@GetMapping("/{isvNo}")
public ApiRes detail(@PathVariable("isvNo") String isvNo) {
IsvInfoEntity isvInfoEntity = isvInfoService.getById(isvNo);
if (isvInfoEntity == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(isvInfoEntity);
}
@GetMapping("/isvInfoList")
public ApiRes getIsvInfoList() {
String ifCode = getValStringRequired("ifCode");
String infoType = getValStringRequired("infoType");
String infoId = getValStringRequired("infoId");
String range = getValString("range");
Integer state = getValInteger("state");
String isvName = getValString("isvName");
List<IsvInfo> isvAndPayConfig = isvInfoService.getIsvAndPayConfig(infoType, isvName,infoId, ifCode, range, state);
Page<IsvInfo> page = new Page<>();
page.setRecords(isvAndPayConfig);
page.setSize(-1);
page.setPages(1);
if (!CS.SYS_ROLE_TYPE.MCH.equalsIgnoreCase(infoType)) {
return ApiRes.ok(page);
}
// 如果是查看商户数据,则查询他的默认渠道
List<Map<String, String>> defIsv = mchInfoService.getDefIsv(infoId, ifCode);
if (!ObjectUtils.isEmpty(defIsv)) {
Map<String, String> defIsvItem = defIsv.get(0);
String defIsvNo = defIsvItem.get(MchConfig.getDefIsvKey(ifCode));
page.getRecords().forEach(r -> r.addExt("defFlag", r.getIsvNo().equals(defIsvNo) ? CS.YES : CS.NO));
} else {
page.getRecords().forEach(r -> r.addExt("defFlag", CS.NO));
}
return ApiRes.ok(page);
}
@PostMapping("/autoBindIsvConn")
public ApiRes autoBindIsvConn() {
String isvNo = getValStringRequired("isvNo");
String infoId = getValStringRequired("infoId");
String roleType = getValStringRequired("roleType");
Byte configStatus = getValByteRequired("configStatus");
isvInfoService.autoBindIsvConn(isvNo, infoId, roleType, configStatus);
return ApiRes.ok();
}
/**
* 获取商户费率在对应渠道下的费率
*
*/
@GetMapping("/mchUpsRate")
public ApiRes getMchUpsRateList() {
String mchNo = getValStringRequired("mchNo");
String isvNo = getValStringRequired("isvNo");
String ifCode = getValStringRequired("ifCode");
Integer range = getValIntegerRequired("range");
String mccCode = getValString("mccCode");
List<RateConfig> mchUpsRateList = isvInfoService.getMchIsvRateConfig(mchNo, isvNo, ifCode, range, mccCode);
return ApiRes.ok(mchUpsRateList);
}
/**
* 新建服务商、用户与渠道的关联关系
*/
@PostMapping("/isvConn")
public ApiRes isvConn() {
String isvNo = getValStringRequired("isvNo");
String infoId = getValStringRequired("infoId");
String infoType = getValStringRequired("infoType");
isvInfoService.saveIsvConn(isvNo, infoType, infoId, getCurrentUser().getSysUser());
return ApiRes.ok();
}
@GetMapping("/getSettType")
public ApiRes getSettType(){
String ifCode = getValStringRequired("ifCode");
String infoId = getValStringRequired("infoId");
JSONArray settType = isvInfoService.getSettType(ifCode, infoId);
return ApiRes.ok(settType);
}
@PostMapping("/editStatus")
public ApiRes editStatus() {
String isvNo = getValStringRequired("isvNo");
String ifCode = getValStringRequired("ifCode");
String infoId = getValStringRequired("infoId");
String infoType = getValStringRequired("infoType");
Integer status = getValIntegerRequired("state");
isvInfoService.editConnStatus(isvNo, ifCode, infoId, infoType, status);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,83 @@
package com.jeequan.jeepay.mgr.ctrl.member;
import cn.hutool.core.util.DesensitizedUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MemberAccountHistory;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MemberAccountHistoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* 会员账户流水
*
* @author xiaoyu
*
* @date 2023/4/13 17:22
*/
@RestController
@RequestMapping("/api/member/accountHistory")
public class MemberAccountHistoryController extends CommonCtrl {
@Autowired private MemberAccountHistoryService accountHistoryService;
/**
* @author: xiaoyu
* @date: 2023/4/13 17:24
* @describe: 会员账户流水列表
*/
@PreAuthorize("hasAuthority('ENT_MEMBER_ACCOUNT_HISTORY_LIST')")
@GetMapping
public ApiRes list() {
MemberAccountHistory accountHistory = getObject(MemberAccountHistory.class);
LambdaQueryWrapper<MemberAccountHistory> wrapper = MemberAccountHistory.gw();
// 查询条件
accountHistoryService.selectParams(accountHistory, wrapper);
wrapper.orderByDesc(MemberAccountHistory::getCreatedAt);
IPage<MemberAccountHistory> page = accountHistoryService.page(getIPage(), wrapper);
// 手机号脱敏
page.getRecords().stream().forEach(i -> i.setMbrTel(DesensitizedUtil.mobilePhone(i.getMbrTel())));
return ApiRes.page(page);
}
/**
* @author: xiaoyu
* @date: 2023/4/13 17:49
* @describe: 会员账户流水信息
*/
@PreAuthorize("hasAuthority('ENT_MEMBER_ACCOUNT_HISTORY_VIEW')")
@GetMapping("/{hid}")
public ApiRes detail(@PathVariable("hid") String hid) {
MemberAccountHistory history = accountHistoryService.getById(hid);
return ApiRes.ok(history);
}
/**
* @author: xiaoyu
* @date: 2023/4/18 9:32
* @describe: 账户流水统计
*/
@RequestMapping(value="/count", method = RequestMethod.GET)
public ApiRes count() {
MemberAccountHistory accountHistory = getObject(MemberAccountHistory.class);
LambdaQueryWrapper<MemberAccountHistory> wrapper = MemberAccountHistory.gw();
// 查询参数
accountHistoryService.selectParams(accountHistory, wrapper);
Map count = accountHistoryService.count(wrapper);
return ApiRes.ok(count);
}
}

View File

@@ -0,0 +1,242 @@
package com.jeequan.jeepay.mgr.ctrl.member;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.DesensitizedUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.export.MemberInfoExportExcel;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.db.entity.MemberAccountHistory;
import com.jeequan.jeepay.db.entity.MemberInfo;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MemberAccountHistoryService;
import com.jeequan.jeepay.service.impl.MemberInfoService;
import com.jeequan.jeepay.service.impl.SysUserAuthService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 会员管理
*
* @author xiaoyu
*
* @date 2023/4/13 17:22
*/
@RestController
@RequestMapping("/api/member")
public class MemberController extends CommonCtrl {
@Autowired private MemberInfoService memberInfoService;
@Autowired private SysUserAuthService sysUserAuthService;
@Autowired private MemberAccountHistoryService accountHistoryService;
/**
* @author: xiaoyu
* @date: 2023/4/13 17:24
* @describe: 会员列表
*/
@PreAuthorize("hasAuthority('ENT_MEMBER_LIST')")
@GetMapping
public ApiRes list() {
MemberInfo memberInfo = getObject(MemberInfo.class);
LambdaQueryWrapper<MemberInfo> wrapper = MemberInfo.gw();
// 额外条件参数
JSONObject paramJSON = getReqParamJSON();
// 会员查询条件
memberInfoService.memberParams(memberInfo, wrapper);
wrapper.orderByDesc(MemberInfo::getCreatedAt);
// 二合一 会员名称/手机号
if (paramJSON != null && StringUtils.isNotEmpty(paramJSON.getString("unionQueryParam"))) {
wrapper.and(wr -> {
wr.like(MemberInfo::getMbrTel, paramJSON.getString("unionQueryParam"))
.or().like(MemberInfo::getMbrName, paramJSON.getString("unionQueryParam"));
});
}
IPage<MemberInfo> page = memberInfoService.page(getIPage(), wrapper);
// 手机号脱敏
page.getRecords().stream().forEach(i -> i.setMbrTel(DesensitizedUtil.mobilePhone(i.getMbrTel())));
return ApiRes.page(page);
}
/**
* @author: xiaoyu
* @date: 2023/4/13 17:36
* @describe: 新增会员
*/
@PreAuthorize("hasAuthority('ENT_MEMBER_ADD')")
@MethodLog(remark = "新增会员")
@PostMapping
public ApiRes add() {
MemberInfo memberInfo = getObject(MemberInfo.class);
memberInfo.setMbrId("B" + DateUtil.currentSeconds());
memberInfo.setMchNo(memberInfo.getMchNo());
memberInfo.setBalance(0L);
memberInfo.setSafeKey(JeepayKit.genAccountSafeKey(memberInfo.getMbrId(), 0L));
memberInfo.setAvatarUrl(getMemberAvatarDefault());
if (StringUtils.isEmpty(memberInfo.getMbrTel())) {
throw new BizException("会员手机号不可为空");
}
// 查询当前会员是否已存在
MemberInfo dbMemberInfo = memberInfoService.selectOne(memberInfo.getMchNo(), null, memberInfo.getMbrTel(), null, null);
if (dbMemberInfo != null) {
throw new BizException(memberInfo.getMbrTel() + "当前会员已存在");
}
boolean result = memberInfoService.save(memberInfo);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2023/4/13 17:49
* @describe: 会员信息
*/
@PreAuthorize("hasAnyAuthority('ENT_MEMBER_VIEW', 'ENT_MEMBER_EDIT')")
@GetMapping("/{mbrId}")
public ApiRes detail(@PathVariable("mbrId") String mbrId) {
MemberInfo memberInfo = memberInfoService.getById(mbrId);
return ApiRes.ok(memberInfo);
}
/**
* @author: xiaoyu
* @date: 2023/4/13 17:51
* @describe: 更新会员信息
*/
@PreAuthorize("hasAuthority('ENT_MCH_APP_EDIT')")
@MethodLog(remark = "更新会员信息")
@PutMapping("/{mbrId}")
public ApiRes update(@PathVariable("mbrId") String mbrId) {
MemberInfo memberInfo = getObject(MemberInfo.class);
memberInfo.setMbrId(mbrId);
memberInfo.setMchNo(null);
memberInfo.setBalance(null);
memberInfo.setSafeKey(null);
memberInfo.setMbrTel(null);
// 校验当前会员信息
MemberInfo dbMemberInfo = memberInfoService.getById(mbrId);
if (dbMemberInfo == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
// 更新信息
boolean result = memberInfoService.updateById(memberInfo);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2023/4/14 14:30
* @describe: 会员调账
*/
@PreAuthorize("hasAuthority('ENT_MEMBER_MANUAL')")
@MethodLog(remark = "会员调账")
@PostMapping("/manual/{mbrId}")
public ApiRes manual(@PathVariable("mbrId") String mbrId) {
// 变动金额
Long changeAmount = getRequiredAmountL("changeAmount");
// 登录密码
String currentPassword = Base64.decodeStr(getValStringRequired("currentPassword"));
// 校验当前会员信息
MemberInfo dbMemberInfo = memberInfoService.getById(mbrId);
if (dbMemberInfo == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
//验证当前密码是否正确
if(!sysUserAuthService.validateCurrentUserPwd(currentPassword)){
throw new BizException("密码验证失败!");
}
// 会员调账
accountHistoryService.updateMbrAccountAndInsertHistory(dbMemberInfo.getMchNo(), null, null, dbMemberInfo.getMbrId(), changeAmount,
MemberAccountHistory.BIZ_MANUAL, null, null);
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2023/4/17 17:25
* @describe: 会员列表数据导出
*/
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() {
try {
MemberInfo memberInfo = getObject(MemberInfo.class);
LambdaQueryWrapper<MemberInfo> wrapper = MemberInfo.gw();
// 会员查询条件
memberInfoService.memberParams(memberInfo, wrapper);
wrapper.orderByDesc(MemberInfo::getCreatedAt);
IPage<MemberInfo> memberList = memberInfoService.page(getIPage(true), wrapper);
List<JSONObject> newList = new LinkedList<>();
for (MemberInfo info: memberList.getRecords()) {
JSONObject object = (JSONObject) JSONObject.toJSON(info);
object.put("balance", AmountUtil.convertCent2Dollar(info.getBalance()));
newList.add(object);
}
List<MemberInfoExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), MemberInfoExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "会员信息", "会员信息", MemberInfoExportExcel.class, "会员信息", response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出订单失败!");
}
}
/**
* @author: xiaoyu
* @date: 2023/4/18 9:32
* @describe: 会员统计
*/
@RequestMapping(value="/count", method = RequestMethod.GET)
public ApiRes count() {
MemberInfo memberInfo = getObject(MemberInfo.class);
// 状态不作为参数传入
memberInfo.setState(null);
LambdaQueryWrapper<MemberInfo> wrapper = MemberInfo.gw();
// 查询参数
memberInfoService.memberParams(memberInfo, wrapper);
Map count = memberInfoService.count(wrapper);
return ApiRes.ok(count);
}
}

View File

@@ -0,0 +1,108 @@
package com.jeequan.jeepay.mgr.ctrl.member;
import cn.hutool.core.util.DesensitizedUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MemberRechargeRecord;
import com.jeequan.jeepay.db.entity.PayWay;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MemberRechargeRecordService;
import com.jeequan.jeepay.service.impl.PayWayService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 会员充值记录
*
* @author xiaoyu
*
* @date 2023/4/13 17:22
*/
@RestController
@RequestMapping("/api/member/rechargeRecord")
public class MemberRechargeRecordController extends CommonCtrl {
@Autowired private MemberRechargeRecordService rechargeRecordService;
@Autowired private PayWayService payWayService;
/**
* @author: xiaoyu
* @date: 2023/4/13 17:24
* @describe: 会员充值记录列表
*/
@PreAuthorize("hasAuthority('ENT_MEMBER_RECHARGE_RECORD_LIST')")
@GetMapping
public ApiRes list() {
MemberRechargeRecord rechargeRecord = getObject(MemberRechargeRecord.class);
LambdaQueryWrapper<MemberRechargeRecord> wrapper = MemberRechargeRecord.gw();
// 查询参数
rechargeRecordService.selectParams(rechargeRecord, wrapper);
wrapper.orderByDesc(MemberRechargeRecord::getCreatedAt);
IPage<MemberRechargeRecord> page = rechargeRecordService.page(getIPage(), wrapper);
// 得到所有支付方式
Map<String, String> payWayNameMap = new HashMap<>();
List<PayWay> payWayList = payWayService.list();
// 手机号脱敏、支付方式名称赋值
page.getRecords().stream().forEach(i -> {
i.setMbrTel(DesensitizedUtil.mobilePhone(i.getMbrTel()));
if (!CollectionUtils.isEmpty(payWayList)) {
for (PayWay payWay:payWayList) {
payWayNameMap.put(payWay.getWayCode(), payWay.getWayName());
}
// 存入支付方式名称
if (StringUtils.isNotEmpty(payWayNameMap.get(i.getWayCode()))) {
i.addExt("wayName", payWayNameMap.get(i.getWayCode()));
}else {
i.addExt("wayName", i.getWayCode());
}
}
});
return ApiRes.page(page);
}
/**
* @author: xiaoyu
* @date: 2023/4/13 17:49
* @describe: 会员充值记录详情
*/
@PreAuthorize("hasAuthority('ENT_MEMBER_RECHARGE_RECORD_VIEW')")
@GetMapping("/{recordId}")
public ApiRes detail(@PathVariable("recordId") String recordId) {
MemberRechargeRecord record = rechargeRecordService.getById(recordId);
return ApiRes.ok(record);
}
/**
* @author: xiaoyu
* @date: 2023/4/18 9:32
* @describe: 充值记录统计
*/
@RequestMapping(value="/count", method = RequestMethod.GET)
public ApiRes count() {
MemberRechargeRecord rechargeRecord = getObject(MemberRechargeRecord.class);
LambdaQueryWrapper<MemberRechargeRecord> wrapper = MemberRechargeRecord.gw();
// 查询参数
rechargeRecordService.selectParams(rechargeRecord, wrapper);
Map count = rechargeRecordService.count(wrapper);
return ApiRes.ok(count);
}
}

View File

@@ -0,0 +1,168 @@
package com.jeequan.jeepay.mgr.ctrl.member;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MemberRechargeRule;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MemberRechargeRuleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
/**
* 会员充值规则管理
*
* @author xiaoyu
*
* @date 2023/4/13 17:22
*/
@RestController
@RequestMapping("/api/member/rechargeRule")
public class MemberRechargeRuleController extends CommonCtrl {
@Autowired private MemberRechargeRuleService memberRechargeRuleService;
/**
* @author: xiaoyu
* @date: 2023/4/13 17:24
* @describe: 会员充值规则列表
*/
@PreAuthorize("hasAuthority('ENT_MEMBER_RECHARGE_LIST')")
@GetMapping
public ApiRes list() {
MemberRechargeRule rechargeRule = getObject(MemberRechargeRule.class);
LambdaQueryWrapper<MemberRechargeRule> wrapper = MemberRechargeRule.gw();
// 商户号
wrapper.eq(StringUtils.isNotEmpty(rechargeRule.getMchNo()), MemberRechargeRule::getMchNo, rechargeRule.getMchNo());
// 充值ID
wrapper.eq(rechargeRule.getRuleId() != null, MemberRechargeRule::getRuleId, rechargeRule.getRuleId());
// 充值金额
wrapper.eq(rechargeRule.getRechargeAmount() != null, MemberRechargeRule::getRechargeAmount, rechargeRule.getRechargeAmount());
// 会员状态
wrapper.eq(rechargeRule.getState() != null, MemberRechargeRule::getState, rechargeRule.getState());
//门店id和名称
if (StringUtils.isNotEmpty(rechargeRule.getStoreId())){
wrapper.and(i->i.eq(MemberRechargeRule::getStoreId,rechargeRule.getStoreId())
.or().eq(MemberRechargeRule::getStoreName,rechargeRule.getStoreId()));
}
// 时间范围条件
Date[] dateRange = rechargeRule.buildQueryDateRange();
if (dateRange[0] != null) {
wrapper.ge(MemberRechargeRule::getCreatedAt, dateRange[0]);
}
if (dateRange[1] != null) {
wrapper.le(MemberRechargeRule::getCreatedAt, dateRange[1]);
}
wrapper.orderByAsc(MemberRechargeRule::getSort);
wrapper.orderByDesc(MemberRechargeRule::getCreatedAt);
IPage page = memberRechargeRuleService.page(getIPage(), wrapper);
return ApiRes.page(page);
}
/**
* @author: xiaoyu
* @date: 2023/4/13 19:09
* @describe: 新增会员充值规则
*/
@PreAuthorize("hasAuthority('ENT_MEMBER_RECHARGE_ADD')")
@MethodLog(remark = "新增会员充值规则")
@PostMapping
public ApiRes add() {
// 充值金额
Long rechargeAmount = getRequiredAmountL("rechargeAmount");
// 赠送金额
Long giveAmount = getAmountL("giveAmount");
// 商户号
String mchNo = getValStringRequired("mchNo");
MemberRechargeRule rechargeRule = getObject(MemberRechargeRule.class);
// 商户号
rechargeRule.setMchNo(mchNo);
// 充值金额
rechargeRule.setRechargeAmount(rechargeAmount);
// 赠送金额
rechargeRule.setGiveAmount(giveAmount);
//将规则同步到门店
if (rechargeRule.getIsAllStore() != null){
memberRechargeRuleService.saveDB(rechargeRule);
}
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2023/4/13 17:49
* @describe: 会员充值规则信息
*/
@PreAuthorize("hasAnyAuthority('ENT_MEMBER_RECHARGE_VIEW', 'ENT_MEMBER_RECHARGE_EDIT')")
@GetMapping("/{ruleId}")
public ApiRes detail(@PathVariable("ruleId") String ruleId) {
MemberRechargeRule rechargeRule = memberRechargeRuleService.getById(ruleId);
return ApiRes.ok(rechargeRule);
}
/**
* @author: xiaoyu
* @date: 2023/4/13 17:51
* @describe: 更新会员充值规则
*/
@PreAuthorize("hasAuthority('ENT_MEMBER_RECHARGE_EDIT')")
@MethodLog(remark = "更新会员充值规则")
@PutMapping("/{ruleId}")
public ApiRes update(@PathVariable("ruleId") String ruleId) {
// 校验当前会员信息
MemberRechargeRule dbRechargeRule = memberRechargeRuleService.getById(ruleId);
if (dbRechargeRule == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
// 充值金额
Long rechargeAmount = getRequiredAmountL("rechargeAmount");
// 赠送金额
Long giveAmount = getAmountL("giveAmount");
MemberRechargeRule rechargeRule = getObject(MemberRechargeRule.class);
rechargeRule.setMchNo(null);
// 充值金额
rechargeRule.setRechargeAmount(rechargeAmount);
// 赠送金额
rechargeRule.setGiveAmount(giveAmount);
// 更新信息
boolean result = memberRechargeRuleService.updateById(rechargeRule);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2023/4/13 17:58
* @describe: 删除会员充值规则
*/
@PreAuthorize("hasAuthority('ENT_MEMBER_RECHARGE_DELETE')")
@MethodLog(remark = "删除会员充值规则")
@DeleteMapping("/{ruleId}")
public ApiRes delete(@PathVariable("ruleId") String ruleId) {
MemberRechargeRule rechargeRule = memberRechargeRuleService.getById(ruleId);
if (rechargeRule == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
memberRechargeRuleService.removeById(ruleId);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,34 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBDefaultConfig;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 系统默认配置
*
* @author xiaoyu
*
* @date 2023/4/11 9:38
*/
@RestController
@RequestMapping("/api/defaultConfig")
public class DefaultConfigController extends CommonCtrl {
/** 平台默认配置查询 **/
@GetMapping("")
public ApiRes getDefaultConfig() {
JSONObject result = new JSONObject();
// 进件图片大小默认配置
DBDefaultConfig defaultConfig = sysConfigService.getDBDefaultConfig();
result.put("applymentImgUploadSize", defaultConfig.getApplymentImgUploadSize());
return ApiRes.ok(result);
}
}

View File

@@ -0,0 +1,38 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.OCRImgParams;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.ImgInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 图片信息OCR
*
* @author xiaoyu
*
* @date 2022/1/12 15:15
*/
@RestController
@RequestMapping("/api/imgInfo")
public class ImgInfoOCRController extends CommonCtrl {
@Autowired private ImgInfoService imgInfoService;
/** 图片信息 **/
@PreAuthorize("hasAuthority('ENT_MCH_IMG_OCR_DETAIL')")
@PostMapping("/detail")
public ApiRes detail() {
String imgUrl = getValStringRequired("imgUrl");
String type = getValStringRequired("type");
// 调用ocr接口
OCRImgParams imgParams = imgInfoService.getImgInfo(imgUrl, type);
return ApiRes.ok(imgParams);
}
}

View File

@@ -0,0 +1,54 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.thirdparty.channel.kqpay.KqpayMchApplymentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping("/api/mchApplyments")
public class KqpayMchApplymentController extends CommonCtrl {
@Autowired
private MchApplymentService mchApplymentService;
@Autowired
private KqpayMchApplymentService kqpayMchApplymentService;
@Autowired
private MchInfoConverter mchInfoConverter;
@PostMapping("/kqSignApply/{recordId}")
public ApiRes signApply(@PathVariable("recordId") String recordId) {
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
com.jeequan.jeepay.core.entity.MchApplyment mchApplyment = kqpayMchApplymentService.signApply(mchInfoConverter.toModel(dbRecord));
MchApplyment applymentResult = new MchApplyment();
BeanUtils.copyProperties(mchApplyment, applymentResult);
// 当状态发生了变化时
if (!dbRecord.getState().equals(applymentResult.getState())) {
// 更新数据
applymentResult.setApplyId(recordId);
applymentResult.setLastApplyAt(new Date());
mchApplymentService.updateById(applymentResult);
}
return ApiRes.ok(applymentResult);
}
}

View File

@@ -0,0 +1,38 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/api/mchApplyments")
public class LklspayMchApplymentController {
/** 拉卡拉获取银行信息列表 **/
@GetMapping("/getLklBankList/{areaCode}/{branchName}")
public ApiRes getLklBankList(@PathVariable("areaCode") String areaCode, @PathVariable("branchName") String branchName) {
HttpResponse httpResponse = null;
try {
String result = null;
if (StringUtils.isNotEmpty(areaCode)) {
httpResponse = HttpRequest.get("https://tkapi.lakala.com/registration/bank?areaCode=" + areaCode + "&bankName=" + branchName).execute();
result = httpResponse.body();
}
return ApiRes.ok(result);
} catch (Exception e) {
throw new BizException(e.getMessage());
} finally {
if (httpResponse != null) {
httpResponse.close();
}
}
}
}

View File

@@ -0,0 +1,26 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchAppApplyment;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchAppApplymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController("/mch/app/applyment")
public class MchAppApplymentController extends CommonCtrl {
@Autowired private MchAppApplymentService mchAppApplymentService;
@PreAuthorize("hasAuthority('ENT_MCH_APP_APPLYMENT_LIST')")
@GetMapping
public ApiRes list() {
MchAppApplyment entity = getObject(MchAppApplyment.class);
IPage iPage = getIPage(true);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,327 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchApp;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.Capability;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mgr.config.SystemYmlConfig;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* 商户应用管理类
*/
@RestController
@RequestMapping("/api/mchApps")
public class MchAppController extends CommonCtrl {
@Autowired
private MchAppService mchAppService;
@Autowired
private SystemYmlConfig systemYmlConfig;
@Autowired
private ProductAppService productAppService;
@Autowired
private ProductAppConnService productAppConnService;
@Autowired
private ProductInfoService productInfoService;
@Autowired
private MachAppUpdateEXTVService machAppUpdateEXTVService;
@Autowired
private MchInfoConverter mchInfoConverter;
@Autowired
private IsvUserConnService isvUserConnService;
/**
* @Author: ZhuXiao
* @Description: 应用列表
* @Date: 9:59 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_APP_LIST')")
@GetMapping
public ApiRes list() {
MchAppEntity mchAppEntity = getObject(MchAppEntity.class);
IPage<MchAppEntity> pages = mchAppService.selectPage(getIPage(true), mchAppEntity);
return ApiRes.ok(pages);
}
/**
* @Author: ZhuXiao
* @Description: 新建应用
* @Date: 10:05 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_APP_ADD')")
@MethodLog(remark = "新建应用")
@PostMapping
public ApiRes add() {
MchApp mchApp = getObject(MchApp.class);
mchApp.setAppId(SeqKit.getMchAppId());
MchInfo mchInfo = mchInfoService.getById(mchApp.getMchNo());
if (mchInfo == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
mchApp.setAgentNo(mchInfo.getAgentNo());
mchApp.setTopAgentNo(mchInfo.getTopAgentNo());
//默认设置为审核中
mchApp.setState(MchAppEntity.AUDIT);
// 如果当前为默认
if (mchApp.getDefaultFlag() == CS.YES) {
mchAppService.update(new LambdaUpdateWrapper<MchAppEntity>()
.set(MchAppEntity::getDefaultFlag, CS.NO)
.eq(MchAppEntity::getMchNo, mchApp.getMchNo())
);
}
// 根据功能code获取功能的信息
List<Capability> openFuncList = new ArrayList<>();
if (!CollUtil.isEmpty(mchApp.getCapabilityCodeList())){
for (String code : mchApp.getCapabilityCodeList()) {
Capability capability = Capability.MAP.get(code);
Assert.notNull(capability, "非法的功能代码");
openFuncList.add(capability);
}
}
mchApp.setPreCapabilities(openFuncList);
boolean result = mchAppService.save(mchInfoConverter.toDbEntity(mchApp));
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
return ApiRes.ok();
}
/**
* @Author: ZhuXiao
* @Description: 应用详情
* @Date: 10:13 2021/6/16
*/
@PreAuthorize("hasAnyAuthority('ENT_MCH_APP_VIEW', 'ENT_MCH_APP_EDIT')")
@GetMapping("/{appId}")
public ApiRes detail(@PathVariable("appId") String appId) {
MchAppEntity mchAppEntity = mchAppService.selectById(appId);
if (mchAppEntity == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(mchAppEntity);
}
/**
* @Author: ZhuXiao
* @Description: 更新应用信息
* @Date: 10:11 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_APP_EDIT')")
@MethodLog(remark = "更新应用信息")
@PutMapping("/{appId}")
public ApiRes update(@PathVariable("appId") String appId) {
MchApp mchApp = getObject(MchApp.class);
mchApp.setAppId(appId);
MchAppEntity dbMchAppEntity = mchAppService.getById(appId);
if (!dbMchAppEntity.getDefaultFlag().equals(mchApp.getDefaultFlag())) {
// 如果修改当前为默认
if (mchApp.getDefaultFlag() == CS.YES) {
mchAppService.update(new LambdaUpdateWrapper<MchAppEntity>()
.set(MchAppEntity::getDefaultFlag, CS.NO)
.eq(MchAppEntity::getMchNo, dbMchAppEntity.getMchNo())
);
} else {
throw new BizException("应用不可修改为非默认!");
}
}
// 根据功能code获取功能的信息
List<Capability> openFuncList = new ArrayList<>();
if (!CollUtil.isEmpty(mchApp.getCapabilityCodeList())){
for (String code : mchApp.getCapabilityCodeList()) {
Capability capability = Capability.MAP.get(code);
Assert.notNull(capability, "非法的功能代码");
openFuncList.add(capability);
}
}
mchApp.setPreCapabilities(openFuncList);
boolean result = mchAppService.updateById(mchInfoConverter.toDbEntity(mchApp));
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @Author: ZhuXiao
* @Description: 删除应用
* @Date: 10:14 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_APP_DEL')")
@MethodLog(remark = "删除应用")
@DeleteMapping("/{appId}")
public ApiRes delete(@PathVariable("appId") String appId) {
MchAppEntity mchAppEntity = mchAppService.getById(appId);
mchAppService.removeByAppId(appId);
return ApiRes.ok();
}
/**
* 功能描述: 查询系统公钥
*/
@PreAuthorize("hasAnyAuthority('ENT_MCH_APP_ADD', 'ENT_MCH_APP_EDIT')")
@GetMapping("/sysRSA2PublicKey")
public ApiRes sysRSA2PublicKey() {
return ApiRes.ok(systemYmlConfig.getSysRSA2PublicKey());
}
@GetMapping("/getNewProductList")
@MethodLog(remark = "新获取产品列表")
public ApiRes getNewProductList() {
String appId = getValString("appId");
if (StringUtils.isBlank(appId)) {
return ApiRes.customFail("appId不能为空!");
}
//获取已审核通过和正在审核的产品列表包括产品和商户的绑定关系
//1.获取t_product_app表中已经通过审核和待审核的数据并拿到product_id
LambdaQueryWrapper<PackageOrder> appWrapper = new LambdaQueryWrapper<>();
appWrapper.in(PackageOrder::getState, 1, 3);
List<PackageOrder> appList = productAppService.list(appWrapper);
List<String> productIdCollect = appList.stream()
.map(PackageOrder::getProductId)
.collect(Collectors.toList());
//2通过product_id获取到具体的产品信息
LambdaQueryWrapper<ProductInfo> infoWrapper = new LambdaQueryWrapper<>();
infoWrapper.in(ProductInfo::getProductId, productIdCollect);
List<ProductInfo> infoList = productInfoService.list(infoWrapper);
//3.获取关联关系
// 获取当前商户信息
String mchNo = getCurrentUser().getSysUser().getBelongInfoId();
//合并信息通过审核和待审核的产品和当前appid绑定的数据有则返回1没有则为0
for (ProductInfo itemProductInfo : infoList) {
String productId = itemProductInfo.getProductId();
LambdaQueryWrapper<ProductAppConn> appConnWrapper = new LambdaQueryWrapper<>();
appConnWrapper.eq(ProductAppConn::getProductId, productId)
.eq(ProductAppConn::getAppId, appId)
.eq(ProductAppConn::getState, 1)
.eq(ProductAppConn::getMchNo, mchNo);
//传入审核状态
List<PackageOrder> appStateList = appList.stream().filter(u -> productId.equals(u.getProductId())).collect(Collectors.toList());
if (!appStateList.isEmpty()) {
int checkState = appStateList.get(0).getState();
itemProductInfo.setCheckState(checkState);
}
//添加绑定状态
List<ProductAppConn> appConnList = productAppConnService.list(appConnWrapper);
if (!appConnList.isEmpty()) {
itemProductInfo.setState(1);
} else {
itemProductInfo.setState(0);
}
}
Page page = new Page();
page.setRecords(infoList);
page.setTotal(infoList.size());
page.setCurrent(1);
return ApiRes.ok(page);
}
@PostMapping("/relevancyProduct")
@MethodLog(remark = "关联/解除关联产品")
public ApiRes relevancyProduct() {
ProductAppConn productAppConn = getReqParamJSON().toJavaObject(ProductAppConn.class);
if (!Optional.ofNullable(productAppConn.getAppId()).isPresent()) {
return ApiRes.customFail("传入数据不能为空!");
}
// 获取当前商户信息
String mchNo = getCurrentUser().getSysUser().getBelongInfoId();
//根据传入信息查看库中是否有数据
LambdaQueryWrapper<ProductAppConn> appConnWrapper = new LambdaQueryWrapper<>();
appConnWrapper.eq(ProductAppConn::getProductId, productAppConn.getProductId())
.eq(ProductAppConn::getAppId, productAppConn.getAppId())
.eq(ProductAppConn::getMchNo, mchNo);
List<ProductAppConn> appConnList = productAppConnService.list(appConnWrapper);
//如果没有则进行新增关联关系
if (appConnList.isEmpty()) {
ProductAppConn appConnOne = new ProductAppConn();
appConnOne.setProductId(productAppConn.getProductId());
appConnOne.setAppId(productAppConn.getAppId());
appConnOne.setState(productAppConn.getState());
appConnOne.setMchNo(mchNo);
productAppConnService.save(appConnOne);
//关联时将产品关联的固定功能信息`funcCode`存储到应用信息`extx`中
machAppUpdateEXTVService.machAppUpdateEXTV(productAppConn, 1);
return ApiRes.ok("关联成功!");
} else {
//如果库中有数据则进行修改 关联状态修改
ProductAppConn appConnOne = productAppConnService.getOne(appConnWrapper);
appConnOne.setState(productAppConn.getState());
productAppConnService.updateById(appConnOne);
if (Objects.equals(productAppConn.getState(), 1)) {
//关联时将产品关联的固定功能信息`funcCode`存储到应用信息`extx`中
machAppUpdateEXTVService.machAppUpdateEXTV(productAppConn, 1);
return ApiRes.ok("关联成功!");
} else {
machAppUpdateEXTVService.machAppUpdateEXTV(productAppConn, 0);
return ApiRes.ok("解除关联成功!");
}
}
}
@MethodLog(remark = "一键关联")
@PostMapping("/relevance")
public ApiRes oneKeyXRelevance() {
MchAppEntity mchAppEntity = getObject(MchAppEntity.class);
return ApiRes.ok(mchAppService.correlation(mchAppEntity.getAppId()));
}
@MethodLog(remark = "配置应用的能力")
@PostMapping("/configAppCapability")
public ApiRes configAppCapability() {
JSONObject reqParamJSON = getReqParamJSON();
List<String> funcCodes = reqParamJSON.getJSONArray("funcCodes").toJavaList(String.class);
String mchAppId = reqParamJSON.getString("mchAppId");
return ApiRes.ok(mchAppService.configAppCapability(mchAppId, funcCodes));
}
@GetMapping("/allCapability")
public ApiRes getAllCapability() {
return ApiRes.ok(Capability.MAP.values());
}
@PreAuthorize("hasAnyAuthority('ENT_MCH_APP_AUDIT')")
@PostMapping("/audit")
public ApiRes audit() {
MchAppEntity mchApp = getObject(MchAppEntity.class);
mchAppService.audit(mchApp);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,235 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.paychannel.ISqbApiService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBApplicationConfig;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.MchAppEntity;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.db.entity.MchConfig;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.MchConfigService;
import com.jeequan.jeepay.service.impl.MchInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 商户配置管理类
*
* @author zx
*
* @date 2021-06-16 09:15
*/
@RestController
@RequestMapping("/api/mchConfig")
public class MchConfigController extends CommonCtrl {
@Autowired private MchConfigService mchConfigService;
@Autowired private MchInfoService mchInfoService;
@Autowired private MchAppService mchAppService;
/**
* @Author: zx
* @Description: 查询商户配置
* @Date: 9:59 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_CONFIG_PAGE')")
@GetMapping
public ApiRes list() {
String groupKey = getValString("groupKey");
String mchNo = getValStringRequired("mchNo");
String mchAppId = getValString("mchAppId");
String mchApplyId = getValString("mchApplyId");
LambdaQueryWrapper<MchConfig> queryWrapper = MchConfig.gw()
.eq(MchConfig::getMchNo, mchNo)
.eq(!ObjUtil.isEmpty(mchAppId), MchConfig::getMchAppId, mchAppId)
.eq(!ObjUtil.isEmpty(mchApplyId), MchConfig::getMchApplyId, mchApplyId);
if (StringUtils.isNotBlank(groupKey)) {
queryWrapper.eq(MchConfig::getGroupKey, groupKey);
}
List<MchConfig> list = mchConfigService.list(queryWrapper);
return ApiRes.ok(list);
}
/**
* @Author: zx
* @Description: 根据configKey查询商户配置
* @Date: 9:59 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_CONFIG_PAGE')")
@GetMapping("/{configKey}")
public ApiRes get(@PathVariable("configKey") String configKey) {
MchConfig mchConfig = mchConfigService.getOne(MchConfig.gw().eq(MchConfig::getMchNo, getValStringRequired("mchNo")).eq(MchConfig::getConfigKey, configKey));
return ApiRes.ok(mchConfig);
}
/**
* @author: zx
* @Description: 批量更新商户配置信息
* @Date: 10:11 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_CONFIG_PAGE')")
@MethodLog(remark = "批量更新商户配置信息")
@PutMapping("/{groupKey}")
public ApiRes updateBatch(@PathVariable("groupKey") String groupKey) {
String params = getValStringRequired("configData");
List<MchConfig> mchConfigList = JSONArray.parseArray(params, MchConfig.class);
String mchNo = getValStringRequired("mchNo");
String mchAppId = getValString("mchAppId");
String mchApplyId = getValString("mchApplyId");
int update = mchConfigService.updateBatch(mchConfigList, mchNo, mchAppId, mchApplyId, groupKey);
if(update <= 0) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* 收钱吧 商户激活配置参数
* @return
*/
@PreAuthorize("hasAuthority('ENT_MCH_CONFIG_PAGE')")
@PostMapping("/activation")
public ApiRes activation() {
JSONObject paramJSON = getReqParamJSON();
String mchAppId = paramJSON.getString("mchAppId");
// 应用信息
MchAppEntity mchAppEntity = mchAppService.getById(mchAppId);
if (mchAppEntity == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
// 商户信息 [商户类型必须为特约商户]
MchInfo mchInfo = mchInfoService.getById(mchAppEntity.getMchNo());
if (mchInfo == null || mchInfo.getType() == CS.MCH_TYPE_NORMAL) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
paramJSON.put("mchNo", mchInfo.getMchNo());
ISqbApiService sqbpayApiService = SpringBeansUtil.getBean(CS.IF_CODE.SQBPAY + "ApiService", ISqbApiService.class);
JSONObject activationRes = sqbpayApiService.activation(paramJSON);
return ApiRes.ok(activationRes);
}
/** 收银台地址 **/
@PreAuthorize("hasAnyAuthority('ENT_MCH_CASHIER_URL')")
@PostMapping("/createCashier")
public ApiRes createCashier() {
//获取请求参数
String appId = getValString("appId");
String mchNo = getValString("mchNo");
String storeId = getValStringRequired("storeId");
// 当前没有传入应用,那么使用默认应用
if(StringUtils.isBlank(appId)){
appId = mchAppService.getDefaultApp(mchNo).getAppId();
}
MchAppEntity mchAppEntity = mchAppService.getById(appId);
if(mchAppEntity == null || mchAppEntity.getState() != CS.PUB_USABLE || !mchAppEntity.getAppId().equals(appId)){
throw new BizException("商户应用不存在或不可用");
}
DBApplicationConfig dbApplicationConfig = sysConfigService.getDBApplicationConfig();
try {
String payUrl = dbApplicationConfig.genCashierPayUrl(appId, storeId+"");
return ApiRes.ok(payUrl);
} catch (Exception e) {
throw new BizException(e.getMessage());
}
}
@PostMapping("/config")
public ApiRes setConfig() {
String applyId = getValStringRequired("applyId");
String configKey = getValStringRequired("configKey");
String configVal = getValStringRequired("configVal");
MchConfig config = mchConfigService.lambdaQuery()
.eq(MchConfig::getConfigKey, configKey)
.eq(MchConfig::getMchApplyId, applyId)
.one();
if (config == null) {
MchConfig.Option option = MchConfig.Option.getFirstByConfigKey(configKey);
Assert.notNull(option, "未知的配置项");
MchApplyment mchApplyment = mchApplymentService.getById(applyId);
MchConfig newData = new MchConfig();
newData.setMchNo(mchApplyment.getMchNo())
.setConfigKey(configKey)
.setMchAppId(mchApplyment.getAutoConfigMchAppId())
.setMchApplyId(mchApplyment.getApplyId())
.setConfigName(option.getConfigName())
.setGroupKey(option.getGroupKey())
.setType(option.getType())
.setConfigVal(configVal);
mchConfigService.save(newData);
} else {
LambdaUpdateWrapper<MchConfig> uWrapper = Wrappers.lambdaUpdate();
uWrapper.eq(MchConfig::getConfigKey, configKey)
.eq(MchConfig::getMchApplyId, applyId)
.set(MchConfig::getConfigVal, configVal);
mchConfigService.update(uWrapper);
}
return ApiRes.ok();
}
// public static void main(String[] args) throws UnsupportedEncodingException {
//// String s = HttpUtil.get(s1);M
////
//// System.out.println(s1);
//
//// RestTemplate restTemplate = new RestTemplate();
//// String forObject = restTemplate.getForObject("https://whois.pconline.com.cn/ipJson.jsp?ip=111.175.29.61&json=true", String.class);
//// System.out.println(forObject);
//
//// Map<String, Object> map = new HashMap<>();
//// map.put("ip", "111.175.29.61");
//// map.put("json", "true");
// String url = "https://whois.pconline.com.cn/ipJson.jsp";
//// System.out.println(url);
//
//
// HttpResponse execute = HttpUtil.createGet(url)
// .form("ip", "111.175.29.61")
// .form("json", "true")
// .header("User-Agent", "11111")
// .execute();
//
// String body = execute.body().replace("\n", "");
// JSONObject jsonObject = JSON.parseObject(body);
// System.out.println(body);
// }
}

View File

@@ -0,0 +1,110 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.JsonKit;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 设备厂商参数接口
*
* @author xiaoyu
*
* @date 2023/7/19 16:11
*/
@Slf4j
@RestController
@RequestMapping("/api/provider/device")
public class MchDeviceCommonController extends CommonCtrl {
/**
* @author: xiaoyu
* @date: 2023/7/19 16:13
* @describe: 获取智网厂商列表
*/
@GetMapping("/getZwCompanyList")
public ApiRes getZwCompanyList() {
JSONArray result = new JSONArray();
try {
String reqUrl = "https://open.smartlinkall.com/magicbox/GetCompanyList";
log.info("[智网]获取厂商信息列表,请求地址:{}", reqUrl);
String response = HttpUtil.createGet(reqUrl).execute().body();
log.info("[智网]获取厂商信息列表,响应结果:{}", response);
JSONObject respJson = JSONObject.parseObject(response);
JSONObject respData = respJson.getJSONObject("respData");
if (respData != null){
result = respData.getJSONArray("list");
}
}catch (BizException e) {
log.error("获取智网厂商列表异常" + e);
throw new BizException(e.getMessage());
}
return ApiRes.ok(result);
}
/**
* @author: xiaoyu
* @date: 2023/7/19 16:13
* @describe: 获取智网厂家软件列表
*/
@GetMapping("/getZwSoftCodeList/{code}")
public ApiRes getZwSoftCodeList(@PathVariable("code") String code) {
JSONArray result = new JSONArray();
try {
String reqUrl = "https://open.smartlinkall.com/magicbox/GetPosList";
JSONObject bodyParam = JsonKit.newJson("code", code);
log.info("[智网]获取软件信息列表,请求地址:{}, bodyParam{}", reqUrl, bodyParam);
String response = HttpUtil.createPost(reqUrl)
.header("Content-type", "application/json")
.body(bodyParam.toJSONString())
.execute().body();
log.info("[智网]获取软件信息列表,响应结果:{}", response);
JSONObject respJson = JSONObject.parseObject(response);
JSONObject respData = respJson.getJSONObject("respData");
if (respData != null){
result = respData.getJSONArray("list");
}
}catch (BizException e) {
log.error("获取智网软件列表异常" + e);
throw new BizException(e.getMessage());
}
return ApiRes.ok(result);
}
/**
* @author: xiaoyu
* @date: 2023/7/19 16:13
* @describe: 获取智网厂家软件列表
*/
@GetMapping("/getZwConfigInfo/{code}")
public ApiRes getZwConfigInfo(@PathVariable("code") String code) {
JSONObject result = new JSONObject();
try {
String reqUrl = "https://open.smartlinkall.com/magicbox/GetPosPara";
JSONObject bodyParam = JsonKit.newJson("code", code);
log.info("[智网]获取软件配置信息,请求地址:{}, bodyParam{}", reqUrl, bodyParam);
String response = HttpUtil.createPost(reqUrl)
.header("Content-type", "application/json")
.body(bodyParam.toJSONString())
.execute().body();
log.info("[智网]获取软件配置信息,响应结果:{}", response);
JSONObject respJson = JSONObject.parseObject(response);
result = respJson.getJSONObject("respData");
}catch (BizException e) {
log.error("获取智网软件配置异常" + e);
throw new BizException(e.getMessage());
}
return ApiRes.ok(result);
}
}

View File

@@ -0,0 +1,208 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import cn.hutool.core.codec.Base64;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.components.mq.model.CleanMchLoginAuthCacheMQ;
import com.jeequan.jeepay.components.mq.model.ResetIsvMchAppInfoConfigMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.smsconfig.SmsBizDiyContentModel;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchInfoService;
import com.jeequan.jeepay.service.impl.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 商户管理类
*
* @author pangxiaoyu
* @site https://www.jeequan.com
* @date 2021-06-07 07:15
*/
@RestController
@RequestMapping("/api/mchInfo")
public class MchInfoController extends CommonCtrl {
@Autowired private MchInfoService mchInfoService;
@Autowired private SysUserService sysUserService;
@Autowired private IMQSender mqSender;
@Autowired private SmsManager smsManager;
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 商户信息列表
*/
@PreAuthorize("hasAuthority('ENT_MCH_LIST')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
MchInfo mchInfo = getObject(MchInfo.class);
// 扩展员仅查询自己的数据
if (getCurrentUser().isEpUser()){
mchInfo.setCreatedUid(getCurrentUser().getSysUser().getSysUserId());
}
Page<MchInfo> listPage = mchInfoService.getListPage(getIPage(), mchInfo);
return ApiRes.page(listPage);
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 新增商户信息
*/
@PreAuthorize("hasAuthority('ENT_MCH_INFO_ADD')")
@MethodLog(remark = "新增商户")
@RequestMapping(value="", method = RequestMethod.POST)
public ApiRes add() {
MchInfo mchInfo = getObject(MchInfo.class);
// 获取传入的商户登录名、登录密码
String loginPassword = getValString("loginPassword");
Byte isNotify = getValByteRequired("isNotify");
if (StringUtils.isBlank(loginPassword)) {
loginPassword = null;
}
mchInfo.setMchNo(SeqKit.genMchNo());
// 当前登录用户信息
SysUser sysUser = getCurrentUser().getSysUser();
mchInfo.setCreatedUid(sysUser.getSysUserId());
mchInfo.setCreatedBy(sysUser.getRealname());
mchInfoService.addMch(mchInfo, loginPassword);
// 发送短信通知
if (isNotify == CS.YES) {
smsManager.sendDiyContentSms(SmsBizDiyContentModel.genUserOpenAccount(mchInfo.getContactTel(), mchInfo.getLoginUsername(), loginPassword));
}
return ApiRes.ok();
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 删除商户信息
*/
@PreAuthorize("hasAuthority('ENT_MCH_INFO_DEL')")
@MethodLog(remark = "删除商户")
@RequestMapping(value="/{mchNo}", method = RequestMethod.DELETE)
public ApiRes delete(@PathVariable("mchNo") String mchNo) {
List<Long> userIdList = mchInfoService.removeByMchNo(mchNo);
// 推送mq删除redis用户缓存
mqSender.send(CleanMchLoginAuthCacheMQ.build(userIdList));
return ApiRes.ok();
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 更新商户信息
*/
@PreAuthorize("hasAuthority('ENT_MCH_INFO_EDIT')")
@MethodLog(remark = "更新商户信息")
@RequestMapping(value="/{mchNo}", method = RequestMethod.PUT)
public ApiRes update(@PathVariable("mchNo") String mchNo) {
//获取查询条件
MchInfo mchInfo = getObject(MchInfo.class);
mchInfo.setMchNo(mchNo); //设置商户号主键
mchInfo.setType(null); //防止变更商户类型
// mchInfo.setIsvNo(null);
mchInfo.setLoginUsername(null); // 防止修改用户登录名
// 是否重置密码 & 确认新密码
boolean resetPass = getReqParamJSON().getBooleanValue("resetPass");
String confirmPwd = null;
if(resetPass){
confirmPwd = getReqParamJSON().getBoolean("defaultPass") ? null : Base64.decodeStr(getValStringRequired("confirmPwd"));
}
// 是否修改状态为停用,设置为由运营平台停用
if (mchInfo.getState() != null && mchInfo.getState() != MchInfo.STATE_YES) {
mchInfo.setState(MchInfo.STATE_NO_MGR);
}
// 更新商户 & 得到需要删除的商户用户ID的记录
Set<Long> removeCacheUserIdList = mchInfoService.updateMch(mchInfo, resetPass, confirmPwd);
// 推送mq删除redis用户认证信息
if (!removeCacheUserIdList.isEmpty()) {
mqSender.send(CleanMchLoginAuthCacheMQ.build(new ArrayList<>(removeCacheUserIdList)));
}
// 推送mq到目前节点进行更新数据
mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_MCH_INFO, null, mchNo, null));
return ApiRes.ok();
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 查询商户信息
*/
@PreAuthorize("hasAnyAuthority('ENT_MCH_INFO_VIEW', 'ENT_MCH_INFO_EDIT')")
@RequestMapping(value="/{mchNo}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("mchNo") String mchNo) {
MchInfo mchInfo = mchInfoService.getById(mchNo);
if (mchInfo == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
if (mchInfo.getState() == MchInfo.STATE_NO_MGR) {
mchInfo.setState(CS.NO);
}
return ApiRes.ok(mchInfo);
}
/**
* 获取默认渠道
*
* @param mchNo
* @return
*/
@PreAuthorize("hasAnyAuthority('ENT_MCH_INFO_VIEW')")
@GetMapping("/defIsv/{mchNo}")
public ApiRes getDefaultIsv(@PathVariable("mchNo") String mchNo) {
String ifCode = getValString("ifCode");
List<Map<String, String>> defIsv = mchInfoService.getDefIsv(mchNo, ifCode);
return ApiRes.ok(defIsv);
}
/**
* 设置默认渠道
*
* @param mchNo
* @return
*/
@PreAuthorize("hasAnyAuthority('ENT_MCH_INFO_VIEW', 'ENT_MCH_INFO_EDIT')")
@PostMapping("/defIsv/{mchNo}")
public ApiRes setDefaultIsv(@PathVariable("mchNo") String mchNo) {
String ifCode = getValStringRequired("ifCode");
String isvNo = getValStringRequired("isvNo");
mchInfoService.setDefIsv(mchNo, ifCode, isvNo);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,71 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchModifyApplymentEntity;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchModifyApplymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/**
* TODO
*
* @author crystal
* @date 2023/12/27 15:36
*/
@RestController
@RequestMapping("/api/mchModifyApplyment")
public class MchModifyApplymentController extends CommonCtrl {
@Autowired
private MchModifyApplymentService modifyApplymentService;
@Autowired
private MchApplymentService mchApplymentService;
@PreAuthorize("hasAuthority('ENT_MCH_MODIFY_LIST')")
@GetMapping
public ApiRes list() {
MchModifyApplymentEntity modifyApplyment = getObject(MchModifyApplymentEntity.class);
JSONObject paramJSON = getReqParamJSON();
Page<MchModifyApplymentEntity> pages = modifyApplymentService.pageList(getIPage(), modifyApplyment, paramJSON);
return ApiRes.page(pages);
}
@PreAuthorize("hasAuthority('ENT_MCH_MODIFY_AUDIT')")
@PostMapping(value = "/audit")
public ApiRes audit() {
String modifyApplymentId = getValStringRequired("modifyApplymentId");
Boolean auditFlag = getValRequired("state", Boolean.class);
String remark = getValString("remark");
modifyApplymentService.audit(modifyApplymentId, auditFlag, remark, false);
return ApiRes.ok();
}
@GetMapping("/result/{modifyApplyId}")
public ApiRes getResult(@PathVariable("modifyApplyId") String modifyApplyId) {
modifyApplymentService.getResult(modifyApplyId);
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_MCH_APPLYMENT_VIEW')")
@GetMapping("/{recordId}")
public ApiRes detail(@PathVariable("recordId") String recordId) {
Byte originData = getValByteDefault("originData", CS.NO);
MchModifyApplymentEntity record;
if (CS.NO == originData) {
record = modifyApplymentService.getInfoById(recordId);
} else {
record = modifyApplymentService.getById(recordId);
}
return ApiRes.ok(record);
}
}

View File

@@ -0,0 +1,144 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.IConfigContextQueryService;
import com.jeequan.jeepay.core.interfaces.paychannel.aliaqfbiz.IAliaqfApiService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBApplicationConfig;
import com.jeequan.jeepay.core.model.params.aliaqf.AliaqfIsvParams;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.MchAppEntity;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.PayInterfaceConfig;
import com.jeequan.jeepay.db.entity.PayInterfaceDefine;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
/**
* 商户支付接口管理类
*
* @author zhuxiao
*
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("/api/mch/payConfigs")
public class MchPayInterfaceConfigController extends CommonCtrl {
@Autowired private PayInterfaceConfigService payInterfaceConfigService;
@Autowired private PayInterfaceDefineService payInterfaceDefineService;
@Autowired private MchAppService mchAppService;
@Autowired private MchInfoService mchInfoService;
@Autowired private SysConfigService sysConfigService;
@Autowired private IConfigContextQueryService configContextQueryService;
/** 查询支付宝商户授权URL **/
@GetMapping("/alipayIsvsubMchAuthUrls/{mchAppId}/{isvNo}")
public ApiRes queryAlipayIsvsubMchAuthUrl(@PathVariable("mchAppId") String mchAppId, @PathVariable("isvNo") String isvNo) {
MchAppEntity mchAppEntity = mchAppService.getById(mchAppId);
DBApplicationConfig dbApplicationConfig = sysConfigService.getDBApplicationConfig();
String authUrl = dbApplicationConfig.genAlipayIsvsubMchAuthUrl(isvNo, mchAppId);
String authQrImgUrl = dbApplicationConfig.genScanImgUrl(authUrl);
JSONObject result = new JSONObject();
result.put("authUrl", authUrl);
result.put("authQrImgUrl", authQrImgUrl);
return ApiRes.ok(result);
}
/** 查询当前应用支持的支付接口
* 使用功能: 新增分账用户
* */
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECEIVER_ADD' )")
@RequestMapping(value="ifCodes/{appId}", method = RequestMethod.GET)
public ApiRes getIfCodeByAppId(@PathVariable("appId") String appId) {
if(mchAppService.lambdaQuery().eq(MchAppEntity::getAppId, appId).count() <= 0){
throw new BizException("商户应用不存在");
}
Set<String> result = new HashSet<>();
payInterfaceConfigService.list(PayInterfaceConfig.gw().select(PayInterfaceConfig::getIfCode)
.eq(PayInterfaceConfig::getState, CS.PUB_USABLE)
.eq(PayInterfaceConfig::getInfoId, appId)
.eq(PayInterfaceConfig::getInfoType, CS.SYS_ROLE_TYPE.MCH_APP)
).stream().forEach(r -> result.add(r.getIfCode()));
if(result.isEmpty()){
return ApiRes.ok(new ArrayList<>());
}
return ApiRes.ok(payInterfaceDefineService.list(PayInterfaceDefine.gw()
.select(PayInterfaceDefine::getIfCode, PayInterfaceDefine::getIfName, PayInterfaceDefine::getIcon, PayInterfaceDefine::getBgColor)
.in(PayInterfaceDefine::getIfCode, result))
);
}
/** 支付宝安全发签约页面 **/
@GetMapping("/alipayAgreementPageSign/{mchAppId}/{isvNo}")
public ApiRes alipayAgreementPageSign(@PathVariable("mchAppId") String mchAppId
, @PathVariable("isvNo") String isvNo) {
MchAppEntity mchAppEntity = mchAppService.getById(mchAppId);
AliaqfIsvParams aliaqfIsvParams = applyCheck(mchAppEntity.getMchNo(), isvNo);
IAliaqfApiService ALIAQFApiService = SpringBeansUtil.getBean(CS.IF_CODE.ALIAQF + "ApiService", IAliaqfApiService.class);
// 1.获取签约页面
String jumpUrl = ALIAQFApiService.userAgreementPageSign(aliaqfIsvParams, mchAppId);
return ApiRes.ok(jumpUrl);
}
/** 查询支付宝安全发签约结果 **/
@GetMapping("/queryUserAgreementPageSign/{mchAppId}/{isvNo}")
public ApiRes queryUserAgreementPageSign(@PathVariable("mchAppId") String mchAppId
, @PathVariable("isvNo") String isvNo) {
MchAppEntity mchAppEntity = mchAppService.getById(mchAppId);
AliaqfIsvParams ALIAQFIsvParams = applyCheck(mchAppEntity.getMchNo(), isvNo);
IAliaqfApiService aliaqfApiService = SpringBeansUtil.getBean(CS.IF_CODE.ALIAQF + "ApiService", IAliaqfApiService.class);
// 1.查询签约结果
String agreementNo = aliaqfApiService.queryUserAgreementPageSign(ALIAQFIsvParams, mchAppId);
String accountBookId = "";
if (StringUtils.isNotEmpty(agreementNo)) {
// 2.资金记账本开通
accountBookId = aliaqfApiService.fundAccountbookCreate(ALIAQFIsvParams, mchAppId, mchAppEntity.getMchNo(), agreementNo);
}
JSONObject result = new JSONObject();
result.put("agreementNo", agreementNo);
result.put("accountBookId", accountBookId);
return ApiRes.ok(result);
}
private AliaqfIsvParams applyCheck(String mchNo, String isvNo) {
MchInfo mchInfo = mchInfoService.getById(mchNo);
if (MchInfo.TYPE_ISVSUB != mchInfo.getType()) {
throw new BizException("仅支持特约商户");
}
AliaqfIsvParams isvParams = (AliaqfIsvParams) configContextQueryService.queryIsvParams(isvNo, CS.IF_CODE.ALIAQF);
if (isvParams == null) {
throw new BizException("服务商未配置参数,请联系平台处理!");
}
return isvParams;
}
}

View File

@@ -0,0 +1,70 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.ctrls.AbstractCtrl;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchVideoCacheEntity;
import com.jeequan.jeepay.service.impl.MchVideoCacheService;
import com.jeequan.jeepay.thirdparty.service.wxchannel.WechatChannelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/mchVideo")
public class MchVideoController extends AbstractCtrl {
@Autowired
private WechatChannelService wechatChannelService;
@Autowired
private MchVideoCacheService mchVideoCacheService;
@PostMapping("/authTask")
public ApiRes auth() {
String mchNo = getValStringRequired("mchNo");
JSONObject task = wechatChannelService.createTask(mchNo);
return ApiRes.ok(task);
}
@GetMapping("/authTask")
public ApiRes taskResult() {
String taskId = getValStringRequired("taskId");
JSONObject taskResult = wechatChannelService.queryTask(taskId);
return ApiRes.ok(taskResult);
}
@GetMapping("/dataList")
public ApiRes cacheList() {
Page<MchVideoCacheEntity> iPage = getIPage();
MchVideoCacheEntity mchInfo = getObject(MchVideoCacheEntity.class);
LambdaQueryWrapper<MchVideoCacheEntity> wrapper = Wrappers.lambdaQuery(mchInfo);
Page<MchVideoCacheEntity> page = mchVideoCacheService.page(iPage, wrapper);
return ApiRes.ok(page);
}
@GetMapping("/randomOne")
public ApiRes randomOne() {
String mchNo = getValStringRequired("mchNo");
MchVideoCacheEntity randomOne = mchVideoCacheService.getRandomOne(mchNo);
return ApiRes.ok(randomOne);
}
@PostMapping("/choiceFlag/{id}")
public ApiRes choiceFlag(@PathVariable("id") Long id) {
String choiceFlag = getValStringRequired("choiceFlag");
mchVideoCacheService.lambdaUpdate()
.eq(MchVideoCacheEntity::getId, id)
.set(MchVideoCacheEntity::getChoiceFlag, choiceFlag)
.update();
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,143 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PackageInfo;
import com.jeequan.jeepay.db.entity.PackageOrder;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.PackageInfoService;
import com.jeequan.jeepay.service.impl.PackageProductService;
import com.jeequan.jeepay.service.impl.ProductAppService;
import com.jeequan.jeepay.service.impl.ProductInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
@RestController
@RequestMapping("/api/packageInfo")
public class PackageInfoController extends CommonCtrl {
@Autowired private PackageInfoService packageInfoService;
@Autowired private PackageProductService packageProductService;
@Autowired private ProductInfoService productInfoService;
@Autowired private ProductAppService productAppService;
@GetMapping
@MethodLog(remark = "查询方案")
public ApiRes list(){
IPage<PackageInfo> page=getIPage(true);
PackageInfo packageInfo = getObject(PackageInfo.class);
//提供id和名字检索
LambdaQueryWrapper<PackageInfo> queryWrapper= Wrappers.lambdaQuery();
IPage<PackageInfo> result = packageInfoService.getList(page, queryWrapper,packageInfo);
return ApiRes.ok(result);
}
@RequestMapping(value = "/getDetailById", method = RequestMethod.GET)
@MethodLog(remark = "回显方案详情")
public ApiRes getDetailById() throws BizException {
//获取查询条件
PackageInfo packageInfo = getObject(PackageInfo.class);
PackageInfo info = packageInfoService.getDetailById(packageInfo.getPackageId());
return ApiRes.ok(info);
}
@MethodLog(remark = "删除方案")
@PostMapping(value="/deletePackageInfo")
public ApiRes deletePackageInfo() {
PackageInfo packageInfo = getObject(PackageInfo.class);
if (StringUtils.isNotEmpty(packageInfo.getPackageId())){
packageInfo.setPackageState(2);
packageInfo.setUpdatedAt(new Date());
packageInfoService.updateById(packageInfo);
}else {
return ApiRes.customFail("所传方案id不能为空");
}
return ApiRes.ok();
}
/*新增或修改方案*/
@PostMapping("/saveOrUpdate")
@MethodLog(remark = "新增或修改方案")
public ApiRes saveOrUpdate() {
PackageInfo packageInfo = getObject(PackageInfo.class);
String sysUser = getCurrentUser().getSysUser().getRealname();
packageInfo.setCreatedBy(sysUser);
//前端组件不稳定,防止出错做一下数据校验
boolean checkout = packageInfoService.dataCheckout(packageInfo.getProductIds(), packageInfo.getPackageIds(), packageInfo.getPayInterfaceCodes());
if (!checkout){
throw new BizException("关联数据格式不正确!");
}
//如果收费规则为不收费给默认的免费值
if(packageInfo.getCharge() != null && packageInfo.getCharge().equals(PackageInfo.PACKAGE_STATE_ON_CHARGE)){
JSONArray jsonArray =JSONArray.parseArray(PackageInfo.JSON_STR);
packageInfo.setPackageText(jsonArray);
}
//方案表进行新增或者修改
if (StringUtils.isNotEmpty(packageInfo.getPackageId())){
//传入id方案表修改
LambdaUpdateWrapper<PackageInfo> updateWrapper= Wrappers.lambdaUpdate();
updateWrapper.eq(PackageInfo::getPackageId,packageInfo.getPackageId());
//如果不需要模板则把之前的清空--前端说不好处理。。
if(packageInfo.getCertification() != null && packageInfo.getCertification().equals(PackageInfo.PACKAGE_STATE_ON_CHARGE)){
updateWrapper.set(PackageInfo::getSpecialCertificationText,null);
}
boolean update = packageInfoService.update(packageInfo,updateWrapper);
if (!update) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
}else {
//不传id方案表新增
packageInfo.setPackageId(DateUtil.format(new Date(), "yyMMdd")+ RandomUtil.randomNumbers(6));
//根据规则“API_名称拼音大写_FA_PAY”定义
if (StringUtils.isEmpty(packageInfo.getName())){
throw new BizException("方案名称不能为空!");
}
String pinyinString = PinyinUtil.getPinyin(packageInfo.getName(),""); // 获取拼音字符串,
String upperCasePinyin = pinyinString.toUpperCase(); // 将拼音转化为大写
packageInfo.setApiCode(PackageInfo.API_CODE_FIRST+upperCasePinyin+PackageInfo.API_CODE_LAST);
//code唯一判定
long count = packageInfoService.count(PackageInfo.gw().eq(PackageInfo::getApiCode, packageInfo.getApiCode()));
if (count > 0){
throw new BizException("唯一性code值重复请尝试更换方案名称");
}
boolean save = packageInfoService.save(packageInfo);
if (!save) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
}
return ApiRes.ok();
}
@RequestMapping(value = "/getPackageCheckList", method = RequestMethod.GET)
@MethodLog(remark = "方案审核列表")
public ApiRes getPackageCheckList() throws BizException {
//获取查询条件
PackageInfo packageInfo = getObject(PackageInfo.class);
Page<PackageOrder> page=getIPage(true);
IPage<PackageInfo> pages = packageInfoService.getPackageCheckList(page,packageInfo.getName(),packageInfo.getPackageState(),packageInfo.getMchName());
return ApiRes.page(pages);
}
}

View File

@@ -0,0 +1,92 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PackageInfo;
import com.jeequan.jeepay.db.entity.PackageType;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.PackageInfoService;
import com.jeequan.jeepay.service.impl.PackageTypeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
@RestController
@RequestMapping("/api/packageType")
public class PackageTypeController extends CommonCtrl {
@Autowired private PackageTypeService packageTypeService;
@Autowired private PackageInfoService packageInfoService;
@RequestMapping(value = "/getList", method = RequestMethod.GET)
@MethodLog(remark = "方案分类列表")
public ApiRes list(){
IPage<PackageType> page=getIPage(true);
PackageType packageType = getObject(PackageType.class);
//提供id和名字检索
LambdaQueryWrapper<PackageType> queryWrapper= Wrappers.lambdaQuery();
queryWrapper.like(StringUtils.isNotEmpty(packageType.getTypeName()),PackageType::getTypeName,packageType.getTypeName());
queryWrapper.orderByDesc(PackageType::getCreatedAt);
IPage<PackageType> result = packageTypeService.page(page,queryWrapper);
return ApiRes.ok(result);
}
@MethodLog(remark = "新增方案分类")
@PostMapping(value="/add")
public ApiRes add() {
PackageType packageType = getObject(PackageType.class);
// 当前登录用户信息
SysUser sysUser = getCurrentUser().getSysUser();
packageType.setCreatedBy(String.valueOf(sysUser.getSysUserId()));
packageTypeService.save(packageType);
return ApiRes.ok();
}
@MethodLog(remark = "删除方案分类")
@PostMapping(value="/deletePackage")
public ApiRes deletePackage() {
PackageType packageType = getObject(PackageType.class);
//判断该节点下是否有子节点 有则不让删除
LambdaQueryWrapper<PackageInfo> wrapper=new LambdaQueryWrapper<>();
wrapper.eq(PackageInfo::getPackageId,packageType.getTypeId());
wrapper.eq(PackageInfo::getPackageState,1);
List<PackageInfo> packageInfosList = packageInfoService.list(wrapper);
if (!packageInfosList.isEmpty()){
return ApiRes.customFail("该方案分类下相关内容未清空!");
}
packageTypeService.removeById(packageType.getTypeId());
return ApiRes.ok();
}
@MethodLog(remark = "更新方案分类信息")
@PostMapping(value="/updatePackage")
public ApiRes updatePackage() {
//获取查询条件
PackageType type = getObject(PackageType.class);
type.setUpdatedAt(new Date());
packageTypeService.updateById(type);
return ApiRes.ok();
}
@RequestMapping(value = "/getTypeDetailById", method = RequestMethod.GET)
@MethodLog(remark = "回显方案分类详情")
public ApiRes getTypeDetailById() throws BizException {
//获取查询条件
PackageType packageType = getObject(PackageType.class);
PackageType type = packageTypeService.getById(packageType.getTypeId());
return ApiRes.ok(type);
}
}

View File

@@ -0,0 +1,285 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.components.mq.model.MchAuditThirdNotifyMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchModifyApplyment;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.paychannel.IYsApplymentApiService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.MchAppEntity;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.db.entity.MchModifyApplymentEntity;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchModifyApplymentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/api/mchApplyments")
public class YspayMchApplymentController extends CommonCtrl {
@Autowired private MchApplymentService mchApplymentService;
@Autowired private MchAppService mchAppService;
@Autowired private MchInfoConverter mchInfoConverter;
@Autowired private IMQSender mqSender;
@Autowired
private MchModifyApplymentService mchModifyApplymentService;
/** 银盛 上传图片 **/
@PostMapping("/yspayUpload/{recordId}")
public ApiRes yspayUpload(@PathVariable("recordId") String recordId) {
JSONObject paramJSON = getReqParamJSON();
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_AUDITING && dbRecord.getState() != MchApplyment.STATE_WAIT_VERIFY &&
dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_FINISH_SIGN)) {
throw new BizException("当前申请单状态错误,无法继续。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IYsApplymentApiService.class);
String respJSONStr = "";
try {
// 更新参数
dbRecord.setApplyDetailInfo(paramJSON.toJSONString());
// 调起接口
com.jeequan.jeepay.core.entity.MchApplyment mchApplymentImg = ysApplymentApiService.uploadImg(mchInfoConverter.toModel(dbRecord));
respJSONStr = mchApplymentImg.getChannelVar1();
MchApplyment updateRecord = new MchApplyment();
updateRecord.setApplyDetailInfo(dbRecord.getApplyDetailInfo());
BeanUtils.copyProperties(mchApplymentImg, updateRecord);
// 更新数据
updateRecord.setApplyId(recordId);
mchApplymentService.updateById(updateRecord);
} catch (BizException e) {
logger.info("请求异常", e);
throw e;
}
return ApiRes.ok(respJSONStr);
}
/** 银盛 资料确认 **/
@PostMapping("/yspayConfirm/{recordId}")
public ApiRes yspayConfirm(@PathVariable("recordId") String recordId) {
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_AUDITING && dbRecord.getState() != MchApplyment.STATE_WAIT_VERIFY &&
dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_FINISH_SIGN)) {
throw new BizException("当前申请单状态错误,无法继续。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IYsApplymentApiService.class);
String respJSONStr = "";
try {
// 提交审核
com.jeequan.jeepay.core.entity.MchApplyment applymentResult = ysApplymentApiService.attachConfirm(mchInfoConverter.toModel(dbRecord));
respJSONStr = applymentResult.getApplyErrorInfo();
MchApplyment updateRecordAudit = new MchApplyment();
BeanUtils.copyProperties(applymentResult, updateRecordAudit);
// 更新数据
updateRecordAudit.setApplyId(recordId);
mchApplymentService.updateById(updateRecordAudit);
} catch (BizException e) {
logger.info("请求异常", e);
throw e;
}
return ApiRes.ok(respJSONStr);
}
/** 银盛 发起合同签约 **/
@PostMapping("/ysSignApply/{recordId}")
public ApiRes ysSignApply(@PathVariable("recordId") String recordId) {
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IYsApplymentApiService.class);
// 调起接口
com.jeequan.jeepay.core.entity.MchApplyment applymentResult = ysApplymentApiService.signApply(getReqParamJSON(), mchInfoConverter.toModel(dbRecord));
// 更新商户费率配置
MchApplyment updateRecordAudit = new MchApplyment();
BeanUtils.copyProperties(applymentResult, updateRecordAudit);
// 更新数据
updateRecordAudit.setApplyId(recordId);
mchApplymentService.updateById(updateRecordAudit);
return ApiRes.ok(applymentResult.getChannelVar2());
}
/** 银盛 查询合同签约状态 **/
@PostMapping("/ysSignQuery/{recordId}")
public ApiRes ysSignQuery(@PathVariable("recordId") String recordId) {
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
// 获取当前进件签约信息,未发起签约时为空
if (StringUtils.isBlank(dbRecord.getChannelVar2())) {
return ApiRes.ok();
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IYsApplymentApiService.class);
// 调起接口
com.jeequan.jeepay.core.entity.MchApplyment applymentResult = ysApplymentApiService.signQuery(mchInfoConverter.toModel(dbRecord));
// 更新商户费率配置
MchApplyment updateRecordAudit = new MchApplyment();
BeanUtils.copyProperties(applymentResult, updateRecordAudit);
// 更新数据
updateRecordAudit.setApplyId(recordId);
mchApplymentService.updateById(updateRecordAudit);
if (updateRecordAudit.getState() == MchApplyment.STATE_SUCCESS) {
mchApplymentService.onApplymentSuccess(updateRecordAudit.getApplyId());
mqSender.send(MchAuditThirdNotifyMQ.build(recordId, MchAuditThirdNotifyMQ.TYPE_AUDIT));
}
return ApiRes.ok(applymentResult.getChannelVar2());
}
/** 银盛 签约重发 **/
@PostMapping("/ysSignSendAgain/{recordId}")
public ApiRes ysSignSendAgain(@PathVariable("recordId") String recordId) {
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null) {
MchModifyApplymentEntity modifyApplyment = mchModifyApplymentService.getById(recordId);
if (modifyApplyment == null || modifyApplyment.getState() != MchApplyment.STATE_WAIT_SIGN) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(CS.IF_CODE.YSPAY + "ApplymentApiService", IYsApplymentApiService.class);
// 调起接口
MchModifyApplyment applymentResult = ysApplymentApiService.signSendAgain(getReqParamJSON(), mchInfoConverter.toModel(modifyApplyment));
// 更新数据
if (!StrUtil.isEmpty(applymentResult.getChannelVar1())) {
MchModifyApplymentEntity updateRecordAudit = new MchModifyApplymentEntity();
updateRecordAudit.setApplyId(recordId);
updateRecordAudit.setChannelVar1(applymentResult.getChannelVar1());
mchModifyApplymentService.updateById(updateRecordAudit);
}
return ApiRes.ok(applymentResult.getChannelVar1());
} else {
if (dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(CS.IF_CODE.YSPAY + "ApplymentApiService", IYsApplymentApiService.class);
// 调起接口
com.jeequan.jeepay.core.entity.MchApplyment applymentResult = ysApplymentApiService.signSendAgain(getReqParamJSON(), mchInfoConverter.toModel(dbRecord));
// 更新数据
if (!StrUtil.isEmpty(applymentResult.getChannelVar2())) {
MchApplyment updateRecordAudit = new MchApplyment();
updateRecordAudit.setApplyId(recordId);
updateRecordAudit.setChannelVar2(applymentResult.getChannelVar2());
mchApplymentService.updateById(updateRecordAudit);
}
return ApiRes.ok(applymentResult.getChannelVar2());
}
}
/** 银盛费率配置 **/
@PostMapping("/ysPayRateConfig/{recordId}")
public ApiRes ysPayRateConfig(@PathVariable("recordId") String recordId) {
JSONObject reqParamJSON = getReqParamJSON();
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_AUDITING && dbRecord.getState() != MchApplyment.STATE_REJECT_WAIT_MODIFY
&& dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN)) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IYsApplymentApiService.class);
// 调起接口
com.jeequan.jeepay.core.entity.MchApplyment applymentResult = ysApplymentApiService.payRateConfig(reqParamJSON, mchInfoConverter.toModel(dbRecord));
// 更新商户费率配置
MchApplyment updateRecordAudit = new MchApplyment();
// 配置成功更新费率
if (applymentResult.getState() != null && applymentResult.getState() == MchApplyment.STATE_SUCCESS) {
BeanUtils.copyProperties(applymentResult, updateRecordAudit);
} else {
applymentResult.setApplyDetailInfo(null);
applymentResult.setState(MchApplyment.STATE_AUDITING);
BeanUtils.copyProperties(applymentResult, updateRecordAudit);
}
// 更新数据
updateRecordAudit.setApplyId(recordId);
mchApplymentService.updateById(updateRecordAudit);
return ApiRes.ok(applymentResult.getChannelVar1());
}
/** 银盛 配置相关信息 **/
@PostMapping("/yspayInterfaceConfig/{applyId}/{mchAppId}")
public ApiRes yspayInterfaceConfig(@PathVariable("applyId") String applyId, @PathVariable("mchAppId") String mchAppId) {
String configType = getValStringRequired("configType"); // PAY_BASE_URL, BIND_APP_ID, SUBSCRIBE_APP_ID, QUERY
String configVal = getValStringRequired("configVal");
MchApplyment tbMchApplyment = mchApplymentService.getById(applyId);
MchAppEntity mchAppEntity = mchAppService.getById(mchAppId);
IYsApplymentApiService applymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(tbMchApplyment.getIfCode()) + "ApplymentApiService", IYsApplymentApiService.class);
com.jeequan.jeepay.core.entity.MchApplyment mchApplyment = mchInfoConverter.toModel(tbMchApplyment);
if ("PAY_BASE_URL".equals(configType)) {
return ApiRes.ok(applymentApiService.configPayBaseUrl(configVal, mchAppEntity.getAppId(), mchApplyment));
} else if ("BIND_APP_ID".equals(configType)) {
return ApiRes.ok(applymentApiService.configBindAppId(configVal, mchAppEntity.getAppId(), mchApplyment));
} else if ("SUBSCRIBE_APP_ID".equals(configType)) {
return ApiRes.ok(applymentApiService.configSubscribeAppId(configVal, mchAppEntity.getAppId(), mchApplyment));
}
return ApiRes.customFail("没有[" + configType + "]配置");
}
}

View File

@@ -0,0 +1,38 @@
package com.jeequan.jeepay.mgr.ctrl.merchant;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/mchApplyments")
public class ZftMchApplymentController extends CommonCtrl {
// @Autowired
// private IZftApplymentApiService zftApplymentApiService;
//
// @Autowired private MchAppService mchAppService;
//
// /** 支付宝直付通废弃商户接口 **/
// @PostMapping("/zftMchDelete/{appId}/{smId}")
// public ApiRes zftMchDelete(@PathVariable("appId") String appId, @PathVariable("smId") String smId) {
//
// if (StringUtils.isEmpty(smId)) {
// throw new BizException("支付宝商户号不可为空");
// }
//
// // 商户信息
// MchApp mchApp = mchAppService.getById(appId);
//
// if (mchApp == null) {
// throw new BizException(appId + "商户应用不存在");
// }
// MchInfo mchInfo = mchInfoService.getById(mchApp.getMchNo());
// if (mchInfo == null) {
// throw new BizException(mchApp.getMchNo() + "商户不存在");
// }
//
// ChannelRetMsg channelRetMsg = zftApplymentApiService.zftMchDelete(mchInfo, smId);
// return ApiRes.ok(channelRetMsg);
// }
}

View File

@@ -0,0 +1,296 @@
package com.jeequan.jeepay.mgr.ctrl.order;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Pair;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.IConfigContextQueryService;
import com.jeequan.jeepay.core.interfaces.paychannel.IChannelAccountService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.cashout.CashoutParams;
import com.jeequan.jeepay.core.model.cashout.CashoutRetMsg;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.ChannelAccountCashoutRecord;
import com.jeequan.jeepay.db.entity.PayInterfaceConfig;
import com.jeequan.jeepay.db.entity.PayInterfaceDefine;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.ChannelAccountCashoutRecordService;
import com.jeequan.jeepay.service.impl.PayInterfaceConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/***
* 渠道提现记录管理类
*
* @author zx
*
* @date 2022/3/23 16:45
*/
@RestController
@RequestMapping("/api/channel/cashouts")
@Slf4j
public class ChannelCashoutRecordController extends CommonCtrl {
@Autowired private ChannelAccountCashoutRecordService channelAccountCashoutRecordService;
@Autowired private IConfigContextQueryService configContextQueryService;
@Autowired private PayInterfaceConfigService payInterfaceConfigService;
@PreAuthorize("hasAuthority('ENT_MCH_CHANNEL_ACCOUNT')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
String appId = getValStringRequired("appId");
String ifCode = getValString("ifCode");
String channelMchId = getValString("channelMchId");
// 查询条件:启用状态 && 支持提现 && 开启提现
List<PayInterfaceDefine> ifDefines = payInterfaceDefineService.list(PayInterfaceDefine.gw()
.eq(PayInterfaceDefine::getState, CS.YES)
.eq(PayInterfaceDefine::getIsSupportCashout, CS.YES)
.eq(PayInterfaceDefine::getIsOpenCashout, CS.YES)
);
if (CollUtil.isEmpty(ifDefines)) {
return ApiRes.page(new Page(getPageIndex(), getPageSize(), 0));
}
List<String> ifCodeList = ifDefines.stream().map(PayInterfaceDefine::getIfCode).collect(Collectors.toList());
IPage<PayInterfaceConfig> payInterfaceConfigIPage = payInterfaceConfigService.page(getIPage(), PayInterfaceConfig.gw()
.eq(PayInterfaceConfig::getInfoId, appId)
.eq(PayInterfaceConfig::getInfoType, CS.SYS_ROLE_TYPE.MCH_APP)
.eq(StringUtils.isNotBlank(ifCode), PayInterfaceConfig::getIfCode, ifCode)
.eq(PayInterfaceConfig::getState, CS.YES)
.isNotNull(PayInterfaceConfig::getIfParams)
.in(PayInterfaceConfig::getIfCode, ifCodeList)
);
if (CollUtil.isEmpty(payInterfaceConfigIPage.getRecords())) {
return ApiRes.page(payInterfaceConfigIPage);
}
MchAppConfigContext mchAppConfigContext = configContextQueryService.queryMchInfoAndAppInfo(appId);
Long id = null;
Pair<String, Long> pair = null;
for (PayInterfaceConfig payInterfaceConfig : payInterfaceConfigIPage.getRecords()) {
// 查询结算接口是否存在
IChannelAccountService channelAccountService =
SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(payInterfaceConfig.getIfCode()) + "ChannelAccountService", IChannelAccountService.class);
// 提现接口实现不存在
if(channelAccountService == null){
throw new BizException(payInterfaceConfig.getIfCode() + "不支持提现");
}
try {
pair = channelAccountService.queryBalanceAmount(mchAppConfigContext, payInterfaceConfig.getIfCode());
if (StringUtils.equals(channelMchId, pair.getKey())) {
id = payInterfaceConfig.getId();
}
payInterfaceConfig.addExt("currentBalance", pair.getValue());
payInterfaceConfig.addExt("channelMchId", pair.getKey());
}catch (Exception e) {
log.error("查询三方账户余额失败ifCode={}mchNo={}appId={}", payInterfaceConfig.getIfCode(), mchAppConfigContext.getMchNo(), appId);
}
}
if (StringUtils.isNotBlank(channelMchId) && id == null) {
return ApiRes.page(new Page(getPageIndex(), getPageSize(), 0));
}
// 根据渠道子商户号搜索的情况
if (id != null) {
PayInterfaceConfig config = payInterfaceConfigService.getById(id);
if (pair != null) {
config.addExt("currentBalance", pair.getValue());
config.addExt("channelMchId", pair.getKey());
}
Page page = new Page(getPageIndex(), getPageSize(), 1);
page.setRecords(Collections.singletonList(config));
return ApiRes.page(page);
}
setIfName(payInterfaceConfigIPage.getRecords());
return ApiRes.page(payInterfaceConfigIPage);
}
@PreAuthorize("hasAuthority('ENT_CHANNEL_CASHOUT_LIST')")
@RequestMapping(value="/records", method = RequestMethod.GET)
public ApiRes records() {
ChannelAccountCashoutRecord queryRecord = getObject(ChannelAccountCashoutRecord.class);
LambdaQueryWrapper<ChannelAccountCashoutRecord> wrapper = ChannelAccountCashoutRecord.gw();
// 单号
wrapper.eq(StringUtils.isNotEmpty(queryRecord.getRid()), ChannelAccountCashoutRecord::getRid, queryRecord.getRid());
// infoId
wrapper.eq( StringUtils.isNotEmpty(queryRecord.getAppId() ), ChannelAccountCashoutRecord::getAppId, queryRecord.getAppId());
// 状态查询
wrapper.eq(queryRecord.getState() != null, ChannelAccountCashoutRecord::getState, queryRecord.getState());
// 商户号
wrapper.eq(StringUtils.isNotEmpty(queryRecord.getMchNo()), ChannelAccountCashoutRecord::getMchNo, queryRecord.getMchNo());
// 支付接口
wrapper.eq(StringUtils.isNotEmpty(queryRecord.getIfCode()), ChannelAccountCashoutRecord::getIfCode, queryRecord.getIfCode());
// 渠道子商户号
wrapper.eq(StringUtils.isNotEmpty(queryRecord.getChannelSubMchId()), ChannelAccountCashoutRecord::getChannelSubMchId, queryRecord.getChannelSubMchId());
// 时间范围条件
Date[] dateRange = queryRecord.buildQueryDateRange();
wrapper.ge(dateRange[0] != null, ChannelAccountCashoutRecord::getCreatedAt, dateRange[0]);
wrapper.le(dateRange[1] != null, ChannelAccountCashoutRecord::getCreatedAt, dateRange[1]);
wrapper.orderByDesc(ChannelAccountCashoutRecord::getCreatedAt);
IPage<ChannelAccountCashoutRecord> pages = channelAccountCashoutRecordService.page(getIPage(), wrapper);
setIfName(pages.getRecords());
return ApiRes.page(pages);
}
@PreAuthorize("hasAuthority('ENT_CHANNEL_CASHOUT_RECORD_VIEW')")
@RequestMapping(value="/{rid}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("rid") String rid) {
return ApiRes.ok(channelAccountCashoutRecordService.getById(rid));
}
/** 发起提现 **/
@PreAuthorize("hasAuthority('ENT_MCH_CHANNEL_CASHOUT')")
@PostMapping
public ApiRes cashout() {
String ifCode = getValStringRequired("ifCode");
String isvNo = getValStringRequired("isvNo");
String appId = getValStringRequired("appId");
Long amount = getRequiredAmountL("amount");
if (amount <= 0) {
throw new BizException("提现金额应大于0");
}
// 查询结算接口是否存在
IChannelAccountService channelAccountService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(ifCode) + "ChannelAccountService", IChannelAccountService.class);
// 提现接口实现不存在
MchAppConfigContext mchAppConfigContext = configContextQueryService.queryMchInfoAndAppInfo(appId);
MchInfo mchInfo = mchAppConfigContext.getMchInfo();
// 校验提现权限
if (!checkCashoutJudge(ifCode, isvNo)) {
throw new BizException("暂不支持发起提现,请检查是否开启提现");
}
Pair<String, Long> pair = channelAccountService.queryBalanceAmount(mchAppConfigContext, ifCode);
Long currentBalance = pair.getValue();
if(currentBalance < amount){
throw new BizException("商户可用余额不足");
}
// 提现记录入库
SysUser sysUser = getCurrentUser().getSysUser();
ChannelAccountCashoutRecord cashoutRecord = channelAccountCashoutRecordService.initRecord(SeqKit.genCashoutRecordId(), amount, currentBalance, mchAppConfigContext.getMchNo(), mchAppConfigContext.getMchInfo().getMchName(),
mchAppConfigContext.getAppId(), isvNo, ifCode, pair.getKey(), null, sysUser.getSysUserId(), sysUser.getRealname());
// 提现
CashoutRetMsg cashoutRS = channelAccountService.cashout(cashoutRecord, mchAppConfigContext, ifCode);
processChannelMsg(cashoutRS, cashoutRecord.getRid());
return ApiRes.ok(channelAccountCashoutRecordService.getById(cashoutRecord.getRid()));
}
/** 处理返回的渠道信息,并更新状态 **/
public void processChannelMsg(CashoutRetMsg cashoutRetMsg, String recordId){
//对象为空 || 上游返回状态为空, 则无需操作
if(cashoutRetMsg == null || cashoutRetMsg.getChannelState() == null){
throw new BizException("上游返回状态为空");
}
if(cashoutRetMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_SUCCESS) {
updateStatusInit2Other(recordId, ChannelAccountCashoutRecord.CASHOUT_STATE_SUCCESS, cashoutRetMsg.getChannelOrderId(), cashoutRetMsg.getBankName(), cashoutRetMsg.getBankAccount(), cashoutRetMsg.getBankAccountName(), null);
}else if(cashoutRetMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_FAIL) {
//更新为失败状态
String applyMsg = String.format("failInfo=[code=%s, msg=%s]", cashoutRetMsg.getChannelErrCode(), cashoutRetMsg.getChannelErrMsg());
updateStatusInit2Other(recordId, ChannelAccountCashoutRecord.CASHOUT_STATE_FAIL, null, null, null, null, applyMsg);
}else {
updateStatusInit2Other(recordId, ChannelAccountCashoutRecord.CASHOUT_STATE_ING, cashoutRetMsg.getChannelOrderId(), null, null, null, null);
}
}
private void updateStatusInit2Other(String recordId, byte state, String channelRid, String bankName, String bankAccount, String bankAccountName, String channelErrMsg) {
boolean isSuccess = channelAccountCashoutRecordService.updateInit2Ing(recordId, channelRid);
if(!isSuccess){
throw new BizException("更新提现单异常!");
}
if(state == ChannelAccountCashoutRecord.CASHOUT_STATE_SUCCESS){
isSuccess = channelAccountCashoutRecordService.updateIng2Success(recordId, channelRid, bankName, bankAccount, bankAccountName);
if(!isSuccess){
throw new BizException("更新提现单异常!");
}
}else if(state == ChannelAccountCashoutRecord.CASHOUT_STATE_FAIL){
isSuccess = channelAccountCashoutRecordService.updateIng2Fail(recordId, channelErrMsg);
if(!isSuccess){
throw new BizException("更新提现单异常!");
}
}
}
// 校验提现权限
public boolean checkCashoutJudge(String ifCode, String isvNo) {
// 支付接口应支持且开启提现
PayInterfaceDefine ifDefine = payInterfaceDefineService.getOne(PayInterfaceDefine.gw()
.eq(PayInterfaceDefine::getIfCode, ifCode)
.eq(PayInterfaceDefine::getIsSupportCashout, CS.YES)
.eq(PayInterfaceDefine::getIsOpenCashout, CS.YES)
);
if (ifDefine == null) {
log.info("支付接口:{},未开启提现", ifCode);
return false;
}
// 服务商提现配置
if (StringUtils.isNotBlank(isvNo)) {
PayInterfaceConfig isvIfConfig = payInterfaceConfigService.getOne(PayInterfaceConfig.gw()
.eq(PayInterfaceConfig::getIfCode, ifCode)
.eq(PayInterfaceConfig::getInfoType, CS.SYS_ROLE_TYPE.ISV)
.eq(PayInterfaceConfig::getInfoId, isvNo)
);
if (isvIfConfig == null || StringUtils.isBlank(isvIfConfig.getCashoutParams())) {
log.info("服务商:{},未开启提现", isvNo);
return false;
}
// 服务商需开启提现
CashoutParams isvCashoutParams = JSON.parseObject(isvIfConfig.getCashoutParams(), CashoutParams.class);
if (isvCashoutParams == null || isvCashoutParams.getIsOpenIsvCashout() == null || isvCashoutParams.getIsOpenIsvCashout() != CS.YES) {
log.info("服务商:{},未开启提现", isvNo);
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,126 @@
package com.jeequan.jeepay.mgr.ctrl.order;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.components.mq.model.PayOrderMchNotifyMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchNotifyRecord;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchNotifyRecordService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
/**
* 商户通知类
*
* @author pangxiaoyu
*
* @date 2021-06-07 07:15
*/
@RestController
@RequestMapping("/api/mchNotify")
public class MchNotifyController extends CommonCtrl {
@Autowired private MchNotifyRecordService mchNotifyService;
@Autowired private IMQSender mqSender;
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 商户通知列表
*/
@PreAuthorize("hasAuthority('ENT_NOTIFY_LIST')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
MchNotifyRecord mchNotify = getObject(MchNotifyRecord.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<MchNotifyRecord> wrapper = MchNotifyRecord.gw();
if (StringUtils.isNotEmpty(mchNotify.getOrderId())) {
wrapper.eq(MchNotifyRecord::getOrderId, mchNotify.getOrderId());
}
if (StringUtils.isNotEmpty(mchNotify.getMchNo())) {
wrapper.eq(MchNotifyRecord::getMchNo, mchNotify.getMchNo());
}
if (StringUtils.isNotEmpty(mchNotify.getIsvNo())) {
wrapper.eq(MchNotifyRecord::getIsvNo, mchNotify.getIsvNo());
}
if (StringUtils.isNotEmpty(mchNotify.getMchOrderNo())) {
wrapper.eq(MchNotifyRecord::getMchOrderNo, mchNotify.getMchOrderNo());
}
if (mchNotify.getOrderType() != null) {
wrapper.eq(MchNotifyRecord::getOrderType, mchNotify.getOrderType());
}
if (mchNotify.getState() != null) {
wrapper.eq(MchNotifyRecord::getState, mchNotify.getState());
}
if (StringUtils.isNotEmpty(mchNotify.getAppId())) {
wrapper.eq(MchNotifyRecord::getAppId, mchNotify.getAppId());
}
// 时间范围条件
Date[] dateRange = mchNotify.buildQueryDateRange();
if (dateRange[0] != null) {
wrapper.ge(MchNotifyRecord::getCreatedAt, dateRange[0]);
}
if (dateRange[1] != null) {
wrapper.le(MchNotifyRecord::getCreatedAt, dateRange[1]);
}
wrapper.orderByDesc(MchNotifyRecord::getCreatedAt);
IPage<MchNotifyRecord> pages = mchNotifyService.page(getIPage(), wrapper);
return ApiRes.page(pages);
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 商户通知信息
*/
@PreAuthorize("hasAuthority('ENT_MCH_NOTIFY_VIEW')")
@RequestMapping(value="/{notifyId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("notifyId") String notifyId) {
MchNotifyRecord mchNotify = mchNotifyService.getById(notifyId);
if (mchNotify == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(mchNotify);
}
/*
* 功能描述: 商户通知重发操作
* @Author: terrfly
* @Date: 2021/6/21 17:41
*/
@PreAuthorize("hasAuthority('ENT_MCH_NOTIFY_RESEND')")
@RequestMapping(value="resend/{notifyId}", method = RequestMethod.POST)
public ApiRes resend(@PathVariable("notifyId") Long notifyId) {
MchNotifyRecord mchNotify = mchNotifyService.getById(notifyId);
if (mchNotify == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
if (mchNotify.getState() != MchNotifyRecord.STATE_FAIL) {
throw new BizException("请选择失败的通知记录");
}
//更新通知中
mchNotifyService.getBaseMapper().updateIngAndAddNotifyCountLimit(notifyId);
//调起MQ重发
mqSender.send(PayOrderMchNotifyMQ.build(notifyId));
return ApiRes.ok(mchNotify);
}
}

View File

@@ -0,0 +1,56 @@
package com.jeequan.jeepay.mgr.ctrl.order;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PayAlizftSettRecord;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.PayAlizftSettRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* 直付通 二级商户结算记录
*
* @author yr
*
* @date 2023-09-04 10:15
*/
@RestController
@RequestMapping("/api/zftSettRecords")
public class PayAlizftSettRecordController extends CommonCtrl {
@Autowired private PayAlizftSettRecordService settRecordService;
/**
* @author: yr
* @date: 2023-09-04 10:15
* @describe: 直付通结算记录列表
*/
@PreAuthorize("hasAuthority('ENT_ZFT_SETT_RECORD_LIST')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
PayAlizftSettRecord settRecord = getObject(PayAlizftSettRecord.class);
IPage<PayAlizftSettRecord> pages = settRecordService.listByPage(getIPage(), settRecord);
return ApiRes.page(pages);
}
/**
* @author: yr
* @date: 2023-09-04 10:15
* @describe: 直付通结算记录列表
*/
@PreAuthorize("hasAuthority('ENT_ZFT_SETT_RECORD_VIEW')")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") String recordId) {
PayAlizftSettRecord settRecord = settRecordService.getById(recordId);
if (settRecord == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(settRecord);
}
}

View File

@@ -0,0 +1,217 @@
package com.jeequan.jeepay.mgr.ctrl.order;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.JeepayClient;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.paychannel.IRefundService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.export.PayOrderExportExcel;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRefundLimit;
import com.jeequan.jeepay.core.utils.*;
import com.jeequan.jeepay.db.entity.MchAppEntity;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.db.entity.PayWay;
import com.jeequan.jeepay.exception.JeepayException;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.model.RefundOrderCreateReqModel;
import com.jeequan.jeepay.request.RefundOrderCreateRequest;
import com.jeequan.jeepay.response.RefundOrderCreateResponse;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 支付订单类
*
* @author pangxiaoyu
* @date 2021-06-07 07:15
*/
@RestController
@RequestMapping("/api/payOrder")
public class PayOrderController extends CommonCtrl {
@Autowired private PayOrderService payOrderService;
@Autowired private PayWayService payWayService;
@Autowired private SysConfigService sysConfigService;
@Autowired private MchAppService mchAppService;
@Autowired private OrderProfitSettRecordService orderProfitSettRecordService;
@Autowired private StatsTradeService statsTradeService;
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:15
* @describe: 订单信息列表
*/
@PreAuthorize("hasAuthority('ENT_ORDER_LIST')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
PayOrder payOrder = getObject(PayOrder.class);
JSONObject paramJSON = getReqParamJSON();
IPage<PayOrder> pages = payOrderService.listByPage(getIPage(), payOrder, paramJSON);
return ApiRes.page(pages);
}
/**
* @author: xiaoyu
* @date: 2022/2/10 17:00
* @describe: 订单列表统计
*/
@PreAuthorize("hasAuthority('ENT_ORDER_COUNT')")
@RequestMapping(value="/count", method = RequestMethod.GET)
public ApiRes count() {
PayOrder payOrder = getObject(PayOrder.class);
JSONObject paramJSON = getReqParamJSON();
// JSONObject resMap = payOrderService.orderCount(payOrder, paramJSON, null);
// 查询支付、退款金额 笔数
PayOrderCount orderCount = statsTradeService.selectTotalByTransaction(paramJSON, null);
return ApiRes.ok(orderCount);
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:15
* @describe: 支付订单信息
*/
@PreAuthorize("hasAuthority('ENT_PAY_ORDER_VIEW')")
@RequestMapping(value="/{payOrderId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("payOrderId") String payOrderId) {
PayOrder payOrder = payOrderService.getDetails(payOrderId);
if (payOrder == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
// 查询订单分润情况
payOrder.addExt("profitList", orderProfitSettRecordService.getBaseMapper().queryOrderProfitSum(payOrderId, null, null));
return ApiRes.ok(payOrder);
}
/**
* 发起订单退款
* @author terrfly
* @date 2021/6/17 16:38
*/
@MethodLog(remark = "发起订单退款")
@PreAuthorize("hasAuthority('ENT_PAY_ORDER_REFUND')")
@PostMapping("/refunds/{payOrderId}")
public ApiRes refund(@PathVariable("payOrderId") String payOrderId) {
Long refundAmount = getRequiredAmountL("refundAmount");
String refundReason = getValStringRequired("refundReason");
//退款模式 “1”收款商户号退款,"2"平台一般户退款
String refundModel = getValString("refundModel");
PayOrder payOrder = payOrderService.getById(payOrderId);
if (payOrder == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
if(payOrder.getState() != PayOrder.STATE_SUCCESS){
throw new BizException("订单状态不正确");
}
if(payOrder.getRefundAmount() + refundAmount > payOrder.getAmount()){
throw new BizException("退款金额超过订单可退款金额!");
}
RefundOrderCreateRequest request = new RefundOrderCreateRequest();
RefundOrderCreateReqModel model = new RefundOrderCreateReqModel();
model.setPas(SysConfigService.PLATFORM_API_SECRET); // 通信秘钥
model.setExtParam(refundModel);
request.setBizModel(model);
model.setMchNo(payOrder.getMchNo()); // 商户号
model.setAppId(payOrder.getAppId());
model.setPayOrderId(payOrderId);
model.setMchRefundNo(SeqKit.genMhoOrderId());
model.setRefundAmount(refundAmount);
model.setRefundReason(refundReason);
model.setCurrency("CNY");
MchAppEntity mchAppEntity = mchAppService.getById(payOrder.getAppId());
JeepayClient jeepayClient = new JeepayClient(sysConfigService.getDBApplicationConfig().getPaySiteUrl(), mchAppEntity.getAppSecret());
try {
RefundOrderCreateResponse response = jeepayClient.execute(request);
if(response.getCode() != 0){
throw new BizException(response.getMsg());
}
return ApiRes.ok(response.get());
} catch (JeepayException e) {
throw new BizException(e.getMessage());
}
}
/**
* 是否支持平台户退款
* @param payOrderId
* @return
*/
@GetMapping("/refunds/limit/{payOrderId}")
public ApiRes isPlatCheck(@PathVariable("payOrderId") String payOrderId) {
PayOrder payOrder = payOrderService.getById(payOrderId);
if (payOrder == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
//获取退款接口
IRefundService refundService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(payOrder.getIfCode()) + "RefundService", IRefundService.class);
if(refundService == null){
return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR,"未获取到退款接口");
}
ChannelRefundLimit refundLimit = refundService.isRefundLimit(payOrder.getSettleType(), payOrder.getMchExtNo());
return ApiRes.ok(refundLimit);
}
/**
* @author: xiaoyu
* @date: 2022/1/14 9:45
* @describe: 订单列表数据导出
*/
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() {
try {
PayOrder payOrder = getObject(PayOrder.class);
JSONObject paramJSON = getReqParamJSON();
IPage<PayOrder> pages = payOrderService.listByPage(getIPage(true), payOrder, paramJSON);
List<JSONObject> newList = new LinkedList<>();
for (PayOrder order:pages.getRecords()) {
JSONObject object = (JSONObject) JSONObject.toJSON(order);
object.put("amount", AmountUtil.convertCent2Dollar(order.getAmount()));
object.put("refundAmount", AmountUtil.convertCent2Dollar(order.getRefundAmount()));
object.put("mchFeeAmount", AmountUtil.convertCent2Dollar(order.getMchFeeAmount()));
object.put("mchOrderFeeAmount", AmountUtil.convertCent2Dollar(order.getMchOrderFeeAmount()));
newList.add(object);
}
List<PayOrderExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), PayOrderExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "支付订单", "支付订单", PayOrderExportExcel.class, "支付订单", response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出订单失败!");
}
}
}

View File

@@ -0,0 +1,111 @@
package com.jeequan.jeepay.mgr.ctrl.order;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.export.RefundOrderExportExcel;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.db.entity.RefundOrder;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.RefundOrderService;
import com.jeequan.jeepay.service.impl.StatsTradeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 退款订单类
*/
@RestController
@RequestMapping("/api/refundOrder")
public class RefundOrderController extends CommonCtrl {
@Autowired private RefundOrderService refundOrderService;
@Autowired private StatsTradeService statsTradeService;
/**
* 退款订单信息列表
*/
@PreAuthorize("hasAuthority('ENT_REFUND_LIST')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
RefundOrder refundOrder = getObject(RefundOrder.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<RefundOrder> wrapper = RefundOrder.gw();
IPage<RefundOrder> pages = refundOrderService.pageList(getIPage(), wrapper, refundOrder, paramJSON);
setIfName(pages.getRecords());
return ApiRes.page(pages);
}
/**
* 退款订单信息
*/
@PreAuthorize("hasAuthority('ENT_REFUND_ORDER_VIEW')")
@RequestMapping(value="/{refundOrderId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("refundOrderId") String refundOrderId) {
RefundOrder refundOrder = refundOrderService.getById(refundOrderId);
if (refundOrder == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(refundOrder);
}
/**
* 退款列表数据导出
*/
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() {
try {
RefundOrder refundOrder = getObject(RefundOrder.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<RefundOrder> wrapper = RefundOrder.gw();
IPage<RefundOrder> pages = refundOrderService.pageList(getIPage(true), wrapper, refundOrder, paramJSON);
List<JSONObject> newList = new LinkedList<>();
for (RefundOrder order:pages.getRecords()) {
JSONObject object = (JSONObject) JSONObject.toJSON(order);
object.put("payAmount", AmountUtil.convertCent2Dollar(order.getPayAmount()));
object.put("refundAmount", AmountUtil.convertCent2Dollar(order.getRefundAmount()));
object.put("refundFeeAmount", AmountUtil.convertCent2Dollar(order.getRefundFeeAmount()));
newList.add(object);
}
List<RefundOrderExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), RefundOrderExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "退款订单", "退款订单", RefundOrderExportExcel.class, "退款订单", response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出订单失败!");
}
}
@PreAuthorize("hasAuthority('ENT_REFUND_ORDER_COUNT')")
@GetMapping("/count")
public ApiRes count() {
RefundOrder refundOrder = getObject(RefundOrder.class);
refundOrder.setAgentNo(null);
JSONObject paramJSON = getReqParamJSON();
// 查询支付、退款金额 笔数
PayOrderCount orderCount = statsTradeService.selectTotalByTransaction(paramJSON, Collections.emptyList());
return ApiRes.ok(orderCount);
}
}

View File

@@ -0,0 +1,112 @@
package com.jeequan.jeepay.mgr.ctrl.order;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.export.TransferOrderExportExcel;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.db.entity.TransferOrderEntity;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.TransferOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 转账订单api
*
* @author terrfly
*
* @date 2021/8/13 10:52
*/
@RestController
@RequestMapping("/api/transferOrders")
public class TransferOrderController extends CommonCtrl {
@Autowired private TransferOrderService transferOrderService;
/** list **/
@PreAuthorize("hasAuthority('ENT_TRANSFER_ORDER_LIST')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
TransferOrderEntity transferOrder = getObject(TransferOrderEntity.class);
IPage<TransferOrderEntity> pages = transferOrderService.pageList(getIPage(),transferOrder);
return ApiRes.page(pages);
}
/** detail **/
@PreAuthorize("hasAuthority('ENT_TRANSFER_ORDER_VIEW')")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") String transferId) {
TransferOrderEntity refundOrder = transferOrderService.getById(transferId);
if (refundOrder == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(refundOrder);
}
/**
* @author: xiaoyu
* @date: 2022/1/14 9:45
* @describe: 转账数据导出
*/
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() {
try {
TransferOrderEntity transferOrder = getObject(TransferOrderEntity.class);
IPage<TransferOrderEntity> pages = transferOrderService.pageList(getIPage(true), transferOrder);
List<JSONObject> newList = new LinkedList<>();
for (TransferOrderEntity order:pages.getRecords()) {
JSONObject object = (JSONObject) JSONObject.toJSON(order);
object.put("entryType",order.getEntryType().replaceAll("_",""));
object.put("amount", AmountUtil.convertCent2Dollar(order.getAmount()));
newList.add(object);
}
List<TransferOrderExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), TransferOrderExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "转账订单", "转账订单", TransferOrderExportExcel.class, "转账订单", response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出订单失败!");
}
}
/**
* @author: xiaoyu
* @date: 2023/4/26 14:55
* @describe: 数据统计
*/
@PreAuthorize("hasAuthority('ENT_TRANSFER_ORDER_COUNT')")
@RequestMapping(value="/count", method = RequestMethod.GET)
public ApiRes count() {
TransferOrderEntity transferOrder = getObject(TransferOrderEntity.class);
LambdaQueryWrapper<TransferOrderEntity> wrapper = TransferOrderEntity.gw();
transferOrder.setState(null);
// 条件参数
transferOrderService.selectParams(wrapper, transferOrder);
Map result = transferOrderService.queryCount(wrapper);
return ApiRes.ok(result);
}
}

View File

@@ -0,0 +1,144 @@
package com.jeequan.jeepay.mgr.ctrl.payconfig;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.bizcommons.manage.MchPayPassageConfigManage;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.applyment.ApplymentBasicInfo;
import com.jeequan.jeepay.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.core.utils.JsonKit;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.db.entity.MchPayPassage;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchPayPassageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/****
* 新版商户支付通道配置ctrl
*
* @author terrfly
*
* @date 2022/3/30 16:37
*/
@RestController
@RequestMapping("/api/mch/payPassages")
public class MchPayPassageConfigController extends CommonCtrl {
@Autowired private MchPayPassageService mchPayPassageService;
@Autowired private MchPayPassageConfigManage mchPayPassageConfigManage;
@Autowired private MchApplymentService mchApplymentService;
@Autowired
private IMQSender mqSender;
/**
* 支付方式 <--> 通道配置
* 左侧列表(支付方式)
*
* **/
@GetMapping
public ApiRes list() {
String appId = getValStringRequired("appId");
String wayCode = getValString("wayCode");
String wayName = getValString("wayName");
return mchPayPassageConfigManage.queryPaywayList(appId, wayCode, wayName, null, null, getIPage());
}
/**
* 支付方式 <--> 通道配置
* 右侧列表(可用的支付接口)
*
* **/
@GetMapping("/availablePayInterface/{appId}/{wayCode}")
public ApiRes availablePayInterface(@PathVariable("appId") String appId, @PathVariable("wayCode") String wayCode) {
return mchPayPassageConfigManage.availablePayInterface(appId, wayCode);
}
/**
* 更新商户使用的通道信息
*/
@PostMapping("/mchPassage")
@MethodLog(remark = "更新商户支付通道")
public ApiRes updatePassage() {
String appId = getValStringRequired("appId");
String ifCode = getValStringRequired("ifCode");
String wayCode = getValStringRequired("wayCode");
Byte state = getValByteRequired("state");
mchPayPassageService.updateMchPassageState(appId, wayCode, ifCode, state);
return ApiRes.ok();
}
/**
* 查询商户应用支付通道是否配置
* 用于进件成功一键配置到应用,点击按钮时检查进件记录中包含的支付方式是否在该应用下已配置其他渠道
*/
@GetMapping("/exist/{applyId}/{appId}")
public ApiRes exist(@PathVariable("applyId") String applyId, @PathVariable("appId") String appId) {
MchApplyment tbMchApplyment = mchApplymentService.getById(applyId);
if (tbMchApplyment == null || tbMchApplyment.getState() != MchApplyment.STATE_SUCCESS) {
return ApiRes.customFail("进件记录不存在或进件状态未成功");
}
// 获取当前进件记录费率配置
ApplymentBasicInfo applymentBasicInfo = JSONObject.parseObject(tbMchApplyment.getApplyDetailInfo(), ApplymentBasicInfo.class);
// 费率
List<PaywayFee> paywayFeeList = applymentBasicInfo.getPaywayFeeList();
// 费率为空,进件成功一键配置到应用将不执行配置费率和通道,可直接返回
if (CollUtil.isEmpty(paywayFeeList)) {
return ApiRes.ok();
}
// 获取费率配置的支付方式
List<String> wayCodeList = new ArrayList<>();
paywayFeeList.forEach(paywayFee -> {
wayCodeList.add(paywayFee.getWayCode());
});
// 支付方式已配置其他渠道
List<MchPayPassage> payPassages = mchPayPassageService.list(MchPayPassage.gw()
.eq(MchPayPassage::getAppId, appId)
.ne(MchPayPassage::getIfCode, tbMchApplyment.getIfCode())
.in(MchPayPassage::getWayCode, wayCodeList));
if (CollUtil.isNotEmpty(payPassages)) {
return ApiRes.ok(JsonKit.newJson("existMchPayPassage", CS.YES));
}
return ApiRes.ok();
}
/**
* 进件成功一键配置到应用,更新商户支付通道
*/
@MethodLog(remark = "进件成功,一键配置商户支付信息")
@PostMapping("/applyment/{applyId}/{appId}")
public ApiRes updateMchPayPassageByApplyment(@PathVariable("applyId") String applyId, @PathVariable("appId") String appId) {
// AutoConfigMchAppPayInfoResult result = mchApplymentService.autoConfigMchAppPayInfo(applyId, appId, getValByteRequired("isOverWrite") == CS.YES);
//
// if (StringUtils.isNotBlank(result.getErrMsg())) {
// return ApiRes.customFail(result.getErrMsg());
// }
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,550 @@
package com.jeequan.jeepay.mgr.ctrl.payconfig;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeequan.jeepay.components.mq.model.ResetIsvMchAppInfoConfigMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.IsvUserConn;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.params.IsvParams;
import com.jeequan.jeepay.core.model.params.NormalMchParams;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.IsvInfoService;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.PayInterfaceConfigService;
import com.jeequan.jeepay.service.impl.RateConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/***
* 支付配置
*
* @author terrfly
*
* @date 2022/3/21 0:13
*/
@RestController
@RequestMapping("/api/payConfig")
public class PayConfigController extends CommonCtrl {
@Autowired
private MchAppService mchAppService;
@Autowired
private PayInterfaceConfigService payInterfaceConfigService;
@Autowired
private RateConfigService rateConfigService;
@Autowired
private IMQSender mqSender;
@Autowired
private IsvInfoService isvInfoService;
/**
* 查询可用的支付接口
* <p>
* 使用功能项目: 参数及费率的填写
* 服务商查询全部支付接口
* 服务商查询服务商开启的支付接口
**/
@GetMapping("/ifCodes")
public ApiRes ifCodes() {
// 搜索条件
String ifName = getValString("ifName");
// infoId 运营平台 发起 商户进件, 此时infoId是商户的所属 商户ID
String infoId = getValStringRequired("infoId");
// 设置类型
String configMode = getValStringRequired("configMode");
// 支付接口列表
LambdaQueryWrapper<PayInterfaceDefine> lambdaQueryWrapper = PayInterfaceDefine.gw();
lambdaQueryWrapper.eq(PayInterfaceDefine::getState, CS.YES); // 查询可用的支付接口列表
lambdaQueryWrapper.like(StringUtils.isNotEmpty(ifName), PayInterfaceDefine::getIfName, ifName);
String infoType = null;
// 配置服务商 支付参数
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
lambdaQueryWrapper.eq(PayInterfaceDefine::getIsIsvMode, CS.YES); // 查询支持服务商的接口。
//查询全部
infoType = CS.SYS_ROLE_TYPE.ISV;
} else if (RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.AGENT;
}
final List<String> ifCodes = new ArrayList<>();
// 进件 支付参数
if (RateConfig.CONFIG_MODE_MGRAPPLYMENT.equals(configMode)) {
lambdaQueryWrapper.eq(PayInterfaceDefine::getIsSupportApplyment, CS.YES); // 查询支持进件的接口
MchInfo mchInfo = mchInfoService.getById(infoId);
// CURRENT 查询将返回空
if (mchInfo == null || StringUtils.isEmpty(mchInfo.getAgentNo())) {
return ApiRes.ok();
}
// 根据渠道号获取ifCode
Map<String, IsvUserConn> ifCodeMap = isvInfoService.getIsvUserConn(CS.SYS_ROLE_TYPE.MCH, mchInfo.getMchNo(), CS.YES);
ifCodes.addAll(ifCodeMap.keySet());
// if (ifCodes.isEmpty()) { // 没有可用的接口
// return ApiRes.ok(ifCodes);
// }
//
// lambdaQueryWrapper.in(PayInterfaceDefine::getIfCode, ifCodes);
}
// 运营平台 配置 服务商费率 【显示 服务商的所有接口】
if (RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)) {
lambdaQueryWrapper.eq(PayInterfaceDefine::getIsIsvMode, CS.YES); // 查询支持服务商的接口。
// 查询当前服务商
AgentInfo agentInfo = agentInfoService.getById(infoId);
Map<String, IsvUserConn> ifCodeMap = isvInfoService.getIsvUserConn(CS.SYS_ROLE_TYPE.AGENT, agentInfo.getAgentNo(), null);
ifCodes.addAll(ifCodeMap.keySet());
// if (ifCodes.isEmpty()) { // 没有可用的接口
// return ApiRes.ok(ifCodes);
// }
// lambdaQueryWrapper.in(PayInterfaceDefine::getIfCode, ifCodes);
}
// 是否是进件
boolean isProcessApplyment = RateConfig.CONFIG_MODE_MGRAPPLYMENT.equals(configMode)
|| RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode)
|| RateConfig.CONFIG_MODE_MCHAPPLYMENT.equals(configMode);
// 运营平台 配置 商户费率 【显示 服务商的所有接口】
if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.MCH;
// 查询当前用户/商户
// MchAppEntity mchAppEntity = mchAppService.getById(infoId);
MchInfo mchInfo = mchInfoService.getById(infoId);
// 特约商户
if (mchInfo.getType() != CS.MCH_TYPE_ISVSUB) {
// 普通商户
lambdaQueryWrapper.eq(PayInterfaceDefine::getIsMchMode, CS.YES); // 查询支持普通商户的接口。
}
}
// 进件操作,只显示关联的通道信息
if (isProcessApplyment) {
infoType = CS.SYS_ROLE_TYPE.MCH;
Map<String, IsvUserConn> ifCodeStateMap = isvInfoService.getIsvUserConn(infoType, infoId, CS.YES);
if (!ifCodeStateMap.isEmpty()) {
lambdaQueryWrapper.in(PayInterfaceDefine::getIfCode, ifCodes);
}
}
lambdaQueryWrapper.orderByAsc(PayInterfaceDefine::getCreatedAt);
List<PayInterfaceDefine> list = payInterfaceDefineService.list(lambdaQueryWrapper);
if (list.isEmpty()) {
return ApiRes.ok(list);
}
Map<String, IsvUserConn> ifCodeStateMap = isvInfoService.getIsvUserConn(infoType, infoId, null);
if (CollUtil.isEmpty(ifCodeStateMap)) {
return ApiRes.ok(list);
}
// 是否已配置
list.forEach(r -> {
String ifCode = r.getIfCode();
Optional.ofNullable(ifCodeStateMap.get(ifCode)).ifPresent(it -> {
r.addExt("configState", CS.YES);
});
});
return ApiRes.ok(list);
}
/**
* 查询已经配置的参数信息
*/
@GetMapping(value = "/interfaceSavedConfigs")
public ApiRes interfaceSavedConfigs() {
String ifCode = getValStringRequired("ifCode"); // ifCode
String infoId = getValStringRequired("infoId"); // infoId
String configMode = getValStringRequired("configMode"); // 设置类型
// 是否查询真实配置信息
boolean queryConfigRealInfos = getValByteDefault("qcreals", CS.NO) == CS.YES;
PayInterfaceDefine payInterfaceDefine = payInterfaceDefineService.getById(ifCode);
String infoType = null;
JSONArray ifDefineArray = null;
Byte mchType = null; // 商户类型
Byte isvIsOpenApplyment = 0; // 服务商是否开启进件
// 运营平台 配置服务商信息 --》
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.ISV;
try {
ifDefineArray = JSON.parseArray(payInterfaceDefine.getIsvParams());
} catch (Exception e) {
ifDefineArray = new JSONArray();
}
}
// 运营平台 配置商户应用信息
else if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.MCH_APP;
MchInfo mchInfo = mchInfoService.getById(infoId);
mchType = mchInfo.getType();
ifDefineArray = JSON.parseArray(mchType == CS.MCH_TYPE_NORMAL ? payInterfaceDefine.getNormalMchParams() : payInterfaceDefine.getIsvsubMchParams());
}
// 运营平台 配置服务商信息
else if (RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.AGENT;
AgentInfo agentInfo = agentInfoService.getById(infoId);
if (agentInfo != null && !ObjectUtils.isEmpty(agentInfo.getIsvNo())) {
PayInterfaceConfig isvIfConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.ISV, agentInfo.getIsvNo(), ifCode);
isvIsOpenApplyment = isvIfConfig != null ? isvIfConfig.getIsOpenApplyment() : 0;
}
}
// 查询已经配置的信息
PayInterfaceConfig payInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(infoType, infoId, ifCode);
payInterfaceConfig = Optional.ofNullable(payInterfaceConfig).orElse(new PayInterfaceConfig());
// 处理脱敏数据
if (StringUtils.isNotEmpty(payInterfaceConfig.getIfParams())) {
// 查询真实数据 && base64脱敏
if (queryConfigRealInfos) {
payInterfaceConfig.setIfParams(Base64.encode(payInterfaceConfig.getIfParams()));
} else {
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
IsvParams isvParams = IsvParams.factory(ifCode, payInterfaceConfig.getIfParams());
if (isvParams != null) {
payInterfaceConfig.setIfParams(isvParams.deSenData());
}
} else if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode) && mchType == CS.MCH_TYPE_NORMAL) {
NormalMchParams isvParams = NormalMchParams.factory(ifCode, payInterfaceConfig.getIfParams());
if (isvParams != null) {
payInterfaceConfig.setIfParams(isvParams.deSenData());
}
}
}
}
payInterfaceConfig.addExt("ifDefineArray", ifDefineArray);
payInterfaceConfig.addExt("mchType", mchType);
payInterfaceConfig.addExt("configPageType", payInterfaceDefine.getConfigPageType());
payInterfaceConfig.addExt("isSupportApplyment", payInterfaceDefine.getIsSupportApplyment()); // 支付接口是否支持进件
payInterfaceConfig.addExt("isSupportCheckBill", payInterfaceDefine.getIsSupportCheckBill()); // 支付接口是否支持对账
payInterfaceConfig.addExt("isSupportCashout", payInterfaceDefine.getIsSupportCashout()); // 支付接口是否支持提现
payInterfaceConfig.addExt("isvIsOpenApplyment", isvIsOpenApplyment); // 上级服务商是否开启进件
Map<String, String> channelTypeMap = new HashMap<>();
// 默认禁用
channelTypeMap.put("type_0", "-1");
channelTypeMap.put("type_1", "-1");
channelTypeMap.put("type_2", "-1");
if (payInterfaceDefine.getChannelTypes() != null) {
for (String s : payInterfaceDefine.getChannelTypes().split(",")) {
if (s.equals("0")) {
// 可选
channelTypeMap.put("type_0", "0");
}
if (s.equals("1")) {
// 可选
channelTypeMap.put("type_1", "0");
}
if (s.equals("2")) {
// 可选
channelTypeMap.put("type_2", "0");
}
}
}
if (payInterfaceConfig.getChannelTypes() != null) {
for (String s : payInterfaceConfig.getChannelTypes().split(",")) {
if (s.equals("0")) {
// 可选
channelTypeMap.put("type_0", "1");
}
if (s.equals("1")) {
// 可选
channelTypeMap.put("type_1", "1");
}
if (s.equals("2")) {
// 可选
channelTypeMap.put("type_2", "1");
}
}
}
payInterfaceConfig.addExt("channelTypeOption", channelTypeMap);
return ApiRes.ok(payInterfaceConfig);
}
/**
* 更新支付参数
**/
@PostMapping("/interfaceParams")
@MethodLog(remark = "更新支付参数")
public ApiRes saveOrUpdate() {
PayInterfaceConfig payInterfaceConfig = getObject(PayInterfaceConfig.class);
String configMode = payInterfaceConfig.extv().getString("configMode"); // 设置类型
String infoType = null;
// 运营平台 配置服务商信息 --》
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.ISV;
}
// 运营平台 配置商户应用
else if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.MCH_APP;
}
// 运营平台 配置服务商
else if (RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.AGENT;
}
payInterfaceConfig.setInfoType(infoType);
//添加更新者信息
Long userId = getCurrentUser().getSysUser().getSysUserId();
String realName = getCurrentUser().getSysUser().getRealname();
payInterfaceConfig.setUpdatedUid(userId);
payInterfaceConfig.setUpdatedBy(realName);
//根据 服务商号、接口类型 获取商户参数配置
PayInterfaceConfig dbRecord = payInterfaceConfigService.getByInfoIdAndIfCode(payInterfaceConfig.getInfoType(), payInterfaceConfig.getInfoId(), payInterfaceConfig.getIfCode());
//若配置存在为saveOrUpdate添加ID第一次配置添加创建者
if (dbRecord != null) {
payInterfaceConfig.setId(dbRecord.getId());
// 合并支付参数
payInterfaceConfig.setIfParams(StringKit.marge(dbRecord.getIfParams(), payInterfaceConfig.getIfParams(), dbRecord.getIfCode()));
} else {
payInterfaceConfig.setCreatedUid(userId);
payInterfaceConfig.setCreatedBy(realName);
}
boolean result = payInterfaceConfigService.saveOrUpdate(payInterfaceConfig);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, "配置失败");
}
// 推送mq到目前节点进行更新数据
// 运营平台 配置服务商信息 --》
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_ISV_INFO, payInterfaceConfig.getInfoId(), null, null));
}
return ApiRes.ok();
}
/**
* 查询商户应用支付参数、费率是否配置
* 用于发起进件 自动配置到应用时的提示
*/
@GetMapping("/existPayParams/{appId}/{ifCode}")
public ApiRes existPayParams(@PathVariable("appId") String appId, @PathVariable("ifCode") String ifCode) {
// Integer range = getValInteger("range");
// String mccCode = getValString("mccCode");
// String isvNo = getValString("isvNo");
//
// // 应用参数配置
// PayInterfaceConfig interfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.MCH_APP, appId, ifCode);
// if (interfaceConfig == null) {
// return ApiRes.ok();
// }
//
// if (StringUtils.isNotBlank(interfaceConfig.getIfParams()) && !interfaceConfig.getIfParams().equals("{}")) {
// return ApiRes.ok(JsonKit.newJson("existMchParams", CS.YES));
// }
//
// // 费率配置
// Map<String, PaywayFee> paywayFeeMap = rateConfigService.queryPaywayFeeMap(appId + "_" + RateConfig.MCHRATE, CS.SYS_ROLE_TYPE.MCH_APP, ifCode, range, mccCode, isvNo);
// if (paywayFeeMap != null && StringUtils.isNotBlank(interfaceConfig.getIfParams()) && !interfaceConfig.getIfParams().equals("{}")) {
// return ApiRes.ok(JsonKit.newJson("existMchParams", CS.YES));
// }
return ApiRes.ok();
}
// /**
// * @author deng
// * 保存支付参数实例
// */
// @PostMapping("/saveConfigAlternative")
// public ApiRes saveConfigAlternative() {
// com.jeequan.jeepay.db.entity.MchPayInterfaceConfig mchPayInterfaceConfig = getObject(com.jeequan.jeepay.db.entity.MchPayInterfaceConfig.class);
//
// String configMode = mchPayInterfaceConfig.extv().getString("configMode"); // 设置类型
//
// String infoType = CS.SYS_ROLE_TYPE.ISV;
//
// mchPayInterfaceConfig.setInfoType(infoType);
//
// //添加更新者信息
// Long userId = getCurrentUser().getSysUser().getSysUserId();
// String realName = getCurrentUser().getSysUser().getRealname();
// mchPayInterfaceConfig.setUpdatedUid(userId);
// mchPayInterfaceConfig.setUpdatedBy(realName);
// if (mchPayInterfaceConfig.getId() != null) {
// com.jeequan.jeepay.db.entity.MchPayInterfaceConfig existData = this.mchPayInterfaceConfig.getById(mchPayInterfaceConfig.getId());
// mchPayInterfaceConfig.setIfParams(StringKit.marge(mchPayInterfaceConfig.getIfParams(), existData.getIfParams(), mchPayInterfaceConfig.getIfCode()));
// }
//
// boolean result = this.mchPayInterfaceConfig.saveOrUpdate(mchPayInterfaceConfig);
// if (!result) {
// return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, "配置失败");
// }
//
// //根据 服务商号、接口类型获取正在使用的通道配置信息,如果存在并且修改的是这一个
// PayInterfaceConfig existPayInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(mchPayInterfaceConfig.getInfoType(), mchPayInterfaceConfig.getInfoId(), mchPayInterfaceConfig.getIfCode());
// //若配置存在为saveOrUpdate添加ID第一次配置添加创建者
//
// if (existPayInterfaceConfig != null
// && mchPayInterfaceConfig.getId().equals(existPayInterfaceConfig.getAltId())) {
// existPayInterfaceConfig.setIfParams(mchPayInterfaceConfig.getIfParams());
// payInterfaceConfigService.updateById(existPayInterfaceConfig);
// }
//
// // 运营平台 配置服务商信息 --》
// mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_ISV_INFO, mchPayInterfaceConfig.getInfoId(), null, null));
//
//// if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
//// mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_ISV_INFO, payInterfaceConfigAlternative.getInfoId(), null, null));
//// } else if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)) { // 配置商户参数
//// MchAppEntity mchAppEntity = mchAppService.getById(payInterfaceConfigAlternative.getInfoId());
//// mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_MCH_APP, null, mchAppEntity.getMchNo(), payInterfaceConfigAlternative.getInfoId()));
//// }
//
// return ApiRes.ok();
// }
//
// /**
// * @author deng
// * 返回支付参数实例的分页数据
// */
// @GetMapping("/configAlternativeList")
// public ApiRes configAlternativeList() {
// // 渠道编码必传
// String ifCode = getValStringRequired("ifCode");
// // 服务商(原服务商)编号
// String isvNo = getValStringRequired("isvNo");
//
// String alias = getValString("alias");
//
// Page<com.jeequan.jeepay.db.entity.MchPayInterfaceConfig> iPage = getIPage(false);
//
// Page<com.jeequan.jeepay.db.entity.MchPayInterfaceConfig> page = mchPayInterfaceConfig
// .wrapperByIsvNo(isvNo, ifCode)
// .eq(!ObjectUtils.isEmpty(alias), com.jeequan.jeepay.db.entity.MchPayInterfaceConfig::getAlias, alias)
// .orderByDesc(com.jeequan.jeepay.db.entity.MchPayInterfaceConfig::getId)
// .page(iPage);
//
// PayInterfaceConfig payInterfaceConfigUse = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.ISV, isvNo, ifCode);
//
// page.getRecords().forEach(item -> {
// int inUseFlag = (payInterfaceConfigUse != null && Objects.equals(payInterfaceConfigUse.getAltId(), item.getId())) ? 1 : 0;
// item.setInUseFlag(inUseFlag);
// });
//
// return ApiRes.ok(page);
// }
//
// @PostMapping("/chosenConfigAlternative")
// public ApiRes configAlternativeUse() {
// Long altId = getValLongRequired("altId");
// // 渠道编码必传
// String ifCode = getValStringRequired("ifCode");
// // 服务商(原服务商)编号
// String isvNo = getValStringRequired("isvNo");
//
// com.jeequan.jeepay.db.entity.MchPayInterfaceConfig alternativeData = mchPayInterfaceConfig.getById(altId);
// Assert.notNull(alternativeData, "渠道实例不存在");
//
// PayInterfaceConfig payInterfaceConfig = mchInfoConverter.toConfig(alternativeData);
// payInterfaceConfig.setAltId(alternativeData.getId());
//
// //添加更新者信息
// Long userId = getCurrentUser().getSysUser().getSysUserId();
// String realName = getCurrentUser().getSysUser().getRealname();
// payInterfaceConfig.setUpdatedUid(userId);
// payInterfaceConfig.setUpdatedBy(realName);
//
// //根据 服务商号、接口类型 获取商户参数配置
// PayInterfaceConfig configData = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.ISV, isvNo, ifCode);
// //若配置存在为saveOrUpdate添加ID第一次配置添加创建者
// if (configData != null) {
// // 合并支付参数
// payInterfaceConfig.setIfParams(StringKit.marge(configData.getIfParams(), payInterfaceConfig.getIfParams(), configData.getIfCode()));
// payInterfaceConfig.setId(configData.getId());
// } else {
// payInterfaceConfig.setIfParams(alternativeData.getIfParams());
// payInterfaceConfig.setCreatedUid(userId);
// payInterfaceConfig.setCreatedBy(realName);
// }
//
// boolean result = payInterfaceConfigService.saveOrUpdate(payInterfaceConfig);
// if (!result) {
// return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, "配置失败");
// }
//
//// isvUserConnService.getSuperiorConnInfo()
//
// // 推送mq到目前节点进行更新数据
//
// // 运营平台 配置服务商信息 --》
//// mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_ISV_INFO, payInterfaceConfig.getInfoId(), null, null));
//
//// if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
////
//// } else if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)) { // 配置商户参数
////
//// MchAppEntity mchAppEntity = mchAppService.getById(payInterfaceConfig.getInfoId());
//// mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_MCH_APP, null, mchAppEntity.getMchNo(), payInterfaceConfig.getInfoId()));
//// }
//
// return ApiRes.ok();
// }
}

View File

@@ -0,0 +1,250 @@
package com.jeequan.jeepay.mgr.ctrl.payconfig;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PayInterfaceConfig;
import com.jeequan.jeepay.db.entity.PayInterfaceDefine;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.PayInterfaceConfigService;
import com.jeequan.jeepay.service.impl.PayOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* 支付接口定义管理类
*
* @author zhuxiao
* @since 2021-04-27 15:50
*/
@RestController
@RequestMapping("api/payIfDefines")
public class PayInterfaceDefineController extends CommonCtrl {
@Autowired private PayOrderService payOrderService;
@Autowired private PayInterfaceConfigService payInterfaceConfigService;
/**
* @author ZhuXiao
* @Description: list
* @since 15:51 2021/4/27
*/
@PreAuthorize("hasAuthority('ENT_PC_IF_DEFINE_LIST')")
@GetMapping
public ApiRes list() {
PayInterfaceDefine queryRecord = getObject(PayInterfaceDefine.class);
LambdaQueryWrapper<PayInterfaceDefine> lambdaQueryWrapper = PayInterfaceDefine.gw();
lambdaQueryWrapper.eq(queryRecord.getState() != null , PayInterfaceDefine::getState, queryRecord.getState());
lambdaQueryWrapper.eq(queryRecord.getIsSupportApplyment() != null , PayInterfaceDefine::getIsSupportApplyment, queryRecord.getIsSupportApplyment());
lambdaQueryWrapper.eq(queryRecord.getIsSupportCheckBill() != null , PayInterfaceDefine::getIsSupportCheckBill, queryRecord.getIsSupportCheckBill());
lambdaQueryWrapper.eq(queryRecord.getIsOpenCheckBill() != null , PayInterfaceDefine::getIsOpenCheckBill, queryRecord.getIsOpenCheckBill());
lambdaQueryWrapper.eq(queryRecord.getIsSupportCashout() != null , PayInterfaceDefine::getIsSupportCashout, queryRecord.getIsSupportCashout());
lambdaQueryWrapper.eq(queryRecord.getIsOpenCashout() != null , PayInterfaceDefine::getIsOpenCashout, queryRecord.getIsOpenCashout());
lambdaQueryWrapper.orderByAsc(PayInterfaceDefine::getCreatedAt);
List<PayInterfaceDefine> list = payInterfaceDefineService.list(lambdaQueryWrapper);
return ApiRes.ok(list);
}
/**
* 分页查询
* @return
*/
@GetMapping("/listPage")
public ApiRes listPage() {
PayInterfaceDefine queryRecord = getObject(PayInterfaceDefine.class);
LambdaQueryWrapper<PayInterfaceDefine> lambdaQueryWrapper = PayInterfaceDefine.gw();
lambdaQueryWrapper.eq(queryRecord.getState() != null , PayInterfaceDefine::getState, queryRecord.getState());
lambdaQueryWrapper.eq(queryRecord.getIsSupportApplyment() != null , PayInterfaceDefine::getIsSupportApplyment, queryRecord.getIsSupportApplyment());
lambdaQueryWrapper.eq(queryRecord.getIsSupportCheckBill() != null , PayInterfaceDefine::getIsSupportCheckBill, queryRecord.getIsSupportCheckBill());
lambdaQueryWrapper.eq(queryRecord.getIsOpenCheckBill() != null , PayInterfaceDefine::getIsOpenCheckBill, queryRecord.getIsOpenCheckBill());
lambdaQueryWrapper.eq(queryRecord.getIsSupportCashout() != null , PayInterfaceDefine::getIsSupportCashout, queryRecord.getIsSupportCashout());
lambdaQueryWrapper.eq(queryRecord.getIsOpenCashout() != null , PayInterfaceDefine::getIsOpenCashout, queryRecord.getIsOpenCashout());
lambdaQueryWrapper.orderByAsc(PayInterfaceDefine::getCreatedAt);
Page<PayInterfaceDefine> page = payInterfaceDefineService.page(getIPage(), lambdaQueryWrapper);
return ApiRes.ok(page);
}
/**
* @author ZhuXiao
* @Description: detail
* @since 15:51 2021/4/27
*/
@PreAuthorize("hasAnyAuthority('ENT_PC_IF_DEFINE_VIEW', 'ENT_PC_IF_DEFINE_EDIT')")
@GetMapping("/{ifCode}")
public ApiRes detail(@PathVariable("ifCode") String ifCode) {
return ApiRes.ok(payInterfaceDefineService.getById(ifCode));
}
/**
* @author ZhuXiao
* @Description: add
* @since 15:51 2021/4/27
*/
@PreAuthorize("hasAuthority('ENT_PC_IF_DEFINE_ADD')")
@PostMapping
@MethodLog(remark = "新增支付接口")
public ApiRes add() {
PayInterfaceDefine payInterfaceDefine = getObject(PayInterfaceDefine.class);
// 查询if_code是否已存在
PayInterfaceDefine define = payInterfaceDefineService.getById(payInterfaceDefine.getIfCode());
if (define != null) {
throw new BizException("当前接口代码已存在,请求改后重试");
}
JSONArray jsonArray = new JSONArray();
String[] wayCodes = getValStringRequired("wayCodeStrs").split(",");
for (String wayCode : wayCodes) {
JSONObject object = new JSONObject();
object.put("wayCode", wayCode);
jsonArray.add(object);
}
payInterfaceDefine.setWayCodes(jsonArray);
boolean result = payInterfaceDefineService.save(payInterfaceDefine);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
return ApiRes.ok();
}
/**
* @author ZhuXiao
* @Description: update
* @since 15:51 2021/4/27
*/
@PreAuthorize("hasAuthority('ENT_PC_IF_DEFINE_EDIT')")
@PutMapping("/{ifCode}")
@MethodLog(remark = "更新支付接口")
public ApiRes update(@PathVariable("ifCode") String ifCode) {
PayInterfaceDefine payInterfaceDefine = getObject(PayInterfaceDefine.class);
payInterfaceDefine.setIfCode(ifCode);
JSONArray jsonArray = new JSONArray();
String[] wayCodes = getValStringRequired("wayCodeStrs").split(",");
for (String wayCode : wayCodes) {
JSONObject object = new JSONObject();
object.put("wayCode", wayCode);
jsonArray.add(object);
}
payInterfaceDefine.setWayCodes(jsonArray);
boolean result = payInterfaceDefineService.updateById(payInterfaceDefine);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @author ZhuXiao
* @Description: delete
* @since 15:52 2021/4/27
*/
@PreAuthorize("hasAuthority('ENT_PC_IF_DEFINE_DEL')")
@DeleteMapping("/{ifCode}")
@MethodLog(remark = "删除支付接口")
public ApiRes delete(@PathVariable("ifCode") String ifCode) {
// 校验该支付方式是否有服务商或商户配置参数或者已有订单
if (payInterfaceConfigService.count(PayInterfaceConfig.gw().eq(PayInterfaceConfig::getIfCode, ifCode)) > 0
|| payOrderService.count(PayOrder.gw().eq(PayOrder::getIfCode, ifCode)) > 0) {
throw new BizException("该支付接口已有服务商或商户配置参数或已发生交易,无法删除!");
}
boolean result = payInterfaceDefineService.removeById(ifCode);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
}
return ApiRes.ok();
}
/** 查询克隆模式的信息, 比如数量名称等 **/
@PreAuthorize("hasAnyAuthority('ENT_PC_IF_DEFINE_EDIT')")
@GetMapping("/cloneInfos/{ifCode}")
public ApiRes cloneInfos(@PathVariable("ifCode") String ifCode) {
long count = payInterfaceDefineService.count(PayInterfaceDefine.gw().likeRight(PayInterfaceDefine::getIfCode, (ifCode + "_") ));
PayInterfaceDefine result = new PayInterfaceDefine();
result.setIfCode(ifCode + "_" + (count + 1));
result.setIfName(payInterfaceDefineService.getById(ifCode).getIfName() + "_副本" + (count + 1));
return ApiRes.ok(result);
}
/** 同步参数到所有副本 **/
@PreAuthorize("hasAnyAuthority('ENT_PC_IF_DEFINE_EDIT')")
@PutMapping("/syncConfigInfo2CloneIfCodes/{ifCode}")
public ApiRes syncConfigInfo2CloneIfCodes(@PathVariable("ifCode") String ifCode) {
List<PayInterfaceDefine> clonedList = payInterfaceDefineService.list(PayInterfaceDefine.gw().select(PayInterfaceDefine::getIfCode).likeRight(PayInterfaceDefine::getIfCode, (ifCode + "_") ));
if(clonedList.isEmpty()){
throw new BizException("不存在副本列表!");
}
// ifCode列表
List<String> cloneListByIfcode = new ArrayList<>();
for (PayInterfaceDefine payInterfaceDefineItem : clonedList) {
cloneListByIfcode.add(payInterfaceDefineItem.getIfCode());
}
// 当前接口信息
PayInterfaceDefine payInterfaceDefine = payInterfaceDefineService.getById(ifCode);
// 更新的项目: 支持部分和参数部分, 其他的不做更新
PayInterfaceDefine updateRecord = new PayInterfaceDefine();
updateRecord.setIsMchMode(payInterfaceDefine.getIsMchMode());
updateRecord.setIsIsvMode(payInterfaceDefine.getIsIsvMode());
updateRecord.setIsSupportApplyment(payInterfaceDefine.getIsSupportApplyment());
updateRecord.setIsSupportCheckBill(payInterfaceDefine.getIsSupportCheckBill());
updateRecord.setIsSupportCashout(payInterfaceDefine.getIsSupportCashout());
updateRecord.setConfigPageType(payInterfaceDefine.getConfigPageType());
updateRecord.setIsvParams(payInterfaceDefine.getIsvParams());
updateRecord.setIsvsubMchParams(payInterfaceDefine.getIsvsubMchParams());
updateRecord.setNormalMchParams(payInterfaceDefine.getNormalMchParams());
updateRecord.setWayCodes(payInterfaceDefine.getWayCodes());
updateRecord.setChannelFeeCalModel(payInterfaceDefine.getChannelFeeCalModel());
// 更新
payInterfaceDefineService.update(updateRecord, PayInterfaceDefine.gw().in(PayInterfaceDefine::getIfCode, cloneListByIfcode));
return ApiRes.ok();
}
@GetMapping("/getPayIfDefines")
public ApiRes getPayIfDefines() {
PayInterfaceDefine queryRecord = getObject(PayInterfaceDefine.class);
LambdaQueryWrapper<PayInterfaceDefine> lambdaQueryWrapper = PayInterfaceDefine.gw();
lambdaQueryWrapper.eq(queryRecord.getState() != null , PayInterfaceDefine::getState, queryRecord.getState());
lambdaQueryWrapper.eq(queryRecord.getIsSupportApplyment() != null , PayInterfaceDefine::getIsSupportApplyment, queryRecord.getIsSupportApplyment());
lambdaQueryWrapper.eq(queryRecord.getIsSupportCheckBill() != null , PayInterfaceDefine::getIsSupportCheckBill, queryRecord.getIsSupportCheckBill());
lambdaQueryWrapper.eq(queryRecord.getIsOpenCheckBill() != null , PayInterfaceDefine::getIsOpenCheckBill, queryRecord.getIsOpenCheckBill());
lambdaQueryWrapper.eq(queryRecord.getIsSupportCashout() != null , PayInterfaceDefine::getIsSupportCashout, queryRecord.getIsSupportCashout());
lambdaQueryWrapper.eq(queryRecord.getIsOpenCashout() != null , PayInterfaceDefine::getIsOpenCashout, queryRecord.getIsOpenCashout());
lambdaQueryWrapper.orderByAsc(PayInterfaceDefine::getCreatedAt);
Page<PayInterfaceDefine> page = payInterfaceDefineService.page(getIPage(), lambdaQueryWrapper);
return ApiRes.ok(page);
}
}

View File

@@ -0,0 +1,239 @@
package com.jeequan.jeepay.mgr.ctrl.payconfig;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.components.mq.model.ResetIsvMchAppInfoConfigMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.oauth2.Oauth2Params;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.db.entity.PayInterfaceConfig;
import com.jeequan.jeepay.db.entity.RateConfig;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.PayInterfaceConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/***
* oauth2配置
*
* @author terrfly
*
* @date 2022/11/9 17:01
*/
@RestController
@RequestMapping("/api/payOauth2Config")
public class PayOauth2ConfigController extends CommonCtrl {
@Autowired
private MchAppService mchAppService;
@Autowired
private PayInterfaceConfigService payInterfaceConfigService;
@Autowired
private IMQSender mqSender;
/**
* 查询已经配置的参数信息
**/
@GetMapping(value = "/savedConfigs")
public ApiRes interfaceSavedConfigs() {
String ifCode = getValStringRequired("ifCode"); // ifCode
String infoId = getValStringRequired("infoId"); // infoId
String configMode = getValStringRequired("configMode"); // 设置类型
String infoType = null;
// 运营平台 配置服务商信息 --》
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.ISV_OAUTH2;
} else // 运营平台 配置商户应用信息
if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.MCH_APP_OAUTH2;
}
// 查询已经配置的信息
PayInterfaceConfig payInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(infoType, infoId, ifCode);
if (payInterfaceConfig == null) {
payInterfaceConfig = new PayInterfaceConfig();
}
// 处理脱敏数据
if (StringUtils.isNotEmpty(payInterfaceConfig.getIfParams())) {
Oauth2Params isvParams = Oauth2Params.factory(ifCode, payInterfaceConfig.getIfParams());
if (isvParams != null) {
payInterfaceConfig.setIfParams(isvParams.deSenData());
}
}
return ApiRes.ok(payInterfaceConfig);
}
/**
* 更新支付参数
**/
@PostMapping("/configParams")
@MethodLog(remark = "更新oauth2参数")
public ApiRes saveOrUpdate() {
PayInterfaceConfig payInterfaceConfig = getObject(PayInterfaceConfig.class);
String configMode = payInterfaceConfig.extv().getString("configMode"); // 设置类型
String infoType = null;
// 运营平台 配置服务商信息 --》
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.ISV_OAUTH2;
} else // 运营平台 配置商户应用
if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.MCH_APP_OAUTH2;
}
payInterfaceConfig.setInfoType(infoType);
//添加更新者信息
Long userId = getCurrentUser().getSysUser().getSysUserId();
String realName = getCurrentUser().getSysUser().getRealname();
payInterfaceConfig.setUpdatedUid(userId);
payInterfaceConfig.setUpdatedBy(realName);
//根据 服务商号、接口类型 获取商户参数配置
PayInterfaceConfig dbRecord = payInterfaceConfigService.getByInfoIdAndIfCode(payInterfaceConfig.getInfoType(), payInterfaceConfig.getInfoId(), payInterfaceConfig.getIfCode());
//若配置存在为saveOrUpdate添加ID第一次配置添加创建者
if (dbRecord != null) {
payInterfaceConfig.setId(dbRecord.getId());
// 合并支付参数
payInterfaceConfig.setIfParams(StringKit.marge(dbRecord.getIfParams(), payInterfaceConfig.getIfParams(), dbRecord.getIfCode()));
} else {
payInterfaceConfig.setCreatedUid(userId);
payInterfaceConfig.setCreatedBy(realName);
}
boolean result = payInterfaceConfigService.saveOrUpdate(payInterfaceConfig);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, "配置失败");
}
// 推送mq到目前节点进行更新数据
// 运营平台 配置服务商信息 --》
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
// 获取到原始 isvId
String infoId = payInterfaceConfig.getInfoId();
if (infoId.indexOf("_LIST_") > 0) {
infoId = infoId.split("_LIST_")[0];
}
mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_ISV_INFO, infoId, null, null));
}
return ApiRes.ok();
}
/**
* 查询oauth2列表 diyList
**/
@GetMapping(value = "/diyList")
public ApiRes diyList() {
String infoId = getValStringRequired("infoId"); // infoId
String configMode = getValStringRequired("configMode"); // 设置类型
String infoType = null;
// 运营平台 配置服务商信息 --》 ( oauth2页面 只支持该类型)
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.ISV_OAUTH2;
}
// 示例: V1650963022_LIST_20220109105300
String infoIdLike = infoId + "_LIST_";
List<PayInterfaceConfig> result =
payInterfaceConfigService.list(PayInterfaceConfig.gw()
.select(PayInterfaceConfig::getId, PayInterfaceConfig::getInfoId, PayInterfaceConfig::getRemark)
.like(PayInterfaceConfig::getInfoId, infoIdLike).eq(PayInterfaceConfig::getInfoType, infoType));
// infoId - remark(名称) (作用: 去重)
Map<String, String> nameMap = new HashMap<>();
for (PayInterfaceConfig payInterfaceConfig : result) {
if (StringUtils.isNotBlank(payInterfaceConfig.getRemark())) {
nameMap.put(payInterfaceConfig.getInfoId(), payInterfaceConfig.getRemark());
}
}
// 改为最终的返回结果
List<PayInterfaceConfig> apiResult = new ArrayList<>();
for (String s : nameMap.keySet()) {
PayInterfaceConfig p = new PayInterfaceConfig();
p.setInfoId(s);
p.setRemark(nameMap.get(s));
apiResult.add(p);
}
return ApiRes.ok(apiResult);
}
/**
* 新增一个
**/
@PostMapping(value = "/diyList")
public ApiRes diyListAdd() {
String infoId = getValStringRequired("infoId"); // infoId
String configMode = getValStringRequired("configMode"); // 设置类型
String remark = getValStringRequired("remark"); // 名称
// 示例: V1650963022_LIST_20220109105300
String infoIdAddId = infoId + "_LIST_" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN);
String infoType = null;
// 运营平台 配置服务商信息 --》 (只支持该类型)
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.ISV_OAUTH2;
}
if (payInterfaceConfigService.count(PayInterfaceConfig.gw().eq(PayInterfaceConfig::getInfoId, infoIdAddId).eq(PayInterfaceConfig::getInfoType, infoType)) > 0) {
throw new BizException(infoIdAddId + "已存在, 不能重复添加");
}
PayInterfaceConfig payInterfaceConfig = new PayInterfaceConfig();
payInterfaceConfig.setInfoType(infoType);
payInterfaceConfig.setInfoId(infoIdAddId);
payInterfaceConfig.setIfCode(CS.IF_CODE.WXPAY);
payInterfaceConfig.setIfParams(new JSONObject().toJSONString());
payInterfaceConfig.setState(CS.YES);
payInterfaceConfig.setRemark(remark);
payInterfaceConfig.setCreatedUid(getCurrentUser().getSysUserId());
payInterfaceConfig.setCreatedBy(getCurrentUser().getSysUser().getRealname());
payInterfaceConfigService.save(payInterfaceConfig);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,141 @@
package com.jeequan.jeepay.mgr.ctrl.payconfig;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchPayPassage;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.db.entity.PayWay;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/**
* 支付方式管理类
*
* @author zhuxiao
*
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("api/payWays")
public class PayWayController extends CommonCtrl {
@Autowired PayWayService payWayService;
@Autowired MchPayPassageService mchPayPassageService;
@Autowired PayInterfaceDefineService payInterfaceDefineService;
@Autowired PayInterfaceConfigService payInterfaceConfigService;
@Autowired PayOrderService payOrderService;
/**
* @Author: ZhuXiao
* @Description: list
* @Date: 15:52 2021/4/27
*/
@PreAuthorize("hasAnyAuthority('ENT_PC_WAY_LIST', 'ENT_PAY_ORDER_SEARCH_PAY_WAY')")
@GetMapping
public ApiRes list() {
LambdaQueryWrapper<PayWay> condition = PayWay.gw();
PayWay queryObject = getObject(PayWay.class);
if(ObjUtil.isNotEmpty(queryObject.getWayCode())){
condition.like(PayWay::getWayCode, queryObject.getWayCode());
}
if(ObjUtil.isNotEmpty(queryObject.getWayName())){
condition.like(PayWay::getWayName, queryObject.getWayName());
}
if(ObjUtil.isNotEmpty(queryObject.getProductType())){
condition.eq(PayWay::getProductType, queryObject.getProductType());
}
condition.orderByAsc(PayWay::getWayCode);
IPage<PayWay> pages = payWayService.page(getIPage(true), condition);
return ApiRes.page(pages);
}
/**
* @Author: ZhuXiao
* @Description: detail
* @Date: 15:52 2021/4/27
*/
@PreAuthorize("hasAnyAuthority('ENT_PC_WAY_VIEW', 'ENT_PC_WAY_EDIT')")
@GetMapping("/{wayCode}")
public ApiRes detail(@PathVariable("wayCode") String wayCode) {
return ApiRes.ok(payWayService.getById(wayCode));
}
/**
* @Author: ZhuXiao
* @Description: add
* @Date: 15:52 2021/4/27
*/
@PreAuthorize("hasAuthority('ENT_PC_WAY_ADD')")
@PostMapping
@MethodLog(remark = "新增支付方式")
public ApiRes add() {
PayWay payWay = getObject(PayWay.class);
if (payWayService.count(PayWay.gw().eq(PayWay::getWayCode, payWay.getWayCode())) > 0) {
throw new BizException("支付方式代码已存在");
}
payWay.setWayCode(payWay.getWayCode().toUpperCase());
boolean result = payWayService.save(payWay);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
return ApiRes.ok();
}
/**
* @Author: ZhuXiao
* @Description: update
* @Date: 15:52 2021/4/27
*/
@PreAuthorize("hasAuthority('ENT_PC_WAY_EDIT')")
@PutMapping("/{wayCode}")
@MethodLog(remark = "更新支付方式")
public ApiRes update(@PathVariable("wayCode") String wayCode) {
PayWay payWay = getObject(PayWay.class);
payWay.setWayCode(wayCode);
boolean result = payWayService.updateById(payWay);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @Author: ZhuXiao
* @Description: delete
* @Date: 15:52 2021/4/27
*/
@PreAuthorize("hasAuthority('ENT_PC_WAY_DEL')")
@DeleteMapping("/{wayCode}")
@MethodLog(remark = "删除支付方式")
public ApiRes delete(@PathVariable("wayCode") String wayCode) {
// 校验该支付方式是否有商户已配置通道或者已有订单
if (mchPayPassageService.count(MchPayPassage.gw().eq(MchPayPassage::getWayCode, wayCode)) > 0
|| payOrderService.count(PayOrder.gw().eq(PayOrder::getWayCode, wayCode)) > 0) {
throw new BizException("该支付方式已有商户配置通道或已发生交易,无法删除!");
}
boolean result = payWayService.removeById(wayCode);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
}
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,73 @@
package com.jeequan.jeepay.mgr.ctrl.payconfig;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.QualificationDefineEntity;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.QualificationDefineService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RequestMapping("/api/qualificationDefine")
@RestController
public class QualificationDefineController extends CommonCtrl {
@Autowired
private QualificationDefineService qualificationDefineService;
@PostMapping("/save")
public ApiRes save() {
QualificationDefineEntity entity = getObject(QualificationDefineEntity.class);
//根据规则“API_名称拼音大写_CP_PAY”定义
if (StringUtils.isEmpty(entity.getName())){
throw new BizException("资质名称不能为空!");
}
String pinyinString = PinyinUtil.getPinyin(entity.getName(),""); // 获取拼音字符串,
String upperCasePinyin = pinyinString.toUpperCase(); // 将拼音转化为大写
entity.setCode(QualificationDefineEntity.API_CODE_FIRST+upperCasePinyin+QualificationDefineEntity.API_CODE_LAST);
//code唯一判定
QualificationDefineEntity qualificationDefineServiceById = qualificationDefineService.getById(entity.getCode());
if (qualificationDefineServiceById != null){
throw new BizException("唯一性code值重复请尝试更换资质名称");
}else {
boolean save = qualificationDefineService.save(entity);
return ApiRes.ok(save);
}
}
@GetMapping("/page")
public ApiRes page() {
Page<QualificationDefineEntity> iPage = getIPage(false);
QualificationDefineEntity condition = getObject(QualificationDefineEntity.class);
qualificationDefineService.lambdaQuery().setEntity(condition).page(iPage);
return ApiRes.ok(iPage);
}
@GetMapping("/{code}")
public ApiRes one(@PathVariable String code) {
QualificationDefineEntity one = qualificationDefineService.lambdaQuery().eq(QualificationDefineEntity::getCode, code).one();
return ApiRes.ok(one);
}
@DeleteMapping("/{code}")
public ApiRes del(@PathVariable String code) {
qualificationDefineService.removeById(code);
return ApiRes.ok();
}
/**
* 编辑
*/
@PutMapping("/update")
public ApiRes update() {
String code = getValStringRequired("code");
QualificationDefineEntity entity = getObject(QualificationDefineEntity.class);
boolean update = qualificationDefineService.updateById(entity);
return ApiRes.ok(update);
}
}

View File

@@ -0,0 +1,637 @@
package com.jeequan.jeepay.mgr.ctrl.payconfig;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jeequan.jeepay.converter.BaseConverter;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.constants.ConstWord;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.model.RateConfigSimple;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* 费率配置信息
*
* @author terrfly
* @since 2022/3/21 0:13
*/
@RestController
@RequestMapping("/api/rateConfig")
public class RateConfigController extends CommonCtrl {
@Autowired
private MchAppService mchAppService;
@Autowired
private RateConfigService rateConfigService;
@Autowired
private PayWayService payWayService;
@Autowired
private IsvUserConnService isvUserConnService;
@Autowired
private BaseConverter baseConverter;
@Autowired
private RateConfigV2Service rateConfigV2Service;
/**
* 查询所有可配置的支付方式 payways
**/
@GetMapping("/payways")
public ApiRes payways() {
String ifCode = getValStringRequired(ConstWord.IF_CODE); // ifCode
String infoId = getValStringRequired(ConstWord.INFO_ID); // infoId
String isvNo = getValString(ConstWord.ISV_NO); // isvNo
String configMode = getValStringRequired(ConstWord.CONFIG_MODE); // 设置类型
Integer range = getValInteger("range");
String mccCode = getValString("mccCode");
// 商户服务商或者服务商的父ID (用于过滤掉关闭的支付方式)
String belongAgentNo = null;
String belongIsvNo = null;
String mchAppId = getValString(ConstWord.APP_ID);
if (!ObjUtil.isEmpty(mchAppId)) {
MchAppEntity mchApp = mchAppService.getById(mchAppId);
range = mchApp.getRange();
mccCode = mchApp.getMccCode();
}
// 是否仅显示 支持进件的支付方式(用作进件使用)
boolean isOnlyApplymentSupport = RateConfig.CONFIG_MODE_MGRAPPLYMENT.equals(configMode);
// 运营平台 配置 服务商显示全部的就可以。
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
isvNo = infoId;
// 给服务商配置, 显示所有的就可以。
// 运营平台配置服务商的费率
} else if (RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)) {
AgentInfo agentInfo = agentInfoService.getById(infoId);
belongAgentNo = agentInfo.getPid();
belongIsvNo = isvNo;
// 运营平台 配置 商户应用费率 || 商户发起的进件
} else if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode) || RateConfig.CONFIG_MODE_MGRAPPLYMENT.equals(configMode)) {
String mchNo;
// 运营平台进件模式 : infoId = applyId_mchNo 的拼接方式。
if (RateConfig.CONFIG_MODE_MGRAPPLYMENT.equals(configMode)) {
mchNo = infoId.split("_")[1];
} else {
mchNo = infoId;
}
MchInfo mchInfo = mchInfoService.getById(mchNo);
belongAgentNo = mchInfo.getAgentNo();
}
return ApiRes.page(payWayService.queryWayListByRate(ifCode, belongIsvNo, belongAgentNo, isOnlyApplymentSupport, range, mccCode, isvNo));
}
/**
* 查询当前已经配置的列表
**/
@GetMapping(value = "/savedMapData")
public ApiRes savedMapData() {
String ifCode = getValStringRequired("ifCode"); // ifCode
String infoId = getValStringRequired("infoId"); // infoId
String configMode = getValStringRequired("configMode"); // 设置类型
String isvNo = getValString("isvNo"); // 设置类型
Integer range = getValInteger("range");
String mccCode = getValString("mccCode");
String mchAppId = getValString("appId");
if (!ObjUtil.isEmpty(mchAppId)) {
MchAppEntity mchApp = mchAppService.getById(mchAppId);
range = mchApp.getRange();
mccCode = mchApp.getMccCode();
}
// 配置渠道商费率
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
Map<String, Object> result = new HashMap<>();
result.put(RateConfig.ISVCOST, rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.ISVCOST, commonGetInfoType(configMode), ifCode, range, mccCode, infoId));
result.put(RateConfig.AGENTDEF, rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.AGENTDEF, commonGetInfoType(configMode), ifCode, range, mccCode, infoId));
result.put(RateConfig.MCHAPPLYDEF, rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.MCHAPPLYDEF, commonGetInfoType(configMode), ifCode, range, mccCode, infoId));
result.put(RateConfig.AGENTMAX, rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.AGENTMAX, commonGetInfoType(configMode), ifCode, range, mccCode, infoId));
result.put(RateConfig.MCHAPPLYMAX, rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.MCHAPPLYMAX, commonGetInfoType(configMode), ifCode, range, mccCode, infoId));
return ApiRes.ok(result);
}
// 配置服务商费率
if (RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)) {
Map<String, Object> result = new HashMap<>();
Map<String, PaywayFee> agentRate = rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.AGENTRATE, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
result.put(RateConfig.AGENTRATE, agentRate);
result.put(RateConfig.MCHAPPLYMAX, rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.MCHAPPLYMAX, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
AgentInfo agentInfo = agentInfoService.getById(infoId);
Map<String, PaywayFee> agentRateDef = null;
if (agentInfo.getPid() == null) {
agentRateDef = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgentDef(infoId), CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo);
} else {
agentRateDef = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgentDef(infoId), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
}
result.put(RateConfig.AGENTDEF, agentRateDef);
result.put(RateConfig.MCHAPPLYDEF, rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.MCHAPPLYDEF, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
// 查询渠道商底价
result.put(RateConfig.READONLYISVCOST, rateConfigService.queryPaywayFeeMap(isvNo + "_" + RateConfig.ISVCOST, CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo));
Map<String, PaywayFee> parentDefRate = null;
// 查询上级服务商的费率
if (!ObjUtil.isEmpty(agentInfo.getPid())) {
result.put(RateConfig.READONLYPARENTAGENT, rateConfigService.queryPaywayFeeMap(agentInfo.getPid() + "_" + RateConfig.AGENTRATE, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
// 默认费率
parentDefRate = rateConfigService.queryPaywayFeeMap(agentInfo.getPid() + "_" + RateConfig.AGENTDEF, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
} else { // 无上级服务商, 查询服务商配置的。
// 默认费率
parentDefRate = rateConfigService.queryPaywayFeeMap(isvNo + "_" + RateConfig.AGENTDEF, CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo);
}
result.put(RateConfig.READONLYPARENTDEFRATE, parentDefRate);
PaywayFee.resetData(agentRate, baseConverter.newPaywayFeeMap(parentDefRate));
// 默认下级代理最大费率
if (ObjUtil.isEmpty(agentInfo.getPid())) {
result.put(RateConfig.READONLYPARENTSUBAGENTMAX, rateConfigService.queryPaywayFeeMap(isvNo + "_" + RateConfig.AGENTMAX, CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo));
} else {
result.put(RateConfig.READONLYPARENTSUBAGENTMAX, rateConfigService.queryPaywayFeeMap(agentInfo.getPid() + "_" + RateConfig.AGENTMAX, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
}
// 商户最大费率
if (ObjUtil.isEmpty(agentInfo.getPid())) {
result.put(RateConfig.READONLYPARENTMCHMAX, rateConfigService.queryPaywayFeeMap(isvNo + "_" + RateConfig.MCHAPPLYMAX, CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo));
} else {
result.put(RateConfig.READONLYPARENTMCHMAX, rateConfigService.queryPaywayFeeMap(agentInfo.getPid() + "_" + RateConfig.MCHAPPLYMAX, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
}
return ApiRes.ok(result);
}
// 配置商户费率 || 服务商进件模式
if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode) || RateConfig.CONFIG_MODE_MGRAPPLYMENT.equals(configMode)) {
Assert.notBlank(isvNo, "渠道号不能为空");
Map<String, Object> result = new HashMap<>();
String mchNo;
String applyId = "";
// 运营平台进件模式 : infoId = applyId_mchNo 的拼接方式。
if (RateConfig.CONFIG_MODE_MGRAPPLYMENT.equals(configMode)) {
applyId = infoId.split("_")[0];
mchNo = infoId.split("_")[1];
} else {
// 不再使用应用关联费率,直接用用户/商户关联费率
mchNo = infoId;
}
Map<String, PaywayFee> mchRateMap = null;
// 查询已经配置的信息
if (RateConfig.CONFIG_MODE_MGRAPPLYMENT.equals(configMode) && !ObjUtil.isEmpty(applyId)) { // 运营平台进件模式
// mchRateMap = rateConfigService.queryPaywayFeeMapByApplyment(applyId);
// 此处费率不从商户信息里面取了
mchRateMap = rateConfigService.queryPaywayFeeMap(applyId, CS.SYS_ROLE_TYPE.MCH_APPLYMENT, ifCode, range, mccCode, isvNo);
} else {
// 这里直接取服务商给用户配置的费率
mchRateMap = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchApp(mchNo), CS.SYS_ROLE_TYPE.MCH_APP, ifCode, range, mccCode, isvNo);
}
result.put(RateConfig.MCHRATE, mchRateMap);
MchInfo mchInfo = mchInfoService.getById(mchNo);
// 特约商户
if (mchInfo.getType() == CS.MCH_TYPE_ISVSUB) {
// 查询渠道商底价
result.put(RateConfig.READONLYISVCOST, rateConfigService.queryPaywayFeeMap(isvNo + "_" + RateConfig.ISVCOST, CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo));
// 查询上级服务商的费率
if (!ObjUtil.isEmpty(mchInfo.getAgentNo())) {
result.put(RateConfig.READONLYPARENTAGENT, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(mchInfo.getAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
}
Map<String, PaywayFee> parentDefRate = null;
// 默认费率
if (ObjUtil.isEmpty(mchInfo.getAgentNo())) {
parentDefRate = rateConfigService.queryPaywayFeeMap(isvNo + "_" + RateConfig.MCHAPPLYDEF, CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo);
} else {
parentDefRate = rateConfigService.queryPaywayFeeMap(mchInfo.getAgentNo() + "_" + RateConfig.MCHAPPLYDEF, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
}
result.put(RateConfig.READONLYPARENTDEFRATE, parentDefRate);
// 默认商户最大费率
if (ObjUtil.isEmpty(mchInfo.getAgentNo())) {
result.put(RateConfig.READONLYPARENTMCHMAX, rateConfigService.queryPaywayFeeMap(isvNo + "_" + RateConfig.MCHAPPLYMAX, CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo));
} else {
result.put(RateConfig.READONLYPARENTMCHMAX, rateConfigService.queryPaywayFeeMap(mchInfo.getAgentNo() + "_" + RateConfig.MCHAPPLYMAX, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
}
// 商户费率为空时,将默认费率设置为商户费率
if (ObjUtil.isEmpty(result.get(RateConfig.MCHRATE))) {
result.put(RateConfig.MCHRATE, result.get(RateConfig.READONLYPARENTDEFRATE));
}
// if (ObjUtil.isEmpty(result.get(RateConfig.MCHRATE))) {
// throw new BizException("未获取到商户费率,且其上级服务商未配置默认商户费率");
// }
// 后续添加跟渠道费率配置对比
PaywayFee.resetData(mchRateMap, baseConverter.newPaywayFeeMap(parentDefRate));
}
return ApiRes.ok(result);
}
return ApiRes.ok();
}
/**
* 保存费率信息
**/
@MethodLog(remark = "配置服务商费率")
@PostMapping(value = "")
public ApiRes reset() {
// 需要删除的集合, 比如: 配置渠道商底价, 关闭了某些渠道, 那么需要将下属的配置删除掉。
List<RateConfig> delList = new ArrayList<>();
String configMode = getValStringRequired("configMode");
// 运营平台: 是否 不校验商户规则
Byte noCheckRuleFlag = getValByteDefault("noCheckRuleFlag", CS.NO);
// 主对象
RateConfig mainRateConfig = getObject(RateConfig.class);
// 必须设置infoType, 检查费率会使用
mainRateConfig.setInfoType(commonGetInfoType(configMode));
// 配置渠道费率
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
mainRateConfig.setIsvNo(mainRateConfig.getInfoId());
}
Map<String, PaywayFee> isvCostMap = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByIsvCost(mainRateConfig.getIsvNo()), CS.SYS_ROLE_TYPE.ISV,
mainRateConfig.getIfCode(), mainRateConfig.getRange(), mainRateConfig.getMccCode(), mainRateConfig.getIsvNo());
List<RateConfig> list = new ArrayList<>();
// 渠道商底价 infoId = ISVNO_ISVCOST infoType = 1(服务商)
if (!ObjUtil.isEmpty(mainRateConfig.extv().getString(RateConfig.ISVCOST))) {
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.ISVCOST), PaywayFee.class)
.forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.ISVCOST, configMode)));
// 配置服务商需要删除 下属配置。
delList = this.genDelRateConfigList(mainRateConfig.getInfoId(), null, mainRateConfig.getIfCode());
}
// 服务商默认费率 infoId = ISVNO_AGENTDEF infoType = 1(服务商)
if (!ObjUtil.isEmpty(mainRateConfig.extv().getString(RateConfig.AGENTDEF))) {
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.AGENTDEF), PaywayFee.class)
.forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.AGENTDEF, configMode)));
}
// 服务商最大费率 infoId = ISVNO_AGENTMAX infoType = 1(服务商)
if (!ObjUtil.isEmpty(mainRateConfig.extv().getString(RateConfig.AGENTMAX))) {
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.AGENTMAX), PaywayFee.class)
.forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.AGENTMAX, configMode)));
}
// 商户默认费率 infoId = ISVNO_MCHAPPLYDEF infoType = 1(服务商)
if (!ObjUtil.isEmpty(mainRateConfig.extv().getString(RateConfig.MCHAPPLYDEF))) {
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.MCHAPPLYDEF), PaywayFee.class)
.forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.MCHAPPLYDEF, configMode)));
}
// 商户最大费率 infoId = ISVNO_MCHAPPLYMAX infoType = 1(服务商)
if (!ObjUtil.isEmpty(mainRateConfig.extv().getString(RateConfig.MCHAPPLYMAX))) {
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.MCHAPPLYMAX), PaywayFee.class)
.forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.MCHAPPLYMAX, configMode)));
}
// 商户费率
if (!ObjUtil.isEmpty(mainRateConfig.extv().getString(RateConfig.MCHRATE))) {
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.MCHRATE), PaywayFee.class)
.forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.MCHRATE, configMode)));
}
// 服务商费率
if (!ObjUtil.isEmpty(mainRateConfig.extv().getString(RateConfig.AGENTRATE))) {
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.AGENTRATE), PaywayFee.class)
.forEach(r -> {
PaywayFee paywayFee = isvCostMap.get(r.getWayCode());
Optional.ofNullable(paywayFee).ifPresent(it -> r.setApplymentSupport(paywayFee.getApplymentSupport()));
list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.AGENTRATE, configMode));
});
// 配置 服务商 需要删除 下属配置。
delList = this.genDelRateConfigList(null, mainRateConfig.getInfoId(), mainRateConfig.getIfCode());
}
LambdaQueryWrapper<RateConfig> delWrapper = Wrappers.lambdaQuery();
delWrapper.eq(RateConfig::getIfCode, mainRateConfig.getIfCode());
delWrapper.eq(RateConfig::getIsvNo, mainRateConfig.getIsvNo());
delWrapper.eq(RateConfig::getInfoType, commonGetInfoType(configMode));
delWrapper.eq(mainRateConfig.getRange() != null, RateConfig::getRange, mainRateConfig.getRange());
delWrapper.eq(!ObjUtil.isEmpty(mainRateConfig.getMccCode()), RateConfig::getMccCode, mainRateConfig.getMccCode());
delWrapper.in(RateConfig::getInfoId, commonGetInfoId(configMode, mainRateConfig.getInfoId()));
rateConfigService.resetRate(list, delWrapper, mainRateConfig, (noCheckRuleFlag == CS.YES), delList);
return ApiRes.ok();
}
private RateConfig getFillInfoIdAndType(RateConfig mainRateConfig, PaywayFee paywayFee, String infoSuffix, String configMode) {
RateConfig result = new RateConfig();
result.setInfoId(mainRateConfig.getInfoId() + "_" + infoSuffix);
result.setIfCode(mainRateConfig.getIfCode());
result.setMccCode(mainRateConfig.getMccCode());
result.setRange(mainRateConfig.getRange());
result.setIsvNo(mainRateConfig.getIsvNo());
result.setWayCode(paywayFee.getWayCode());
result.setFeeType(paywayFee.getFeeType());
result.setFeeRate(paywayFee.getFeeRate());
result.setApplymentSupport(paywayFee.getApplymentSupport());
result.setPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFee));
result.setInfoType(commonGetInfoType(configMode));
return result;
}
private String commonGetInfoType(String configMode) {
//设置服务商信息
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
return CS.SYS_ROLE_TYPE.ISV;
} else if (RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)) {
return CS.SYS_ROLE_TYPE.AGENT;
} else if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)) {
return CS.SYS_ROLE_TYPE.MCH_APP;
} else if (RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)) {
return CS.SYS_ROLE_TYPE.AGENT;
} else if (RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode)) {
return CS.SYS_ROLE_TYPE.AGENT;
} else if (RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode)) {
return CS.SYS_ROLE_TYPE.MCH_APP;
}
return "";
}
private List<String> commonGetInfoId(String configMode, String infoId) {
//设置服务商信息
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
return Arrays.asList(
(infoId + "_" + RateConfig.ISVCOST),
(infoId + "_" + RateConfig.AGENTDEF),
(infoId + "_" + RateConfig.AGENTMAX),
(infoId + "_" + RateConfig.MCHAPPLYDEF),
(infoId + "_" + RateConfig.MCHAPPLYMAX)
);
} else if (RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)) {
return Arrays.asList(
(infoId + "_" + RateConfig.AGENTRATE),
(infoId + "_" + RateConfig.AGENTDEF),
(infoId + "_" + RateConfig.AGENTMAX),
(infoId + "_" + RateConfig.MCHAPPLYDEF),
(infoId + "_" + RateConfig.MCHAPPLYMAX)
);
} else if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)) {
return Collections.singletonList((infoId + "_" + RateConfig.MCHRATE));
} else if (RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)) {
return Arrays.asList(
(infoId + "_" + RateConfig.AGENTDEF),
(infoId + "_" + RateConfig.MCHAPPLYDEF),
(infoId + "_" + RateConfig.MCHAPPLYMAX)
);
} else if (RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode)) {
return Arrays.asList(
(infoId + "_" + RateConfig.AGENTRATE),
(infoId + "_" + RateConfig.MCHAPPLYMAX)
);
} else if (RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode)) {
return Collections.singletonList(
(infoId + "_" + RateConfig.MCHRATE)
);
}
return new ArrayList<>();
}
/**
* 获取待删除的列表集合 info_id/ info_type if_code way_code
* <p>
* 以下三个场景需要判断:
* 渠道商底价
* 运营平台 --> 设置服务商费率
* 服务商 配置 下级服务商费率 (服务商)
**/
private List<RateConfig> genDelRateConfigList(String isvNo, String agentNo, String ifCode) {
String delPaywayCodeListStr = getValString("delPaywayCodeListStr");
if (StringUtils.isEmpty(delPaywayCodeListStr)) {
return Collections.emptyList();
}
List<String> delWayCodeList = JSON.parseArray(delPaywayCodeListStr, String.class);
// 没有待删除的列表
if (delWayCodeList.isEmpty()) {
return Collections.emptyList();
}
List<RateConfig> result = new ArrayList<>();
Set<String> allAgentNoList = new HashSet<>();
Set<String> allMchNoList = new HashSet<>();
Set<String> allAppIdList = new HashSet<>();
// 服务商不为空
if (!ObjUtil.isEmpty(isvNo)) {
// 判断是否支持服务商
if (SysConfigService.IS_HAS_AGENT_ENT) {
// 查询所有的服务商列表 ( 一级服务商 )
agentInfoService.list(AgentInfo.gw().select(AgentInfo::getAgentNo).eq(AgentInfo::getIsvNo, isvNo)).forEach(r -> allAgentNoList.add(r.getAgentNo()));
}
// 查询所有的商户列表 [ 无需查询服务商的所属了, 已经是全部服务商下的商户了。 ]
isvUserConnService.lambdaQuery().eq(IsvUserConnEntity::getIsvNo, isvNo)
.eq(IsvUserConnEntity::getStatus, CS.YES)
.eq(IsvUserConnEntity::getInfoType, CS.SYS_ROLE_TYPE.MCH)
.list()
.forEach(r -> allMchNoList.add(r.getInfoId()));
// 查询下级服务商的 子服务商【递归】
Set<String> tempAgentNoSet = new HashSet<>(); // 避免出现ConcurrentModificationException
for (String agentNoItem : allAgentNoList) {
tempAgentNoSet.addAll(agentInfoService.queryAllSubAgentNo(agentNoItem));
}
allAgentNoList.addAll(tempAgentNoSet);
}
// 服务商不为空
if (!ObjUtil.isEmpty(agentNo)) {
// 查询所有的服务商列表 当前服务商的 直属 服务商
agentInfoService.list(AgentInfo.gw().select(AgentInfo::getAgentNo).eq(AgentInfo::getPid, agentNo)).forEach(r -> allAgentNoList.add(r.getAgentNo()));
// 查询所有的商户列表 当前服务商的 直属 商户 【 当前服务商的所属商户 】
mchInfoService.list(MchInfo.gw().select(MchInfo::getMchNo).eq(MchInfo::getAgentNo, agentNo)).forEach(r -> allMchNoList.add(r.getMchNo()));
// 查询下级服务商的 子服务商【递归】
Set<String> tempAgentNoSet = new HashSet<>(); // 避免出现ConcurrentModificationException
for (String agentNoItem : allAgentNoList) {
tempAgentNoSet.addAll(agentInfoService.queryAllSubAgentNo(agentNoItem));
}
allAgentNoList.addAll(tempAgentNoSet);
// 查询下级服务商 所属的商户集合
for (String agentNoItem : allAgentNoList) {
mchInfoService.list(MchInfo.gw().select(MchInfo::getMchNo).eq(MchInfo::getAgentNo, agentNoItem)).forEach(r -> allMchNoList.add(r.getMchNo()));
}
}
if (!allMchNoList.isEmpty()) {
// 查询所有的商户列表
mchAppService.lambdaQuery().select(MchAppEntity::getAppId).in(MchAppEntity::getMchNo, allMchNoList).list().forEach(r -> allAppIdList.add(r.getAppId()));
}
// 服务商: 包括 服务商配置, 下级服务商默认、 服务商商户默认
for (String agentNoItem : allAgentNoList) {
for (String wayCode : delWayCodeList) {
RateConfig r = new RateConfig();
r.setInfoId(RateConfig.buildInfoId(agentNoItem, RateConfig.AGENTRATE));
r.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
r.setIfCode(ifCode);
r.setWayCode(wayCode);
result.add(r);
RateConfig r1 = new RateConfig();
r1.setInfoId(RateConfig.buildInfoId(agentNoItem, RateConfig.AGENTDEF));
r1.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
r1.setIfCode(ifCode);
r1.setWayCode(wayCode);
result.add(r1);
RateConfig r2 = new RateConfig();
r2.setInfoId(RateConfig.buildInfoId(agentNoItem, RateConfig.MCHAPPLYDEF));
r2.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
r2.setIfCode(ifCode);
r2.setWayCode(wayCode);
result.add(r2);
}
}
// 商户: 包括 商户应用费率
for (String appIdItem : allAppIdList) {
for (String wayCode : delWayCodeList) {
RateConfig r = new RateConfig();
r.setInfoId(RateConfig.buildInfoId(appIdItem, RateConfig.MCHRATE));
r.setInfoType(CS.SYS_ROLE_TYPE.MCH_APP);
r.setIfCode(ifCode);
r.setWayCode(wayCode);
result.add(r);
}
}
return result;
}
@GetMapping("/rateInfoDetail")
public ApiRes rateInfoDetail() {
String isvNo = getValStringRequired("isvNo");
String ifCode = getValStringRequired("ifCode");
Integer range = getValInteger("range");
String mccCode = getValString("mccCode");
String infoType = getValStringRequired("infoType");
String infoId = getValStringRequired("infoId");
List<RateConfigSimple> result = rateConfigV2Service.getRankFeeList(isvNo, infoType, infoId, ifCode, range, mccCode, isvNo);
return ApiRes.ok(result);
}
@PostMapping("/resetV2")
public ApiRes resetV2() {
RateConfigSimple rateConfigSimple = getObject(RateConfigSimple.class);
rateConfigV2Service.save(rateConfigSimple);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,188 @@
package com.jeequan.jeepay.mgr.ctrl.product;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PackageOrder;
import com.jeequan.jeepay.db.entity.ProductInfo;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.PackageInfoService;
import com.jeequan.jeepay.service.impl.ProductAppService;
import com.jeequan.jeepay.service.impl.ProductInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
/**
* 产品列表
*
* @author huay
* @date 2023-11-08 14:50
*/
@RestController
@RequestMapping("/api/product")
public class ProductListController extends CommonCtrl {
@Autowired
private ProductInfoService productInfoService;
@Autowired
ProductAppService productAppService;
@Autowired
MchAppService mchAppService;
@Autowired
PackageInfoService packageInfoService;
/**
* 产品列表
**/
@RequestMapping(value = "/getProductList", method = RequestMethod.GET)
@MethodLog(remark = "产品列表")
public ApiRes getProductList() throws BizException {
//获取查询条件
ProductInfo productInfo = getObject(ProductInfo.class);
Date[] searchDateRange = productInfo.buildQueryDateRange();
productInfo.setFirstDate(searchDateRange[0]);
productInfo.setLastDate(searchDateRange[1]);
Page<ProductInfo> resut=productInfoService.getMgrProductList(getIPage(true),productInfo);
return ApiRes.page(resut);
}
@MethodLog(remark = "新增产品")
@RequestMapping(value = "/add", method = RequestMethod.POST)
public ApiRes add() {
//获取查询条件
ProductInfo productInfo = getObject(ProductInfo.class);
//前端组件不稳定,防止出错做一下数据校验
boolean checkout = packageInfoService.dataCheckout(productInfo.getProductIds(), productInfo.getPackageIds(), productInfo.getPayInterfaceCodes());
if (!checkout){
throw new BizException("关联数据格式不正确!");
}
//根据规则“API_名称拼音大写_CP_PAY”定义
if (StringUtils.isEmpty(productInfo.getProductName())){
throw new BizException("产品名称不能为空!");
}
String pinyinString = PinyinUtil.getPinyin(productInfo.getProductName(),""); // 获取拼音字符串,
String upperCasePinyin = pinyinString.toUpperCase(); // 将拼音转化为大写
productInfo.setApiCode(ProductInfo.API_CODE_FIRST+upperCasePinyin+ProductInfo.API_CODE_LAST);
//code唯一判定
long count = productInfoService.count(ProductInfo.gw().eq(ProductInfo::getApiCode, productInfo.getApiCode()));
if (count > 0){
throw new BizException("唯一性code值重复请尝试更换产品名称");
}
// 当前登录用户信息
SysUser sysUser = getCurrentUser().getSysUser();
productInfo.setProductId(DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
productInfo.setCreatedBy(String.valueOf(sysUser.getSysUserId()));
//如果收费规则为不收费给默认的免费值
if(productInfo.getCharge() != null && productInfo.getCharge().equals(ProductInfo.PRODUCT_STATE_ON_CHARGE)){
JSONArray jsonArray =JSONArray.parseArray(ProductInfo.JSON_STR);
productInfo.setProductText(jsonArray);
}
productInfoService.save(productInfo);
return ApiRes.ok();
}
@MethodLog(remark = "删除产品")
@RequestMapping(value = "/{productId}", method = RequestMethod.DELETE)
public ApiRes delete(@PathVariable("productId") String productId) {
productInfoService.deleteProduct(productId);
return ApiRes.ok();
}
@RequestMapping(value = "/getDetailById", method = RequestMethod.GET)
@MethodLog(remark = "回显产品详情")
public ApiRes getDetailById() throws BizException {
//获取查询条件
ProductInfo productInfo = getObject(ProductInfo.class);
ProductInfo info = productInfoService.getDetailById(productInfo.getProductId());
return ApiRes.ok(info);
}
@MethodLog(remark = "更新产品信息")
@RequestMapping(value = "/{productId}", method = RequestMethod.PUT)
public ApiRes update(@PathVariable("productId") String productId) {
//获取查询条件
ProductInfo productInfo = getObject(ProductInfo.class);
LambdaUpdateWrapper<ProductInfo> updateWrapper= Wrappers.lambdaUpdate();
updateWrapper.eq(ProductInfo::getProductId,productInfo.getProductId());
//前端组件不稳定,防止出错做一下数据校验
boolean checkout = packageInfoService.dataCheckout(productInfo.getProductIds(), productInfo.getPackageIds(), productInfo.getPayInterfaceCodes());
if (!checkout){
throw new BizException("关联数据格式不正确!");
}
productInfo.setProductId(productId);//设置主键
productInfo.setUpdatedAt(new Date());
//如果收费规则为不收费给默认的免费值
if(productInfo.getCharge() != null && productInfo.getCharge().equals(ProductInfo.PRODUCT_STATE_ON_CHARGE)){
JSONArray jsonArray =JSONArray.parseArray(ProductInfo.JSON_STR);
productInfo.setProductText(jsonArray);
}
//如果不需要模板则把之前的清空--前端说不好处理。。
if(productInfo.getCertification() != null && productInfo.getCertification().equals(ProductInfo.PRODUCT_STATE_ON_CHARGE)){
updateWrapper.set(ProductInfo::getSpecialCertificationText,null);
}
productInfoService.update(productInfo,updateWrapper);
return ApiRes.ok();
}
/**
* 审核列表
**/
@GetMapping("/getProductCheckList")
@MethodLog(remark = "审核列表")
public ApiRes getProductCheckList() throws BizException {
//获取查询条件
Page<PackageOrder> page=getIPage(true);
PackageOrder packageOrder = getObject(PackageOrder.class);
// 时间搜索
Date[] searchDateRange = packageOrder.buildQueryDateRange();
packageOrder.setFirstDate(searchDateRange[0]);
packageOrder.setLastDate(searchDateRange[1]);
Page<PackageOrder> result = productAppService.getProductAppList(page, packageOrder);
return ApiRes.page(result);
}
@PostMapping(value = "/checkProduct")
@MethodLog(remark = "产品审核")
public ApiRes checkProduct() throws BizException {
//获取查询条件
PackageOrder app = getObject(PackageOrder.class);
app.setUpdatedAt(new Date());
productInfoService.checkProduct(app);
return ApiRes.ok();
}
@RequestMapping(value = "/getPackageOderById", method = RequestMethod.GET)
@MethodLog(remark = "审核内容详情")
public ApiRes getPackageOderById() throws BizException {
//获取查询条件
PackageOrder packageOrder = getObject(PackageOrder.class);
PackageOrder serviceById = productAppService.getDetail(packageOrder.getId());
return ApiRes.ok(serviceById);
}
public void selectParams(ProductInfo productInfo, LambdaQueryWrapper<ProductInfo> wrapper) {
wrapper.like(StringUtils.isNotEmpty(productInfo.getProductName()), ProductInfo::getProductName, productInfo.getProductName());
wrapper.eq(productInfo.getProductState() != null, ProductInfo::getProductState, productInfo.getProductState());
}
}

View File

@@ -0,0 +1,105 @@
package com.jeequan.jeepay.mgr.ctrl.product;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.ProductInfo;
import com.jeequan.jeepay.db.entity.ProductType;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.ProductInfoService;
import com.jeequan.jeepay.service.impl.ProductTypeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
/**
* 产品分类
*
* @author huay
* @date 2023-11-09 14:50
*/
@RestController
@RequestMapping("/api/productType")
public class ProductTypeController extends CommonCtrl {
@Autowired private ProductTypeService productTypeService;
@Autowired private ProductInfoService productInfoService;
/**
* 分类列表
* **/
@RequestMapping(value = "/getList", method = RequestMethod.GET)
@MethodLog(remark = "分类列表")
public ApiRes getList() throws BizException {
//获取查询条件
ProductType type = getObject(ProductType.class);
LambdaQueryWrapper<ProductType> wrapper = ProductType.gw();
selectParams(type, wrapper);
wrapper.orderByDesc(ProductType::getCreatedAt);
Page<ProductType> pages = productTypeService.page(getIPage(true), wrapper);
return ApiRes.page(pages);
}
@MethodLog(remark = "新增分类")
@RequestMapping(value="/add", method = RequestMethod.POST)
public ApiRes add() {
ProductType type = getObject(ProductType.class);
// 当前登录用户信息
SysUser sysUser = getCurrentUser().getSysUser();
type.setCreatedBy(String.valueOf(sysUser.getSysUserId()));
productTypeService.save(type);
return ApiRes.ok();
}
@MethodLog(remark = "删除分类")
@RequestMapping(value="/{typeId}", method = RequestMethod.DELETE)
public ApiRes delete(@PathVariable("typeId") String typeId) {
//判断该节点下是否有子节点 有则不让删除
LambdaQueryWrapper<ProductInfo> wrapper=new LambdaQueryWrapper<>();
wrapper.eq(ProductInfo::getProductType,typeId);
wrapper.eq(ProductInfo::getProductState,1);
List<ProductInfo> productInfoslist = productInfoService.list(wrapper);
if (!productInfoslist.isEmpty()){
return ApiRes.customFail("该分类下相关内容未清空!");
}
productTypeService.deleteProductType(typeId);
return ApiRes.ok();
}
@RequestMapping(value = "/getDetailById", method = RequestMethod.GET)
@MethodLog(remark = "回显产品详情")
public ApiRes getDetailById() throws BizException {
//获取查询条件
ProductType productType = getObject(ProductType.class);
ProductType type = productTypeService.getById(productType.getTypeId());
return ApiRes.ok(type);
}
@MethodLog(remark = "更新分类信息")
@RequestMapping(value="/{typeId}", method = RequestMethod.PUT)
public ApiRes update(@PathVariable("typeId") String typeId) {
//获取查询条件
ProductType type = getObject(ProductType.class);
type.setTypeId(typeId);//设置主键
type.setUpdatedAt(new Date());
productTypeService.updateById(type);
return ApiRes.ok();
}
public void selectParams(ProductType type, LambdaQueryWrapper<ProductType> wrapper) {
wrapper.like(StringUtils.isNotEmpty(type.getTypeName()), ProductType::getTypeName, type.getTypeName());
}
}

View File

@@ -0,0 +1,519 @@
package com.jeequan.jeepay.mgr.ctrl.qrcode;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.icbc.api.internal.apache.http.impl.cookie.S;
import com.jeequan.jeepay.bizcommons.manage.qrshell.AbstractGenerator;
import com.jeequan.jeepay.bizcommons.manage.qrshell.ShellQRGenerator;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBApplicationConfig;
import com.jeequan.jeepay.core.model.QRCodeParams;
import com.jeequan.jeepay.core.model.export.MchQrCodesExportExcel;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchQrcShellService;
import com.jeequan.jeepay.service.impl.MchQrcodeCardService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 商户应用管理类
*
* @author zhuxiao
*
* @date 2021-06-16 09:15
*/
@RestController
@RequestMapping("/api/mchQrCodes")
public class MchQrCodeController extends CommonCtrl {
@Autowired private MchQrcodeCardService mchQrcodeCardService;
@Autowired private SysConfigService sysConfigService;
@Autowired private MchQrcShellService mchQrcShellService;
@Autowired private MchApplymentService mchApplymentService;
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_LIST')")
@GetMapping
public ApiRes list() {
// 构造查询条件
MchQrcodeCard mchQrCode = getObject(MchQrcodeCard.class);
//mchQrCode.setQrcBelongType(MchQrcodeCard.QRC_BELONG_TYPE_ISV_PRE); // 只查询 下发二维码
IPage<MchQrcodeCard> records = mchQrcodeCardService.selectPageRecords(getIPage(), mchQrCode);
String payHostUrl = sysConfigService.getDBApplicationConfig().getPaySiteUrl();
for (MchQrcodeCard record : records.getRecords()) {
record.addExt("payHostUrl", payHostUrl);
}
return ApiRes.ok(records);
}
/** 查询当前批次号的数量 **/
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_ADD')")
@GetMapping("/batchIdDistinctCount")
public ApiRes selectBatchIdDistinctCount() {
Date now = new Date();
Integer count = mchQrcodeCardService.getBaseMapper().selectBatchIdDistinctCount(DateKit.getBegin(now), DateKit.getEnd(now));
// 时间格式化两位年 + 月 + 日
String nowStr = DateUtil.format(now, "yyMMdd");
// 左补两位0如果不足
return ApiRes.ok(nowStr + String.format("%02d", ++count));
}
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_ADD')")
@MethodLog(remark = "新建预制二维码")
@PostMapping
public ApiRes add() {
// 处理金额类型
handleParamAmount("fixedPayAmount");
MchQrcodeCard mchQrCode = getObject(MchQrcodeCard.class);
if(StringUtils.isEmpty(mchQrCode.getBatchId())){
throw new BizException("请录入批次号");
}
try {
Long.parseLong(mchQrCode.getBatchId());
}catch (Exception e){
throw new BizException("批次号格式不正确");
}
if(mchQrcodeCardService.count(MchQrcodeCard.gw().eq(MchQrcodeCard::getBatchId, mchQrCode.getBatchId())) > 0){
throw new BizException("批次号已存在,请重新填写");
}
mchQrCode.setBindState(CS.NO); // 未绑定
int addNum = mchQrCode.extv().getInteger("addNum");
if(addNum > 9999){
throw new BizException("新建数量不能超过9999");
}
for (int i = 0; i < addNum; i++) {
mchQrCode.setQrcId( Long.parseLong(String.format("%s%04d", mchQrCode.getBatchId(), (i + 1) ) )); // 避免 赋值ID
boolean result = mchQrcodeCardService.addQrCode(mchQrCode, MchQrcodeCard.QRC_BELONG_TYPE_ISV_PRE);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
}
return ApiRes.ok();
}
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_QRC_VIEW', 'ENT_DEVICE_QRC_EDIT')")
@GetMapping("/{recordId}")
public ApiRes detail(@PathVariable("recordId") Long recordId) {
MchQrcodeCard dbRecord = mchQrcodeCardService.getById(recordId);
if (dbRecord == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(dbRecord);
}
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_EDIT')")
@MethodLog(remark = "更新二维码信息")
@PutMapping("/{recordId}")
public ApiRes update(@PathVariable("recordId") Long recordId) {
// 处理金额类型
handleParamAmount("fixedPayAmount");
MchQrcodeCard mchQrCode = getObject(MchQrcodeCard.class);
mchQrCode.setBatchId(null); // 批次号不允许变更
mchQrCode.setQrcId(recordId);
mchQrCode.setCreatedAt(null);
mchQrCode.setUpdatedAt(null);
boolean result = mchQrcodeCardService.updateById(mchQrCode);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_DEL')")
@MethodLog(remark = "删除二维码")
@DeleteMapping
public ApiRes delete() {
String delQrcIds = getValStringRequired("delQrcIds");
List<String> qrcIdList = Arrays.stream(delQrcIds.split(",")).collect(Collectors.toList());
long count = mchQrcodeCardService.count(MchQrcodeCard.gw()
.eq(MchQrcodeCard::getBindState, CS.YES)
.in(MchQrcodeCard::getQrcId, qrcIdList)
);
if (count > 0) {
return ApiRes.customFail("码牌已绑定商户,不可删除!");
}
if(mchQrcodeCardService.removeByIds(qrcIdList)) {
return ApiRes.ok();
}
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2022/1/14 9:45
* @describe: 订单列表数据导出
*/
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_EXPORT')")
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() throws Exception{
String exportModel = getValStringRequired("exportModel");
MchQrcodeCard mchQrcodeCard = getObject(MchQrcodeCard.class);
LambdaQueryWrapper<MchQrcodeCard> wrapper = MchQrcodeCard.gw();
if(mchQrcodeCardService.countByWrapper(mchQrcodeCard) > 500){
throw new BizException("导出数量不可超过500");
}
IPage<MchQrcodeCard> pages = mchQrcodeCardService.listByPage(getIPage(true), mchQrcodeCard, wrapper);
// 查询当前系统配置信息
DBApplicationConfig dbApplicationConfig = sysConfigService.getDBApplicationConfig();
// Excel: 信息和url
if ("infoAndUrl".equals(exportModel)) {
try {
List<JSONObject> newList = new LinkedList<>();
for (MchQrcodeCard qrcodeCard:pages.getRecords()) {
MchStore mchStore = mchStoreService.getById(qrcodeCard.getStoreId());
if(StringUtils.isNotEmpty(qrcodeCard.getStoreId()) && !"0".equals(qrcodeCard.getStoreId())){
qrcodeCard.setStoreName(mchStore.getStoreName());
}
MchApplyment applyment = mchApplymentService.getById(qrcodeCard.getMchApplyId());
JSONObject object = (JSONObject) JSONObject.toJSON(qrcodeCard);
object.put("fixedPayAmount", AmountUtil.convertCent2Dollar(qrcodeCard.getFixedPayAmount()));
object.put("qrCodeUrl", dbApplicationConfig.genUniJsapiPayUrl(QRCodeParams.TYPE_QRC, qrcodeCard.getEntryPage(), qrcodeCard.getQrcId() + "", applyment.getIsvNo()));
newList.add(object);
}
List<MchQrCodesExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), MchQrCodesExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "码牌", "码牌", MchQrCodesExportExcel.class, "码牌", response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出二维码失败!");
}
// 模板图片 || 纯二维码 || 二维码包含ID
}else if ("templateImg".equals(exportModel) || "qrcode".equals(exportModel) || "qrcodeAndQrcId".equals(exportModel) ) {
//文件的名称
String downloadFilename = "qrcode_" + DateUtil.today() + ".zip";
//设置格式
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(downloadFilename, "UTF-8"));
ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
// 查询所有的模板数据
Map<Long, MchQrcShell> map = new HashMap<>();
pages.getRecords().forEach(r -> map.put(r.getQrcShellId(), null));
if(!map.keySet().isEmpty()){
mchQrcShellService.list(MchQrcShell.gw().in(MchQrcShell::getSid, map.keySet())).forEach(r -> {
map.put(r.getSid(), r);
});
}
for (MchQrcodeCard qrcodeCard:pages.getRecords()) {
String mchStoreName = "";
if(qrcodeCard.getBindState() == CS.YES && qrcodeCard.getStoreId() != null && !"-1".equals(qrcodeCard.getStoreId())){
MchStore mchStore = mchStoreService.getById(qrcodeCard.getStoreId());
mchStoreName = mchStore != null ? mchStore.getStoreName() : "";
}
BufferedImage bufferedImage = null;
MchQrcShell mchQrcShell = map.get(qrcodeCard.getQrcShellId());
AbstractGenerator abstractGenerator = SpringBeansUtil.getBean(ShellQRGenerator.class);
if(mchQrcShell != null && "templateImg".equals(exportModel)){ //存在模板 && 显式导出模板
abstractGenerator = getAbstractGenerator(mchQrcShell.getStyleCode());
}
String configStr = null;
if("templateImg".equals(exportModel)){ // 模板图片
if(mchQrcShell != null){
configStr = mchQrcShell.getConfigInfo();
}
}else if("qrcode".equals(exportModel)){ // 纯二维码不包含ID
configStr = "{showIdFlag: false}";
}else if("qrcodeAndQrcId".equals(exportModel)){ // 二维码 + ID
configStr = "{showIdFlag: true}";
}
MchApplyment applyment = mchApplymentService.getById(qrcodeCard.getMchApplyId());
bufferedImage = abstractGenerator
.genQrImgBuffer(configStr,
dbApplicationConfig.genUniJsapiPayUrl(QRCodeParams.TYPE_QRC, qrcodeCard.getEntryPage(), qrcodeCard.getQrcId() + "", applyment.getIsvNo()),
qrcodeCard.getQrcId(),
mchStoreName,
false
);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", out);
InputStream is = new ByteArrayInputStream(out.toByteArray());
zos.putNextEntry(new ZipEntry( qrcodeCard.getQrcId() + ".png"));
byte[] buffer = new byte[1024];
int r = 0;
while ((r = is.read(buffer)) != -1) {
zos.write(buffer, 0, r);
}
is.close();
is = null;
out.close();
out = null;
zos.flush();
}
zos.flush();
zos.close();
}
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 绑定码牌
*/
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_EDIT')")
@PutMapping("/bind/{recordId}")
public ApiRes bind(@PathVariable("recordId") Long recordId) {
String mchNo = getValStringRequired("mchNo");
String appId = getValStringRequired("appId");
String storeId = getValStringRequired("storeId");
String mchApplyId=getValStringRequired("mchApplyId");
MchInfo mchInfo = mchInfoService.getById(mchNo);
if (mchInfo == null) {
throw new BizException("商户不存在");
}
MchQrcodeCard dbRecord = mchQrcodeCardService.getById(recordId);
if (StringUtils.isNotBlank(dbRecord.getAgentNo()) && !dbRecord.getAgentNo().equals(mchInfo.getAgentNo())) {
throw new BizException("选择的商户不属于设备已划拨的服务商,请收回设备或绑定其他商户");
}
MchQrcodeCard updateRecord = new MchQrcodeCard();
updateRecord.setQrcId(recordId).setMchNo(mchNo).setStoreId(storeId).setAppId(appId).setMchApplyId(mchApplyId).setBindState(CS.YES).setAgentNo(mchInfo.getAgentNo());
mchQrcodeCardService.bindEmptyQR(updateRecord);
return ApiRes.ok();
}
/**
* @Author: zx
* @Description: 解绑码牌
* @Date: 15:59 2022/5/30
*/
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_EDIT')")
@PostMapping("/unbind/{qrcId}")
public ApiRes unbind(@PathVariable("qrcId") Long qrcId) {
MchQrcodeCard dbRecord = mchQrcodeCardService.getById(qrcId);
if (dbRecord == null) {
return ApiRes.customFail("解绑失败");
}
mchQrcodeCardService.unbind(dbRecord);
return ApiRes.ok();
}
/**
* @Author: zx
* @Description: 查看码牌绑定的设备列表
* @Date: 15:59 2022/5/30
*/
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_EDIT')")
@GetMapping("/bindDevice/{qrcId}")
public ApiRes bindDevice(@PathVariable("qrcId") Long qrcId) {
MchQrcodeCard dbRecord = mchQrcodeCardService.getById(qrcId);
if (dbRecord == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
IPage<MchStoreDevice> page = mchQrcodeCardService.getBindDevice(getIPage(), dbRecord, null);
return ApiRes.page(page);
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 划拨码牌给服务商
*/
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_ALLOT')")
@PostMapping("/allotQrc")
public ApiRes allotQrc() {
String allotType = getValStringRequired("allotType"); // 划拨类型select-勾选划拨 batch-批次划拨 range-区间划拨
String allotOrRecover = getValStringRequired("allotOrRecover"); // 分配类型allot-划拨 recover-收回
List<Long> qrcIdList = new LinkedList<>();
// 构建批量更新设备ID集合
if (allotType.equals("select")) {
String allotds = getValStringRequired("allotIds");
qrcIdList = Arrays.stream(allotds.split(",")).map(Long::parseLong).collect(Collectors.toList());
}else if (allotType.equals("batch")) {
String batchId = getValStringRequired("batchId");
List<MchQrcodeCard> list = mchQrcodeCardService.list(MchQrcodeCard.gw().eq(MchQrcodeCard::getBatchId, batchId));
if (CollUtil.isEmpty(list)) {
throw new BizException("批次号错误");
}
for (MchQrcodeCard mchQrcodeCard : list) {
qrcIdList.add(mchQrcodeCard.getQrcId());
}
} else if (allotType.equals("range")) {
String startQrcId=getValStringRequired("startQrcId");
String endQrcId=getValStringRequired("endQrcId");
List<MchQrcodeCard> list = mchQrcodeCardService.list(MchQrcodeCard.gw().ge(MchQrcodeCard::getQrcId, startQrcId)
.le(MchQrcodeCard::getQrcId, endQrcId));
if (CollUtil.isEmpty(list)) {
throw new BizException("区间不存在相应码牌数据");
}
for (MchQrcodeCard mchQrcodeCard : list) {
qrcIdList.add(mchQrcodeCard.getQrcId());
}
} else {
throw new BizException("划拨类型错误");
}
if (CollUtil.isEmpty(qrcIdList)) {
throw new BizException("请选择码牌");
}
// 1、收回码牌
if (allotOrRecover.equals("recover")) {
mchQrcodeCardService.recoverQrc(true, qrcIdList, null, null);
return ApiRes.ok();
}
// 2、划拨码牌
String agentNo = getValStringRequired("agentNo");
List<String> mchNoList = getMchNoListByAgentNo(agentNo);
mchQrcodeCardService.allotQrc(true, agentNo, qrcIdList, mchNoList, null);
return ApiRes.ok();
}
/** 查询支付系统的地址 **/
@GetMapping("/paySiteUrl")
public ApiRes paySiteUrl() {
String paySiteUrl = sysConfigService.getDBApplicationConfig().getPaySiteUrl();
return ApiRes.ok(paySiteUrl);
}
/** 区间划拨码牌 提前校验接口 **/
@PostMapping("/check4RangeAllot")
public ApiRes check4RangeAllot() {
List<MchQrcodeCard> qrcList = getRangeQrcList();
List<Long> qrcIdList = qrcList.stream().map(MchQrcodeCard::getQrcId).collect(Collectors.toList());
if (qrcIdList.size() <= 10) {
return ApiRes.ok("将划拨【" + CollUtil.join(qrcIdList, ",") + "】共" + qrcIdList.size() + "个码牌");
}else {
String beforeStr = CollUtil.join(CollUtil.sub(qrcIdList, 0, 3), ",");
String afterStr = CollUtil.join(CollUtil.sub(qrcIdList, qrcIdList.size() - 4, qrcIdList.size() - 1), ",");
return ApiRes.ok("将划拨【" + beforeStr + "..." + afterStr + "】等共" + qrcIdList.size() + "个码牌");
}
}
private AbstractGenerator getAbstractGenerator(String code){
AbstractGenerator generator = SpringBeansUtil.getBean(code + "Generator", AbstractGenerator.class);
if(generator == null){
throw new BizException("选择模板[" + code + "]不存在!");
}
return generator;
}
/** 按码牌ID区间划拨码牌时获取区间内的码牌ID列表 **/
private List<MchQrcodeCard> getRangeQrcList(){
try {
Long.parseLong(getValStringRequired("startQrcId"));
Long.parseLong(getValStringRequired("endQrcId"));
}catch (Exception e){
throw new BizException("起始或截止码牌ID格式不正确");
}
Long startQrcId = getValLongRequired("startQrcId");
Long endQrcId = getValLongRequired("endQrcId");
List<MchQrcodeCard> list = mchQrcodeCardService.list(MchQrcodeCard.gw().between(MchQrcodeCard::getQrcId, startQrcId, endQrcId).orderByAsc(MchQrcodeCard::getQrcId));
if (CollUtil.isEmpty(list)) {
throw new BizException("当前ID区间无码牌请检查起止码牌ID是否正确");
}
return list;
}
}

View File

@@ -0,0 +1,180 @@
package com.jeequan.jeepay.mgr.ctrl.qrcode;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.zxing.WriterException;
import com.jeequan.jeepay.bizcommons.manage.qrshell.AbstractGenerator;
import com.jeequan.jeepay.bizcommons.manage.qrshell.ShellQRGenerator;
import com.jeequan.jeepay.components.oss.ctrl.OssFileController;
import com.jeequan.jeepay.components.oss.model.MockMultipartFile;
import com.jeequan.jeepay.components.oss.model.OssFileConfig;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.QRCodeParams;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.db.entity.MchQrcShell;
import com.jeequan.jeepay.db.entity.MchQrcodeCard;
import com.jeequan.jeepay.db.entity.MchStore;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchQrcShellService;
import com.jeequan.jeepay.service.impl.MchQrcodeCardService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
/**
* 二维码模板管理
*
* @author terrfly
*
* @date 2022/1/17 14:22
*/
@RestController
@RequestMapping("/api/mchQrcShells")
public class MchQrcShellController extends CommonCtrl {
@Autowired private MchQrcodeCardService mchQrcodeCardService;
@Autowired private MchQrcShellService mchQrcShellService;
@Autowired private SysConfigService sysConfigService;
@Autowired private OssFileController ossFileController;
@Autowired private MchApplymentService mchApplymentService;
@GetMapping
public ApiRes list() {
// 构造查询条件
MchQrcShell mchQrCode = getObject(MchQrcShell.class);
mchQrCode.setSysType(CS.SYS_ROLE_TYPE.PLATFORM);
LambdaQueryWrapper<MchQrcShell> lambdaQueryWrapper = MchQrcShell.gw();
lambdaQueryWrapper.eq(MchQrcShell::getSysType, CS.SYS_ROLE_TYPE.PLATFORM);
IPage<MchQrcShell> records = mchQrcShellService.page(getIPage(true), lambdaQueryWrapper);
return ApiRes.ok(records);
}
@MethodLog(remark = "新建模板")
@PostMapping
public ApiRes add() throws IOException, WriterException {
MchQrcShell record = getObject(MchQrcShell.class);
record.setSysType(CS.SYS_ROLE_TYPE.PLATFORM);
record.setBelongInfoId("0");
MchQrcShell qrcShell = mchQrcShellService.getDefaultTemplate(CS.SYS_ROLE_TYPE.PLATFORM);
qrcShell.setIsDefault(qrcShell == null ? CS.YES : CS.NO);
// 示例图片
InputStream inputStreamByView = AbstractGenerator.convertInputStream(getAbstractGenerator(record.getStyleCode()).genQrImgBuffer(record.getConfigInfo(), "示例", 18888L, "示例门店名称", true));
String viewUrl = ossFileController.singleFileUpload(new MockMultipartFile(UUID.fastUUID() + ".png", 1L, inputStreamByView), OssFileConfig.BIZ_TYPE.QRC);
record.setShellImgViewUrl(viewUrl); //预览图
mchQrcShellService.save(record);
return ApiRes.ok();
}
@GetMapping("/{recordId}")
public ApiRes detail(@PathVariable("recordId") Long recordId) {
return ApiRes.ok(mchQrcShellService.getById(recordId));
}
@MethodLog(remark = "更新模板信息")
@PutMapping("/{recordId}")
public ApiRes update(@PathVariable("recordId") Long recordId) throws IOException, WriterException {
MchQrcShell record = getObject(MchQrcShell.class);
MchQrcShell dbRecord = mchQrcShellService.getById(recordId);
// 发生了变化
if(!dbRecord.getConfigInfo().equals(record.getConfigInfo())){
// 示例图片
InputStream inputStreamByBiew = AbstractGenerator.convertInputStream(getAbstractGenerator(dbRecord.getStyleCode()).genQrImgBuffer(record.getConfigInfo(), "示例", 188L, "示例门店名称",true));
String viewUrl = ossFileController.singleFileUpload(new MockMultipartFile(UUID.fastUUID() + ".png", 1L, inputStreamByBiew), OssFileConfig.BIZ_TYPE.QRC);
record.setShellImgViewUrl(viewUrl); //预览图
}
record.setSid(recordId);
record.setStyleCode(null); //类型不允许修改
mchQrcShellService.updateById(record);
return ApiRes.ok();
}
@MethodLog(remark = "删除二维码")
@DeleteMapping("/{recordId}")
public ApiRes delete(@PathVariable("recordId") Long recordId) {
mchQrcShellService.removeById(recordId);
return ApiRes.ok();
}
/** 预览二维码 **/
@PostMapping("/view")
public ApiRes view() throws Exception {
String configModelStr = getValStringRequired("configModelStr");
AbstractGenerator generator = getAbstractGenerator(getValStringRequired("styleCode"));
Long viewQrId = 220101000001L;
BufferedImage bufferedImage = generator.genQrImgBuffer(configModelStr, "示例", viewQrId, "示例门店名称",true);
//给前端拼接上 【 data:image/jpg;base64 】
return ApiRes.ok("data:image/jpg;base64,"+ AbstractGenerator.convertImgBase64(bufferedImage));
}
/** 根据qrcId获取图片base64 **/
@GetMapping("/viewByQrc/{qrcId}")
public ApiRes viewByQrc(@PathVariable("qrcId") Long qrcId) throws Exception {
MchQrcodeCard dbRecord = mchQrcodeCardService.getById(qrcId);
String mchStoreName = "";
if(dbRecord.getBindState() == CS.YES && dbRecord.getStoreId() != null && !"-1".equals(dbRecord.getStoreId())){
MchStore mchStore = mchStoreService.getById(dbRecord.getStoreId());
mchStoreName = mchStore != null ? mchStore.getStoreName() : "";
}
MchApplyment applyment = mchApplymentService.getById(dbRecord.getMchApplyId());
// 封装URL
String qrUrlContent = sysConfigService.getDBApplicationConfig().genUniJsapiPayUrl(QRCodeParams.TYPE_QRC, dbRecord.getEntryPage(), qrcId + "", applyment.getIsvNo());
if(dbRecord.getQrcShellId() == null || dbRecord.getQrcShellId() <= 0){
//给前端拼接上 【 data:image/jpg;base64 】
AbstractGenerator shellQRGenerator = SpringBeansUtil.getBean(ShellQRGenerator.class);
return ApiRes.ok("data:image/jpg;base64,"+ AbstractGenerator.convertImgBase64(shellQRGenerator.genQrImgBuffer(null, qrUrlContent, qrcId, mchStoreName, false)));
}
MchQrcShell mchQrcShell = mchQrcShellService.getById(dbRecord.getQrcShellId());
AbstractGenerator generator = getAbstractGenerator(mchQrcShell.getStyleCode());
BufferedImage bufferedImage = generator.genQrImgBuffer(mchQrcShell.getConfigInfo(), qrUrlContent, qrcId, mchStoreName, false);
//给前端拼接上 【 data:image/jpg;base64 】
return ApiRes.ok("data:image/jpg;base64,"+ AbstractGenerator.convertImgBase64(bufferedImage));
}
private AbstractGenerator getAbstractGenerator(String code){
AbstractGenerator generator = SpringBeansUtil.getBean(code + "Generator", AbstractGenerator.class);
if(generator == null){
throw new BizException("选择模板[" + code + "]不存在!");
}
return generator;
}
}

View File

@@ -0,0 +1,91 @@
package com.jeequan.jeepay.mgr.ctrl.route;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.Route;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.RouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/**
* 商户路由管理类
*
* @date 2021-06-16 09:15
*/
@RestController
@RequestMapping("/api/route")
public class RouteController extends CommonCtrl {
@Autowired
private RouteService routeService;
/**
* @Description: 商户路由列表
* @since 2024/04/19
*/
@GetMapping
public ApiRes list() {
Route entity = getObject(Route.class);
IPage<Route> pages = routeService.pageList(getIPage(true), entity);
return ApiRes.page(pages);
}
@PreAuthorize("hasAuthority('ENT_ROUTE_ADD')")
@MethodLog(remark = "新增路由策略")
@PostMapping
public ApiRes add() {
Route entity = getObject(Route.class);
SysUser sysUser = getCurrentUser().getSysUser();
entity.setCreatedUid(sysUser.getSysUserId());
entity.setCreatedBy(sysUser.getRealname());
entity.setRouteId(SeqKit.genFlowNo("RU"));
routeService.addSave(entity);
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_ROUTE_EDIT')")
@MethodLog(remark = "修改路由信息")
@PutMapping("/{id}")
public ApiRes update(@PathVariable("id") String id) {
Route entity = getObject(Route.class).setRouteId(id);
entity.preCheck();
routeService.updateById(entity);
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_ROUTE_DEL')")
@MethodLog(remark = "删除路由")
@DeleteMapping("/{id}")
public ApiRes delete(@PathVariable("id") String id) {
routeService.del(id);
return ApiRes.ok();
}
/**
* 数据统计
* @return
*/
@GetMapping("/count")
public ApiRes count() {
Route entity = getObject(Route.class);
PayOrderCount count = routeService.totalCount(entity);
return ApiRes.ok(count);
}
/**
* 获取二维码
* @return
*/
@GetMapping("/qrcode/{id}")
public ApiRes qrcode(@PathVariable("id") String id) {
String url = routeService.getQrCode(id);
return ApiRes.ok(url);
}
}

View File

@@ -0,0 +1,45 @@
package com.jeequan.jeepay.mgr.ctrl.route;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.PayOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 路由运行策略
* @date 2021-06-16 09:15
*/
@RestController
@RequestMapping("/api/routeData")
public class RouteDataController extends CommonCtrl {
@Autowired
private PayOrderService payOrderService;
/**
* @Description: 分页查询
* @since 2024/04/19
*/
@GetMapping
public ApiRes list() {
PayOrderCount entity = getObject(PayOrderCount.class);
IPage<PayOrderCount> pages = payOrderService.routePageList(getIPage(true), entity);
return ApiRes.page(pages);
}
/**
* 统计
* @return
*/
@GetMapping("/count")
public ApiRes count() {
PayOrderCount entity = getObject(PayOrderCount.class);
PayOrderCount orderCount = payOrderService.routeCount(entity);
return ApiRes.ok(orderCount);
}
}

View File

@@ -0,0 +1,73 @@
package com.jeequan.jeepay.mgr.ctrl.route;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.RouteManage;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.RouteManageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.List;
/**
*
*
* @date 2021-06-16 09:15
*/
@RestController
@RequestMapping("/api/routeManage")
public class RouteManageController extends CommonCtrl {
@Autowired
private RouteManageService routeManageService;
/**
* @Description: 商户路由列表
* @since 2024/04/19
*/
@GetMapping
public ApiRes list() {
RouteManage entity = getObject(RouteManage.class);
IPage<RouteManage> pages = routeManageService.pageList(getIPage(true), entity);
return ApiRes.page(pages);
}
@PreAuthorize("hasAuthority('ENT_ROUTE_MANAGE_ADD')")
@MethodLog(remark = "绑定门店路由")
@PostMapping
public ApiRes add() {
RouteManage entity = getObject(RouteManage.class);
routeManageService.addSave(entity);
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_ROUTE_MANAGE_EDIT')")
@MethodLog(remark = "修改路由绑定信息")
@PutMapping("/{id}")
public ApiRes update(@PathVariable("id") String id) {
RouteManage entity = getObject(RouteManage.class).setStoreId(id);
List<String> amtRange = entity.getAmtRange();
if(amtRange != null){
amtRange.stream().map(amt -> {
amtRange.replaceAll(value -> new BigDecimal(value).multiply(BigDecimal.valueOf(100)).toString());
return amtRange;
});
}
routeManageService.updateById(entity);
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_ROUTE_MANAGE_DEL')")
@MethodLog(remark = "删除路由绑定")
@DeleteMapping("/{id}")
public ApiRes delete(@PathVariable("id") String id) {
routeManageService.removeById(id);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,34 @@
package com.jeequan.jeepay.mgr.ctrl.route;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.RouteRecord;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.RouteRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 路由运行策略
* @date 2021-06-16 09:15
*/
@RestController
@RequestMapping("/api/routeRecord")
public class RouteRecordController extends CommonCtrl {
@Autowired
private RouteRecordService routeRecordService;
/**
* @Description: 分页查询
* @since 2024/04/19
*/
@GetMapping
public ApiRes list() {
RouteRecord entity = getObject(RouteRecord.class);
IPage<RouteRecord> pages = routeRecordService.pageList(getIPage(true), entity);
return ApiRes.page(pages);
}
}

View File

@@ -0,0 +1,121 @@
package com.jeequan.jeepay.mgr.ctrl.settle;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.export.SettleInfoExportExcel;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.db.entity.PayInterfaceDefine;
import com.jeequan.jeepay.db.entity.SettleInfo;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.PayInterfaceDefineService;
import com.jeequan.jeepay.service.impl.SettleInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* TODO
*
* @author crystal
* @date 2023/12/6 15:11
*/
@RestController
@RequestMapping("/api/settle")
public class SettleInfoController extends CommonCtrl {
@Autowired private SettleInfoService settleInfoService;
@Autowired private PayInterfaceDefineService payInterfaceDefineService;
@GetMapping
public ApiRes list() {
SettleInfo info = getObject(SettleInfo.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<SettleInfo> wrapper = SettleInfo.gw();
Page<SettleInfo> pages = settleInfoService.pageList(getIPage(), wrapper,info,paramJSON);
Map<String, String> ifCodeMap = new HashMap<>();
List<PayInterfaceDefine> list = payInterfaceDefineService.list();
if(!list.isEmpty()){
for (PayInterfaceDefine define:list) {
ifCodeMap.put(define.getIfCode(), define.getIfName());
}
}
for (SettleInfo data:pages.getRecords()) {
if(StringUtils.isNotBlank(data.getIfCode())){
data.setIfName(ifCodeMap.get(data.getIfCode()));
}
}
return ApiRes.page(pages);
}
/**
* 结算信息导出
*/
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() {
try {
SettleInfo info = getObject(SettleInfo.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<SettleInfo> wrapper = SettleInfo.gw(info);
Page<SettleInfo> pages = settleInfoService.pageList(getIPage(), wrapper,info,paramJSON);
Map<String, String> ifCodeMap = new HashMap<>();
List<PayInterfaceDefine> list = payInterfaceDefineService.list();
if(!list.isEmpty()){
for (PayInterfaceDefine define:list) {
ifCodeMap.put(define.getIfCode(), define.getIfName());
}
}
List<JSONObject> newList = new LinkedList<>();
if (!pages.getRecords().isEmpty()){
//成功交易总笔数
List<SettleInfo> infoList = pages.getRecords().stream().filter(p -> p.getState() == 2).collect(Collectors.toList());
//成功交易总金额
BigDecimal allSuccessAmount = BigDecimal.ZERO;
for (SettleInfo settleInfo : infoList) {
allSuccessAmount=allSuccessAmount.add(BigDecimal.valueOf(settleInfo.getSettleAmt()));
}
for (SettleInfo data:pages.getRecords()) {
if(StringUtils.isNotBlank(data.getIfCode())){
data.setIfName(ifCodeMap.get(data.getIfCode()));
}
JSONObject object = (JSONObject) JSONObject.toJSON(data);
newList.add(object);
}
}
List<SettleInfoExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), SettleInfoExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "结算信息", "结算信息", SettleInfoExportExcel.class, "结算信息", response);
}catch (Exception e){
logger.error("导出excel失败", e);
throw new BizException("导出结算信息失败!");
}
}
@GetMapping("/count")
public ApiRes getCount(){
SettleInfo info = getObject(SettleInfo.class);
LambdaQueryWrapper<SettleInfo> wrapper = SettleInfo.gw();
// 时间范围条件
Date[] dateRange = info.buildQueryDateRange();
if (dateRange[0] != null) {
wrapper.ge(SettleInfo::getUpdatedAt, dateRange[0]);
}
if (dateRange[1] != null) {
wrapper.le(SettleInfo::getUpdatedAt, dateRange[1]);
}
List<SettleInfo> infoList = settleInfoService.list(wrapper);
return settleInfoService.getCount(infoList);
}
}

View File

@@ -0,0 +1,188 @@
package com.jeequan.jeepay.mgr.ctrl.statistics;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.export.statistic.*;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.StatsChannelService;
import com.jeequan.jeepay.service.impl.StatsDeviceService;
import com.jeequan.jeepay.service.impl.StatsPayWayService;
import com.jeequan.jeepay.service.impl.StatsTradeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* 统计列表接口
*
* @author xiaoyu
*
* @date 2022/5/23 16:52
*/
@Slf4j
@RestController
@RequestMapping("/api/statistic/export")
public class ExportExcelStatisticController extends CommonCtrl {
@Autowired private StatsTradeService statsTradeService;
@Autowired private StatsChannelService statsChannelService;
@Autowired private StatsPayWayService statsPayWayService;
@Autowired private StatsDeviceService statsDeviceService;
/**
* @author: xiaoyu
* @date: 2022/5/23 17:15
* @describe: 统计列表
*/
@PreAuthorize("hasAnyAuthority('ENT_STATISTIC_TRANSACTION', 'ENT_STATISTIC_MCH', 'ENT_STATISTIC_MCH_STORE', 'ENT_STATISTIC_MCH_WAY', 'ENT_STATISTIC_MCH_TYPE', 'ENT_STATISTIC_AGENT', 'ENT_STATISTIC_ISV', 'ENT_STATISTIC_CHANNEL')")
@RequestMapping(value="", method = RequestMethod.GET)
public void list() {
JSONObject paramJSON = getReqParamJSON();
PayOrder payOrder = getObject(PayOrder.class);
String method = getValStringRequired("method");
String mchNo = null;
Page<PayOrderCount> mapPage = new Page<>();
switch (method) {
case CS.STATISTIC_TYPE.MCH:
// 商户
// mapPage = payOrderService.countListByMch(payOrder, paramJSON, null);
mapPage = statsTradeService.selectMchStatsList(paramJSON, null);
exportExcel(mapPage, StatisticMchExportExcel.class, "商户统计");
break;
case CS.STATISTIC_TYPE.AGENT:
// 服务商
// mapPage = payOrderService.countListByAgent(payOrder, paramJSON, null);
mapPage = statsTradeService.selectAgentStatsList(paramJSON, null);
exportExcel(mapPage, StatisticAgentExportExcel.class, "服务商统计");
break;
case CS.STATISTIC_TYPE.ISV:
// 服务商
// mapPage = payOrderService.countListByIsv(payOrder, paramJSON);
mapPage = statsTradeService.selectIsvStatsList(paramJSON);
exportExcel(mapPage, StatisticIsvExportExcel.class, "服务商统计");
break;
case CS.STATISTIC_TYPE.CHANNEL:
// 通道
// mapPage = payOrderService.countListByChannel(payOrder, paramJSON);
mapPage = statsChannelService.selectStatsList(paramJSON);
exportExcel(mapPage, StatisticChannelExportExcel.class, "通道统计");
break;
case CS.STATISTIC_TYPE.TRANSACTION:
// 交易报表
// mapPage = payOrderService.countListByTransaction(payOrder, paramJSON, null);
mapPage = statsTradeService.selectTransactionStatsList(payOrder, paramJSON, null);
exportExcel(mapPage, StatisticTransactionExportExcel.class, "交易报表");
break;
case CS.STATISTIC_TYPE.STORE:
// 门店
getValStringRequired("mchNo");
// payOrder.setMchNo(mchNo);
// mapPage = payOrderService.countListByStore(payOrder, paramJSON);
mapPage = statsTradeService.selectStoreStatsList(paramJSON);
exportExcel(mapPage, StatisticStoreExportExcel.class, "门店统计");
break;
case CS.STATISTIC_TYPE.WAY_CODE:
// 支付方式
getValStringRequired("mchNo");
// payOrder.setMchNo(mchNo);
// mapPage = payOrderService.countListByWayCode(payOrder, paramJSON);
mapPage = statsPayWayService.selectPayWayStatsList(paramJSON);
exportExcel(mapPage, StatisticWayCodeExportExcel.class, "支付方式统计");
break;
case CS.STATISTIC_TYPE.WAY_CODE_TYPE:
// 支付类型
getValStringRequired("mchNo");
// payOrder.setMchNo(mchNo);
// mapPage = payOrderService.countListByWayCodeType(payOrder, paramJSON);
mapPage = statsPayWayService.selectWayCodeTypeStatsList(paramJSON);
exportExcel(mapPage, StatisticWayCodeTypeExportExcel.class, "支付类型统计");
break;
case CS.STATISTIC_TYPE.DEVICE:
// 通道统计
// mapPage = payOrderService.countListByDevice(payOrder, paramJSON, null);
mapPage = statsDeviceService.selectStatsList(paramJSON, null);
exportExcel(mapPage, StatisticDeviceExportExcel.class, "设备统计");
break;
default:
break;
}
}
public List<String> getAgentSubList(JSONObject paramJSON, PayOrder payOrder) {
List<String> allAgentNoList = null;
if (StringUtils.isNotEmpty(payOrder.getAgentNo())) {
Boolean onlyOne = paramJSON.getBoolean("onlyOne");
if (onlyOne) {
// 仅查询单个服务商
allAgentNoList = Arrays.asList(payOrder.getAgentNo());
}else {
// 查询服务商所有下级
allAgentNoList = agentInfoService.queryAllSubAgentNo(payOrder.getAgentNo());
}
}
return allAgentNoList;
}
/** 通用导出类 **/
public void exportExcel(Page<PayOrderCount> mapPage, Class clazz, String title) {
try {
List<JSONObject> newList = new LinkedList<>();
mapPage.getRecords().stream().forEach(record -> {
JSONObject resItem = (JSONObject) JSONObject.toJSON(record);
// 交易金额转换
BigDecimal allAmount = BigDecimal.valueOf(record.getTotalSuccAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
resItem.put("allAmount", allAmount);
// 实收金额转换
BigDecimal payAmount = BigDecimal.valueOf(record.getTotalFinalAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
resItem.put("payAmount", payAmount);
// 退款金额转换
BigDecimal refundAmount = BigDecimal.valueOf(record.getTotalRefundAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
resItem.put("refundAmount", refundAmount);
//手续费
if (record.getTotalFeeAmt() != null){
BigDecimal totalfeeamt = BigDecimal.valueOf(record.getTotalFeeAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
resItem.put("totalFeeAmt", totalfeeamt);
}
//手续费回退
if (record.getTotalRefundFeeAmt() != null){
BigDecimal totalReFeeAmt= BigDecimal.valueOf(record.getTotalRefundFeeAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
resItem.put("totalRefundFeeAmt", totalReFeeAmt);
}
// 成功率
resItem.put("round", record.getSuccRate() + "%");
if (StringUtils.isNotBlank(record.getDeviceType())) {
resItem.put("deviceType", PayOrder.DEVICE_TYPE_MAP.get(record.getDeviceType()));
}
newList.add(resItem);
});
List<T> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), clazz);
// excel输出
ExcelUtil.exportExcel(linkedList, title, title, clazz, title, response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出订单失败!");
}
}
}

View File

@@ -0,0 +1,152 @@
package com.jeequan.jeepay.mgr.ctrl.statistics;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.db.entity.StatsTaskRecord;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
/**
* 统计列表接口
*
* @author xiaoyu
*
* @date 2022/5/23 16:52
*/
@Slf4j
@RestController
@RequestMapping("/api/statistic")
public class StatisticController extends CommonCtrl {
@Autowired private StatsTradeService statsTradeService;
@Autowired private StatsChannelService statsChannelService;
@Autowired private StatsPayWayService statsPayWayService;
@Autowired private StatsDeviceService statsDeviceService;
@Autowired private StatsTaskRecordService statsTaskRecordService;
@Autowired private PayOrderService payOrderService;
/**
* @author: xiaoyu
* @date: 2022/5/23 17:15
* @describe: 统计列表
*/
@PreAuthorize("hasAnyAuthority('ENT_STATISTIC_TRANSACTION', 'ENT_STATISTIC_MCH', 'ENT_STATISTIC_MCH_STORE', 'ENT_STATISTIC_MCH_WAY', 'ENT_STATISTIC_MCH_TYPE', 'ENT_STATISTIC_AGENT', 'ENT_STATISTIC_ISV', 'ENT_STATISTIC_CHANNEL')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
JSONObject paramJSON = getReqParamJSON();
PayOrder payOrder = getObject(PayOrder.class);
String method = getValStringRequired("method");
String mchNo = null;
Page<PayOrderCount> mapPage = new Page<>();
switch (method) {
case CS.STATISTIC_TYPE.MCH:
// 商户
mapPage = statsTradeService.selectMchStatsList(paramJSON, null);
break;
case CS.STATISTIC_TYPE.AGENT:
// 服务商
mapPage = statsTradeService.selectAgentStatsList(paramJSON, null);
break;
case CS.STATISTIC_TYPE.ISV:
// 服务商
mapPage = statsTradeService.selectIsvStatsList(paramJSON);
break;
case CS.STATISTIC_TYPE.CHANNEL:
// 通道
mapPage = statsChannelService.selectStatsList(paramJSON);
break;
case CS.STATISTIC_TYPE.TRANSACTION:
// 交易报表
mapPage = statsTradeService.selectTransactionStatsList(payOrder, paramJSON, null);
break;
case CS.STATISTIC_TYPE.STORE:
// 门店
getValStringRequired("mchNo");
mapPage = statsTradeService.selectStoreStatsList(paramJSON);
break;
case CS.STATISTIC_TYPE.WAY_CODE:
// 支付方式
getValStringRequired("mchNo");
mapPage = statsPayWayService.selectPayWayStatsList(paramJSON);
break;
case CS.STATISTIC_TYPE.WAY_CODE_TYPE:
// 支付类型
getValStringRequired("mchNo");
mapPage = statsPayWayService.selectWayCodeTypeStatsList(paramJSON);
break;
case CS.STATISTIC_TYPE.DEVICE:
// 设备
mapPage = statsDeviceService.selectStatsList(paramJSON, null);
break;
default:
break;
}
// 解决hasnext不显示的问题
mapPage.setCurrent(paramJSON.getIntValue("pageNumber"));
mapPage.setSize(paramJSON.getIntValue("pageSize"));
return ApiRes.page(mapPage);
}
/**
* @author: zx
* @date: 2022/5/23 17:15
* @describe: 统计数据修复
*/
@PreAuthorize("hasAuthority('ENT_STATISTIC_REPAIR')")
@PostMapping
public ApiRes repair() {
String repairDate = getValString("repairDate");
String mchNo = getValString("mchNo");
Date beginRepairDate; // 开始日期
Date endRepairDate; // 结束日期
if (StringUtils.isBlank(repairDate)) {
PayOrder payOrder = payOrderService.getOne(PayOrder.gw().orderByAsc(PayOrder::getCreatedAt).last("limit 1"));
if (payOrder == null) {
throw new BizException("无可修复订单数据");
}
beginRepairDate = DateUtil.beginOfDay(payOrder.getCreatedAt());
endRepairDate = DateUtil.endOfDay(DateUtil.yesterday());
}else {
String[] repairDateSplit = repairDate.split(",");
beginRepairDate = DateUtil.parseDate(repairDateSplit[0]);
endRepairDate = DateUtil.parseDate(repairDateSplit[1]);
}
// 查询是否存在进行中的数据修复任务
List<StatsTaskRecord> list = statsTaskRecordService.list(StatsTaskRecord.gw()
.eq(StatsTaskRecord::getTaskType, StatsTaskRecord.TASK_TYPE_REPAIR)
.eq(StatsTaskRecord::getState, StatsTaskRecord.TASK_STATE_ING)
);
if (CollUtil.isNotEmpty(list)) {
throw new BizException("请等待上次数据修复任务完成,再执行新任务");
}
// 数据修复任务记录 初始化
Long taskId = statsTaskRecordService.initTask(StatsTaskRecord.TASK_TYPE_REPAIR, beginRepairDate, endRepairDate);
// 异步执行
statsTaskRecordService.repairStats(taskId, beginRepairDate, endRepairDate, mchNo);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,61 @@
package com.jeequan.jeepay.mgr.ctrl.statistics;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.StatsTaskRecord;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.StatsTaskRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 统计任务记录接口
*
* @author zx
*
* @date 2022/5/23 16:52
*/
@Slf4j
@RestController
@RequestMapping("/api/stats/record")
public class StatsTaskRecordController extends CommonCtrl {
@Autowired private StatsTaskRecordService statsTaskRecordService;
/**
* @author: zx
* @date: 2022/5/23 17:15
* @describe: 列表
*/
@PreAuthorize("hasAnyAuthority('ENT_STATISTIC_RECORD_LIST')")
@GetMapping
public ApiRes list() {
StatsTaskRecord record = getObject(StatsTaskRecord.class);
IPage<StatsTaskRecord> page = statsTaskRecordService.page(getIPage(), StatsTaskRecord.gw()
.eq(record.getState() != null, StatsTaskRecord::getState, record.getState())
.eq(record.getTaskType() != null, StatsTaskRecord::getTaskType, record.getTaskType())
.ge(record.getBeginTime() != null, StatsTaskRecord::getBeginTime, record.getBeginTime())
.le(record.getEndTime() != null, StatsTaskRecord::getEndTime, record.getEndTime())
.orderByDesc(StatsTaskRecord::getCreatedAt)
);
return ApiRes.page(page);
}
/**
* @author: zx
* @date: 2022/5/23 17:15
* @describe: 详情
*/
@PreAuthorize("hasAuthority('ENT_STATISTIC_RECORD_VIEW')")
@GetMapping("/{id}")
public ApiRes repair(@PathVariable("id") Long id) {
return ApiRes.ok(statsTaskRecordService.getById(id));
}
}

View File

@@ -0,0 +1,125 @@
package com.jeequan.jeepay.mgr.ctrl.statistics;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.StatsChannelService;
import com.jeequan.jeepay.service.impl.StatsDeviceService;
import com.jeequan.jeepay.service.impl.StatsPayWayService;
import com.jeequan.jeepay.service.impl.StatsTradeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
/**
* 总计接口
*
* @author xiaoyu
*
* @date 2022/5/23 16:52
*/
@Slf4j
@RestController
@RequestMapping("/api/statistic/total")
public class TotalStatisticController extends CommonCtrl {
@Autowired private StatsTradeService statsTradeService;
@Autowired private StatsChannelService statsChannelService;
@Autowired private StatsPayWayService statsPayWayService;
@Autowired private StatsDeviceService statsDeviceService;
/**
* @author: xiaoyu
* @date: 2022/5/23 17:15
* @describe: 总计
*/
@PreAuthorize("hasAnyAuthority('ENT_STATISTIC_TRANSACTION', 'ENT_STATISTIC_MCH', 'ENT_STATISTIC_MCH_STORE', 'ENT_STATISTIC_MCH_WAY', 'ENT_STATISTIC_MCH_TYPE', 'ENT_STATISTIC_AGENT', 'ENT_STATISTIC_ISV', 'ENT_STATISTIC_CHANNEL')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes total() {
JSONObject paramJSON = getReqParamJSON();
String method = getValStringRequired("method");
PayOrderCount orderCount = new PayOrderCount();
switch (method) {
case CS.STATISTIC_TYPE.MCH:
// 商户统计
// resMap = payOrderService.totalByMch(payOrder, paramJSON, null);
orderCount = statsTradeService.selectTotalByMch(paramJSON, null);
break;
case CS.STATISTIC_TYPE.AGENT:
// 服务商统计
// resMap = payOrderService.totalByAgent(payOrder, paramJSON, null);
orderCount = statsTradeService.selectTotalByAgent(paramJSON, null);
break;
case CS.STATISTIC_TYPE.ISV:
// 服务商统计
// resMap = payOrderService.totalByIsv(payOrder, paramJSON);
orderCount = statsTradeService.selectTotalByIsv(paramJSON);
break;
case CS.STATISTIC_TYPE.CHANNEL:
// 通道统计
// resMap = payOrderService.totalByChannel(payOrder, paramJSON);
orderCount = statsChannelService.selectTotalByChannel(paramJSON);
break;
case CS.STATISTIC_TYPE.TRANSACTION:
// 交易报表统计
// resMap = payOrderService.totalByTransaction(payOrder, paramJSON, null);
orderCount = statsTradeService.selectTotalByTransaction(paramJSON, null);
break;
case CS.STATISTIC_TYPE.STORE:
// 门店统计
getValStringRequired("mchNo");
// payOrder.setMchNo(mchNo);
// resMap = payOrderService.totalByStore(payOrder, paramJSON);
orderCount = statsTradeService.selectTotalByStore(paramJSON, null);
break;
case CS.STATISTIC_TYPE.WAY_CODE:
// 支付方式统计
getValStringRequired("mchNo");
// payOrder.setMchNo(mchNo);
// resMap = payOrderService.totalByWayCode(payOrder, paramJSON);
orderCount = statsPayWayService.selectTotalByPayWay(paramJSON);
break;
case CS.STATISTIC_TYPE.WAY_CODE_TYPE:
// 支付类型统计
getValStringRequired("mchNo");
// payOrder.setMchNo(mchNo);
// resMap = payOrderService.totalByWayCodeType(payOrder, paramJSON);
orderCount = statsPayWayService.selectTotalByWayCodeType(paramJSON);
break;
case CS.STATISTIC_TYPE.DEVICE:
// 设备统计
// resMap = payOrderService.totalByDevice(payOrder, paramJSON, null);
orderCount = statsDeviceService.selectTotalByDeviceNo(paramJSON, null);
break;
default:
break;
}
return ApiRes.ok(orderCount);
}
public List<String> getAgentSubList(JSONObject paramJSON, PayOrder payOrder) {
List<String> allAgentNoList = null;
if (StringUtils.isNotEmpty(payOrder.getAgentNo())) {
Boolean onlyOne = paramJSON.getBoolean("onlyOne");
if (onlyOne) {
// 仅查询单个服务商
allAgentNoList = Arrays.asList(payOrder.getAgentNo());
}else {
// 查询服务商所有下级
allAgentNoList = agentInfoService.queryAllSubAgentNo(payOrder.getAgentNo());
}
}
return allAgentNoList;
}
}

View File

@@ -0,0 +1,196 @@
package com.jeequan.jeepay.mgr.ctrl.store;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBApiMapConfig;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.MchStore;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchInfoService;
import com.jeequan.jeepay.service.impl.MchStoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 商户门店管理
*
* @date 2021/12/29 9:52
*/
@RestController
@RequestMapping("/api/mchStore")
public class MchStoreController extends CommonCtrl {
@Autowired
private MchStoreService mchStoreService;
@Autowired
private MchInfoService mchInfoService;
@Autowired
private MchApplymentService mchApplymentService;
/**
* @date: 2021/12/29 9:53
* @describe: 门店列表查询
*/
@GetMapping
@PreAuthorize("hasAuthority('ENT_MCH_STORE_LIST')")
public ApiRes list() {
MchStore mchStore = getObject(MchStore.class);
IPage<MchStore> records = mchStoreService.listByPage(getIPage(true), mchStore, null);
return ApiRes.ok(records);
}
/**
* @date: 2021/12/29 9:59
* @describe: 新建门店
*/
@MethodLog(remark = "新建门店")
@PostMapping
@PreAuthorize("hasAuthority('ENT_MCH_STORE_ADD')")
public ApiRes add() {
MchStore mchStore = getObject(MchStore.class);
// 规则STO + 用户ID + 当前商户的门店序号
mchStore.setStoreId(SeqKit.genStoreNo());
// 所属商户信息是否存在
Assert.hasLength(mchStore.getMchNo(), "用户号[mchNo]不能为空");
Assert.notNull(mchStore.getAreaCode(), "请选择省市区");
MchInfo mchInfo = mchInfoService.getById(mchStore.getMchNo());
Assert.notNull(mchInfo, "用户不存在");
Assert.hasLength(mchStore.getMchApplyId(), "商户号[mchApplyId]不能为空");
MchApplyment tbMchApplyment = mchApplymentService.getById(mchStore.getMchApplyId());
Assert.notNull(tbMchApplyment, "商户不存在");
//关联商户信息原进件信息t_mch_applyment需要校验商户状态必须是进件成功的
if (MchApplyment.STATE_SUCCESS != tbMchApplyment.getState()) {
return ApiRes.customFail("该商户状态未进件成功!");
}
//校验指定商户号下的进件信息
String applyMchNo = tbMchApplyment.getMchNo();
String storeMchNo = mchStore.getMchNo();
if (!applyMchNo.equals(storeMchNo)) {
return ApiRes.customFail("用户信息与商户信息不匹配!");
}
// 初始为非默认门店
mchStore.setDefaultFlag(CS.NO);
mchStore.setAgentNo(mchInfo.getAgentNo());
mchStore.setTopAgentNo(mchInfo.getTopAgentNo());
boolean result = mchStoreService.save(mchStore);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
return ApiRes.ok();
}
/**
* @date: 2021/12/29 9:59
* @describe: 门店详情
*/
@GetMapping("/{recordId}")
@PreAuthorize("hasAuthority('ENT_MCH_STORE_VIEW')")
public ApiRes detail(@PathVariable("recordId") Long recordId) {
MchStore mchStore = mchStoreService.getById(recordId);
return ApiRes.ok(mchStore);
}
/**
* @date: 2022/2/19 10:41
* @describe: 获取地图配置参数
*/
@GetMapping("/mapConfig")
@PreAuthorize("hasAuthority('ENT_MCH_STORE_MAP')")
public ApiRes getMapConfig() {
DBApiMapConfig apiMapConfig = sysConfigService.getDBApiMapConfig();
return ApiRes.ok(apiMapConfig);
}
/**
* @date: 2021/12/29 10:00
* @describe: 更新门店
*/
@MethodLog(remark = "更新门店")
@PutMapping("/{recordId}")
@PreAuthorize("hasAuthority('ENT_MCH_STORE_EDIT')")
public ApiRes update(@PathVariable("recordId") String recordId) {
MchStore mchStore = getObject(MchStore.class);
mchStore.setStoreId(recordId);
mchStore.setMchNo(null);
mchStore.setAgentNo(null);
mchStore.setTopAgentNo(null);
mchStore.setCreatedAt(null);
mchStore.setUpdatedAt(null);
MchStore dbMchStore = mchStoreService.getById(recordId);
if (!dbMchStore.getDefaultFlag().equals(mchStore.getDefaultFlag())) {
// 如果修改当前为默认
if (mchStore.getDefaultFlag() == CS.YES) {
mchStoreService.updateAllDefaultFlag(dbMchStore.getMchNo());
} else {
throw new BizException("门店不可修改为非默认!");
}
}
boolean result = mchStoreService.updateById(mchStore);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @date: 2021/12/29 10:05
* @describe: 删除门店
*/
@MethodLog(remark = "删除门店")
@DeleteMapping("/{recordId}")
@PreAuthorize("hasAuthority('ENT_MCH_STORE_DELETE')")
public ApiRes delete(@PathVariable("recordId") String recordId) {
mchStoreService.deleteStore(recordId, false);
return ApiRes.ok();
}
/**
* @date: 2021/12/29 9:53
* @describe: 门店列表查询
*/
@GetMapping("/bindStoreList")
@PreAuthorize("hasAuthority('ENT_MCH_STORE_LIST')")
public ApiRes bindStoreList() {
JSONObject paramJSON = getReqParamJSON();
MchStore mchStore = getObject(MchStore.class);
// 门店条件
List<String> storeIdList = getCurrentUser().getStoreIdList();
if (CollectionUtil.isNotEmpty(storeIdList)) {
mchStore.setStoreIdList(storeIdList);
}
IPage<MchStore> mchStoreList = mchStoreService.getBindStoreList(getIPage(true), mchStore, paramJSON);
return ApiRes.page(mchStoreList);
}
}

View File

@@ -0,0 +1,73 @@
package com.jeequan.jeepay.mgr.ctrl.sysuser;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.TreeDataBuilder;
import com.jeequan.jeepay.db.entity.SysEntitlement;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.SysEntitlementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/*
* 权限 菜单 管理
*
* @author terrfly
*
* @date 2021/6/8 17:13
*/
@RestController
@RequestMapping("api/sysEnts")
public class SysEntController extends CommonCtrl {
@Autowired SysEntitlementService sysEntitlementService;
/** getOne */
@PreAuthorize("hasAnyAuthority( 'ENT_UR_ROLE_ENT_LIST' )")
@RequestMapping(value="/bySysType", method = RequestMethod.GET)
public ApiRes bySystem() {
return ApiRes.ok(sysEntitlementService.getOne(SysEntitlement.gw()
.eq(SysEntitlement::getEntId, getValStringRequired("entId"))
.eq(SysEntitlement::getSysType, getValStringRequired("sysType")))
);
}
/** updateById */
@PreAuthorize("hasAuthority( 'ENT_UR_ROLE_ENT_EDIT')")
@MethodLog(remark = "更新资源权限")
@RequestMapping(value="/{entId}", method = RequestMethod.PUT)
public ApiRes updateById(@PathVariable("entId") String entId) {
SysEntitlement queryObject = getObject(SysEntitlement.class);
sysEntitlementService.update(queryObject, SysEntitlement.gw().eq(SysEntitlement::getEntId, entId).eq(SysEntitlement::getSysType, queryObject.getSysType()));
return ApiRes.ok();
}
/** 查询权限集合 */
@PreAuthorize("hasAnyAuthority( 'ENT_UR_ROLE_ENT_LIST', 'ENT_UR_ROLE_DIST' )")
@RequestMapping(value="/showTree", method = RequestMethod.GET)
public ApiRes showTree() {
//查询全部数据
List<SysEntitlement> list = sysEntitlementService.list(SysEntitlement.gw().eq(SysEntitlement::getSysType, getValStringRequired("sysType")));
//转换为json树状结构
JSONArray jsonArray = (JSONArray) JSONArray.toJSON(list);
List<JSONObject> leftMenuTree = new TreeDataBuilder(jsonArray,
"entId", "pid", "children", "entSort", true)
.buildTreeObject();
return ApiRes.ok(leftMenuTree);
}
}

View File

@@ -0,0 +1,108 @@
package com.jeequan.jeepay.mgr.ctrl.sysuser;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.config.dynamic.DataSourceSwitch;
import com.jeequan.jeepay.db.config.dynamic.DynamicDataSource;
import com.jeequan.jeepay.db.entity.SysLog;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.SysLogService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/**
* 系统日志记录类
*
* @author pangxiaoyu
*
* @date 2021-06-07 07:15
*/
@RestController
@RequestMapping("api/sysLog")
public class SysLogController extends CommonCtrl {
@Autowired SysLogService sysLogService;
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:15
* @describe: 日志记录列表
*/
@DataSourceSwitch(DynamicDataSource.DataSourceTypeEnum.SLAVE)
@PreAuthorize("hasAuthority('ENT_LOG_LIST')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
SysLog sysLog = getObject(SysLog.class);
JSONObject paramJSON = getReqParamJSON();
// 查询列表
LambdaQueryWrapper<SysLog> condition = SysLog.gw();
condition.orderByDesc(SysLog::getCreatedAt);
if (sysLog.getUserId() != null) {
condition.eq(SysLog::getUserId, sysLog.getUserId());
}
if (sysLog.getUserName() != null) {
condition.eq(SysLog::getUserName, sysLog.getUserName());
}
if (StringUtils.isNotEmpty(sysLog.getSysType())) {
condition.eq(SysLog::getSysType, sysLog.getSysType());
}
// 时间搜索
Date[] searchDateRange = sysLog.buildQueryDateRange();
condition.ge(searchDateRange[0] != null, SysLog::getCreatedAt, searchDateRange[0]);
condition.le(searchDateRange[1] != null, SysLog::getCreatedAt, searchDateRange[1]);
IPage<SysLog> pages = sysLogService.page(getIPage(), condition);
return ApiRes.page(pages);
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:16
* @describe: 查看日志信息
*/
@PreAuthorize("hasAuthority('ENT_SYS_LOG_VIEW')")
@RequestMapping(value="/{sysLogId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("sysLogId") String sysLogId) {
SysLog sysLog = sysLogService.getById(sysLogId);
if (sysLog == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(sysLog);
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:16
* @describe: 删除日志信息
*/
@PreAuthorize("hasAuthority('ENT_SYS_LOG_DEL')")
@MethodLog(remark = "删除日志信息")
@RequestMapping(value="/{selectedIds}", method = RequestMethod.DELETE)
public ApiRes delete(@PathVariable("selectedIds") String selectedIds) {
String[] ids = selectedIds.split(",");
List<Long> idsList = new LinkedList<>();
for (String id : ids) {
idsList.add(Long.valueOf(id));
}
boolean result = sysLogService.removeByIds(idsList);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
}
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,156 @@
package com.jeequan.jeepay.mgr.ctrl.sysuser;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.db.entity.SysRole;
import com.jeequan.jeepay.db.entity.SysUserRoleRela;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.mgr.service.AuthService;
import com.jeequan.jeepay.service.impl.SysRoleEntRelaService;
import com.jeequan.jeepay.service.impl.SysRoleService;
import com.jeequan.jeepay.service.impl.SysUserRoleRelaService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/*
* 角色管理
*
* @author terrfly
*
* @date 2021/6/8 17:13
*/
@RestController
@RequestMapping("api/sysRoles")
public class SysRoleController extends CommonCtrl {
@Autowired SysRoleService sysRoleService;
@Autowired SysUserRoleRelaService sysUserRoleRelaService;
@Autowired private AuthService authService;
@Autowired private SysRoleEntRelaService sysRoleEntRelaService;
/** list */
@PreAuthorize("hasAnyAuthority( 'ENT_UR_ROLE_LIST', 'ENT_UR_USER_UPD_ROLE' )")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
SysRole queryObject = getObject(SysRole.class);
QueryWrapper<SysRole> condition = new QueryWrapper<>();
LambdaQueryWrapper<SysRole> lambdaCondition = condition.lambda();
lambdaCondition.eq(SysRole::getSysType, CS.SYS_ROLE_TYPE.PLATFORM);
lambdaCondition.eq(SysRole::getBelongInfoId, 0);
if(StringUtils.isNotEmpty(queryObject.getRoleName())){
lambdaCondition.like(SysRole::getRoleName, queryObject.getRoleName());
}
if(StringUtils.isNotEmpty(queryObject.getRoleId())){
lambdaCondition.like(SysRole::getRoleId, queryObject.getRoleId());
}
//是否有排序字段
MutablePair<Boolean, String> orderInfo = getSortInfo();
if(orderInfo != null){
condition.orderBy(true, orderInfo.getLeft(), orderInfo.getRight());
}else{
lambdaCondition.orderByDesc(SysRole::getUpdatedAt);
}
IPage<SysRole> pages = sysRoleService.page(getIPage(true), condition);
return ApiRes.page(pages);
}
/** detail */
@PreAuthorize("hasAuthority( 'ENT_UR_ROLE_EDIT' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") String recordId) {
return ApiRes.ok(sysRoleService.getById(recordId));
}
/** add */
@PreAuthorize("hasAuthority( 'ENT_UR_ROLE_ADD' )")
@MethodLog(remark = "添加角色信息")
@RequestMapping(value="", method = RequestMethod.POST)
public ApiRes add() {
SysRole SysRole = getObject(SysRole.class);
String roleId = "ROLE_" + StringKit.getUUID(6);
SysRole.setRoleId(roleId);
SysRole.setSysType(CS.SYS_ROLE_TYPE.PLATFORM); //后台系统
sysRoleService.save(SysRole);
//权限信息集合
String entIdListStr = getValString("entIdListStr");
//如果包含: 可分配权限的权限 && entIdListStr 不为空
if(getCurrentUser().getAuthorities().contains(new SimpleGrantedAuthority("ENT_UR_ROLE_DIST"))
&& StringUtils.isNotEmpty(entIdListStr)){
List<String> entIdList = JSONArray.parseArray(entIdListStr, String.class);
sysRoleEntRelaService.resetRela(roleId, entIdList);
}
return ApiRes.ok();
}
/** update */
@PreAuthorize("hasAuthority( 'ENT_UR_ROLE_EDIT' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.PUT)
@MethodLog(remark = "更新角色信息")
public ApiRes update(@PathVariable("recordId") String recordId) {
SysRole SysRole = getObject(SysRole.class);
SysRole.setRoleId(recordId);
sysRoleService.updateById(SysRole);
//权限信息集合
String entIdListStr = getValString("entIdListStr");
//如果包含: 可分配权限的权限 && entIdListStr 不为空
if(getCurrentUser().getAuthorities().contains(new SimpleGrantedAuthority("ENT_UR_ROLE_DIST"))
&& StringUtils.isNotEmpty(entIdListStr)){
List<String> entIdList = JSONArray.parseArray(entIdListStr, String.class);
sysRoleEntRelaService.resetRela(recordId, entIdList);
List<Long> sysUserIdList = new ArrayList<>();
sysUserRoleRelaService.list(SysUserRoleRela.gw().eq(SysUserRoleRela::getRoleId, recordId)).stream().forEach(item -> sysUserIdList.add(item.getUserId()));
//查询到该角色的人员, 将redis更新
authService.refAuthentication(sysUserIdList);
}
return ApiRes.ok();
}
/** delete */
@PreAuthorize("hasAuthority('ENT_UR_ROLE_DEL')")
@MethodLog(remark = "删除角色")
@RequestMapping(value="/{recordId}", method = RequestMethod.DELETE)
public ApiRes del(@PathVariable("recordId") String recordId) {
if(sysUserRoleRelaService.count(SysUserRoleRela.gw().eq(SysUserRoleRela::getRoleId, recordId)) > 0){
throw new BizException("当前角色已分配到用户, 不可删除!");
}
sysRoleService.removeRole(recordId);
return ApiRes.ok();
}
}

View File

@@ -0,0 +1,46 @@
package com.jeequan.jeepay.mgr.ctrl.sysuser;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.SysRoleEntRela;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.SysRoleEntRelaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/*
* 角色 权限管理
*
* @author terrfly
*
* @date 2021/6/8 17:13
*/
@RestController
@RequestMapping("api/sysRoleEntRelas")
public class SysRoleEntRelaController extends CommonCtrl {
@Autowired private SysRoleEntRelaService sysRoleEntRelaService;
/** list */
@PreAuthorize("hasAnyAuthority( 'ENT_UR_ROLE_ADD', 'ENT_UR_ROLE_DIST' )")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
SysRoleEntRela queryObject = getObject(SysRoleEntRela.class);
LambdaQueryWrapper<SysRoleEntRela> condition = SysRoleEntRela.gw();
if(queryObject.getRoleId() != null){
condition.eq(SysRoleEntRela::getRoleId, queryObject.getRoleId());
}
IPage<SysRoleEntRela> pages = sysRoleEntRelaService.page(getIPage(true), condition);
return ApiRes.page(pages);
}
}

Some files were not shown because too many files have changed in this diff Show More