Przeglądaj źródła

cow: details update

Yi 2 dni temu
rodzic
commit
1ce9a0197d
49 zmienionych plików z 262 dodań i 169 usunięć
  1. 1 1
      http/middleware/log.go
  2. 0 2
      http/route/event_api.go
  3. 29 16
      model/cow.go
  4. 39 0
      model/cow_pregnant.go
  5. 1 1
      model/crontab_log.go
  6. 2 2
      model/event_cow_disease.go
  7. 1 1
      model/event_enter.go
  8. 1 1
      model/event_immunization_plan.go
  9. 0 5
      model/event_mating.go
  10. 0 1
      model/event_sale.go
  11. 3 3
      model/neck_ring.go
  12. 6 0
      model/neck_ring_bind_log.go
  13. 2 2
      model/outbound.go
  14. 1 1
      model/work_order_master.go
  15. 2 2
      model/work_order_sub.go
  16. 45 33
      module/backend/analysis.go
  17. 3 3
      module/backend/calendar.go
  18. 1 1
      module/backend/calendar_more.go
  19. 1 1
      module/backend/cow.go
  20. 4 4
      module/backend/dashboard.go
  21. 14 15
      module/backend/event_base_more.go
  22. 5 2
      module/backend/event_breed.go
  23. 1 2
      module/backend/event_breed_more.go
  24. 1 1
      module/backend/event_breed_more_more.go
  25. 1 1
      module/backend/event_check.go
  26. 1 1
      module/backend/event_health.go
  27. 7 8
      module/backend/goods.go
  28. 1 1
      module/backend/milk_gea.go
  29. 1 1
      module/backend/neck_ring_warning.go
  30. 1 1
      module/backend/system_service.go
  31. 1 0
      module/backend/test_service.go
  32. 1 1
      module/backend/upload_file.go
  33. 3 3
      module/backend/work.go
  34. 51 21
      module/crontab/cow_cron.go
  35. 5 5
      module/crontab/estrus_warning.go
  36. 1 1
      module/crontab/health_warning.go
  37. 4 4
      module/crontab/neck_ring_calculate.go
  38. 1 1
      module/crontab/neck_ring_estrus.go
  39. 1 1
      module/crontab/neck_ring_estus_test.go
  40. 2 2
      module/crontab/neck_ring_merge.go
  41. 2 2
      module/crontab/other.go
  42. 1 1
      module/crontab/pen_behavior_day.go
  43. 1 1
      module/crontab/work_cron.go
  44. 1 1
      service/asynqsvc/asynq.go
  45. 3 3
      service/excel/interface.go
  46. 1 1
      service/redis/cache.go
  47. 4 4
      util/util.go
  48. 2 2
      util/util_more.go
  49. 2 2
      util/util_test.go

+ 1 - 1
http/middleware/log.go

@@ -34,7 +34,7 @@ func GinLogger() gin.HandlerFunc {
 			requestBody, _ = ioutil.ReadAll(c.Request.Body)
 			c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(requestBody))
 		}
-		start := time.Now()
+		start := time.Now().Local()
 		c.Next()
 		cost := time.Since(start)
 		logFields := []zap.Field{

+ 0 - 2
http/route/event_api.go

@@ -69,11 +69,9 @@ func EventAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		// 免疫
 		eventRoute.POST("/immunization/batch", event.ImmunizationBatch)
 		eventRoute.POST("/immunization/list", event.ImmunizationList)
-
 		// 干奶
 		eventRoute.POST("/dry/milk/batch", event.DryMilkBatch)
 		eventRoute.POST("/dry/milk/list", event.DryMilkList)
-
 		// 禁配
 		eventRoute.POST("/forbidden/mating/batch", event.ForbiddenMatingBatch)
 		eventRoute.POST("/forbidden/mating/list", event.ForbiddenMatingList)

+ 29 - 16
model/cow.go

@@ -34,6 +34,7 @@ type Cow struct {
 	CurrentWeight         int64                          `json:"currentWeight"`         // 当前体重
 	CurrentHeight         int64                          `json:"currentHeight"`         // 当前身高
 	AdmissionWeight       int64                          `json:"admissionWeight"`       // 入场体重
+	AdmissionPrice        float32                        `json:"admissionPrice"`        // 入场价格
 	SourceKind            pasturePb.CowSource_Kind       `json:"sourceKind"`            // 来源哪里
 	PurposeKind           pasturePb.Purpose_Kind         `json:"purposeKind"`           // 用途
 	FatherNumber          string                         `json:"fatherNumber"`          // 父号
@@ -110,10 +111,12 @@ func (c *Cow) EventWeaningUpdate(weaningAt int64, penId int32, currentWeight int
 }
 
 // EventPregnantCheckUpdate 孕检更新
-func (c *Cow) EventPregnantCheckUpdate(breedStatus pasturePb.BreedStatus_Kind, pregnantCheckAt int64, isPregnant pasturePb.IsShow_Kind) {
+func (c *Cow) EventPregnantCheckUpdate(breedStatus pasturePb.BreedStatus_Kind, pregnantCheckAt int64,
+	isPregnant pasturePb.IsShow_Kind, pregnancyCheckName string) {
 	c.BreedStatus = breedStatus
 	c.LastPregnantCheckAt = pregnantCheckAt
 	c.IsPregnant = isPregnant
+	c.PregnancyCheckName = pregnancyCheckName
 }
 
 // EventAbortionUpdate 流产更新
@@ -162,16 +165,20 @@ func (c *Cow) EventDeathUpdate(eventAt int64) {
 }
 
 // EventSaleUpdate 更新牛只销售信息
-func (c *Cow) EventSaleUpdate(eventAt int64, salesType pasturePb.SalesType_Kind) {
-	if salesType == pasturePb.SalesType_Out {
+func (c *Cow) EventSaleUpdate(eventSale *EventSale) {
+	if eventSale.SaleKind == pasturePb.SalesType_Out {
 		c.HealthStatus = pasturePb.HealthStatus_Out
 		c.AdmissionStatus = pasturePb.AdmissionStatus_Out
 	}
-	if salesType == pasturePb.SalesType_Sales {
+	if eventSale.SaleKind == pasturePb.SalesType_Sales {
 		c.AdmissionStatus = pasturePb.AdmissionStatus_Sale
 	}
-	c.DepartureAt = eventAt
+	c.DepartureAt = eventSale.SaleAt
 	c.NeckRingNumber = ""
+	c.DeparturePrice = float32(eventSale.SalePrice)
+	if eventSale.SaleCowCount > 0 {
+		c.DepartureAvgWeight = int32(eventSale.SaleAllWeight / eventSale.SaleCowCount)
+	}
 }
 
 // EventMatingUpdate 配种更新
@@ -360,6 +367,11 @@ func (c CowSlice) ToPB(
 			purposeName = pn
 		}
 
+		pregnancyCheckTimes := "初检"
+		if v.PregnancyCheckName == PregnantCheckForSecond {
+			pregnancyCheckTimes = "复检"
+		}
+
 		res[i] = &pasturePb.CowDetails{
 			CowId:                       int32(v.Id),
 			Sex:                         sex,
@@ -405,10 +417,10 @@ func (c CowSlice) ToPB(
 			LastForbiddenMatingAtFormat: lastForbiddenMatingAtFormat,
 			LastEstrusAtFormat:          lastEstrusAtFormat,
 			PregnancyDate:               pregnancyDate,
-			PregnancyCheckTimes:         v.PregnancyCheckName,
+			PregnancyCheckTimes:         pregnancyCheckTimes,
 			AvgDailyWeight:              float32(v.GetAverageDailyWeight()),
 			EleEarNumber:                v.EleEarNumber,
-			AdmissionPrice:              float32(v.AdmissionWeight / 1000),
+			AdmissionPrice:              v.AdmissionPrice,
 			PurposeName:                 purposeName,
 		}
 	}
@@ -507,6 +519,7 @@ func NewEnterCow(pastureId int64, req *pasturePb.EventEnterRequest, penMap map[i
 		LastCalvingAt:       int64(req.CalvingAt),
 		LastBullNumber:      req.BullNumber,
 		LastAbortionAt:      int64(req.AbortionAt),
+		AdmissionPrice:      req.Price,
 	}
 	cow.AdmissionAge = cow.GetAdmissionAge()
 	cow.DayAge = cow.GetDayAge()
@@ -557,7 +570,7 @@ func (c *Cow) GetDayAge() int32 {
 	if c.BirthAt <= 0 {
 		return 0
 	}
-	return int32(math.Floor(float64(time.Now().Unix()-c.BirthAt) / 86400))
+	return int32(math.Floor(float64(time.Now().Local().Unix()-c.BirthAt) / 86400))
 }
 
 // GetCalvingAge 产后天数
@@ -565,7 +578,7 @@ func (c *Cow) GetCalvingAge() int32 {
 	if c.LastCalvingAt <= 0 {
 		return 0
 	}
-	return int32(math.Floor(float64(time.Now().Unix()-c.LastCalvingAt) / 86400))
+	return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastCalvingAt) / 86400))
 }
 
 // GetDaysPregnant 怀孕天数
@@ -573,7 +586,7 @@ func (c *Cow) GetDaysPregnant() int32 {
 	if c.BreedStatus == pasturePb.BreedStatus_Pregnant &&
 		c.AdmissionStatus == pasturePb.AdmissionStatus_Admission &&
 		c.IsPregnant == pasturePb.IsShow_Ok {
-		return int32(math.Floor(float64(time.Now().Unix()-c.LastMatingAt) / 86400))
+		return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastMatingAt) / 86400))
 	}
 	return 0
 }
@@ -591,7 +604,7 @@ func (c *Cow) GetDaysPregnancy(pregnancyAgeValue int32) int32 {
 // GetLactationDays 泌乳天数
 func (c *Cow) GetLactationDays() int32 {
 	if c.BreedStatus == pasturePb.BreedStatus_Calving && c.AdmissionStatus == pasturePb.AdmissionStatus_Admission {
-		return int32(math.Floor(float64(time.Now().Unix()-c.LastCalvingAt) / 86400))
+		return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastCalvingAt) / 86400))
 	}
 	return 0
 }
@@ -599,12 +612,12 @@ func (c *Cow) GetLactationDays() int32 {
 // GetAdmissionAge 入场天数
 func (c *Cow) GetAdmissionAge() int32 {
 	if c.AdmissionAt > 0 && c.AdmissionStatus == pasturePb.AdmissionStatus_Admission {
-		return int32(math.Floor(float64(time.Now().Unix()-c.AdmissionAt) / 86400))
+		return int32(math.Floor(float64(time.Now().Local().Unix()-c.AdmissionAt) / 86400))
 	}
 	return 0
 }
 
-// GetAverageDailyWeight 平均日增重 (最后一次称重 -  入场体重 ) ÷ 在群天数
+// GetAverageDailyWeight 平均日增重(最后一次称重 - 入场体重)÷在群天数
 func (c *Cow) GetAverageDailyWeight() float64 {
 	if c.AdmissionAge <= 0 {
 		c.AdmissionAge = c.GetAdmissionAge()
@@ -636,7 +649,7 @@ func (c *Cow) GetPreviousStageDailyWeight() float64 {
 // GetAbortionAge 流产天数
 func (c *Cow) GetAbortionAge() int32 {
 	if c.LastAbortionAt > 0 && c.AdmissionStatus == pasturePb.AdmissionStatus_Admission {
-		return int32(math.Floor(float64(time.Now().Unix()-c.LastAbortionAt) / 86400))
+		return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastAbortionAt) / 86400))
 	}
 	return 0
 }
@@ -644,7 +657,7 @@ func (c *Cow) GetAbortionAge() int32 {
 // GetLactationAge 泌乳天数
 func (c *Cow) GetLactationAge() int32 {
 	if c.MilkKind == pasturePb.CowMilk_Lactation {
-		return int32(math.Floor(float64(time.Now().Unix()-c.LastCalvingAt) / 86400))
+		return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastCalvingAt) / 86400))
 	}
 	return c.LactationAge
 }
@@ -652,7 +665,7 @@ func (c *Cow) GetLactationAge() int32 {
 // GetDryMilkAge 干奶天数
 func (c *Cow) GetDryMilkAge() int32 {
 	if c.MilkKind == pasturePb.CowMilk_Dry_Milk {
-		return int32(math.Floor(float64(time.Now().Unix()-c.LastDryMilkAt) / 86400))
+		return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastDryMilkAt) / 86400))
 	}
 	return c.DryMilkAge
 }

+ 39 - 0
model/cow_pregnant.go

@@ -0,0 +1,39 @@
+package model
+
+import (
+	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
+)
+
+type CowPregnant struct {
+	Id           int64                  `json:"id"`
+	PastureId    int64                  `json:"pastureId"`
+	CowId        int64                  `json:"cowId"`
+	EarNumber    string                 `json:"earNumber"`
+	Lact         int32                  `json:"lact"`
+	PregnancyAge int32                  `json:"pregnancyAge"`
+	CowType      pasturePb.CowType_Kind `json:"cowType"`
+	DateTime     string                 `json:"dateTime"`
+	CreatedAt    int64                  `json:"createdAt"`
+	UpdatedAt    int64                  `json:"updatedAt"`
+}
+
+func (c *CowPregnant) TableName() string {
+	return "cow_pregnant"
+}
+
+func NewCowPregnant(pastureId int64, cowInfo *Cow, dateTime string) *CowPregnant {
+	return &CowPregnant{
+		PastureId:    pastureId,
+		CowId:        cowInfo.Id,
+		EarNumber:    cowInfo.EarNumber,
+		Lact:         cowInfo.Lact,
+		CowType:      cowInfo.CowType,
+		PregnancyAge: cowInfo.GetDaysPregnant(),
+		DateTime:     dateTime,
+	}
+}
+
+type CowPregnantMonth struct {
+	Month    string `json:"month"`
+	CowCount int32  `json:"cowCount"`
+}

+ 1 - 1
model/crontab_log.go

