feat: add assignment import

This commit is contained in:
Donghuang 2024-10-27 14:06:20 +08:00
parent b3e6ed7483
commit 9de37aed9d
86 changed files with 3377 additions and 486 deletions

View File

@ -1,8 +1,18 @@
package com.pudonghot.yo.util;
import lombok.val;
import lombok.Setter;
import lombok.Getter;
import java.util.List;
import lombok.ToString;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.stream.Stream;
import java.util.stream.Collector;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
/**
* @author Donghuang
@ -28,4 +38,69 @@ public class ListUtils {
consumer.accept(list.subList(i, Math.min(size, i + batch)));
}
}
public static <T> void eachBatch(
final Iterable<T> it,
final int batch,
final Consumer<List<T>> consumer) {
val iterator = it.iterator();
Stream.<T>generate(() -> null)
.takeWhile(x -> iterator.hasNext())
.map(e -> iterator.next())
.collect(partitionBySize(batch, Collectors.toList())).forEach(consumer);
}
static <T, A, R> Collector<T, ?, R> partitionBySize(final int batchSize,
final Collector<List<T>, A, R> downstream) {
return Collector.of(() -> new Accumulator<>(
batchSize,
downstream.supplier().get(),
downstream.accumulator()::accept
),
(acc, value) -> acc.add(value),
(acc1, acc2) -> acc1.combine(acc2, downstream.combiner()),
acc -> {
if (!acc.values.isEmpty()) {
downstream.accumulator().accept(acc.downstreamAccumulator, acc.values);
}
return downstream.finisher().apply(acc.downstreamAccumulator);
},
Collector.Characteristics.UNORDERED);
}
@Getter
@Setter
@ToString
static class Accumulator<T, A> {
private final List<T> values = new ArrayList<>();
private final int batchSize;
private A downstreamAccumulator;
private final BiConsumer<A, List<T>> batchFullListener;
public Accumulator(final int batchSize,
final A downstreamAccumulator,
final BiConsumer<A, List<T>> batchFullListener) {
this.batchSize = batchSize;
this.downstreamAccumulator = downstreamAccumulator;
this.batchFullListener = batchFullListener;
}
public void add(final T value) {
values.add(value);
if (values.size() == batchSize) {
batchFullListener.accept(downstreamAccumulator, new ArrayList<>(values));
values.clear();
}
}
public Accumulator<T, A> combine(final Accumulator<T, A> other,
final BinaryOperator<A> accumulatorCombiner) {
this.downstreamAccumulator = accumulatorCombiner.apply(downstreamAccumulator, other.downstreamAccumulator);
other.values.forEach(this::add);
return this;
}
}
}

View File

@ -1,10 +1,15 @@
package com.pudonghot.yo.util;
import lombok.val;
import org.junit.Test;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.IntStream;
import lombok.extern.slf4j.Slf4j;
import static java.util.stream.Collectors.toList;
/**
* @author Donghuang
* @date Sep 13, 2020 10:25:44
@ -14,10 +19,18 @@ public class ListUtilsTest {
@Test
public void testEachBatch() {
List<Long> list = new ArrayList<>(100);
for (long i = 0; i < 100; i++) {
list.add(i);
}
val list = IntStream.range(0, 100)
.mapToObj(i -> i)
.collect(toList());
ListUtils.eachBatch(list, 8, sub -> log.info("{}", sub));
}
@Test
public void testEachBatch2() {
val list = IntStream.range(0, 100)
.mapToObj(i -> i)
.collect(toList());
ListUtils.eachBatch(list, 8, sub -> log.info("{}", sub));
}
}

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="log.level">DEBUG</Property>
<Property name="log.dir">.logs</Property>
<Property name="pattern">%-d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%t][%c{1}] %m%n</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%highlight{%-d{yyyy-MM-dd HH:mm:ss,SSS}}{FATAL=magenta, ERROR=magenta, WARN=magenta, INFO=magenta, DEBUG=magenta, TRACE=magenta} %highlight{%-5p}{FATAL=red blink, ERROR=red, WARN=yellow bold, INFO=black, DEBUG=green bold, TRACE=blue} [%t][%highlight{%c{1.}}{FATAL=cyan, ERROR=cyan, WARN=cyan, INFO=cyan, DEBUG=cyan, TRACE=cyan}] %m%n"/>
</Console>
<RollingFile name="File"
fileName="${log.dir}/app.log"
filePattern="${log.dir}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="${pattern}" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="16 MB" />
</Policies>
<DefaultRolloverStrategy max="32" />
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.springframework" level="INFO" additivity="false">
<AppenderRef ref="File" />
</Logger>
<Logger name="org.apache" level="WARN" additivity="false">
<AppenderRef ref="File" />
</Logger>
<Logger name="org.hibernate.validator" level="WARN" additivity="false">
<AppenderRef ref="File" />
</Logger>
<Root level="${log.level}" additivity="false">
<AppenderRef ref="File" level="${log.level}" />
<AppenderRef ref="Console" level="${log.level}" />
</Root>
</Loggers>
</Configuration>

View File

@ -15,8 +15,8 @@ import com.pudonghot.tigon.enumuration.LabelEnum;
public enum AssignmentStatusEnum implements LabelEnum {
ACTIVE("在调"),
STOP("停调"),
EXPIRE("出调"),
STOP_COLLECT("停调"),
;

View File

@ -0,0 +1,24 @@
package com.pudonghot.yo.operation.enumeration.assignment;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import com.pudonghot.tigon.enumuration.LabelEnum;
/**
* 分案案件状态
*
* @author Donghuang
* @date Oct 22, 2024 10:57:51
*/
@Getter
@RequiredArgsConstructor
public enum AssignmentTypeEnum implements LabelEnum {
MANUAL("手动"),
AUTOMATIC("自动"),
AVERAGE("平均"),
;
private final String label;
}

View File

@ -0,0 +1,23 @@
package com.pudonghot.yo.operation.enumeration.interaction;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import com.pudonghot.tigon.enumuration.LabelEnum;
/**
* 跟进记录操作类型
*
* @author Donghuang
* @date Oct 23, 2024 14:21:30
*/
@Getter
@RequiredArgsConstructor
public enum HandelCategoryEnum implements LabelEnum {
MANUAL("人工"),
SYSTEM("系统"),
;
private final String label;
}

View File

@ -1,20 +1,21 @@
package com.pudonghot.yo.operation.enumeration.customer;
package com.pudonghot.yo.operation.enumeration.interaction;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import com.pudonghot.tigon.enumuration.LabelEnum;
/**
* 跟进记录类型
*
* @author Donghuang
* @date Oct 10, 2024 11:05:03
* @date Oct 23, 2024 11:32:53
*/
@Getter
@RequiredArgsConstructor
public enum GenderEnum implements LabelEnum {
public enum InteractionTypeEnum implements LabelEnum {
M(""),
F(""),
U("未知"),
PHONE("电话"),
MESSAGE("短信"),
;

View File

@ -64,6 +64,10 @@
<groupId>com.pudonghot.yo</groupId>
<artifactId>yo-tj-operation-common</artifactId>
</dependency>
<dependency>
<groupId>com.pudonghot.tigon</groupId>
<artifactId>tigon-cms-dal</artifactId>
</dependency>
<dependency>
<groupId>com.pudonghot.yo</groupId>
<artifactId>yo-dal</artifactId>

View File

@ -1,7 +1,9 @@
package com.pudonghot.yo.operation.dal.assignment;
import java.util.Collection;
import com.pudonghot.tigon.dal.BaseDal;
import com.pudonghot.yo.operation.dal.assignment.model.AssignmentDO;
import com.pudonghot.yo.operation.dal.assignment.request.AssignReqDO;
/**
* 催收案件分单记录表
@ -10,4 +12,20 @@ import com.pudonghot.yo.operation.dal.assignment.model.AssignmentDO;
* @date Oct 01, 2024 14:19:37
*/
public interface AssignmentDal extends BaseDal<Long, AssignmentDO> {
/**
* 出催
*
* @param loanIdList loan id list
* @return rows
*/
Integer checkOut(Collection<Long> loanIdList);
/**
* 分案
*
* @param req req
* @return rows
*/
Integer assign(Collection<AssignReqDO> req);
}

View File

@ -1,10 +1,14 @@
package com.pudonghot.yo.operation.dal.assignment.impl;
import org.springframework.stereotype.Component;
import com.pudonghot.yo.operation.dal.assignment.model.AssignmentDO;
import com.pudonghot.yo.operation.dal.assignment.mapper.AssignmentMapper;
import com.pudonghot.yo.operation.dal.assignment.AssignmentDal;
import java.util.Collection;
import com.pudonghot.tigon.mybatis.Search;
import com.pudonghot.tigon.dal.impl.BaseDalImpl;
import org.springframework.stereotype.Component;
import com.pudonghot.tigon.mybatis.util.EntityUtils;
import com.pudonghot.yo.operation.dal.assignment.AssignmentDal;
import com.pudonghot.yo.operation.dal.assignment.model.AssignmentDO;
import com.pudonghot.yo.operation.dal.assignment.request.AssignReqDO;
import com.pudonghot.yo.operation.dal.assignment.mapper.AssignmentMapper;
/**
* 催收案件分单记录表
@ -16,4 +20,21 @@ import com.pudonghot.tigon.dal.impl.BaseDalImpl;
public class AssignmentDalImpl
extends BaseDalImpl<Long, AssignmentDO, AssignmentMapper>
implements AssignmentDal {
/**
* {@inheritDoc}
*/
@Override
public Integer checkOut(final Collection<Long> loanIdList) {
return update(EntityUtils.updateMap(new BatchDisableDO()),
Search.of(AssignmentDO.Fields.loanId, loanIdList));
}
/**
* {@inheritDoc}
*/
@Override
public Integer assign(final Collection<AssignReqDO> req) {
return mapper.assign(req);
}
}

View File

@ -1,10 +1,13 @@
package com.pudonghot.yo.operation.dal.assignment.mapper;
import com.pudonghot.tigon.mybatis.Table;
import com.pudonghot.yo.operation.dal.assignment.request.AssignReqDO;
import org.apache.ibatis.annotations.Mapper;
import com.pudonghot.tigon.mybatis.BaseMapper;
import com.pudonghot.yo.operation.dal.assignment.model.AssignmentDO;
import java.util.Collection;
/**
* 催收案件分单记录表
*
@ -14,4 +17,12 @@ import com.pudonghot.yo.operation.dal.assignment.model.AssignmentDO;
@Mapper
@Table("assignment")
public interface AssignmentMapper extends BaseMapper<Long, AssignmentDO> {
/**
* 分案
*
* @param req req
* @return rows
*/
Integer assign(Collection<AssignReqDO> req);
}

View File

@ -10,4 +10,30 @@
* @date Oct 01, 2024 14:19:37
*/
-->
<insert id="assign">
insert into <include refid="table" />
(loan_id, agent_id, status, assign_time, assign_type, expect_expire_date)
select l.id, m.id, 'ACTIVE', now(), 'MANUAL', bn.withdraw_date
from <include refid="com.pudonghot.yo.operation.dal.loan.mapper.LoanMapper.table" /> l
join <include refid="com.pudonghot.yo.operation.dal.loanimport.mapper.BatchNumberMapper.table" /> bn
on l.import_batch_id = bn.id
join (
select null loan_id, null agent_id
<foreach collection="collection" item="it">
union select #{it.loanId}, #{it.agentId}
</foreach>
) t
on l.id = t.loan_id
join <include refid="com.pudonghot.tigon.cms.dal.member.mapper.MemberMapper.table" /> m
on m.id = t.agent_id
left join <include refid="table" /> a
on l.id = a.loan_id
and a.active = 1
where a.id is null
</insert>
</mapper>

View File

