Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
customer-service
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
QG
customer-service
Commits
fcb47335
Commit
fcb47335
authored
Mar 02, 2022
by
吴琼
Browse files
Options
Browse Files
Download
Plain Diff
处理冲突
parents
0245e681
fb5a0b6b
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
1785 additions
and
4 deletions
+1785
-4
pom.xml
pom.xml
+39
-2
Bootstrap.java
src/main/java/cn/quantgroup/customer/Bootstrap.java
+6
-0
CrosFilter.java
...uantgroup/customer/config/http/mvc/filter/CrosFilter.java
+4
-1
ValidOperatePermitFilter.java
...omer/config/http/mvc/filter/ValidOperatePermitFilter.java
+1
-1
OfflineRepayOperateRecord.java
...quantgroup/customer/entity/OfflineRepayOperateRecord.java
+48
-0
OfflineRepaySubmitRecord.java
.../quantgroup/customer/entity/OfflineRepaySubmitRecord.java
+74
-0
ApprovalStatus.java
...ain/java/cn/quantgroup/customer/enums/ApprovalStatus.java
+25
-0
VccRepayStatusEnum.java
...java/cn/quantgroup/customer/enums/VccRepayStatusEnum.java
+42
-0
FileInfo.java
src/main/java/cn/quantgroup/customer/model/ftp/FileInfo.java
+21
-0
ServerInfo.java
...ain/java/cn/quantgroup/customer/model/ftp/ServerInfo.java
+22
-0
OfflineRepayOperateRecordRepo.java
...antgroup/customer/repo/OfflineRepayOperateRecordRepo.java
+10
-0
OfflineRepaySubmitRecordRepo.java
...uantgroup/customer/repo/OfflineRepaySubmitRecordRepo.java
+21
-0
VccRest.java
src/main/java/cn/quantgroup/customer/rest/VccRest.java
+220
-0
ApplyBill.java
...java/cn/quantgroup/customer/rest/param/vcc/ApplyBill.java
+24
-0
OfflineRepaySubmitParam.java
...roup/customer/rest/param/vcc/OfflineRepaySubmitParam.java
+48
-0
UserPreRepayInfoQuery.java
...tgroup/customer/rest/param/vcc/UserPreRepayInfoQuery.java
+31
-0
QueryPreOfflineRepayVo.java
...antgroup/customer/rest/vo/vcc/QueryPreOfflineRepayVo.java
+26
-0
QuerySubmitRecordVo.java
.../quantgroup/customer/rest/vo/vcc/QuerySubmitRecordVo.java
+12
-0
IFastDFSService.java
.../java/cn/quantgroup/customer/service/IFastDFSService.java
+9
-0
IVccService.java
...main/java/cn/quantgroup/customer/service/IVccService.java
+28
-0
AbstractFtpService.java
...n/quantgroup/customer/service/ftp/AbstractFtpService.java
+269
-0
CustomerSftpServiceImpl.java
...ntgroup/customer/service/ftp/CustomerSftpServiceImpl.java
+97
-0
IFtpService.java
.../java/cn/quantgroup/customer/service/ftp/IFtpService.java
+71
-0
FastDFSServiceImpl.java
.../quantgroup/customer/service/impl/FastDFSServiceImpl.java
+28
-0
VccServiceImpl.java
...a/cn/quantgroup/customer/service/impl/VccServiceImpl.java
+398
-0
IdUtil.java
src/main/java/cn/quantgroup/customer/util/IdUtil.java
+68
-0
IpAddrUtils.java
src/main/java/cn/quantgroup/customer/util/IpAddrUtils.java
+84
-0
ProtoCommon.java
src/main/java/cn/quantgroup/customer/util/ProtoCommon.java
+59
-0
No files found.
pom.xml
View file @
fcb47335
...
@@ -52,6 +52,22 @@
...
@@ -52,6 +52,22 @@
<encoding>
${project.build.sourceEncoding}
</encoding>
<encoding>
${project.build.sourceEncoding}
</encoding>
</configuration>
</configuration>
</plugin>
</plugin>
<!-- <plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>-->
</plugins>
</plugins>
</build>
</build>
...
@@ -253,6 +269,7 @@
...
@@ -253,6 +269,7 @@
<artifactId>
spring-boot-starter-test
</artifactId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>
test
</scope>
<scope>
test
</scope>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>
com.itextpdf
</groupId>
<groupId>
com.itextpdf
</groupId>
<artifactId>
itextpdf
</artifactId>
<artifactId>
itextpdf
</artifactId>
...
@@ -277,8 +294,21 @@
...
@@ -277,8 +294,21 @@
<groupId>
org.springframework
</groupId>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-test
</artifactId>
<artifactId>
spring-test
</artifactId>
</dependency>
</dependency>
<!--fastdfs-->
<!--<dependency>
<!--<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>4.2.1</version>
<scope>provided</scope>
</dependency>-->
<dependency>
<groupId>
com.github.tobato
</groupId>
<groupId>
com.github.tobato
</groupId>
<artifactId>
fastdfs-client
</artifactId>
<artifactId>
fastdfs-client
</artifactId>
<version>
1.25.2-RELEASE
</version>
<version>
1.25.2-RELEASE
</version>
...
@@ -296,11 +326,18 @@
...
@@ -296,11 +326,18 @@
<artifactId>
slf4j-api
</artifactId>
<artifactId>
slf4j-api
</artifactId>
</exclusion>
</exclusion>
</exclusions>
</exclusions>
</dependency>
-->
</dependency>
<!-- <dependency>
<!-- <dependency>
<groupId>org.springframework</groupId>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<artifactId>spring-test</artifactId>
</dependency>-->
</dependency>-->
<!-- sftp -->
<dependency>
<groupId>
com.jcraft
</groupId>
<artifactId>
jsch
</artifactId>
<version>
0.1.54
</version>
</dependency>
</dependencies>
</dependencies>
</project>
</project>
src/main/java/cn/quantgroup/customer/Bootstrap.java
View file @
fcb47335
package
cn
.
quantgroup
.
customer
;
package
cn
.
quantgroup
.
customer
;
import
com.github.tobato.fastdfs.FdfsClientConfig
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.boot.web.servlet.ServletComponentScan
;
import
org.springframework.boot.web.servlet.ServletComponentScan
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.EnableAspectJAutoProxy
;
import
org.springframework.context.annotation.EnableAspectJAutoProxy
;
import
org.springframework.context.annotation.EnableMBeanExport
;
import
org.springframework.context.annotation.Import
;
import
org.springframework.jmx.support.RegistrationPolicy
;
@Import
(
FdfsClientConfig
.
class
)
@EnableMBeanExport
(
registration
=
RegistrationPolicy
.
IGNORE_EXISTING
)
@Configuration
@Configuration
@ServletComponentScan
@ServletComponentScan
@EnableAspectJAutoProxy
@EnableAspectJAutoProxy
...
...
src/main/java/cn/quantgroup/customer/config/http/mvc/filter/CrosFilter.java
View file @
fcb47335
...
@@ -40,13 +40,16 @@ public class CrosFilter implements Filter {
...
@@ -40,13 +40,16 @@ public class CrosFilter implements Filter {
String
allowedOrigin
=
"*"
;
String
allowedOrigin
=
"*"
;
response
.
setHeader
(
"Access-Control-Allow-Origin"
,
allowedOrigin
);
response
.
setHeader
(
"Access-Control-Allow-Origin"
,
allowedOrigin
);
response
.
setHeader
(
"Access-Control-Allow-Methods"
,
"POST, GET"
);
response
.
setHeader
(
"Access-Control-Allow-Methods"
,
"POST, GET"
);
String
allowedHeaders
=
"Origin, No-Cache, x-auth-token, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type,Authorization"
;
String
allowedHeaders
=
"Origin, No-Cache, x-auth-token, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type,Authorization"
+
"Accept,Access-Token,Account,Account-Name,Referer,sec-ch-ua,sec-ch-ua-mobile,sec-ch-ua-platform,User-Agent"
;
response
.
setHeader
(
"Access-Control-Allow-Headers"
,
allowedHeaders
);
response
.
setHeader
(
"Access-Control-Allow-Headers"
,
allowedHeaders
);
response
.
setHeader
(
"Access-Control-Max-Age"
,
"3600"
);
response
.
setHeader
(
"Access-Control-Max-Age"
,
"3600"
);
if
(
DISALLOWED_METHOD
.
contains
(
request
.
getMethod
()))
{
if
(
DISALLOWED_METHOD
.
contains
(
request
.
getMethod
()))
{
return
;
return
;
}
}
filterChain
.
doFilter
(
servletRequest
,
servletResponse
);
filterChain
.
doFilter
(
servletRequest
,
servletResponse
);
}
}
@Override
@Override
...
...
src/main/java/cn/quantgroup/customer/config/http/mvc/filter/ValidOperatePermitFilter.java
View file @
fcb47335
...
@@ -26,7 +26,7 @@ import java.util.Objects;
...
@@ -26,7 +26,7 @@ import java.util.Objects;
* @Desc 鉴权过滤器
* @Desc 鉴权过滤器
* @Update
* @Update
*/
*/
@WebFilter
(
filterName
=
"operatePermitFilter"
,
urlPatterns
=
{
"/operate/sys/*"
,
"/repay/earlySettleOperate"
})
@WebFilter
(
filterName
=
"operatePermitFilter"
,
urlPatterns
=
{
"/operate/sys/*"
,
"/repay/earlySettleOperate"
,
"/vcc/*"
})
@Slf4j
@Slf4j
public
class
ValidOperatePermitFilter
implements
Filter
{
public
class
ValidOperatePermitFilter
implements
Filter
{
@Autowired
@Autowired
...
...
src/main/java/cn/quantgroup/customer/entity/OfflineRepayOperateRecord.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
entity
;
import
lombok.*
;
import
org.hibernate.annotations.DynamicInsert
;
import
org.hibernate.annotations.DynamicUpdate
;
import
org.springframework.data.annotation.CreatedDate
;
import
org.springframework.data.annotation.LastModifiedDate
;
import
javax.persistence.*
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
import
java.util.Date
;
@Entity
@Table
(
name
=
"offline_repay_operate_record"
)
@ToString
@Builder
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@DynamicUpdate
@DynamicInsert
public
class
OfflineRepayOperateRecord
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
9206318459421433518L
;
@Id
@Column
(
name
=
"id"
)
@GeneratedValue
(
strategy
=
GenerationType
.
IDENTITY
)
private
Long
id
;
@Column
(
name
=
"serial_no"
)
private
String
serialNo
;
@Column
(
name
=
"operate_account"
)
private
String
operateAccount
;
@Column
(
name
=
"operate_name"
)
private
String
operateName
;
@Column
(
name
=
"operate_content"
)
private
String
operateContent
;
@Column
(
name
=
"operate_time"
)
private
Date
operateTime
;
@Column
(
name
=
"remark"
)
private
String
remark
;
@Column
(
name
=
"create_time"
)
private
Date
createTime
;
@Column
(
name
=
"update_time"
)
private
Date
updateTime
;
}
src/main/java/cn/quantgroup/customer/entity/OfflineRepaySubmitRecord.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
entity
;
import
lombok.*
;
import
org.hibernate.annotations.DynamicInsert
;
import
org.hibernate.annotations.DynamicUpdate
;
import
org.springframework.data.annotation.CreatedDate
;
import
org.springframework.data.annotation.LastModifiedDate
;
import
javax.persistence.*
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.util.Date
;
@Entity
@Table
(
name
=
"offline_repay_submit_record"
)
@ToString
@Builder
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@DynamicInsert
@DynamicUpdate
public
class
OfflineRepaySubmitRecord
implements
Serializable
{
private
static
final
long
serialVersionUID
=
2930019435843122345L
;
@Id
@Column
(
name
=
"id"
)
@GeneratedValue
(
strategy
=
GenerationType
.
IDENTITY
)
private
Long
id
;
@Column
(
name
=
"serial_no"
)
private
String
serialNo
;
@Column
(
name
=
"unique_id"
)
private
String
uniqueId
;
@Column
(
name
=
"bills"
)
private
String
bills
;
@Column
(
name
=
"curr_term"
)
private
Integer
currTerm
;
@Column
(
name
=
"amount"
)
private
BigDecimal
amount
;
@Column
(
name
=
"actual_amount"
)
private
BigDecimal
actualAmount
;
@Column
(
name
=
"actual_date"
)
private
Date
actualDate
;
@Column
(
name
=
"trans_no"
)
private
String
transNo
;
@Column
(
name
=
"receive_account"
)
private
String
receiveAccount
;
@Column
(
name
=
"receive_account_name"
)
private
String
receiveAccountName
;
@Column
(
name
=
"credentials_address"
)
private
String
credentialsAddress
;
@Column
(
name
=
"mark"
)
private
String
mark
;
@Column
(
name
=
"repay_type"
)
private
Integer
repayType
;
@Column
(
name
=
"user_id"
)
private
Integer
userId
;
@Column
(
name
=
"name"
)
private
String
name
;
@Column
(
name
=
"phone"
)
private
String
phone
;
@Column
(
name
=
"id_no"
)
private
String
idNo
;
@Column
(
name
=
"repay_status"
)
private
String
repayStatus
;
@Column
(
name
=
"approval_status"
)
private
Integer
approvalStatus
;
@Column
(
name
=
"create_time"
)
private
Date
createTime
;
@Column
(
name
=
"update_time"
)
private
Date
updateTime
;
}
src/main/java/cn/quantgroup/customer/enums/ApprovalStatus.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
enums
;
public
enum
ApprovalStatus
{
APPROVAL_PROCESSING
(
0
,
"审批中"
),
APPROVAL_PASS
(
1
,
"审批通过"
),
APPROVAL_REFUSE
(
2
,
"审批拒绝"
);
private
Integer
code
;
private
String
desc
;
ApprovalStatus
(
Integer
code
,
String
desc
){
this
.
code
=
code
;
this
.
desc
=
desc
;
}
public
static
String
getDescByValue
(
Integer
value
){
for
(
ApprovalStatus
approvalStatus:
ApprovalStatus
.
values
()){
if
(
approvalStatus
.
code
.
equals
(
value
)){
return
approvalStatus
.
desc
;
}
}
return
""
;
}
}
src/main/java/cn/quantgroup/customer/enums/VccRepayStatusEnum.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
enums
;
public
enum
VccRepayStatusEnum
{
/**
* 正常状态,主要包括:还款计划未出账、额度状态正常
*/
Normal
(
"正常"
),
/**
* 还款状态,主要包括:账单待还款、还款计划待还款
* 韩伟:待还款,生成账单后
*/
Repay
(
"还款"
),
/**
* 逾期状态,主要包括:账单逾期、还款计划逾期
*/
Overdue
(
"逾期"
),
/**
* 完结状态,主要包括:账单还清、还款计划还清、分期交易还清
*/
Finish
(
"完结"
),
/**
* 完成状态, 主要包括:交易完成
*/
Complete
(
"完成"
);
private
String
desc
;
private
VccRepayStatusEnum
(
String
desc
){
this
.
desc
=
desc
;
}
public
static
String
getDescByValue
(
String
value
){
for
(
VccRepayStatusEnum
statusEnum:
VccRepayStatusEnum
.
values
()){
if
(
statusEnum
.
toString
().
equals
(
value
)){
return
statusEnum
.
desc
;
}
}
return
""
;
}
}
src/main/java/cn/quantgroup/customer/model/ftp/FileInfo.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
model
.
ftp
;
import
lombok.Data
;
/**
* @author yexiong.wang
* @date 2022/02/27
*/
@Data
public
class
FileInfo
{
private
String
fileName
;
private
byte
[]
fileBytes
;
private
String
filePath
;
public
FileInfo
(
String
fileName
,
byte
[]
fileBytes
,
String
filePath
)
{
this
.
fileName
=
fileName
;
this
.
fileBytes
=
fileBytes
;
this
.
filePath
=
filePath
;
}
}
src/main/java/cn/quantgroup/customer/model/ftp/ServerInfo.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
model
.
ftp
;
import
lombok.Builder
;
import
lombok.Data
;
/**
* @author yexiong.wang
* @date 2022/02/27
*/
@Data
@Builder
public
class
ServerInfo
{
private
String
username
;
private
String
password
;
private
String
host
;
private
String
directory
;
private
int
port
;
}
src/main/java/cn/quantgroup/customer/repo/OfflineRepayOperateRecordRepo.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
repo
;
import
cn.quantgroup.customer.entity.OfflineRepayOperateRecord
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
java.util.List
;
public
interface
OfflineRepayOperateRecordRepo
extends
JpaRepository
<
OfflineRepayOperateRecord
,
Long
>
{
List
<
OfflineRepayOperateRecord
>
findBySerialNoEquals
(
String
serailNo
);
}
src/main/java/cn/quantgroup/customer/repo/OfflineRepaySubmitRecordRepo.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
repo
;
import
cn.quantgroup.customer.entity.OfflineRepaySubmitRecord
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.querydsl.QueryDslPredicateExecutor
;
import
java.util.List
;
public
interface
OfflineRepaySubmitRecordRepo
extends
JpaRepository
<
OfflineRepaySubmitRecord
,
Long
>,
QueryDslPredicateExecutor
<
OfflineRepaySubmitRecord
>
{
OfflineRepaySubmitRecord
findBySerialNoEquals
(
String
serialNo
);
OfflineRepaySubmitRecord
findFirstByUniqueIdEquals
(
String
uniqueId
);
OfflineRepaySubmitRecord
findFirstByUniqueIdEqualsAndApprovalStatusNot
(
String
uniqueId
,
Integer
approvalStatus
);
List
<
OfflineRepaySubmitRecord
>
findByUserIdEqualsAndRepayTypeEquals
(
Integer
userId
,
Integer
repayType
);
List
<
OfflineRepaySubmitRecord
>
findByUserIdEqualsAndRepayTypeEqualsAndApprovalStatusNot
(
Integer
userId
,
Integer
repayType
,
Integer
approvalStatus
);
OfflineRepaySubmitRecord
findBySerialNoEqualsAndApprovalStatusEquals
(
String
serialNo
,
Integer
approvalStatus
);
}
src/main/java/cn/quantgroup/customer/rest/VccRest.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
rest
;
import
cn.quantgroup.customer.aop.OperateLog
;
import
cn.quantgroup.customer.rest.param.vcc.OfflineRepaySubmitParam
;
import
cn.quantgroup.customer.rest.param.vcc.UserPreRepayInfoQuery
;
import
cn.quantgroup.customer.rest.vo.JsonResult
;
import
cn.quantgroup.customer.service.IVccService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.validation.BindingResult
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.validation.Valid
;
import
javax.validation.constraints.NotNull
;
import
java.util.Map
;
import
java.util.Objects
;
@Slf4j
@RestController
@RequestMapping
(
"/vcc"
)
public
class
VccRest
{
@Autowired
private
IVccService
vccService
;
/**
* 查询用户的待还款信息
* @param query
* @return
*/
@PostMapping
(
"/offline_pre_repay/query_page"
)
@OperateLog
(
moduleName
=
"查询用户的待还款信息"
)
public
JsonResult
queryPage
(
@RequestBody
@Valid
UserPreRepayInfoQuery
query
,
BindingResult
bindingResult
){
if
(
bindingResult
.
hasErrors
()){
return
JsonResult
.
buildErrorStateResult
(
bindingResult
.
getFieldError
().
getField
()
+
":"
+
bindingResult
.
getFieldError
().
getDefaultMessage
());
}
log
.
info
(
"queryPage | 开始用户待还款查询,param={}"
,
query
);
if
(
StringUtils
.
isBlank
(
query
.
getBillId
())
&&
StringUtils
.
isBlank
(
query
.
getPhone
())
&&
StringUtils
.
isBlank
(
query
.
getUserId
())
&&
StringUtils
.
isBlank
(
query
.
getOrderNo
())){
log
.
error
(
"queryPage | 请求参数userId,phone,billId,orderNo不能同时为空"
);
return
JsonResult
.
buildErrorStateResult
(
"请求参数userId,phone,billId,orderNo不能同时为空"
);
}
try
{
JsonResult
jsonResult
=
vccService
.
queryPage
(
query
);
log
.
info
(
"queryPage | 结束用户待还款查询,param={}"
,
query
);
return
jsonResult
;
}
catch
(
Exception
e
){
log
.
error
(
"queryPage | 用户待还款查询发生异常"
,
e
);
return
JsonResult
.
buildErrorStateResult
(
"用户待还款查询发生异常:"
+
e
.
getMessage
());
}
}
/**
* 查询分期账单的详情
* @param uniqueId
* @param repayType
* @return
*/
@GetMapping
(
"/pre_repay_cal/detail"
)
@OperateLog
(
moduleName
=
"查询分期账单的详情"
)
public
JsonResult
repayPlanDetail
(
@NotNull
String
uniqueId
,
@NotNull
Integer
repayType
){
log
.
info
(
"repayPlanDetail | 查询用户分期的详情及试算详情,uniqueId={},repayType={}"
,
uniqueId
,
repayType
);
try
{
JsonResult
jsonResult
=
vccService
.
queryRepayCalDetail
(
uniqueId
,
repayType
);
log
.
info
(
"repayPlanDetail | 结束查询用户分期的详情及试算详情,uniqueId={},repayType={}"
,
uniqueId
,
repayType
);
return
jsonResult
;
}
catch
(
Exception
e
){
log
.
error
(
"repayPlanDetail | 查询用户分期的详情及试算详情发生异常"
,
e
);
return
JsonResult
.
buildErrorStateResult
(
"查询用户分期的详情及试算详情发生异常:"
+
e
.
getMessage
());
}
}
/**
* 保存线下还款的申请记录
* @param request
* @param param
* @return
*/
@PostMapping
(
"/offline_repay/save_submit"
)
@OperateLog
(
moduleName
=
"保存线下还款的申请记录"
)
public
JsonResult
saveSubmit
(
HttpServletRequest
request
,
@RequestBody@Valid
OfflineRepaySubmitParam
param
,
BindingResult
bindingResult
){
if
(
bindingResult
.
hasErrors
()){
return
JsonResult
.
buildErrorStateResult
(
bindingResult
.
getFieldError
().
getField
()
+
":"
+
bindingResult
.
getFieldError
().
getDefaultMessage
());
}
if
(
param
.
getRepayType
()
==
1
){
if
(
CollectionUtils
.
isEmpty
(
param
.
getList
())){
return
JsonResult
.
buildErrorStateResult
(
"还款月还账单时,账单不能为空"
);
}
}
else
{
if
(
StringUtils
.
isBlank
(
param
.
getUniqueId
())){
return
JsonResult
.
buildErrorStateResult
(
"提前结清时单号不能为空"
);
}
if
(
Objects
.
isNull
(
param
.
getCurrTerm
())){
return
JsonResult
.
buildErrorStateResult
(
"提前结清开始期数不能为空"
);
}
}
log
.
info
(
"saveSubmit | 开始保存线下还款的申请记录,param={}"
,
param
);
try
{
String
token
=
request
.
getHeader
(
"x-auth-token"
);
vccService
.
saveSubmitRecord
(
param
,
token
);
log
.
info
(
"saveSubmit | 保存线下还款的申请记录成功,param={}"
,
param
);
return
JsonResult
.
buildSuccessResult
(
"请求成功"
,
null
);
}
catch
(
Exception
e
){
log
.
error
(
"saveSubmit | 保存线下还款提交申请时发生异常"
,
e
);
return
JsonResult
.
buildErrorStateResult
(
"保存线下还款提交申请时发生异常:"
+
e
.
getMessage
());
}
}
/**
* 审批回显提交的线下还款申请记录
* @param serialNo
* @return
*/
@GetMapping
(
"/offline_repay/approval"
)
@OperateLog
(
moduleName
=
"审批回显提交的线下还款申请记录"
)
public
JsonResult
approval
(
@NotNull
String
serialNo
){
log
.
info
(
"approval | 开始点击审批按钮查询信息,serialNo={}"
,
serialNo
);
try
{
OfflineRepaySubmitParam
param
=
vccService
.
approvalQuery
(
serialNo
);
log
.
info
(
"approval | 点击审批按钮查询信息成功,serialNo={}"
,
serialNo
);
return
JsonResult
.
buildSuccessResult
(
"请求成功"
,
param
);
}
catch
(
Exception
e
){
log
.
error
(
"approval | 点击审批按钮查询信息时发生异常"
,
e
);
return
JsonResult
.
buildErrorStateResult
(
"点击审批按钮查询信息时发生异常:"
,
e
.
getMessage
());
}
}
/**
* 查看审批流水记录
* @param serialNo
* @return
*/
@GetMapping
(
"/approval/detail"
)
@OperateLog
(
moduleName
=
"查看审批流水记录"
)
public
JsonResult
queryApprovalRecord
(
@NotNull
String
serialNo
){
log
.
info
(
"queryApprovalRecord | 开始查看审批流水记录,serialNo={}"
,
serialNo
);
try
{
JsonResult
jsonResult
=
vccService
.
queryApprovalRecord
(
serialNo
);
log
.
info
(
"queryApprovalRecord | 查看审批流水记录成功,serialNo={}"
,
serialNo
);
return
jsonResult
;
}
catch
(
Exception
e
){
log
.
error
(
"queryApprovalRecord | 查询审批流水时发生异常"
,
e
);
return
JsonResult
.
buildErrorStateResult
(
"查询审批流水时发生异常:"
+
e
.
getMessage
());
}
}
/**
* 审批结果:通过/拒绝
* @param request
* @param serialNo
* @param remark
* @param status
* @return
*/
@GetMapping
(
"/approval/result"
)
@OperateLog
(
moduleName
=
"审批结果:通过/拒绝"
)
public
JsonResult
approvalResult
(
HttpServletRequest
request
,
@NotNull
String
serialNo
,
String
remark
,
@NotNull
Integer
status
){
log
.
info
(
"approvalResult | 开始提交审批结果,serialNo={},remark={},status={}"
,
serialNo
,
remark
,
status
);
try
{
String
token
=
request
.
getHeader
(
"x-auth-token"
);
vccService
.
approvalResult
(
serialNo
,
remark
,
status
,
token
);
log
.
info
(
"approvalResult | 提交审批结果成功,serialNo={},remark={},status={}"
,
serialNo
,
remark
,
status
);
return
JsonResult
.
buildSuccessResult
(
"请求成功"
,
null
);
}
catch
(
Exception
e
){
log
.
error
(
"approvalResult | 通过/拒绝审批时发生异常"
,
e
);
return
JsonResult
.
buildErrorStateResult
(
"通过/拒绝审批时发生异常:"
+
e
.
getMessage
());
}
}
/**
* 上传打款凭证
* @param file
* @return
*/
@PostMapping
(
"/offline_repay_file/upload"
)
@OperateLog
(
moduleName
=
"上传打款凭证"
)
public
JsonResult
fileUpload
(
MultipartFile
file
){
log
.
info
(
"fileUpload | 开始上传打款凭证"
);
try
{
Map
<
String
,
String
>
map
=
vccService
.
fileUpload
(
file
);
log
.
info
(
"fileUpload | 上传打款凭证成功map={}"
,
map
);
return
JsonResult
.
buildSuccessResult
(
"请求成功"
,
map
);
}
catch
(
Exception
e
){
log
.
error
(
"fileUpload | 文件上传时发生异常"
,
e
);
return
JsonResult
.
buildErrorStateResult
(
"文件上传时发生异常:"
+
e
.
getMessage
());
}
}
/**
* 查询线下还款的申请记录
* @param query
* @return
*/
@PostMapping
(
"/approval/query_applly_record"
)
@OperateLog
(
moduleName
=
"查询线下还款的申请记录"
)
public
JsonResult
queryApplyRecord
(
@RequestBody@Valid
UserPreRepayInfoQuery
query
,
BindingResult
bindingResult
){
if
(
bindingResult
.
hasErrors
()){
return
JsonResult
.
buildErrorStateResult
(
bindingResult
.
getFieldError
().
getField
()
+
":"
+
bindingResult
.
getFieldError
().
getDefaultMessage
());
}
if
(
StringUtils
.
isBlank
(
query
.
getBillId
())
&&
StringUtils
.
isBlank
(
query
.
getPhone
())
&&
StringUtils
.
isBlank
(
query
.
getUserId
())
&&
StringUtils
.
isBlank
(
query
.
getOrderNo
())){
log
.
error
(
"queryPage | 请求参数userId,phone,billId,orderNo不能同时为空"
);
return
JsonResult
.
buildErrorStateResult
(
"请求参数userId,phone,billId,orderNo不能同时为空"
);
}
log
.
info
(
"queryApplyRecord | 开始查看线下还款的申请记录,param={}"
,
query
);
try
{
JsonResult
jsonResult
=
vccService
.
queryApplyRecord
(
query
);
log
.
info
(
"queryApplyRecord | 查看线下还款的申请记录成功,param={}"
,
query
);
return
jsonResult
;
}
catch
(
Exception
e
){
log
.
error
(
"queryApplyRecord | 查询线下还款申请记录时发生异常"
,
e
);
return
JsonResult
.
buildErrorStateResult
(
"查询线下还款申请记录时发生异常:"
+
e
.
getMessage
());
}
}
}
src/main/java/cn/quantgroup/customer/rest/param/vcc/ApplyBill.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
rest
.
param
.
vcc
;
import
lombok.Data
;
import
java.math.BigDecimal
;
import
java.util.Objects
;
@Data
public
class
ApplyBill
{
private
Long
billId
;
private
BigDecimal
amount
;
@Override
public
boolean
equals
(
Object
o
){
if
(
o
==
null
){
return
false
;
}
if
(
o
instanceof
ApplyBill
){
ApplyBill
applyBill
=
(
ApplyBill
)
o
;
return
Objects
.
equals
(
applyBill
.
billId
,
this
.
billId
);
}
return
super
.
equals
(
o
);
}
}
src/main/java/cn/quantgroup/customer/rest/param/vcc/OfflineRepaySubmitParam.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
rest
.
param
.
vcc
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
lombok.Data
;
import
org.hibernate.validator.constraints.NotBlank
;
import
org.hibernate.validator.constraints.NotEmpty
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
javax.validation.constraints.NotNull
;
import
java.math.BigDecimal
;
import
java.time.LocalDate
;
import
java.util.Date
;
import
java.util.List
;
@Data
public
class
OfflineRepaySubmitParam
{
private
String
uniqueId
;
private
List
<
ApplyBill
>
list
;
private
Integer
currTerm
;
@NotNull
private
BigDecimal
amount
;
@NotNull
private
BigDecimal
actualAmount
;
@NotNull
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
,
timezone
=
"GMT+8"
)
private
Date
actualDate
;
@NotBlank
private
String
transNo
;
@NotBlank
private
String
receiveAccount
;
@NotBlank
private
String
receiveAccountName
;
@NotEmpty
private
List
<
String
>
credentialsAddress
;
private
String
mark
;
@NotNull
private
Integer
repayType
;
@NotBlank
private
String
name
;
@NotBlank
private
String
phone
;
@NotBlank
private
String
idNo
;
@NotBlank
private
String
repayStatus
;
@NotNull
private
Integer
userId
;
}
src/main/java/cn/quantgroup/customer/rest/param/vcc/UserPreRepayInfoQuery.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
rest
.
param
.
vcc
;
import
lombok.Data
;
import
javax.validation.constraints.NotNull
;
@Data
public
class
UserPreRepayInfoQuery
{
private
String
userId
;
private
String
phone
;
private
String
billId
;
private
String
orderNo
;
private
Integer
approvalStatus
;
/**
* 1.月还账单 2.账单分期 3.订单分期
*/
@NotNull
private
Integer
repayType
;
//当前页数
@NotNull
private
Integer
pageIndex
;
//默认每页条数
@NotNull
private
Integer
pageSize
;
}
src/main/java/cn/quantgroup/customer/rest/vo/vcc/QueryPreOfflineRepayVo.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
rest
.
vo
.
vcc
;
import
lombok.Data
;
import
java.math.BigDecimal
;
@Data
public
class
QueryPreOfflineRepayVo
{
private
String
uniqueId
;
private
String
name
;
private
String
phone
;
private
String
idNo
;
private
String
installTime
;
private
Integer
installTerm
;
private
Integer
currTerm
;
private
BigDecimal
currBall
;
private
BigDecimal
settleAmount
;
private
String
repayStatus
;
private
String
repayStatusName
;
private
String
billTime
;
private
String
repayTime
;
private
String
serialNo
;
private
Integer
approvalStatus
;
private
Integer
userId
;
}
src/main/java/cn/quantgroup/customer/rest/vo/vcc/QuerySubmitRecordVo.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
rest
.
vo
.
vcc
;
import
cn.quantgroup.customer.entity.OfflineRepaySubmitRecord
;
import
lombok.Data
;
@Data
public
class
QuerySubmitRecordVo
extends
OfflineRepaySubmitRecord
{
private
static
final
long
serialVersionUID
=
-
1359026440976090642L
;
private
String
repayStatusName
;
private
String
approvalStatusName
;
}
src/main/java/cn/quantgroup/customer/service/IFastDFSService.java
View file @
fcb47335
...
@@ -62,4 +62,13 @@ public interface IFastDFSService {
...
@@ -62,4 +62,13 @@ public interface IFastDFSService {
* @throws IOException
* @throws IOException
*/
*/
byte
[]
downloadFile
(
String
path
)
throws
IOException
;
byte
[]
downloadFile
(
String
path
)
throws
IOException
;
/**
* 转成一个临时可用的url
*
* @param path
* @return
* @throws IOException
*/
String
toUrl
(
String
path
)
throws
IOException
;
}
}
src/main/java/cn/quantgroup/customer/service/IVccService.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
service
;
import
cn.quantgroup.customer.rest.param.vcc.OfflineRepaySubmitParam
;
import
cn.quantgroup.customer.rest.param.vcc.UserPreRepayInfoQuery
;
import
cn.quantgroup.customer.rest.vo.JsonResult
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.util.Map
;
public
interface
IVccService
{
JsonResult
queryPage
(
UserPreRepayInfoQuery
query
)
throws
Exception
;
JsonResult
queryRepayCalDetail
(
String
uniqueId
,
Integer
repayType
)
throws
Exception
;
void
saveSubmitRecord
(
OfflineRepaySubmitParam
param
,
String
token
)
throws
Exception
;
OfflineRepaySubmitParam
approvalQuery
(
String
serialNo
)
throws
Exception
;
JsonResult
queryApprovalRecord
(
String
serialNo
)
throws
Exception
;
void
approvalResult
(
String
serialNo
,
String
remark
,
Integer
status
,
String
token
)
throws
Exception
;
Map
<
String
,
String
>
fileUpload
(
MultipartFile
file
)
throws
Exception
;
JsonResult
queryApplyRecord
(
UserPreRepayInfoQuery
query
)
throws
Exception
;
void
saveApprovalRecord
(
String
serialNo
,
String
remark
,
Integer
status
,
String
token
)
throws
Exception
;
}
src/main/java/cn/quantgroup/customer/service/ftp/AbstractFtpService.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
service
.
ftp
;
import
cn.quantgroup.customer.exception.BusinessException
;
import
cn.quantgroup.customer.model.ftp.FileInfo
;
import
cn.quantgroup.customer.model.ftp.ServerInfo
;
import
com.jcraft.jsch.*
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.exception.ExceptionUtils
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.FileNotFoundException
;
import
java.io.InputStream
;
import
java.nio.charset.Charset
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Properties
;
import
java.util.Vector
;
import
static
com
.
jcraft
.
jsch
.
ChannelSftp
.
SSH_FX_NO_SUCH_FILE
;
@Slf4j
public
class
AbstractFtpService
implements
IFtpService
{
private
static
final
int
SO_TIME_OUT
=
60
*
1000
;
// 超时时间
private
static
final
int
TIME_OUT
=
15
*
1000
;
@Override
public
Object
send
(
Object
request
)
{
return
null
;
}
@Override
public
boolean
send
(
FileInfo
fileInfo
,
ServerInfo
serverInfo
,
int
retryTime
)
{
String
path
=
fileInfo
.
getFilePath
();
byte
[]
fileBytes
=
fileInfo
.
getFileBytes
();
String
fileName
=
fileInfo
.
getFileName
();
if
(
StringUtils
.
isBlank
(
fileName
))
{
throw
new
RuntimeException
(
"文件名不能为空"
);
}
if
(
fileBytes
==
null
)
{
throw
new
RuntimeException
(
"文件内容不能为空"
);
}
log
.
info
(
"AbstractFtpService send fileName={}"
,
fileName
);
JSch
jsch
=
null
;
Session
session
=
null
;
Channel
channel
=
null
;
ChannelSftp
channelSftp
=
null
;
/**
* 方法返回值
*/
boolean
result
=
Boolean
.
FALSE
;
try
{
jsch
=
new
JSch
();
session
=
jsch
.
getSession
(
serverInfo
.
getUsername
(),
serverInfo
.
getHost
(),
serverInfo
.
getPort
());
session
.
setPassword
(
serverInfo
.
getPassword
().
getBytes
(
Charset
.
forName
(
"ISO-8859-1"
)));
Properties
config
=
new
Properties
();
config
.
put
(
"StrictHostKeyChecking"
,
"no"
);
session
.
setConfig
(
config
);
session
.
setTimeout
(
SO_TIME_OUT
);
log
.
info
(
"连接SFTP服务器host={},port={}"
,
serverInfo
.
getHost
(),
serverInfo
.
getPort
());
session
.
connect
(
TIME_OUT
);
channel
=
session
.
openChannel
(
"sftp"
);
channel
.
connect
();
channelSftp
=
(
ChannelSftp
)
channel
;
log
.
info
(
"SFTPclient打开channel..."
);
InputStream
input
=
null
;
if
(!
session
.
isConnected
()
||
!
channelSftp
.
isConnected
())
{
log
.
error
(
"SFTPchannel已经关闭"
);
throw
new
BusinessException
(
"SFTPchannel已经关闭"
);
}
// 目录不存在则创建
SftpATTRS
exist
=
null
;
try
{
exist
=
channelSftp
.
lstat
(
serverInfo
.
getDirectory
().
concat
(
path
));
}
catch
(
SftpException
e
)
{
log
.
info
(
"路径不存在{},exist={}"
,
serverInfo
.
getDirectory
().
concat
(
path
),
exist
);
}
if
(
exist
==
null
&&
StringUtils
.
isNotBlank
(
path
))
{
path
=
serverInfo
.
getDirectory
().
concat
(
path
);
createPath
(
path
,
channelSftp
);
}
else
if
(
StringUtils
.
isBlank
(
path
))
{
path
=
serverInfo
.
getDirectory
();
}
else
{
path
=
serverInfo
.
getDirectory
().
concat
(
path
);
}
log
.
info
(
"SFTP.client.切换到目录={}"
,
path
);
channelSftp
.
cd
(
path
);
log
.
info
(
"SFTP.client.切换到目录成功={}"
,
path
);
input
=
new
ByteArrayInputStream
(
fileBytes
);
// 重试标上传志位
boolean
retry
=
Boolean
.
TRUE
;
int
alreadyTryTime
=
0
;
log
.
info
(
"开始上传文件"
);
// 发生异常,重试三次
while
(
retry
&&
alreadyTryTime
<=
retryTime
)
{
try
{
channelSftp
.
put
(
input
,
fileName
);
log
.
info
(
"SFTP.client.上传成功 目录={} 文件名={}"
,
path
,
fileName
);
result
=
Boolean
.
TRUE
;
retry
=
Boolean
.
FALSE
;
}
catch
(
Exception
e
)
{
log
.
error
(
"SFTP文件上传失败 filename:{},alreadyTryTime:{},e:{}"
,
fileName
,
alreadyTryTime
,
e
);
try
{
Thread
.
sleep
(
300
);
}
catch
(
InterruptedException
interruptedException
)
{
}
alreadyTryTime
++;
}
}
if
(!
result
)
{
throw
new
BusinessException
(
"SFTP服务器异常!"
);
}
if
(
channelSftp
!=
null
)
{
channelSftp
.
disconnect
();
}
if
(
channel
!=
null
)
{
channel
.
disconnect
();
}
if
(
session
!=
null
)
{
session
.
disconnect
();
}
}
catch
(
JSchException
e
)
{
log
.
error
(
"JSchException fileName={},e={}"
,
fileName
,
ExceptionUtils
.
getStackTrace
(
e
));
throw
new
BusinessException
(
"SFTP创建连接失败, 信息="
+
e
);
}
catch
(
SftpException
e
)
{
log
.
error
(
"SftpException fileName={},e={}"
,
fileName
,
ExceptionUtils
.
getStackTrace
(
e
));
throw
new
BusinessException
(
"SFTP.client.操作失败"
);
}
return
result
;
}
protected
void
createPath
(
String
path
,
ChannelSftp
channelSftp
)
throws
SftpException
{
String
[]
folders
=
path
.
split
(
"/"
);
for
(
String
folder
:
folders
)
{
if
(
folder
.
length
()
>
0
)
{
try
{
channelSftp
.
cd
(
folder
);
}
catch
(
SftpException
e
)
{
try
{
channelSftp
.
mkdir
(
folder
);
}
catch
(
SftpException
e1
)
{
log
.
info
(
"创建失败,path:{}, exception:{}"
,
path
,
ExceptionUtils
.
getStackTrace
(
e1
));
}
channelSftp
.
cd
(
folder
);
}
}
}
}
@Override
public
byte
[]
down
(
String
fullName
,
ServerInfo
serverInfo
,
int
retryTime
)
throws
Exception
{
ByteArrayOutputStream
fileOutputStream
=
new
ByteArrayOutputStream
();
JSch
jsch
;
Session
session
=
null
;
Channel
channel
=
null
;
ChannelSftp
channelSftp
=
null
;
try
{
jsch
=
new
JSch
();
session
=
jsch
.
getSession
(
serverInfo
.
getUsername
(),
serverInfo
.
getHost
(),
serverInfo
.
getPort
());
session
.
setPassword
(
serverInfo
.
getPassword
().
getBytes
(
Charset
.
forName
(
"ISO-8859-1"
)));
Properties
config
=
new
Properties
();
config
.
put
(
"StrictHostKeyChecking"
,
"no"
);
session
.
setConfig
(
config
);
session
.
setTimeout
(
SO_TIME_OUT
);
log
.
info
(
"连接 SFTP 服务器 "
+
serverInfo
.
getHost
()
+
":"
+
serverInfo
.
getPort
());
session
.
connect
(
TIME_OUT
);
channel
=
session
.
openChannel
(
"sftp"
);
channel
.
connect
();
channelSftp
=
(
ChannelSftp
)
channel
;
log
.
info
(
"SFTP client 打开 channel ..."
);
if
(
channelSftp
==
null
||
session
==
null
||
!
session
.
isConnected
()
||
!
channelSftp
.
isConnected
())
{
log
.
warn
(
"SFTP channel 已经关闭"
);
throw
new
BusinessException
(
"SFTP channel 已经关闭"
);
}
channelSftp
.
get
(
fullName
,
fileOutputStream
);
byte
[]
data
=
fileOutputStream
.
toByteArray
();
if
(
data
==
null
||
data
.
length
<
2
)
{
log
.
warn
(
"SFTP.client.下载回来的文件长度不对!文件名={}"
,
fullName
);
return
null
;
}
log
.
info
(
"SFTP.client.下载成功 文件名={}"
,
fullName
);
return
data
;
}
catch
(
JSchException
e
)
{
log
.
warn
(
"SFTP.client.创建连接失败"
);
throw
new
BusinessException
(
"SFTP创建连接失败, 信息="
+
e
);
}
catch
(
SftpException
e
)
{
log
.
warn
(
"SFTP.client.操作失败, 信息exception="
,
e
);
if
(
e
.
id
==
SSH_FX_NO_SUCH_FILE
)
{
throw
new
FileNotFoundException
(
"file not found "
+
fullName
);
}
throw
new
BusinessException
(
"SFTP.client.操作失败"
);
}
finally
{
if
(
channelSftp
!=
null
)
{
channelSftp
.
disconnect
();
}
if
(
channel
!=
null
)
{
channel
.
disconnect
();
}
if
(
session
!=
null
)
{
session
.
disconnect
();
}
}
}
@Override
public
List
<
String
>
listDirectory
(
ServerInfo
serverInfo
)
throws
Exception
{
JSch
jsch
;
Session
session
=
null
;
Channel
channel
=
null
;
ChannelSftp
channelSftp
=
null
;
try
{
jsch
=
new
JSch
();
session
=
jsch
.
getSession
(
serverInfo
.
getUsername
(),
serverInfo
.
getHost
(),
serverInfo
.
getPort
());
session
.
setPassword
(
serverInfo
.
getPassword
().
getBytes
(
Charset
.
forName
(
"ISO-8859-1"
)));
Properties
config
=
new
Properties
();
config
.
put
(
"StrictHostKeyChecking"
,
"no"
);
session
.
setConfig
(
config
);
session
.
setTimeout
(
SO_TIME_OUT
);
log
.
info
(
"连接 SFTP 服务器 "
+
serverInfo
.
getHost
()
+
":"
+
serverInfo
.
getPort
());
session
.
connect
(
TIME_OUT
);
channel
=
session
.
openChannel
(
"sftp"
);
channel
.
connect
();
channelSftp
=
(
ChannelSftp
)
channel
;
log
.
info
(
"SFTP client 打开 channel ..."
);
if
(
channelSftp
==
null
||
session
==
null
||
!
session
.
isConnected
()
||
!
channelSftp
.
isConnected
())
{
log
.
warn
(
"SFTP channel 已经关闭"
);
throw
new
BusinessException
(
"SFTP channel 已经关闭"
);
}
List
<
String
>
fileNameList
=
new
ArrayList
<>();
Vector
<
ChannelSftp
.
LsEntry
>
fileNameVector
=
channelSftp
.
ls
(
serverInfo
.
getDirectory
());
for
(
ChannelSftp
.
LsEntry
lsEntry
:
fileNameVector
){
if
(
lsEntry
.
getFilename
().
equals
(
"."
)
||
lsEntry
.
getFilename
().
equals
(
".."
)){
continue
;
}
fileNameList
.
add
(
lsEntry
.
getFilename
());
}
return
fileNameList
;
}
catch
(
JSchException
e
)
{
log
.
warn
(
"SFTP.client.创建连接失败"
);
throw
new
BusinessException
(
"SFTP创建连接失败, 信息={}"
+
e
);
}
catch
(
SftpException
e
)
{
log
.
warn
(
"SFTP.client.操作失败, 信息exception="
,
e
);
if
(
e
.
id
==
SSH_FX_NO_SUCH_FILE
)
{
throw
new
FileNotFoundException
(
"directory not found "
+
serverInfo
.
getDirectory
());
}
throw
new
BusinessException
(
"SFTP.client.操作失败"
);
}
finally
{
if
(
channelSftp
!=
null
)
{
channelSftp
.
disconnect
();
}
if
(
channel
!=
null
)
{
channel
.
disconnect
();
}
if
(
session
!=
null
)
{
session
.
disconnect
();
}
}
}
}
src/main/java/cn/quantgroup/customer/service/ftp/CustomerSftpServiceImpl.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
service
.
ftp
;
import
cn.quantgroup.customer.model.ftp.FileInfo
;
import
cn.quantgroup.customer.model.ftp.ServerInfo
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.exception.ExceptionUtils
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
java.io.IOException
;
import
java.util.Map
;
/**
* @author yexiong.wang
* @date 2022/02/27
*/
@Slf4j
@Service
(
"CustomerSftpServiceImpl"
)
public
class
CustomerSftpServiceImpl
extends
AbstractFtpService
implements
IFtpService
{
//由于原定使用的没有使用,先直接给定默认值1
@Value
(
"${customer.sftp.user:1}"
)
private
String
username
;
@Value
(
"${customer.sftp.password:1}"
)
private
String
password
;
@Value
(
"${customer.sftp.host:1}"
)
private
String
host
;
@Value
(
"${customer.sftp.directory:1}"
)
private
String
directory
;
@Value
(
"${customer.sftp.port:1}"
)
private
int
port
;
/**
* @param request 请求参数对象
* @param retryTime 上传失败重试次数
* @return ture:上传成功,false:上传失败
* @throws Exception
*/
@Override
public
Boolean
send
(
Object
request
,
int
retryTime
)
throws
Exception
{
String
fileName
=
""
;
String
path
=
""
;
byte
[]
fileBytes
=
null
;
if
(
request
instanceof
Map
)
{
fileName
=
(
String
)
((
Map
)
request
).
get
(
"fileName"
);
fileBytes
=
(
byte
[])
((
Map
)
request
).
get
(
"fileBytes"
);
path
=
(
String
)
((
Map
)
request
).
get
(
"filePath"
);
}
if
(
StringUtils
.
isBlank
(
fileName
))
{
throw
new
RuntimeException
(
"文件名不能为空"
);
}
if
(
fileBytes
==
null
)
{
throw
new
RuntimeException
(
"文件内容不能为空"
);
}
log
.
info
(
"客服系统上传sftp, fileName:{}, path:{}"
,
fileName
,
path
);
FileInfo
fileInfo
=
new
FileInfo
(
fileName
,
fileBytes
,
path
);
ServerInfo
serverInfo
=
ServerInfo
.
builder
()
.
username
(
username
)
.
directory
(
directory
)
.
host
(
host
)
.
password
(
password
)
.
port
(
port
)
.
build
();
send
(
fileInfo
,
serverInfo
,
3
);
return
null
;
}
@Override
public
byte
[]
down
(
String
fileName
)
throws
IOException
{
ServerInfo
serverInfo
=
ServerInfo
.
builder
()
.
username
(
username
).
directory
(
directory
)
.
host
(
host
).
password
(
password
)
.
port
(
port
)
.
build
();
byte
[]
result
;
try
{
fileName
=
directory
.
concat
(
fileName
);
result
=
down
(
fileName
,
serverInfo
,
1
);
}
catch
(
IOException
ioEx
)
{
log
.
warn
(
"客服系统下载文件,出现异常,fileName:{}, ex:{}"
,
fileName
,
ExceptionUtils
.
getStackTrace
(
ioEx
));
throw
ioEx
;
}
catch
(
Exception
e
)
{
log
.
warn
(
"客服系统下载文件,出现异常,fileName:{}, ex:{}"
,
fileName
,
ExceptionUtils
.
getStackTrace
(
e
));
throw
new
IOException
(
"下载未知异常"
);
}
if
(
result
==
null
)
{
throw
new
IOException
(
"文件为空"
);
}
return
result
;
}
}
src/main/java/cn/quantgroup/customer/service/ftp/IFtpService.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
service
.
ftp
;
import
cn.quantgroup.customer.model.ftp.FileInfo
;
import
cn.quantgroup.customer.model.ftp.ServerInfo
;
import
org.apache.commons.lang3.NotImplementedException
;
import
java.io.IOException
;
import
java.util.List
;
public
interface
IFtpService
{
Object
send
(
Object
request
);
/**
* @param request 请求参数对象
* @param retryTime 上传失败重试次数
* @return ture:上传成功,false:上传失败
* @throws Exception
*/
default
Boolean
send
(
Object
request
,
int
retryTime
)
throws
Exception
{
throw
new
NotImplementedException
(
"send(Object request,int retryTime)方法没有实现!"
);
}
/**
* 文件下载
*
* @param fileName
* @return
* @throws IOException
*/
default
byte
[]
down
(
String
fileName
)
throws
IOException
{
throw
new
NotImplementedException
(
"文件下载没有实现!"
);
}
/**
* SFTP 方式文件上传
*
* @param fileInfo 文件信息
* @param serverInfo SFTP服务器信息
* @param retryTime 重试次数
* @return
* @throws Exception
*/
default
boolean
send
(
FileInfo
fileInfo
,
ServerInfo
serverInfo
,
int
retryTime
)
throws
Exception
{
throw
new
NotImplementedException
(
"send没有实现!"
);
}
/**
* 文件下载
*
* @param fullName 路径文件名称
* @param serverInfo 服务器信息
* @param retryTime 重试次数
* @return
* @throws Exception
*/
default
byte
[]
down
(
String
fullName
,
ServerInfo
serverInfo
,
int
retryTime
)
throws
Exception
{
throw
new
NotImplementedException
(
"文件下载没有实现!"
);
}
/**
* 获取文件名列表
*
* @param serverInfo
* @return
* @throws Exception
*/
default
List
<
String
>
listDirectory
(
ServerInfo
serverInfo
)
throws
Exception
{
throw
new
NotImplementedException
(
"查看目录下的所有文件没有实现!"
);
}
}
src/main/java/cn/quantgroup/customer/service/impl/FastDFSServiceImpl.java
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
service
.
impl
;
package
cn
.
quantgroup
.
customer
.
service
.
impl
;
import
cn.quantgroup.customer.service.IFastDFSService
;
import
cn.quantgroup.customer.service.IFastDFSService
;
import
cn.quantgroup.customer.util.ProtoCommon
;
import
com.github.tobato.fastdfs.domain.StorePath
;
import
com.github.tobato.fastdfs.domain.StorePath
;
import
com.github.tobato.fastdfs.proto.storage.DownloadByteArray
;
import
com.github.tobato.fastdfs.proto.storage.DownloadByteArray
;
import
com.github.tobato.fastdfs.service.FastFileStorageClient
;
import
com.github.tobato.fastdfs.service.FastFileStorageClient
;
...
@@ -146,4 +147,31 @@ public class FastDFSServiceImpl implements IFastDFSService {
...
@@ -146,4 +147,31 @@ public class FastDFSServiceImpl implements IFastDFSService {
});
});
return
bytes
;
return
bytes
;
}
}
/**
* 转成一个临时可用的url
* @param path
* @return
* @throws IOException
*/
@Override
public
String
toUrl
(
String
path
)
throws
IOException
{
if
(
StringUtils
.
isBlank
(
path
))
{
return
null
;
}
String
fileName
=
path
;
if
(
fileName
.
indexOf
(
"/M"
)
>
0
)
{
fileName
=
fileName
.
substring
(
fileName
.
indexOf
(
"/M"
)
+
1
);
}
int
lts
=
(
int
)
(
System
.
currentTimeMillis
()
/
1000
);
// 初始化secret_key
try
{
String
token
=
ProtoCommon
.
getToken
(
fileName
,
lts
,
secretKey
);
return
fastDfsHttp
+
"/"
+
path
+
"?token="
+
token
+
"&ts="
+
lts
;
}
catch
(
Exception
e
)
{
log
.
warn
(
"生成FastDFS下载链接失败:path:{},"
,
path
,
e
);
throw
new
IOException
(
"生成下载链接失败"
);
}
}
}
}
src/main/java/cn/quantgroup/customer/service/impl/VccServiceImpl.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
service
.
impl
;
import
cn.quantgroup.customer.entity.OfflineRepayOperateRecord
;
import
cn.quantgroup.customer.entity.OfflineRepaySubmitRecord
;
import
cn.quantgroup.customer.entity.OpUser
;
import
cn.quantgroup.customer.entity.QOfflineRepaySubmitRecord
;
import
cn.quantgroup.customer.enums.ApprovalStatus
;
import
cn.quantgroup.customer.enums.VccRepayStatusEnum
;
import
cn.quantgroup.customer.repo.OfflineRepayOperateRecordRepo
;
import
cn.quantgroup.customer.repo.OfflineRepaySubmitRecordRepo
;
import
cn.quantgroup.customer.rest.param.vcc.ApplyBill
;
import
cn.quantgroup.customer.rest.param.vcc.OfflineRepaySubmitParam
;
import
cn.quantgroup.customer.rest.param.vcc.UserPreRepayInfoQuery
;
import
cn.quantgroup.customer.rest.vo.JsonResult
;
import
cn.quantgroup.customer.rest.vo.vcc.QueryPreOfflineRepayVo
;
import
cn.quantgroup.customer.rest.vo.vcc.QuerySubmitRecordVo
;
import
cn.quantgroup.customer.service.IFastDFSService
;
import
cn.quantgroup.customer.service.IOpSystemService
;
import
cn.quantgroup.customer.service.IVccService
;
import
cn.quantgroup.customer.service.ftp.IFtpService
;
import
cn.quantgroup.customer.service.http.IHttpService
;
import
cn.quantgroup.customer.util.IdUtil
;
import
cn.quantgroup.user.retbean.XUser
;
import
cn.quantgroup.user.vo.UserSysResult
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.google.common.reflect.TypeToken
;
import
com.google.gson.Gson
;
import
com.querydsl.core.types.dsl.BooleanExpression
;
import
com.querydsl.core.types.dsl.Expressions
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.PageRequest
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.annotation.Resource
;
import
javax.transaction.Transactional
;
import
java.time.LocalDate
;
import
java.time.format.DateTimeFormatter
;
import
java.util.*
;
import
java.util.List
;
@Slf4j
@Service
public
class
VccServiceImpl
implements
IVccService
{
@Value
(
"${vcc-talos.http}"
)
private
String
talosHttp
;
@Autowired
private
IHttpService
httpService
;
@Resource
private
OfflineRepaySubmitRecordRepo
offlineRepaySubmitRecordRepo
;
@Resource
private
OfflineRepayOperateRecordRepo
offlineRepayOperateRecordRepo
;
@Autowired
private
IOpSystemService
IOpSystemService
;
@Autowired
private
IFastDFSService
fastDfsService
;
@Autowired
private
IFtpService
ftpService
;
@Autowired
private
UserSdkImpl
userSdk
;
@Override
public
JsonResult
queryPage
(
UserPreRepayInfoQuery
query
)
throws
Exception
{
String
url
=
talosHttp
+
"/vcc/offline_pre_repay/query_page"
;
JSONObject
param
=
JSONObject
.
parseObject
(
JSON
.
toJSONString
(
query
));
log
.
info
(
"queryPage | 开始请求talos获取预还款的详情,param={}"
,
param
);
String
post
=
httpService
.
post
(
url
,
param
);
log
.
info
(
"queryPage | 请求talos结束,param={},result={}"
,
param
,
post
);
if
(
StringUtils
.
isBlank
(
post
)){
log
.
error
(
"queryPage | 请求talos异常,返回值为空,param={}"
,
query
);
return
JsonResult
.
buildErrorStateResult
(
"请求talos获取详情异常:没有请求通"
);
}
JSONObject
jsonObject
=
JSONObject
.
parseObject
(
post
);
if
(!
"0000"
.
equals
(
jsonObject
.
getString
(
"code"
))
||
!
"0000"
.
equals
(
jsonObject
.
getString
(
"businessCode"
))){
log
.
error
(
"queryPage | talos没有正确查询出结果:"
+
jsonObject
.
getString
(
"msg"
));
return
JsonResult
.
buildErrorStateResult
(
"talos没有正确查询出结果:"
+
jsonObject
.
getString
(
"msg"
));
}
JSONObject
data
=
jsonObject
.
getJSONObject
(
"data"
);
JSONArray
list
=
data
.
getJSONArray
(
"list"
);
List
<
QueryPreOfflineRepayVo
>
voList
=
new
Gson
().
fromJson
(
list
.
toString
(),
new
TypeToken
<
List
<
QueryPreOfflineRepayVo
>>()
{
}.
getType
());
for
(
int
i
=
0
;
i
<
voList
.
size
();
i
++){
if
(
1
==
query
.
getRepayType
()){
ApplyBill
applyBill
=
new
ApplyBill
();
applyBill
.
setBillId
(
Long
.
parseLong
(
voList
.
get
(
i
).
getUniqueId
()));
applyBill
.
setAmount
(
voList
.
get
(
i
).
getCurrBall
());
List
<
OfflineRepaySubmitRecord
>
byUserIdEqualsAndRepayTypeEquals
=
offlineRepaySubmitRecordRepo
.
findByUserIdEqualsAndRepayTypeEquals
(
voList
.
get
(
i
).
getUserId
(),
1
);
if
(!
CollectionUtils
.
isEmpty
(
byUserIdEqualsAndRepayTypeEquals
)){
for
(
OfflineRepaySubmitRecord
record:
byUserIdEqualsAndRepayTypeEquals
){
List
<
ApplyBill
>
billList
=
new
Gson
().
fromJson
(
record
.
getBills
(),
new
TypeToken
<
List
<
ApplyBill
>>()
{
}.
getType
());
log
.
info
(
"billList={},applyBill={}"
,
billList
,
applyBill
);
if
(
billList
.
contains
(
applyBill
)){
log
.
info
(
"发现已经提交过了,补充流水号前:voList={}"
,
voList
);
voList
.
get
(
i
).
setSerialNo
(
record
.
getSerialNo
());
voList
.
get
(
i
).
setApprovalStatus
(
record
.
getApprovalStatus
());
log
.
info
(
"发现已经提交过了,补充流水号后:voList={}"
,
voList
);
break
;
}
}
}
}
else
{
OfflineRepaySubmitRecord
firstByUniqueIdEquals
=
offlineRepaySubmitRecordRepo
.
findFirstByUniqueIdEquals
(
voList
.
get
(
i
).
getUniqueId
());
if
(
Objects
.
nonNull
(
firstByUniqueIdEquals
)){
voList
.
get
(
i
).
setSerialNo
(
firstByUniqueIdEquals
.
getSerialNo
());
voList
.
get
(
i
).
setApprovalStatus
(
firstByUniqueIdEquals
.
getApprovalStatus
());
}
}
}
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"count"
,
data
.
get
(
"count"
));
map
.
put
(
"type"
,
data
.
get
(
"type"
));
map
.
put
(
"list"
,
voList
);
log
.
info
(
"voList={}"
,
voList
);
return
JsonResult
.
buildSuccessResult
(
"请求成功"
,
map
);
}
@Override
public
JsonResult
queryRepayCalDetail
(
String
uniqueId
,
Integer
repayType
)
throws
Exception
{
String
url
=
talosHttp
+
"/vcc/offline_pre_repay/detail?uniqueId="
+
uniqueId
+
"&repayType="
+
repayType
;
log
.
info
(
"queryRepayCalDetail | 开始请求talos,url={}"
,
url
);
String
get
=
httpService
.
get
(
url
);
log
.
info
(
"queryRepayCalDetail | 请求talos结束,get={}"
,
get
);
if
(
StringUtils
.
isBlank
(
get
)){
log
.
error
(
"queryRepayCalDetail | 请求talos异常,返回值为空"
);
return
JsonResult
.
buildErrorStateResult
(
"请求talos获取详情异常:没有请求通"
);
}
JSONObject
jsonObject
=
JSONObject
.
parseObject
(
get
);
if
(!
"0000"
.
equals
(
jsonObject
.
getString
(
"code"
))
||
!
"0000"
.
equals
(
jsonObject
.
getString
(
"businessCode"
))){
log
.
error
(
"queryRepayCalDetail | talos没有正确查询出结果:"
+
jsonObject
.
getString
(
"msg"
));
return
JsonResult
.
buildErrorStateResult
(
"talos没有正确查询出结果:"
+
jsonObject
.
getString
(
"msg"
));
}
JSONObject
data
=
jsonObject
.
getJSONObject
(
"data"
);
return
JsonResult
.
buildSuccessResult
(
"请求成功"
,
data
);
}
@Override
@Transactional
public
void
saveSubmitRecord
(
OfflineRepaySubmitParam
param
,
String
token
)
throws
Exception
{
String
serialNo
=
IdUtil
.
generateSequenceNo
();
if
(
1
==
param
.
getRepayType
()){
//月还账单
List
<
ApplyBill
>
list
=
param
.
getList
();
List
<
OfflineRepaySubmitRecord
>
byUserIdEqualsAndRepayTypeEquals
=
offlineRepaySubmitRecordRepo
.
findByUserIdEqualsAndRepayTypeEqualsAndApprovalStatusNot
(
param
.
getUserId
(),
1
,
2
);
if
(!
CollectionUtils
.
isEmpty
(
byUserIdEqualsAndRepayTypeEquals
)){
for
(
OfflineRepaySubmitRecord
record:
byUserIdEqualsAndRepayTypeEquals
){
List
<
ApplyBill
>
billList
=
new
Gson
().
fromJson
(
record
.
getBills
(),
new
TypeToken
<
List
<
ApplyBill
>>()
{
}.
getType
());
if
(!
Collections
.
disjoint
(
list
,
billList
)){
log
.
error
(
"saveSubmitRecord | 提交时发现已经提交过了,请确认,newBills={},existBills={}"
,
list
.
toString
(),
billList
.
toString
());
throw
new
Exception
(
"提交时发现已经提交过了,请确认,newBills="
+
list
.
toString
()+
",existBills="
+
billList
.
toString
());
}
}
}
OfflineRepaySubmitRecord
record
=
new
OfflineRepaySubmitRecord
();
BeanUtils
.
copyProperties
(
param
,
record
);
record
.
setSerialNo
(
serialNo
);
record
.
setBills
(
JSONObject
.
toJSONString
(
list
));
String
replace
=
param
.
getCredentialsAddress
().
toString
().
replace
(
"["
,
""
).
replace
(
"]"
,
""
);
record
.
setCredentialsAddress
(
replace
);
record
.
setApprovalStatus
(
0
);
offlineRepaySubmitRecordRepo
.
save
(
record
);
}
else
{
OfflineRepaySubmitRecord
firstByUniqueIdEquals
=
offlineRepaySubmitRecordRepo
.
findFirstByUniqueIdEqualsAndApprovalStatusNot
(
param
.
getUniqueId
(),
2
);
if
(
Objects
.
nonNull
(
firstByUniqueIdEquals
)){
log
.
error
(
"saveSubmitRecord | 提交时发现已经提交过了,请确认,uniqueId={}"
,
param
.
getUniqueId
());
throw
new
Exception
(
"提交时发现已经提交过了,请确认,uniqueId="
+
param
.
getUniqueId
());
}
OfflineRepaySubmitRecord
record
=
new
OfflineRepaySubmitRecord
();
BeanUtils
.
copyProperties
(
param
,
record
);
record
.
setSerialNo
(
serialNo
);
String
replace
=
param
.
getCredentialsAddress
().
toString
().
replace
(
"["
,
""
).
replace
(
"]"
,
""
);
record
.
setCredentialsAddress
(
replace
);
record
.
setApprovalStatus
(
0
);
offlineRepaySubmitRecordRepo
.
save
(
record
);
}
//保存操作人记录
saveApprovalRecord
(
serialNo
,
""
,
0
,
token
);
}
@Override
public
OfflineRepaySubmitParam
approvalQuery
(
String
serialNo
)
throws
Exception
{
OfflineRepaySubmitRecord
bySerialNoEquals
=
offlineRepaySubmitRecordRepo
.
findBySerialNoEquals
(
serialNo
);
if
(
Objects
.
isNull
(
bySerialNoEquals
)){
log
.
error
(
"approvalQuery | 没有查询到这条申请记录,请确认:serialNo = {}"
,
serialNo
);
throw
new
Exception
(
"没有查询到这条申请记录,请确认:serialNo = "
+
serialNo
);
}
OfflineRepaySubmitParam
param
=
new
OfflineRepaySubmitParam
();
BeanUtils
.
copyProperties
(
bySerialNoEquals
,
param
);
List
<
ApplyBill
>
billList
=
new
Gson
().
fromJson
(
bySerialNoEquals
.
getBills
(),
new
TypeToken
<
List
<
ApplyBill
>>()
{
}.
getType
());
param
.
setList
(
billList
);
String
[]
split
=
bySerialNoEquals
.
getCredentialsAddress
().
split
(
","
);
List
<
String
>
list
=
Arrays
.
asList
(
split
);
// List<String> addressList = new ArrayList<>();
// for (String baseUrl:list){
//// String viewUrl = fastDfsService.toUrl(baseUrl);
//// addressList.add(viewUrl);
// byte[] down = ftpService.down(baseUrl);
// addressList.add(Base64.getEncoder().encodeToString(down));
// }
param
.
setCredentialsAddress
(
list
);
return
param
;
}
@Override
public
JsonResult
queryApprovalRecord
(
String
serialNo
)
throws
Exception
{
List
<
OfflineRepayOperateRecord
>
bySerialNoEquals
=
offlineRepayOperateRecordRepo
.
findBySerialNoEquals
(
serialNo
);
return
JsonResult
.
buildSuccessResult
(
"请求成功"
,
bySerialNoEquals
);
}
@Override
@Transactional
public
void
approvalResult
(
String
serialNo
,
String
remark
,
Integer
status
,
String
token
)
throws
Exception
{
OfflineRepaySubmitRecord
bySerialNoEquals
=
offlineRepaySubmitRecordRepo
.
findBySerialNoEqualsAndApprovalStatusEquals
(
serialNo
,
0
);
if
(
Objects
.
isNull
(
bySerialNoEquals
)){
log
.
error
(
"approvalQuery | 没有查询到这条申请记录,请确认:serialNo = {}"
,
serialNo
);
throw
new
Exception
(
"没有查询到这条申请记录,请确认:serialNo = "
+
serialNo
);
}
if
(
0
==
status
){
//审批拒绝
bySerialNoEquals
.
setApprovalStatus
(
2
);
offlineRepaySubmitRecordRepo
.
save
(
bySerialNoEquals
);
saveApprovalRecord
(
serialNo
,
remark
,
2
,
token
);
}
else
if
(
1
==
status
){
//审批通过
String
url
=
""
;
// String phone = bySerialNoEquals.getPhone();
// UserSysResult<XUser> userByPhoneNo = userSdk.getService().findUserByPhoneNo(phone);
// if (userByPhoneNo == null || !userByPhoneNo.isSuccess() || userByPhoneNo.getData() == null) {
// throw new RuntimeException("用户中心接口findUserDetailByPhone返回失败");
// }
if
(
1
==
bySerialNoEquals
.
getRepayType
()){
//月还账单
List
<
ApplyBill
>
billList
=
new
Gson
().
fromJson
(
bySerialNoEquals
.
getBills
(),
new
TypeToken
<
List
<
ApplyBill
>>()
{
}.
getType
());
StringBuilder
stringBuilder
=
new
StringBuilder
();
for
(
ApplyBill
applyBill:
billList
){
stringBuilder
.
append
(
applyBill
.
getBillId
()).
append
(
","
);
}
String
billNo
=
stringBuilder
.
substring
(
0
,
stringBuilder
.
lastIndexOf
(
","
));
url
=
talosHttp
+
"/vcc/repay/offlineRepay?userId="
+
bySerialNoEquals
.
getUserId
()
+
"&amount="
+
bySerialNoEquals
.
getAmount
()
+
"&billNo="
+
billNo
;
}
else
{
//提前结清
url
=
talosHttp
+
"/vcc/offline_pre_repay/repay?userId="
+
bySerialNoEquals
.
getUserId
()
+
"&amount="
+
bySerialNoEquals
.
getAmount
()
+
"&repayType="
+
bySerialNoEquals
.
getRepayType
()
+
"&uniqueId="
+
bySerialNoEquals
.
getUniqueId
();
}
log
.
info
(
"queryRepayCalDetail | 开始请求talos,url={}"
,
url
);
String
get
=
httpService
.
get
(
url
);
log
.
info
(
"queryRepayCalDetail | 请求talos结束,get={}"
,
get
);
if
(
StringUtils
.
isBlank
(
get
)){
log
.
error
(
"queryRepayCalDetail | 请求talos异常,返回值为空"
);
throw
new
Exception
(
"请求talos异常:没有请求通"
);
}
JSONObject
jsonObject
=
JSONObject
.
parseObject
(
get
);
if
(!
"0000"
.
equals
(
jsonObject
.
getString
(
"code"
))
||
!
"0000"
.
equals
(
jsonObject
.
getString
(
"businessCode"
))){
log
.
error
(
"queryRepayCalDetail | 请求talos处理失败,msg={}"
,
jsonObject
.
getString
(
"msg"
));
throw
new
Exception
(
"请求talos处理失败:"
+
jsonObject
.
getString
(
"msg"
));
}
bySerialNoEquals
.
setApprovalStatus
(
1
);
offlineRepaySubmitRecordRepo
.
save
(
bySerialNoEquals
);
saveApprovalRecord
(
serialNo
,
remark
,
1
,
token
);
}
}
@Override
public
Map
<
String
,
String
>
fileUpload
(
MultipartFile
file
)
throws
Exception
{
// String name = file.getOriginalFilename();
// log.info("fileUpload | filename={}",name);
// String substring = name.substring(name.lastIndexOf(".") + 1);
// String baseUrl = fastDfsService.uploadFile(file.getBytes(), substring);
// String viewUrl = fastDfsService.toUrl(baseUrl);
// Map<String,String> map = new HashMap<>();
// map.put("baseUrl",baseUrl);
// map.put("viewUrl",viewUrl);
// return map;
String
fileName
=
file
.
getOriginalFilename
();
byte
[]
bytes
=
file
.
getBytes
();
Map
<
String
,
Object
>
paramMap
=
new
HashMap
<>(
8
);
paramMap
.
put
(
"fileName"
,
fileName
);
paramMap
.
put
(
"fileBytes"
,
bytes
);
String
filePath
=
LocalDate
.
now
().
format
(
DateTimeFormatter
.
ofPattern
(
"yyyyMMdd"
))
+
"/"
;
paramMap
.
put
(
"filePath"
,
filePath
);
ftpService
.
send
(
paramMap
,
3
);
Map
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"base64"
,
Base64
.
getEncoder
().
encodeToString
(
bytes
));
map
.
put
(
"url"
,
filePath
+
fileName
);
return
map
;
}
@Override
public
JsonResult
queryApplyRecord
(
UserPreRepayInfoQuery
query
)
throws
Exception
{
BooleanExpression
booleanExpression
=
Expressions
.
asBoolean
(
true
).
isTrue
();
String
phone
=
""
;
if
(
StringUtils
.
isNotBlank
(
query
.
getUserId
())){
log
.
info
(
"userSdk={}"
,
userSdk
);
UserSysResult
<
XUser
>
userByUserId
=
userSdk
.
getService
().
findUserByUserId
(
Long
.
getLong
(
query
.
getUserId
()));
if
(
userByUserId
==
null
||
!
userByUserId
.
isSuccess
()
||
userByUserId
.
getData
()
==
null
)
{
log
.
info
(
"queryApplyRecord | 查询用户中心失败"
);
}
else
{
phone
=
userByUserId
.
getData
().
getPhoneNo
();
}
}
if
(
StringUtils
.
isNotBlank
(
query
.
getPhone
())){
phone
=
query
.
getPhone
();
}
if
(
StringUtils
.
isNotBlank
(
phone
)){
booleanExpression
=
booleanExpression
.
and
(
QOfflineRepaySubmitRecord
.
offlineRepaySubmitRecord
.
phone
.
eq
(
phone
));
}
if
(
query
.
getApprovalStatus
()
!=
null
){
booleanExpression
=
booleanExpression
.
and
(
QOfflineRepaySubmitRecord
.
offlineRepaySubmitRecord
.
approvalStatus
.
eq
(
query
.
getApprovalStatus
()));
}
if
(
query
.
getRepayType
()
!=
null
){
booleanExpression
=
booleanExpression
.
and
(
QOfflineRepaySubmitRecord
.
offlineRepaySubmitRecord
.
repayType
.
eq
(
query
.
getRepayType
()));
}
if
(
StringUtils
.
isNotBlank
(
query
.
getOrderNo
())){
booleanExpression
=
booleanExpression
.
and
(
QOfflineRepaySubmitRecord
.
offlineRepaySubmitRecord
.
uniqueId
.
eq
(
query
.
getOrderNo
()));
}
if
(
StringUtils
.
isNotBlank
(
query
.
getBillId
())){
if
(
1
==
query
.
getRepayType
()){
booleanExpression
=
booleanExpression
.
and
(
QOfflineRepaySubmitRecord
.
offlineRepaySubmitRecord
.
bills
.
contains
(
query
.
getBillId
()));
}
else
{
booleanExpression
=
booleanExpression
.
and
(
QOfflineRepaySubmitRecord
.
offlineRepaySubmitRecord
.
uniqueId
.
eq
(
query
.
getBillId
()));
}
}
long
count
=
offlineRepaySubmitRecordRepo
.
count
(
booleanExpression
);
int
offset
=
(
query
.
getPageIndex
()
-
1
)
*
query
.
getPageSize
();
Page
<
OfflineRepaySubmitRecord
>
plantPage
=
offlineRepaySubmitRecordRepo
.
findAll
(
booleanExpression
,
new
PageRequest
(
offset
,
query
.
getPageSize
()));
List
<
OfflineRepaySubmitRecord
>
content
=
plantPage
.
getContent
();
List
<
QuerySubmitRecordVo
>
submitRecordVoList
=
new
ArrayList
<>();
for
(
OfflineRepaySubmitRecord
record
:
content
){
QuerySubmitRecordVo
submitRecordVo
=
new
QuerySubmitRecordVo
();
BeanUtils
.
copyProperties
(
record
,
submitRecordVo
);
submitRecordVo
.
setRepayStatusName
(
VccRepayStatusEnum
.
getDescByValue
(
submitRecordVo
.
getRepayStatus
()));
submitRecordVo
.
setApprovalStatusName
(
ApprovalStatus
.
getDescByValue
(
submitRecordVo
.
getApprovalStatus
()));
if
(
1
==
submitRecordVo
.
getRepayType
())
{
//月还账单
List
<
ApplyBill
>
billList
=
new
Gson
().
fromJson
(
submitRecordVo
.
getBills
(),
new
TypeToken
<
List
<
ApplyBill
>>()
{
}.
getType
());
StringBuilder
stringBuilder
=
new
StringBuilder
();
for
(
ApplyBill
applyBill
:
billList
)
{
stringBuilder
.
append
(
applyBill
.
getBillId
()).
append
(
","
);
}
String
billNo
=
stringBuilder
.
substring
(
0
,
stringBuilder
.
lastIndexOf
(
","
));
submitRecordVo
.
setUniqueId
(
billNo
);
}
submitRecordVoList
.
add
(
submitRecordVo
);
}
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"count"
,
count
);
map
.
put
(
"type"
,
query
.
getRepayType
());
map
.
put
(
"list"
,
submitRecordVoList
);
return
JsonResult
.
buildSuccessResult
(
"请求成功"
,
map
);
}
@Override
public
void
saveApprovalRecord
(
String
serialNo
,
String
remark
,
Integer
status
,
String
token
)
throws
Exception
{
JsonResult
<
OpUser
>
opUserResult
=
IOpSystemService
.
findUserByToken
(
token
,
null
);
if
(
Objects
.
isNull
(
opUserResult
)
||
!
opUserResult
.
isSuccess
())
{
log
.
error
(
"根据token查询不到用户信息 token:{}"
,
token
);
return
;
}
else
{
OpUser
opUser
=
opUserResult
.
getData
();
OfflineRepayOperateRecord
record
=
new
OfflineRepayOperateRecord
();
record
.
setSerialNo
(
serialNo
);
record
.
setOperateAccount
(
opUser
.
getUser
());
record
.
setOperateName
(
opUser
.
getName
());
if
(
0
==
status
){
record
.
setOperateContent
(
"已提交"
);
}
else
if
(
1
==
status
){
record
.
setOperateContent
(
"审批通过"
);
}
else
if
(
2
==
status
){
record
.
setOperateContent
(
"审批拒绝"
);
}
record
.
setOperateTime
(
new
Date
());
record
.
setRemark
(
remark
);
offlineRepayOperateRecordRepo
.
save
(
record
);
}
}
}
src/main/java/cn/quantgroup/customer/util/IdUtil.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
util
;
import
org.apache.commons.lang3.StringUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.text.*
;
import
java.util.Calendar
;
public
class
IdUtil
{
/** .log */
private
final
static
Logger
logger
=
LoggerFactory
.
getLogger
(
IdUtil
.
class
);
/** The FieldPosition. */
private
static
final
FieldPosition
HELPER_POSITION
=
new
FieldPosition
(
0
);
/** This Format for format the data to special format. */
private
final
static
Format
dateFormat
=
new
SimpleDateFormat
(
"yyyyMMddHHmmss"
);
/** This Format for format the number to special format. */
private
final
static
NumberFormat
numberFormat
=
new
DecimalFormat
(
"000"
);
/** This int is the sequence number ,the default value is 0. */
private
static
int
seq
=
0
;
private
static
final
int
MAX
=
999
;
/**
* 时间格式生成序列
*
* @return String
*/
public
static
String
generateSequenceNo
()
{
return
generateSequenceNo
(
"Q"
);
}
/**
* 时间格式生成序列
*
* @return String
*/
public
static
synchronized
String
generateSequenceNo
(
String
prefix
)
{
Calendar
rightNow
=
Calendar
.
getInstance
();
StringBuffer
sb
=
new
StringBuffer
();
dateFormat
.
format
(
rightNow
.
getTime
(),
sb
,
HELPER_POSITION
);
numberFormat
.
format
(
seq
,
sb
,
HELPER_POSITION
);
if
(
seq
==
MAX
)
{
seq
=
0
;
}
else
{
seq
++;
}
if
(
StringUtils
.
isEmpty
(
prefix
)){
prefix
=
"C"
;
}
String
ip
=
IpAddrUtils
.
getHostIp
();
Integer
ipValue
=
Integer
.
parseInt
(
ip
.
split
(
"\\."
)[
ip
.
split
(
"\\."
).
length
-
1
]);
StringBuffer
ipStr
=
new
StringBuffer
();
numberFormat
.
format
(
ipValue
,
ipStr
,
HELPER_POSITION
);
String
idNo
=
prefix
+
sb
.
toString
()
+
ipStr
.
toString
();
logger
.
debug
(
"THE SQUENCE IS :"
+
idNo
);
return
idNo
;
}
public
static
void
main
(
String
[]
args
)
{
// for (int i = 0; i < 1000; i++) {
// System.out.println(generateSequenceNo());
// }
System
.
out
.
println
(
System
.
currentTimeMillis
());
//System.out.println(dateFormat.format(Calendar.getInstance().getTime().getTime(), new StringBuffer(), HELPER_POSITION));
}
}
src/main/java/cn/quantgroup/customer/util/IpAddrUtils.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
util
;
import
lombok.extern.slf4j.Slf4j
;
import
javax.servlet.http.HttpServletRequest
;
import
java.net.InetAddress
;
import
java.net.NetworkInterface
;
import
java.util.Enumeration
;
@Slf4j
public
class
IpAddrUtils
{
private
final
static
String
UNKNOWN
=
"unknown"
;
public
static
String
getIpAddr
(
HttpServletRequest
request
)
{
try
{
StringBuffer
sb
=
new
StringBuffer
();
Enumeration
<
String
>
er
=
request
.
getHeaderNames
();
while
(
er
.
hasMoreElements
())
{
String
name
=
er
.
nextElement
();
String
value
=
request
.
getHeader
(
name
);
sb
.
append
(
name
).
append
(
"="
).
append
(
value
).
append
(
";"
);
}
log
.
info
(
"获取请求Header: "
+
sb
.
toString
());
}
catch
(
Exception
e
)
{
log
.
error
(
"获取请求Header: "
+
e
.
getMessage
());
}
String
ip
=
request
.
getHeader
(
"X-Forwarded-For"
);
if
(
ip
!=
null
&&
ip
.
length
()
!=
0
&&
!
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
// 多次反向代理后会有多个ip值,第一个ip才是真实ip
if
(
ip
.
contains
(
","
))
{
ip
=
ip
.
split
(
","
)[
0
];
}
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"Proxy-Client-IP"
);
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"WL-Proxy-Client-IP"
);
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"HTTP_CLIENT_IP"
);
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"HTTP_X_FORWARDED_FOR"
);
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"X-Real-IP"
);
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getRemoteAddr
();
}
return
ip
;
}
public
static
String
getHostIp
()
{
String
sIP
=
""
;
InetAddress
ip
=
null
;
try
{
boolean
bFindIP
=
false
;
Enumeration
<
NetworkInterface
>
netInterfaces
=
NetworkInterface
.
getNetworkInterfaces
();
while
(
netInterfaces
.
hasMoreElements
())
{
if
(
bFindIP
)
{
break
;
}
NetworkInterface
ni
=
netInterfaces
.
nextElement
();
Enumeration
<
InetAddress
>
ips
=
ni
.
getInetAddresses
();
while
(
ips
.
hasMoreElements
())
{
ip
=
ips
.
nextElement
();
if
(!
ip
.
isLoopbackAddress
()
&&
ip
.
getHostAddress
().
matches
(
"(\\d{1,3}\\.){3}\\d{1,3}"
))
{
bFindIP
=
true
;
break
;
}
}
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
if
(
null
!=
ip
)
{
sIP
=
ip
.
getHostAddress
();
}
return
sIP
;
}
}
src/main/java/cn/quantgroup/customer/util/ProtoCommon.java
0 → 100644
View file @
fcb47335
package
cn
.
quantgroup
.
customer
.
util
;
import
java.io.UnsupportedEncodingException
;
import
java.nio.charset.Charset
;
import
java.security.NoSuchAlgorithmException
;
/**
* protocol common functions
*
* @author jie.feng
*/
public
class
ProtoCommon
{
private
ProtoCommon
()
{
}
/**
* md5 function
*
* @param source the input buffer
* @return md5 string
*/
public
static
String
md5
(
byte
[]
source
)
throws
NoSuchAlgorithmException
{
char
hexDigits
[]
=
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
};
java
.
security
.
MessageDigest
md
=
java
.
security
.
MessageDigest
.
getInstance
(
"MD5"
);
md
.
update
(
source
);
byte
tmp
[]
=
md
.
digest
();
char
str
[]
=
new
char
[
32
];
int
k
=
0
;
for
(
int
i
=
0
;
i
<
16
;
i
++)
{
str
[
k
++]
=
hexDigits
[
tmp
[
i
]
>>>
4
&
0xf
];
str
[
k
++]
=
hexDigits
[
tmp
[
i
]
&
0xf
];
}
return
new
String
(
str
);
}
/**
* get token for file URL
*
* @param remote_filename the filename return by FastDFS server
* @param ts unix timestamp, unit: second
* @param secret_key the secret key
* @return token string
*/
public
static
String
getToken
(
String
remote_filename
,
int
ts
,
String
secret_key
)
throws
UnsupportedEncodingException
,
NoSuchAlgorithmException
{
byte
[]
bsFilename
=
remote_filename
.
getBytes
(
Charset
.
defaultCharset
());
byte
[]
bsKey
=
secret_key
.
getBytes
(
Charset
.
defaultCharset
());
byte
[]
bsTimestamp
=
(
new
Integer
(
ts
)).
toString
().
getBytes
(
Charset
.
defaultCharset
());
byte
[]
buff
=
new
byte
[
bsFilename
.
length
+
bsKey
.
length
+
bsTimestamp
.
length
];
System
.
arraycopy
(
bsFilename
,
0
,
buff
,
0
,
bsFilename
.
length
);
System
.
arraycopy
(
bsKey
,
0
,
buff
,
bsFilename
.
length
,
bsKey
.
length
);
System
.
arraycopy
(
bsTimestamp
,
0
,
buff
,
bsFilename
.
length
+
bsKey
.
length
,
bsTimestamp
.
length
);
return
md5
(
buff
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment