Merge branch 'master' of http://192.168.5.5:10010/r/silk/silkServer
| | |
| | | type BadFinenessGrade string |
| | | |
| | | const ( |
| | | BadFinenessGradeA = "badA" |
| | | BadFinenessGradeB = "badB" |
| | | BadFinenessGradeC = "badC" |
| | | BadFinenessGradeA = "野纤" |
| | | BadFinenessGradeB = "大野" |
| | | BadFinenessGradeC = "特野" |
| | | ) |
| | | |
| | | const ( |
| | |
| | | import ( |
| | | "errors" |
| | | "github.com/gin-gonic/gin" |
| | | "github.com/shopspring/decimal" |
| | | "gorm.io/gorm" |
| | | "silkserver/controllers/request" |
| | | "silkserver/controllers/response" |
| | |
| | | "silkserver/pkg/logx" |
| | | "silkserver/pkg/structx" |
| | | "silkserver/service" |
| | | "strings" |
| | | ) |
| | | |
| | | type FinenessController struct{} |
| | |
| | | return |
| | | } |
| | | |
| | | silkStandard, err := service.GetSilkRankStandard() |
| | | if err := slf.ParamsCheck(params); err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, err.Error()) |
| | | return |
| | | } |
| | | |
| | | specArr := strings.Split(params.Spec, "/") |
| | | start, _ := decimal.NewFromString(specArr[0]) |
| | | end, _ := decimal.NewFromString(specArr[1]) |
| | | silkStandard, err := service.GetSilkRankStandard(start, end) |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, err.Error()) |
| | | return |
| | |
| | | |
| | | endCarMap, err := service.GetWorkshopEndCarMap(params.WorkshopNumber, params.WorkshopGroup) |
| | | if len(endCarMap) == 0 { |
| | | util.ResponseFormat(c, code.RequestParamError, "请对该车间和车组进行车号设置") |
| | | return |
| | | } |
| | | |
| | | if err := slf.ParamsCheck(params); err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, err.Error()) |
| | | util.ResponseFormat(c, code.RequestParamError, "该车间未配置车号,请在车间管理中配置!") |
| | | return |
| | | } |
| | | |
| | |
| | | }) |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "保存失败") |
| | | return |
| | | } |
| | | |
| | | err = service.FinenessCheck(¶ms, silkStandard, endCarMap, isNew) |
| | |
| | | } |
| | | |
| | | func (slf FinenessController) ParamsCheck(params models.FinenessRegister) (err error) { |
| | | if params.Spec == "" || !strings.Contains(params.Spec, "/") { |
| | | return errors.New("规格格式不正确") |
| | | } |
| | | |
| | | specArr := strings.Split(params.Spec, "/") |
| | | |
| | | _, err = decimal.NewFromString(specArr[0]) |
| | | if err != nil { |
| | | return errors.New("规格格式不正确") |
| | | } |
| | | _, err = decimal.NewFromString(specArr[1]) |
| | | if err != nil { |
| | | return errors.New("规格格式不正确") |
| | | } |
| | | |
| | | if params.WorkshopNumber == "" || params.WorkshopGroup == 0 { |
| | | return errors.New("车间车组参数缺失") |
| | | } |
| | | |
| | | if len(params.FinenessList) == 0 { |
| | | return errors.New("纤度列表缺失") |
| | | } |
| | | |
| | | if params.ID == 0 { |
| | | _, err = models.NewFinenessRegisterSearch().SetNumber(params.Number).First() |
| | | if err != gorm.ErrRecordNotFound { |
| | |
| | | // @Tags 纤度检验 |
| | | // @Summary 纤度检验修改 |
| | | // @Produce application/json |
| | | // @Param object body models.FinenessCheck true "字典信息" |
| | | // @Param object body response.FinenessCheckInfo true "参数" |
| | | // @Param Authorization header string true "token" |
| | | // @Success 200 {object} util.Response "成功" |
| | | // @Router /api-jl/v1/fineness/check [post] |
| | | // @Router /api-jl/v1/fineness/check [PUT] |
| | | func (slf FinenessController) CheckEdit(c *gin.Context) { |
| | | var params models.FinenessCheck |
| | | var params response.FinenessCheckInfo |
| | | if err := c.BindJSON(¶ms); err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误") |
| | | return |
| | | } |
| | | if params.Info == nil || params.Info.FinenessRegisterID == 0 || len(params.Items) == 0 { |
| | | util.ResponseFormat(c, code.RequestParamError, "参数缺失") |
| | | return |
| | | } |
| | | |
| | | _, err := models.NewFinenessCheckSearch().SetID(params.ID).First() |
| | | _, err := models.NewFinenessCheckSearch().SetID(params.Info.ID).First() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "检验记录不存在") |
| | | return |
| | | } |
| | | |
| | | err = service.FinenessReCheck(¶ms) |
| | | check := params.Info |
| | | finenessRegister, err := models.NewFinenessRegisterSearch().SetID(check.FinenessRegisterID).First() |
| | | if err != nil { |
| | | logx.Errorf("service.FinenessReCheck err:%v, finenessCheck:%+v", err, params) |
| | | util.ResponseFormat(c, code.RequestParamError, "检验失败") |
| | | util.ResponseFormat(c, code.RequestParamError, "纤度登记不存在") |
| | | return |
| | | } |
| | | specArr := strings.Split(finenessRegister.Spec, "/") |
| | | start, _ := decimal.NewFromString(specArr[0]) |
| | | end, _ := decimal.NewFromString(specArr[1]) |
| | | standardMap, err := service.GetSilkRankStandard(start, end) |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, err.Error()) |
| | | return |
| | | } |
| | | check.FinenessGrade = service.CalcFinenessGrade(check.Deviation, check.TotalDeviation, check.Cleanliness, check.Purity, check.TwiceChange, standardMap) |
| | | |
| | | items := params.Items |
| | | |
| | | for _, item := range items { |
| | | if item.FinenessGrade != "" { |
| | | item.FinenessGrade = service.CalcFinenessGrade(item.Deviation, item.TotalDeviation, item.Cleanliness, item.Purity, item.TwiceChange, standardMap) |
| | | } |
| | | } |
| | | |
| | | err = models.WithTransaction(func(db *gorm.DB) error { |
| | | err = models.NewFinenessCheckSearch().SetOrm(db).Save(params.Info) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | |
| | | for _, item := range items { |
| | | if item.FinenessGrade == "" { |
| | | continue |
| | | } |
| | | err = models.NewFinenessCheckItemSearch().SetOrm(db).SetID(item.ID).UpdateByMap(map[string]interface{}{"fineness_grade": item.FinenessGrade}) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | } |
| | | return nil |
| | | }) |
| | | |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.SaveFail, "保存失败") |
| | | return |
| | | } |
| | | |
| | | err = models.NewFinenessCheckSearch().Save(¶ms) |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "保存失败") |
| | | return |
| | | } |
| | | util.ResponseFormat(c, code.Success, "保存成功") |
| | | } |
| | |
| | | } |
| | | } |
| | | }, |
| | | "post": { |
| | | "put": { |
| | | "produces": [ |
| | | "application/json" |
| | | ], |
| | |
| | | "summary": "纤度检验修改", |
| | | "parameters": [ |
| | | { |
| | | "description": "字典信息", |
| | | "description": "参数", |
| | | "name": "object", |
| | | "in": "body", |
| | | "required": true, |
| | | "schema": { |
| | | "$ref": "#/definitions/models.FinenessCheck" |
| | | "$ref": "#/definitions/response.FinenessCheckInfo" |
| | | } |
| | | }, |
| | | { |
| | | "type": "string", |
| | | "description": "token", |
| | | "name": "Authorization", |
| | | "in": "header", |
| | | "required": true |
| | | } |
| | | ], |
| | | "responses": { |
| | |
| | | } |
| | | } |
| | | }, |
| | | "post": { |
| | | "put": { |
| | | "produces": [ |
| | | "application/json" |
| | | ], |
| | |
| | | "summary": "纤度检验修改", |
| | | "parameters": [ |
| | | { |
| | | "description": "字典信息", |
| | | "description": "参数", |
| | | "name": "object", |
| | | "in": "body", |
| | | "required": true, |
| | | "schema": { |
| | | "$ref": "#/definitions/models.FinenessCheck" |
| | | "$ref": "#/definitions/response.FinenessCheckInfo" |
| | | } |
| | | }, |
| | | { |
| | | "type": "string", |
| | | "description": "token", |
| | | "name": "Authorization", |
| | | "in": "header", |
| | | "required": true |
| | | } |
| | | ], |
| | | "responses": { |
| | |
| | | summary: 纤度检验列表 |
| | | tags: |
| | | - 纤度检验 |
| | | post: |
| | | put: |
| | | parameters: |
| | | - description: 字典信息 |
| | | - description: 参数 |
| | | in: body |
| | | name: object |
| | | required: true |
| | | schema: |
| | | $ref: '#/definitions/models.FinenessCheck' |
| | | $ref: '#/definitions/response.FinenessCheckInfo' |
| | | - description: token |
| | | in: header |
| | | name: Authorization |
| | | required: true |
| | | type: string |
| | | produces: |
| | | - application/json |
| | | responses: |
| | |
| | | return slf |
| | | } |
| | | |
| | | func (slf *RawSilkRankStandardSearch) SetFineness(start, end decimal.Decimal) *RawSilkRankStandardSearch { |
| | | slf.StartFineness, slf.EndFineness = start, end |
| | | return slf |
| | | } |
| | | |
| | | func (slf *RawSilkRankStandardSearch) build() *gorm.DB { |
| | | db := slf.Orm.Table(slf.TableName()) |
| | | |
| | |
| | | db = db.Where("id = ?", slf.ID) |
| | | } |
| | | |
| | | if !slf.StartFineness.IsZero() || !slf.EndFineness.IsZero() { |
| | | db = db.Where("start_fineness = ? and end_fineness = ?", slf.StartFineness, slf.EndFineness) |
| | | } |
| | | |
| | | return db |
| | | } |
| | | |
| | |
| | | var carCheckNumber = 0 //单个car已检查样本数 |
| | | |
| | | var item *models.FinenessCheckItem |
| | | var deviation decimal.Decimal |
| | | 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 { |
| | | roundedHalfFineness := ToRoundedHalfFineness(finenessItem.Fineness) |
| | | 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) |
| | | carCheckNumber++ |
| | | if carCheckNumber == constvar.EveryPersonCarCheckNumber { |
| | | carCheckNumber = 0 |
| | | if endCarMap[finenessItem.Position] { //走到了某个人最后的车号,每人算一次偏差和等级 |
| | | deviation = utils.Deviation(personFinenessList) |
| | | finenessGrade = CalcFinenessGrade(item.Deviation, item.TotalDeviation, item.Cleanliness, item.Purity, item.TwiceChange, standardMap) |
| | | personFinenessList = personFinenessList[:0] |
| | | } |
| | | } |
| | | if lastCarNo != finenessItem.Position { //每个车号存一个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: finenessRegister.ID, |
| | | Position: lastCarNo, |
| | | FinenessRoundingItems: roundingItems, |
| | | Deviation: deviation, |
| | | FinenessGrade: finenessGrade, |
| | | Remark: "", |
| | | } |
| | | |
| | | finenessCheckItems = append(finenessCheckItems, item) |
| | | lastCarNo = finenessItem.Position |
| | | roundingItemMap = make(map[float32]*models.FinenessRoundingItem, 0) |
| | | personFinenessList = append(personFinenessList, fineness) |
| | | } |
| | | |
| | | if roundingItemMap[roundedHalfFineness] == nil { |
| | |
| | | } |
| | | } else { |
| | | roundingItemMap[roundedHalfFineness].Quantity += finenessItem.Quantity |
| | | } |
| | | |
| | | carCheckNumber++ |
| | | if carCheckNumber == constvar.EveryPersonCarCheckNumber { |
| | | carCheckNumber = 0 |
| | | if endCarMap[finenessItem.Position] { //走到了某个人最后的车号,每人算一次偏差和等级 |
| | | deviation = utils.Deviation(personFinenessList) |
| | | totalDeviation = 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) //重置 |
| | | } |
| | | } |
| | | |
| | |
| | | return err |
| | | } |
| | | |
| | | 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 |
| | |
| | | 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 st.SortType == ValueTypeSmallerBetter { |
| | | if deviation.LessThanOrEqual(pair.RankValue) { |
| | | grade = pair.RankName |
| | | } |
| | |
| | | } |
| | | } |
| | | case constvar.CheckItemMaxDeviation: |
| | | if st.SortType == SortTypeAsc { |
| | | if st.SortType == ValueTypeSmallerBetter { |
| | | if totalDeviation.LessThanOrEqual(pair.RankValue) { |
| | | grade = pair.RankName |
| | | } |
| | |
| | | } |
| | | } |
| | | case constvar.CheckItemTwiceChange: |
| | | if st.SortType == SortTypeAsc { |
| | | if st.SortType == ValueTypeSmallerBetter { |
| | | if twiceChange.LessThanOrEqual(pair.RankValue) { |
| | | grade = pair.RankName |
| | | } |
| | |
| | | } |
| | | } |
| | | case constvar.CheckItemCleanliness: |
| | | if st.SortType == SortTypeAsc { |
| | | if st.SortType == ValueTypeSmallerBetter { |
| | | if cleanliness.LessThanOrEqual(pair.RankValue) { |
| | | grade = pair.RankName |
| | | } |
| | |
| | | } |
| | | } |
| | | case constvar.CheckItemPurity: |
| | | if st.SortType == SortTypeAsc { |
| | | if st.SortType == ValueTypeSmallerBetter { |
| | | if purity.LessThanOrEqual(pair.RankValue) { |
| | | grade = pair.RankName |
| | | } |
| | |
| | | break |
| | | } |
| | | } |
| | | if grade != "" { |
| | | checkItemGradeMap[st.CheckItem] = grade |
| | | gradeRanks = append(gradeRanks, gradeRank{ |
| | | gradeName: grade, |
| | | gradeRank: st.GradeRank[grade], |
| | | }) |
| | | if grade == "" { |
| | | grade = constvar.BadFinenessGradeC |
| | | } |
| | | checkItemGradeMap[st.CheckItem] = grade |
| | | gradeRanks = append(gradeRanks, gradeRank{ |
| | | gradeName: grade, |
| | | gradeRank: st.GradeRank[grade], |
| | | }) |
| | | } |
| | | if len(gradeRanks) == 0 { |
| | | return "" |
| | |
| | | // 保留一位小数,并在整数情况下在小数点后加一个零 |
| | | result = float32(math.Round(float64(result)*10) / 10) |
| | | return result |
| | | } |
| | | |
| | | func FinenessReCheck(finenessCheck *models.FinenessCheck) (err error) { |
| | | standardMap, err := GetSilkRankStandard() |
| | | if err != nil { |
| | | return err |
| | | } |
| | | finenessCheck.FinenessGrade = CalcFinenessGrade(finenessCheck.Deviation, finenessCheck.TotalDeviation, finenessCheck.Cleanliness, finenessCheck.Purity, finenessCheck.TwiceChange, standardMap) |
| | | return |
| | | } |
| | | |
| | | func TotalDeviation(numbers []decimal.Decimal, average decimal.Decimal) decimal.Decimal { |
| | |
| | | EndFineness decimal.Decimal |
| | | GradeMap map[string]struct{} |
| | | ValueList []*Pair |
| | | SortType SortType |
| | | SortType ValueType |
| | | GradeRank map[string]int |
| | | } |
| | | |
| | |
| | | RankValue decimal.Decimal |
| | | } |
| | | |
| | | type SortType int |
| | | type ValueType int |
| | | |
| | | const ( |
| | | SortTypeAsc SortType = 0 |
| | | SortTypeDesc SortType = 1 |
| | | ValueTypeSmallerBetter ValueType = 0 //值按升序排名(值越大,等级越高) |
| | | ValueTypeGreaterBetter ValueType = 1 //值按降序排名(值越小,等级越低) |
| | | ) |
| | | |
| | | var sortTypeMap = map[constvar.CheckItem]SortType{ |
| | | constvar.CheckItemDeviation: SortTypeAsc, |
| | | constvar.CheckItemTwiceChange: SortTypeAsc, |
| | | constvar.CheckItemCleanliness: SortTypeDesc, |
| | | constvar.CheckItemPurity: SortTypeDesc, |
| | | constvar.CheckItemMaxDeviation: SortTypeAsc, |
| | | var sortTypeMap = map[constvar.CheckItem]ValueType{ |
| | | constvar.CheckItemDeviation: ValueTypeSmallerBetter, |
| | | constvar.CheckItemTwiceChange: ValueTypeSmallerBetter, |
| | | constvar.CheckItemCleanliness: ValueTypeGreaterBetter, |
| | | constvar.CheckItemPurity: ValueTypeGreaterBetter, |
| | | constvar.CheckItemMaxDeviation: ValueTypeSmallerBetter, |
| | | } |
| | | |
| | | func GetSilkRankStandard() (map[string]*Standard, error) { |
| | | rankStandards, err := models.NewRawSilkRankStandardSearch().FindNotTotal() |
| | | func GetSilkRankStandard(startFineness, endFineness decimal.Decimal) (map[string]*Standard, error) { |
| | | rankStandards, err := models.NewRawSilkRankStandardSearch().SetFineness(startFineness, endFineness).FindNotTotal() |
| | | if err != nil { |
| | | return nil, err |
| | | } |
| | |
| | | } |
| | | } |
| | | //value排序 |
| | | for k := range standardMap { |
| | | 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 { |
| | | if sortType == ValueTypeSmallerBetter { |
| | | 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) |
| | | } |
| | | }) |
| | | } |
| | | //等级排名 |
| | | //等级排名 GradeRank越大,等级越高 |
| | | for lineId, standard := range standardMap { |
| | | for k, pair := range standard.ValueList { |
| | | if standardMap[lineId].GradeRank == nil { |
| | | standardMap[lineId].GradeRank = make(map[string]int, 0) |
| | | } |
| | | if standard.SortType == SortTypeAsc { |
| | | standardMap[lineId].GradeRank[pair.RankName] = k + 1 |
| | | } else { |
| | | standardMap[lineId].GradeRank[pair.RankName] = len(standard.ValueList) - k |
| | | } |
| | | standardMap[lineId].GradeRank[pair.RankName] = len(standard.ValueList) - k |
| | | } |
| | | } |
| | | return standardMap, nil |