@ -1,5 +1,6 @@
package com.pudonghot.yo.operation.dal.assignment.model;
import com.pudonghot.yo.operation.enumeration.assignment.AssignmentTypeEnum;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
@ -34,16 +35,6 @@ public class AssignmentDO extends BaseDbEntity {
@NotUpdate
private Long agentId;
/**
* 催收员分组ID
*/
private Long groupId;
/**
* 协助催收员ID
*/
private Long assistantAgentId;
/**
* 催收状态在催出催
*/
@ -55,6 +46,12 @@ public class AssignmentDO extends BaseDbEntity {
@NotUpdate
private Date assignTime;
/**
* 分案方式
*/
@NotUpdate
private AssignmentTypeEnum assignType;
/**
* 预计出催日期
*/
@ -66,7 +63,13 @@ public class AssignmentDO extends BaseDbEntity {
private Date actualExpireDate;
/**
* 分案方式
* 催收员分组ID
*/
private String assignType;
private Long groupId;
/**
* 协助催收员ID
*/
private Long assistantAgentId;
}

View File

@ -0,0 +1,28 @@
package com.pudonghot.yo.operation.dal.assignment.request;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
/**
* 手动分案
*
* @author Donghuang
* @date Oct 27, 2024 10:56:14
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "loanId")
public class AssignReqDO implements Serializable {
private static final long serialVersionUID = 1L;
private Long loanId;
private Long agentId;
}

View File

@ -1,7 +1,9 @@
package com.pudonghot.yo.operation.dal.interaction;
import com.pudonghot.yo.operation.dal.interaction.model.InteractionDO;
import java.util.List;
import com.pudonghot.tigon.dal.BaseDal;
import com.pudonghot.yo.operation.dal.interaction.model.InteractionDO;
import com.pudonghot.yo.operation.dal.interaction.response.InteractionAgentDO;
/**
* 催收记录表
@ -10,4 +12,12 @@ import com.pudonghot.tigon.dal.BaseDal;
* @date Oct 01, 2024 14:19:55
*/
public interface InteractionDal extends BaseDal<Long, InteractionDO> {
/**
* agents
*
* @param loanId loan id
* @return agents
*/
List<InteractionAgentDO> agents(Long loanId);
}

View File

@ -1,10 +1,22 @@
package com.pudonghot.yo.operation.dal.interaction.impl;
import lombok.val;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import lombok.ToString;
import java.io.Serializable;
import com.pudonghot.tigon.mybatis.Search;
import org.springframework.stereotype.Component;
import com.pudonghot.tigon.dal.impl.BaseDalImpl;
import com.pudonghot.tigon.dal.model.BaseDbEntity;
import com.pudonghot.tigon.dal.request.ListDalReq;
import com.pudonghot.yo.operation.dal.interaction.InteractionDal;
import com.pudonghot.yo.operation.dal.interaction.model.InteractionDO;
import com.pudonghot.yo.operation.enumeration.interaction.ConclusionEnum;
import com.pudonghot.yo.operation.dal.interaction.mapper.InteractionMapper;
import com.pudonghot.yo.operation.enumeration.interaction.InteractionTypeEnum;
import com.pudonghot.yo.operation.dal.interaction.response.InteractionAgentDO;
/**
* 催收记录表
@ -16,4 +28,58 @@ import com.pudonghot.yo.operation.dal.interaction.mapper.InteractionMapper;
public class InteractionDalImpl
extends BaseDalImpl<Long, InteractionDO, InteractionMapper>
implements InteractionDal {
/**
* {@inheritDoc}
*/
@Override
public List<InteractionAgentDO> agents(final Long loanId) {
return mapper.agents(loanId);
}
/**
* {@inheritDoc}
*/
@Override
protected void beforeList(final ListDalReq req, final Search search) {
search.desc(BaseDbEntity.Fields.id);
val params = beanService.convert(req, ListReqParam.class);
search.eq(InteractionDO.Fields.loanId, params.getLoanId());
notNull(params::getAgentId, v -> search.eq(InteractionDO.Fields.agentId, v));
notNull(params::getType, v -> search.eq(InteractionDO.Fields.type, v));
notNull(params::getConclusion, v -> search.eq(InteractionDO.Fields.conclusion, v));
notBlank(params::getRemark, v -> search.contains(BaseDbEntity.Fields.remark, v));
}
@Getter
@Setter
@ToString
static class ListReqParam implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 案件ID
*/
private Long loanId;
/**
* 调解员
*/
private Long agentId;
/**
* 催收方式
*/
private InteractionTypeEnum type;
/**
* 结论
*/
private ConclusionEnum conclusion;
/**
* 备注
*/
private String remark;
}
}

View File

@ -1,9 +1,11 @@
package com.pudonghot.yo.operation.dal.interaction.mapper;
import java.util.List;
import com.pudonghot.tigon.mybatis.Table;
import org.apache.ibatis.annotations.Mapper;
import com.pudonghot.tigon.mybatis.BaseMapper;
import com.pudonghot.yo.operation.dal.interaction.model.InteractionDO;
import com.pudonghot.yo.operation.dal.interaction.response.InteractionAgentDO;
/**
* 催收记录表
@ -14,4 +16,12 @@ import com.pudonghot.yo.operation.dal.interaction.model.InteractionDO;
@Mapper
@Table("interaction")
public interface InteractionMapper extends BaseMapper<Long, InteractionDO> {
/**
* interaction agents
*
* @param loanId loan id
* @return agents
*/
List<InteractionAgentDO> agents(Long loanId);
}

View File

@ -10,4 +10,15 @@
* @date Oct 01, 2024 14:19:55
*/
-->
<select id="agents" resultType="com.pudonghot.yo.operation.dal.interaction.response.InteractionAgentDO">
select a.id, a.name, a.active
from
<include refid="com.pudonghot.tigon.cms.dal.member.mapper.MemberMapper.table" /> a
join <include refid="table" /> i
on a.id = i.agent_id
and i.loan_id = #{loanId}
and a.deleted = 0
and i.deleted = 0
</select>
</mapper>

View File

@ -1,5 +1,7 @@
package com.pudonghot.yo.operation.dal.interaction.model;
import com.pudonghot.yo.operation.enumeration.interaction.HandelCategoryEnum;
import com.pudonghot.yo.operation.enumeration.interaction.InteractionTypeEnum;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
@ -38,7 +40,7 @@ public class InteractionDO extends BaseDbEntity {
/**
* 催收方式
*/
private String type;
private InteractionTypeEnum type;
/**
* 催收日期
@ -58,7 +60,7 @@ public class InteractionDO extends BaseDbEntity {
/**
* 操作类别:内部人工;内部自动
*/
private String handleCategory;
private HandelCategoryEnum handleCategory;
/**
* 是否有效联络: 有效;无效

View File

@ -0,0 +1,20 @@
package com.pudonghot.yo.operation.dal.interaction.response;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
/**
* @author Donghuang
* @date Oct 23, 2024 11:37:23
*/
@Getter
@Setter
@ToString
public class InteractionAgentDO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
}

View File

@ -3,6 +3,8 @@ package com.pudonghot.yo.operation.dal.loan;
import com.pudonghot.tigon.dal.BaseDal;
import com.pudonghot.yo.operation.dal.loan.model.BankCardDO;
import java.util.List;
/**
* 银行卡绑定信息表
*
@ -18,4 +20,12 @@ public interface BankCardDal extends BaseDal<Long, BankCardDO> {
* @return rows
*/
Integer removeByLoanId(Long loanId);
/**
* list by loan id
*
* @param loanId loan id
* @return bank cards
*/
List<BankCardDO> listByLoanId(Long loanId);
}

View File

@ -3,6 +3,8 @@ package com.pudonghot.yo.operation.dal.loan;
import com.pudonghot.tigon.dal.BaseDal;
import com.pudonghot.yo.operation.dal.loan.model.ContactDO;
import java.util.List;
/**
* 客户联系人表
*
@ -18,4 +20,12 @@ public interface ContactDal extends BaseDal<Long, ContactDO> {
* @return rows
*/
Integer removeByLoanId(Long loanId);
/**
* list by loan id
*
* @param loanId loan id
* @return contacts
*/
List<ContactDO> listByLoanId(Long loanId);
}

View File

@ -1,40 +0,0 @@
package com.pudonghot.yo.operation.dal.loan;
import com.pudonghot.yo.operation.dal.loan.model.LoanSourceDO;
import com.pudonghot.tigon.dal.BaseDal;
import java.util.Collection;
import java.util.List;
/**
* 案件来源表
*
* @author Donghuang
* @date Oct 01, 2024 14:20:47
*/
public interface LoanSourceDal extends BaseDal<Long, LoanSourceDO> {
/**
* find by code
*
* @param code code
* @return loan source
*/
LoanSourceDO findByCode(String code);
/**
* find by name
*
* @param name name
* @return loan source
*/
LoanSourceDO findByName(String name);
/**
* list by names
*
* @param names name
* @return loan sources
*/
List<LoanSourceDO> listByNames(Collection<String> names);
}

View File

@ -1,11 +1,12 @@
package com.pudonghot.yo.operation.dal.loan.impl;
import java.util.List;
import com.pudonghot.tigon.mybatis.Search;
import org.springframework.stereotype.Component;
import com.pudonghot.tigon.dal.impl.BaseDalImpl;
import com.pudonghot.yo.operation.dal.loan.BankCardDal;
import com.pudonghot.yo.operation.dal.loan.model.BankCardDO;
import com.pudonghot.yo.operation.dal.loan.mapper.BankCardMapper;
import com.pudonghot.yo.operation.dal.loan.BankCardDal;
import com.pudonghot.tigon.dal.impl.BaseDalImpl;
/**
* 银行卡绑定信息表
@ -25,4 +26,12 @@ public class BankCardDalImpl
public Integer removeByLoanId(final Long loanId) {
return mapper.delete(Search.of(BankCardDO.Fields.loanId, loanId));
}
/**
* {@inheritDoc}
*/
@Override
public List<BankCardDO> listByLoanId(final Long loanId) {
return list(Search.of(BankCardDO.Fields.loanId, loanId));
}
}

View File

@ -1,11 +1,12 @@
package com.pudonghot.yo.operation.dal.loan.impl;
import java.util.List;
import com.pudonghot.tigon.mybatis.Search;
import org.springframework.stereotype.Component;
import com.pudonghot.tigon.dal.impl.BaseDalImpl;
import com.pudonghot.yo.operation.dal.loan.ContactDal;
import com.pudonghot.yo.operation.dal.loan.model.ContactDO;
import com.pudonghot.yo.operation.dal.loan.mapper.ContactMapper;
import com.pudonghot.yo.operation.dal.loan.ContactDal;
import com.pudonghot.tigon.dal.impl.BaseDalImpl;
/**
* 客户联系人表
@ -25,4 +26,12 @@ public class ContactDalImpl
public Integer removeByLoanId(final Long loanId) {
return mapper.delete(Search.of(ContactDO.Fields.loanId, loanId));
}
/**
* {@inheritDoc}
*/
@Override
public List<ContactDO> listByLoanId(final Long loanId) {
return list(Search.of(ContactDO.Fields.loanId, loanId));
}
}

View File

@ -1,51 +0,0 @@
package com.pudonghot.yo.operation.dal.loan.impl;
import com.pudonghot.tigon.mybatis.Search;
import org.springframework.stereotype.Component;
import com.pudonghot.tigon.dal.impl.BaseDalImpl;
import com.pudonghot.tigon.dal.model.BaseDbEntity;
import com.pudonghot.yo.operation.dal.loan.LoanSourceDal;
import com.pudonghot.yo.operation.dal.loan.model.LoanSourceDO;
import com.pudonghot.yo.operation.dal.loan.mapper.LoanSourceMapper;
import java.util.Collection;
import java.util.List;
/**
* 案件来源表
*
* @author Donghuang
* @date Oct 01, 2024 14:20:47
*/
@Component
public class LoanSourceDalImpl
extends BaseDalImpl<Long, LoanSourceDO, LoanSourceMapper>
implements LoanSourceDal {
/**
* {@inheritDoc}
*/
@Override
public LoanSourceDO findByCode(final String code) {
return find(Search.of(LoanSourceDO.Fields.loanSourceCode, code)
.isTrue(BaseDbEntity.Fields.active));
}
/**
* {@inheritDoc}
*/
@Override
public LoanSourceDO findByName(final String name) {
return find(Search.of(LoanSourceDO.Fields.loanSourceName, name)
.isTrue(BaseDbEntity.Fields.active));
}
/**
* {@inheritDoc}
*/
@Override
public List<LoanSourceDO> listByNames(final Collection<String> names) {
return list(Search.of(LoanSourceDO.Fields.loanSourceName, names)
.isTrue(BaseDbEntity.Fields.active));
}
}

View File

@ -109,7 +109,11 @@
t.commission_date,
t.commission_org,
t.dept_id,
t.dept_name,
t.assign_status,
t.assign_agent_id,
t.assign_agent_name,
t.assign_time,
@ -144,12 +148,15 @@
c.name customer_name,
c.id_no customer_id_no,
ls.loan_source_name,
ls.value loan_source_name,
bn.batch_number,
bn.commission_date,
bn.commission_org,
bn.dept_id,
dept.value dept_name,
aa.status assign_status,
aa.agent_id assign_agent_id,
agent.name assign_agent_name,
@ -236,8 +243,9 @@
</foreach>
</if>
join <include refid="com.pudonghot.yo.operation.dal.loan.mapper.LoanSourceMapper.table" /> ls
join <include refid="com.pudonghot.tigon.cms.dal.dict.mapper.DictMapper.table" /> ls
on l.loan_source_id = ls.id
and ls.deleted = 0
join <include refid="com.pudonghot.yo.operation.dal.loanimport.mapper.BatchNumberMapper.table" /> bn
on l.import_batch_id = bn.id
@ -258,10 +266,18 @@
and bn.commission_date between #{startCommissionDate} and #{endCommissionDate}
</if>
join <include refid="com.pudonghot.tigon.cms.dal.dict.mapper.DictMapper.table" /> dept
on bn.dept_id = dept.id
and dept.deleted = 0
left join <include refid="com.pudonghot.yo.operation.dal.assignment.mapper.AssignmentMapper.table" /> aa
on l.id = aa.loan_id
left join <include refid="com.pudonghot.yo.dal.agent.mapper.AgentMapper.table" /> agent
and aa.deleted = 0
and aa.active = 1
left join <include refid="com.pudonghot.tigon.cms.dal.member.mapper.MemberMapper.table" /> agent
on aa.agent_id = agent.id
and agent.deleted = 0
where 1 = 1
@ -325,13 +341,14 @@
)
from
<include refid="com.pudonghot.yo.operation.dal.interaction.mapper.InteractionMapper.table" /> i
join <include refid="com.pudonghot.tigon.cms.dal.member.mapper.MemberMapper.table" /> a
on i.agent_id = a.id
and a.deleted = 0
left join <include refid="com.pudonghot.yo.operation.dal.interaction.mapper.InteractionMapper.table" /> i2
on i.loan_id = i2.loan_id
and i2.id > i.id
join <include refid="com.pudonghot.yo.dal.agent.mapper.AgentMapper.table" /> a
on i.agent_id = a.id
where i.loan_id = l.id
and i2.id is null
</sql>

