Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
asset-distribution
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
data-spider
asset-distribution
Commits
a869a83a
Commit
a869a83a
authored
Mar 06, 2020
by
liwenbin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
6.6
parent
279cd9c5
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
660 additions
and
24 deletions
+660
-24
RuleConstants.java
...quantgroup/asset/distribution/constant/RuleConstants.java
+19
-0
RuleOperator.java
...com/quantgroup/asset/distribution/enums/RuleOperator.java
+46
-0
UnionType.java
...va/com/quantgroup/asset/distribution/enums/UnionType.java
+30
-0
QGExceptionType.java
...ntgroup/asset/distribution/exception/QGExceptionType.java
+10
-0
ChannelFundConfigNew.java
.../distribution/model/entity/fund/ChannelFundConfigNew.java
+45
-0
ApprovalLogServiceImpl.java
...ibution/service/approval/impl/ApprovalLogServiceImpl.java
+0
-3
AssetServiceImpl.java
...set/distribution/service/asset/impl/AssetServiceImpl.java
+26
-21
IRuleService.java
...ntgroup/asset/distribution/service/rule/IRuleService.java
+18
-0
RuleServiceImpl.java
...asset/distribution/service/rule/impl/RuleServiceImpl.java
+96
-0
BaseRuleVO.java
...tgroup/asset/distribution/service/rule/vo/BaseRuleVO.java
+199
-0
IRuleVO.java
...uantgroup/asset/distribution/service/rule/vo/IRuleVO.java
+50
-0
UnionRuleVO.java
...group/asset/distribution/service/rule/vo/UnionRuleVO.java
+121
-0
No files found.
src/main/java/com/quantgroup/asset/distribution/constant/RuleConstants.java
0 → 100644
View file @
a869a83a
package
com
.
quantgroup
.
asset
.
distribution
.
constant
;
/**
* @author : Hyuk
* @description : RuleConstants
* @date : 2020/3/5 4:57 下午
*/
public
class
RuleConstants
{
public
static
final
String
CONDITION
=
"conditions"
;
public
static
final
String
OPERATOR
=
"operator"
;
public
static
final
String
AND
=
"and"
;
public
static
final
String
OR
=
"or"
;
public
static
final
String
KEY
=
"key"
;
public
static
final
String
VAL
=
"value"
;
public
static
final
String
DEC_TABLE_RESULT
=
"result"
;
public
static
final
String
DEC_TABLE_ELSE
=
"else"
;
}
src/main/java/com/quantgroup/asset/distribution/enums/RuleOperator.java
0 → 100644
View file @
a869a83a
package
com
.
quantgroup
.
asset
.
distribution
.
enums
;
import
com.quantgroup.asset.distribution.exception.QGException
;
import
com.quantgroup.asset.distribution.exception.QGExceptionType
;
import
com.quantgroup.asset.distribution.exception.QGPreconditions
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
/**
* @author : Hyuk
* @description : RuleOperator
* @date : 2020/3/5 5:08 下午
*/
@Slf4j
public
enum
RuleOperator
{
GreaterThan
(
">"
,
"大于"
),
GreaterThanOrEqual
(
">="
,
"大于"
),
LessThan
(
"<"
,
"小于"
),
Equal
(
"="
,
"等于"
),
In
(
"in"
,
"包含"
),
NotIn
(
"exclude"
,
"不包含"
),
NotEqual
(
"!="
,
"不等于"
),
LessThanOrEqual
(
"<="
,
"小于"
);
private
String
code
;
private
String
description
;
RuleOperator
(
String
code
,
String
description
)
{
this
.
code
=
code
;
this
.
description
=
description
;
}
public
static
RuleOperator
fromCode
(
String
code
)
{
QGPreconditions
.
checkArgument
(
StringUtils
.
isNoneBlank
(
code
),
QGExceptionType
.
COMMON_STRING_PARAM_IS_ALL_NULL
,
"操作"
);
for
(
RuleOperator
ruleOperator
:
RuleOperator
.
values
())
{
if
(
StringUtils
.
equalsAnyIgnoreCase
(
code
,
ruleOperator
.
code
))
{
return
ruleOperator
;
}
}
log
.
error
(
"枚举不存在,code={}"
,
code
);
throw
new
QGException
(
QGExceptionType
.
COMMON_ILLEGAL_PARAM
);
}
}
src/main/java/com/quantgroup/asset/distribution/enums/UnionType.java
0 → 100644
View file @
a869a83a
package
com
.
quantgroup
.
asset
.
distribution
.
enums
;
import
com.quantgroup.asset.distribution.exception.QGException
;
import
com.quantgroup.asset.distribution.exception.QGExceptionType
;
import
com.quantgroup.asset.distribution.exception.QGPreconditions
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
@Slf4j
public
enum
UnionType
{
And
(
"and"
,
"而且"
),
Or
(
"or"
,
"或者"
);
private
String
code
;
private
String
description
;
UnionType
(
String
code
,
String
description
)
{
this
.
code
=
code
;
this
.
description
=
description
;
}
public
static
UnionType
fromCode
(
String
code
)
{
QGPreconditions
.
checkArgument
(
StringUtils
.
isNoneBlank
(
code
),
QGExceptionType
.
COMMON_STRING_PARAM_IS_ALL_NULL
,
"条件组类型"
);
for
(
UnionType
unionType
:
UnionType
.
values
())
{
if
(
StringUtils
.
equalsAnyIgnoreCase
(
code
,
unionType
.
code
))
{
return
unionType
;
}
}
log
.
error
(
"枚举不存在, code = {}"
,
code
);
throw
new
QGException
(
QGExceptionType
.
COMMON_ILLEGAL_PARAM
);
}
}
src/main/java/com/quantgroup/asset/distribution/exception/QGExceptionType.java
View file @
a869a83a
...
@@ -20,6 +20,7 @@ public enum QGExceptionType {
...
@@ -20,6 +20,7 @@ public enum QGExceptionType {
COMMON_ILLEGAL_PARAM
(
1010
,
"参数异常"
),
COMMON_ILLEGAL_PARAM
(
1010
,
"参数异常"
),
COMMON_THIRD_PARTY_TIMEOUT
(
1011
,
"第三方服务超时"
),
COMMON_THIRD_PARTY_TIMEOUT
(
1011
,
"第三方服务超时"
),
COMMON_ENUM_NOT_EXIST
(
1012
,
"枚举不存在"
),
COMMON_ENUM_NOT_EXIST
(
1012
,
"枚举不存在"
),
COMMON_STRING_PARAM_IS_ALL_NULL
(
1013
,
"参数不能为空"
,
"%s不能为空"
),
ASSET_IN_CODE_ERROR
(
2001
,
"资产入库code异常! uuid : %s, bizNo : %s, code : %s"
),
ASSET_IN_CODE_ERROR
(
2001
,
"资产入库code异常! uuid : %s, bizNo : %s, code : %s"
),
GET_DEC_ATTRIBUTE_VALUE_ERROR
(
2002
,
"获取决策资产属性值异常, uuid : %s, keys : %s"
),
GET_DEC_ATTRIBUTE_VALUE_ERROR
(
2002
,
"获取决策资产属性值异常, uuid : %s, keys : %s"
),
...
@@ -32,6 +33,15 @@ public enum QGExceptionType {
...
@@ -32,6 +33,15 @@ public enum QGExceptionType {
RULE_CALC_UNKNOW_RESULT
(
2024
,
"规则判断出现未知结果,请联系管理人员, expression : %s"
),
RULE_CALC_UNKNOW_RESULT
(
2024
,
"规则判断出现未知结果,请联系管理人员, expression : %s"
),
UNKNOW_RULE_TYPE
(
2025
,
"未知的规则类型, %s"
),
UNKNOW_RULE_TYPE
(
2025
,
"未知的规则类型, %s"
),
NO_DISTRIBUTE_NODE
(
2026
,
"未找到分发节点, uuid : %s, assetNo %s, records : %s"
),
NO_DISTRIBUTE_NODE
(
2026
,
"未找到分发节点, uuid : %s, assetNo %s, records : %s"
),
RULE_EXPRESSION_IS_EMPTY
(
2027
,
"规则表达式未空"
),
RULE_IS_NOT_JSON
(
2028
,
"规则不是json,解析失败"
),
RULE_UNION_OPERATOR_NOT_EXIST
(
2029
,
"联合规则符不存在"
),
DATA_NOT_EXIST_FOR_RULE
(
2030
,
"规则数据不存在,key:%s, operator:%s, value:%s"
),
RULE_OPERATOR_IS_EMPTY
(
2031
,
"规则符为空"
),
RULE_DATA_IS_EMPTY
(
2032
,
"规则数据为空,key:%s, operator:%s, value:%s"
),
DATA_COMPARE_ERROR
(
2033
,
"数据比较出现错误"
),
RULE_OPERATOR_NOT_EXIST
(
2034
,
"规则符不存在"
),
NOTIFY_FUND_SERVER_ERROR
(
2041
,
"通知资金系统失败, uuid : %s, bizNo : %s, assetNo : %s"
),
NOTIFY_FUND_SERVER_ERROR
(
2041
,
"通知资金系统失败, uuid : %s, bizNo : %s, assetNo : %s"
),
NOT_FOUND_FUND_SERVER_RESULT_BIZNO
(
2042
,
"未找到资金结果通知订单, bizNo : %s, status : %s"
),
NOT_FOUND_FUND_SERVER_RESULT_BIZNO
(
2042
,
"未找到资金结果通知订单, bizNo : %s, status : %s"
),
...
...
src/main/java/com/quantgroup/asset/distribution/model/entity/fund/ChannelFundConfigNew.java
0 → 100644
View file @
a869a83a
package
com
.
quantgroup
.
asset
.
distribution
.
model
.
entity
.
fund
;
import
lombok.Data
;
import
java.io.Serializable
;
/**
* @author : Hyuk
* @description : ChannelFundConfigNew
* @date : 2020/3/5 3:49 下午
*/
@Data
public
class
ChannelFundConfigNew
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
private
Integer
fundId
;
private
Integer
fundProductId
;
private
String
fundName
;
private
String
attentions
;
private
Limits
limits
;
private
String
rate
;
private
Integer
feeType
;
private
Integer
rateType
;
private
Integer
priority
;
@Data
public
static
class
Limits
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
private
String
limitDetail
;
private
String
limitTranslate
;
}
}
src/main/java/com/quantgroup/asset/distribution/service/approval/impl/ApprovalLogServiceImpl.java
View file @
a869a83a
...
@@ -39,8 +39,6 @@ public class ApprovalLogServiceImpl implements IApprovalLogService{
...
@@ -39,8 +39,6 @@ public class ApprovalLogServiceImpl implements IApprovalLogService{
@Autowired
@Autowired
private
IApprovalLogRepository
approvalLogRepository
;
private
IApprovalLogRepository
approvalLogRepository
;
@Autowired
@Autowired
private
IFundModuleChannelFundConfigService
fundModuleChannelFundConfigService
;
@Autowired
private
IFundModuleChannelFundConfigNewService
fundModuleChannelFundConfigNewService
;
private
IFundModuleChannelFundConfigNewService
fundModuleChannelFundConfigNewService
;
@Override
@Override
...
@@ -115,7 +113,6 @@ public class ApprovalLogServiceImpl implements IApprovalLogService{
...
@@ -115,7 +113,6 @@ public class ApprovalLogServiceImpl implements IApprovalLogService{
public
void
audit
(
ApprovalLog
approvalLog
,
Integer
auditStatus
)
{
public
void
audit
(
ApprovalLog
approvalLog
,
Integer
auditStatus
)
{
if
(
auditStatus
==
AuditStatusEnum
.
PASS
.
getCode
())
{
if
(
auditStatus
==
AuditStatusEnum
.
PASS
.
getCode
())
{
// 先更改审核记录, 这里返回的是新配置
// 先更改审核记录, 这里返回的是新配置
// FundModuleChannelFundConfig config = fundModuleChannelFundConfigService.auditPassConfig(approvalLog.getPreConfigId(), approvalLog.getAuditConfigId());
FundModuleChannelFundConfigNew
config
=
fundModuleChannelFundConfigNewService
.
auditPassConfig
(
approvalLog
.
getPreConfigId
(),
approvalLog
.
getAuditConfigId
());
FundModuleChannelFundConfigNew
config
=
fundModuleChannelFundConfigNewService
.
auditPassConfig
(
approvalLog
.
getPreConfigId
(),
approvalLog
.
getAuditConfigId
());
// 根据新配置清楚渠道缓存
// 根据新配置清楚渠道缓存
fundModuleChannelFundConfigNewService
.
clearChannelFundConfigCache
(
config
.
getBizChannel
());
fundModuleChannelFundConfigNewService
.
clearChannelFundConfigCache
(
config
.
getBizChannel
());
...
...
src/main/java/com/quantgroup/asset/distribution/service/asset/impl/AssetServiceImpl.java
View file @
a869a83a
...
@@ -10,6 +10,10 @@ import java.util.concurrent.ExecutorService;
...
@@ -10,6 +10,10 @@ import java.util.concurrent.ExecutorService;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeUnit
;
import
com.quantgroup.asset.distribution.model.entity.fund.ChannelFundConfigNew
;
import
com.quantgroup.asset.distribution.service.funding.IFundModuleChannelFundConfigNewService
;
import
com.quantgroup.asset.distribution.service.jpa.entity.FundModuleChannelFundConfigNew
;
import
com.quantgroup.asset.distribution.service.rule.vo.IRuleVO
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
@@ -64,7 +68,7 @@ public class AssetServiceImpl implements IAssetService{
...
@@ -64,7 +68,7 @@ public class AssetServiceImpl implements IAssetService{
@Autowired
@Autowired
private
IDistributeFailLogService
distributeFailLogService
;
private
IDistributeFailLogService
distributeFailLogService
;
@Autowired
@Autowired
private
IFundModuleChannelFundConfig
Service
fundModuleCHannelFundConfig
Service
;
private
IFundModuleChannelFundConfig
NewService
fundModuleChannelFundConfigNew
Service
;
@Autowired
@Autowired
private
IRuleService
ruleService
;
private
IRuleService
ruleService
;
@Autowired
@Autowired
...
@@ -229,7 +233,7 @@ public class AssetServiceImpl implements IAssetService{
...
@@ -229,7 +233,7 @@ public class AssetServiceImpl implements IAssetService{
return
null
;
return
null
;
}
}
FundModuleChannelFundConfig
config
=
fundModuleCHannelFundConfig
Service
.
findByBizChannel
(
assetForm
.
getBizChannel
());
FundModuleChannelFundConfig
New
config
=
fundModuleChannelFundConfigNew
Service
.
findByBizChannel
(
assetForm
.
getBizChannel
());
if
(
config
==
null
&&
(
executeType
==
ExecuteType
.
TEST
||
!
"true"
.
equals
(
assetForm
.
getAuditResult
())))
{
if
(
config
==
null
&&
(
executeType
==
ExecuteType
.
TEST
||
!
"true"
.
equals
(
assetForm
.
getAuditResult
())))
{
return
null
;
return
null
;
}
}
...
@@ -237,28 +241,29 @@ public class AssetServiceImpl implements IAssetService{
...
@@ -237,28 +241,29 @@ public class AssetServiceImpl implements IAssetService{
JSONArray
fundArray
=
new
JSONArray
();
JSONArray
fundArray
=
new
JSONArray
();
// 资方去重, 可能存在多条件同一个资方
// 资方去重, 可能存在多条件同一个资方
Set
<
String
>
fundSet
=
new
HashSet
<>();
Set
<
String
>
fundSet
=
new
HashSet
<>();
List
<
ChannelFundConfig
>
fundConfigList
=
JSONArray
.
parseArray
(
config
.
getFunds
(),
ChannelFundConfig
.
class
);
List
<
ChannelFundConfig
New
>
fundConfigList
=
JSONArray
.
parseArray
(
config
.
getFunds
(),
ChannelFundConfigNew
.
class
);
A
:
for
(
ChannelFundConfig
channelFundConfig
:
fundConfigList
)
{
A
:
for
(
ChannelFundConfig
New
channelFundConfig
:
fundConfigList
)
{
List
<
ChannelFundConfig
.
Limit
>
limits
=
channelFundConfig
.
getLimits
(
);
IRuleVO
ruleVO
=
ruleService
.
getIRuleVo
(
channelFundConfig
.
getLimits
()
);
// 是否配了审核条件
if
(
ruleVO
!=
null
)
{
boolean
hasAuditResultLimit
=
false
;
if
(!
ruleVO
.
valid
(
data
))
{
if
(
CollectionUtils
.
isNotEmpty
(
limits
))
{
continue
A
;
for
(
ChannelFundConfig
.
Limit
limit
:
limits
)
{
}
String
expression
=
limit
.
getLimit
();
}
if
(
expression
.
contains
(
"audit_result"
))
{
// 如果参数为空,直接不满足
hasAuditResultLimit
=
true
;
Set
<
String
>
params
=
ruleVO
.
getParamNames
()
;
}
for
(
String
key
:
params
)
{
if
(!
ruleService
.
valid
(
expression
,
data
))
{
if
(!
data
.
containsKey
(
key
))
{
continue
A
;
continue
A
;
}
}
}
}
// 是否配了审核条件
boolean
hasAuditResultLimit
=
params
.
contains
(
"audit_result"
);
if
(!
hasAuditResultLimit
)
{
if
(!
hasAuditResultLimit
)
{
// 如果没配,自动过一层auditResult@true的条件
// 如果没配,自动过一层auditResult@true的条件
if
(!
ruleService
.
valid
(
"audit_result==true"
,
data
))
{
if
(!
ruleService
.
valid
(
"audit_result==true"
,
data
))
{
continue
A
;
continue
A
;
}
}
}
}
}
String
key
=
channelFundConfig
.
getFundId
()
+
"_"
+
channelFundConfig
.
getFundProductId
()
+
"_"
+
channelFundConfig
.
getPriority
();
String
key
=
channelFundConfig
.
getFundId
()
+
"_"
+
channelFundConfig
.
getFundProductId
()
+
"_"
+
channelFundConfig
.
getPriority
();
if
(!
fundSet
.
contains
(
key
))
{
if
(!
fundSet
.
contains
(
key
))
{
// 创建并增加资方配置
// 创建并增加资方配置
...
...
src/main/java/com/quantgroup/asset/distribution/service/rule/IRuleService.java
View file @
a869a83a
package
com
.
quantgroup
.
asset
.
distribution
.
service
.
rule
;
package
com
.
quantgroup
.
asset
.
distribution
.
service
.
rule
;
import
com.quantgroup.asset.distribution.model.entity.fund.ChannelFundConfigNew
;
import
com.quantgroup.asset.distribution.service.rule.vo.IRuleVO
;
import
java.util.Map
;
import
java.util.Map
;
public
interface
IRuleService
{
public
interface
IRuleService
{
...
@@ -11,4 +14,19 @@ public interface IRuleService {
...
@@ -11,4 +14,19 @@ public interface IRuleService {
* @return 返回true或者false
* @return 返回true或者false
*/
*/
public
boolean
valid
(
String
expression
,
Map
<
String
,
Object
>
data
);
public
boolean
valid
(
String
expression
,
Map
<
String
,
Object
>
data
);
/**
* limitDetail表达式判断
* @param limits
* @param data
* @return
*/
public
boolean
validNew
(
ChannelFundConfigNew
.
Limits
limits
,
Map
<
String
,
Object
>
data
);
/**
* 获取IRuleVO规则对象
* @param limits
* @return
*/
public
IRuleVO
getIRuleVo
(
ChannelFundConfigNew
.
Limits
limits
);
}
}
src/main/java/com/quantgroup/asset/distribution/service/rule/impl/RuleServiceImpl.java
View file @
a869a83a
...
@@ -3,6 +3,14 @@ package com.quantgroup.asset.distribution.service.rule.impl;
...
@@ -3,6 +3,14 @@ package com.quantgroup.asset.distribution.service.rule.impl;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.util.Map
;
import
java.util.Map
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.quantgroup.asset.distribution.constant.RuleConstants
;
import
com.quantgroup.asset.distribution.enums.UnionType
;
import
com.quantgroup.asset.distribution.model.entity.fund.ChannelFundConfigNew
;
import
com.quantgroup.asset.distribution.service.rule.vo.BaseRuleVO
;
import
com.quantgroup.asset.distribution.service.rule.vo.IRuleVO
;
import
com.quantgroup.asset.distribution.service.rule.vo.UnionRuleVO
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
...
@@ -15,6 +23,7 @@ import com.quantgroup.asset.distribution.util.calc.Expression;
...
@@ -15,6 +23,7 @@ import com.quantgroup.asset.distribution.util.calc.Expression;
import
com.quantgroup.asset.distribution.util.calc.Expression.ExpressionException
;
import
com.quantgroup.asset.distribution.util.calc.Expression.ExpressionException
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.util.CollectionUtils
;
/**
/**
* 规则判断
* 规则判断
...
@@ -46,4 +55,91 @@ public class RuleServiceImpl implements IRuleService{
...
@@ -46,4 +55,91 @@ public class RuleServiceImpl implements IRuleService{
}
}
}
}
@Override
public
boolean
validNew
(
ChannelFundConfigNew
.
Limits
limits
,
Map
<
String
,
Object
>
data
)
{
try
{
if
(
StringUtils
.
isEmpty
(
limits
.
getLimitDetail
()))
{
throw
new
QGException
(
QGExceptionType
.
RULE_EXPRESSION_IS_EMPTY
);
}
IRuleVO
ruleVO
=
translateFromWebFrontJSON
(
limits
.
getLimitDetail
());
return
ruleVO
.
valid
(
data
);
}
catch
(
QGException
qx
)
{
log
.
error
(
"规则判断出现错误, limitDetail : {}, limitTranslate : {}, data : {}"
,
limits
.
getLimitDetail
(),
limits
.
getLimitTranslate
(),
data
);
throw
qx
;
}
catch
(
Exception
e
)
{
log
.
error
(
"规则判断出现未知异常, limitDetail : {}, limitTranslate : {}, data : {}"
,
limits
.
getLimitDetail
(),
limits
.
getLimitTranslate
(),
data
);
throw
new
QGException
(
QGExceptionType
.
RULE_CALC_ERROR
,
limits
.
getLimitTranslate
());
}
}
@Override
public
IRuleVO
getIRuleVo
(
ChannelFundConfigNew
.
Limits
limits
)
{
if
(
StringUtils
.
isEmpty
(
limits
.
getLimitDetail
()))
{
throw
new
QGException
(
QGExceptionType
.
RULE_EXPRESSION_IS_EMPTY
);
}
IRuleVO
ruleVO
=
translateFromWebFrontJSON
(
limits
.
getLimitDetail
());
return
ruleVO
;
}
/**
* JSON转IRuleVO
*
* @param json
* @return
*/
private
IRuleVO
translateFromWebFrontJSON
(
String
json
)
{
try
{
JSONObject
jsonObject
=
JSON
.
parseObject
(
json
);
if
(!
isUnionRule
(
jsonObject
))
return
jsonObject
.
toJavaObject
(
BaseRuleVO
.
class
);
return
translateUnionRuleVO
(
jsonObject
);
}
catch
(
Exception
e
)
{
log
.
error
(
"解析规则json出错,错误内容为 : {}"
,
json
,
e
);
throw
new
QGException
(
QGExceptionType
.
RULE_EXPRESSION_IS_EMPTY
);
}
}
/**
* 检测是否组合规则
*
* @param jsonObject
* @return
*/
private
boolean
isUnionRule
(
JSONObject
jsonObject
)
{
QGPreconditions
.
checkArgument
(
jsonObject
!=
null
,
QGExceptionType
.
RULE_IS_NOT_JSON
);
if
(
jsonObject
.
containsKey
(
RuleConstants
.
CONDITION
))
{
checkUnionRule
(
jsonObject
);
return
true
;
}
checkBaseRule
(
jsonObject
);
return
false
;
}
/**
* JSON转UnionRuleVO
*
* @param jsonObject
* @return
*/
private
UnionRuleVO
translateUnionRuleVO
(
JSONObject
jsonObject
)
{
JSONArray
jsonArray
=
jsonObject
.
getJSONArray
(
RuleConstants
.
CONDITION
);
UnionRuleVO
unionRuleVO
=
new
UnionRuleVO
(
UnionType
.
fromCode
(
jsonObject
.
getString
(
RuleConstants
.
OPERATOR
)));
for
(
int
i
=
0
;
i
<
jsonArray
.
size
();
i
++)
{
JSONObject
child
=
jsonArray
.
getJSONObject
(
i
);
if
(!
isUnionRule
(
child
))
{
unionRuleVO
.
getBaseRules
().
add
(
child
.
toJavaObject
(
BaseRuleVO
.
class
));
}
else
{
unionRuleVO
.
getUnionRules
().
add
(
translateUnionRuleVO
(
child
));
}
}
return
unionRuleVO
;
}
private
void
checkUnionRule
(
JSONObject
jsonObject
)
{
QGPreconditions
.
checkArgument
(
jsonObject
.
containsKey
(
RuleConstants
.
OPERATOR
)
&&
jsonObject
.
size
()
>=
2
,
QGExceptionType
.
RULE_IS_NOT_JSON
);
QGPreconditions
.
checkArgument
(!
CollectionUtils
.
isEmpty
(
jsonObject
.
getJSONArray
(
RuleConstants
.
CONDITION
)),
QGExceptionType
.
RULE_IS_NOT_JSON
);
QGPreconditions
.
checkArgument
(
StringUtils
.
equalsAnyIgnoreCase
(
jsonObject
.
getString
(
RuleConstants
.
OPERATOR
),
RuleConstants
.
AND
,
RuleConstants
.
OR
),
QGExceptionType
.
RULE_IS_NOT_JSON
);
}
private
void
checkBaseRule
(
JSONObject
jsonObject
)
{
QGPreconditions
.
checkArgument
(
jsonObject
.
containsKey
(
RuleConstants
.
OPERATOR
)
&&
jsonObject
.
size
()
>=
3
,
QGExceptionType
.
RULE_IS_NOT_JSON
);
QGPreconditions
.
checkArgument
(
jsonObject
.
containsKey
(
RuleConstants
.
KEY
),
QGExceptionType
.
RULE_IS_NOT_JSON
);
QGPreconditions
.
checkArgument
(
jsonObject
.
containsKey
(
RuleConstants
.
VAL
),
QGExceptionType
.
RULE_IS_NOT_JSON
);
}
}
}
src/main/java/com/quantgroup/asset/distribution/service/rule/vo/BaseRuleVO.java
0 → 100644
View file @
a869a83a
package
com
.
quantgroup
.
asset
.
distribution
.
service
.
rule
.
vo
;
import
com.alibaba.fastjson.annotation.JSONField
;
import
com.alibaba.fastjson.annotation.JSONType
;
import
com.alibaba.fastjson.serializer.SerializerFeature
;
import
com.google.common.base.Objects
;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.collect.Sets
;
import
com.google.common.primitives.Doubles
;
import
com.quantgroup.asset.distribution.enums.RuleOperator
;
import
com.quantgroup.asset.distribution.exception.QGException
;
import
com.quantgroup.asset.distribution.exception.QGExceptionType
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.util.Arrays
;
import
java.util.Map
;
import
java.util.Set
;
@Data
@AllArgsConstructor
@NoArgsConstructor
@JSONType
(
typeName
=
"base"
,
serialzeFeatures
=
SerializerFeature
.
WriteEnumUsingToString
)
@Slf4j
public
class
BaseRuleVO
implements
IRuleVO
,
Serializable
{
private
static
final
long
serialVersionUID
=
-
1L
;
public
static
final
String
IN_FORMAT
=
"%s in (%s)"
;
public
static
final
String
NOT_IN_FORMAT
=
"%s not in (%s)"
;
private
String
key
;
private
String
operator
;
@JSONField
(
name
=
"value"
)
private
String
value
;
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
BaseRuleVO
that
=
(
BaseRuleVO
)
o
;
return
Objects
.
equal
(
key
,
that
.
key
)
&&
Objects
.
equal
(
operator
,
that
.
operator
)
&&
Objects
.
equal
(
value
,
that
.
value
);
}
@Override
public
String
format
()
{
switch
(
RuleOperator
.
fromCode
(
operator
))
{
case
In:
return
String
.
format
(
IN_FORMAT
,
key
,
value
);
case
NotIn:
return
String
.
format
(
NOT_IN_FORMAT
,
key
,
value
);
default
:
return
key
+
operator
+
value
;
}
}
@Override
public
boolean
valid
(
Map
<
String
,
Object
>
data
)
{
if
(
data
==
null
||
!
data
.
containsKey
(
key
)){
log
.
info
(
"规则数据不存在,key:{},operator:{},value:{}"
,
key
,
operator
,
value
);
throw
new
QGException
(
QGExceptionType
.
DATA_NOT_EXIST_FOR_RULE
,
key
,
operator
,
value
);
}
if
(
operator
==
null
){
log
.
info
(
"规则符为空,key:{},value:{}"
,
key
,
value
);
throw
new
QGException
(
QGExceptionType
.
RULE_OPERATOR_IS_EMPTY
);
}
Object
object
=
data
.
get
(
key
);
if
(
object
==
null
){
log
.
info
(
"规则数据为空,key:{},operator:{},value:{}"
,
key
,
operator
,
value
);
throw
new
QGException
(
QGExceptionType
.
RULE_DATA_IS_EMPTY
,
key
,
operator
,
value
);
}
return
compareCommon
(
object
);
}
@Override
public
Map
<
String
,
Boolean
>
valid2
(
Map
<
String
,
Object
>
data
)
{
return
ImmutableMap
.
of
(
this
.
format
(),
compareCommon
(
data
.
get
(
key
)));
}
/**
* 比较
* @param object
* @return
*/
private
boolean
compareCommon
(
Object
object
){
try
{
if
(
object
instanceof
Integer
)
return
Doubles
.
tryParse
(
value
)
==
null
?
operateInt
((
Integer
)
object
)
:
operateBigDecimal
(
BigDecimal
.
valueOf
(((
Integer
)
object
)));
if
(
object
instanceof
Float
)
return
operateBigDecimal
(
BigDecimal
.
valueOf
(((
Float
)
object
)));
if
(
object
instanceof
Double
)
return
operateBigDecimal
(
BigDecimal
.
valueOf
(((
Double
)
object
)));
if
(
object
instanceof
BigDecimal
)
return
operateBigDecimal
((
BigDecimal
)
object
);
//防止 仿真把数字传成字符串
try
{
return
operateBigDecimal
(
BigDecimal
.
valueOf
((
Double
.
parseDouble
(
String
.
valueOf
(
object
)))));
}
catch
(
NumberFormatException
e
)
{
return
operateString
(
String
.
valueOf
(
object
));
}
}
catch
(
Exception
e
)
{
log
.
error
(
"数据比较出现错误,key:{}, 配置数据:{}, 待比较的数据:{}"
,
key
,
value
,
object
,
e
);
throw
new
QGException
(
QGExceptionType
.
DATA_COMPARE_ERROR
);
}
}
@Override
public
String
getId
()
{
return
null
;
}
private
boolean
operateInt
(
int
data
)
{
switch
(
RuleOperator
.
fromCode
(
operator
))
{
case
Equal:
return
Integer
.
parseInt
(
value
)
==
data
;
case
In:
return
Arrays
.
stream
(
StringUtils
.
split
(
value
,
','
)).
filter
(
StringUtils:
:
isNumeric
).
map
(
Integer:
:
parseInt
).
anyMatch
(
i
->
data
==
i
);
case
NotIn:
return
Arrays
.
stream
(
StringUtils
.
split
(
value
,
','
)).
filter
(
StringUtils:
:
isNumeric
).
map
(
Integer:
:
parseInt
).
noneMatch
(
i
->
data
==
i
);
case
LessThan:
return
data
<
Integer
.
parseInt
(
value
);
case
NotEqual:
return
data
!=
Integer
.
parseInt
(
value
);
case
GreaterThan:
return
data
>
Integer
.
parseInt
(
value
);
case
LessThanOrEqual:
return
data
<=
Integer
.
parseInt
(
value
);
case
GreaterThanOrEqual:
return
data
>=
Integer
.
parseInt
(
value
);
default
:
throw
new
QGException
(
QGExceptionType
.
RULE_OPERATOR_NOT_EXIST
);
}
}
private
boolean
operateBigDecimal
(
BigDecimal
data
)
{
switch
(
RuleOperator
.
fromCode
(
operator
))
{
case
Equal:
return
new
BigDecimal
(
value
).
compareTo
(
data
)
==
0
;
case
In:
return
Arrays
.
stream
(
StringUtils
.
split
(
value
,
','
)).
filter
(
StringUtils:
:
isNumeric
).
map
(
BigDecimal:
:
new
).
anyMatch
(
o
->
o
.
compareTo
(
data
)
==
0
);
case
NotIn:
return
Arrays
.
stream
(
StringUtils
.
split
(
value
,
','
)).
filter
(
StringUtils:
:
isNumeric
).
map
(
BigDecimal:
:
new
).
noneMatch
(
o
->
o
.
compareTo
(
data
)
==
0
);
case
LessThan:
return
new
BigDecimal
(
value
).
compareTo
(
data
)
>
0
;
case
NotEqual:
return
new
BigDecimal
(
value
).
compareTo
(
data
)
!=
0
;
case
GreaterThan:
return
new
BigDecimal
(
value
).
compareTo
(
data
)
<
0
;
case
LessThanOrEqual:
return
new
BigDecimal
(
value
).
compareTo
(
data
)
>=
0
;
case
GreaterThanOrEqual:
return
new
BigDecimal
(
value
).
compareTo
(
data
)
<=
0
;
default
:
throw
new
QGException
(
QGExceptionType
.
RULE_OPERATOR_NOT_EXIST
);
}
}
private
boolean
operateString
(
String
data
)
{
switch
(
RuleOperator
.
fromCode
(
operator
))
{
case
Equal:
return
StringUtils
.
equals
(
StringUtils
.
replaceAll
(
value
,
"\""
,
""
),
data
);
case
In:
return
Arrays
.
stream
(
StringUtils
.
split
(
StringUtils
.
replaceAll
(
value
,
"\""
,
""
),
','
)).
anyMatch
(
data:
:
equals
);
case
NotIn:
return
Arrays
.
stream
(
StringUtils
.
split
(
StringUtils
.
replaceAll
(
value
,
"\""
,
""
),
','
)).
noneMatch
(
data:
:
equals
);
case
LessThan:
return
StringUtils
.
compare
(
data
,
StringUtils
.
replaceAll
(
value
,
"\""
,
""
))
<
0
;
case
NotEqual:
return
!
StringUtils
.
equals
(
data
,
StringUtils
.
replaceAll
(
value
,
"\""
,
""
));
case
GreaterThan:
return
StringUtils
.
compare
(
data
,
StringUtils
.
replaceAll
(
value
,
"\""
,
""
))
>
0
;
case
LessThanOrEqual:
return
StringUtils
.
compare
(
data
,
StringUtils
.
replaceAll
(
value
,
"\""
,
""
))
<=
0
;
case
GreaterThanOrEqual:
return
StringUtils
.
compare
(
data
,
StringUtils
.
replaceAll
(
value
,
"\""
,
""
))
>=
0
;
default
:
throw
new
QGException
(
QGExceptionType
.
RULE_OPERATOR_NOT_EXIST
);
}
}
@Override
public
void
checkParams
()
{
}
@Override
public
Set
<
String
>
getParamNames
()
{
return
Sets
.
newHashSet
(
key
);
}
}
\ No newline at end of file
src/main/java/com/quantgroup/asset/distribution/service/rule/vo/IRuleVO.java
0 → 100644
View file @
a869a83a
package
com
.
quantgroup
.
asset
.
distribution
.
service
.
rule
.
vo
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.annotation.JSONType
;
import
com.alibaba.fastjson.serializer.SerializerFeature
;
import
com.fasterxml.jackson.annotation.JsonSubTypes
;
import
com.fasterxml.jackson.annotation.JsonTypeInfo
;
import
java.util.Map
;
import
java.util.Set
;
/**
* @author : Hyuk
* @description : IRuleVO
* @date : 2020/3/5 4:50 下午
*/
//支持fastjson
@JSONType
(
seeAlso
=
{
BaseRuleVO
.
class
,
UnionRuleVO
.
class
})
//支持jackson
@JsonTypeInfo
(
use
=
JsonTypeInfo
.
Id
.
NAME
,
include
=
JsonTypeInfo
.
As
.
PROPERTY
,
property
=
"@type"
)
@JsonSubTypes
({
@JsonSubTypes
.
Type
(
value
=
BaseRuleVO
.
class
,
name
=
"base"
),
@JsonSubTypes
.
Type
(
value
=
UnionRuleVO
.
class
,
name
=
"union"
)})
public
interface
IRuleVO
{
boolean
valid
(
Map
<
String
,
Object
>
data
);
/**
* 记录拒绝规则 二次校验
*
* @param data
* @return
*/
Map
<
String
,
Boolean
>
valid2
(
Map
<
String
,
Object
>
data
);
String
getId
();
void
checkParams
();
Set
<
String
>
getParamNames
();
String
format
();
default
String
toJSONString
()
{
return
JSON
.
toJSONString
(
this
,
SerializerFeature
.
WriteClassName
,
SerializerFeature
.
WriteEnumUsingName
);
}
}
src/main/java/com/quantgroup/asset/distribution/service/rule/vo/UnionRuleVO.java
0 → 100644
View file @
a869a83a
package
com
.
quantgroup
.
asset
.
distribution
.
service
.
rule
.
vo
;
import
com.alibaba.fastjson.annotation.JSONType
;
import
com.google.common.base.Joiner
;
import
com.google.common.base.Objects
;
import
com.google.common.collect.Lists
;
import
com.quantgroup.asset.distribution.enums.UnionType
;
import
com.quantgroup.asset.distribution.exception.QGException
;
import
com.quantgroup.asset.distribution.exception.QGExceptionType
;
import
com.quantgroup.asset.distribution.exception.QGPreconditions
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
org.apache.commons.collections.MapUtils
;
import
org.springframework.util.CollectionUtils
;
import
java.io.Serializable
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
/**
* {condition:[
* {key:’v5’, operator:’<‘, value:’0.2’},
* {key:’v4’, operator:’in‘, value:’100,200,4900’},
* {condition:[{key:’v5’, operator:’<‘, value:’0.2’},{key:’v4’, operator:’<‘, value:’100’}], operator:’or’}
* ], operator:’and’}
* <p>
* v5<0.2 && v4<100 && (v5<0.2 || v4<100)
* <p>
* {condition:[{key:’v5’,operator:’<‘,value:’0.2’},{key:’v4’,operator:’<‘,value:’100’}],operator:’and’}
*/
@Data
@NoArgsConstructor
@JSONType
(
typeName
=
"union"
)
public
class
UnionRuleVO
implements
IRuleVO
,
Serializable
{
private
static
final
long
serialVersionUID
=
-
1L
;
private
UnionType
unionType
;
private
List
<
UnionRuleVO
>
unionRules
=
Lists
.
newArrayList
();
private
List
<
BaseRuleVO
>
baseRules
=
Lists
.
newArrayList
();
public
UnionRuleVO
(
UnionType
unionType
)
{
this
.
unionType
=
unionType
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
UnionRuleVO
that
=
(
UnionRuleVO
)
o
;
return
unionType
==
that
.
unionType
&&
Objects
.
equal
(
unionRules
,
that
.
unionRules
)
&&
Objects
.
equal
(
baseRules
,
that
.
baseRules
);
}
@Override
public
boolean
valid
(
Map
<
String
,
Object
>
data
)
{
QGPreconditions
.
checkArgument
(!(
CollectionUtils
.
isEmpty
(
baseRules
)
&&
CollectionUtils
.
isEmpty
(
unionRules
)),
QGExceptionType
.
RULE_IS_NOT_JSON
);
switch
(
unionType
)
{
case
Or:
return
unionRules
.
stream
().
anyMatch
(
r
->
r
.
valid
(
data
))
||
baseRules
.
stream
().
anyMatch
(
r
->
r
.
valid
(
data
));
case
And:
return
unionRules
.
stream
().
allMatch
(
r
->
r
.
valid
(
data
))
&&
baseRules
.
stream
().
allMatch
(
r
->
r
.
valid
(
data
));
default
:
throw
new
QGException
(
QGExceptionType
.
RULE_UNION_OPERATOR_NOT_EXIST
);
}
}
@Override
public
Map
<
String
,
Boolean
>
valid2
(
Map
<
String
,
Object
>
data
)
{
Map
<
String
,
Boolean
>
maps
=
new
HashMap
<>();
Map
<
String
,
Boolean
>
umap
=
unionRules
.
parallelStream
().
collect
(
Collectors
.
toMap
(
k
->
k
.
format
(),
v
->
v
.
valid
(
data
)));
Map
<
String
,
Boolean
>
bmap
=
baseRules
.
parallelStream
().
collect
(
Collectors
.
toMap
(
k
->
k
.
format
(),
v
->
v
.
valid
(
data
)));
if
(
MapUtils
.
isNotEmpty
(
umap
))
maps
.
putAll
(
umap
);
if
(
MapUtils
.
isNotEmpty
(
bmap
))
maps
.
putAll
(
bmap
);
return
maps
;
}
@Override
public
String
format
()
{
StringBuilder
stringBuilder
=
new
StringBuilder
();
String
operator
=
unionType
==
UnionType
.
And
?
"&&"
:
"||"
;
stringBuilder
.
append
(
Joiner
.
on
(
operator
).
join
(
baseRules
.
parallelStream
().
map
(
BaseRuleVO:
:
format
).
collect
(
Collectors
.
toList
())));
if
(!
CollectionUtils
.
isEmpty
(
unionRules
))
{
if
(!
CollectionUtils
.
isEmpty
(
baseRules
))
stringBuilder
.
append
(
operator
);
stringBuilder
.
append
(
Joiner
.
on
(
operator
).
join
(
unionRules
.
parallelStream
().
map
(
r
->
"("
+
r
.
format
()
+
")"
).
collect
(
Collectors
.
toList
())));
}
return
stringBuilder
.
toString
();
}
@Override
public
String
getId
()
{
return
null
;
}
@Override
public
void
checkParams
()
{
}
@Override
public
Set
<
String
>
getParamNames
()
{
Set
<
String
>
keys
=
baseRules
.
parallelStream
().
map
(
BaseRuleVO:
:
getKey
).
collect
(
Collectors
.
toSet
());
if
(!
CollectionUtils
.
isEmpty
(
unionRules
))
unionRules
.
parallelStream
().
forEach
(
unionRuleVO
->
keys
.
addAll
(
unionRuleVO
.
getParamNames
()));
return
keys
;
}
}
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