Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
刘栋
/
infynova-udi
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
a22aff01
authored
May 16, 2024
by
刘栋
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
UDI-规则三和规则四
parent
f6e2f9eb
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
468 additions
and
177 deletions
libs/simmetrics-core-4.1.1.jar
saas-udi-api/src/main/java/com/infynova/udi/config/MybatisPlusConfig.java
saas-udi-api/src/main/java/com/infynova/udi/entity/MatchTemp.java
saas-udi-api/src/main/java/com/infynova/udi/entity/Udi.java
saas-udi-api/src/main/java/com/infynova/udi/vo/UdiMatchRateVo.java
saas-udi-service/pom.xml
saas-udi-service/src/main/java/com/infynova/udi/controller/UdiEsController.java
saas-udi-service/src/main/java/com/infynova/udi/mapper/UdiMapper.java
saas-udi-service/src/main/java/com/infynova/udi/service/helper/EsSearchHelper.java
saas-udi-service/src/main/java/com/infynova/udi/service/helper/IKAnalyzerSupport.java
saas-udi-service/src/main/java/com/infynova/udi/service/helper/MatchESHelper.java
saas-udi-service/src/main/java/com/infynova/udi/service/helper/MatchHelper.java
saas-udi-service/src/main/java/com/infynova/udi/service/helper/PercentageCalculatorUtil.java
saas-udi-service/src/main/resources/mapper/UdiMapper.xml
libs/simmetrics-core-4.1.1.jar
0 → 100644
View file @
a22aff01
No preview for this file type
saas-udi-api/src/main/java/com/infynova/udi/config/MybatisPlusConfig.java
0 → 100644
View file @
a22aff01
package
com
.
infynova
.
udi
.
config
;
import
com.baomidou.mybatisplus.annotation.DbType
;
import
com.baomidou.mybatisplus.core.injector.AbstractMethod
;
import
com.baomidou.mybatisplus.core.injector.DefaultSqlInjector
;
import
com.baomidou.mybatisplus.core.injector.ISqlInjector
;
import
com.baomidou.mybatisplus.extension.injector.methods.AlwaysUpdateSomeColumnById
;
import
com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn
;
import
com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
;
import
com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor
;
import
com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
java.util.List
;
/**
* @author liudong
* 2024/5/15 17:12
* @version 1.0
*/
@Configuration
public
class
MybatisPlusConfig
{
@Bean
public
MybatisPlusInterceptor
mybatisPlusInterceptor
()
{
MybatisPlusInterceptor
interceptor
=
new
MybatisPlusInterceptor
();
// 分页插件
interceptor
.
addInnerInterceptor
(
new
PaginationInnerInterceptor
(
DbType
.
MYSQL
));
interceptor
.
addInnerInterceptor
(
new
OptimisticLockerInnerInterceptor
());
return
interceptor
;
}
@Bean
public
ISqlInjector
sqlInjector
()
{
return
new
DefaultSqlInjector
()
{
@Override
public
List
<
AbstractMethod
>
getMethodList
(
Class
<?>
mapperClass
)
{
List
<
AbstractMethod
>
methodList
=
super
.
getMethodList
(
mapperClass
);
methodList
.
add
(
new
InsertBatchSomeColumn
());
methodList
.
add
(
new
AlwaysUpdateSomeColumnById
());
return
methodList
;
}
};
}
}
saas-udi-api/src/main/java/com/infynova/udi/entity/MatchTemp.java
View file @
a22aff01
...
...
@@ -157,5 +157,8 @@ public class MatchTemp {
@ApiModelProperty
(
value
=
"修改时间"
)
private
LocalDateTime
updateTime
;
@ApiModelProperty
(
value
=
"来源规则:1、2、3、4"
)
private
Integer
source
;
}
saas-udi-api/src/main/java/com/infynova/udi/entity/Udi.java
View file @
a22aff01
...
...
@@ -2,6 +2,7 @@ package com.infynova.udi.entity;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
...
...
@@ -17,6 +18,7 @@ import java.time.LocalDateTime;
*/
@Data
@ApiModel
(
value
=
"udi"
,
description
=
""
)
@TableName
(
value
=
"product"
)
public
class
Udi
implements
Serializable
{
@TableId
(
type
=
IdType
.
AUTO
)
...
...
saas-udi-api/src/main/java/com/infynova/udi/vo/UdiMatchRateVo.java
View file @
a22aff01
...
...
@@ -17,4 +17,6 @@ public class UdiMatchRateVo extends Udi {
private
BigDecimal
matchRatio
;
@ApiModelProperty
(
value
=
"输入值"
)
private
String
userItem
;
@ApiModelProperty
(
value
=
"来源规则:1、2、3、4"
)
private
Integer
source
;
}
saas-udi-service/pom.xml
View file @
a22aff01
...
...
@@ -139,10 +139,17 @@
<dependency>
<groupId>
com.infynova
</groupId>
<artifactId>
saas-ucpm-api
</artifactId>
<version>
1.0.0
</version>
<version>
4.1.1
</version>
<scope>
system
</scope>
<systemPath>
${project.basedir}/../libs/saas-ucpm-api-1.0.0.jar
</systemPath>
</dependency>
<dependency>
<groupId>
org.simmetrics
</groupId>
<artifactId>
simmetrics-core
</artifactId>
<version>
1.0.0
</version>
<scope>
system
</scope>
<systemPath>
${project.basedir}/../libs/simmetrics-core-4.1.1.jar
</systemPath>
</dependency>
</dependencies>
<build>
...
...
saas-udi-service/src/main/java/com/infynova/udi/controller/UdiEsController.java
View file @
a22aff01
...
...
@@ -7,6 +7,7 @@ import com.infynova.udi.service.helper.EsSearchHelper;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.extern.slf4j.Slf4j
;
import
org.elasticsearch.action.search.SearchResponse
;
import
org.elasticsearch.action.support.master.AcknowledgedResponse
;
import
org.elasticsearch.client.indices.CreateIndexResponse
;
import
org.springframework.web.bind.annotation.*
;
...
...
@@ -46,7 +47,7 @@ public class UdiEsController {
@ApiOperationSupport
(
order
=
400
)
@ApiOperation
(
value
=
"searchThree"
,
notes
=
"searchThree"
)
@PostMapping
(
"searchThree"
)
public
Object
searchThree
(
@RequestParam
(
value
=
"companyName"
,
required
=
false
)
String
companyName
,
public
SearchResponse
searchThree
(
@RequestParam
(
value
=
"companyName"
,
required
=
false
)
String
companyName
,
@RequestParam
(
value
=
"productFactoryCode"
,
required
=
false
)
String
productFactoryCode
){
return
esSearchHelper
.
searchThree
(
companyName
,
productFactoryCode
);
}
...
...
@@ -54,7 +55,7 @@ public class UdiEsController {
@ApiOperationSupport
(
order
=
500
)
@ApiOperation
(
value
=
"searchFour"
,
notes
=
"searchFour"
)
@PostMapping
(
"searchFour"
)
public
Object
searchFour
(
@RequestParam
(
value
=
"brandName"
,
required
=
false
)
String
brandName
,
public
SearchResponse
searchFour
(
@RequestParam
(
value
=
"brandName"
,
required
=
false
)
String
brandName
,
@RequestParam
(
value
=
"productName"
,
required
=
false
)
String
productName
,
@RequestParam
(
value
=
"specification"
,
required
=
false
)
String
specification
,
@RequestParam
(
value
=
"model"
,
required
=
false
)
String
model
){
...
...
saas-udi-service/src/main/java/com/infynova/udi/mapper/UdiMapper.java
View file @
a22aff01
...
...
@@ -3,27 +3,19 @@ package com.infynova.udi.mapper;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.infynova.udi.dto.UdiListQry
;
import
com.infynova.udi.entity.Udi
;
import
com.infynova.udi.mapper.base.SuperMapper
;
import
com.infynova.udi.vo.UdiMatchRateVo
;
import
com.infynova.udi.vo.UdiVo
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.List
;
public
interface
UdiMapper
{
public
interface
UdiMapper
extends
SuperMapper
<
Udi
>
{
Page
<
UdiVo
>
getUdiPage
(
IPage
page
,
@Param
(
"query"
)
UdiListQry
udiListQry
);
List
<
UdiVo
>
getUdiList
(
@Param
(
"query"
)
UdiListQry
udiListQry
);
Page
<
UdiVo
>
getUdi
(
IPage
page
,
@Param
(
"udi"
)
String
udiCode
,
@Param
(
"yiBaoCode"
)
String
yiBaoCode
,
@Param
(
"companyName"
)
String
companyName
,
@Param
(
"productFactoryCode"
)
String
productFactoryCode
,
@Param
(
"brandName"
)
String
brandName
,
@Param
(
"productName"
)
String
productName
,
@Param
(
"specification"
)
String
specification
,
@Param
(
"model"
)
String
model
);
List
<
UdiMatchRateVo
>
getUdiCodeRegex
(
@Param
(
"udiCode"
)
String
udiCode
,
@Param
(
"udiCodeList"
)
List
<
String
>
udiCodeList
);
List
<
UdiMatchRateVo
>
getYiBaoCodeRegex
(
@Param
(
"yiBaoCode"
)
String
yiBaoCode
,
@Param
(
"yiBaoCodeList"
)
List
<
String
>
yiBaoCodeList
);
...
...
saas-udi-service/src/main/java/com/infynova/udi/service/helper/EsSearchHelper.java
View file @
a22aff01
package
com
.
infynova
.
udi
.
service
.
helper
;
import
com.infynova.udi.mapper.UdiMapper
;
import
com.infynova.udi.vo.UdiMatchRateVo
;
import
com.infynova.udi.vo.UdiVo
;
import
lombok.SneakyThrows
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.http.HttpHost
;
import
org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest
;
import
org.elasticsearch.action.bulk.BulkRequest
;
...
...
@@ -27,15 +29,15 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import
org.elasticsearch.common.xcontent.XContentFactory
;
import
org.elasticsearch.common.xcontent.XContentType
;
import
org.elasticsearch.index.query.*
;
import
org.elasticsearch.search.SearchHit
;
import
org.elasticsearch.search.builder.SearchSourceBuilder
;
import
org.springframework.stereotype.Component
;
import
org.springframework.util.StopWatch
;
import
javax.annotation.Resource
;
import
java.io.IOException
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.math.BigDecimal
;
import
java.util.*
;
/**
* @author liudong
...
...
@@ -186,14 +188,22 @@ public class EsSearchHelper {
}
@SneakyThrows
public
Object
searchThree
(
String
companyName
,
String
productFactoryCode
){
public
SearchResponse
searchThree
(
String
companyName
,
String
productFactoryCode
){
if
(
StringUtils
.
isBlank
(
companyName
)
&&
StringUtils
.
isBlank
(
productFactoryCode
)){
return
null
;
}
SearchRequest
searchRequest
=
new
SearchRequest
(
INDEX_NAME
);
// 构建查询条件
BoolQueryBuilder
boolQueryBuilder
=
QueryBuilders
.
boolQuery
()
.
should
(
new
MatchQueryBuilder
(
"companyName"
,
companyName
))
.
should
(
new
TermQueryBuilder
(
"companyName.keyword"
,
companyName
))
.
should
(
new
MatchQueryBuilder
(
"productFactoryCode"
,
productFactoryCode
))
.
should
(
new
TermQueryBuilder
(
"productFactoryCode.keyword"
,
productFactoryCode
));
BoolQueryBuilder
boolQueryBuilder
=
QueryBuilders
.
boolQuery
();
if
(
StringUtils
.
isNotBlank
(
companyName
)){
boolQueryBuilder
.
should
(
new
MatchQueryBuilder
(
"companyName"
,
companyName
))
.
should
(
new
TermQueryBuilder
(
"companyName.keyword"
,
companyName
));
}
// boost 倾向性:查询时倾向于productFactoryCode
if
(
StringUtils
.
isNotBlank
(
productFactoryCode
)){
boolQueryBuilder
.
should
(
new
MatchQueryBuilder
(
"productFactoryCode"
,
productFactoryCode
).
boost
(
2
))
.
should
(
new
TermQueryBuilder
(
"productFactoryCode.keyword"
,
productFactoryCode
).
boost
(
2
));
}
// 构建搜索源
SearchSourceBuilder
searchSourceBuilder
=
new
SearchSourceBuilder
().
query
(
boolQueryBuilder
);
...
...
@@ -205,19 +215,59 @@ public class EsSearchHelper {
return
searchResponse
;
}
/**
* 规则三
* @param companyName 企业名称
* @param productFactoryCode 产品厂家编码
*/
public
List
<
UdiMatchRateVo
>
threeQuery
(
String
companyName
,
String
productFactoryCode
){
List
<
UdiMatchRateVo
>
resultList
=
new
ArrayList
<>();
SearchResponse
searchResponse
=
searchThree
(
companyName
,
productFactoryCode
);
if
(
Objects
.
isNull
(
searchResponse
)){
return
new
ArrayList
<>();
}
// 处理搜索结果
SearchHit
[]
searchHits
=
searchResponse
.
getHits
().
getHits
();
for
(
SearchHit
hit
:
searchHits
)
{
UdiMatchRateVo
udiMatchRateVo
=
new
UdiMatchRateVo
();
Long
idQuery
=
Long
.
valueOf
(
hit
.
getSourceAsMap
().
get
(
"id"
).
toString
());
String
companyNameQuery
=
Optional
.
ofNullable
(
hit
.
getSourceAsMap
().
get
(
"companyName"
)).
orElse
(
""
).
toString
();
String
productFactoryCodeQuery
=
Optional
.
ofNullable
(
hit
.
getSourceAsMap
().
get
(
"productFactoryCode"
)).
orElse
(
""
).
toString
();
udiMatchRateVo
.
setId
(
idQuery
);
udiMatchRateVo
.
setCompanyName
(
companyNameQuery
);
udiMatchRateVo
.
setProductFactoryCode
(
productFactoryCodeQuery
);
resultList
.
add
(
udiMatchRateVo
);
}
return
resultList
;
}
@SneakyThrows
public
Object
searchFour
(
String
brandName
,
String
productName
,
String
specification
,
String
model
){
public
SearchResponse
searchFour
(
String
brandName
,
String
productName
,
String
specification
,
String
model
){
if
(
StringUtils
.
isBlank
(
brandName
)
&&
StringUtils
.
isBlank
(
productName
)
&&
StringUtils
.
isBlank
(
specification
)
&&
StringUtils
.
isBlank
(
model
)
){
return
null
;
}
SearchRequest
searchRequest
=
new
SearchRequest
(
INDEX_NAME
);
// 构建查询条件
BoolQueryBuilder
boolQueryBuilder
=
QueryBuilders
.
boolQuery
()
.
should
(
new
MatchQueryBuilder
(
"brandName"
,
brandName
))
.
should
(
new
TermQueryBuilder
(
"brandName.keyword"
,
brandName
))
.
should
(
new
MatchQueryBuilder
(
"productName"
,
productName
))
.
should
(
new
TermQueryBuilder
(
"productName.keyword"
,
productName
))
.
should
(
new
MatchQueryBuilder
(
"specification"
,
specification
))
.
should
(
new
TermQueryBuilder
(
"specification.keyword"
,
specification
))
.
should
(
new
MatchQueryBuilder
(
"model"
,
model
))
BoolQueryBuilder
boolQueryBuilder
=
QueryBuilders
.
boolQuery
();
if
(
StringUtils
.
isNotBlank
(
brandName
)){
boolQueryBuilder
.
should
(
new
MatchQueryBuilder
(
"brandName"
,
brandName
))
.
should
(
new
TermQueryBuilder
(
"brandName.keyword"
,
brandName
));
}
if
(
StringUtils
.
isNotBlank
(
productName
)){
boolQueryBuilder
.
should
(
new
MatchQueryBuilder
(
"productName"
,
productName
))
.
should
(
new
TermQueryBuilder
(
"productName.keyword"
,
productName
));
}
if
(
StringUtils
.
isNotBlank
(
specification
)){
boolQueryBuilder
.
should
(
new
MatchQueryBuilder
(
"specification"
,
specification
))
.
should
(
new
TermQueryBuilder
(
"specification.keyword"
,
specification
));
}
if
(
StringUtils
.
isNotBlank
(
model
)){
boolQueryBuilder
.
should
(
new
MatchQueryBuilder
(
"model"
,
model
))
.
should
(
new
TermQueryBuilder
(
"model.keyword"
,
model
));
}
// 构建搜索源
SearchSourceBuilder
searchSourceBuilder
=
new
SearchSourceBuilder
().
query
(
boolQueryBuilder
);
...
...
@@ -228,4 +278,34 @@ public class EsSearchHelper {
SearchResponse
searchResponse
=
client
.
search
(
searchRequest
,
RequestOptions
.
DEFAULT
);
return
searchResponse
;
}
/**
* 规则四
* @param brandName
* @param productName
* @param specification
* @param model
* @return
*/
public
List
<
UdiMatchRateVo
>
fourQuery
(
String
brandName
,
String
productName
,
String
specification
,
String
model
){
List
<
UdiMatchRateVo
>
resultList
=
new
ArrayList
<>();
SearchResponse
searchResponse
=
searchFour
(
brandName
,
productName
,
specification
,
model
);
// 处理搜索结果
SearchHit
[]
searchHits
=
searchResponse
.
getHits
().
getHits
();
for
(
SearchHit
hit
:
searchHits
)
{
UdiMatchRateVo
udiMatchRateVo
=
new
UdiMatchRateVo
();
Long
idQuery
=
Long
.
valueOf
(
hit
.
getSourceAsMap
().
get
(
"id"
).
toString
());
String
brandNameQuery
=
Optional
.
ofNullable
(
hit
.
getSourceAsMap
().
get
(
"brandName"
)).
orElse
(
""
).
toString
();
String
productNameQuery
=
Optional
.
ofNullable
(
hit
.
getSourceAsMap
().
get
(
"productName"
)).
orElse
(
""
).
toString
();
String
specificationQuery
=
Optional
.
ofNullable
(
hit
.
getSourceAsMap
().
get
(
"specification"
)).
orElse
(
""
).
toString
();
String
modelQuery
=
Optional
.
ofNullable
(
hit
.
getSourceAsMap
().
get
(
"model"
)).
orElse
(
""
).
toString
();
udiMatchRateVo
.
setId
(
idQuery
);
udiMatchRateVo
.
setBrandName
(
brandNameQuery
);
udiMatchRateVo
.
setProductName
(
productNameQuery
);
udiMatchRateVo
.
setSpecification
(
specificationQuery
);
udiMatchRateVo
.
setModel
(
modelQuery
);
resultList
.
add
(
udiMatchRateVo
);
}
return
resultList
;
}
}
saas-udi-service/src/main/java/com/infynova/udi/service/helper/IKAnalyzerSupport.java
deleted
100644 → 0
View file @
f6e2f9eb
//package com.infynova.udi.service.helper;
//
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.StringUtils;
//import org.wltea.analyzer.core.IKSegmenter;
//import org.wltea.analyzer.core.Lexeme;
//
//import java.io.StringReader;
//import java.util.ArrayList;
//import java.util.List;
//
///**
// * @author liudong
// * 2024/3/14 18:27
// * @version 1.0
// */
//@Slf4j
//public class IKAnalyzerSupport {
//
// /**
// * IK分词
// * @param target
// * @return
// */
// public static List<String> iKSegmenterToList(String target) throws Exception {
// if (StringUtils.isEmpty(target)){
// return new ArrayList<>();
// }
// List<String> result = new ArrayList<>();
// StringReader sr = new StringReader(target);
// // false:关闭智能分词 (对分词的精度影响较大)
// IKSegmenter ik = new IKSegmenter(sr, true);
// Lexeme lex;
// while((lex=ik.next())!=null) {
// String lexemeText = lex.getLexemeText();
// result.add(lexemeText);
// }
// return result;
// }
//}
saas-udi-service/src/main/java/com/infynova/udi/service/helper/MatchESHelper.java
0 → 100644
View file @
a22aff01
package
com
.
infynova
.
udi
.
service
.
helper
;
import
com.infynova.udi.entity.Udi
;
import
com.infynova.udi.mapper.UdiMapper
;
import
com.infynova.udi.vo.UdiMatchRateVo
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.simmetrics.StringMetric
;
import
org.simmetrics.metrics.Levenshtein
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
java.math.BigDecimal
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.function.Function
;
import
java.util.stream.Collectors
;
/**
* @author liudong
* 2024/5/15 14:12
* @version 1.0
*/
@Slf4j
@Component
(
"matchESHelper"
)
public
class
MatchESHelper
{
@Resource
private
EsSearchHelper
esSearchHelper
;
@Resource
private
UdiMapper
udiMapper
;
private
static
final
BigDecimal
ONE_HUNDRED_RATE
=
new
BigDecimal
(
"100"
);
private
static
final
BigDecimal
NINE_RATE
=
new
BigDecimal
(
"90"
);
/**
* 规则三
*/
public
List
<
UdiMatchRateVo
>
three
(
String
companyName
,
String
productFactoryCode
){
List
<
UdiMatchRateVo
>
udiMatchRateVos
=
esSearchHelper
.
threeQuery
(
companyName
,
productFactoryCode
);
if
(
CollectionUtils
.
isEmpty
(
udiMatchRateVos
)){
return
udiMatchRateVos
;
}
List
<
Long
>
idList
=
udiMatchRateVos
.
stream
().
map
(
UdiMatchRateVo:
:
getId
).
collect
(
Collectors
.
toList
());
List
<
Udi
>
udiList
=
udiMapper
.
selectBatchIds
(
idList
);
Map
<
Long
,
Udi
>
udiMap
=
udiList
.
stream
().
collect
(
Collectors
.
toMap
(
Udi:
:
getId
,
Function
.
identity
()));
for
(
UdiMatchRateVo
udiMatchRateVo
:
udiMatchRateVos
)
{
Long
id
=
udiMatchRateVo
.
getId
();
if
(
udiMap
.
containsKey
(
id
)){
Udi
udi
=
udiMap
.
get
(
id
);
BeanUtils
.
copyProperties
(
udi
,
udiMatchRateVo
);
// todo 如何去计算匹配率
String
companyNameUdi
=
udi
.
getCompanyName
();
String
productFactoryCodeUdi
=
udi
.
getProductFactoryCode
();
BigDecimal
matchRatio
=
this
.
matchThree
(
companyName
,
productFactoryCode
,
companyNameUdi
,
productFactoryCodeUdi
);
udiMatchRateVo
.
setMatchRatio
(
matchRatio
);
}
else
{
// 没匹配成功
udiMatchRateVo
.
setMatchRatio
(
BigDecimal
.
ZERO
);
}
}
return
udiMatchRateVos
;
}
/**
* 规则三 - 计算匹配率
* @param companyName excel中的companyName
* @param productFactoryCode excel中的productFactoryCode
* @param companyNameUdi 找到的companyName
* @param productFactoryCodeUdi 找到的productFactoryCode
* @return 匹配率
*/
private
BigDecimal
matchThree
(
String
companyName
,
String
productFactoryCode
,
String
companyNameUdi
,
String
productFactoryCodeUdi
){
if
(
StringUtils
.
isBlank
(
companyName
)){
// 如果【公司名称】为空,则只判断厂家产品货号/编号
if
(
StringUtils
.
equals
(
productFactoryCode
,
productFactoryCodeUdi
)){
// 如果这个编码对得上,则90%;
return
NINE_RATE
;
}
else
{
// 匹配率 关键~!!
StringMetric
metric
=
new
Levenshtein
();
float
result
=
metric
.
compare
(
productFactoryCode
,
productFactoryCodeUdi
);
result
=
result
*
100
;
return
new
BigDecimal
(
result
);
}
}
else
if
(
StringUtils
.
isBlank
(
productFactoryCode
)){
// 如果【厂家产品货号/编号】为空,则只判断公司名称
if
(
StringUtils
.
equals
(
companyName
,
companyNameUdi
)){
// 如果这个编码对得上,则90%;
return
NINE_RATE
;
}
else
{
// 匹配率 关键~!!
StringMetric
metric
=
new
Levenshtein
();
float
result
=
metric
.
compare
(
companyName
,
companyNameUdi
);
result
=
result
*
100
;
return
new
BigDecimal
(
result
);
}
}
else
{
// 两者都不为空
// Levenshtein距离算法 算出匹配率
StringMetric
metric
=
new
Levenshtein
();
double
productFactoryCodeWeight
=
0.6
;
double
companyNameWeight
=
0.4
;
// 如果productFactoryCode相等 计算匹配率倾向于productFactoryCode
if
(
StringUtils
.
equals
(
productFactoryCode
,
productFactoryCodeUdi
)){
productFactoryCodeWeight
=
0.8
;
companyNameWeight
=
0.2
;
}
float
productFactoryCodeResult
=
metric
.
compare
(
productFactoryCode
,
productFactoryCodeUdi
);
float
companyNameResult
=
metric
.
compare
(
companyName
,
companyNameUdi
);
// 权重,偏向productFactoryCode
double
result
=
PercentageCalculatorUtil
.
calculateWeightedAverageRate
(
productFactoryCodeResult
,
companyNameResult
,
productFactoryCodeWeight
,
companyNameWeight
);
result
=
result
*
100
;
return
new
BigDecimal
(
result
);
}
}
/**
* 规则四
*/
public
List
<
UdiMatchRateVo
>
four
(
String
brandName
,
String
productName
,
String
specification
,
String
model
){
List
<
UdiMatchRateVo
>
udiMatchRateVos
=
esSearchHelper
.
fourQuery
(
brandName
,
productName
,
specification
,
model
);
List
<
Long
>
idList
=
udiMatchRateVos
.
stream
().
map
(
UdiMatchRateVo:
:
getId
).
collect
(
Collectors
.
toList
());
List
<
Udi
>
udiList
=
udiMapper
.
selectBatchIds
(
idList
);
Map
<
Long
,
Udi
>
udiMap
=
udiList
.
stream
().
collect
(
Collectors
.
toMap
(
Udi:
:
getId
,
Function
.
identity
()));
for
(
UdiMatchRateVo
udiMatchRateVo
:
udiMatchRateVos
)
{
Long
id
=
udiMatchRateVo
.
getId
();
if
(
udiMap
.
containsKey
(
id
)){
Udi
udi
=
udiMap
.
get
(
id
);
BeanUtils
.
copyProperties
(
udi
,
udiMatchRateVo
);
// todo 如何去计算匹配率
String
brandNameUdi
=
udi
.
getBrandName
();
String
productNameUdi
=
udi
.
getProductName
();
String
specificationUdi
=
udi
.
getSpecification
();
String
modelUdi
=
udi
.
getModel
();
BigDecimal
matchRatio
=
this
.
matchFour
(
brandName
,
productName
,
specification
,
model
,
brandNameUdi
,
productNameUdi
,
specificationUdi
,
modelUdi
);
udiMatchRateVo
.
setMatchRatio
(
matchRatio
);
}
else
{
// 没匹配成功
udiMatchRateVo
.
setMatchRatio
(
BigDecimal
.
ZERO
);
}
}
return
udiMatchRateVos
;
}
/**
* 规则四 - 计算匹配率
* @param brandName excel中的
* @param productName excel中的
* @param specification excel中的
* @param model excel中的
* @param brandNameUdi 找到的
* @param productNameUdi 找到的
* @param specificationUdi 找到的
* @param modelUdi 找到的
* @return 匹配率
*/
private
BigDecimal
matchFour
(
String
brandName
,
String
productName
,
String
specification
,
String
model
,
String
brandNameUdi
,
String
productNameUdi
,
String
specificationUdi
,
String
modelUdi
){
// Levenshtein距离算法 算出匹配率
StringMetric
metric
=
new
Levenshtein
();
float
brandNameRate
=
0
;
if
(
StringUtils
.
isNotBlank
(
brandName
)){
brandNameRate
=
metric
.
compare
(
brandName
,
brandNameUdi
);
}
float
productNameRate
=
0
;
if
(
StringUtils
.
isNotBlank
(
productName
)){
productNameRate
=
metric
.
compare
(
productName
,
productNameUdi
);
}
float
specificationRate
=
0
;
if
(
StringUtils
.
isNotBlank
(
specification
)){
specificationRate
=
metric
.
compare
(
specification
,
specificationUdi
);
}
float
modelRate
=
0
;
if
(
StringUtils
.
isNotBlank
(
model
)){
modelRate
=
metric
.
compare
(
model
,
modelUdi
);
}
double
result
=
PercentageCalculatorUtil
.
calculateWeightedAverageRate
(
brandNameRate
,
productNameRate
,
specificationRate
,
modelRate
,
0.25
,
0.25
,
0.25
,
0.25
);
result
=
result
*
100
;
return
new
BigDecimal
(
result
);
}
}
saas-udi-service/src/main/java/com/infynova/udi/service/helper/MatchHelper.java
View file @
a22aff01
...
...
@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.infynova.udi.entity.MatchData
;
import
com.infynova.udi.entity.MatchTemp
;
import
com.infynova.udi.entity.Udi
;
import
com.infynova.udi.enums.match.MatchStatusEnum
;
import
com.infynova.udi.enums.match.MatchUpdateStatusEnum
;
import
com.infynova.udi.mapper.MatchDataMapper
;
...
...
@@ -12,7 +11,6 @@ import com.infynova.udi.mapper.MatchTempMapper;
import
com.infynova.udi.mapper.UdiMapper
;
import
com.infynova.udi.vo.TaskVo
;
import
com.infynova.udi.vo.UdiMatchRateVo
;
import
com.infynova.udi.vo.UdiVo
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
...
...
@@ -52,6 +50,9 @@ public class MatchHelper {
@Resource
private
UdiLock
udiLock
;
@Resource
private
MatchESHelper
matchESHelper
;
private
static
final
BigDecimal
ONE_HUNDRED_RATE
=
new
BigDecimal
(
"100"
);
private
String
getKey
(
String
key
){
...
...
@@ -139,14 +140,17 @@ public class MatchHelper {
// 去匹配YiBaoCode
matchRateVoList
=
this
.
queryYiBaoCode
(
matchData
);
}
else
if
(
StringUtils
.
isNotBlank
(
matchData
.
getCompanyName
())
||
StringUtils
.
isNotBlank
(
matchData
.
getProductFactoryCode
())){
// 厂家+产品货号/编号
todo
// 厂家+产品货号/编号
matchRateVoList
=
matchESHelper
.
three
(
matchData
.
getCompanyName
(),
matchData
.
getProductFactoryCode
());
}
else
if
(
StringUtils
.
isNotBlank
(
matchData
.
getBrandName
())
||
StringUtils
.
isNotBlank
(
matchData
.
getProductName
())
||
StringUtils
.
isNotBlank
(
matchData
.
getSpecification
())
||
StringUtils
.
isNotBlank
(
matchData
.
getModel
()))
{
// 品牌+名称+规格+型号; todo
// 品牌+名称+规格+型号;
matchRateVoList
=
matchESHelper
.
four
(
matchData
.
getBrandName
(),
matchData
.
getProductName
(),
matchData
.
getSpecification
(),
matchData
.
getModel
());
}
// 计算匹配率
...
...
@@ -181,7 +185,6 @@ public class MatchHelper {
matchData
.
setUpdateStatus
(
MatchUpdateStatusEnum
.
NOT_APPLICABLE
.
getCode
());
matchData
.
setUpdateTime
(
LocalDateTime
.
now
());
matchDataMapper
.
updateById
(
matchData
);
return
;
}
else
{
if
(
hundredRate
){
// 100%对码
...
...
@@ -200,29 +203,6 @@ public class MatchHelper {
}
}
/**
* 查询udi
*/
private
Page
<
UdiVo
>
queryUdi
(
int
pageNo
,
int
pageSize
,
MatchData
matchData
){
String
udiCode
=
matchData
.
getUdiCode
();
String
yiBaoCode
=
matchData
.
getYiBaoCode
();
String
companyName
=
matchData
.
getCompanyName
();
String
productFactoryCode
=
matchData
.
getProductFactoryCode
();
String
brandName
=
matchData
.
getBrandName
();
String
productName
=
matchData
.
getProductName
();
String
specification
=
matchData
.
getSpecification
();
String
model
=
matchData
.
getModel
();
Page
<
UdiVo
>
page
=
new
Page
<>(
pageNo
,
pageSize
);
return
udiMapper
.
getUdi
(
page
,
udiCode
,
yiBaoCode
,
companyName
,
productFactoryCode
,
brandName
,
productName
,
specification
,
model
);
}
/**
* 查询udi
...
...
@@ -262,7 +242,6 @@ public class MatchHelper {
*/
private
List
<
UdiMatchRateVo
>
queryYiBaoCode
(
MatchData
matchData
){
String
yiBaoCode
=
matchData
.
getYiBaoCode
();
// todo 分次
List
<
String
>
yiBaoCodeRegexList
=
new
ArrayList
<>();
String
lastYiBaoCode
=
yiBaoCode
;
// 规定udi截取的最小长度
...
...
@@ -280,66 +259,9 @@ public class MatchHelper {
return
udiMapper
.
getUdiCodeRegex
(
yiBaoCode
,
yiBaoCodeRegexList
);
}
/**
* 对目标进行分词
*/
// private String splitWord(String item){
// log.info("对目标进行分词");
//
// List<String> splitWord = new ArrayList<>();
// String result = item;
// try {
// splitWord = IKAnalyzerSupport.iKSegmenterToList(item);
// result = splitWord.stream().map(String::valueOf).distinct().collect(Collectors.joining("|")) ;
// log.info("分词结果:{}",result);
// } catch (Exception e) {
// log.error("分词报错:{}",e.getMessage());
// }
// return result;
// }
private
final
BigDecimal
RATE
=
new
BigDecimal
(
"0.25"
);
/**
* 匹配率计算逻辑
*/
private
BigDecimal
matchRate
(
Udi
udi
,
MatchData
matchData
){
BigDecimal
matchRate
=
BigDecimal
.
ZERO
;
// - 规则1:DI码,即69码;
String
udiCode
=
udi
.
getUdiCode
();
String
matchUdiCode
=
matchData
.
getUdiCode
();
if
(
StringUtils
.
equals
(
udiCode
,
matchUdiCode
)){
matchRate
=
matchRate
.
add
(
RATE
);
}
// - 规则2:C码 ,是指医保编码;
String
yiBaoCode
=
udi
.
getYiBaoCode
();
String
matchYiBaoCode
=
matchData
.
getYiBaoCode
();
if
(
StringUtils
.
equals
(
yiBaoCode
,
matchYiBaoCode
)){
matchRate
=
matchRate
.
add
(
RATE
);
}
// - 规则3:厂家+产品货号/编号;
String
companyName
=
udi
.
getCompanyName
();
String
matchCompanyName
=
matchData
.
getCompanyName
();
String
productFactoryCode
=
udi
.
getProductFactoryCode
();
String
matchProductFactoryCode
=
matchData
.
getProductFactoryCode
();
if
(
StringUtils
.
equals
(
companyName
,
matchCompanyName
)
&&
StringUtils
.
equals
(
productFactoryCode
,
matchProductFactoryCode
)){
matchRate
=
matchRate
.
add
(
RATE
);
}
// - 规则4:品牌+名称+规格+型号;
String
brandName
=
udi
.
getBrandName
();
String
matchBrandName
=
matchData
.
getBrandName
();
String
productName
=
udi
.
getProductName
();
String
matchProductName
=
matchData
.
getProductName
();
String
specification
=
udi
.
getSpecification
();
String
matchSpecification
=
matchData
.
getSpecification
();
String
model
=
udi
.
getModel
();
String
matchModel
=
matchData
.
getModel
();
if
(
StringUtils
.
equals
(
brandName
,
matchBrandName
)
&&
StringUtils
.
equals
(
productName
,
matchProductName
)
&&
StringUtils
.
equals
(
specification
,
matchSpecification
)
&&
StringUtils
.
equals
(
model
,
matchModel
)){
matchRate
=
matchRate
.
add
(
RATE
);
private
void
setSource
(
List
<
UdiMatchRateVo
>
list
,
Integer
source
){
if
(
CollectionUtils
.
isNotEmpty
(
list
)){
list
.
forEach
(
i
->
i
.
setSource
(
source
));
}
return
matchRate
;
}
}
saas-udi-service/src/main/java/com/infynova/udi/service/helper/PercentageCalculatorUtil.java
0 → 100644
View file @
a22aff01
package
com
.
infynova
.
udi
.
service
.
helper
;
/**
* @author liudong
* 2024/5/15 18:20
* @version 1.0
*/
public
class
PercentageCalculatorUtil
{
public
static
void
main
(
String
[]
args
)
{
example01
();
example02
();
example03
();
example04
();
}
/**
* 简单平均
* 这种方法计算两个百分比的平均值
*/
public
static
double
calculateAverageRate
(
double
percentage1
,
double
percentage2
)
{
return
(
percentage1
+
percentage2
)
/
2
;
}
public
static
void
example01
()
{
double
percentage1
=
75.0
;
double
percentage2
=
85.0
;
double
result
=
calculateAverageRate
(
percentage1
,
percentage2
);
System
.
out
.
println
(
"Average Rate 简单平均: "
+
result
+
"%"
);
}
/**
* 加权平均
* 如果两个百分比的权重不同,可以根据权重计算加权平均
* @param percentage1
* @param percentage2
* @param weight1
* @param weight2
* @return
*/
public
static
double
calculateWeightedAverageRate
(
double
percentage1
,
double
percentage2
,
double
weight1
,
double
weight2
)
{
return
(
percentage1
*
weight1
+
percentage2
*
weight2
)
/
(
weight1
+
weight2
);
}
public
static
double
calculateWeightedAverageRate
(
double
percentage1
,
double
percentage2
,
double
percentage3
,
double
percentage4
,
double
weight1
,
double
weight2
,
double
weight3
,
double
weight4
)
{
return
(
percentage1
*
weight1
+
percentage2
*
weight2
+
percentage3
*
weight3
+
percentage4
*
weight4
)
/
(
weight1
+
weight2
+
weight3
+
weight4
);
}
public
static
void
example02
()
{
double
percentage1
=
75.0
;
double
percentage2
=
85.0
;
double
weight1
=
0.4
;
// 权重1
double
weight2
=
0.6
;
// 权重2
double
result
=
calculateWeightedAverageRate
(
percentage1
,
percentage2
,
weight1
,
weight2
);
System
.
out
.
println
(
"Weighted Average Rate 加权平均: "
+
result
+
"%"
);
}
/**
* 乘法平均(几何平均)
* 这种方法适用于计算多个百分比的综合效果。
* @param percentage1
* @param percentage2
* @return
*/
public
static
double
calculateGeometricMeanRate
(
double
percentage1
,
double
percentage2
)
{
return
Math
.
sqrt
(
percentage1
*
percentage2
);
}
public
static
void
example03
()
{
double
percentage1
=
75.0
;
double
percentage2
=
85.0
;
double
result
=
calculateGeometricMeanRate
(
percentage1
,
percentage2
);
System
.
out
.
println
(
"Geometric Mean Rate 乘法平均(几何平均): "
+
result
+
"%"
);
}
/**
* 自定义算法
* 你可以根据具体业务需求,设计一个自定义的算法。例如,可以通过计算两个百分比的差异来调整符合率。
* @param percentage1
* @param percentage2
* @return
*/
public
static
double
calculateCustomRate
(
double
percentage1
,
double
percentage2
)
{
double
difference
=
Math
.
abs
(
percentage1
-
percentage2
);
return
(
percentage1
+
percentage2
-
difference
)
/
2
;
}
public
static
void
example04
()
{
double
percentage1
=
75.0
;
double
percentage2
=
85.0
;
double
result
=
calculateCustomRate
(
percentage1
,
percentage2
);
System
.
out
.
println
(
"Custom Rate 自定义算法: "
+
result
+
"%"
);
}
}
saas-udi-service/src/main/resources/mapper/UdiMapper.xml
View file @
a22aff01
...
...
@@ -78,20 +78,6 @@
</if>
</sql>
<select
id=
"getUdi"
resultType=
"com.infynova.udi.vo.UdiVo"
>
select *
from product
where udi_code = #{udi}
OR yi_bao_code = #{yiBaoCode}
OR company_name = #{companyName}
OR product_factory_code = #{productFactoryCode}
OR brand_name = #{brandName}
OR product_name = #{productName}
OR specification = #{specification}
OR model = #{model}
order by id desc
</select>
<select
id=
"getUdiCodeRegex"
resultType=
"com.infynova.udi.vo.UdiMatchRateVo"
>
SELECT
ifnull(calculate_match_ratio(p.udi_code, #{udiCode}),0) as match_ratio,
...
...
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