View File

@ -1,17 +0,0 @@
package com.pudonghot.yo.operation.dal.loan.mapper;
import com.pudonghot.tigon.mybatis.Table;
import org.apache.ibatis.annotations.Mapper;
import com.pudonghot.tigon.mybatis.BaseMapper;
import com.pudonghot.yo.operation.dal.loan.model.LoanSourceDO;
/**
* 案件来源表
*
* @author Donghuang
* @date Oct 01, 2024 14:20:47
*/
@Mapper
@Table("loan_source")
public interface LoanSourceMapper extends BaseMapper<Long, LoanSourceDO> {
}

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pudonghot.yo.operation.dal.loan.mapper.LoanSourceMapper">
<!--
/**
* 案件来源表
*
* @author Donghuang
* @date Oct 01, 2024 14:20:47
*/
-->
</mapper>

View File

@ -2,11 +2,12 @@ package com.pudonghot.yo.operation.dal.loan.model;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import com.pudonghot.tigon.mybatis.NotUpdate;
import lombok.experimental.FieldNameConstants;
import com.pudonghot.tigon.dal.model.BaseDbEntity;
import com.pudonghot.tigon.mybatis.UseGeneratedKeys;
import com.pudonghot.yo.operation.enumeration.customer.GenderEnum;
import com.pudonghot.tigon.cms.common.enumeration.GenderEnum;
/**
* 客户表
@ -37,6 +38,16 @@ public class CustomerDO extends BaseDbEntity {
*/
private String idNo;
/**
* 性别
*/
private GenderEnum gender;
/**
* 出生日期
*/
private Date birthday;
/**
* 手机
*/
@ -47,21 +58,11 @@ public class CustomerDO extends BaseDbEntity {
*/
private String email;
/**
* 性别
*/
private GenderEnum gender;
/**
* 民族
*/
private String nation;
/**
* 出生日期
*/
private String birthday;
/**
* 户籍地址
*/

View File

@ -1,33 +0,0 @@
package com.pudonghot.yo.operation.dal.loan.model;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldNameConstants;
import com.pudonghot.tigon.mybatis.NotUpdate;
import com.pudonghot.tigon.dal.model.BaseDbEntity;
import com.pudonghot.tigon.mybatis.UseGeneratedKeys;
/**
* 案件来源表
*
* @author Donghuang
* @date Oct 01, 2024 14:20:47
*/
@Getter
@Setter
@UseGeneratedKeys
@FieldNameConstants
public class LoanSourceDO extends BaseDbEntity {
private static final long serialVersionUID = 1L;
/**
* 渠道数据源代码
*/
@NotUpdate
private String loanSourceCode;
/**
* 渠道数据源名称
*/
private String loanSourceName;
}

View File

@ -34,6 +34,9 @@ public class LoanQueryRowRespDO implements Serializable {
private String commissionOrg;
private Date commissionDate;
private Long deptId;
private String deptName;
private Long assignAgentId;
private String assignAgentName;
private AssignmentStatusEnum assignStatus;

View File

@ -7,7 +7,7 @@ import lombok.experimental.FieldNameConstants;
import com.pudonghot.tigon.dal.model.BaseDbEntity;
import com.pudonghot.tigon.mybatis.UseGeneratedKeys;
import com.pudonghot.tigon.mybatis.NotUpdateWhenNull;
import com.pudonghot.yo.operation.enumeration.customer.GenderEnum;
import com.pudonghot.tigon.cms.common.enumeration.GenderEnum;
/**
* 站点调解员

View File

@ -0,0 +1,31 @@
package com.pudonghot.yo.operation.dal.assignment;
import com.pudonghot.yo.operation.dal.TestBase;
import com.pudonghot.yo.operation.dal.assignment.request.AssignReqDO;
import com.pudonghot.yo.operation.dal.loan.LoanDal;
import com.pudonghot.yo.operation.dal.loan.mapper.LoanMapper;
import com.pudonghot.yo.operation.dal.loan.request.LoanQueryReqDO;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
/**
* @author Donghuang
* @date Oct 01, 2024 11:25:34
*/
@Slf4j
public class AssignmentDalTest extends TestBase {
@Autowired
private AssignmentDal dal;
@Test
public void testAssign() {
val assignReqDO = new AssignReqDO();
assignReqDO.setLoanId(1L);
assignReqDO.setAgentId(1L);
dal.assign(Arrays.asList(assignReqDO));
}
}

View File

@ -0,0 +1,28 @@
package com.pudonghot.yo.operation.dal.auth;
import com.pudonghot.tigon.dal.hook.AuthHook;
import org.springframework.stereotype.Component;
/**
* @author Donghuang
* @date Oct 23, 2024 11:49:23
*/
@Component
public class AuthHookMock extends AuthHook<Long> {
/**
* {@inheritDoc}
*/
@Override
public Long doGetMemberId() {
return 1L;
}
/**
* {@inheritDoc}
*/
@Override
public Long doGetTenantId() {
return 1L;
}
}

View File

@ -0,0 +1,23 @@
package com.pudonghot.yo.operation.dal.interaction;
import lombok.val;
import org.junit.Test;
import lombok.extern.slf4j.Slf4j;
import com.pudonghot.yo.operation.dal.TestBase;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author Donghuang
* @date Oct 01, 2024 11:25:34
*/
@Slf4j
public class InteractionDalTest extends TestBase {
@Autowired
private InteractionDal dal;
@Test
public void testAgents() {
val agents = dal.agents(2L);
log.info("Agents: [{}].", agents);
}
}

View File

@ -43,9 +43,9 @@ public class LoanDalTest extends TestBase {
// req.setColors(Arrays.asList("#F00"));
// req.setMobiles(Arrays.asList("13764268888"));
// req.setNames(Arrays.asList("东煌"));
req.setHasAssigned(true);
req.setBatchNumber("20230909_004");
req.setConclusions(Arrays.asList(ConclusionEnum.UNCONNECTED));
// req.setHasAssigned(true);
// req.setBatchNumber("20230909_004");
// req.setConclusions(Arrays.asList(ConclusionEnum.UNCONNECTED));
val list = loanMapper.query(req);
log.info("List: [{}].", list);
}

View File

@ -1,5 +1,6 @@
mybatis:
mapper-locations:
- classpath*:com/pudonghot/tigon/cms/dal/*/mapper/*Mapper.xml
- classpath*:com/pudonghot/yo/dal/*/mapper/*Mapper.xml
- classpath*:com/pudonghot/yo/operation/dal/*/mapper/*Mapper.xml
lazy-initialization: false
@ -24,4 +25,4 @@ tigon:
mybatis:
# quotation-mark: "`"
cms:
table-prefix: br_
table-prefix: tj

View File

@ -1,9 +1,11 @@
package com.pudonghot.yo.operation.service.assignment;
import com.pudonghot.tigon.service.TigonService;
import com.pudonghot.yo.operation.service.assignment.model.AssignmentBO;
import com.pudonghot.yo.operation.service.assignment.request.AssignmentCreateReqBO;
import com.pudonghot.yo.operation.service.assignment.request.AssignmentImportReqBO;
import com.pudonghot.yo.operation.service.assignment.request.AssignmentUpdateReqBO;
import com.pudonghot.tigon.service.TigonService;
import com.pudonghot.yo.operation.service.assignment.response.AssignmentImportRespBO;
/**
* 催收案件分单记录表
@ -16,4 +18,12 @@ public interface AssignmentService
AssignmentBO,
AssignmentCreateReqBO,
AssignmentUpdateReqBO> {
/**
* assignment import
*
* @param req req
* @return resp
*/
AssignmentImportRespBO assignmentImport(AssignmentImportReqBO req);
}

View File

@ -1,13 +1,32 @@
package com.pudonghot.yo.operation.service.assignment.impl;
import lombok.val;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.excel.EasyExcel;
import java.util.stream.Collectors;
import com.pudonghot.yo.util.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.pudonghot.tigon.cms.dal.dict.DictDal;
import com.pudonghot.tigon.file.util.StreamUtils;
import com.alibaba.excel.context.AnalysisContext;
import com.pudonghot.yo.operation.dal.loan.LoanDal;
import com.alibaba.excel.read.listener.ReadListener;
import com.pudonghot.tigon.cms.dal.member.MemberDal;
import com.pudonghot.tigon.cms.dal.member.model.MemberDO;
import com.pudonghot.tigon.service.impl.TigonServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Autowired;
import com.pudonghot.yo.operation.dal.assignment.AssignmentDal;
import com.pudonghot.yo.operation.dal.assignment.model.AssignmentDO;
import com.pudonghot.yo.operation.dal.assignment.request.AssignReqDO;
import com.pudonghot.yo.operation.service.assignment.AssignmentService;
import com.pudonghot.yo.operation.service.assignment.model.AssignmentBO;
import com.pudonghot.yo.operation.service.assignment.impl.reader.ReadContext;
import com.pudonghot.yo.operation.service.assignment.request.AssignmentCreateReqBO;
import com.pudonghot.yo.operation.service.assignment.request.AssignmentUpdateReqBO;
import com.pudonghot.yo.operation.service.assignment.request.AssignmentImportReqBO;
import com.pudonghot.yo.operation.service.assignment.response.AssignmentImportRespBO;
/**
* 催收案件分单记录表
@ -15,6 +34,7 @@ import com.pudonghot.yo.operation.service.assignment.request.AssignmentUpdateReq
* @author Donghuang
* @date Oct 15, 2024 15:49:03
*/
@Slf4j
@Service
public class AssignmentServiceImpl
extends TigonServiceImpl<Long,
@ -24,4 +44,109 @@ public class AssignmentServiceImpl
AssignmentDO,
AssignmentDal>
implements AssignmentService {
@Value("${yo.tj.loan-source.category-code}")
private String loanSourceCategory;
@Autowired
private LoanDal loanDal;
@Autowired
private DictDal dictDal;
@Autowired
private MemberDal memberDal;
/**
* {@inheritDoc}
*/
@Override
public AssignmentImportRespBO assignmentImport(final AssignmentImportReqBO req) {
val resp = new AssignmentImportRespBO();
StreamUtils.openStream(req.getFile(), inputStream -> {
val readContext = new ReadContext();
EasyExcel.read(inputStream, AssignmentImportReqBO.ImportExcelModel.class, new ReadListener<AssignmentImportReqBO.ImportExcelModel>() {
/**
* {@inheritDoc}
*/
@Override
public void invoke(final AssignmentImportReqBO.ImportExcelModel record,
final AnalysisContext context) {
val bizKey = record.getBizKey();
if (StringUtils.isNotBlank(bizKey)) {
val rec = new ReadContext.Record(bizKey);
val loanSource = record.getLoanSource();
if (StringUtils.isNotBlank(loanSource)) {
val loanSourceDO = dictDal.findByValue(loanSourceCategory, 0L, loanSource);
if (loanSourceDO == null) {
readContext.addError("案件来源[" + loanSource + "]不存在");
}
else {
if (loanSourceDO != null) {
val loan = loanDal.findBySourceIdAndBizKey(loanSourceDO.getId(), bizKey);
if (loan != null) {
rec.setLoan(loan);
}
else {
readContext.addError("案件[" + bizKey + "]不存在");
}
}
}
}
else {
readContext.addError("案件来源不能为空");
}
val mediatorKey = record.getMediator();
if (StringUtils.isNotBlank(mediatorKey)) {
val mediator = findMediator(mediatorKey);
if (mediator != null) {
rec.setMediator(mediator);
readContext.addRecord(rec);
}
else {
readContext.addError("调解员[" + mediatorKey + "]不存在");
}
}
else {
readContext.addError("调解员不能为空");
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void doAfterAllAnalysed(final AnalysisContext context) {
if (readContext.hasError()) {
resp.setErrors(readContext.getErrors());
return;
}
val records = readContext.getRecords();
val rows = new int[] { 0 };
ListUtils.eachBatch(records.values(), 20, recs -> {
dal.checkOut(recs.stream().map(rec -> rec.getLoan().getId()).collect(Collectors.toList()));
rows[0] +=
dal.assign(recs.stream().map(
rec -> new AssignReqDO(rec.getLoan().getId(),
rec.getMediator().getId()))
.collect(Collectors.toSet()));
});
resp.setTotal(rows[0]);
}
}).customObject(readContext).sheet(0).doRead();
});
return resp;
}
MemberDO findMediator(final String mediator) {
val rec = memberDal.findByAccount(mediator);
return rec != null ? rec : memberDal.findByName(mediator);
}
}

View File

@ -0,0 +1,59 @@
package com.pudonghot.yo.operation.service.assignment.impl.reader;
import lombok.Getter;
import lombok.Setter;
import java.util.Map;
import java.util.List;
import lombok.ToString;
import java.util.HashMap;
import java.util.ArrayList;
import java.io.Serializable;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
import com.pudonghot.yo.operation.dal.loan.model.LoanDO;
import com.pudonghot.tigon.cms.dal.member.model.MemberDO;
/**
* @author Donghuang
* @date Sep 27, 2024 20:51:56
*/
@Getter
@Setter
@ToString
public class ReadContext implements Serializable {
private static final long serialVersionUID = 1L;
private final List<String> errors = new ArrayList<>();
private Integer total;
private Map<Integer, String> appExtHeaders;
private final Map<String, Record> records = new HashMap<>();
public boolean hasError() {
return !errors.isEmpty();
}
public void addError(final String error) {
errors.add(error);
}
public void addRecord(final Record record) {
records.putIfAbsent(record.getBizKey(), record);
}
public Record getRecord(final String bizKey) {
return records.get(bizKey);
}
@Getter
@Setter
@ToString
@RequiredArgsConstructor
@EqualsAndHashCode(of = "bizKey")
public static class Record implements Serializable {
private static final long serialVersionUID = 1L;
private final String bizKey;
private LoanDO loan;
private MemberDO mediator;
}
}

View File

@ -0,0 +1,39 @@
package com.pudonghot.yo.operation.service.assignment.request;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import com.alibaba.excel.annotation.ExcelProperty;
import org.springframework.web.multipart.MultipartFile;
import com.pudonghot.tigon.kit.bean.annotation.ShallowField;
/**
* @author Donghuang
* @date Oct 23, 2024 16:12:37
*/
@Getter
@Setter
@ToString
public class AssignmentImportReqBO implements Serializable {
private static final long serialVersionUID = 1L;
@ShallowField
private MultipartFile file;
@Getter
@Setter
@ToString
public static class ImportExcelModel implements Serializable {
private static final long serialVersionUID = 1L;
@ExcelProperty("案件来源")
private String loanSource;
@ExcelProperty("合同号")
private String bizKey;
@ExcelProperty("分案调解员")
private String mediator;
}
}

View File

@ -0,0 +1,22 @@
package com.pudonghot.yo.operation.service.assignment.response;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.List;
import java.util.ArrayList;
import java.io.Serializable;
/**
* @author Donghuang
* @date Oct 23, 2024 16:12:31
*/
@Getter
@Setter
@ToString
public class AssignmentImportRespBO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer total = 0;
private List<String> errors = new ArrayList<>();
}

View File

@ -1,5 +1,6 @@
package com.pudonghot.yo.operation.service.home.impl;
import com.pudonghot.yo.operation.service.loan.DeptService;
import lombok.val;
import java.util.List;
import com.pudonghot.yo.dal.agent.AgentDal;
@ -34,7 +35,7 @@ public class HomeServiceImpl implements HomeService {
@Autowired
private SmsTemplateDal smsTemplateDal;
@Autowired
private DeptDal deptDal;
private DeptService deptService;
@Value("${yo.webrtc.endpoint}")
private String webRtcEndpoint;
@ -74,7 +75,7 @@ public class HomeServiceImpl implements HomeService {
*/
@Override
public List<DeptListRespBO> deptList() {
return beanService.convert(deptDal.listTop(), DeptListRespBO.class);
return beanService.convert(deptService.list(), DeptListRespBO.class);
}
/**

View File

@ -0,0 +1,30 @@
package com.pudonghot.yo.operation.service.interaction;
import com.pudonghot.tigon.service.TigonService;
import com.pudonghot.yo.operation.service.interaction.model.InteractionBO;
import com.pudonghot.yo.operation.service.interaction.request.InteractionCreateReqBO;
import com.pudonghot.yo.operation.service.interaction.request.InteractionUpdateReqBO;
import com.pudonghot.yo.operation.service.interaction.response.InteractionAgentBO;
import java.util.List;
/**
* 催收记录表
*
* @author Donghuang
* @date Oct 23, 2024 11:16:16
*/
public interface InteractionService
extends TigonService<Long,
InteractionBO,
InteractionCreateReqBO,
InteractionUpdateReqBO> {
/**
* loan interaction agents
*
* @param loanId loan id
* @return agents
*/
List<InteractionAgentBO> agents(Long loanId);
}

View File

@ -0,0 +1,72 @@
package com.pudonghot.yo.operation.service.interaction.impl;
import lombok.val;
import java.util.Date;
import java.util.List;
import org.springframework.util.Assert;
import com.pudonghot.tigon.dal.hook.AuthHook;
import org.springframework.stereotype.Service;
import com.pudonghot.yo.operation.dal.loan.LoanDal;
import com.pudonghot.tigon.service.impl.TigonServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import com.pudonghot.yo.operation.dal.interaction.InteractionDal;
import com.pudonghot.yo.operation.dal.interaction.model.InteractionDO;
import com.pudonghot.yo.operation.service.interaction.InteractionService;
import com.pudonghot.yo.operation.service.interaction.model.InteractionBO;
import com.pudonghot.yo.operation.enumeration.interaction.HandelCategoryEnum;
import com.pudonghot.yo.operation.service.interaction.response.InteractionAgentBO;
import com.pudonghot.yo.operation.service.interaction.request.InteractionCreateReqBO;
import com.pudonghot.yo.operation.service.interaction.request.InteractionUpdateReqBO;
/**
* 催收记录表
*
* @author Donghuang
* @date Oct 23, 2024 11:16:16
*/
@Service
public class InteractionServiceImpl
extends TigonServiceImpl<Long,
InteractionBO,
InteractionCreateReqBO,
InteractionUpdateReqBO,
InteractionDO,
InteractionDal>
implements InteractionService {
@Autowired
private LoanDal loanDal;
@Autowired
private AuthHook<Long> authHook;
/**
* {@inheritDoc}
*/
@Override
public List<InteractionAgentBO> agents(final Long loanId) {
return beanService.convert(dal.agents(loanId), InteractionAgentBO.class);
}
/**
* {@inheritDoc}
*/
@Override
protected void validateCreate(final InteractionCreateReqBO req) {
super.validateCreate(req);
val loanId = req.getLoanId();
val loan = loanDal.find(loanId);
Assert.state(loan != null, () -> "No loan [" + loanId + "] found");
}
/**
* {@inheritDoc}
*/
@Override
protected void beforeCreate(final InteractionCreateReqBO req, final InteractionDO model) {
super.beforeCreate(req, model);
model.setAgentId(authHook.getMemberId());
model.setDueDate(new Date());
model.setHandleCategory(HandelCategoryEnum.MANUAL);
}
}

View File

@ -0,0 +1,109 @@
package com.pudonghot.yo.operation.service.interaction.model;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.math.BigDecimal;
import com.pudonghot.tigon.service.model.ServModel;
import com.pudonghot.yo.operation.enumeration.interaction.ConclusionEnum;
import com.pudonghot.yo.operation.enumeration.interaction.InteractionTypeEnum;
/**
* 催收记录表
*
* @author Donghuang
* @date Oct 23, 2024 11:16:16
*/
@Getter
@Setter
public class InteractionBO extends ServModel {
private static final long serialVersionUID = 1L;
/**
* 催收案件ID
*/
private Long loanId;
/**
* 催收员ID
*/
private Long agentId;
/**
* 催收方式
*/
private InteractionTypeEnum type;
/**
* 结论
*/
private ConclusionEnum conclusion;
/**
* 催收日期
*/
private Date dueDate;
/**
* 下次跟进时间
*/
private Date recheckDate;
/**
* 操作类别:内部人工;内部自动
*/
private String handleCategory;
/**
* 是否有效联络: 有效;无效
*/
private String isCallValid;
/**
* 承诺还款日期
*/
private Date promisedPaymentDate;
/**
* 逾期原因
*/
private String overdueReason;
/**
* 本人手机号状态
*/
private String phoneStatus;
/**
* 短信表主键ID
*/
private Long smsId;
/**
* 催收操作结果
*/
private String result;
/**
* 承诺还款金额
*/
private BigDecimal promisedPaymentAmount;
/**
* 客户姓名
*/
private String name;
/**
* 客户手机
*/
private String phone;
/**
* contact表主键联系人
*/
private Long contactId;
private String relation;
}

View File

@ -0,0 +1,111 @@
package com.pudonghot.yo.operation.service.interaction.request;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.math.BigDecimal;
import com.pudonghot.tigon.service.request.BaseServReq;
import com.pudonghot.yo.operation.enumeration.interaction.ConclusionEnum;
import com.pudonghot.yo.operation.enumeration.interaction.InteractionTypeEnum;
/**
* 催收记录表
*
* @author Donghuang
* @date Oct 23, 2024 11:16:16
*/
@Getter
@Setter
public class InteractionCreateReqBO extends BaseServReq {
private static final long serialVersionUID = 1L;
/**
* 催收案件ID
*/
private Long loanId;
/**
* 催收员ID
*/
private Long agentId;
/**
* 催收方式
*/
private InteractionTypeEnum type;
/**
* 结论
*/
private ConclusionEnum conclusion;
/**
* 催收日期
*/
private Date dueDate;
/**
* 下次跟进时间
*/
private Date recheckDate;
/**
* 操作类别:内部人工;内部自动
*/
private String handleCategory;
/**
* 是否有效联络: 有效;无效
*/
private String isCallValid;
/**
* 承诺还款日期
*/
private Date promisedPaymentDate;
/**
* 逾期原因
*/
private String overdueReason;
/**
* 本人手机号状态
*/
private String phoneStatus;
/**
* 短信表主键ID
*/
private Long smsId;
/**
* 催收操作结果
*/
private String result;
/**
* 承诺还款金额
*/
private BigDecimal promisedPaymentAmount;
/**
* 客户姓名
*/
private String name;
/**
* 客户手机
*/
private String phone;
/**
* contact表主键联系人
*/
private Long contactId;
/**
* 关系
*/
private String relation;
}

View File

@ -0,0 +1,106 @@
package com.pudonghot.yo.operation.service.interaction.request;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.math.BigDecimal;
import com.pudonghot.tigon.service.request.UpdateServReq;
/**
* 催收记录表
*
* @author Donghuang
* @date Oct 23, 2024 11:16:16
*/
@Getter
@Setter
public class InteractionUpdateReqBO extends UpdateServReq<Long> {
private static final long serialVersionUID = 1L;
/**
* 催收案件ID
*/
private Long loanId;
/**
* 催收方式
*/
private String type;
/**
* 结论
*/
private String conclusion;
/**
* 催收日期
*/
private Date dueDate;
/**
* 下次跟进时间
*/
private Date recheckDate;
/**
* 操作类别:内部人工;内部自动
*/
private String handleCategory;
/**
* 是否有效联络: 有效;无效
*/
private String isCallValid;
/**
* 承诺还款日期
*/
private Date promisedPaymentDate;
/**
* 逾期原因
*/
private String overdueReason;
/**
* 本人手机号状态
*/
private String phoneStatus;
/**
* 短信表主键ID
*/
private Long smsId;
/**
* 催收操作结果
*/
private String result;
/**
* 承诺还款金额
*/
private BigDecimal promisedPaymentAmount;
/**
* 客户姓名
*/
private String name;
/**
* 客户手机
*/
private String phone;
/**
* contact表主键联系人
*/
private Long contactId;
private String relation;
/**
* 催收员ID
*/
private Long agentId;
}

View File

@ -0,0 +1,20 @@
package com.pudonghot.yo.operation.service.interaction.response;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
/**
* @author Donghuang
* @date Oct 23, 2024 11:26:08
*/
@Getter
@Setter
@ToString
public class InteractionAgentBO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
}

View File

@ -1,9 +1,8 @@
package com.pudonghot.yo.operation.service.loanimport;
package com.pudonghot.yo.operation.service.loan;
import com.pudonghot.yo.operation.service.loanimport.model.DeptBO;
import java.util.Collection;
import java.util.List;
import java.util.Collection;
import com.pudonghot.yo.operation.service.loan.model.DeptBO;
/**
* @author Donghuang
@ -26,6 +25,13 @@ public interface DeptService {
*/
DeptBO find(String name);
/**
* list depts
*
* @return depts
*/
List<DeptBO> list();
/**
* depts
*

View File

@ -2,11 +2,12 @@ package com.pudonghot.yo.operation.service.loan;
import com.pudonghot.tigon.service.TigonService;
import com.pudonghot.yo.operation.service.loan.model.LoanBO;
import com.pudonghot.yo.operation.service.loan.request.LoanCreateReqBO;
import com.pudonghot.yo.operation.service.loan.request.LoanQueryReqBO;
import com.pudonghot.yo.operation.service.loan.request.LoanCreateReqBO;
import com.pudonghot.yo.operation.service.loan.request.LoanUpdateReqBO;
import com.pudonghot.yo.operation.service.loan.request.LoanBatchUpdateFieldReqBO;
import com.pudonghot.yo.operation.service.loan.response.LoanQueryRespBO;
import com.pudonghot.yo.operation.service.loan.response.LoanDetailRespBO;
import com.pudonghot.yo.operation.service.loan.request.LoanBatchUpdateFieldReqBO;
/**
* 信贷案件表
@ -35,4 +36,12 @@ public interface LoanService
* @return resp
*/
LoanQueryRespBO query(LoanQueryReqBO req);
/**
* loan detail
*
* @param loanId loan id
* @return loan detail
*/
LoanDetailRespBO detail(Long loanId);
}

View File

@ -1,19 +1,42 @@
package com.pudonghot.yo.operation.service.loan;
import java.util.List;
import java.util.Collection;
import com.pudonghot.yo.operation.service.loan.model.LoanSourceBO;
import com.pudonghot.yo.operation.service.loan.request.LoanSourceCreateReqBO;
import com.pudonghot.yo.operation.service.loan.request.LoanSourceUpdateReqBO;
import com.pudonghot.tigon.service.TigonService;
/**
* 案件来源表
*
* @author Donghuang
* @date Oct 15, 2024 15:57:07
* @date Oct 01, 2024 20:00:10
*/
public interface LoanSourceService
extends TigonService<Long,
LoanSourceBO,
LoanSourceCreateReqBO,
LoanSourceUpdateReqBO> {
public interface LoanSourceService {
/**
* find default loan source
*
* @return loan source
*/
LoanSourceBO findDefault();
/**
* find loan source
*
* @param name name
* @return loan source
*/
LoanSourceBO find(String name);
/**
* list loan sources
*
* @return loan sources
*/
List<LoanSourceBO> list();
/**
* list loan source
*
* @param names names
* @return loan sources
*/
List<LoanSourceBO> list(Collection<String> names);
}

View File

@ -0,0 +1,67 @@
package com.pudonghot.yo.operation.service.loan.impl;
import lombok.val;
import java.util.List;
import java.util.Collection;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import com.pudonghot.tigon.kit.bean.BeanService;
import com.pudonghot.tigon.cms.dal.dict.DictDal;
import org.springframework.beans.factory.annotation.Value;
import com.pudonghot.yo.operation.service.loan.DeptService;
import com.pudonghot.yo.operation.service.loan.model.DeptBO;
import org.springframework.beans.factory.annotation.Autowired;
import com.pudonghot.tigon.cms.dal.dict.request.DictListOfCategoryReqDO;
import com.pudonghot.tigon.cms.common.enumeration.dict.DictBasicCategoryEnum;
/**
* @author Donghuang
* @date Oct 09, 2024 15:58:37
*/
@Service("deptImportServiceImpl")
public class DeptServiceImpl implements DeptService {
@Autowired
private DictDal deptDal;
@Autowired
private BeanService beanService;
@Value("${yo.dept.default:创易广州分公司}")
private String defaultDept;
/**
* {@inheritDoc}
*/
@Override
public DeptBO findDefault() {
return find(defaultDept);
}
/**
* {@inheritDoc}
*/
@Override
public DeptBO find(final String name) {
return beanService.convert(deptDal.findByValue(DictBasicCategoryEnum.DEPT.name(), 0L, name), DeptBO.class);
}
/**
* {@inheritDoc}
*/
@Override
public List<DeptBO> list() {
val category = deptDal.findCategoryByCode(DictBasicCategoryEnum.DEPT.name());
val req = new DictListOfCategoryReqDO();
req.setCategoryId(category.getId());
req.setParentId(0L);
return beanService.convert(deptDal.listAllByCategoryId(req), DeptBO.class);
}
/**
* {@inheritDoc}
*/
@Override
public List<DeptBO> list(final Collection<String> names) {
return list().stream().filter(it -> names.contains(it.getName())).collect(Collectors.toList());
}
}

View File

@ -1,16 +1,30 @@
package com.pudonghot.yo.operation.service.loan.impl;
import lombok.val;
import java.util.Arrays;
import java.util.Objects;
import java.util.Collections;
import java.util.stream.Collectors;
import org.springframework.util.Assert;
import org.springframework.stereotype.Service;
import com.pudonghot.tigon.cms.dal.dict.DictDal;
import com.pudonghot.yo.operation.dal.loan.LoanDal;
import com.pudonghot.yo.operation.dal.loan.BankCardDal;
import com.pudonghot.yo.operation.dal.loan.CustomerDal;
import com.pudonghot.yo.operation.dal.loan.model.LoanDO;
import com.pudonghot.yo.operation.dal.loan.RepaymentDal;
import com.pudonghot.tigon.service.impl.TigonServiceImpl;
import com.pudonghot.yo.operation.service.loan.LoanService;
import com.pudonghot.yo.operation.service.loan.model.LoanBO;
import org.springframework.beans.factory.annotation.Autowired;
import com.pudonghot.yo.operation.dal.application.ApplicationDal;
import com.pudonghot.yo.operation.dal.loan.request.LoanQueryReqDO;
import com.pudonghot.yo.operation.dal.application.ApplicationExtDal;
import com.pudonghot.yo.operation.service.loan.request.LoanQueryReqBO;
import com.pudonghot.yo.operation.service.loan.request.LoanCreateReqBO;
import com.pudonghot.yo.operation.service.loan.request.LoanUpdateReqBO;
import com.pudonghot.yo.operation.service.loan.response.LoanQueryRespBO;
import com.pudonghot.yo.operation.service.loan.response.LoanDetailRespBO;
import com.pudonghot.yo.operation.service.loan.request.LoanBatchUpdateFieldReqBO;
/**
@ -29,6 +43,19 @@ public class LoanServiceImpl
LoanDal>
implements LoanService {
@Autowired
private DictDal loanSourceDal;
@Autowired
private ApplicationDal applicationDal;
@Autowired
private ApplicationExtDal applicationExtDal;
@Autowired
private CustomerDal customerDal;
@Autowired
private BankCardDal bankCardDal;
@Autowired
private RepaymentDal repaymentDal;
/**
* {@inheritDoc}
*/
@ -44,4 +71,57 @@ public class LoanServiceImpl
public LoanQueryRespBO query(final LoanQueryReqBO req) {
return beanService.convert(dal.query(beanService.convert(req, LoanQueryReqDO.class)), LoanQueryRespBO.class);
}
/**
* {@inheritDoc}
*/
@Override
public LoanDetailRespBO detail(final Long loanId) {
val loan = dal.find(loanId);
Assert.state(loan != null, () -> "No loan [" + loanId + "] found");
val resp = new LoanDetailRespBO();
resp.setLoan(beanService.convert(loan, LoanDetailRespBO.LoanBO.class));
val loanSourceId = loan.getLoanSourceId();
resp.setLoanSource(beanService.convert(loanSourceDal.find(loanSourceId), LoanDetailRespBO.LoanSourceBO.class));
val application = applicationDal.findByLoanId(loanId);
Assert.state(application != null, () -> "No application of loan [" + loanId + "] found");
val applicationBO = beanService.convert(application, LoanDetailRespBO.ApplicationBO.class);
val appExt = applicationExtDal.findByLoanId(loanId);
if (appExt != null) {
val extFields = beanService.convert(
Arrays.asList(
appExt.getExtData1(),
appExt.getExtData2(),
appExt.getExtData3(),
appExt.getExtData4(),
appExt.getExtData5(),
appExt.getExtData6(),
appExt.getExtData7(),
appExt.getExtData8(),
appExt.getExtData9(),
appExt.getExtData10()
).stream().filter(Objects::nonNull).collect(Collectors.toList()),
LoanDetailRespBO.ApplicationBO.ExtFieldBO.class
);
applicationBO.setExtFields(extFields);
}
else {
applicationBO.setExtFields(Collections.emptyList());
}
resp.setApplication(applicationBO);
val customer = customerDal.findByLoanId(loanId);
Assert.state(customer != null, () -> "No customer of loan [" + loanId + "] found");
resp.setCustomer(beanService.convert(customer, LoanDetailRespBO.CustomerBO.class));
val bankCards = bankCardDal.listByLoanId(loanId);
resp.setBankCards(beanService.convert(bankCards, LoanDetailRespBO.BankCardBO.class));
val repayments = repaymentDal.listByLoanId(loanId);
resp.setRepayments(beanService.convert(repayments, LoanDetailRespBO.RepaymentBO.class));
return resp;
}
}

View File

@ -1,27 +1,67 @@
package com.pudonghot.yo.operation.service.loan.impl;
import com.pudonghot.yo.operation.dal.loan.LoanSourceDal;
import com.pudonghot.yo.operation.dal.loan.model.LoanSourceDO;
import lombok.val;
import java.util.List;
import java.util.Collection;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import com.pudonghot.tigon.service.impl.TigonServiceImpl;
import com.pudonghot.yo.operation.service.loan.model.LoanSourceBO;
import com.pudonghot.yo.operation.service.loan.request.LoanSourceCreateReqBO;
import com.pudonghot.yo.operation.service.loan.request.LoanSourceUpdateReqBO;
import com.pudonghot.tigon.kit.bean.BeanService;
import com.pudonghot.tigon.cms.dal.dict.DictDal;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Autowired;
import com.pudonghot.yo.operation.service.loan.LoanSourceService;
import com.pudonghot.tigon.cms.dal.dict.request.DictListOfCategoryReqDO;
import com.pudonghot.yo.operation.service.loan.model.LoanSourceBO;
/**
* 案件来源表
*
* @author Donghuang
* @date Oct 15, 2024 15:57:07
* @date Oct 09, 2024 12:11:33
*/
@Service
public class LoanSourceServiceImpl
extends TigonServiceImpl<Long,
LoanSourceBO,
LoanSourceCreateReqBO,
LoanSourceUpdateReqBO,
LoanSourceDO,
LoanSourceDal>
implements LoanSourceService {
@Service("loanSourceImportServiceImpl")
public class LoanSourceServiceImpl implements LoanSourceService {
@Autowired
private DictDal dictDal;
@Autowired
private BeanService beanService;
@Value("${yo.loan-source.category:LOAN_SOURCE}")
private String categoryCode;
@Value("${yo.loan-source.default:DEFAULT}")
private String defaultCode;
/**
* {@inheritDoc}
*/
@Override
public LoanSourceBO findDefault() {
val loanSource = dictDal.findByCode(categoryCode, defaultCode);
return beanService.convert(loanSource, LoanSourceBO.class);
}
/**
* {@inheritDoc}
*/
@Override
public LoanSourceBO find(final String name) {
return beanService.convert(dictDal.findByValue(categoryCode, 0L, name), LoanSourceBO.class);
}
/**
* {@inheritDoc}
*/
@Override
public List<LoanSourceBO> list() {
val category = dictDal.findCategoryByCode(categoryCode);
val req = new DictListOfCategoryReqDO();
req.setCategoryId(category.getId());
return beanService.convert(dictDal.listAllByCategoryId(req), LoanSourceBO.class);
}
/**
* {@inheritDoc}
*/
@Override
public List<LoanSourceBO> list(final Collection<String> names) {
return list().stream().filter(it -> names.contains(it.getName())).collect(Collectors.toList());
}
}

View File

@ -1,7 +1,8 @@
package com.pudonghot.yo.operation.service.loanimport.model;
package com.pudonghot.yo.operation.service.loan.model;
import lombok.Getter;
import lombok.Setter;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.pudonghot.tigon.service.model.BaseServModel;
/**
@ -18,5 +19,6 @@ public class DeptBO extends BaseServModel {
/**
* 部门名称
*/
@JsonAlias("value")
private String name;
}

View File

@ -2,26 +2,28 @@ package com.pudonghot.yo.operation.service.loan.model;
import lombok.Getter;
import lombok.Setter;
import com.pudonghot.tigon.service.model.ServModel;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.pudonghot.tigon.service.model.BaseServModel;
/**
* 案件来源表
*
* @author Donghuang
* @date Oct 15, 2024 15:57:07
* @date Oct 09, 2024 12:09:08
*/
@Getter
@Setter
public class LoanSourceBO extends ServModel {
public class LoanSourceBO extends BaseServModel {
private static final long serialVersionUID = 1L;
/**
* 渠道数据源代码
*/
private String loanSourceCode;
private String code;
/**
* 渠道数据源名称
*/
private String loanSourceName;
@JsonAlias({"value"})
private String name;
}

View File

@ -0,0 +1,628 @@
package com.pudonghot.yo.operation.service.loan.response;
import com.fasterxml.jackson.annotation.JsonAlias;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.util.List;
import lombok.ToString;
import java.io.Serializable;
import java.math.BigDecimal;
import com.pudonghot.tigon.cms.common.enumeration.GenderEnum;
import com.pudonghot.yo.operation.enumeration.repayment.RepaymentStatusEnum;
/**
* 借款详情
*
* @author Donghuang
* @date Oct 23, 2024 10:07:37
*/
@Getter
@Setter
@ToString
public class LoanDetailRespBO implements Serializable {
private static final long serialVersionUID = 1L;
private LoanSourceBO loanSource;
private ApplicationBO application;
private LoanBO loan;
private CustomerBO customer;
private List<BankCardBO> bankCards;
private List<ContactBO> contacts;
private List<RepaymentBO> repayments;
/**
* 信贷案件表
*
* @author Donghuang
* @date Oct 15, 2024 15:59:16
*/
@Getter
@Setter
public static class LoanBO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 导入时间
*/
private Date importTime;
/**
* 导入批次ID
*/
private Long importBatchId;
/**
* 案件来源ID
*/
private Long loanSourceId;
/**
* 外部合同号
*/
private String contractNumber;
/**
* 逾期天数
*/
private Integer overdueDays;
/**
* 应还总金额单位
*/
private Long overdueAmount;
/**
* 应还本金单位
*/
private Long principalAmount;
/**
* 应还利息单位
*/
private Long interestAmount;
/**
* 应还服务费单位
*/
private Long serviceAmount;
/**
* 应还罚息单位
*/
private Long penaltyAmount;
/**
* 还款状态
*/
private RepaymentStatusEnum repaymentStatus;
/**
* 颜色
*/
private String color;
/**
* 调解函地址
*/
private String mediateFile;
/**
* 调解结果
*/
private String mediateResult;
}
/**
* 还款计划表
*
* @author Donghuang
* @date Oct 23, 2024 10:16:17
*/
@Getter
@Setter
@ToString
public static class RepaymentBO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 期数
*/
private int installment;
/**
* 还款状态 UNPAID未还款 PARTIALLY_PAID 部分还款 FULLY_PAID全部还款
*/
private RepaymentStatusEnum status;
/**
* 计划还款时间
*/
private Date expectRepayTime;
/**
* 实际还款时间
*/
private Date actualRepayTime;
/**
* 应还本金单位
*/
private Long expectPrincipalAmount;
/**
* 已还本金单位
*/
private Long actualPrincipalAmount;
/**
* 应还利息单位
*/
private Long expectInterestAmount;
/**
* 已还利息单位
*/
private Long actualInterestAmount;
/**
* 应还平台服务费单位
*/
private Long expectServiceAmount;
/**
* 已还平台服务费单位
*/
private Long actualServiceAmount;
/**
* 应还罚息,单位:
*/
private Long expectPenaltyAmount;
/**
* 已还罚息,单位:
*/
private Long actualPenaltyAmount;
/**
* 减免金额
*/
private Long reductionAmount;
/**
* 减免原因
*/
private String reductionReason;
/**
* 应还总金额,单位:
*/
private Long expectTotalAmount;
/**
* 已还总金额,单位:
*/
private Long actualTotalAmount;
/**
* 逾期金额单位
*/
private Long overdueAmount;
}
/**
* @author Donghuang
* @date Oct 23, 2024 10:15:50
*/
@Getter
@Setter
@ToString
public static class LoanSourceBO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 渠道数据源代码
*/
private String code;
/**
* 渠道数据源名称
*/
@JsonAlias("value")
private String name;
}
/**
* 客户
*
* @author Donghuang
* @date Oct 01, 2024 14:20:47
*/
@Getter
@Setter
@ToString
public static class CustomerBO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 姓名
*/
private String name;
/**
* 身份证号
*/
private String idNo;
/**
* 手机
*/
private String mobile;
/**
* 邮箱
*/
private String email;
/**
* 性别
*/
private GenderEnum gender;
/**
* 民族
*/
private String nation;
/**
* 出生日期
*/
private Date birthday;
/**
* 户籍地址
*/
private String censusRegisterAddress;
/**
* 学历
*/
private String educational;
/**
* 婚姻状态
*/
private String marriage;
/**
* 居住省
*/
private String residenceProvince;
/**
* 居住市
*/
private String residenceCity;
/**
* 居住区
*/
private String residenceDistrict;
/**
* 常住地址
*/
private String residenceAddress;
/**
* 居住时长
*/
private String residenceTime;
/**
* qq
*/
private String qq;
/**
* 职业
*/
private String profession;
/**
* 月收入
*/
private String salary;
/**
* 单位名称
*/
private String workCompany;
/**
* 最近工作年限
*/
private String recentlyWorkDuration;
/**
* 单位所在省
*/
private String companyProvince;
/**
* 单位所在市
*/
private String companyCity;
/**
* 单位所在区
*/
private String companyDistrict;
/**
* 单位详细地址
*/
private String companyAddress;
}
/**
* 客户联系人
*
* @author Donghuang
* @date Oct 23, 2024 10:12:50
*/
@Getter
@Setter
@ToString
public static class ContactBO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 姓名
*/
private String name;
/**
* 手机
*/
private String mobile;
/**
* 关系
*/
private String relationType;
/**
* 联系频率
*/
private String frequency;
/**
* 联系人来源
*/
private String source;
}
/**
* 银行卡
*
* @author Donghuang
* @date Oct 23, 2024 10:13:28
*/
@Getter
@Setter
@ToString
public static class BankCardBO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 开户名
*/
private String name;
/**
* 银行预留手机号
*/
private String mobile;
/**
* 银行ID
*/
private Long bankId;
/**
* 银行卡卡号
*/
private String bankCardNo;
/**
* 银行卡开户行
*/
private String bankName;
/**
* 绑定优先级
*/
private Boolean priority;
}
/**
* 申请单
*
* @author Donghuang
* @date Oct 23, 2024 10:26:32
*/
@Getter
@Setter
@ToString
public static class ApplicationBO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 总期数
*/
private Integer totalInstallments;
/**
* 当前期数
*/
private Integer currentInstallment;
/**
* 已还期数
*/
private Integer repaidInstallments;
/**
* 逾期期数
*/
private Integer overdueInstallments;
/**
* 申请时间
*/
private Date applyDate;
/**
* 批核时间
*/
private Date approveDate;
/**
* 放款时间
*/
private Date loanDate;
/**
* 当期账单日
*/
private Date dueDate;
/**
* 利率
*/
private BigDecimal interestRate;
/**
* 服务费率
*/
private BigDecimal serviceInterestRate;
/**
* 罚息利率
*/
private BigDecimal penaltyInterestRate;
/**
* 合同(申请)金额
*/
private Long applyAmount;
/**
* 放款金额
*/
private Long loanAmount;
/**
* 违约金,罚金
*/
private Long defaultFineAmount;
/**
* 逾期金额
*/
private Long overdueAmount;
/**
* 剩余本金
*/
private Long principalRemain;
/**
* 提前清贷金额
*/
private Long prepaymentAmount;
/**
* 募资方
*/
private String fundraiser;
/**
* 产品名称
*/
private String productName;
/**
* 还款方式
*/
private String repaymentType;
/**
* 贷款平台名称
*/
private String platformName;
/**
* 募资方名称
*/
private String fundraiserName;
/**
* 助贷机构名称
*/
private String loanAgencyName;
/**
* 紧急联系人关系
*/
private String emergencyContactRelation;
/**
* 紧急联系人备注名
*/
private String emergencyContactName;
/**
* 紧急联系人号码
*/
private String emergencyContactMobile;
private List<ExtFieldBO> extFields;
@Getter
@Setter
@ToString
public static class ExtFieldBO implements Serializable {
private static final long serialVersionUID = 1L;
private String label;
private String value;
}
}
}

