From 1a2e7a46273fdb6eb53348f4e06100aa7854c3cf Mon Sep 17 00:00:00 2001 From: zhangqian <zhangqian@123.com> Date: 星期二, 12 三月 2024 19:35:27 +0800 Subject: [PATCH] 新增或保存纤度登记表后进行纤度检查并保存结果到纤度检查表 --- constvar/const.go | 8 + models/fineness_check_item.go | 22 +- extend/code/code.go | 25 +- service/fineness.go | 193 +++++++++++++++++++++++++++ service/silk_rank.go | 112 ++++++++++++++++ controllers/fineness.go | 8 + models/fineness_check.go | 6 utils/mathx.go | 30 ++++ models/fineness_item.go | 4 9 files changed, 378 insertions(+), 30 deletions(-) diff --git a/constvar/const.go b/constvar/const.go index c255f71..1aa8b1b 100644 --- a/constvar/const.go +++ b/constvar/const.go @@ -34,3 +34,11 @@ CheckItemPurity //娲佸噣鍒� CheckItemMaxDeviation //鏈�澶у亸宸� ) + +type BadFinenessGrade string + +const ( + BadFinenessGradeA = "badA" + BadFinenessGradeB = "badB" + BadFinenessGradeC = "badC" +) diff --git a/controllers/fineness.go b/controllers/fineness.go index 6760b3b..43981d1 100644 --- a/controllers/fineness.go +++ b/controllers/fineness.go @@ -8,7 +8,9 @@ "silkserver/extend/util" "silkserver/models" "silkserver/pkg/convertx" + "silkserver/pkg/logx" "silkserver/pkg/structx" + "silkserver/service" ) type FinenessController struct{} @@ -52,6 +54,12 @@ util.ResponseFormat(c, code.RequestParamError, "淇濆瓨澶辫触") } + err = service.FinenessCheck(¶ms) + if err != nil { + logx.Errorf("service.FinenessCheck err:%v, finenessRegister:%+v", err, params) + util.ResponseFormat(c, code.RequestParamError, "鐢熸垚妫�楠岃〃澶辫触") + } + util.ResponseFormat(c, code.Success, "淇濆瓨鎴愬姛") } diff --git a/extend/code/code.go b/extend/code/code.go index 23016bf..6838258 100644 --- a/extend/code/code.go +++ b/extend/code/code.go @@ -8,22 +8,21 @@ Message string `json:"msg"` // 鎻忚堪淇℃伅 } +// 瀹炵幇 error 鎺ュ彛鐨� Error 鏂规硶 +func (c *Code) Error() string { + return c.Message +} + var ( Success = &Code{http.StatusOK, "璇锋眰澶勭悊鎴愬姛"} UpdateSuccess = &Code{http.StatusOK, "鏇存柊鎴愬姛"} DeleteSuccess = &Code{http.StatusOK, "鍒犻櫎鎴愬姛"} - SaveFail = &Code{3001, "鏂板澶辫触"} - RequestParamError = &Code{3002, "璇锋眰鍙傛暟鏈夎"} - DeleteUsingError = &Code{3003, "鍒犻櫎澶辫触"} - NameExistedError = &Code{3004, "鍚嶇О宸插瓨鍦�"} - OrderSchedulingError = &Code{3005, "璁㈠崟姝e湪鎺掔▼涓�"} - InventoryNotEnoughError = &Code{3006, "鐗╂枡搴撳瓨涓嶈冻"} - UseAmountNotEnoughError = &Code{3007, "浣跨敤鏁伴噺涓嶈冻"} - OrderProductNoProcedureError = &Code{3008, "璁㈠崟浜у搧鏃犲伐搴�"} - SetStatusError = &Code{3009, "璁剧疆鐘舵�佸け璐�"} - NoTemplateError = &Code{3010, "鏈厤缃鍗曟ā鏉�"} - InternalError = &Code{3011, "鍐呴儴閿欒"} - NoProductionRequiredError = &Code{3012, "褰撳墠搴撳瓨婊¤冻姣涢渶姹傞噺锛屾殏鏃舵棤闇�杩涜鐢熶骇"} - SelectError = &Code{3013, "鏌ヨ澶辫触"} + SaveFail = &Code{3001, "鏂板澶辫触"} + RequestParamError = &Code{3002, "璇锋眰鍙傛暟鏈夎"} + DeleteUsingError = &Code{3003, "鍒犻櫎澶辫触"} + NameExistedError = &Code{3004, "鍚嶇О宸插瓨鍦�"} + SelectError = &Code{3013, "鏌ヨ澶辫触"} + + SilkRankStandardNotSetError = &Code{4101, "鐢熶笣鏍囨敞鏈瀹�"} ) diff --git a/models/fineness_check.go b/models/fineness_check.go index 3bdecfe..ebe9d70 100644 --- a/models/fineness_check.go +++ b/models/fineness_check.go @@ -18,9 +18,9 @@ Deviation decimal.Decimal `gorm:"type:decimal(12,2);not null;comment:鍋忓樊" json:"deviation"` //鍋忓樊 TotalDeviation decimal.Decimal `gorm:"type:decimal(12,2);not null;comment:鎬诲樊" json:"totalDeviation"` //鎬诲樊 FinenessGrade string `gorm:"type:varchar(255);not null;comment:绾ゅ害绛夌骇" json:"finenessGrade"` //绾ゅ害绛夌骇 - Cleanliness string `gorm:"type:varchar(255);not null;comment:娓呮磥搴�" json:"cleanliness"` //娓呮磥搴� - Purity string `gorm:"type:varchar(255);not null;comment:娲佸噣搴�" json:"purity"` //娲佸噣搴� - TwiceChange string `gorm:"type:varchar(255);not null;comment:浜屽害鍙樺寲" json:"twiceChange"` //浜屽害鍙樺寲 + Cleanliness decimal.Decimal `gorm:"type:varchar(255);not null;comment:娓呮磥搴�" json:"cleanliness"` //娓呮磥搴� + Purity decimal.Decimal `gorm:"type:varchar(255);not null;comment:娲佸噣搴�" json:"purity"` //娲佸噣搴� + TwiceChange decimal.Decimal `gorm:"type:varchar(255);not null;comment:浜屽害鍙樺寲" json:"twiceChange"` //浜屽害鍙樺寲 MarketProcessOrderNumber string `gorm:"type:varchar(255);not null;comment:搴勫彛宸ヨ壓鍗曠紪鍙�" json:"marketProcessOrderNumber"` //搴勫彛宸ヨ壓鍗曠紪鍙� Inspector string `gorm:"type:varchar(255);not null;comment:妫�楠屽憳" json:"inspector"` //妫�楠屽憳 } diff --git a/models/fineness_check_item.go b/models/fineness_check_item.go index 0efd875..9a22f55 100644 --- a/models/fineness_check_item.go +++ b/models/fineness_check_item.go @@ -13,22 +13,20 @@ gorm.Model FinenessRegisterID uint `gorm:"not null;comment:绾ゅ害鐧昏琛↖D" json:"finenessRegisterID"` //绾ゅ害鐧昏琛↖D FinenessCheckID uint `gorm:"not null;comment:绾ゅ害妫�楠岃〃ID" json:"finenessCheckID"` //绾ゅ害妫�楠岃〃ID - Position int8 `json:"position"` //杞﹀彿 - FinenessRoundingItem FinenessRoundingItem - AverageFineness decimal.Decimal `gorm:"type:decimal(12,2);not null;comment:骞冲潎绾ゅ害" json:"averageFineness"` //骞冲潎绾ゅ害 - MeasureFineness decimal.Decimal `gorm:"type:decimal(12,2);not null;comment:鍏噺绾ゅ害" json:"measureFineness"` //鍏噺绾ゅ害 - Deviation decimal.Decimal `gorm:"type:decimal(12,2);not null;comment:鍋忓樊" json:"deviation"` //鍋忓樊 - TotalDeviation decimal.Decimal `gorm:"type:decimal(12,2);not null;comment:鎬诲樊" json:"totalDeviation"` //鎬诲樊 - FinenessGrade string `gorm:"type:varchar(255);not null;comment:绾ゅ害绛夌骇" json:"finenessGrade"` //绾ゅ害绛夌骇 - Cleanliness string `gorm:"type:varchar(255);not null;comment:娓呮磥搴�" json:"cleanliness"` //娓呮磥搴� - Purity string `gorm:"type:varchar(255);not null;comment:娲佸噣搴�" json:"purity"` //娲佸噣搴� - TwiceChange string `gorm:"type:varchar(255);not null;comment:浜屽害鍙樺寲" json:"twiceChange"` //浜屽害鍙樺寲 - Remark string `gorm:"type:varchar(255);not null;comment:澶囨敞" json:"remark"` //澶囨敞 + Position int `json:"position"` //杞﹀彿 + FinenessRoundingItem []*FinenessRoundingItem + Deviation decimal.Decimal `gorm:"type:decimal(12,2);not null;comment:鍋忓樊" json:"deviation"` //鍋忓樊 + TotalDeviation decimal.Decimal `gorm:"type:decimal(12,2);not null;comment:鎬诲樊" json:"totalDeviation"` //鎬诲樊 + FinenessGrade string `gorm:"type:varchar(255);not null;comment:绾ゅ害绛夌骇" json:"finenessGrade"` //绾ゅ害绛夌骇 + Cleanliness decimal.Decimal `gorm:"type:varchar(255);not null;comment:娓呮磥搴�" json:"cleanliness"` //娓呮磥搴� + Purity decimal.Decimal `gorm:"type:varchar(255);not null;comment:娲佸噣搴�" json:"purity"` //娲佸噣搴� + TwiceChange decimal.Decimal `gorm:"type:varchar(255);not null;comment:浜屽害鍙樺寲" json:"twiceChange"` //浜屽害鍙樺寲 + Remark string `gorm:"type:varchar(255);not null;comment:澶囨敞" json:"remark"` //澶囨敞 } FinenessRoundingItem struct { Fineness decimal.Decimal `json:"fineness"` //绾ゅ害 - Quantity decimal.Decimal `json:"quantity"` //鏁伴噺 + Quantity int `json:"quantity"` //鏁伴噺 } FinenessCheckItemSearch struct { FinenessCheckItem diff --git a/models/fineness_item.go b/models/fineness_item.go index e6cc5db..5b74633 100644 --- a/models/fineness_item.go +++ b/models/fineness_item.go @@ -12,8 +12,8 @@ FinenessItem struct { gorm.Model FinenessRegisterID uint `json:"finenessRegisterID"` - Position int8 `json:"position"` //杞﹀彿 - Fineness decimal.Decimal `json:"fineness"` //绾ゅ害 + Position int `json:"position"` //杞﹀彿 + Fineness float32 `json:"fineness"` //绾ゅ害 Quantity decimal.Decimal `json:"quantity"` //鏁伴噺 Sum decimal.Decimal `json:"sum"` //绾ゅ害鍚堣 } diff --git a/service/fineness.go b/service/fineness.go new file mode 100644 index 0000000..fc3635b --- /dev/null +++ b/service/fineness.go @@ -0,0 +1,193 @@ +package service + +import ( + "github.com/shopspring/decimal" + "gorm.io/gorm" + "math" + "silkserver/constvar" + "silkserver/models" + "silkserver/utils" + "sort" +) + +func FinenessCheck(finenessRegister *models.FinenessRegister) (err error) { + standardMap, err := GetSilkRankStandard() + if err != nil { + return err + } + //鏁寸悊鎴愭楠岃〃鐨勬暟鎹粨鏋� + finenessRoundingItemMap := make(map[int]map[float32]*models.FinenessRoundingItem) + for _, item := range finenessRegister.FinenessList { + if finenessRoundingItemMap[item.Position] == nil { + finenessRoundingItemMap[item.Position] = make(map[float32]*models.FinenessRoundingItem, 0) + } + roundedHalfFineness := ToRoundedHalfFineness(item.Fineness) + if finenessRoundingItemMap[item.Position][roundedHalfFineness] == nil { + finenessRoundingItemMap[item.Position][roundedHalfFineness] = &models.FinenessRoundingItem{ + Fineness: decimal.NewFromFloat32(roundedHalfFineness), + Quantity: 1, + } + } else { + finenessRoundingItemMap[item.Position][roundedHalfFineness].Quantity++ + } + } + finenessCheckItems := make([]*models.FinenessCheckItem, 0) + var allFinenessList []decimal.Decimal + var personEndFlag bool //璧板埌浜嗘煇涓汉鏈�鍚庣殑杞﹀彿 + var finenessList []decimal.Decimal + var step = 3 //涓存椂鎸変竴涓汉涓変釜杞﹀彿绠椼�� + for pos, roundingItemMap := range finenessRoundingItemMap { + roundingItems := make([]*models.FinenessRoundingItem, 0, len(roundingItemMap)) + for _, v := range roundingItemMap { + roundingItems = append(roundingItems, v) + finenessList = append(finenessList, v.Fineness) + allFinenessList = append(allFinenessList, v.Fineness) + } + + item := &models.FinenessCheckItem{ + FinenessRegisterID: finenessRegister.ID, + Position: pos, + FinenessRoundingItem: roundingItems, + Remark: "", + } + if pos%step == 0 { + personEndFlag = true + } else { + personEndFlag = false + } + if personEndFlag { + item.Deviation = utils.Deviation(finenessList) + item.FinenessGrade = CalcFinenessGrade(item.Deviation, item.TotalDeviation, item.Cleanliness, item.Purity, item.TwiceChange, standardMap) + finenessList = finenessList[:0] + } + + finenessCheckItems = append(finenessCheckItems, item) + } + 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.FinenessGrade = CalcFinenessGrade(finenessCheck.Deviation, finenessCheck.TotalDeviation, finenessCheck.Cleanliness, finenessCheck.Purity, finenessCheck.TwiceChange, standardMap) + + err = models.WithTransaction(func(db *gorm.DB) error { + err := models.NewFinenessCheckSearch().SetOrm(db).Create(&finenessCheck) + if err != nil { + return err + } + return models.NewFinenessCheckItemSearch().SetOrm(db).CreateBatch(finenessCheckItems) + }) + return err +} + +type gradeRank struct { + gradeName string + gradeRank int +} + +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 { + if st.StartFineness.GreaterThan(deviation) || st.EndFineness.LessThan(deviation) { + continue + } + grade := "" + for _, pair := range st.ValueList { + switch st.CheckItem { + case constvar.CheckItemDeviation: + if st.SortType == SortTypeAsc { + if deviation.LessThanOrEqual(pair.RankValue) { + grade = pair.RankName + } + } else { + if deviation.GreaterThanOrEqual(pair.RankValue) { + grade = pair.RankName + } + } + case constvar.CheckItemMaxDeviation: + if st.SortType == SortTypeAsc { + if totalDeviation.LessThanOrEqual(pair.RankValue) { + grade = pair.RankName + } + } else { + if totalDeviation.GreaterThanOrEqual(pair.RankValue) { + grade = pair.RankName + } + } + case constvar.CheckItemTwiceChange: + if st.SortType == SortTypeAsc { + if twiceChange.LessThanOrEqual(pair.RankValue) { + grade = pair.RankName + } + } else { + if twiceChange.GreaterThanOrEqual(pair.RankValue) { + grade = pair.RankName + } + } + case constvar.CheckItemCleanliness: + if st.SortType == SortTypeAsc { + if cleanliness.LessThanOrEqual(pair.RankValue) { + grade = pair.RankName + } + } else { + if cleanliness.GreaterThanOrEqual(pair.RankValue) { + grade = pair.RankName + } + } + case constvar.CheckItemPurity: + if st.SortType == SortTypeAsc { + if purity.LessThanOrEqual(pair.RankValue) { + grade = pair.RankName + } + } else { + if purity.GreaterThanOrEqual(pair.RankValue) { + grade = pair.RankName + } + } + } + if grade != "" { + break + } + } + if grade != "" { + 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 +} + +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 +} diff --git a/service/silk_rank.go b/service/silk_rank.go new file mode 100644 index 0000000..a694467 --- /dev/null +++ b/service/silk_rank.go @@ -0,0 +1,112 @@ +package service + +import ( + "github.com/shopspring/decimal" + "silkserver/constvar" + "silkserver/extend/code" + "silkserver/models" + "sort" +) + +type Standard struct { + CheckItem constvar.CheckItem + StartFineness decimal.Decimal + EndFineness decimal.Decimal + GradeMap map[string]struct{} + ValueList []*Pair + SortType SortType + GradeRank map[string]int +} + +type Pair struct { + RankName string + RankValue decimal.Decimal +} + +type SortType int + +const ( + SortTypeAsc SortType = 0 + SortTypeDesc SortType = 1 +) + +var sortTypeMap = map[constvar.CheckItem]SortType{ + constvar.CheckItemDeviation: SortTypeAsc, + constvar.CheckItemTwiceChange: SortTypeAsc, + constvar.CheckItemCleanliness: SortTypeDesc, + constvar.CheckItemPurity: SortTypeDesc, + constvar.CheckItemMaxDeviation: SortTypeAsc, +} + +func GetSilkRankStandard() (map[string]*Standard, error) { + rankStandards, err := models.NewRawSilkRankStandardSearch().FindNotTotal() + if err != nil { + return nil, err + } + if len(rankStandards) == 0 { + return nil, code.SilkRankStandardNotSetError + } + standardMap := make(map[string]*Standard) + for _, v := range rankStandards { + if standardMap[v.LineId] == nil { + standardMap[v.LineId] = &Standard{ + CheckItem: v.CheckItem, + StartFineness: v.StartFineness, + EndFineness: v.EndFineness, + GradeMap: make(map[string]struct{}), + ValueList: make([]*Pair, 0), + } + } + if _, ok := standardMap[v.LineId].GradeMap[constvar.BadFinenessGradeA]; !ok { + standardMap[v.LineId].ValueList = append(standardMap[v.LineId].ValueList, &Pair{ + RankName: constvar.BadFinenessGradeA, + RankValue: v.RankA, + }) + standardMap[v.LineId].GradeMap[constvar.BadFinenessGradeA] = struct{}{} + } + if _, ok := standardMap[v.LineId].GradeMap[constvar.BadFinenessGradeB]; !ok { + standardMap[v.LineId].ValueList = append(standardMap[v.LineId].ValueList, &Pair{ + RankName: constvar.BadFinenessGradeB, + RankValue: v.RankB, + }) + standardMap[v.LineId].GradeMap[constvar.BadFinenessGradeB] = struct{}{} + } + if _, ok := standardMap[v.LineId].GradeMap[constvar.BadFinenessGradeC]; !ok { + standardMap[v.LineId].ValueList = append(standardMap[v.LineId].ValueList, &Pair{ + RankName: constvar.BadFinenessGradeC, + RankValue: v.RankC, + }) + standardMap[v.LineId].GradeMap[constvar.BadFinenessGradeC] = struct{}{} + } + if _, ok := standardMap[v.LineId].GradeMap[v.RankName]; !ok { + standardMap[v.LineId].ValueList = append(standardMap[v.LineId].ValueList, &Pair{ + RankName: v.RankName, + RankValue: v.RankValue, + }) + standardMap[v.LineId].GradeMap[v.RankName] = struct{}{} + } + } + //value鎺掑簭 + for k := range standardMap { + sort.Slice(standardMap[k].ValueList, func(i, j int) bool { + sortType := sortTypeMap[standardMap[k].CheckItem] + standardMap[k].SortType = sortType + if sortType == SortTypeAsc { + return standardMap[k].ValueList[i].RankValue.LessThan(standardMap[k].ValueList[j].RankValue) + } else { + return standardMap[k].ValueList[i].RankValue.GreaterThan(standardMap[k].ValueList[j].RankValue) + } + }) + } + //绛夌骇鎺掑悕 + for lineId, standard := range standardMap { + for k, pair := range standard.ValueList { + if standard.SortType == SortTypeAsc { + standardMap[lineId].GradeRank[pair.RankName] = k + 1 + } else { + standardMap[lineId].GradeRank[pair.RankName] = len(standard.ValueList) - k + } + } + } + return standardMap, nil +} diff --git a/utils/mathx.go b/utils/mathx.go new file mode 100644 index 0000000..3bbf646 --- /dev/null +++ b/utils/mathx.go @@ -0,0 +1,30 @@ +package utils + +import "github.com/shopspring/decimal" + +func Average(numbers []decimal.Decimal) decimal.Decimal { + if len(numbers) == 0 { + return decimal.Decimal{} + } + if len(numbers) == 1 { + return numbers[0] + } + var sum decimal.Decimal + for _, d := range numbers { + sum = sum.Add(d) + } + return sum.Div(decimal.NewFromInt(int64(len(numbers)))) +} + +func Deviation(numbers []decimal.Decimal) decimal.Decimal { + if len(numbers) == 0 || len(numbers) == 1 { + return decimal.Decimal{} + } + avgNum := Average(numbers) + var diffSquaredSum decimal.Decimal + for _, n := range numbers { + diff := n.Sub(avgNum) + diffSquaredSum = diffSquaredSum.Add(diff.Mul(diff)) + } + return diffSquaredSum.Div(decimal.NewFromInt(int64(len(numbers)))) +} -- Gitblit v1.8.0