Java微服务系统项目技术栈总结

Common:
1.RetryPolicyFactory 重试工厂类
2.SpringCtxUtils spring上下文工厂类
3.SleuthMyBatisPluginTraceInterceptor 服务链路追踪(Spring Cloud Sleuth)
4.RequestValidator 请求参数校验
5.UUIDGenerator UUID生成器
6.ThreadPoolUtil 线程池
/*线程池的最大线程数量/
private static final int MAX_THREAD = 100;

/*线程池的最大等待队列数量/
private static final int MAX_QUEUE = 1000;
//拒绝策略
RejectedExecutionHandler handler = new CallerRunsPolicy();

threadPool = new ThreadPoolExecutor(MAX_THREAD, MAX_THREAD,
30L, TimeUnit.SECONDS,
new LinkedBlockingQueue(MAX_QUEUE),
Executors.defaultThreadFactory(),
handler);
7.ReflectHelper 反射帮助类
getKeyAndValue() 把请求参数解析成map
8.PasswordUtil 密码相关
9.millis 耗时
10.DateUtils 日期时间类
11.BeanCopy 未用到
12.ApolloConfigListener 阿波罗配置监听器?
13.OSinfo 操作系统相关信息
14.MoneyUtil 金额操作
15.NumberUtil 获取随机数字
16.HandleFileUtils 读取文件
17.FileTools 文件工具
18.EventBus 允许组件之间通过发布-订阅进行通信,而不需要组件之间显示的注册。它专门设计为了代替使用显示注册的传统的Java进程内事件分发。它不是通用的发布-订阅系统,也不是用于进程间通信的。优点:简化组件之间的通信。是发布者和订阅之间解耦,同时避免了复杂且容易出错的依赖性和生命周期问题。使代码更加简洁
19.EventbusPublisher 的实现描述:发布异步消息
20.@PostConstruct 注解的用途: 在当前对象加载完依赖注入的 bean 后,运行这个被 @PostConstruct 注解的方法,而且只运行一次。
21.Signature 签名
22.Cache redis接口
23.SETEX key seconds value SET key value EXPIRE key seconds # 设置生存时间 含义(setex = set expire)
24.SETNX key value 含义(setnx = SET if Not eXists):
25.Collections.singletonList被限定只被分配一个内存空间,也就是只能存放一个元素的内容
26.RedisCache 对redis的操作
27.创建redis池
public JedisPool jedisPool() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxWaitMillis(maxWaitMillis);
poolConfig.setMaxTotal(maxTotal);
poolConfig.setMinIdle(minIdle);
poolConfig.setMaxIdle(maxIdle);
poolConfig.setTestOnBorrow(testOnBorrow);
return new JedisPool(poolConfig, address, port, timeout, password);
}
28. 加锁执行并且回调
try {
//RequestValidator.validate(req);
resp = lock.lockAndExecute(req.getRepayPlanNo(), req.get_requestId(), new LockExecuteCallback() {
@SuppressWarnings(“unchecked”)
@Override
public BaseRespDto doBusiness() {
BaseRespDto resp1 = repayService.applyRepay(req);
return resp1;
}
});
29.LOCK_EXPIRE_SECONDS = 5 * 60;
30.一秒钟最多尝试十次
long timeout = System.currentTimeMillis() + 1000;
long sleepInterval = 100;//这个又是什么作用
//在一秒钟之内每隔0.1秒获取一次锁
while (System.currentTimeMillis() <= timeout) {
Boolean success = redisCache.lock(new StringBuffer(RedisLock.LOCK).append(operateNo).toString(), new StringBuffer(_requestId).append(RedisLock.LOCK_SPLIT).append(operateNo).toString(), expire);
if (success) {
return true;
}
try {
Thread.sleep(sleepInterval);
} catch (InterruptedException e) {
}
}
31.ConvertBeanUtil Bean 对象属性copy Util
32.

  • POJO :plain ordinary java object 无规则简单java对象
  • BO:business object 业务对象
  • VO:value object 值对象 / view object 表现层对象
  • DTO(TO):Data Transfer Object 数据传输对象
  • DAO:data access object数据访问对象
    33.ExceptionHandler 异常的抛出都要封装一下

ops
34.application.properties
spring.application.name=fjy-ops
mybatis.logger=io.jiayan.fjy.ops.dao

logging.path=/alidata1/apphome/logs
logging.level=INFO
max.history=300
35.jdbc.xml 之前从来没有仔细看过这个文件的配置 这个文件要怎么被spring加载?
这里配置了mapper的位置


classpath*:/mybatis/sqlmap//.xml
classpath:/mybatis/sqlmapExt//*.xml


配置隔离级别和传播类型




<-- 数据库连接 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" init-method="init"
	lazy-init="false">
	<property name="driverClassName" value="${jdbc.driver}" />
	<property name="url" value="${jdbc.url}" />
	<property name="username" value="${jdbc.username}" />
	<-- <property name="password" value="${jdbc.password}" /> -->
	<-- 初始化连接大小 -->
	<property name="initialSize" value="${jdbc.initialSize}" />
	<-- 连接池最大数量 -->
	<property name="maxActive" value="${jdbc.maxActive}" />
	<-- 连接池最小空闲 -->
	<property name="minIdle" value="${jdbc.minIdle}" />
	<-- 获取连接最大等待时间 -->
	<property name="maxWait" value="${jdbc.maxWait}" />
	<-- -->
	<property name="defaultReadOnly" value="false" />
	<property name="proxyFilters">

36.applicationContext-service.xml 加载 DicCacheManager
37.DicCacheManager implements ApplicationListener 数据字典
从application中获得实例,再调用方法,查询放在缓(了解spring的原理还是重要的,否则不会理解这个做法的,不会看懂这个代码的意思的,application是干什么的都不知道)
public void onApplicationEvent(ApplicationReadyEvent event) {
ApplicationContext applicationContext = event.getApplicationContext();
dictionariesService = applicationContext.getBean(DictionariesService.class);
List opsDictionariesDOListAll = dictionariesService.queryOpsDictionariesDOListAll();
if (opsDictionariesDOListAll == null || opsDictionariesDOListAll.size() == 0) {
return;
}

    for (OpsDictionariesDto item : opsDictionariesDOListAll) {
		dicCacheMap.put(item.getDicCode(), item);
	}

}
38.app.properties app.id=fjy-ops
39.过滤器
SessionFilter 封装,不需要登录过滤的list列表
RequestHolder 存放登录相关缓存
CorsFilter
40.@FeignClient(value = “fjy-chain”, url=“${chainFeignClient.url}”)
41.@Api是Swagger的注解。该注解用于Controller类上,表示对类的说明
42.@ApiOperation是Swagger包中的一种注解使用@ApiOperation注解用来描述我们写的接口。ApiOperation 注解提供了丰富的属性来允许我们自定义接口描述信息,包括接口名称,接口所属分组等
43.@AllArgsConstructor 它是lombok中的注解,作用在类上;使用后添加一个构造函数,该构造函数含有所有已声明字段属性参数
44.@Data注解在类上时,简化java代码编写,为该类提供读写属性。简单来说就是不用再手动添加构造方法和get/set等方法了
45.BaseDto implements Serializable, Cloneable 提供toString fromJson toJson clone 方法
46.BaseRespDto extends BaseDto 包含resultCode-业务应答码 resultMessage-业务应答信息字段
47.BaseReqDto extends BaseDto 只包含请求流水号 private String _requestId = UUID.randomUUID().toString().replace(“-”, “”);
48.Constant 常数; 常量 干java这么久了,现在才知道这个单词的意思
49.Feign是Netflix开源的一个REST客户端,通过定义接口,使用注解的方式描述接口的信息,就可以发起接口调用。
50.ProceedingJoinPoint 过程连接点
51.Dto还有 BasePlatformOperateReqDto BaseCorpOperateReqDto 的区分
52.BizImplProxy 统一对Api层进行异常处理和日志记录 @Pointcut(“execution(* io.jiayan.fjy.ops.api.Ops*.*(…))”) OpsAssetRegisterApiImpl
53.Config
Trans
54.app.properties app.id=fjy-trans
55.logback.xml 只需配置好 log.dir 和 projectname 属性
56.application.properties
spring.application.name=fjy-trans
mybatis.logger=io.jiayan.fjy.trans.dao

logging.path=/alidata1/apphome/logs
logging.level=INFO
max.history=300

server.port=8082
57.DtoUtils DO到Dto的转化
58.RespUtils 返回对象组装
59.TransUtils 请求信息组装等
60.spring提供的TransactionTemplate 工具类来控制细粒度事务
//一个sql为什么要加事务
transactionTemplate.execute(new TransactionCallback() {
@Override
public Boolean doInTransaction(TransactionStatus status) {
upperChainRecordDOMapperExt.updateByPrimaryKeySelective(item);
return Boolean.TRUE;
}
});
61.Handler 就是处理器
62.AbstractHandler 这个抽象类就写的很高深 这么多交易处理器是干什么的?
63.以ApplyIssueQuotaTransHandler为例,其run方法被AbstractHandler的internalHandle方法调用,internalHandle 又被 RetryJobTask.getBaseRespDto 和 AbstractHandler.handled调用
64.handle可以手动调用,也可以批处理执行
65.批处理:task,都继承AbstractTask
User

66.Config多了,阿波罗的和xxljob的配置
67.资产:1.资产登记 2.资产编辑 3.应收/应付资产列表查询 4.资产详情查询 5.资产作废 6.资产交易控制 7.修改资产hash信息 8.修改资产交易状态
68. 线程数计算用的是 AtomicInteger,缓存队列是LinkedBlockingQueue
public void init() {
executor = new ThreadPoolExecutor(30, 30, 0l, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(10000),
new ThreadFactory() {
private AtomicInteger index = new AtomicInteger(0);

                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r, "za-bio-eventbus-" + index.incrementAndGet());
                }
            });
  1. redis缓存用的是ConcurrentHashMap和threadLocal ,RedisLock中用到了大量的ConcurrentHashMap
    private static final ThreadLocal<ConcurrentHashMap<String, ConcurrentHashMap<String, Object>>> threadLocal = new ThreadLocal<ConcurrentHashMap<String, ConcurrentHashMap<String, Object>>>();

ConcurrentHashMap<String, ConcurrentHashMap<String, Object>> outMap = new ConcurrentHashMap<String, ConcurrentHashMap<String, Object>>(); outMap.put(operateNo, innerMap);

70.可以改进的地方:(1)if else会增加代码的耦合度,以卫语句取代嵌套的条件表达式。应该会策略模式代替 (2)长参数列表(一旦参数列表变得很长,作为普通人,我们就很难对这些内容进行把控了)可以做的就是将这些参数封装成一个类,一个创建作品的参数类这样一来,这个函数参数列表就只剩下一个参数了,一个长参数列表就消除了。
71.TransactionTemplate的编程式事务管理是使用模板方法设计模式对原始事务管理方式的封装
72. 这个才能看出事务的优势
Boolean flag = transactionTemplate.execute(status -> {
//更新邀请码状态
corpInviteCodeService.changeCorpInviteCodeStatus(modifyStatus);
//新增企业
CorpDto respDto = corpService.addCorp(addCorp);
//新增用户
record.setCorpNo(respDto.getCorpNo());
corpOperDOMapperExt.insertSelective(record);
// send notice
addNoticeReq.setReceiverCorpNo(respDto.getCorpNo());
messageService.addNotice(addNoticeReq);

	    return Boolean.TRUE;
	});

73.注册:1.参数判空 2.邮箱格式校验 3.验证码校验 4.登录名是否存在校验 5.企业名称是否存在校验 6.邀请码校验(1)邀请码是否存在 (2)邀请码是否和企业匹配 (3)邀请码是否失效 (4)邀请码是否已被使用 7.生成操作员号operNo 8.绑定动态码(参数是json.setOperNo(operNo)) 8.生成秘钥bindGoogle.getData().getSecretKey();9.更新邀请码状态 10.新增企业,新增用户
74.发送通知:消息模板参数:手机号码,业务类型,企业名称,登录名,原因,发起方,接收方,(1)检查消息模板参数是否存在 (2)插入消息 (3)把消息参数解析成KV结构 (4)替换模板中的占位符 (5)插入数据库,发送站内信,发送短信 (6)发送状态:生成业务通知时待发送,生成公告时是发送中,
75.登录:createUserToken(1)判断用户名密码是否正确(查询用户信息是否存在),用户名或密码不正确,用登录作参数 (2)校验密码 (3)验证安全码 (4)返回权限列表
76.登出:删除缓存,清空缓存
77.重置密码:1.参数校验 2.两次输入密码校验 3.操作员账号校验 4.验证码校验
78.修改密码:1.参数校验 2.新密码和旧密码校验 3.新密码两次输入校验 4.获取用户信息 5.根据用户信息查询旧密码,验证旧密码 6.执行修改
79.账户管理:不是这个账户管理 链属企业账户管理 核心企业账户管理 资金方回收账户管理 资金方融资账 根据企业编号,查询token信息
角色管理
80.查询系统角色列表 (1)校验用户是否登录(2)根据登录信息获得企业编号,角色类型 (3)查询角色列表(角色名称,状态,角色用户)(4)查询权限列表(权限编号,权限名称)
81.||新增角色 (1)创建并设置角色编号(2)获取登录信息,设置企业编号,角色类型(3)角色是否重复校验(4)执行插入
82.||修改角色 (1)用角色ID查询角色是否存在 (2) 用角色名称查询觉得是否存在(3)删除角色对应的权限列表并且新增新的权限列表 (4)更新角色表
83.||禁用/启动角色 (其实就是修改角色状态)(1)查询角色信息 (2)校验角色状态,状态相同不允许修改 (3)修改
84.||删除角色 (1)查询角色信息 (2)校验角色用户信息是否为空,如果不为空不能删除 (3)执行删除操作
||新增角色用户 (1)查询角色信息 (2)角色状态校验未生效状态不允许增加用户 (3)验证所新增角色是否存在,如果存在,返回该账号已被使用 (4)新增操作 (5)发送信息
85.||删除角色用户(1)根据角色用户ID查询用户信息是否存在 (2)删除信息
权限管理
86.新增权限 (1)生成权限编号(2)直接新增
87.获取权限列表 直接分页查询,校验都没有
企业注册
88.分页获取邀请码列表 直接查询,字段:id,邀请码,企业类型,企业名称,联系人,过期时间,状态
89.查询邀请码 (1)查询邀请码,参数(邀请码,被邀请企业名称)
90.生成邀请码 (1)邀请码相关信息入库 (2)发送信息
91.修改邀请码状态 (1)无需校验,直接修改 UNUSED-未使用,USED-已使用,INVALID-已失效
92.分页获取企业列表 (1)直接查询企业信息,查询参数:企业编号,状态(INIT-初始无信息, FREEZE-审核冻结, VALID-有效, INVALID-失效),流程状态(INIT-初始无信息, FREEZE-审核冻结, VALID-有效, INVALID-失效),增信状态(VALID-有效;INVALID-失效),企业类型,企业名称。返回值:企业名称,企业类型,企业编号,主账号名称,状态,流程状态,增信状态,企业认证时间
93.平台方分页获取企业审核列表(1)
94.平台查询企业审核信息(1)
95.查询企业(1)
96.查询企业详情(1)
97.新增企业(1)创建企业编号 (2)设置企业编号,状态 (3)执行插入
98.更新企业 (1)直接更新没有校验
99.新增企业信息(1)校验企业是存在 (2)校验企业名称(3)执行插入
100.修改企业信息(1)和新增逻辑差不多
101.发送短信(1)和发送通知逻辑一样
资产管理
102.资产登记(1)幂等处理,合同编号重复性校验 (2)从请求头获取当前登陆用户及企业信息 (3)业务检查(查询企业信息,查询企业详情,查询企业状态,校验应收方和应付方不能一样)(4)获取应收和应付方企业信息(5)封装资产数据 (6)封装资产附件数据 (7)数据入库
103.资产编辑(1)查看要编辑的资产是否存在 (2)从请求头获取当前登陆用户及企业信息 (3)控制编辑操作只能资产登记方的企业才能进行编辑 (4)控制编辑操作只能在没有产生交易的情况下才能进行编辑 (5)业务检查 (6)获取企业信息 (7)资产主数据入库 (8)删除编辑删除的数据 (9)附件数据入库 (10)删除原来的文件记录 (11)添加新的文件
104.应收/应付资产列表查询(1)获取当前用户信息 2.查金额>0的资产
105.资产详情查询(1)查询资产主表数据 (2)查询资产附件
106.资产作废(1)获取当前用户信息 (2)检查企业状态是否正常 (3)控制编辑操作只能资产登记方的企业才能进行作废 (4)控制编辑操作只能在没有产生交易的情况下才能进行作废 (5)执行更新操作
107.资产交易控制 这里有用到lock,为什么这里会用到锁,有涉及到并发吗?
RequestValidator.validate(req);
resp = lock.lockAndExecute(req.getAssetNo(), req.get_requestId(), new LockExecuteCallback() {
@SuppressWarnings(“unchecked”)
@Override
public BaseRespDto doBusiness() {
BaseRespDto resp1 = assetRegisterService.transControl(req);
return resp1;
(1)幂等校验,查询交易信息 (2)从请求头获取当前登陆用户及企业信息 (3)基本业务校验,资产编号查询资产表信息 (4)交易请求入表transReqDOMapperExt.insertSelective(transReq); (5)交易入表 assetDOMapperExt.updateByPrimaryKeySelectiveUseLock(assetDO);
108.修改资产hash信息(1)查询是否存在资产记录 (2)确认资产是否已上链 (3)执行修改
109.修改资产交易状态(1)幂等校验,查询是否存在资产交易信息 (2)从请求头获取当前登陆用户及企业信息 (3)资产编号查询资产信息是否存在 (4)更新操作
110.费率维护
费率类型 (单一/阶梯) 费率(大于 0,小于 100,保留小数点后
四位) 计费方式(年/月/日(单利)) 融资比例(0-100%,整数) 生效日期(可设置某一时间生效) 处理日期(流程最后处理人处理的日期) 维护内容(费率类型/收费方式/费率/计费方
式/融资比例) 更新前(更新前的状态或金额) 更新后(更新后的状态或金额) 处理结果(通过/拒绝) 经办 ID
待办
111.queryTodoTaskCount 查询待办任务总数 (1)缓存获得登录信息,校验与参数是否一致(2)注册审核、授信审批、签发审核、融资审批、兑付审核
112.queryUndoTaskCount
113.报表(1)远期兑付报表 近期兑付报表 (2)查询和下载功能
114.Ereka(1)
115.xxl-job(1)
116.apollo(1)
117.业务架构图

118.应用架构图

119.交互层 基于nodejs+vue的前端PC网站,同时支持调用CFCA控件读取Ukey信息
120.接入层 运营前置管理会话,调用交易核心及其他接口;
121.
1)业务层 运营管理
(1)安全管理
注册:
登录:
忘记密码:
修改密码:
修改邮箱:
动态码管理:
ukey管理:
(2)权限管理
基于企业-角色-菜单的权限管理;
基于账户-角色-按钮的权限管理;
2)基础业务
(1)用户系统
企业管理及审核:企业新增、企业信息审核
银行卡管理及审核:银行卡新增、银行卡审核
邀请码管理:邀请码生成,邀请码验证
融资产品管理:融资产品配置,支持资金方自定义地区、还款方式、利率等各种的融资产品;
平台服务费管理:平台服务费配置
站内信:站内信模板配置,站内信发送
邮件服务:邮件模板配置,邮件发送
(2)通证系统
通证生成:
通证签发:
通证转让:
通证冻结:
通证解冻:
通证解冻并扣减;
通证收回:
(3)资产系统
应收资产登记;
应付资产登记:
(4)合约系统
合约生成:
合约确认:
3)交易核心
(1)审批
基于用户-账户-角色的通用审批流程,支持自动重试补偿;
(2)开户
核心企业、链属企业、资金方注册,平台审核通过后,新增企业用户;
(3)授信
资金方根据企业基本信息、企业增信等进行授信动作,授信成功后,颁发额度;
(4)签发
核心企业基于应付资产,签发额度给到链属企业;
(5)转让
链属企业基于应付资产,转让额度给到下级链属企业;
(6)融资
链属企业基于持有的通证,选择通证额度签发资金方进行融资;
(7)抽成
链属企业基于平台配置的抽成规则,主动进行抽成打款;
(8)还款
核心企业在通证签发有效期到期后,对通证持有方进行还款;
(9)上链
应用区块链技术,对所有基础数据、交易数据进行上链操作,存证防篡改;
支撑系统
1)电子签章
2)邮件短信
3)动态码
4)CFCA

122.区块链 企业链是企业科技新一代的联盟链的核心引擎,拥有集高安全性,高性能,及高可用性等特点于一身,非常适用于具有联盟性质的商业机构之间业务之场景,也适合金融级高频交易、对安全性要求高的场景。
123.中间件
(1)消息中心:RocketMQ,一款分布式、队列模型的消息中间件;
(2)缓存中心:Redis,一个高性能的key-value数据库;
(3)调度中心:XXL-JOB是一个轻量级分布式任务调度平台;
(4)分布式事务:bscf-retry,企业自研基于补偿机制的分布式事务解决方案;
(5)远程调用:使用SpringCloud微服务套件支持分布式远程调用;
(6)服务发现:Eureka是Netflix开发的服务发现框架;
124.基础运维层:
1)应用运维
(1)应用服务器:基于阿里云ECS提供稳定高可用服务;
(2)数据库:基于阿里云RDS的数据库服务;
(3)OSS:基于阿里云的分布式文件系统;
(4)SFTP服务器:自建SFT服务器,用于与外部系统进行文件交互;
(5)代码库管理:基于gitlab的私有代码版本管理工具;
(6)发布平台:基于jenkins的服务自动发布平台;
(7)配置中心:基于apollo的可视化配置中心;
2)运维
一站式部署区块链系统。
安链云BaaS平台以企业科技自主研发的企业链为基础,提供了可视化、一站式的区块链云服务。安链云BaaS平台支持用户快速、定制化部署区块链系统,提供充足的计算资源、开发工具、部署工具和监控工具。安链云BaaS平台通过高性能的资源池和灵活的定价模式,保障用户的业务规模的弹性可伸缩,通过共享或独享服务资源,提供用户间业务的安全隔离,为用户提供一站式的生产力工具集,为区块链+行业生态提供科技赋能。
126.

Third,chain,ops,user 这4个项目的装配方式是byName: default-autowire=“byName”>

127.AOP 相关配置
/**

  • 统一对Api层进行异常处理和日志记录
    /
    @Component
    @Configuration
    @Aspect
    @Order(3) // @Order(i)注解来标识切面的优先级。i的值越小,优先级越高
    public class BizImplProxy {
    @Pointcut("execution(
    io.jiayan.fjy.ops.api.Ops*.*(…))")
    public void bizPointcut() {
    }

@SuppressWarnings(“rawtypes”)
@Around(“bizPointcut()”)
public Object doArount(ProceedingJoinPoint point) throws Throwable {
// 返回对象
Object ret = null;

128.starter总结

com.jiayan.openchain.sdk
openchain-oap-sdk
1.3-SNAPSHOT

spring-boot-autoconfigure
spring-boot-starter-web
boot-starter-actuator
spring-boot-starter-test
spring-cloud-starter-feign
springfox-swagger2
springfox-swagger-ui
junit
protobuf-java
org.springframework.cloud
lombok
jackson-databind
hibernate-validator
maven-compiler-plugin
maven-source-plugin
commons-lang3
spring-boot-maven-plugin
xxl-job-core
spring-boot-starter-aop
spring-boot-starter-jdbc
spring-test
mysql-connector-java
druid
sharding-jdbc-core
jedis
mybatis
mybatis-spring
pagehelper
commons-io
commons-lang
commons-beanutils
guava
httpclient
commons-net
joda-time
jsch
rocketmq-client
spring-cloud-starter-zipkin
itext
itextpdf
xmlworker
flying-saucer-pdf-itext5
itext-asian
feign-form
feign-form-spring
easymock
mockito-all
jackson-databind
jackson-core
jackson-annotations
slf4j-api
commons-fileupload
aliyun-sdk-oss
mail
commons-codec
javase
etl-uaclient
sadk
tech-nsign-sdk-share
hsqldb
commons-dbcp
commons-pool

129.综合资产系统
130.pom文件 pom(project object model)//从来没有想到要了解一下什么是pom
(1)cta-facade
(2)joda-time
(3)junit
(4)slf4j-api
(5)log4j
(6)validation-api
(7)hibernate-validator validator(验证控件)
(8)spring-test
(9)spring-webmvc 这个jar 文件包含Spring MVC 框架相关的所有类。包括框架的Servlets,Web MVC框架,控制器和视图支持。当然,如果你的应用使用了独立的MVC 框架,则无需这个JAR 文件里的任何类。
  外部依赖spring-web, (spring-support,Tiles,iText,POI)。

(10)spring-core
(11)spring-jdbc 这个jar 文件包含对Spring 对JDBC 数据访问进行封装的所有类。
  外部依赖spring-beans,spring-dao。
(12)spring-aspects 提供对AspectJ的支持,以便可以方便的将面向方面的功能集成进IDE中,比如Eclipse AJDT。
(13)spring-context-support
(14)spring-oxm Spring 对Object/XMl的映射支持,可以让Java与XML之间来回切换
(15)spring-security-web
(16)spring-batch-infrastructure
(17)aspectjweaver
(18)spring-data-redis
(19)jedis
(20)mybatis-spring
(21)mybatis
(22)druid
(23)oracle
(24)httpclient
(25)httpclient-cache
(26)httpmime
(27)commons-pool2
(28)commons-lang3
(29)commons-lang
(30)commons-io
(31)poi
(32)poi-ooxml
(33)poi-ooxml-schemas
(34)dom4j
(35)commons-fileupload
(36)commons-beanutils
(37)ant
(38)dubbo
(39)zookeeper
(40)zkclient
(41)jstl
(42)servlet-api
(43)validation-api
(44)hibernate-validator
(45)bcprov-jdk14
(46)jackson-databind
(47)jackson-core
(48)fastjson
(49)json-lib
(50)juh
(51)ridl
(52)unoil
(53)jacob
(54)jodconverter
(55)jodconverter-cli
(56)xstream
(57)activiti-engine
(58)activiti-spring
(59)activiti-bpmn-model
(60)activiti-bpmn-converter
(61)activiti-process-validation
(62)mongo-java-driver
(63)java-uuid-generator
(64)guava
(65)javassist
131.总共有7个模块
(1)aim-web,
配置文件:activity–工作流
jetty

<-- jedis 配置 -->









<-- -->


<-- redis template definition p表示对该bean里面的属性进行注入,格式为p:属性名=注入的对象 效果与在bean里面使用标签一样 -->

<-- 序列化方式 建议key/hashKey采用StringRedisSerializer。 -->












mybatis_config.xml 分页拦截器配置


Redis redis_host=127.0.0.1 redis_port=6379 redis_password=123456 redis_maxIdle=100 redis_maxActive=300 redis_maxWait=1000 redis_testOnBorrow=true redis_timeout=10000

applicationContext.xml 终于知道applicationContext是什么了,慢慢的会对spring越来越理解
<-- 引入属性文件 -->
<context:property-placeholder location=“classpath:config.properties,classpath:log4j.properties,classpath:redis/redis.properties” />

<-- 自动扫描(自动注入),不扫描带有@Controller注解的类。因为这些类已经随容器启动时,在servlet-context中扫描过一遍了 -->
<context:component-scan base-package=“com.gaoqianjf.aim”>
<context:exclude-filter type=“annotation” expression=“org.springframework.stereotype.Controller”/>
</context:component-scan>

<-- 配置数据源 -->



<-- 初始化连接大小 -->

<-- 连接池最大使用连接数量 -->

<-- 连接池最小空闲 -->

<-- 获取连接最大等待时间 -->

<-- -->

<-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->

<-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->

<-- 打开removeAbandoned功能 -->

<-- 1800秒,也就是30分钟 -->

<-- 关闭abanded连接时输出错误日志 -->

<-- 监控数据库 -->
<-- -->

<-- myBatis文件 -->



<-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置。这里不支持多个路径,只能用**来统一处理 -->

<-- 配置事务管理器 start -->


<-- 使用tx标签方式配置事务 -->
<tx:advice id=“transactionAdvice” transaction-manager=“transactionManager”>
tx:attributes
<tx:method name=“add*” propagation=“REQUIRED” />
<tx:method name=“append*” propagation=“REQUIRED” />
<tx:method name=“insert*” propagation=“REQUIRED” />
<tx:method name=“save*” propagation=“REQUIRED” />
<tx:method name=“update*” propagation=“REQUIRED” />
<tx:method name=“modify*” propagation=“REQUIRED” />
<tx:method name=“edit*” propagation=“REQUIRED” />
<tx:method name=“delete*” propagation=“REQUIRED” />
<tx:method name=“remove*” propagation=“REQUIRED” />
<tx:method name=“repair” propagation=“REQUIRED” />
<tx:method name=“delAndRepair” propagation=“REQUIRED” />
<tx:method name=“claim*” propagation=“REQUIRED” />

  <tx:method name="get*" propagation="SUPPORTS" />
  <tx:method name="find*" propagation="SUPPORTS" />
  <tx:method name="load*" propagation="SUPPORTS" />
  <tx:method name="search*" propagation="SUPPORTS" />
  <tx:method name="datagrid*" propagation="SUPPORTS" />

  <tx:method name="*" propagation="SUPPORTS" />

</tx:attributes>
</tx:advice>

<–加入proxy-target-class=“true” 即可,默认是false;–>
<-- expression=“execution( com.dao…(…))” 其中第一个代表返回值,第二代表dao下子包,第三个代表方法名,“(…)”代表方法参数。 -->
<aop:config proxy-target-class=“true”>
<aop:pointcut id=“transactionPointcut” expression=“execution(* com.gaoqianjf.aim.service…Impl.(…))” />
<aop:advisor pointcut-ref=“transactionPointcut” advice-ref=“transactionAdvice” />
</aop:config>
<-- 配置事务管理器 end -->

<-- 配置druid监控spring jdbc -->

com.gaoqianjf.aim.service.*

aop:config
<aop:advisor advice-ref=“druid-stat-interceptor” pointcut-ref=“druid-stat-pointcut” />
</aop:config>
aop:aspectj-autoproxy/

<-- spring上传文件设置 -->




config.properties
driverClassName=oracle.jdbc.driver.OracleDriver
validationQuery=SELECT 1 FROM DUAL
jdbc_url=jdbc:oracle:thin:@172.18.100.50:1521:morass
jdbc_username=fas_0531
jdbc_password=123456

reinvest_amt=500

#mongodb
mongodb_ip=172.18.100.63
mongodb_port=27017
mongodb_db=testdb
mongodb_user=mdbtest
mongodb_pwd=123456

#activiti
#init activiti data
create.activiti.users=true
create.activiti.models=true
fastdfsUrl=http://172.18.100.63:8888/ FastDFS是一个开源的轻量级分布式文件系统
fastpool.properties
connect_timeout = 2
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 8888
http.anti_steal_token = no
http.secret_key = FastDFS1234567890

tracker_server = 172.18.100.63:22122

log4j.properties
#log4j.rootLogger = [ level ] , appenderName, appenderName, …
log4j.rootLogger = ALL, console,allR

#branch logger
log4j.logger.InfoLogger = INFO,infoR
log4j.logger.ErrorLogger = ERROR,errorR
org.apache.commons = DEBUG

log4j.logger.org.springframework=ERROR
#mybatis logger config
log4j.logger.com.ibatis=ERROR
log4j.logger.org.apache.ibatis.jdbc.ScriptRunner=ERROR
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

#zookeeper off ping output
log4j.logger.org.apache.zookeeper=OFF

#dubbo off heartbeat output
log4j.logger.com.alibaba.dubbo.remoting.exchange.support.header=OFF

#console
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n

#infoR
log4j.appender.infoR = org.apache.log4j.RollingFileAppender
log4j.appender.infoR.File =logs/info/infoLog.txt
log4j.appender.infoR.MaxFileSize = 50MB
log4j.appender.infoR.MaxBackupIndex = 1000
log4j.appender.infoR.layout = org.apache.log4j.PatternLayout
log4j.appender.infoR.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] - %m%n

#errorR
log4j.appender.errorR = org.apache.log4j.RollingFileAppender
log4j.appender.errorR.File =logs/error/errorLog.txt
log4j.appender.errorR.MaxFileSize = 50MB
log4j.appender.errorR.MaxBackupIndex = 1000
log4j.appender.errorR.layout = org.apache.log4j.PatternLayout
log4j.appender.errorR.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] - %m%n

#allR
log4j.appender.allR = org.apache.log4j.RollingFileAppender
log4j.appender.allR.File =logs/all/allLog.txt
log4j.appender.allR.MaxFileSize = 500MB
log4j.appender.allR.MaxBackupIndex = 1000
log4j.appender.allR.layout = org.apache.log4j.PatternLayout
log4j.appender.allR.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] - %m%n
spring-activiti.xml
<-- 创建一个流程引擎的配置对象 -->



<-- 设置数据库schema的更新方式 -->

<-- 是否启动jobExecutor -->



<-- -->

 </bean>
  <-- 创建一个流程引擎bean -->
 <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
   <property name="processEngineConfiguration" ref="processEngineConfiguration" />
 </bean>
 <-- 创建activiti提供的各种服务 -->
 <-- 工作流仓储服务 -->
 <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
 <-- 工作流运行服务 -->
 <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
 <--  工作流任务服务-->
 <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
 <--  工作流历史数据服务-->
 <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
 <--  工作流管理服务-->
 <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
 <-- 工作流唯一服务 -->
 <bean id="IdentityService" factory-bean="processEngine" factory-method="getIdentityService" />
spring-task.xml <--自动申请 定时任务 --> <--自动报盘Cta定时任务 --> <--账户状态同步推送定时任务,在自动报盘完成之后进行 -->

<–更新逾期状态任务定时任务

task:scheduled-tasks
<task:scheduled ref=“overdueStatusTask” method=“updateOverdueStatus” cron=“0 0 1 * * ?”/>
</task:scheduled-tasks>–>

<–逾期自动报盘

task:scheduled-tasks
<task:scheduled ref=“overdueRepayTask” method=“overdueRepay” cron=“0 30 11,17,21 * * ?”/>
</task:scheduled-tasks>–>
<–计算逾期罚息定时任务

task:scheduled-tasks
<task:scheduled ref=“overduePenaltyTask” method=“calculatePenalty” cron=“0 0 2 * * ?”/>
</task:scheduled-tasks>–>

<-1.对于信用贷款,若超时(5天)未处理则直接归档。每天23点执行一次

task:scheduled-tasks
<task:scheduled ref=“workflowTask” method=“cancelActivity” cron=“0 0 23 * * ?”/>
</task:scheduled-tasks>

1.待签约客户超过15个自然日未签约处理,视为自动拒贷。每天23点执行一次

task:scheduled-tasks
<task:scheduled ref=“refuseLoanTask” method=“automaticRefuseLoan” cron=“0 0 23 * * ?”/>
</task:scheduled-tasks>
tpp-consumer.xml
<dubbo:application name=“tpp-client” />
<–消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<–zookeeper注册中心
<dubbo:registry protocol=“zookeeper” address=“127.0.0.1:2181” />
<-- 生成远程服务代理,可以和本地bean一样使用demoService
<dubbo:reference check=“false” connections=“1” id=“ctaAccountService” interface=“com.gaoqian.cta.facade.service.CtaAccountService” version=“1.0.0” />
<dubbo:reference check=“false” connections=“1” id=“channelService” interface=“com.gaoqian.channel.facade.service.ChannelService” version=“1.0.0” />
<dubbo:reference check=“false” connections=“1” id=“ctaTradeService” interface=“com.gaoqian.cta.facade.service.CtaTradeService” version=“1.0.0” />
<dubbo:reference check=“false” connections=“1” id=“ctaLLPayRealnameService” interface=“com.gaoqian.cta.facade.service.CtaLianLianAccountService” version=“1.0.0” />

src结构
–controller
AccountBindCardController
selectAccBind 开户绑卡信息查询
selectAccBindCardPageInfo 开户绑卡页面自动带出信息查询
selectBankCardOneInfo 银行卡联动查询,根据银行卡id ,跟银行卡号 查询对应银行卡信息
selectAccFirmBindCardPageInfo 点击企业开户,弹出页面,查询页面需要数据,包括法人信息,银行卡信息
addAcctFirmBindingCard 进行企业开户操作
addAcctOperation 进行个人开户操作
openLLPayAountRN 连连支付-实名认证、支付认证
问题点:这个应该写在工具类.随机生成数字字符串
public String incrementValue(){
if (counter.get() > 999999) {
counter.set(1);
}
CorporateCustomerController
initCorporateCust 初始化企业基本信息的数据字典
initCorporateUser 初始化企业人员信息的数据字典
selectReportList 通用报表查询
exportExcel 通用报表导出
addCorporateCust 新增企业客户
addCorporateUser 新增实际控制人、法人、股东、实际控制人配偶信息表
getCorporateCust 查询企业客户基本信息;查询企业用户:包括实际控制人和其他人员
updateCorporateCust 更新企业客户
updateCorporateUser 更新实际控制人、法人、股东、实际控制人配偶信息表
getCompanyList 查询展示所有企业的名字用以添加关联企业信息表
addRelationCompanyCust 保存关联企业
saveCorporateFile 企业附件上传保存
selectCorporateFile 查询企业的所有附件
selectCorportalAllUser 查询企业所有人员信息,包括(法人,实际控制人,股东及配偶)
selectCorportalOneUser
查询企业的单个人员信息,如查询单个实际控制人,或者单个法人信息
UpdateCorportalOneUserFile 修改企业人员的附件,针对每个人。由于字段都在企业人员表中,所以直接更新就行了
PersonalCustomerController
initBasicInfo 初始化客户基本信息页面的数据字典
initContact 初始化相关联系人页面的数据字典
initBankCard 初始化银行卡页面的数据字典
initProfession 初始化职业信息页面的数据字典
initCustomPersonalType 初始化页面字段的数据字典(主要用于查看和修改客户信息)
addPersonalCustomer 新增个人客户基本信息
addContact 新增相关联系人信息
addBankCard 新增银行卡信息
addProfession 新增职业信息
delPersonalCustomer 删除客户信息
NotifyController
tradeBorrowData
SLTradeBorrowData 善林放款更新综合资产信息(还款计划表、投资列表、还款日期、还款状态)
ApplyUploadDataController
loanFinancing 借款融资申请
uploadData 融资申请信息
selectApplyRepayInfo 还款计划表信息查询
uploadTradLoanData 债券信息 excel文件解析上传
selectApplyLoanInfo 融资申请信息查询,单条信息查询
selectLoanInfo 融资申请信息-----查看页面
updateLoanInfo 融资申请信息------修改查看页面
updateApplyLoanInfo 融资申请 信息修改保存
selectTradLoanInfo 查询债券信息
selectApplyLoanAll 查询融资申请信息 分页多条
selectLoanFile 融资申请信息—附件查询
initApplyLoan 初始化融资申请页面 下拉框信息
checkSubAccountLoan 点击申请进件,判断客户是否开户绑卡
checkSubAccountQuery 选择子账户功能,页面联动信息查询
BlackListController
List 黑名单列表页
listQuery 黑名单列表查询
blackListDetail 黑名单详情
addList 新增黑名单
arraignBlackList 提审黑名单
auditBlackList 审核黑名单
cancelBlackList 取消黑名单
delBlackList 删除黑名单
getBlackListExport 导出黑名单
ChangeManagerController
selectCustomInfo 客户信息查询(修改客户经理)
updateCustomerManager 修改客户经理信息
selectCustomManager 根据用户名查询客户经理
CustomerController 客户信息录入
organUser 企业客户信息录入
addBankCardToFrim 企业客户添加银行卡信息,保存银行卡表,保存企业表
selectBankCardToFrim
HouseController
addHouseAssets 房产信息录入,主要包括资产表,房产基础表信息
addHouseLoan 房产贷款信息录入
updateHouseLoan 房产贷款信息修改
updateHouseAssets 房产信息修改,资产表,房产基础信息表
selectHouseAssets 房产基础信息查询,包括资产信息,房产信息
updateHouseAssetsPage 房产基础信息查询,包括资产信息,房产信息
selectHouseLoan 房产贷款信息查询
selectHouseDictData 房产信息数据字典 数据接口
MoveFileController
addHouseAssets 房产信息录入,主要包括资产表,房产基础表信息
uploadFileForMove 上传文件 这个功能写在这里不符合单一职责原则
ContractManageController
contractListSearch 查询合同
toContractCreditLoan 查看信用贷款的合同
toContractCreditLoan 查看信用贷款的合同
processTaskListSearch 流程任务查询,包括(待处理002、申请中003、待签约004、已签约005)
toProcessTaskCreditLoan 查看信用贷款的合同
ContractPreviewController
investorListData 投资人列表分页数据查询
investorDataPreview 投资人列表打印数据查询
selectBorrowContract 打印合同 数据查询组装接口
CreditLoanController
initCreditData 贷款申请菜单
selectCustomInfo
addData 信用贷款申请添加数据
updateCreditApplySubAcct 修改抵押贷款订单中的客户子账号
Check 信用贷款申请查看页面 方法名写的太简单了
Modify 信用贷款申请修改页面
selectContractBasicInfo 合同基本信息查看
modifyData 信用贷款申请修改数据
generatorContract 信用贷款合同生成
activationContract
activationContract调用cta接口,贷款订单生效
selectCreditLoanContacterPage 拉取电话信息调查人员列表
selectCreditLoanCATIPage 拉取电话信息调查记录
selectBankCardSalaryPage 拉取银行卡工资流水记录
selectBankCardDebtPage 拉取银行卡负债记录
sumBankCardDebt 计算银行卡负债总值
addBankCardDebt 新增银行卡负债记录
initCreditLoanApprData 初始化审核意见的数据字典
addCreditLoanApprOpinion 保存审核信息
上传电调附件 addCreditLoanCATIAtts
checkMatchPhone 内匹客户手机号码
initCreditLoanRateScoreData 初始化费率评分的数据字典
saveCreditLoanRateScore 保存/计算费率评分
modifyContractIds 合同查询添加附件
RepayLoanController
Normal 正常还款
Prepayment 提前还款
Overdue 逾期还款
offerQuery 报盘明细查询
lateOfferQuery 逾期报盘明细查询
Reportgeneralquery 报表通用查询
selectAccBind 正常还款分页数据查询
applyNormalRepay 手工申请报盘
removeApplyRepay 撤销申请
updateReport 修改手动报盘信息
hangAmountSettle 挂账结清
overdueRepayData 逾期还款分页数据查询
overdueReport 逾期手工申请报盘
earlyRepayData 提前还款分页数据查询
reportDetailData 报盘明细 分页查询
overdueDetailData 逾期报盘明细查询
applyReport 正常还款申请报盘
AutomobileMortgageController
MortgageLoanController
selectApplyLoanAll 查询融资申请信息 分页多条
toCheckMortgageApply 跳转至查看页面
toModifyMortgageApply 跳转至修改页面
initMortgageApply 初始化抵押贷款订单的数据字典
addMortgageApply 新增抵押贷款订单
updateMortgageApply修改抵押贷款订单
queryMortgageApply 查询抵押贷款订单
updateMortgageApplySubAcct 修改抵押贷款订单中的客户子账号
generatorContract 抵押贷款合同生成
getRepayPlanInfo 计算还款计划表
–RepayPlanInfo
private Long id;
private BigDecimal loanAmount;//放款金额
private Integer loanTerm;//借款期限
private BigDecimal yearRate;//年化利率
private BigDecimal monthRate;//月利率
private BigDecimal totalRate;//总费率
private String repayType;//还款方式

private BigDecimal totalRepayAmount;//还款总额
private BigDecimal totalAmount;//总费用
private BigDecimal riskAmount;//风险金
private BigDecimal totalServiceAmount;//总服务费
private BigDecimal signAmount;//签约金额
private BigDecimal warranty;//质保金

private BigDecimal monthRepayAmount;//月还款额
private BigDecimal repayInterest;//还款中利息
private BigDecimal repayPrincipal;//还款中本金
private BigDecimal residualPrincipal;//剩余本金
private BigDecimal residualPrincipalInterest;//剩余本息
private Integer period;//当前期数
private BigDecimal serviceFee;//服务费
private BigDecimal backFee;//退费
private BigDecimal overdueLiquidatedDamages;//逾期违约金
private BigDecimal advanceLiquidatedDamages;//提前结清违约金
private BigDecimal advanceLiquidatedRepayAmount;//提前结清还款总额

1.定义list集合装载还款计划表(长度为还款期数)
List repayPlanList = new ArrayList
//定义还款计划对象,add到repayPlanList集合中
RepayPlanInfo repayInfo = null;
//上一期还款计划详情
RepayPlanInfo repayByLast = null;
//获取传入参数
if(repayPlanInfo=null){
loanAmount = repayPlanInfo.getLoanAmount();
loanTerm = new BigDecimal(repayPlanInfo.getLoanTerm());
yearRate = repayPlanInfo.getYearRate().divide(new BigDecimal(100));
monthRate = yearRate.divide(new BigDecimal(12),16,BigDecimal.ROUND_HALF_UP);
totalRate = repayPlanInfo.getTotalRate().divide(new BigDecimal(100));
repayType = repayPlanInfo.getRepayType();
}
//计算还款总额(还款总额=月还款额*借款期限)
BigDecimal totalRepayAmount = monthRepayAmount.multiply(loanTerm).setScale(2,BigDecimal.ROUND_HALF_UP);
log.info(“还款总额={}”,totalRepayAmount);

//计算签约金额(签约金额=月还款额*{(1+月利率)借款期限-1}/{月利率*(1+月利率)借款期限})
BigDecimal signAmount = monthRepayAmount.multiply(oneBigdecimal.add(monthRate).pow(repayPlanInfo.getLoanTerm()).subtract(oneBigdecimal))
.divide(monthRate.multiply(
(oneBigdecimal.add(monthRate)).pow(repayPlanInfo.getLoanTerm()))
, 2, BigDecimal.ROUND_HALF_UP);
log.info(“签约金额={}”,signAmount);

//计算质保金(质保金:签约金额*质保金比例)
warranty = signAmount.multiply(new BigDecimal(0.1)).setScale(2, BigDecimal.ROUND_HALF_UP);
log.info(“质保金={}”,warranty);

//计算总费用(总费用=签约金额-放款金额)
BigDecimal totalAmount = signAmount.subtract(loanAmount);
log.info(“总费用={}”,totalAmount);

//计算风险金(风险金:签约金额的4%)
BigDecimal riskAmount = signAmount.multiply(new BigDecimal(0.04)).setScale(2,BigDecimal.ROUND_HALF_UP);
log.info(“风险金={}”,riskAmount);

//计算总服务费(总服务费=总费用-风险金 (包括乙方和丙方服务费))??
//总服务费=总费用2.5
//计算总服务费(总服务费=总费用-质保金 (包括乙方和丙方服务费))??
//BigDecimal totalServiceAmount = totalAmount.subtract(riskAmount);
//BigDecimal totalServiceAmount = totalAmount;
BigDecimal totalServiceAmount = totalAmount.subtract(warranty);
log.info(“总服务费={}”,totalServiceAmount);

/**
* 根据还款期数遍历计算还款计划表内容
/
for(int i=1;i<=loanTerm.intValue();i++){
log.info(“遍历计算还款计划表,下标i=”+i+“-----------------------------------”);
repayInfo = new RepayPlanInfo();
repayInfo.setPeriod(i);//当前期数
repayInfo.setMonthRepayAmount(monthRepayAmount);//月还款额
repayInfo.setTotalRepayAmount(totalRepayAmount);
repayInfo.setSignAmount(signAmount);
repayInfo.setTotalAmount(totalAmount);
repayInfo.setRiskAmount(riskAmount);
repayInfo.setTotalServiceAmount(totalServiceAmount);
//计算当期月还款中利息的部分(当期月还款中利息的部分=上一期剩余本金
月利率)
if(i==1){
lastResidualPrincipal = signAmount;//第一个月上个月剩余本金=签约金额
repayInterest = signAmount.multiply(monthRate).setScale(2,BigDecimal.ROUND_HALF_UP);
log.info(“第{}期还款利息={}”,i,repayInterest);
}else{
//获取上一期还款记录
repayByLast = repayPlanList.get(i-2);
log.info(“获取第{}期还款记录={}”,i-1,repayByLast);
lastResidualPrincipal = repayByLast.getResidualPrincipal();//上个月剩余本金
repayInterest = repayByLast.getResidualPrincipal().multiply(monthRate).setScale(2,BigDecimal.ROUND_HALF_UP);
log.info(“获取第{}期还款利息={}”,i,repayInterest);
}
repayInfo.setRepayInterest(repayInterest);

  //计算还款中本金(当期月还款中本金的部分=当期月还款额-当期月还款中利息的部分)
  repayPrincipal = monthRepayAmount.subtract(repayInterest);
  log.info("获取第{}期还款本金={}",repayPrincipal);
  repayInfo.setRepayPrincipal(repayPrincipal);
  
  //计算剩余本金(剩余本金:上一期剩余本金-当期月还款中本金的部分 )
  if(i=loanTerm.intValue()){
     residualPrincipal = lastResidualPrincipal.subtract(repayPrincipal);
     log.info("获取第{}期剩余本金={}",i,residualPrincipal);
  }else{
     residualPrincipal = new BigDecimal(0);
  }
  repayInfo.setResidualPrincipal(residualPrincipal);
  
  
  //计算服务费(服务费:每期服务费=剩余还款期数/((期数+1)*(期数/2))*总服务费)
  serviceFee = (loanTerm.subtract(new BigDecimal(i)).add(oneBigdecimal)).divide(
              ((loanTerm.add(oneBigdecimal)).multiply(loanTerm.divide(new BigDecimal(2)).setScale(2,BigDecimal.ROUND_HALF_UP)))
              , 8, BigDecimal.ROUND_HALF_UP).multiply(totalServiceAmount).setScale(2,BigDecimal.ROUND_HALF_UP);
  log.info("服务费={}",serviceFee);
  repayInfo.setServiceFee(serviceFee);
  
  //计算退费(退费:总服务费-已过期数应收服务费),1/2/12退费都为0
  if(i=1 && i=2 && i=loanTerm.intValue()){
     serviceFeeSum = BigDecimal.ZERO;
     //查询当前月服务费以及之前几个月的服务费相加
     for(int j=0;j<repayPlanList.size();j++){
        if(j<=i-2){
           serviceFeeSum = serviceFeeSum.add(repayPlanList.get(j).getServiceFee());
        }
     }
     serviceFeeSum = serviceFeeSum.add(serviceFee);
     backFee = totalServiceAmount.subtract(serviceFeeSum).setScale(2, BigDecimal.ROUND_HALF_UP);
     log.info("退费={}",backFee);
     repayInfo.setBackFee(backFee);
  }else{
     backFee = BigDecimal.ZERO;
  }
  
  //计算提前结清违约金:(剩余本金2%)
  if(i=loanTerm.intValue()){
     advanceLiquidatedDamages = residualPrincipal.multiply(new BigDecimal(0.02)).setScale(2,BigDecimal.ROUND_HALF_UP);
     log.info("提前结清违约金={}",advanceLiquidatedDamages);
  }else{
     advanceLiquidatedDamages = new BigDecimal(0);
  }
  repayInfo.setAdvanceLiquidatedDamages(advanceLiquidatedDamages);
  
  //计算提前结清还款总额:(提前结清还款总额=当月还款额+剩余本金+提前结清违约金-退费)
  advanceLiquidatedRepayAmount = monthRepayAmount.add(residualPrincipal).add(advanceLiquidatedDamages).subtract(backFee);
  log.info("提前结清还款总额={}",advanceLiquidatedRepayAmount);
  repayInfo.setAdvanceLiquidatedRepayAmount(advanceLiquidatedRepayAmount);
  
  //计算剩余本息(剩余本息=月还款额*(借款期限-借款处于第几期+1))
  residualPrincipalInterest = monthRepayAmount.multiply(loanTerm.subtract(new BigDecimal(i)).add(oneBigdecimal)).setScale(2,BigDecimal.ROUND_HALF_UP);
  log.info("剩余本息={}",residualPrincipalInterest);
  repayInfo.setResidualPrincipalInterest(residualPrincipalInterest);
  
  //计算逾期违约金(逾期违约金:剩余本息的0.05%,每天)
  overdueLiquidatedDamages = residualPrincipalInterest.multiply(new BigDecimal(0.0005)).setScale(2,BigDecimal.ROUND_HALF_UP);
  log.info("逾期违约金={}",overdueLiquidatedDamages);
  repayInfo.setOverdueLiquidatedDamages(overdueLiquidatedDamages);
  repayPlanList.add(repayInfo);

}
} catch (Exception e) {
e.printStackTrace();
log.error(“还款计划利息计算异常,原因=”+e.getMessage());
}
CreditReportController
selectCreditLoanContacterPage 拉取当前用户提交的征信报告列表
uploadCreditReportsOfBOC 中国银行征信上传
LoanReportController
actualRemindPrincipalExport
applyLoan
signingLoan
signedLoan
creditedLoan
applyLoanExport
signingLoanExport
signedLoanExport
creditedLoanExport
ApplyApprovalLoan
selectVehicleTypeAndBrand
AttachmentController 系统附件
saveFile 附件上传
selectFile 多个附件查询,
delUpLoadFile 上传附件删除
previewAttachment 单个附件预览
dowLoadZipFile 附件打包下载
downloadAnnex 单个附件下载
downloadFilesByName
findFilesByName
BaseController
writeJson 将对象转换成JSON字符串,并响应回前台
Write 将普通字符串数据响应回前台
initBinder 视图数据绑定模型前将字符串类型时间转型为日期格式
DepartmentController
addOrgan 添加部门
updateDepart 修改部门信息
delDepart 删除部门信息
getDepatInfo 查询所有部门信息
getDepartTree 展示当前用户的部门信息
getSysDepartTree 展示系统所有的部门信息
getSonTree 向下获取子树
getFatherTree 获取父节点的信息
getRole 点击节点的时候显示当前节点的部门,角色,用户
getDepartUser 用户信息展示
DictionaryController 字典数据
getDictByType
getChildDictByType 根据父id取出对应的字段列表
getChildDictByTypeAndKey 根据父id and dataKey取出对应的字段列表
IndexController 首页信息加载
goIndex 首页dashboard的一些简要信息
LoginController
Login
loginOutUser
updatePwd
MenuController
addMenu 添加菜单
updateMenu 修改菜单信息
delMenu 删除菜单信息
getMenuInfo 查询菜单信息
getMenuInfo 权限配置
getMenuTrees 获取菜单树
selectProcessInfo 流程配置信息查询
addProcessInfo 流程配置信息新增
updateProcessInfo 流程配置信息修改
saveFile 流程信息添加 附件上传
delUpLoadFile 流程配置上传附件删除
selectUpLoadFile 流程配置上传附件查询
RoleController
Addrole 添加角色
updateRole 修改角色信息
delRole 删除角色信息
getRoleInfo 查询角色信息
getRoleInfo 展示角色信息
getRoleUserInfo 展示角色关联用户信息
getProcessRoleInfo 流程角色查询
updateProcessRoleInfo 流程角色信息修改
selectProcessDepartUserInfo 流程角色分配树,显示所有部门信息,并且显示所有部门下的人员信息
selectProcessUserRoleInfo 流程角色下已经关联的用户查询
TSysDataController
selectDataTypeAll 数据字典,数据类型表查询,需要查询全部数据显示
selectDataTypeAllPage 数据字典,数据类型表查询,需要查询全部数据显示
selectDataAll 数据字典 数据表查询,根据类型Id
addDataTypeAll
updateDataTypeAll
addDataAll
updateDataAll
UpLoad
uploadFile
UserController
addUser 添加用户
updateUser 修改用户信息
delUser 删除用户信息
getRoleUser 查询用户信息
getAllUser 查询所有的用户信息
VehicleController
selectAssetsByPage 资产信息列表前台分页查询
addAssets 资产信息表新增客户数据
addVehicle 车辆基本信息表新增车辆信息
addAssessment 车辆评估表新增评估数据
addVehicleConfig 车辆配置表新增配置数据
updateAssets 修改资产信息表客户数据
updateVehicle 修改车辆基本信息表数据
updateVehicleConfig 修改车辆配置表数据
updateAssessment 修改车辆评估表数据
selectAssessment 查询资产信息表,车辆基本信息表数据
updateAssessmentPage 查询资产信息表,车辆基本信息表数据
IntopiecesController
addIntopieces 业务进件、保存进件信息
loadIntopiecesList 获取进件列表
loadApplyInfo 异步加载申请信息
getvalidatroIntopieces 查询当前企业是否有未完成的流程:已完成的流程包括正常结束和归档的流程。证件编号申请在处理中
insertIntopiecesApply 申请启动流程
toApproveFactoring 办理保理业务的审批
toApproveLoanApply 办理融资申请的审批
toApproveMortLoan 办理抵押贷款的审批
toApproveCreditLoan 办理信用贷款的审批
delIntopieces 删除个人信用货款申请信息
WorkflowController
loadByProcessInstance 读取资源,通过流程ID
traceProcess 输出跟踪流程信息
loadClaimApplyList 任务认领列表(待签收列表)
claimTask 签收任务
loadAllotApplyList 任务分配列表(待签收列表)
allotTask 签收任务(分配任务)
selectByRoleName 根据岗位名称配置审批人员下拉列表
loadRunningList ajax请求已处理流程任务
loadPendingApplyList 请求待处理流程任务列表
completeFactoring 保理业务 审批流程
postponeConfirm 客户经理 延期 落实条件
completeLoanApply 融资申请 审批流程
completeMortLoan 抵押贷款 审批流程
completeCreditLoan 信用贷款 审批流

–excel
–vo
(2)aim-service,
(3)aim-dao,
(4)aim-model,
(5)aim-core,
SessionFilter

(6)aim-task
WorkflowTask
cancelActivity
RefuseLoanTask
automaticRefuseLoan 风控经理审批通过,在待签约环节,客户系统中保留15个自然日进行签约,15个自然日内未签约的客户,系统做超时自动拒贷处理。
OverdueRepayTask
updateOverdueStatus 更新逾期状态
overdueRepay 逾期自动报盘
calculatePenalty 计算罚息定时任务
NormalRepayTask
automaticReport 自动申请报盘
automaticReportCTA 定时任务自动发起报盘扣款请求对接CTA
AcctStatusTask
acctStatusSync 账户状态同步推送定时任务

spring-task.xml 定期任务的执行在这里调用

<–自动申请 定时任务

task:scheduled-tasks
<task:scheduled ref=“normalTask” method=“automaticReport” cron=“0 0 4 * * ?”/>
</task:scheduled-tasks>-
<–自动报盘Cta定时任务

task:scheduled-tasks
<task:scheduled ref=“payReprotTask” method=“automaticReportCTA” cron=“0 30 10,16,20 * * ?”/>
</task:scheduled-tasks>-
<–账户状态同步推送定时任务,在自动报盘完成之后进行

task:scheduled-tasks
<task:scheduled ref=“acctStatusSyncTask” method=“acctStatusSync” cron=“0 30 12,18,22 * * ?”/>
</task:scheduled-tasks>-

<–更新逾期状态任务定时任务

task:scheduled-tasks
<task:scheduled ref=“overdueStatusTask” method=“updateOverdueStatus” cron=“0 0 1 * * ?”/>
</task:scheduled-tasks>

<–逾期自动报盘

task:scheduled-tasks
<task:scheduled ref=“overdueRepayTask” method=“overdueRepay” cron=“0 30 11,17,21 * * ?”/>
</task:scheduled-tasks>
<–计算逾期罚息定时任务

task:scheduled-tasks
<task:scheduled ref=“overduePenaltyTask” method=“calculatePenalty” cron=“0 0 2 * * ?”/>
</task:scheduled-tasks>

<-- 1.对于信用贷款,若超时(5天)未处理则直接归档。每天23点执行一次

task:scheduled-tasks
<task:scheduled ref=“workflowTask” method=“cancelActivity” cron=“0 0 23 * * ?”/>
</task:scheduled-tasks>
1.待签约客户超过15个自然日未签约处理,视为自动拒贷。每天23点执行一次

task:scheduled-tasks
<task:scheduled ref=“refuseLoanTask” method=“automaticRefuseLoan” cron=“0 0 23 * * ?”/>
</task:scheduled-tasks>

(7)aim-api

CTA系统 有使用到rabbitMq,aim使用了MongoDB

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值