View File

@ -35,6 +35,9 @@ public class LoanQueryRowRespBO implements Serializable {
private String commissionOrg;
private Date commissionDate;
private Long deptId;
private String deptName;
private Long assignAgentId;
private String assignAgentName;
private AssignmentStatusEnum assignStatus;

View File

@ -1,36 +0,0 @@
package com.pudonghot.yo.operation.service.loanimport;
import com.pudonghot.yo.operation.service.loanimport.model.LoanSourceBO;
import java.util.Collection;
import java.util.List;
/**
* @author Donghuang
* @date Oct 01, 2024 20:00:10
*/
public interface LoanSourceService {
/**
* find default loan source
*
* @return loan source
*/
LoanSourceBO findDefault();
/**
* find loan source
*
* @param name name
* @return loan source
*/
LoanSourceBO find(String name);
/**
* list loan source
*
* @param names names
* @return loan sources
*/
List<LoanSourceBO> list(Collection<String> names);
}

View File

@ -3,7 +3,7 @@ package com.pudonghot.yo.operation.service.loanimport.annotation;
import java.io.IOException;
import com.pudonghot.tigon.kit.spring.ApplicationContextProvider;
import com.pudonghot.yo.operation.service.loanimport.DeptService;
import com.pudonghot.yo.operation.service.loan.DeptService;
import jakarta.validation.Payload;
import java.lang.annotation.Target;
import jakarta.validation.Constraint;

View File

@ -18,7 +18,7 @@ import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.pudonghot.tigon.kit.spring.ApplicationContextProvider;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.pudonghot.yo.operation.service.loanimport.LoanSourceService;
import com.pudonghot.yo.operation.service.loan.LoanSourceService;
/**
* 案件来源

View File

@ -1,50 +0,0 @@
package com.pudonghot.yo.operation.service.loanimport.impl;
import java.util.List;
import java.util.Collection;
import org.springframework.stereotype.Service;
import com.pudonghot.tigon.kit.bean.BeanService;
import com.pudonghot.yo.operation.dal.dept.DeptDal;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Autowired;
import com.pudonghot.yo.operation.service.loanimport.DeptService;
import com.pudonghot.yo.operation.service.loanimport.model.DeptBO;
/**
* @author Donghuang
* @date Oct 09, 2024 15:58:37
*/
@Service("deptImportServiceImpl")
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptDal deptDal;
@Autowired
private BeanService beanService;
@Value("${yo.default-dept:创易广州分公司}")
private String defaultDept;
/**
* {@inheritDoc}
*/
@Override
public DeptBO findDefault() {
return beanService.convert(deptDal.findByName(defaultDept), DeptBO.class);
}
/**
* {@inheritDoc}
*/
@Override
public DeptBO find(final String name) {
return beanService.convert(deptDal.findByName(name), DeptBO.class);
}
/**
* {@inheritDoc}
*/
@Override
public List<DeptBO> list(Collection<String> names) {
return beanService.convert(deptDal.listByNames(names), DeptBO.class);
}
}

