package service
|
|
import (
|
"github.com/shopspring/decimal"
|
"gorm.io/gorm"
|
"math"
|
"silkserver/constvar"
|
"silkserver/models"
|
"silkserver/utils"
|
"sort"
|
)
|
|
// FinenessCheck 纤度检查
|
func FinenessCheck(finenessRegister *models.FinenessRegister, standardMap map[string]*Standard, endCarMap map[int]bool, isNew bool) (err error) {
|
finenessCheckItems := make([]*models.FinenessCheckItem, 0)
|
var lastCarNo int
|
var allFinenessList []decimal.Decimal
|
var personFinenessList []decimal.Decimal
|
//var carCheckNumber = 0 //单个car已检查样本数
|
|
var item *models.FinenessCheckItem
|
var deviation, totalDeviation decimal.Decimal
|
var finenessGrade string
|
var roundingItemMap = make(map[float32]*models.FinenessRoundingItem, 0)
|
lastCarNo = finenessRegister.FinenessList[0].Position
|
for _, finenessItem := range finenessRegister.FinenessList {
|
if lastCarNo != finenessItem.Position { //每个车号存一个models.FinenessCheckItem
|
//carCheckNumber = 0
|
lastCarNo = finenessItem.Position
|
}
|
roundedHalfFineness := ToRoundedHalfFineness(finenessItem.Fineness) //类似四舍五入
|
fineness := decimal.NewFromFloat32(roundedHalfFineness)
|
for i := 0; i < finenessItem.Quantity; i++ {
|
allFinenessList = append(allFinenessList, fineness)
|
personFinenessList = append(personFinenessList, fineness)
|
}
|
|
if roundingItemMap[roundedHalfFineness] == nil {
|
roundingItemMap[roundedHalfFineness] = &models.FinenessRoundingItem{
|
Fineness: fineness,
|
Quantity: finenessItem.Quantity,
|
}
|
} else {
|
roundingItemMap[roundedHalfFineness].Quantity += finenessItem.Quantity
|
}
|
|
//carCheckNumber++
|
//if carCheckNumber == constvar.EveryPersonCarCheckNumber { //每人每车号取两个丝,所以每两个等于一个车号,存一行 models.FinenessCheckItem
|
// carCheckNumber = 0
|
if endCarMap[finenessItem.Position] { //走到了某个人最后的车号,每人算一次偏差和等级
|
deviation = utils.Deviation(personFinenessList)
|
totalDeviation = utils.TotalDeviation(personFinenessList, utils.Average(personFinenessList))
|
finenessGrade = CalcFinenessGrade(deviation, totalDeviation, decimal.Zero, decimal.Zero, decimal.Zero, standardMap)
|
personFinenessList = personFinenessList[:0]
|
} else {
|
deviation = decimal.Zero
|
totalDeviation = decimal.Zero
|
finenessGrade = ""
|
}
|
item = MakeFinenessCheckItem(roundingItemMap, finenessRegister.ID, lastCarNo, deviation, totalDeviation, finenessGrade)
|
finenessCheckItems = append(finenessCheckItems, item)
|
roundingItemMap = make(map[float32]*models.FinenessRoundingItem, 0) //重置
|
//}
|
}
|
|
finenessCheck := models.FinenessCheck{
|
FinenessRegisterID: finenessRegister.ID,
|
AverageFineness: utils.Average(allFinenessList),
|
Deviation: utils.Deviation(allFinenessList),
|
TotalDeviation: decimal.Decimal{},
|
Cleanliness: decimal.Decimal{},
|
Purity: decimal.Decimal{},
|
TwiceChange: decimal.Decimal{},
|
MarketProcessOrderNumber: "",
|
Inspector: "",
|
}
|
finenessCheck.TotalDeviation = utils.TotalDeviation(allFinenessList, finenessCheck.AverageFineness)
|
finenessCheck.FinenessGrade = CalcFinenessGrade(finenessCheck.Deviation, finenessCheck.TotalDeviation, finenessCheck.Cleanliness, finenessCheck.Purity, finenessCheck.TwiceChange, standardMap)
|
|
err = models.WithTransaction(func(db *gorm.DB) error {
|
if !isNew {
|
err = models.NewFinenessCheckSearch().SetOrm(db).SetFinenessRegisterID(finenessRegister.ID).Delete()
|
if err != nil {
|
return err
|
}
|
err = models.NewFinenessCheckItemSearch().SetOrm(db).SetFinenessRegisterID(finenessRegister.ID).Delete()
|
if err != nil {
|
return err
|
}
|
}
|
err := models.NewFinenessCheckSearch().SetOrm(db).Create(&finenessCheck)
|
if err != nil {
|
return err
|
}
|
if len(finenessCheckItems) > 0 {
|
for _, v := range finenessCheckItems {
|
v.FinenessCheckID = finenessCheck.ID
|
}
|
err = models.NewFinenessCheckItemSearch().SetOrm(db).CreateBatch(finenessCheckItems)
|
if err != nil {
|
return err
|
}
|
}
|
|
return models.NewFinenessRegisterSearch().SetOrm(db).SetID(finenessRegister.ID).UpdateByMap(map[string]interface{}{"fineness_check_id": finenessCheck.ID})
|
})
|
return err
|
}
|
|
// MakeFinenessCheckItem 纤度检查明细
|
func MakeFinenessCheckItem(roundingItemMap map[float32]*models.FinenessRoundingItem, finenessRegisterID uint, position int, deviation, totalDeviation decimal.Decimal, finenessGrade string) *models.FinenessCheckItem {
|
roundingItems := make([]*models.FinenessRoundingItem, 0, len(roundingItemMap))
|
for _, v := range roundingItemMap {
|
roundingItems = append(roundingItems, &models.FinenessRoundingItem{
|
Fineness: v.Fineness,
|
Quantity: v.Quantity,
|
})
|
}
|
item := &models.FinenessCheckItem{
|
FinenessRegisterID: finenessRegisterID,
|
Position: position,
|
FinenessRoundingItems: roundingItems,
|
Deviation: deviation,
|
TotalDeviation: totalDeviation,
|
FinenessGrade: finenessGrade,
|
Remark: "",
|
}
|
|
return item
|
}
|
|
type gradeRank struct {
|
gradeName string
|
gradeRank int
|
}
|
|
// CalcFinenessGrade 纤度等级
|
func CalcFinenessGrade(deviation, totalDeviation, cleanliness, purity, twiceChange decimal.Decimal, standardMap map[string]*Standard) (gradeName string) {
|
checkItemGradeMap := make(map[constvar.CheckItem]string, 5)
|
gradeRanks := make([]gradeRank, 0)
|
for _, st := range standardMap {
|
grade := ""
|
for _, pair := range st.ValueList {
|
switch st.CheckItem {
|
case constvar.CheckItemDeviation:
|
if st.SortType == ValueTypeSmallerBetter {
|
if deviation.LessThanOrEqual(pair.RankValue) {
|
grade = pair.RankName
|
}
|
} else {
|
if deviation.GreaterThanOrEqual(pair.RankValue) {
|
grade = pair.RankName
|
}
|
}
|
case constvar.CheckItemMaxDeviation:
|
if st.SortType == ValueTypeSmallerBetter {
|
if totalDeviation.LessThanOrEqual(pair.RankValue) {
|
grade = pair.RankName
|
}
|
} else {
|
if totalDeviation.GreaterThanOrEqual(pair.RankValue) {
|
grade = pair.RankName
|
}
|
}
|
case constvar.CheckItemTwiceChange:
|
if st.SortType == ValueTypeSmallerBetter {
|
if twiceChange.LessThanOrEqual(pair.RankValue) {
|
grade = pair.RankName
|
}
|
} else {
|
if twiceChange.GreaterThanOrEqual(pair.RankValue) {
|
grade = pair.RankName
|
}
|
}
|
case constvar.CheckItemCleanliness:
|
if st.SortType == ValueTypeSmallerBetter {
|
if cleanliness.LessThanOrEqual(pair.RankValue) {
|
grade = pair.RankName
|
}
|
} else {
|
if cleanliness.GreaterThanOrEqual(pair.RankValue) {
|
grade = pair.RankName
|
}
|
}
|
case constvar.CheckItemPurity:
|
if st.SortType == ValueTypeSmallerBetter {
|
if purity.LessThanOrEqual(pair.RankValue) {
|
grade = pair.RankName
|
}
|
} else {
|
if purity.GreaterThanOrEqual(pair.RankValue) {
|
grade = pair.RankName
|
}
|
}
|
}
|
if grade != "" {
|
break
|
}
|
}
|
if grade == "" {
|
grade = constvar.BadFinenessGradeC
|
}
|
checkItemGradeMap[st.CheckItem] = grade
|
gradeRanks = append(gradeRanks, gradeRank{
|
gradeName: grade,
|
gradeRank: st.GradeRank[grade],
|
})
|
}
|
if len(gradeRanks) == 0 {
|
return ""
|
}
|
sort.Slice(gradeRanks, func(i, j int) bool {
|
return gradeRanks[i].gradeRank < gradeRanks[j].gradeRank
|
})
|
return gradeRanks[0].gradeName
|
}
|
|
// ToRoundedHalfFineness 小数处理(类似四舍五入)
|
func ToRoundedHalfFineness(fineness float32) float32 {
|
intPart := int(fineness)
|
diff := fineness - float32(intPart)
|
|
var result float32
|
|
if diff < 0.25 {
|
result = float32(intPart)
|
} else if diff < 0.75 {
|
result = float32(intPart) + 0.5
|
} else {
|
result = float32(intPart + 1)
|
}
|
|
// 保留一位小数,并在整数情况下在小数点后加一个零
|
result = float32(math.Round(float64(result)*10) / 10)
|
return result
|
}
|