You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
3.4 KiB
152 lines
3.4 KiB
8 months ago
|
package service
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"pure/global"
|
||
|
"pure/model"
|
||
|
"pure/model/request"
|
||
|
"pure/model/response"
|
||
|
"pure/utils"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
similarityThreshold = 0.6
|
||
|
)
|
||
|
|
||
|
func UserRegister(req *request.UserRegister, filePath, zwPath string) (err error, userInter *model.User) {
|
||
|
var user model.User
|
||
|
global.MG_DB.Where("user_id = ?", req.UserID).First(&user)
|
||
|
if user.UserID != "" {
|
||
|
return errors.New("用户已存在"), nil
|
||
|
}
|
||
|
err, _ = FindMostSimilarUser(req.FeatureCode)
|
||
|
if err == nil {
|
||
|
return errors.New("相似度大于阈值,用户已存在"), nil
|
||
|
}
|
||
|
user.UserID = req.UserID
|
||
|
user.JmFile = filePath
|
||
|
user.FeatureCode = req.FeatureCode
|
||
|
user.ZwFile = zwPath
|
||
|
if err = global.MG_DB.Create(&user).Error; err != nil {
|
||
|
err = errors.New("创建用户失败")
|
||
|
return
|
||
|
}
|
||
|
return nil, &user
|
||
|
}
|
||
|
|
||
|
func UserIdentify(req *request.UserIdentify) (err error, userInter response.UserIdentify) {
|
||
|
var (
|
||
|
user []model.User
|
||
|
maxSimilarity float64 = 0
|
||
|
foundAboveThreshold bool
|
||
|
)
|
||
|
if req.FeatureCode == "" {
|
||
|
err = errors.New("特征码不能为空")
|
||
|
return
|
||
|
}
|
||
|
err = global.MG_DB.Find(&user).Error
|
||
|
if err != nil {
|
||
|
err = errors.New("用户不存在")
|
||
|
return
|
||
|
}
|
||
|
var wg sync.WaitGroup
|
||
|
resultCh := make(chan struct {
|
||
|
similarity float64
|
||
|
id string
|
||
|
})
|
||
|
|
||
|
// 并行计算相似度并寻找最相似的特征
|
||
|
for _, feature := range user {
|
||
|
wg.Add(1)
|
||
|
go func(feat model.User) {
|
||
|
defer wg.Done()
|
||
|
sim := utils.CosineSimilarity(req.FeatureCode, feat.FeatureCode)
|
||
|
fmt.Println(sim)
|
||
|
resultCh <- struct {
|
||
|
similarity float64
|
||
|
id string
|
||
|
}{sim, feat.UserID}
|
||
|
}(feature)
|
||
|
}
|
||
|
|
||
|
// 等待所有goroutines完成
|
||
|
go func() {
|
||
|
wg.Wait()
|
||
|
close(resultCh)
|
||
|
}()
|
||
|
for result := range resultCh {
|
||
|
if result.similarity > maxSimilarity {
|
||
|
maxSimilarity = result.similarity
|
||
|
userInter.UserID = result.id
|
||
|
if maxSimilarity >= similarityThreshold {
|
||
|
foundAboveThreshold = true
|
||
|
userInter.Similarity = utils.Float64ToString(maxSimilarity)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if !foundAboveThreshold {
|
||
|
return errors.New("未找到相似用户"), userInter
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func FindMostSimilarUser(code string) (error, response.UserIdentify) {
|
||
|
var user []model.User
|
||
|
err := global.MG_DB.Find(&user).Error
|
||
|
if err != nil {
|
||
|
return errors.New("用户不存在"), response.UserIdentify{}
|
||
|
}
|
||
|
if len(user) == 0 {
|
||
|
|
||
|
}
|
||
|
var wg sync.WaitGroup
|
||
|
resultCh := make(chan struct {
|
||
|
similarity float64
|
||
|
id string
|
||
|
})
|
||
|
// 并行计算相似度
|
||
|
for _, feature := range user {
|
||
|
wg.Add(1)
|
||
|
go func(feat model.User) {
|
||
|
defer wg.Done()
|
||
|
|
||
|
sim := utils.CosineSimilarity(code, feat.FeatureCode)
|
||
|
resultCh <- struct {
|
||
|
similarity float64
|
||
|
id string
|
||
|
}{similarity: sim, id: feat.UserID}
|
||
|
}(feature)
|
||
|
}
|
||
|
|
||
|
// 等待所有goroutines完成
|
||
|
go func() {
|
||
|
wg.Wait()
|
||
|
close(resultCh)
|
||
|
}()
|
||
|
|
||
|
maxSimilarity := 0.0
|
||
|
foundAboveThreshold := false
|
||
|
userInter := response.UserIdentify{}
|
||
|
|
||
|
// 处理结果并找到最相似的用户
|
||
|
for result := range resultCh {
|
||
|
if result.similarity > maxSimilarity {
|
||
|
maxSimilarity = result.similarity
|
||
|
userInter.UserID = result.id
|
||
|
if maxSimilarity >= similarityThreshold {
|
||
|
foundAboveThreshold = true
|
||
|
userInter.Similarity = utils.Float64ToString(maxSimilarity)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 检查是否找到相似度高于阈值的用户
|
||
|
if !foundAboveThreshold {
|
||
|
return errors.New("未找到相似用户"), userInter
|
||
|
}
|
||
|
|
||
|
return nil, userInter
|
||
|
}
|