View File

@ -37,14 +37,14 @@ import com.pudonghot.yo.operation.dal.loanimport.BatchNumberDal;
import com.pudonghot.tigon.cms.service.seq.request.SeqGenReqBO;
import com.pudonghot.yo.operation.dal.application.ApplicationDal;
import com.pudonghot.tigon.cms.service.seq.response.SeqGenRespBO;
import com.pudonghot.yo.operation.service.loanimport.DeptService;
import com.pudonghot.yo.operation.service.loanimport.model.DeptBO;
import com.pudonghot.yo.operation.service.loan.DeptService;
import com.pudonghot.yo.operation.service.loan.model.DeptBO;
import com.pudonghot.yo.operation.dal.application.ApplicationExtDal;
import com.pudonghot.yo.operation.dal.loanimport.model.BatchNumberDO;
import com.pudonghot.yo.operation.dal.application.model.ApplicationDO;
import com.pudonghot.yo.operation.service.loanimport.LoanImportService;
import com.pudonghot.yo.operation.service.loanimport.LoanSourceService;
import com.pudonghot.yo.operation.service.loanimport.model.LoanSourceBO;
import com.pudonghot.yo.operation.service.loan.LoanSourceService;
import com.pudonghot.yo.operation.service.loan.model.LoanSourceBO;
import com.pudonghot.yo.operation.dal.application.model.ApplicationExtDO;
import com.pudonghot.yo.operation.service.loanimport.impl.reader.BaseReader;
import com.pudonghot.yo.operation.service.loanimport.request.LoanImportReqBO;