@@ -17,6 +17,6 @@ func (c CronLog) TableName() string {
 func NewCronLog(name string) *CronLog {
 	return &CronLog{
 		Name: name,
-		Date: time.Now().Format(LayoutDate2),
+		Date: time.Now().Local().Format(LayoutDate2),
 	}
 }

+ 2 - 2
model/event_cow_disease.go

@@ -64,7 +64,7 @@ func (e *EventCowDisease) EventDiseaseUpdate(disease *Disease, operationUser *Sy
 	e.Temperature = int32(temp * 100)
 	e.DiagnoseOperationId = int32(operationUser.Id)
 	e.DiagnoseOperationName = operationUser.Name
-	e.DiseaseAt = time.Now().Unix()
+	e.DiseaseAt = time.Now().Local().Unix()
 }
 
 // EventTreatmentUpdate 治疗更新
@@ -124,7 +124,7 @@ func (e EventCowDiseaseSlice) ToPB(healthStatusMap map[pasturePb.HealthStatus_Ki
 		onsetDays := int32(0)
 		if v.FirstTreatmentAt > 0 {
 			firstTime := time.Unix(v.FirstTreatmentAt, 0)
-			diff := time.Now().Sub(firstTime)
+			diff := time.Now().Local().Sub(firstTime)
 			onsetDays = int32(diff.Hours() / 24)
 		}
 		res[i] = &pasturePb.EventCowDisease{

+ 1 - 1
model/event_enter.go

@@ -56,7 +56,7 @@ func NewEventEnter(pastureId, cowId int64, req *pasturePb.EventEnterRequest) *Ev
 		CowType:          req.CowType,
 		BreedStatus:      req.BreedStatus,
 		Lact:             req.Lact,
-		DayAge:           int32(math.Floor(float64(int32(time.Now().Unix())-req.BirthAt) / 86400)),
+		DayAge:           int32(math.Floor(float64(int32(time.Now().Local().Unix())-req.BirthAt) / 86400)),
 		PenId:            req.PenId,
 		CowKind:          req.CowKind,
 		FatherNumber:     req.FatherNumber,

+ 1 - 1
model/event_immunization_plan.go

@@ -61,7 +61,7 @@ func (e *EventImmunizationPlan) EventUpdate(immunizationAt int64, cowInfo *Cow,
 }
 
 func NewEventImmunizationPlan(cow *Cow, immunizationPlan *ImmunizationPlan) *EventImmunizationPlan {
-	todayTime := time.Now()
+	todayTime := time.Now().Local()
 	todayStartTime := util.TimeParseLocalUnix(todayTime.Format(LayoutDate2))
 	todayEndTime := util.TimeParseLocalEndUnix(todayTime.AddDate(0, 0, 6).Format(LayoutDate2))
 	return &EventImmunizationPlan{

+ 0 - 5
model/event_mating.go

@@ -313,11 +313,6 @@ type MultiFactorPregnancyRateChart struct {
 	KepMap          []string                     `json:"kepMap"`
 }
 
-type CowPregnantMonth struct {
-	Month    string `json:"month"`
-	CowCount int32  `json:"cowCount"`
-}
-
 // EventMatingCheckBatchModel 批量配种
 type EventMatingCheckBatchModel struct {
 	Cow              *Cow

+ 0 - 1
model/event_sale.go

@@ -124,7 +124,6 @@ type EventSaleModel struct {
 	CowList          []*Cow
 	SalesType        pasturePb.SalesType_Kind
 	SaleAt           int64
-	EventSale        *EventSale
 	EventSaleCarList []*EventSaleCar
 	EventSaleCowList []*EventSaleCow
 	NeckRingList     []*NeckRing

+ 3 - 3
model/neck_ring.go

@@ -28,7 +28,7 @@ func (n *NeckRing) TableName() string {
 
 func (n *NeckRing) EventBindUpdate(cowId int64) {
 	n.CowId = cowId
-	n.WearAt = time.Now().Unix()
+	n.WearAt = time.Now().Local().Unix()
 }
 
 func (n *NeckRing) EventUnBindUpdate() {
@@ -47,7 +47,7 @@ func NewNeckRing(pastureId int64, number string, cowInfo *Cow, operationUser *Sy
 		NeckRingNumber: number,
 		CowId:          cowInfo.Id,
 		EarNumber:      cowInfo.EarNumber,
-		WearAt:         time.Now().Unix(),
+		WearAt:         time.Now().Local().Unix(),
 		IsBind:         pasturePb.NeckRingIsBind_Bind,
 		Status:         pasturePb.NeckRingStatus_Normal,
 		OperationId:    int32(operationUser.Id),
@@ -64,7 +64,7 @@ func (n NeckRingSlice) ToPB(neckRingIsBind map[pasturePb.NeckRingIsBind_Kind]str
 		wearDays := int32(0)
 		if v.WearAt > 0 {
 			wearAtFormat = time.Unix(v.WearAt, 0).Format(LayoutDate2)
-			wearDays = int32(time.Now().Sub(time.Unix(v.WearAt, 0)).Hours() / 24)
+			wearDays = int32(time.Now().Local().Sub(time.Unix(v.WearAt, 0)).Hours() / 24)
 		}
 		res[i] = &pasturePb.SearchNeckRingList{
 			Id:           int32(v.Id),

+ 6 - 0
model/neck_ring_bind_log.go

@@ -1,5 +1,11 @@
 package model
 
+const (
+	OperationNameBind   = "绑定"
+	OperationNameUnbind = "解绑"
+	OperationNameUpdate = "编辑"
+)
+
 type NeckRingBindLog struct {
 	Id             int64  `json:"id"`
 	PastureId      int64  `json:"pastureId"`

+ 2 - 2
model/outbound.go

@@ -37,12 +37,12 @@ func (o *Outbound) Delete() {
 func NewOutbound(pastureId int64, req *pasturePb.OutboundApplyItem, currentUser *SystemUser) *Outbound {
 	return &Outbound{
 		PastureId:        pastureId,
-		Number:           fmt.Sprintf("%s%s", util.GenerateRandomNumberString(8), time.Now().Format(LayoutDate)),
+		Number:           fmt.Sprintf("%s%s", util.GenerateRandomNumberString(8), time.Now().Local().Format(LayoutDate)),
 		OutType:          req.OutType,
 		AuditStatus:      pasturePb.AuditStatus_Pending,
 		ApplicantId:      int32(currentUser.Id),
 		ApplicantName:    currentUser.Name,
-		ApplicantAt:      time.Now().Unix(),
+		ApplicantAt:      time.Now().Local().Unix(),
 		ApplicantRemarks: req.ApplicantRemarks,
 	}
 }

+ 1 - 1
model/work_order_master.go

@@ -115,7 +115,7 @@ func NewTaskWorkOrderPayload(id int64, execTime time.Duration) *asynq.Task {
 	payload, _ := json.Marshal(TaskWorkOrderPayload{
 		WorkOrderId: id,
 	})
-	processAt := time.Now().Add(execTime).Unix()
+	processAt := time.Now().Local().Add(execTime).Unix()
 	return asynq.NewTask(
 		fmt.Sprintf("%s:%s", config.Options().FarmName, TaskWorkOrder),
 		payload,

+ 2 - 2
model/work_order_sub.go

@@ -43,7 +43,7 @@ func NewWorkOrderSub(req *WorkOrderMaster) []*WorkOrderSub {
 		return workOrderSubList
 	}
 
-	nowTime := time.Now()
+	nowTime := time.Now().Local()
 	execTime, err := util.ConvertParseLocalUnix(req.ExecTime)
 	if err != nil {
 		zaplog.Error("NewWorkOrderSub", zap.Any("ConvertParseLocalUnix", err))
@@ -64,7 +64,7 @@ func NewWorkOrderSub(req *WorkOrderMaster) []*WorkOrderSub {
 			ExecTime:           currentExecTime,
 			ExecUserId:         0,
 			SetUserIds:         req.ExecPersons,
-			WorkOrderSubNumber: fmt.Sprintf("s%s%d", LayoutDate, time.Now().Unix()),
+			WorkOrderSubNumber: fmt.Sprintf("s%s%d", LayoutDate, time.Now().Local().Unix()),
 			Status:             pasturePb.WorkOrderStatus_Created,
 			IsShow:             pasturePb.IsShow_Ok,
 			Remarks:            "",

+ 45 - 33
module/backend/analysis.go

@@ -20,6 +20,7 @@ func (s *StoreEntry) WeightScatterPlot(ctx context.Context, req *pasturePb.Searc
 	if err != nil {
 		return nil, xerr.Custom("当前用户信息错误,请退出重新登录")
 	}
+
 	// 查询数据
 	cowList := make([]*model.Cow, 0)
 	pref := s.DB.Model(new(model.Cow)).
@@ -371,17 +372,25 @@ func (s *StoreEntry) AbortionRate(ctx context.Context, req *pasturePb.AbortionRa
 		return nil, xerr.WithStack(err)
 	}
 
+	// 2. 创建月份映射表用于快速查找
+	monthMap := make(map[string]*pasturePb.AbortionRateTable)
+	for _, month := range dayTimeList {
+		monthMap[month] = &pasturePb.AbortionRateTable{
+			MonthName:     month,
+			AbortionCount: 0,
+			PregnantCount: 0,
+			AbortionRate:  0,
+		}
+	}
+
 	// 历史每月怀孕牛头数量
 	cowPregnantMonthList := make([]*model.CowPregnantMonth, 0)
-	pref := s.DB.Model(new(model.EventMating)).
-		Select(`COUNT(cow_id) AS cow_count,DATE_FORMAT(FROM_UNIXTIME(reality_day),'%Y-%m') as month`).
+	pref := s.DB.Model(new(model.CowPregnant)).
+		Select(`COUNT(cow_id) AS cow_count,date_time as month`).
 		Where("cow_type = ?", req.CowType).
-		Where("pasture_id = ?", userModel.AppPasture.Id).
-		Where("status = ?", pasturePb.IsShow_Ok).
-		Where("mating_result = ?", pasturePb.MatingResult_Pregnant).
-		Where("DATE_FORMAT(FROM_UNIXTIME(reality_day),'%Y-%m') IN (?)", dayTimeList)
+		Where("pasture_id = ?", userModel.AppPasture.Id)
 
-	if req.Lact >= 0 && req.Lact <= 3 {
+	if req.CowType == pasturePb.CowType_Breeding_Calf && req.Lact >= 0 && req.Lact <= 3 {
 		pref.Where("lact = ?", req.Lact)
 	} else {
 		pref.Where("lact > ?", req.Lact)
@@ -391,6 +400,14 @@ func (s *StoreEntry) AbortionRate(ctx context.Context, req *pasturePb.AbortionRa
 		Find(&cowPregnantMonthList).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
+
+	// 更新月份映射表中的怀孕数量
+	for _, v := range cowPregnantMonthList {
+		if table, exists := monthMap[v.Month]; exists {
+			table.PregnantCount = v.CowCount
+		}
+	}
+
 	// 历史每月流产牛头数量
 	cowAbortionMonthList := make([]*model.CowPregnantMonth, 0)
 	pref2 := s.DB.Model(new(model.EventAbortion)).
@@ -398,14 +415,25 @@ func (s *StoreEntry) AbortionRate(ctx context.Context, req *pasturePb.AbortionRa
 		Where("cow_type = ?", req.CowType).
 		Where("DATE_FORMAT(FROM_UNIXTIME(abortion_at),'%Y-%m') IN ?", dayTimeList)
 
-	if req.Lact >= 0 {
+	if req.Lact >= 0 && req.CowType == pasturePb.CowType_Breeding_Calf {
 		pref2.Where("lact = ?", req.Lact)
 	}
 
-	if err = pref2.Group("month").Find(&cowAbortionMonthList).Error; err != nil {
+	if err = pref2.Group("month").
+		Find(&cowAbortionMonthList).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
+	// 更新月份映射表中的流产数量和流产率
+	for _, v := range cowAbortionMonthList {
+		if table, exists := monthMap[v.Month]; exists {
+			table.AbortionCount = v.CowCount
+			if table.PregnantCount > 0 {
+				table.AbortionRate = float32(util.RoundToTwoDecimals(float64(v.CowCount) / float64(table.PregnantCount) * 100))
+			}
+		}
+	}
+
 	chart := &pasturePb.AbortionRateChart{
 		Header:             make([]string, 0),
 		AbortionCountMonth: make([]int32, 0),
@@ -414,29 +442,13 @@ func (s *StoreEntry) AbortionRate(ctx context.Context, req *pasturePb.AbortionRa
 	}
 
 	table := make([]*pasturePb.AbortionRateTable, 0)
-	for _, v2 := range cowAbortionMonthList {
-		pregnantCountMonth := int32(0)
-		for _, v := range cowPregnantMonthList {
-			if v.Month == v2.Month {
-				pregnantCountMonth = v.CowCount
-			}
-		}
-		abortionRateMonth := float64(0)
-		if pregnantCountMonth > 0 && v2.CowCount > 0 {
-			abortionRateMonth = util.RoundToTwoDecimals(float64(v2.CowCount) / float64(pregnantCountMonth) * 100)
-		}
-
-		chart.Header = append(chart.Header, v2.Month)
-		chart.AbortionCountMonth = append(chart.AbortionCountMonth, v2.CowCount)
-		chart.PregnantCountMonth = append(chart.PregnantCountMonth, pregnantCountMonth)
-		chart.AbortionRateMonth = append(chart.AbortionRateMonth, float32(abortionRateMonth))
-
-		table = append(table, &pasturePb.AbortionRateTable{
-			AbortionCount: v2.CowCount,
-			MonthName:     v2.Month,
-			PregnantCount: pregnantCountMonth,
-			AbortionRate:  float32(abortionRateMonth),
-		})
+	for _, month := range dayTimeList {
+		data := monthMap[month]
+		chart.Header = append(chart.Header, month) // 添加月份到Header
+		chart.AbortionCountMonth = append(chart.AbortionCountMonth, data.AbortionCount)
+		chart.PregnantCountMonth = append(chart.PregnantCountMonth, data.PregnantCount)
+		chart.AbortionRateMonth = append(chart.AbortionRateMonth, data.AbortionRate)
+		table = append(table, data)
 	}
 
 	return &pasturePb.AbortionRateResponse{
@@ -461,7 +473,7 @@ func (s *StoreEntry) TwentyOnePregnantRate(ctx context.Context, req *pasturePb.T
 		return nil, xerr.Customf("开始时间不能大于结束时间: %s ~ %d", req.StartDate, req.EndDate)
 	}
 
-	nowDateTime := time.Now()
+	nowDateTime := time.Now().Local()
 	if endUnix > nowDateTime.Unix() {
 		return nil, xerr.Customf("结束时间不能大于当前时间: %s ~ %s", req.EndDate, nowDateTime.Format(model.LayoutDate2))
 	}

+ 3 - 3
module/backend/calendar.go

@@ -36,7 +36,7 @@ func (s *StoreEntry) CalendarToDoHistoryList(ctx context.Context, pastureId int6
 		whereSql += fmt.Sprintf(` AND ear_number = '%s' `, earNumber)
 	}
 	whereSql += fmt.Sprintf(" AND pasture_id = %d ", pastureId)
-	whereSql1 := whereSql + fmt.Sprintf(` AND end_day <= %d `, util.TimeParseLocalEndUnix(time.Now().Format(model.LayoutDate2)))
+	whereSql1 := whereSql + fmt.Sprintf(` AND end_day <= %d `, util.TimeParseLocalEndUnix(time.Now().Local().Format(model.LayoutDate2)))
 
 	calendarToDoList := make([]*pasturePb.CalendarToDoList, 0)
 	sql := `SELECT a.cow_id,b.pen_name,a.calendar_type_name,a.calendar_type_kind as calendar_type,DATE_FORMAT(FROM_UNIXTIME(a.plan_day), '%Y-%m-%d') AS plan_day,
@@ -84,7 +84,7 @@ func (s *StoreEntry) CalendarToDoList(ctx context.Context, req *pasturePb.Calend
 		return nil, xerr.WithStack(err)
 	}
 
-	nowTime := time.Now().Format(model.LayoutDate2)
+	nowTime := time.Now().Local().Format(model.LayoutDate2)
 	todayCompletedSql := `SELECT a.count as count,a.calendar_type_name as calendar_type_name,a.calendar_type_kind as calendar_type_kind FROM (
 		SELECT count('cow_id') as count,'免疫' as calendar_type_name,1 as calendar_type_kind FROM event_immunization_plan 
 			WHERE status = 1 AND DATE_FORMAT(FROM_UNIXTIME(reality_day), '%Y-%m-%d') = ? AND pasture_id = ?
@@ -319,7 +319,7 @@ func (s *StoreEntry) SameTimeCowList(ctx context.Context, req *pasturePb.ItemsRe
 		Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission).
 		Where("a.pasture_id = ?", userModel.AppPasture.Id).
 		Where("a.status = ?", pasturePb.IsShow_No).
-		Where("a.plan_day <= ?", time.Now().Unix())
+		Where("a.plan_day <= ?", time.Now().Local().Unix())
 
 	if req.EndDay != "" {
 		dateTime := util.TimeParseLocalEndUnix(req.EndDay)

+ 1 - 1
module/backend/calendar_more.go

@@ -132,7 +132,7 @@ func (s *StoreEntry) DryMilkCowList(ctx context.Context, req *pasturePb.ItemsReq
 			breedStatusName = breedStatus
 		}
 		v.BreedStatusName = breedStatusName
-		v.CalvingAtFormat = time.Now().AddDate(0, 0, int(systemBasic.MinValue-v.PregnancyAge)).Format(model.LayoutDate2)
+		v.CalvingAtFormat = time.Now().Local().AddDate(0, 0, int(systemBasic.MinValue-v.PregnancyAge)).Format(model.LayoutDate2)
 	}
 
 	return &pasturePb.DruMilkItemsResponse{

+ 1 - 1
module/backend/cow.go

@@ -210,7 +210,7 @@ func (s *StoreEntry) BehaviorCurve(ctx context.Context, req *pasturePb.CowBehavi
 		return nil, xerr.Customf("错误的牛只信息: %d", req.CowId)
 	}
 
-	nowTime := time.Now()
+	nowTime := time.Now().Local()
 	nowDayZero := util.TimeParseLocalUnix(nowTime.Format(model.LayoutDate2))
 	endDataTime := nowTime.Format(model.LayoutDate2)
 	startDataTime := nowTime.AddDate(0, 0, -30).Format(model.LayoutDate2)

+ 4 - 4
module/backend/dashboard.go

@@ -105,10 +105,10 @@ func (s *StoreEntry) FocusIndicatorsList(ctx context.Context, dimension string)
 		Where("kind in (?)", userFocusIndicatorsList)
 
 	/*if dimension == "Year" {
-		pref.Where("date = ?", time.Now().Format(model.LayoutMonth))
+		pref.Where("date = ?", time.Now().Local().Format(model.LayoutMonth))
 	}*/
 
-	nowTime := time.Now()
+	nowTime := time.Now().Local()
 	if dimension == "Month" {
 		pref.Where("date = ?", nowTime.Format(model.LayoutMonth))
 	}
@@ -237,7 +237,7 @@ func (s *StoreEntry) DataWarningList(ctx context.Context) (*pasturePb.IndexDataW
 		userDataWarning = defaultDataWarning
 	}
 
-	newTime := time.Now().Unix()
+	newTime := time.Now().Local().Unix()
 	needUpdateWarningIds := make([]int64, 0)
 	for _, warningData := range userDataWarning {
 		// 如果预警数据更新时间大于预警条件更新时间,并且更新时间距离当前时间小于2小时,则跳过
@@ -432,7 +432,7 @@ func (s *StoreEntry) UpdateWarningData(ctx context.Context, needUpdateWarningIds
 			Where("id = ?", warningId).
 			Updates(map[string]interface{}{
 				"data_value":     count,
-				"data_update_at": time.Now().Unix(),
+				"data_update_at": time.Now().Local().Unix(),
 			}).Error; err != nil {
 			zaplog.Error("UpdateWarningData", zap.Any("update", err))
 		}

+ 14 - 15
module/backend/event_base_more.go

@@ -224,24 +224,23 @@ func (s *StoreEntry) CowSaleCreate(ctx context.Context, req *pasturePb.EventCowS
 		}
 	}
 
-	eventSaleModel := &model.EventSaleModel{
-		CowList:          cowList,
-		SalesType:        req.SalesType,
-		EventSale:        newEventSale,
-		EventSaleCarList: model.NewEventSaleCarList(userModel.AppPasture.Id, newEventSale.Id, newEventSale.SaleAt, req.SaleVehicleItems),
-		EventSaleCowList: model.NewEventSaleCowList(userModel.AppPasture.Id, newEventSale.Id, cowList),
-		NeckRingList:     neckRingList,
-		EventCowLog:      eventCowLogList,
-		SaleAt:           int64(req.SaleAt),
-	}
-
 	if err = s.DB.Transaction(func(tx *gorm.DB) error {
 		// 创建销售数据
 		if err = tx.Model(new(model.EventSale)).
-			Create(eventSaleModel.EventSale).Error; err != nil {
+			Create(newEventSale).Error; err != nil {
 			return xerr.WithStack(err)
 		}
 
+		eventSaleModel := &model.EventSaleModel{
+			CowList:          cowList,
+			SalesType:        req.SalesType,
+			EventSaleCarList: model.NewEventSaleCarList(userModel.AppPasture.Id, newEventSale.Id, newEventSale.SaleAt, req.SaleVehicleItems),
+			EventSaleCowList: model.NewEventSaleCowList(userModel.AppPasture.Id, newEventSale.Id, cowList),
+			NeckRingList:     neckRingList,
+			EventCowLog:      eventCowLogList,
+			SaleAt:           int64(req.SaleAt),
+		}
+
 		if len(eventSaleModel.EventSaleCarList) > 0 {
 			if err = tx.Model(new(model.EventSaleCar)).
 				Create(&eventSaleModel.EventSaleCarList).Error; err != nil {
@@ -259,9 +258,9 @@ func (s *StoreEntry) CowSaleCreate(ctx context.Context, req *pasturePb.EventCowS
 
 		if len(eventSaleModel.CowList) > 0 {
 			for _, cow := range eventSaleModel.CowList {
-				cow.EventSaleUpdate(eventSaleModel.SaleAt, eventSaleModel.SalesType)
+				cow.EventSaleUpdate(newEventSale)
 				if err = tx.Model(cow).
-					Select("admission_status", "departure_at", "neck_ring_number", "HealthStatus").
+					Select("admission_status", "departure_at", "neck_ring_number", "health_status", "departure_price", "departure_avg_weight").
 					Where("id = ?", cow.Id).
 					Updates(cow).Error; err != nil {
 					return xerr.WithStack(err)
@@ -275,7 +274,7 @@ func (s *StoreEntry) CowSaleCreate(ctx context.Context, req *pasturePb.EventCowS
 				neckRing.EventUnBindUpdate()
 				if err = tx.Model(new(model.NeckRing)).
 					Select("is_bind", "cow_id", "ear_number", "wear_at", "error_reason", "operation_id", "operation_name").
-					Where("id = ?", neckRing).
+					Where("id = ?", neckRing.Id).
 					Updates(neckRing).Error; err != nil {
 					return xerr.WithStack(err)
 				}

+ 5 - 2
module/backend/event_breed.go

@@ -242,7 +242,7 @@ func (s *StoreEntry) SameTimeBatch(ctx context.Context, req *pasturePb.EventSame
 	}
 	req.DrugsName = drugs.Name
 
-	nowTime := time.Now().Format(model.LayoutDate2)
+	nowTime := time.Now().Local().Format(model.LayoutDate2)
 	eventCowSameTimeList := make([]*model.EventCowSameTime, 0)
 	for _, v := range req.CowIds {
 		eventCowSameTime, err := s.GetEventCowSameTimeByCowId(ctx, userModel.AppPasture.Id, int64(v))
@@ -403,7 +403,10 @@ func (s *StoreEntry) EstrusBatchMating(ctx context.Context, req *pasturePb.Event
 
 		// 记录事件日志
 		for _, v := range eventEstrusBatch.EventEstrusList {
-			cow, _ := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, v.CowId)
+			cow, err := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, v.CowId)
+			if err != nil {
+				return xerr.WithStack(err)
+			}
 			// 更新牛最近发情时间
 			cow.EstrusUpdate(v.RealityDay)
 			if err = tx.Model(cow).

+ 1 - 2
module/backend/event_breed_more.go

@@ -82,7 +82,6 @@ func (s *StoreEntry) PregnantCheckCreateBatch(ctx context.Context, req *pastureP
 			breedStatus := pasturePb.BreedStatus_Pregnant
 			isPregnant := pasturePb.IsShow_Ok
 			matingResult := pasturePb.MatingResult_Pregnant
-
 			if item.PregnantCheckResult == pasturePb.PregnantCheckResult_UnPregnant {
 				breedStatus = pasturePb.BreedStatus_Empty
 				isPregnant = pasturePb.IsShow_No
@@ -95,7 +94,7 @@ func (s *StoreEntry) PregnantCheckCreateBatch(ctx context.Context, req *pastureP
 				matingResult = pasturePb.MatingResult_Abort
 			}
 
-			item.Cow.EventPregnantCheckUpdate(breedStatus, int64(item.PregnantCheckAt), isPregnant)
+			item.Cow.EventPregnantCheckUpdate(breedStatus, int64(item.PregnantCheckAt), isPregnant, item.EventPregnancyCheck.PregnantCheckName)
 			// 更新牛只基本信息
 			if err = tx.Model(item.Cow).
 				Select("breed_status", "last_pregnant_check_at", "is_pregnant").

+ 1 - 1
module/backend/event_breed_more_more.go

@@ -244,7 +244,7 @@ func (s *StoreEntry) UnForbiddenMating(ctx context.Context, req *pasturePb.Event
 		return nil
 	}
 
-	nowTime := time.Now().Unix()
+	nowTime := time.Now().Local().Unix()
 
 	if err = s.DB.Transaction(func(tx *gorm.DB) error {
 		for _, item := range eventForbiddenMatingList {

+ 1 - 1
module/backend/event_check.go

@@ -251,7 +251,7 @@ func (s *StoreEntry) EstrusCheckDataCheck(ctx context.Context, userModel *model.
 			pasturePb.IsShow_Ok, item.IsMating, int64(item.EstrusAt), operationUser, userModel.SystemUser)
 
 		if item.IsMating == pasturePb.IsShow_Ok {
-			newEventMating := model.NewEventMating(userModel.AppPasture.Id, cowInfo, time.Now().Unix(), exposeEstrusType)
+			newEventMating := model.NewEventMating(userModel.AppPasture.Id, cowInfo, time.Now().Local().Unix(), exposeEstrusType)
 			res.EventMatingList = append(res.EventMatingList, newEventMating)
 		} else {
 			newEventEstrus.UnMatingReasonsKind = item.UnMatingReasonsKind

+ 1 - 1
module/backend/event_health.go

@@ -123,7 +123,7 @@ func (s *StoreEntry) CowDiseaseCreate(ctx context.Context, req *pasturePb.EventC
 		// 新的临时处方
 		if req.PrescriptionId <= 0 && len(req.PrescriptionDetail) > 0 {
 			newPrescriptionRequest := &pasturePb.PrescriptionRequest{
-				Name:                 fmt.Sprintf("%s-%s-%s", disease.Name, time.Now().Format("20060102"), operationUser.Name),
+				Name:                 fmt.Sprintf("%s-%s-%s", disease.Name, time.Now().Local().Format("20060102"), operationUser.Name),
 				ApplicableDiseaseIds: []int32{req.DiseaseId},
 				IsShow:               pasturePb.IsShow_Ok,
 			}

+ 7 - 8
module/backend/goods.go

@@ -164,7 +164,7 @@ func (s *StoreEntry) NeckRingCreateOrUpdate(ctx context.Context, req *pasturePb.
 					return xerr.WithStack(err)
 				}
 				number = item.Number
-				newNeckRingLog.OperationName = "绑定"
+				newNeckRingLog.OperationName = model.OperationNameBind
 				// 解绑
 			case pasturePb.NeckRingOperationStatus_UnBind:
 				if ok && neckRing.IsBind != pasturePb.NeckRingIsBind_Bind {
@@ -180,7 +180,7 @@ func (s *StoreEntry) NeckRingCreateOrUpdate(ctx context.Context, req *pasturePb.
 					}).Error; err != nil {
 					return xerr.WithStack(err)
 				}
-				newNeckRingLog.OperationName = "解绑"
+				newNeckRingLog.OperationName = model.OperationNameUnbind
 				// 编辑
 			case pasturePb.NeckRingOperationStatus_Edit:
 				if cowInfo.NeckRingNumber != "" && item.Number != cowInfo.NeckRingNumber {
@@ -192,13 +192,13 @@ func (s *StoreEntry) NeckRingCreateOrUpdate(ctx context.Context, req *pasturePb.
 					Updates(map[string]interface{}{
 						"cow_id":     cowInfo.Id,
 						"ear_number": cowInfo.EarNumber,
-						"wear_at":    time.Now().Unix(),
+						"wear_at":    time.Now().Local().Unix(),
 						"is_bind":    pasturePb.NeckRingIsBind_Bind,
 					}).Error; err != nil {
 					return xerr.WithStack(err)
 				}
 				number = item.Number
-				newNeckRingLog.OperationName = "编辑"
+				newNeckRingLog.OperationName = model.OperationNameUpdate
 			}
 
 			if err = tx.Create(newNeckRingLog).Error; err != nil {
@@ -230,9 +230,8 @@ func (s *StoreEntry) NeckRingList(ctx context.Context, req *pasturePb.SearchNeck
 	pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.NeckRing).TableName())).
 		Select("a.*,COALESCE(b.pen_name, '') AS pen_name").
 		Joins("LEFT JOIN cow as b ON a.cow_id = b.id").
-		//Where("a.is_bind = ?", pasturePb.NeckRingIsBind_Bind).
 		Where("a.pasture_id = ?", userModel.AppPasture.Id).
-		Where("a.neck_ring_number != ''")
+		Where("a.neck_ring_number != ?", "")
 
 	if req.IsBind > 0 {
 		pref.Where("a.is_bind = ?", req.IsBind)
@@ -243,7 +242,7 @@ func (s *StoreEntry) NeckRingList(ctx context.Context, req *pasturePb.SearchNeck
 	}
 
 	if req.Number != "" {
-		pref.Where("a.number like ?", fmt.Sprintf("%s%s%s", "%", req.Number, "%"))
+		pref.Where("a.neck_ring_number like ?", fmt.Sprintf("%s%s%s", "%", req.Number, "%"))
 	}
 
 	if err = pref.Order("a.id desc").
@@ -481,7 +480,7 @@ func (s *StoreEntry) OutboundAudit(ctx context.Context, req *pasturePb.OutboundA
 				"examine_id":      userModel.SystemUser.Id,
 				"examine_name":    userModel.SystemUser.Name,
 				"examine_remarks": req.ExamineRemarks,
-				"examine_at":      time.Now().Unix(),
+				"examine_at":      time.Now().Local().Unix(),
 			}).Error; err != nil {
 			return xerr.WithStack(err)
 		}

+ 1 - 1
module/backend/milk_gea.go

@@ -35,7 +35,7 @@ func (a *GEAMILK) SaveData(ctx context.Context) error {
 		return xerr.WithStack(err)
 	}
 
-	nowTime := time.Now()
+	nowTime := time.Now().Local()
 	gEAOriginalList := make([]*model.MilkOriginal, 0)
 	for _, v := range a.body.Content {
 		content, ok := v.(map[string]interface{})

+ 1 - 1
module/backend/neck_ring_warning.go

@@ -87,7 +87,7 @@ func (s *StoreEntry) EstrusOrAbortionCowList(ctx context.Context, req *pasturePb
 }
 
 func (s *StoreEntry) EstrusWarningQuery(ctx context.Context, pastureId int64) (*gorm.DB, error) {
-	nowTime := time.Now()
+	nowTime := time.Now().Local()
 	startTime := time.Unix(util.TimeParseLocalUnix(nowTime.Format(model.LayoutDate2)), 0).Format(model.LayoutTime)
 	entTime := time.Unix(util.TimeParseLocalEndUnix(nowTime.AddDate(0, 0, 1).Format(model.LayoutDate2)), 0).Format(model.LayoutTime)
 	systemBasic, err := s.FindSystemBasic(ctx, pastureId, model.EstrusWaringDays)

+ 1 - 1
module/backend/system_service.go

@@ -59,7 +59,7 @@ func (s *StoreEntry) Login(ctx context.Context, req *pasturePb.SearchUserRequest
 		return nil, xerr.Custom("获取token错误")
 	}
 
-	expires := time.Now().Add(time.Duration(s.Cfg.JwtExpireTime) * time.Second).Format(util.LayoutTime)
+	expires := time.Now().Local().Add(time.Duration(s.Cfg.JwtExpireTime) * time.Second).Format(util.LayoutTime)
 	farmList, err := s.FindPastureList(ctx, systemUser.PastureIds)
 	if err != nil || len(farmList) == 0 {
 		return nil, xerr.Custom("牧场信息错误")

+ 1 - 0
module/backend/test_service.go

@@ -66,6 +66,7 @@ func (s *StoreEntry) CowNeckRingNumberBound2(ctx context.Context, pagination *pa
 
 	cowList := make([]*model.Cow, 0)
 	if err = s.DB.Model(new(model.Cow)).
+		Where("pasture_id = ?", userModel.AppPasture.Id).
 		Where("neck_ring_number != ?", "").
 		Limit(int(pagination.PageSize)).
 		Offset(int(pagination.PageOffset)).

+ 1 - 1
module/backend/upload_file.go

@@ -20,7 +20,7 @@ func (s *StoreEntry) Photos(ctx context.Context, files []*multipart.FileHeader)
 	}
 
 	workDir := fmt.Sprintf("%s", config.WorkDir)
-	pathDir := fmt.Sprintf("/files/photos/%d/%s", userModel.AppPasture.Id, time.Now().Format("20060102"))
+	pathDir := fmt.Sprintf("/files/photos/%d/%s", userModel.AppPasture.Id, time.Now().Local().Format("20060102"))
 	saveDir := filepath.Join(workDir, pathDir)
 	if _, err = os.Stat(saveDir); os.IsNotExist(err) {
 		if err = os.MkdirAll(saveDir, 0755); err != nil {

+ 3 - 3
module/backend/work.go

@@ -167,7 +167,7 @@ func (s *StoreEntry) WorkOrderSubUpdate(tx *gorm.DB, workOrderMaster *model.Work
 		}
 	} else {
 		// 获取当天的零点时间
-		zeroTime := util.TimeParseLocalUnix(time.Now().Format("2006-01-02"))
+		zeroTime := util.TimeParseLocalUnix(time.Now().Local().Format("2006-01-02"))
 		// 先检查是否存在符合条件的记录
 		var count int64
 		if err := tx.Model(&model.WorkOrderSub{}).
@@ -199,7 +199,7 @@ func (s *StoreEntry) SendAsynqWorkOrder(ctx context.Context, workOrder *model.Wo
 	}
 
 	timeUnix, _ := util.ConvertParseLocalUnix(workOrder.ExecTime)
-	nowTime := time.Now()
+	nowTime := time.Now().Local()
 	// 过滤掉10秒内要执行的任务
 	if timeUnix <= nowTime.Unix()+10 {
 		return
@@ -231,7 +231,7 @@ func (s *StoreEntry) SendAsynqWorkOrder(ctx context.Context, workOrder *model.Wo
 		}
 	}
 
-	execTime := time.Now().Unix() - timeUnix
+	execTime := time.Now().Local().Unix() - timeUnix
 	if _, err := s.AsynqClient.CtxEnqueue(
 		ctx,
 		model.NewTaskWorkOrderPayload(workOrder.Id, time.Duration(execTime)*time.Second),

+ 51 - 21
module/crontab/cow_cron.go

@@ -42,7 +42,7 @@ func (e *Entry) GenerateAsynqWorkOrder() error {
 			zaplog.Error("crontab", zap.Any("GenerateWorkOrder", err), zap.Any("execTime", workOrder.ExecTime))
 			continue
 		}
-		nowTime := time.Now().Unix()
+		nowTime := time.Now().Local().Unix()
 		if timeUnix < nowTime {
 			continue
 		}
@@ -114,30 +114,60 @@ func (e *Entry) Indicators() error {
 
 // UpdateCowInfo 牛只基本信息维护
 func (e *Entry) UpdateCowInfo() error {
+	pastureList := e.FindPastureList()
+	for _, pasture := range pastureList {
+		e.UpdateCowInfoByPasture(pasture.Id)
+	}
+	e.CreateCrontabLog(UpdateCowInfo)
+	return nil
+}
+
+func (e *Entry) UpdateCowInfoByPasture(pastureId int64) {
+	if ok := e.IsExistCrontabLog(UpdateCowInfo); ok {
+		return
+	}
+
 	cowList := make([]*model.Cow, 0)
 	if err := e.DB.Model(new(model.Cow)).
+		Where("pasture_id = ?", pastureId).
 		Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
 		Find(&cowList).Error; err != nil {
-		return err
+		zaplog.Error("crontab", zap.Any("UpdateCowInfoByPasture", err))
+		return
 	}
-	if ok := e.IsExistCrontabLog(UpdateCowInfo); ok {
-		return nil
-	}
-	defer func() {
-		e.CreateCrontabLog(UpdateCowInfo)
-	}()
+
+	dateTime := time.Now().Local().Format(model.LayoutMonth)
 	for _, cow := range cowList {
+		// 周活动量
 		weeklyActive := e.UpdateCowWeeklyHigh(cow)
 		cow.EventUpdate(weeklyActive)
 		if err := e.DB.Model(new(model.Cow)).
-			Select("day_age", "calving_age", "pregnancy_age", "admission_age", "abortion_age", "cow_type",
-				"weekly_active", "lactation_age", "dry_milk_age").
+			Select("day_age", "calving_age", "pregnancy_age", "admission_age",
+				"abortion_age", "cow_type", "weekly_active", "lactation_age", "dry_milk_age").
 			Where("id = ?", cow.Id).
 			Updates(cow).Error; err != nil {
 			zaplog.Error("Crontab", zap.Any("UpdateCowDayAge", err))
 		}
+
+		// 每月怀孕数据
+		cowPregnantList := make([]*model.CowPregnant, 0)
+		if cow.IsPregnant == pasturePb.IsShow_Ok || cow.BreedStatus == pasturePb.BreedStatus_Pregnant {
+			cowPregnantList = append(cowPregnantList, model.NewCowPregnant(pastureId, cow, dateTime))
+		}
+
+		if len(cowPregnantList) > 0 {
+			if err := e.DB.Model(new(model.CowPregnant)).
+				Where("pasture_id = ?", pastureId).
+				Where("date_time = ?", dateTime).
+				Delete(&model.CowPregnant{}).Error; err != nil {
+				zaplog.Error("Crontab", zap.Any("UpdateCowPregnant", err))
+			}
+			if err := e.DB.Model(new(model.CowPregnant)).
+				Create(&cowPregnantList).Error; err != nil {
+				zaplog.Error("Crontab", zap.Any("UpdateCowPregnant", err))
+			}
+		}
 	}
-	return nil
 }
 
 // ImmunizationPlan 免疫计划,生成工作单
@@ -154,7 +184,7 @@ func (e *Entry) ImmunizationPlan() error {
 	}
 	var todayCount int32 = 0
 
-	nowTime := time.Now()
+	nowTime := time.Now().Local()
 	for _, plan := range planList {
 		cowList := make([]*model.Cow, 0)
 		pref := e.DB.Table(fmt.Sprintf("%s as a", new(model.Cow).TableName())).
@@ -182,7 +212,7 @@ func (e *Entry) ImmunizationPlan() error {
 			if plan.ImmunizationPlanId > 0 {
 				pref.Joins("INNER JOIN event_immunization_plan as b ON b.plan_id = ? ", plan.ImmunizationPlanId).
 					Where("b.cow_id = a.id").
-					Where("DATE_ADD(b.reality_day, INTERVAL ? DAY) = ?", plan.Value, time.Now().Format(model.LayoutDate2)).
+					Where("DATE_ADD(b.reality_day, INTERVAL ? DAY) = ?", plan.Value, time.Now().Local().Format(model.LayoutDate2)).
 					Where("b.status = ?", pasturePb.IsShow_Ok)
 			}
 		}
@@ -236,7 +266,7 @@ func (e *Entry) SameTimePlan() error {
 		e.CreateCrontabLog(SameTimePlan)
 	}()
 
-	currWeek := time.Now().Weekday()
+	currWeek := time.Now().Local().Weekday()
 	for _, sameTime := range sameTimeList {
 		if len(sameTime.WeekType) <= 0 {
 			continue
@@ -305,7 +335,7 @@ func (e *Entry) SameTimePlan() error {
 // UpdateSameTime 更新每天同期数据
 func (e *Entry) UpdateSameTime() error {
 	calendarTypeList := backend.CalendarTypeEnumList("")
-	showDay := time.Now().Format(model.LayoutDate2)
+	showDay := time.Now().Local().Format(model.LayoutDate2)
 	for _, v := range calendarTypeList {
 		count := int64(0)
 		if err := e.DB.Model(new(model.EventCowSameTime)).
@@ -363,7 +393,7 @@ func (e *Entry) SystemBasicCrontab() error {
 		return xerr.WithStack(err)
 	}
 
-	currWeekValue := time.Now().Weekday()
+	currWeekValue := time.Now().Local().Weekday()
 	for _, systemBasic := range systemBasicList {
 		// 周执行
 		if systemBasic.Name == model.PregnantCheckForFirst && systemBasic.WeekValue >= 0 &&
@@ -420,7 +450,7 @@ func (e *Entry) SystemBasicCrontab() error {
 
 func (e *Entry) DeleteOldOriginal() error {
 	if err := e.DB.Model(new(model.NeckRingOriginal)).
-		Where("active_date <= ?", time.Now().AddDate(0, 0, -7).Format(model.LayoutDate2)).
+		Where("active_date <= ?", time.Now().Local().AddDate(0, 0, -7).Format(model.LayoutDate2)).
 		Delete(&model.NeckRingOriginal{}).Error; err != nil {
 		zaplog.Error("crontab", zap.Any("DeleteOldOriginal", err))
 	}
@@ -441,7 +471,7 @@ func (e *Entry) UpdateDiseaseToCalendar() error {
 		}
 		if count > 0 {
 			calendarTypeName := backend.CalendarTypeMap()[pasturePb.CalendarType_Disease]
-			startDay := time.Now().Format(model.LayoutDate2)
+			startDay := time.Now().Local().Format(model.LayoutDate2)
 			newCalendar := model.NewCalendar(pasture.Id, calendarTypeName, pasturePb.CalendarType_Disease, startDay, startDay, int32(count))
 			if err := e.DB.Model(new(model.Calendar)).
 				Create(newCalendar).Error; err != nil {
@@ -455,7 +485,7 @@ func (e *Entry) UpdateDiseaseToCalendar() error {
 
 func (e *Entry) InitEventData(cowList []*model.Cow, systemBasic *model.SystemBasic) {
 	calendarType := pasturePb.CalendarType_Invalid
-	nowTime := time.Now()
+	nowTime := time.Now().Local()
 	startDay, endDay := "", ""
 	switch systemBasic.Name {
 	case model.PregnantCheckForFirst, model.PregnantCheckForSecond:
@@ -508,8 +538,8 @@ func (e *Entry) UpdateCowWeeklyHigh(cow *model.Cow) int32 {
 	}
 
 	weeklyActiveModelList := make([]*model.WeeklyActiveModel, 0)
-	startTime := time.Now().AddDate(0, 0, -8).Format(model.LayoutDate2)
-	endTime := time.Now().AddDate(0, 0, -2).Format(model.LayoutDate2)
+	startTime := time.Now().Local().AddDate(0, 0, -8).Format(model.LayoutDate2)
+	endTime := time.Now().Local().AddDate(0, 0, -2).Format(model.LayoutDate2)
 	selectStr := fmt.Sprintf(`cow_id,heat_date,count(1) AS nb,IF(ROUND(AVG(high))>%d, ROUND(AVG(high)), %d) AS high`, minWeeklyActive.Value, minWeeklyActive.Value)
 	if err = e.DB.Model(new(model.NeckActiveHabit)).
 		Select(selectStr).

+ 5 - 5
module/crontab/estrus_warning.go

@@ -36,7 +36,7 @@ func (e *Entry) UpdateNeckRingWarning(pastureId int64) (err error) {
 	}
 
 	// 计算时间范围
-	now := time.Now()
+	now := time.Now().Local()
 	startTime := now.AddDate(0, 0, -1)
 	neckRingEstrusList := make([]*model.NeckRingEstrus, 0)
 	if err = e.DB.Table(fmt.Sprintf("%s as a", new(model.NeckRingEstrus).TableName())).
@@ -188,7 +188,7 @@ func (e *Entry) GroupAndProcessData(records []*model.NeckRingEstrus) []*model.Ne
 }
 
 func (e *Entry) GetCowHighChange(pastureId, minId int64) ([]*model.EstrusWarning, error) {
-	nowTime := time.Now().Add(-48 * time.Hour)
+	nowTime := time.Now().Local().Add(-48 * time.Hour)
 	estrusWarningList := make([]*model.EstrusWarning, 0)
 	if err := e.DB.Table(fmt.Sprintf("%s as a", new(model.NeckActiveHabit).TableName())).
 		Select(
@@ -211,7 +211,7 @@ func (e *Entry) GetCowHighChange(pastureId, minId int64) ([]*model.EstrusWarning
 // getRecentMovedCows 辅助函数:检查是否在移牛事件
 func (e *Entry) getRecentMovedCows(pastureId, cowId int64) bool {
 	var count int64
-	startDate := time.Now().AddDate(0, 0, -2)
+	startDate := time.Now().Local().AddDate(0, 0, -2)
 	table := &model.EventCowLog{CowId: cowId}
 	if err := e.DB.Table(table.TableName()).
 		Where("cow_id = ?", cowId).
@@ -230,7 +230,7 @@ func (e *Entry) getRecentMovedCows(pastureId, cowId int64) bool {
 
 func (e *Entry) getMinId(pastureId int64) int64 {
 	var minId int64
-	nowTime := time.Now().AddDate(0, 0, -2).Format(model.LayoutDate2)
+	nowTime := time.Now().Local().AddDate(0, 0, -2).Format(model.LayoutDate2)
 	if err := e.DB.Model(new(model.NeckActiveHabit)).
 		Select("MIN(id) as id").
 		Where("heat_date = ?", nowTime).
@@ -245,7 +245,7 @@ func (e *Entry) getCowHigh(pastureId, cowId, minId int64, dateTime string) int64
 	dateTimeUnix, _ := util.TimeParseLocal(model.LayoutTime, dateTime)
 	dateTimeUnixStart := time.Time{}
 	if dateTimeUnix.IsZero() {
-		dateTimeUnixStart = time.Now().Add(-22 * time.Hour)
+		dateTimeUnixStart = time.Now().Local().Add(-22 * time.Hour)
 	} else {
 		dateTimeUnixStart = dateTimeUnix.Add(-22 * time.Hour)
 	}

+ 1 - 1
module/crontab/health_warning.go

@@ -83,7 +83,7 @@ func (e *Entry) UpdateNeckRingHealth(pastureId int64) error {
 		healthValue = int32(v.Value)
 	}
 
-	nowTime := time.Now()
+	nowTime := time.Now().Local()
 	neckRingHealthList := make([]*model.NeckRingHealth, 0)
 	if err = e.DB.Model(new(model.NeckRingHealth)).
 		Select("MAX(id) AS id,neck_ring_number,cow_id,score,max_high,created_at,min_high,min_chew,min_intake,sum_chew,before_three_sum_chew").

+ 4 - 4
module/crontab/neck_ring_calculate.go

@@ -97,7 +97,7 @@ func (e *Entry) FirstFilterUpdate(pastureId int64, xToDay *XToday) (processIds [
 	}
 	newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
 	if err = e.DB.Model(new(model.NeckActiveHabit)).
-		Where("heat_date >= ?", time.Now().AddDate(0, 0, -7).Format(model.LayoutDate2)).
+		Where("heat_date >= ?", time.Now().Local().AddDate(0, 0, -7).Format(model.LayoutDate2)).
 		Where("pasture_id = ?", pastureId).
 		Where("is_show = ?", pasturePb.IsShow_No).
 		Where(e.DB.Where("high >= ?", xToDay.High).Or("rumina >= ?", xToDay.Rumina)).
@@ -111,7 +111,7 @@ func (e *Entry) FirstFilterUpdate(pastureId int64, xToDay *XToday) (processIds [
 	for _, v := range newNeckActiveHabitList {
 		// 4小时数据不全的不参与滤波
 		activeTime, _ := util.TimeParseLocal(model.LayoutTime, v.ActiveTime)
-		if v.RecordCount != model.DefaultRecordCount && time.Now().Sub(activeTime).Hours() <= 4 {
+		if v.RecordCount != model.DefaultRecordCount && time.Now().Local().Sub(activeTime).Hours() <= 4 {
 			continue
 		}
 
@@ -280,7 +280,7 @@ func (e *Entry) SecondUpdateChangeFilter(pastureId int64, processIds []int64, xT
 
 // FilterCorrectAndScoreUpdate 计算活动量变化趋势校正值(活跃度校正)和健康评分
 func (e *Entry) FilterCorrectAndScoreUpdate(pastureId int64, processIds []int64, xToday *XToday) {
-	beginDayDate := time.Now()
+	beginDayDate := time.Now().Local()
 	before7DayDate := beginDayDate.AddDate(0, 0, -7).Format(model.LayoutDate2)
 	before1DayDate := beginDayDate.AddDate(0, 0, -1).Format(model.LayoutDate2)
 
@@ -362,7 +362,7 @@ func (e *Entry) UpdateFilterCorrect(pastureId int64, processIds []int64) {
 // UpdateChangeAdJust 更新群体校正数据
 func (e *Entry) UpdateChangeAdJust(pastureId int64, xToday *XToday) {
 	res := make([]*model.NeckRingBarChange, 0)
-	oneDayAgo := time.Now().AddDate(0, 0, -1).Format(model.LayoutDate2)
+	oneDayAgo := time.Now().Local().AddDate(0, 0, -1).Format(model.LayoutDate2)
 	if err := e.DB.Table(fmt.Sprintf("%s as h", new(model.NeckActiveHabit).TableName())).
 		Select(`h.neck_ring_number,h.heat_date, h.frameid, c.pen_id, c.pen_name, COUNT(*) as nb,
 		ROUND(AVG(h.change_high)) as change_high, ROUND(AVG(h.change_filter)) as change_filter`).

+ 1 - 1
module/crontab/neck_ring_estrus.go

@@ -60,7 +60,7 @@ func (e *Entry) EntryCowEstrus(pastureId int64) (err error) {
 			xToday.ActiveHigh = int32(v.Value)
 		}
 	}
-	nowTime := time.Now()
+	nowTime := time.Now().Local()
 	e.CowEstrusWarning(pastureId, xToday, nowTime)
 	e.UpdateNewNeckRingEstrus(pastureId, nowTime)
 	return nil

+ 1 - 1
module/crontab/neck_ring_estus_test.go

@@ -3254,7 +3254,7 @@ func recalculate(neckRingList []*model.NeckRingOriginal) []*model.NeckActiveHabi
 		originalMapData[mapKey].IsMageData(v, xframeId)
 	}
 
-	currTime := time.Now()
+	currTime := time.Now().Local()
 	res := make([]*model.NeckActiveHabit, 0)
 	// 算平均值
 	for k, v := range originalMapData {

+ 2 - 2
module/crontab/neck_ring_merge.go

@@ -32,7 +32,7 @@ var (
 // NeckRingOriginalMerge 把脖环数据合并成2个小时的
 func (e *Entry) NeckRingOriginalMerge() (err error) {
 	if ok := e.IsExistCrontabLog(NeckRingOriginal); !ok {
-		newTime := time.Now()
+		newTime := time.Now().Local()
 		e.CreateCrontabLog(NeckRingOriginal)
 		// 原始数据删除15天前的
 		e.DB.Model(new(model.NeckRingOriginal)).
@@ -170,7 +170,7 @@ func Recalculate(neckRingList []*model.NeckRingOriginal) []*model.NeckActiveHabi
 		originalMapData[mapKey].IsMageData(v, xframeId)
 	}
 
-	currTime := time.Now()
+	currTime := time.Now().Local()
 	res := make([]*model.NeckActiveHabit, 0)
 	// 算平均值
 	for k, v := range originalMapData {

+ 2 - 2
module/crontab/other.go

@@ -13,7 +13,7 @@ import (
 
 // IsExistCrontabLog 定时任务今日是否已经执行过
 func (e *Entry) IsExistCrontabLog(name string) bool {
-	currDateTime := time.Now().Format(model.LayoutDate2)
+	currDateTime := time.Now().Local().Format(model.LayoutDate2)
 	var count int64 = 0
 	if err := e.DB.Model(&model.CronLog{}).Where("name = ?", name).
 		Where("date = ?", currDateTime).Count(&count).Error; err != nil {
@@ -28,7 +28,7 @@ func (e *Entry) IsExistCrontabLog(name string) bool {
 
 func (e *Entry) CreateCrontabLog(name string) {
 	// 日志保留15天以内的
-	nowDay := time.Now()
+	nowDay := time.Now().Local()
 	defer func() {
 		if nowDay.Day()%15 == 0 {
 			beforeDay := nowDay.AddDate(0, 0, -15)

+ 1 - 1
module/crontab/pen_behavior_day.go

@@ -32,7 +32,7 @@ func (e *Entry) UpdatePenBehaviorDaily() error {
 // BehaviorDaily 更新牛只每日行为数据
 func (e *Entry) BehaviorDaily(pastureId int64, days int32) {
 	for i := days; i >= 1; i-- {
-		targetDate := time.Now().AddDate(0, 0, -int(i)).Format(model.LayoutDate2)
+		targetDate := time.Now().Local().AddDate(0, 0, -int(i)).Format(model.LayoutDate2)
 
 		// 1. 更新milk_daily表
 		if err := e.updateMilkDaily(pastureId, targetDate); err != nil {

+ 1 - 1
module/crontab/work_cron.go

@@ -45,7 +45,7 @@ func (e *Entry) GenerateCalendarBySameTimePlan(cowList []*model.Cow, sameTime *m
 		return collateNodes[i].Id < collateNodes[j].Id
 	})
 
-	showDay := time.Now()
+	showDay := time.Now().Local()
 	newSameTimeCowDetailList := make([]*model.EventCowSameTime, 0)
 	newEventMatingList := make([]*model.EventMating, 0)
 	for i, collateNode := range collateNodes {

+ 1 - 1
service/asynqsvc/asynq.go

@@ -54,7 +54,7 @@ func asynqError(ctx context.Context, task *asynq.Task, err error) {
 
 func asynqMiddlewareLog(h asynq.Handler) asynq.Handler {
 	return asynq.HandlerFunc(func(ctx context.Context, task *asynq.Task) error {
-		start := time.Now()
+		start := time.Now().Local()
 		if err := h.ProcessTask(ctx, task); err != nil {
 			return err
 		}

+ 3 - 3
service/excel/interface.go

@@ -30,7 +30,7 @@ func createFile(cfg *config.AppConfig) *excelize.File {
 }
 
 func createFileName() string {
-	name := time.Now().Format(model.LayoutTime)
-	rand.Seed(time.Now().UnixNano())
-	return fmt.Sprintf("excle-%v-%v.xlsx", name, rand.Int63n(time.Now().Unix()))
+	name := time.Now().Local().Format(model.LayoutTime)
+	rand.Seed(time.Now().Local().UnixNano())
+	return fmt.Sprintf("excle-%v-%v.xlsx", name, rand.Int63n(time.Now().Local().Unix()))
 }

+ 1 - 1
service/redis/cache.go

@@ -16,7 +16,7 @@ import (
 )
 
 func init() {
-	rand.Seed(time.Now().UnixNano())
+	rand.Seed(time.Now().Local().UnixNano())
 }
 
 // Options redis 使用约束

+ 4 - 4
util/util.go

@@ -69,7 +69,7 @@ var (
 func GenerateRandomNumberString(n int) string {
 	result := make([]byte, n)
 	// A rand.Int63() generates 63 random bits, enough for letterIdxMax characters!
-	rand.Seed(time.Now().UnixNano())
+	rand.Seed(time.Now().Local().UnixNano())
 	for i, cache, remain := n-1, rand.Int63(), LetterIdxMax; i >= 0; {
 		if remain == 0 {
 			cache, remain = rand.Int63(), LetterIdxMax
@@ -111,7 +111,7 @@ func TimeParseLocalEndUnix(DayTime string) int64 {
 // ConvertParseLocalUnix 字符串转换当天时间戳
 // eg 15:04:05 => 1676998245
 func ConvertParseLocalUnix(timeParse string) (int64, error) {
-	value := fmt.Sprintf("%s %s", time.Now().Format(Layout), timeParse)
+	value := fmt.Sprintf("%s %s", time.Now().Local().Format(Layout), timeParse)
 	theTime, err := TimeParseLocal(LayoutTime, value)
 	if err != nil {
 		return 0, err
@@ -121,7 +121,7 @@ func ConvertParseLocalUnix(timeParse string) (int64, error) {
 
 // GetMonthRemainDay 获取当前月还剩几天
 func GetMonthRemainDay() int {
-	now := time.Now()
+	now := time.Now().Local()
 	lastDayOfMonth := time.Date(now.Year(), now.Month()+1, 0, 23, 59, 59, 999999999, now.Location())
 	return int(lastDayOfMonth.Sub(now).Hours()/24) + 1
 }
@@ -464,7 +464,7 @@ func GetNeckRingActiveTimer(frameId int32) (dateTime string, hours int) {
 	if _, ok := FrameIdMap[frameId]; !ok {
 		return "", 0
 	}
-	nowTime := time.Now()
+	nowTime := time.Now().Local()
 	currHour := nowTime.Hour()
 	// 处理2小时的特殊 farmId
 	hours, ok := SpecialHours[int(frameId)]

+ 2 - 2
util/util_more.go

@@ -13,7 +13,7 @@ import (
 )
 
 func CurrentMaxFrameId() int32 {
-	currentHour := time.Now().Hour()
+	currentHour := time.Now().Local().Hour()
 	return int32(math.Floor(float64(currentHour/2))) * 10
 }
 
@@ -67,7 +67,7 @@ func ConvertCowIdsToInt64Slice(input string) ([]int64, error) {
 // GetMonthStartAndEndTimestamp 获取当前月份的开始时间戳和结束时间戳
 func GetMonthStartAndEndTimestamp() (startTimestamp, endTimestamp int64) {
 	// 获取当前时间
-	now := time.Now()
+	now := time.Now().Local()
 
 	// 获取当前月份的第一天
 	startOfMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())

+ 2 - 2
util/util_test.go

@@ -431,7 +431,7 @@ func TestDaysBetween(t *testing.T) {
 }
 
 func TestGetNeckRingActiveTimer(t *testing.T) {
-	nowTime := time.Now().Format(Layout)
+	nowTime := time.Now().Local().Format(Layout)
 	tests := struct {
 		frameId  []int32
 		dateTime []string
@@ -509,7 +509,7 @@ func TestGetNeckRingActiveTimer(t *testing.T) {
 }
 
 func TestSubstr(t *testing.T) {
-	nowTime := time.Now().Format(Layout)
+	nowTime := time.Now().Local().Format(Layout)
 	text := `102053      0   0   53   12.2   4.7  101415 101538   0.4    0        0 0 ???????? 000000  0.0  0.0  0.0  0.0 0`
 	fmt.Println()