View File

@ -1,50 +0,0 @@
package com.pudonghot.yo.operation.service.loanimport.impl;
import java.util.List;
import java.util.Collection;
import org.springframework.stereotype.Service;
import com.pudonghot.tigon.kit.bean.BeanService;
import com.pudonghot.yo.operation.dal.loan.LoanSourceDal;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Autowired;
import com.pudonghot.yo.operation.service.loanimport.LoanSourceService;
import com.pudonghot.yo.operation.service.loanimport.model.LoanSourceBO;
/**
* @author Donghuang
* @date Oct 09, 2024 12:11:33
*/
@Service("loanSourceImportServiceImpl")
public class LoanSourceServiceImpl implements LoanSourceService {
@Autowired
private LoanSourceDal loanSourceDal;
@Autowired
private BeanService beanService;
@Value("${yo.default-loan-source:DEFAULT}")
private String defaultLoanSourceCode;
/**
* {@inheritDoc}
*/
@Override
public LoanSourceBO findDefault() {
return beanService.convert(loanSourceDal.findByCode(defaultLoanSourceCode), LoanSourceBO.class);
}
/**
* {@inheritDoc}
*/
@Override
public LoanSourceBO find(final String name) {
return beanService.convert(loanSourceDal.findByName(name), LoanSourceBO.class);
}
/**
* {@inheritDoc}
*/
@Override
public List<LoanSourceBO> list(final Collection<String> names) {
return beanService.convert(loanSourceDal.listByNames(names), LoanSourceBO.class);
}
}

View File

@ -1,30 +0,0 @@
package com.pudonghot.yo.operation.service.loanimport.model;
import lombok.Getter;
import lombok.Setter;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.pudonghot.tigon.service.model.BaseServModel;
/**
* 案件来源表
*
* @author Donghuang
* @date Oct 09, 2024 12:09:08
*/
@Getter
@Setter
public class LoanSourceBO extends BaseServModel {
private static final long serialVersionUID = 1L;
/**
* 渠道数据源代码
*/
@JsonAlias("loanSourceCode")
private String code;
/**
* 渠道数据源名称
*/
@JsonAlias("loanSourceName")
private String name;
}

View File

@ -16,9 +16,8 @@ import jakarta.validation.constraints.NotBlank;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import jakarta.validation.constraints.PositiveOrZero;
import org.apache.commons.lang3.time.DateFormatUtils;
import com.pudonghot.yo.operation.service.loanimport.annotation.IdCard;
import com.pudonghot.yo.operation.annotation.MoneyAmount;
import com.pudonghot.yo.operation.service.loanimport.annotation.IdCard;
/**
* @author Donghuang
@ -256,16 +255,16 @@ public class ApplicationImportBO extends BaseImportBO {
/**
* 出生日期
*
* @return birth day
* @return birthday
*/
public String getBirthday() {
public Date getBirthday() {
if (StringUtils.isBlank(idNo)) {
return null;
}
val idCard = IdCardUtils.parse(idNo);
if (idCard != null) {
return DateFormatUtils.format(idCard.birthdate(), "yyyy-MM-dd");
return idCard.birthdate();
}
return null;

View File

@ -0,0 +1 @@
package com.pudonghot.yo.operation.service.loanimport.model;

View File

@ -4,7 +4,6 @@ import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import com.alibaba.excel.annotation.ExcelProperty;
import org.springframework.web.multipart.MultipartFile;
import com.pudonghot.tigon.kit.bean.annotation.ShallowField;
@ -22,17 +21,4 @@ public class LoanImportReqBO implements Serializable {
@ShallowField
private MultipartFile file;
@Getter
@Setter
@ToString
public static class ImportExcelModel implements Serializable {
private static final long serialVersionUID = 1L;
@ExcelProperty("ID")
private Long id;
@ExcelProperty(value = "操作(中标、流标)")
private Boolean outbid;
}
}

View File

@ -1,5 +1,6 @@
package com.pudonghot.yo.operation.service.mediator.impl;
import com.pudonghot.tigon.cms.common.enumeration.GenderEnum;
import lombok.val;
import java.util.Set;
import java.util.List;
@ -20,7 +21,6 @@ import com.pudonghot.yo.operation.dal.mediator.MediatorDal;
import org.springframework.beans.factory.annotation.Autowired;
import com.pudonghot.yo.operation.dal.mediator.model.MediatorDO;
import org.springframework.transaction.annotation.Transactional;
import com.pudonghot.yo.operation.enumeration.customer.GenderEnum;
import com.pudonghot.yo.operation.service.mediator.MediatorService;
import com.pudonghot.yo.operation.service.mediator.model.MediatorBO;
import com.pudonghot.yo.operation.service.mediator.response.UuidRespBO;

View File

@ -46,3 +46,6 @@ tigon:
yo:
webrtc:
endpoint: wss://cc.ideasfin.com:4443/ws
tj:
loan-source:
category-code: LOAN_SOURCE

View File

@ -1,14 +1,26 @@
package com.pudonghot.yo.operation.controller.assignment;
import lombok.val;
import jakarta.validation.Valid;
import org.springframework.util.Assert;
import org.apache.commons.lang3.StringUtils;
import jakarta.validation.constraints.NotNull;
import com.pudonghot.tigon.kit.bean.BeanService;
import org.springframework.util.CollectionUtils;
import com.pudonghot.tigon.web.controller.annotation.Api;
import org.springframework.web.bind.annotation.PostMapping;
import com.pudonghot.tigon.web.controller.annotation.ApiMeta;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import com.pudonghot.tigon.web.controller.annotation.TigonController;
import com.pudonghot.yo.operation.service.assignment.AssignmentService;
import com.pudonghot.yo.operation.controller.assignment.model.AssignmentVO;
import com.pudonghot.yo.operation.service.assignment.request.AssignmentImportReqBO;
import com.pudonghot.yo.operation.controller.assignment.request.AssignmentListReqVO;
import com.pudonghot.yo.operation.controller.assignment.request.AssignmentImportReqVO;
import com.pudonghot.yo.operation.controller.assignment.request.AssignmentCreateReqVO;
import com.pudonghot.yo.operation.controller.assignment.request.AssignmentUpdateReqVO;
import com.pudonghot.yo.operation.controller.assignment.response.AssignmentImportRespVO;
/**
* 催收案件分单记录表
@ -28,4 +40,22 @@ import com.pudonghot.yo.operation.controller.assignment.request.AssignmentUpdate
@ApiMeta("案件分单")
@RequestMapping("/api/assignment")
public class AssignmentController {
@Autowired
private AssignmentService assignmentService;
@Autowired
private BeanService beanService;
@ApiMeta("分案导入")
@PostMapping("/import")
public AssignmentImportRespVO loanImport(
@Valid
@NotNull
final AssignmentImportReqVO req) {
val resp = assignmentService.assignmentImport(beanService.convert(req, AssignmentImportReqBO.class));
Assert.state(CollectionUtils.isEmpty(resp.getErrors()),
() -> "分案导入异常:" + StringUtils.join(resp.getErrors(), "\n"));
return beanService.convert(resp, AssignmentImportRespVO.class);
}
}

View File

@ -0,0 +1,26 @@
package com.pudonghot.yo.operation.controller.assignment.request;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import com.pudonghot.tigon.annotation.Trim;
import jakarta.validation.constraints.NotNull;
import org.springframework.web.multipart.MultipartFile;
import com.pudonghot.tigon.kit.bean.annotation.ShallowField;
/**
* @author Donghuang
* @date Oct 23, 2024 16:09:02
*/
@Trim
@Getter
@Setter
@ToString
public class AssignmentImportReqVO implements Serializable {
private static final long serialVersionUID = 1L;
@NotNull
@ShallowField
private MultipartFile file;
}

View File

@ -0,0 +1,21 @@
package com.pudonghot.yo.operation.controller.assignment.response;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.List;
import java.io.Serializable;
/**
* @author Donghuang
* @date Oct 23, 2024 16:10:14
*/
@Getter
@Setter
@ToString
public class AssignmentImportRespVO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer total;
private List<String> errors;
}

View File

@ -0,0 +1,49 @@
package com.pudonghot.yo.operation.controller.interaction;
import java.util.List;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import com.pudonghot.tigon.kit.bean.BeanService;
import com.pudonghot.tigon.web.controller.annotation.Api;
import org.springframework.web.bind.annotation.RequestParam;
import com.pudonghot.tigon.web.controller.annotation.ApiMeta;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import com.pudonghot.tigon.web.controller.annotation.TigonController;
import com.pudonghot.yo.operation.service.interaction.InteractionService;
import com.pudonghot.yo.operation.controller.interaction.model.InteractionVO;
import com.pudonghot.yo.operation.controller.interaction.response.InteractionAgentVO;
import com.pudonghot.yo.operation.controller.interaction.request.InteractionListReqVO;
import com.pudonghot.yo.operation.controller.interaction.request.InteractionCreateReqVO;
/**
* 催收记录表
*
* @author Donghuang
* @date Oct 23, 2024 11:17:37
*/
@ApiMeta("调解记录")
@TigonController(service = InteractionService.class,
viewModel = InteractionVO.class,
list = @Api(InteractionListReqVO.class),
create = @Api(InteractionCreateReqVO.class)
)
@RequestMapping("/api/interaction")
public class InteractionController {
@Autowired
private InteractionService interactionService;
@Autowired
private BeanService beanService;
@ApiMeta("调解员列表")
@RequestMapping("/agents")
public List<InteractionAgentVO> agents(
@NotNull
@Positive
@RequestParam("loanId")
final Long loanId) {
return beanService.convert(interactionService.agents(loanId), InteractionAgentVO.class);
}
}

View File

@ -0,0 +1,109 @@
package com.pudonghot.yo.operation.controller.interaction.model;
import com.pudonghot.yo.operation.enumeration.interaction.InteractionTypeEnum;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.math.BigDecimal;
import com.pudonghot.tigon.web.controller.model.BaseVO;
import com.pudonghot.yo.operation.enumeration.interaction.ConclusionEnum;
/**
* 催收记录表
*
* @author Donghuang
* @date Oct 23, 2024 11:17:37
*/
@Getter
@Setter
public class InteractionVO extends BaseVO {
private static final long serialVersionUID = 1L;
/**
* 催收案件ID
*/
private Long loanId;
/**
* 调解员
*/
private Long agentId;
/**
* 催收方式
*/
private InteractionTypeEnum type;
/**
* 结论
*/
private ConclusionEnum conclusion;
/**
* 催收日期
*/
private Date dueDate;
/**
* 下次跟进时间
*/
private Date recheckDate;
/**
* 操作类别:内部人工;内部自动
*/
private String handleCategory;
/**
* 是否有效联络: 有效;无效
*/
private String isCallValid;
/**
* 承诺还款日期
*/
private Date promisedPaymentDate;
/**
* 逾期原因
*/
private String overdueReason;
/**
* 本人手机号状态
*/
private String phoneStatus;
/**
* 短信表主键ID
*/
private Long smsId;
/**
* 催收操作结果
*/
private String result;
/**
* 承诺还款金额
*/
private BigDecimal promisedPaymentAmount;
/**
* 客户姓名
*/
private String name;
/**
* 客户手机
*/
private String phone;
/**
* contact表主键联系人
*/
private Long contactId;
private String relation;
}

View File

@ -0,0 +1,26 @@
package com.pudonghot.yo.operation.controller.interaction.request;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
/**
* 催收记录表
*
* @author Donghuang
* @date Oct 23, 2024 11:17:37
*/
@Getter
@Setter
public class InteractionAgentListReqVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 催收案件ID
*/
@NotNull
@Positive
private Long loanId;
}

View File

@ -0,0 +1,111 @@
package com.pudonghot.yo.operation.controller.interaction.request;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.math.BigDecimal;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import com.pudonghot.tigon.web.controller.request.BaseCreateReqVO;
import com.pudonghot.yo.operation.enumeration.interaction.ConclusionEnum;
/**
* 催收记录表
*
* @author Donghuang
* @date Oct 23, 2024 11:17:37
*/
@Getter
@Setter
public class InteractionCreateReqVO extends BaseCreateReqVO {
private static final long serialVersionUID = 1L;
/**
* 催收案件ID
*/
@NotNull
@Positive
private Long loanId;
/**
* 催收方式
*/
private String type;
/**
* 结论
*/
private ConclusionEnum conclusion;
/**
* 催收日期
*/
private Date dueDate;
/**
* 下次跟进时间
*/
private Date recheckDate;
/**
* 操作类别:内部人工;内部自动
*/
private String handleCategory;
/**
* 是否有效联络: 有效;无效
*/
private String isCallValid;
/**
* 承诺还款日期
*/
private Date promisedPaymentDate;
/**
* 逾期原因
*/
private String overdueReason;
/**
* 本人手机号状态
*/
private String phoneStatus;
/**
* 短信表主键ID
*/
private Long smsId;
/**
* 催收操作结果
*/
private String result;
/**
* 承诺还款金额
*/
private BigDecimal promisedPaymentAmount;
/**
* 客户姓名
*/
private String name;
/**
* 客户手机
*/
private String phone;
/**
* contact表主键联系人
*/
private Long contactId;
private String relation;
/**
* 催收员ID
*/
private Long agentId;
}

View File

@ -0,0 +1,112 @@
package com.pudonghot.yo.operation.controller.interaction.request;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import com.pudonghot.tigon.web.controller.request.ListCtrlrReq;
import com.pudonghot.yo.operation.enumeration.interaction.ConclusionEnum;
import com.pudonghot.yo.operation.enumeration.interaction.InteractionTypeEnum;
/**
* 催收记录表
*
* @author Donghuang
* @date Oct 23, 2024 11:17:37
*/
@Getter
@Setter
public class InteractionListReqVO extends ListCtrlrReq {
private static final long serialVersionUID = 1L;
/**
* 催收案件ID
*/
@NotNull
@Positive
private Long loanId;
/**
* 催收员ID
*/
private Long agentId;
/**
* 催收方式
*/
private InteractionTypeEnum type;
/**
* 结论
*/
private ConclusionEnum conclusion;
/**
* 备注
*/
private String remark;
/**
* 催收日期
*/
private Date dueDate;
/**
* 下次跟进时间
*/
private Date recheckDate;
/**
* 操作类别:内部人工;内部自动
*/
private String handleCategory;
/**
* 是否有效联络: 有效;无效
*/
private String isCallValid;
/**
* 承诺还款日期
*/
private Date promisedPaymentDate;
/**
* 逾期原因
*/
private String overdueReason;
/**
* 本人手机号状态
*/
private String phoneStatus;
/**
* 短信表主键ID
*/
private Long smsId;
/**
* 催收操作结果
*/
private String result;
/**
* 客户姓名
*/
private String name;
/**
* 客户手机
*/
private String phone;
/**
* contact表主键联系人
*/
private Long contactId;
private String relation;
}

View File

@ -0,0 +1,20 @@
package com.pudonghot.yo.operation.controller.interaction.response;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
/**
* @author Donghuang
* @date Oct 23, 2024 11:26:08
*/
@Getter
@Setter
@ToString
public class InteractionAgentVO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
}

View File

@ -3,6 +3,7 @@ package com.pudonghot.yo.operation.controller.loan;
import lombok.val;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import com.pudonghot.tigon.kit.bean.BeanService;
import org.springframework.stereotype.Controller;
import com.pudonghot.tigon.dal.model.BaseDbEntity;
@ -10,12 +11,14 @@ import com.pudonghot.yo.operation.dal.loan.model.LoanDO;
import com.pudonghot.yo.operation.service.loan.LoanService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import com.pudonghot.tigon.web.controller.annotation.ApiMeta;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import com.pudonghot.yo.operation.service.loan.request.LoanQueryReqBO;
import com.pudonghot.yo.operation.controller.loan.request.LoanQueryReqVO;
import com.pudonghot.yo.operation.controller.loan.response.LoanQueryRespVO;
import com.pudonghot.yo.operation.controller.loan.response.LoanDetailRespVO;
import com.pudonghot.yo.operation.service.loan.request.LoanBatchUpdateFieldReqBO;
import com.pudonghot.yo.operation.controller.loan.request.LoanBatchUpdateColorReqVO;
import com.pudonghot.yo.operation.controller.loan.request.LoanBatchUpdateRemarkReqVO;
@ -116,4 +119,14 @@ public class LoanController {
return beanService.convert(loanService.query(beanService.convert(req, LoanQueryReqBO.class)), LoanQueryRespVO.class);
}
@ApiMeta("案件详情")
@RequestMapping("/detail")
public LoanDetailRespVO detail(
@RequestParam("id")
@Positive
final Long id) {
return beanService.convert(loanService.detail(id), LoanDetailRespVO.class);
}
}

View File

@ -1,5 +1,6 @@
package com.pudonghot.yo.operation.controller.loan.model;
import com.pudonghot.yo.operation.enumeration.repayment.RepaymentStatusEnum;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
@ -69,7 +70,7 @@ public class LoanVO extends BaseVO {
/**
* 还款状态
*/
private String repaymentStatus;
private RepaymentStatusEnum repaymentStatus;
/**
* 颜色

View File

@ -0,0 +1,659 @@
package com.pudonghot.yo.operation.controller.loan.response;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.util.List;
import lombok.ToString;
import java.io.Serializable;
import java.math.BigDecimal;
import com.pudonghot.tigon.web.controller.annotation.ViewDate;
import com.pudonghot.tigon.cms.common.enumeration.GenderEnum;
import com.pudonghot.yo.operation.controller.loan.annotation.FinanceValue;
import com.pudonghot.yo.operation.enumeration.repayment.RepaymentStatusEnum;
/**
* 案件详情
*
* @author Donghuang
* @date Oct 23, 2024 10:07:37
*/
@Getter
@Setter
@ToString
public class LoanDetailRespVO implements Serializable {
private static final long serialVersionUID = 1L;
private LoanSourceVO loanSource;
private ApplicationVO application;
private LoanVO loan;
private CustomerVO customer;
private List<BankCardVO> bankCards;
private List<ContactVO> contacts;
private List<RepaymentVO> repayments;
/**
* 信贷案件表
*
* @author Donghuang
* @date Oct 15, 2024 15:59:16
*/
@Getter
@Setter
public static class LoanVO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 导入时间
*/
@ViewDate
private Date importTime;
/**
* 导入批次ID
*/
private Long importBatchId;
/**
* 案件来源ID
*/
private Long loanSourceId;
/**
* 外部合同号
*/
private String contractNumber;
/**
* 逾期天数
*/
private Integer overdueDays;
/**
* 应还总金额单位
*/
@FinanceValue
private Long overdueAmount;
/**
* 应还本金单位
*/
@FinanceValue
private Long principalAmount;
/**
* 应还利息单位
*/
@FinanceValue
private Long interestAmount;
/**
* 应还服务费单位
*/
@FinanceValue
private Long serviceAmount;
/**
* 应还罚息单位
*/
@FinanceValue
private Long penaltyAmount;
/**
* 还款状态
*/
private RepaymentStatusEnum repaymentStatus;
/**
* 颜色
*/
private String color;
/**
* 调解函地址
*/
private String mediateFile;
/**
* 调解结果
*/
private String mediateResult;
}
/**
* 还款计划表
*
* @author Donghuang
* @date Oct 23, 2024 10:16:17
*/
@Getter
@Setter
@ToString
public static class RepaymentVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 期数
*/
private int installment;
/**
* 还款状态 UNPAID未还款 PARTIALLY_PAID 部分还款 FULLY_PAID全部还款
*/
private RepaymentStatusEnum status;
/**
* 计划还款时间
*/
@ViewDate
private Date expectRepayTime;
/**
* 实际还款时间
*/
@ViewDate
private Date actualRepayTime;
/**
* 应还本金单位
*/
@FinanceValue
private Long expectPrincipalAmount;
/**
* 已还本金单位
*/
@FinanceValue
private Long actualPrincipalAmount;
/**
* 应还利息单位
*/
@FinanceValue
private Long expectInterestAmount;
/**
* 已还利息单位
*/
@FinanceValue
private Long actualInterestAmount;
/**
* 应还平台服务费单位
*/
@FinanceValue
private Long expectServiceAmount;
/**
* 已还平台服务费单位
*/
@FinanceValue
private Long actualServiceAmount;
/**
* 应还罚息,单位:
*/
@FinanceValue
private Long expectPenaltyAmount;
/**
* 已还罚息,单位:
*/
@FinanceValue
private Long actualPenaltyAmount;
/**
* 减免金额
*/
@FinanceValue
private Long reductionAmount;
/**
* 减免原因
*/
private String reductionReason;
/**
* 应还总金额,单位:
*/
@FinanceValue
private Long expectTotalAmount;
/**
* 已还总金额,单位:
*/
@FinanceValue
private Long actualTotalAmount;
/**
* 逾期金额单位
*/
@FinanceValue
private Long overdueAmount;
}
/**
* @author Donghuang
* @date Oct 23, 2024 10:15:50
*/
@Getter
@Setter
@ToString
public static class LoanSourceVO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 渠道数据源代码
*/
private String loanSourceCode;
/**
* 渠道数据源名称
*/
private String loanSourceName;
}
/**
* 客户
*
* @author Donghuang
* @date Oct 01, 2024 14:20:47
*/
@Getter
@Setter
@ToString
public static class CustomerVO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 姓名
*/
private String name;
/**
* 身份证号
*/
private String idNo;
/**
* 手机
*/
private String mobile;
/**
* 邮箱
*/
private String email;
/**
* 性别
*/
private GenderEnum gender;
/**
* 民族
*/
private String nation;
/**
* 出生日期
*/
@ViewDate
private Date birthday;
/**
* 户籍地址
*/
private String censusRegisterAddress;
/**
* 学历
*/
private String educational;
/**
* 婚姻状态
*/
private String marriage;
/**
* 居住省
*/
private String residenceProvince;
/**
* 居住市
*/
private String residenceCity;
/**
* 居住区
*/
private String residenceDistrict;
/**
* 常住地址
*/
private String residenceAddress;
/**
* 居住时长
*/
private String residenceTime;
/**
* qq
*/
private String qq;
/**
* 职业
*/
private String profession;
/**
* 月收入
*/
private String salary;
/**
* 单位名称
*/
private String workCompany;
/**
* 最近工作年限
*/
private String recentlyWorkDuration;
/**
* 单位所在省
*/
private String companyProvince;
/**
* 单位所在市
*/
private String companyCity;
/**
* 单位所在区
*/
private String companyDistrict;
/**
* 单位详细地址
*/
private String companyAddress;
}
/**
* 客户联系人
*
* @author Donghuang
* @date Oct 23, 2024 10:12:50
*/
@Getter
@Setter
@ToString
public static class ContactVO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 姓名
*/
private String name;
/**
* 手机
*/
private String mobile;
/**
* 关系
*/
private String relationType;
/**
* 联系频率
*/
private String frequency;
/**
* 联系人来源
*/
private String source;
}
/**
* 银行卡
*
* @author Donghuang
* @date Oct 23, 2024 10:13:28
*/
@Getter
@Setter
@ToString
public static class BankCardVO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 开户名
*/
private String name;
/**
* 银行预留手机号
*/
private String mobile;
/**
* 银行ID
*/
private Long bankId;
/**
* 银行卡卡号
*/
private String bankCardNo;
/**
* 银行卡开户行
*/
private String bankName;
/**
* 绑定优先级
*/
private Boolean priority;
}
/**
* 申请单
*
* @author Donghuang
* @date Oct 23, 2024 10:26:32
*/
@Getter
@Setter
@ToString
public static class ApplicationVO implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String remark;
/**
* 总期数
*/
private Integer totalInstallments;
/**
* 当前期数
*/
private Integer currentInstallment;
/**
* 已还期数
*/
private Integer repaidInstallments;
/**
* 逾期期数
*/
private Integer overdueInstallments;
/**
* 申请时间
*/
@ViewDate
private Date applyDate;
/**
* 批核时间
*/
@ViewDate
private Date approveDate;
/**
* 放款时间
*/
@ViewDate
private Date loanDate;
/**
* 当期账单日
*/
@ViewDate
private Date dueDate;
/**
* 利率
*/
private BigDecimal interestRate;
/**
* 服务费率
*/
private BigDecimal serviceInterestRate;
/**
* 罚息利率
*/
private BigDecimal penaltyInterestRate;
/**
* 合同(申请)金额
*/
@FinanceValue
private Long applyAmount;
/**
* 放款金额
*/
@FinanceValue
private Long loanAmount;
/**
* 违约金,罚金
*/
@FinanceValue
private Long defaultFineAmount;
/**
* 逾期金额
*/
@FinanceValue
private Long overdueAmount;
/**
* 剩余本金
*/
@FinanceValue
private Long principalRemain;
/**
* 提前清贷金额
*/
@FinanceValue
private Long prepaymentAmount;
/**
* 募资方
*/
private String fundraiser;
/**
* 产品名称
*/
private String productName;
/**
* 还款方式
*/
private String repaymentType;
/**
* 贷款平台名称
*/
private String platformName;
/**
* 募资方名称
*/
private String fundraiserName;
/**
* 助贷机构名称
*/
private String loanAgencyName;
/**
* 紧急联系人关系
*/
private String emergencyContactRelation;
/**
* 紧急联系人备注名
*/
private String emergencyContactName;
/**
* 紧急联系人号码
*/
private String emergencyContactMobile;
private List<ExtFieldVO> extFields;
@Getter
@Setter
@ToString
public static class ExtFieldVO implements Serializable {
private static final long serialVersionUID = 1L;
private String label;
private String value;
}
}
}

View File

@ -39,6 +39,9 @@ public class LoanQueryRowRespVO implements Serializable {
@ViewDate
private Date commissionDate;
private Long deptId;
private String deptName;
private Long assignAgentId;
private String assignAgentName;
private AssignmentStatusEnum assignStatus;

View File

@ -55,10 +55,15 @@ tigon:
categories:
- code: SITE_HOME_CATEGORY
name: 站点首页分类
- code: SITE_BANNER
name: 站点轮播图
data-type: IMAGE
- code: LOAN_SOURCE
name: 案件来源
user-code: true
- code: SITE_SETTING
name: 站点设置
data-type: RICH_TEXT
@ -130,4 +135,7 @@ yo:
allowed-origins: >
http://localhost:[*],
http://127.0.0.1:[*]
https://*.zhujiachefu.com
https://*.zhujiachefu.com
tj:
loan-source:
category-code: LOAN_SOURCE