作者 yangfu

Merge remote-tracking branch 'origin/test'

@@ -117,7 +117,7 @@ spec: @@ -117,7 +117,7 @@ spec:
117 - name: MANUFACTURE_DEFAULT_ORGID 117 - name: MANUFACTURE_DEFAULT_ORGID
118 value: "44" 118 value: "44"
119 - name: MANUFACTURE_DEFAULT_WORKSHOPID 119 - name: MANUFACTURE_DEFAULT_WORKSHOPID
120 - value: "1" 120 + value: "2"
121 - name: MANUFACTURE_PRODUCT_TYPE 121 - name: MANUFACTURE_PRODUCT_TYPE
122 value: "0502010001ST,0502010007ST,0502010008ST,0502010009ST,0502010010ST,0502010011ST,0502010014ST,0502010016ST,0502010018ST,0502010020ST,0502010021ST,0502010022ST,0502010023ST" 122 value: "0502010001ST,0502010007ST,0502010008ST,0502010009ST,0502010010ST,0502010011ST,0502010014ST,0502010016ST,0502010018ST,0502010020ST,0502010021ST,0502010022ST,0502010023ST"
123 - name: MQTT_HOST 123 - name: MQTT_HOST
@@ -122,8 +122,9 @@ func (deviceCollectionService *DeviceCollectionService) DeviceCollection(createD @@ -122,8 +122,9 @@ func (deviceCollectionService *DeviceCollectionService) DeviceCollection(createD
122 } 122 }
123 123
124 //计算区间的产能 124 //计算区间的产能
  125 +
125 if v, ok := newDeviceCollection.Values["Count"]; ok { 126 if v, ok := newDeviceCollection.Values["Count"]; ok {
126 - newDeviceCollection.Values["total"] = v // 记录原始值 127 + newDeviceCollection.Values["Total"] = v // 记录原始值
127 newDeviceCollection.Values["Count"] = 0 128 newDeviceCollection.Values["Count"] = 0
128 curCount, errCurCount := strconv.Atoi(utils.AssertString(v)) 129 curCount, errCurCount := strconv.Atoi(utils.AssertString(v))
129 lastCount, errLastCount := strconv.Atoi(utils.AssertString(lastDeviceCollectionRecord.Values["Count"])) 130 lastCount, errLastCount := strconv.Atoi(utils.AssertString(lastDeviceCollectionRecord.Values["Count"]))
@@ -142,26 +143,27 @@ func (deviceCollectionService *DeviceCollectionService) DeviceCollection(createD @@ -142,26 +143,27 @@ func (deviceCollectionService *DeviceCollectionService) DeviceCollection(createD
142 newDeviceCollection.ProductCount = count 143 newDeviceCollection.ProductCount = count
143 } 144 }
144 } 145 }
  146 + if _, valErr := newDeviceCollection.Valid(); valErr != nil {
  147 + newDeviceCollection.ResetProductCountToZero()
  148 + }
145 // TODO:测试假数据,后期注释掉 149 // TODO:测试假数据,后期注释掉
146 //if createDeviceCollectionCommand.DeviceType == domain.DeviceTypeChuanChuanJi { 150 //if createDeviceCollectionCommand.DeviceType == domain.DeviceTypeChuanChuanJi {
147 // newDeviceCollection.Values["Count"] = rand.Intn(300) 151 // newDeviceCollection.Values["Count"] = rand.Intn(300)
  152 + // newDeviceCollection.StartupStatus = 1
  153 + // newDeviceCollection.ComStatus = 1
  154 + // newDeviceCollection.CollectionTime = time.Date(2022,4,18,7,0,0,0,time.Local)
148 //} 155 //}
149 - deviceCollection, err := deviceCollectionRepository.Save(newDeviceCollection)  
150 - if err != nil { 156 + if newDeviceCollection, err = deviceCollectionRepository.Save(newDeviceCollection); err != nil {
151 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 157 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
152 } 158 }
153 - err = domainService.SendWorkshopDeviceData(deviceCollection)  
154 - if err != nil { 159 + if err = domainService.SendWorkshopDeviceData(newDeviceCollection); err != nil {
155 log.Logger.Error("车间设备数据加入redis失败:" + err.Error()) 160 log.Logger.Error("车间设备数据加入redis失败:" + err.Error())
156 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 161 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
157 } 162 }
158 -  
159 if err := transactionContext.CommitTransaction(); err != nil { 163 if err := transactionContext.CommitTransaction(); err != nil {
160 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 164 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
161 } 165 }
162 - return map[string]interface{}{  
163 - "deviceCollection": deviceCollection,  
164 - }, nil 166 + return nil, nil
165 167
166 } 168 }
167 169
@@ -2,6 +2,7 @@ package dto @@ -2,6 +2,7 @@ package dto
2 2
3 import ( 3 import (
4 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" 4 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
  5 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
5 "time" 6 "time"
6 ) 7 )
7 8
@@ -43,7 +44,7 @@ func (d *ProductLevelTwoRecord) LoadDto(m *domain.ProductRecord, orgId int) *Pro @@ -43,7 +44,7 @@ func (d *ProductLevelTwoRecord) LoadDto(m *domain.ProductRecord, orgId int) *Pro
43 d.ProductRecordId = m.ProductRecordId 44 d.ProductRecordId = m.ProductRecordId
44 d.ProductWorker = m.ProductWorker 45 d.ProductWorker = m.ProductWorker
45 d.WorkStation = m.WorkStation 46 d.WorkStation = m.WorkStation
46 - d.WeighBefore = m.ProductRecordInfo.WeighBefore 47 + d.WeighBefore = utils.Round(m.ProductRecordInfo.WeighBefore, 1)
47 d.WeighAfter = m.ProductRecordInfo.WeighAfter 48 d.WeighAfter = m.ProductRecordInfo.WeighAfter
48 d.ApproveStatus = m.ProductRecordInfo.ApproveStatus 49 d.ApproveStatus = m.ProductRecordInfo.ApproveStatus
49 d.WorkOn = m.ProductRecordInfo.WorkOn 50 d.WorkOn = m.ProductRecordInfo.WorkOn
@@ -291,12 +291,6 @@ func (productRecordService *ProductRecordService) ProductRecordStatics(cmd *comm @@ -291,12 +291,6 @@ func (productRecordService *ProductRecordService) ProductRecordStatics(cmd *comm
291 }() 291 }()
292 var _ domain.ProductRecordRepository 292 var _ domain.ProductRecordRepository
293 var productRecord *domain.ProductRecord = cmd.ProductRecord 293 var productRecord *domain.ProductRecord = cmd.ProductRecord
294 - //_,productRecord,err = factory.FastPgProductRecord(transactionContext,cmd.ProductRecordId)  
295 - //if err!=nil{  
296 - // log.Logger.Error(err.Error())  
297 - // return nil, nil  
298 - //}  
299 - //  
300 if productRecord == nil { 294 if productRecord == nil {
301 return nil, nil 295 return nil, nil
302 } 296 }
@@ -97,3 +97,26 @@ func (deviceCollection *DeviceCollection) Update(data map[string]interface{}) er @@ -97,3 +97,26 @@ func (deviceCollection *DeviceCollection) Update(data map[string]interface{}) er
97 func TaskDeviceCollection() string { 97 func TaskDeviceCollection() string {
98 return fmt.Sprintf("%v:task:device-collection:report", constant.CACHE_PREFIX) 98 return fmt.Sprintf("%v:task:device-collection:report", constant.CACHE_PREFIX)
99 } 99 }
  100 +
  101 +func (data *DeviceCollection) Valid() (bool, error) {
  102 + var (
  103 + result = false
  104 + )
  105 + if data.ProductCount > DeviceMaxSingleProductCount {
  106 + return result, fmt.Errorf("设备数据异常: 生产数量超过:%v", DeviceMaxSingleProductCount)
  107 + }
  108 + if data.StartupStatus == 0 {
  109 + return result, fmt.Errorf("设备数据异常: 启动0")
  110 + }
  111 + if data.ComStatus == 0 {
  112 + return result, fmt.Errorf("设备数据异常: 通讯0")
  113 + }
  114 + return true, nil
  115 +}
  116 +
  117 +func (data *DeviceCollection) ResetProductCountToZero() {
  118 + data.ProductCount = 0
  119 + if data.Values != nil {
  120 + data.Values["Count"] = 0
  121 + }
  122 +}
@@ -53,14 +53,19 @@ func (deviceDailyRunningRecord *DeviceDailyRunningRecord) Update(data map[string @@ -53,14 +53,19 @@ func (deviceDailyRunningRecord *DeviceDailyRunningRecord) Update(data map[string
53 return nil 53 return nil
54 } 54 }
55 55
56 -func (deviceDailyRunningRecord *DeviceDailyRunningRecord) AddDeviceRunningData(t time.Time, data *DeviceRunningData) { 56 +func (deviceDailyRunningRecord *DeviceDailyRunningRecord) AddDeviceRunningData(data *DeviceRunningData) bool {
  57 + t := data.CollectionTime
57 deviceDailyRunningRecord.DeviceRunningRecordInfo.AddDeviceRunningData(t, data) 58 deviceDailyRunningRecord.DeviceRunningRecordInfo.AddDeviceRunningData(t, data)
58 now := time.Now().Unix() 59 now := time.Now().Unix()
59 - if t.Unix() > (now-DefaultCollectionTimeSpan) && t.Unix() < (now+DefaultCollectionTimeSpan) { 60 + ts := t.Local().Unix()
  61 + deviceDailyRunningRecord.UpdatedAt = time.Now()
  62 + if ts > (now-DefaultCollectionTimeSpan) && ts < (now+DefaultCollectionTimeSpan) {
60 deviceDailyRunningRecord.UpdatedAt = t 63 deviceDailyRunningRecord.UpdatedAt = t
61 - return  
62 } 64 }
63 - deviceDailyRunningRecord.UpdatedAt = time.Now() 65 + if ok, _ := data.Valid(); !ok {
  66 + return false
  67 + }
  68 + return true
64 } 69 }
65 70
66 func (deviceDailyRunningRecord *DeviceDailyRunningRecord) String() string { 71 func (deviceDailyRunningRecord *DeviceDailyRunningRecord) String() string {
1 package domain 1 package domain
2 2
3 -import "time" 3 +import (
  4 + "fmt"
  5 + "time"
  6 +)
  7 +
  8 +const DeviceMaxSingleProductCount = 10000
4 9
5 // 设备运行数据 10 // 设备运行数据
6 type DeviceRunningData struct { 11 type DeviceRunningData struct {
@@ -24,6 +29,8 @@ type DeviceRunningData struct { @@ -24,6 +29,8 @@ type DeviceRunningData struct {
24 // 附加数据 29 // 附加数据
25 // 匹配数目 30 // 匹配数目
26 Count int `json:"count"` 31 Count int `json:"count"`
  32 + // 当天数量
  33 + TodayTotal int `json:"today_total"`
27 // 合计数目 34 // 合计数目
28 Total int `json:"total"` 35 Total int `json:"total"`
29 // 炸机前段温度:炸机前段当前温度 YZJ1 油炸机 36 // 炸机前段温度:炸机前段当前温度 YZJ1 油炸机
@@ -41,3 +48,20 @@ type DeviceRunningData struct { @@ -41,3 +48,20 @@ type DeviceRunningData struct {
41 // 单位数据 比如:1串/0.1kg weight = count * unitQuantity 48 // 单位数据 比如:1串/0.1kg weight = count * unitQuantity
42 UnitQuantity float64 `json:"unitQuantity"` 49 UnitQuantity float64 `json:"unitQuantity"`
43 } 50 }
  51 +
  52 +func (data *DeviceRunningData) Valid() (bool, error) {
  53 + var (
  54 + result = false
  55 + )
  56 + if data.Count > DeviceMaxSingleProductCount {
  57 + data.Count = 0
  58 + return result, fmt.Errorf("设备数据异常: 生产数量超过:%v", DeviceMaxSingleProductCount)
  59 + }
  60 + if data.StartupStatus == 0 {
  61 + return result, fmt.Errorf("设备数据异常: 启动0")
  62 + }
  63 + if data.ComStatus == 0 {
  64 + return result, fmt.Errorf("设备数据异常: 通讯0")
  65 + }
  66 + return true, nil
  67 +}
@@ -75,7 +75,7 @@ func (info *ProductRecordStaticInfo) PreStatistics(productWeight float64, second @@ -75,7 +75,7 @@ func (info *ProductRecordStaticInfo) PreStatistics(productWeight float64, second
75 } else if info.OutputWeight == info.InputWeight { 75 } else if info.OutputWeight == info.InputWeight {
76 info.QualificationRate = 100 76 info.QualificationRate = 100
77 } else { 77 } else {
78 - info.QualificationRate = utils.Round(info.OutputWeight*100.0/info.InputWeight, 0) 78 + info.QualificationRate = utils.Truncate(info.OutputWeight*100.0/info.InputWeight, 2)
79 } 79 }
80 } 80 }
81 81
1 package domainService 1 package domainService
2 2
3 import ( 3 import (
  4 + "fmt"
4 "github.com/hibiken/asynq" 5 "github.com/hibiken/asynq"
5 "github.com/linmadan/egglib-go/utils/json" 6 "github.com/linmadan/egglib-go/utils/json"
6 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" 7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" 8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
8 ) 9 )
9 10
10 -func SendWorkshopWorkTimeStaticJob(productRecord *domain.ProductAttendanceRecord) error {  
11 - return SendAsyncJob(domain.TaskKeyWorkshopWorkTimeRecordStatics(), productRecord) 11 +const (
  12 + QueueProduct = "product"
  13 + QueueDevice = "device"
  14 + QueueDefault = "default"
  15 +)
  16 +
  17 +func FormatQueue(qt string) string {
  18 + return fmt.Sprintf("%v:queue:%v", constant.CACHE_PREFIX, qt)
12 } 19 }
13 20
14 -func SendProductRecordStaticsJob(productRecord *domain.ProductRecord) error {  
15 - task := asynq.NewTask(domain.TaskKeyPatternProductRecordStatics(), []byte(json.MarshalToString(productRecord))) 21 +func SendWorkshopWorkTimeStaticJob(r *domain.ProductAttendanceRecord) error {
  22 + return SendAsyncJob(domain.TaskKeyWorkshopWorkTimeRecordStatics(), r, asynq.Queue(FormatQueue(QueueDefault)))
  23 +}
16 24
17 - client := asynq.NewClient(asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS})  
18 - _, err := client.Enqueue(task)  
19 - return err 25 +func SendProductRecordStaticsJob(r *domain.ProductRecord) error {
  26 + return SendAsyncJob(domain.TaskKeyPatternProductRecordStatics(), r, asynq.Queue(FormatQueue(QueueProduct)))
20 } 27 }
21 28
22 -func SendDeviceZkTecoReportJob(productRecord *domain.DeviceZkTeco) error {  
23 - return SendAsyncJob(domain.TaskDeviceZkTecoReport(), productRecord) 29 +func SendDeviceZkTecoReportJob(r *domain.DeviceZkTeco) error {
  30 + return SendAsyncJob(domain.TaskDeviceZkTecoReport(), r, asynq.Queue(FormatQueue(QueueDefault)))
24 } 31 }
25 32
26 -func SendWorkshopDeviceData(productRecord *domain.DeviceCollection) error {  
27 - return SendAsyncJob(domain.TaskDeviceCollection(), productRecord) 33 +func SendWorkshopDeviceData(r *domain.DeviceCollection) error {
  34 + return SendAsyncJob(domain.TaskDeviceCollection(), r, asynq.Queue(FormatQueue(QueueDevice)))
28 } 35 }
29 36
30 -func SendAsyncJob(queueName string, job interface{}) error { 37 +func SendAsyncJob(queueName string, job interface{}, opts ...asynq.Option) error {
31 task := asynq.NewTask(queueName, []byte(json.MarshalToString(job))) 38 task := asynq.NewTask(queueName, []byte(json.MarshalToString(job)))
32 client := asynq.NewClient(asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS}) 39 client := asynq.NewClient(asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS})
33 - _, err := client.Enqueue(task) 40 + _, err := client.Enqueue(task, opts...)
34 return err 41 return err
35 } 42 }
@@ -60,7 +60,7 @@ func (ptr *PGProductRecordService) SubmitProductRecord(productRecordType int, qu @@ -60,7 +60,7 @@ func (ptr *PGProductRecordService) SubmitProductRecord(productRecordType int, qu
60 workstation *domain.WorkStation 60 workstation *domain.WorkStation
61 uc *domain.UnitConversion 61 uc *domain.UnitConversion
62 err error 62 err error
63 - weight float64 = request.Weigh 63 + weight float64 = utils.Round(request.Weigh, 1)
64 ) 64 )
65 if plan, err = productPlanRepository.FindOne(map[string]interface{}{"productPlanId": request.ProductPlanId}); err != nil { 65 if plan, err = productPlanRepository.FindOne(map[string]interface{}{"productPlanId": request.ProductPlanId}); err != nil {
66 return nil, err 66 return nil, err
@@ -25,10 +25,8 @@ const ( @@ -25,10 +25,8 @@ const (
25 func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain.ProductRecord) (interface{}, error) { 25 func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain.ProductRecord) (interface{}, error) {
26 26
27 var ( 27 var (
28 - workshopRepository, _ = repository.NewWorkshopRepository(ptr.transactionContext)  
29 - productPlanRepository, _ = repository.NewProductPlanRepository(ptr.transactionContext)  
30 - productGroupRepository, _ = repository.NewProductGroupRepository(ptr.transactionContext)  
31 - //employeeProductRecordRepository, _ = repository.NewEmployeeProductRecordRepository(ptr.transactionContext) 28 + workshopRepository, _ = repository.NewWorkshopRepository(ptr.transactionContext)
  29 + productPlanRepository, _ = repository.NewProductPlanRepository(ptr.transactionContext)
32 ) 30 )
33 31
34 var ( 32 var (
@@ -60,9 +58,9 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain. @@ -60,9 +58,9 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain.
60 case ProductSection3: 58 case ProductSection3:
61 break 59 break
62 case ProductSection4: //个人特殊处理 60 case ProductSection4: //个人特殊处理
63 - return ptr.personalProductStatics(nil, nil, nil, productRecord) 61 + return ptr.personalProductStatics(nil, productRecord)
64 default: 62 default:
65 - return nil, nil //ptr.personalProductStatics(productRecord) 63 + return nil, nil
66 } 64 }
67 if planId == 0 { 65 if planId == 0 {
68 log.Logger.Debug(fmt.Sprintf("工段:%v product_record 编号:%v 批次为0", productRecord.WorkStation.WorkStationId, productRecord.ProductRecordId)) 66 log.Logger.Debug(fmt.Sprintf("工段:%v product_record 编号:%v 批次为0", productRecord.WorkStation.WorkStationId, productRecord.ProductRecordId))
@@ -74,9 +72,6 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain. @@ -74,9 +72,6 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain.
74 return nil, err 72 return nil, err
75 } 73 }
76 74
77 - // 2.1 判断是否是支援类型 有打卡记录,员工是否是属于该工段的员工  
78 - groupMembers, groupMembersKeyFunc := FindGroupMembers(productGroupRepository, cid, oid, productRecord.WorkStation.WorkStationId)  
79 -  
80 // 集体 75 // 集体
81 // 1.查询员工 -》 员工打卡记录 工位+打卡日期 76 // 1.查询员工 -》 员工打卡记录 工位+打卡日期
82 // 2.打卡记录的时间区间 在生产记录上报的时间范围内 77 // 2.打卡记录的时间区间 在生产记录上报的时间范围内
@@ -91,8 +86,8 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain. @@ -91,8 +86,8 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain.
91 productRecord.ProductWorker = r.ProductWorker 86 productRecord.ProductWorker = r.ProductWorker
92 // 3.查询员工产能记录 -》员工 批次+工位+批次生产日期 (有 更新产能数据、没有插入一条产能数据) 87 // 3.查询员工产能记录 -》员工 批次+工位+批次生产日期 (有 更新产能数据、没有插入一条产能数据)
93 // 4.更新产能 (产能、二级品) (特殊工段处理 打料、成型) 88 // 4.更新产能 (产能、二级品) (特殊工段处理 打料、成型)
94 - // 个人  
95 - if _, err := ptr.personalProductStatics(productPlan, groupMembers, groupMembersKeyFunc, productRecord); err != nil { 89 + // 个人产能统计
  90 + if _, err := ptr.personalProductStatics(productPlan, productRecord); err != nil {
96 return nil, err 91 return nil, err
97 } 92 }
98 } 93 }
@@ -174,31 +169,28 @@ func FindGroupMembers(productGroupRepository domain.ProductGroupRepository, comp @@ -174,31 +169,28 @@ func FindGroupMembers(productGroupRepository domain.ProductGroupRepository, comp
174 } 169 }
175 170
176 // 个人生产记录统计 171 // 个人生产记录统计
177 -func (ptr *PGProductRecordService) personalProductStatics(productPlan *domain.ProductPlan, groupMembers map[string]*domain.User, groupMembersKeyFunc func(int) string, productRecord *domain.ProductRecord) (interface{}, error) { 172 +func (ptr *PGProductRecordService) personalProductStatics(productPlan *domain.ProductPlan, productRecord *domain.ProductRecord) (interface{}, error) {
178 var ( 173 var (
179 - //workshopRepository,_=repository.NewWorkshopRepository(ptr.transactionContext)  
180 productPlanRepository, _ = repository.NewProductPlanRepository(ptr.transactionContext) 174 productPlanRepository, _ = repository.NewProductPlanRepository(ptr.transactionContext)
181 productGroupRepository, _ = repository.NewProductGroupRepository(ptr.transactionContext) 175 productGroupRepository, _ = repository.NewProductGroupRepository(ptr.transactionContext)
182 employeeProductRecordRepository, _ = repository.NewEmployeeProductRecordRepository(ptr.transactionContext) 176 employeeProductRecordRepository, _ = repository.NewEmployeeProductRecordRepository(ptr.transactionContext)
183 ) 177 )
184 var ( 178 var (
185 - cid = productRecord.CompanyId  
186 - oid = productRecord.OrgId  
187 - planId = productRecord.ProductRecordInfo.ProductPlanId  
188 - //productPlan *domain.ProductPlan  
189 - err error 179 + cid = productRecord.CompanyId
  180 + oid = productRecord.OrgId
  181 + planId = productRecord.ProductRecordInfo.ProductPlanId
  182 + err error
  183 + workStationId = productRecord.WorkStation.WorkStationId
190 ) 184 )
191 // 2.1 判断是否是支援类型 有打卡记录,员工是否是属于该工段的员工 185 // 2.1 判断是否是支援类型 有打卡记录,员工是否是属于该工段的员工
192 - if groupMembers == nil {  
193 - groupMembers, groupMembersKeyFunc = FindGroupMembers(productGroupRepository, cid, oid, productRecord.WorkStation.WorkStationId)  
194 - } 186 + groupMembers, groupMembersKeyFunc := FindGroupMembers(productGroupRepository, cid, oid, workStationId)
  187 +
195 if productPlan == nil { 188 if productPlan == nil {
196 productPlan, err = productPlanRepository.FindOne(map[string]interface{}{"productPlanId": planId}) 189 productPlan, err = productPlanRepository.FindOne(map[string]interface{}{"productPlanId": planId})
197 if err != nil { 190 if err != nil {
198 return nil, err 191 return nil, err
199 } 192 }
200 } 193 }
201 - workStationId := productRecord.WorkStation.WorkStationId  
202 194
203 employeeProductRecordDao, _ := dao.NewEmployeeProductRecordDao(ptr.transactionContext) 195 employeeProductRecordDao, _ := dao.NewEmployeeProductRecordDao(ptr.transactionContext)
204 196
@@ -231,11 +223,13 @@ func (ptr *PGProductRecordService) personalProductStatics(productPlan *domain.Pr @@ -231,11 +223,13 @@ func (ptr *PGProductRecordService) personalProductStatics(productPlan *domain.Pr
231 } 223 }
232 } 224 }
233 } 225 }
  226 + log.Logger.Debug(fmt.Sprintf("产能统计 员工:%v(%v) 当前产能:%v kg 新增产能:%v kg 原始数量:%v",
  227 + employeeProductRecord.ProductWorker.UserName, employeeProductRecord.ProductWorker.UserId,
  228 + employeeProductRecord.ProductWeigh, productRecord.ProductRecordInfo.Weigh, productRecord.ProductRecordInfo.Original))
234 229
235 employeeProductRecord.UpdateProductWeigh(productRecord, yesterdayOutputWeight, bestOutputWeight) 230 employeeProductRecord.UpdateProductWeigh(productRecord, yesterdayOutputWeight, bestOutputWeight)
236 231
237 if employeeProductRecord, err = employeeProductRecordRepository.Save(employeeProductRecord); err != nil { 232 if employeeProductRecord, err = employeeProductRecordRepository.Save(employeeProductRecord); err != nil {
238 - // TODO:异常处理  
239 log.Logger.Error(fmt.Sprintf("生产记录:[%v] 员工:[%v] 处理异常:%v", productRecord.ProductRecordId, productRecord.ProductWorker.UserId, err.Error())) 233 log.Logger.Error(fmt.Sprintf("生产记录:[%v] 员工:[%v] 处理异常:%v", productRecord.ProductRecordId, productRecord.ProductWorker.UserId, err.Error()))
240 } 234 }
241 return nil, nil 235 return nil, nil
@@ -244,9 +238,8 @@ func (ptr *PGProductRecordService) personalProductStatics(productPlan *domain.Pr @@ -244,9 +238,8 @@ func (ptr *PGProductRecordService) personalProductStatics(productPlan *domain.Pr
244 //WorkshopProductStatics 车间产能统计 238 //WorkshopProductStatics 车间产能统计
245 func (ptr *PGProductRecordService) WorkshopProductStatics(productRecord *domain.ProductRecord) (interface{}, error) { 239 func (ptr *PGProductRecordService) WorkshopProductStatics(productRecord *domain.ProductRecord) (interface{}, error) {
246 var ( 240 var (
247 - workshopRepository, _ = repository.NewWorkshopRepository(ptr.transactionContext)  
248 - productPlanRepository, _ = repository.NewProductPlanRepository(ptr.transactionContext)  
249 - //productGroupRepository, _ = repository.NewProductGroupRepository(ptr.transactionContext) 241 + workshopRepository, _ = repository.NewWorkshopRepository(ptr.transactionContext)
  242 + productPlanRepository, _ = repository.NewProductPlanRepository(ptr.transactionContext)
250 workshopProductRecordRepository, _ = repository.NewWorkshopProductRecordRepository(ptr.transactionContext) 243 workshopProductRecordRepository, _ = repository.NewWorkshopProductRecordRepository(ptr.transactionContext)
251 ) 244 )
252 245
@@ -295,6 +288,9 @@ func (ptr *PGProductRecordService) WorkshopProductStatics(productRecord *domain. @@ -295,6 +288,9 @@ func (ptr *PGProductRecordService) WorkshopProductStatics(productRecord *domain.
295 return nil, nil 288 return nil, nil
296 } 289 }
297 } 290 }
  291 + log.Logger.Debug(fmt.Sprintf("产能统计 工位:%v(%v) 当前产能:%v kg 新增产能:%v kg 原始数量:%v",
  292 + workshopProductRecord.WorkStation.WorkStationId, workshopProductRecord.WorkStation.SectionName,
  293 + workshopProductRecord.ProductWeigh, productRecord.ProductRecordInfo.Weigh, productRecord.ProductRecordInfo.Original))
298 workshopProductRecord.UpdateProductWeigh(productRecord) 294 workshopProductRecord.UpdateProductWeigh(productRecord)
299 // 打料 跟 成型工段的初始产能是批次的产能 295 // 打料 跟 成型工段的初始产能是批次的产能
300 if productRecord.WorkStation.SectionName == ProductSection1 && productRecord.WorkStation.SectionName == ProductSection2 { 296 if productRecord.WorkStation.SectionName == ProductSection1 && productRecord.WorkStation.SectionName == ProductSection2 {
@@ -28,7 +28,6 @@ func (ptr *PGWorkshopDataConsumeService) Consume(companyId, orgId int, record *d @@ -28,7 +28,6 @@ func (ptr *PGWorkshopDataConsumeService) Consume(companyId, orgId int, record *d
28 planId int 28 planId int
29 err error 29 err error
30 plan *domain.ProductPlanDispatchRecord 30 plan *domain.ProductPlanDispatchRecord
31 - //datetime time.Time  
32 ) 31 )
33 var ( 32 var (
34 deviceRepository, _ = repository.NewDeviceRepository(ptr.transactionContext) 33 deviceRepository, _ = repository.NewDeviceRepository(ptr.transactionContext)
@@ -67,12 +66,11 @@ func (ptr *PGWorkshopDataConsumeService) Consume(companyId, orgId int, record *d @@ -67,12 +66,11 @@ func (ptr *PGWorkshopDataConsumeService) Consume(companyId, orgId int, record *d
67 66
68 var saveErr error 67 var saveErr error
69 if deviceDailyRecord, saveErr = ptr.saveDeviceDailyRunningRecord(companyId, orgId, workStation, device, planId, deviceRunningData); err != nil { 68 if deviceDailyRecord, saveErr = ptr.saveDeviceDailyRunningRecord(companyId, orgId, workStation, device, planId, deviceRunningData); err != nil {
70 - //log.Logger.Error(saveErr.Error())  
71 return nil, err 69 return nil, err
72 } 70 }
73 defer func() { 71 defer func() {
74 if saveErr != nil { 72 if saveErr != nil {
75 - redis.RemoveDeviceDailyRunningRecord(time.Now(), deviceRunningData.DeviceCode) 73 + redis.RemoveDeviceDailyRunningRecord(deviceRunningData.CollectionTime, deviceRunningData.DeviceCode)
76 } 74 }
77 }() 75 }()
78 } 76 }
@@ -88,24 +86,31 @@ func (ptr *PGWorkshopDataConsumeService) Consume(companyId, orgId int, record *d @@ -88,24 +86,31 @@ func (ptr *PGWorkshopDataConsumeService) Consume(companyId, orgId int, record *d
88 } 86 }
89 87
90 // 1.保存设备运行记录 88 // 1.保存设备运行记录
  89 + deviceRunningData.TodayTotal = deviceDailyRecord.DeviceRunningRecordInfo.Count
91 deviceRunningRecord, _ = ptr.newDeviceRunningRecord(companyId, orgId, workStation, device, deviceRunningData) 90 deviceRunningRecord, _ = ptr.newDeviceRunningRecord(companyId, orgId, workStation, device, deviceRunningData)
92 if _, err = deviceRunningRecordRepository.Save(deviceRunningRecord); err != nil { 91 if _, err = deviceRunningRecordRepository.Save(deviceRunningRecord); err != nil {
93 return nil, err 92 return nil, err
94 } 93 }
95 - // 2.保存设备生产记录 (统计车间、员工产能) 批次跟数量不为空  
96 - if record.DeviceType == domain.DeviceTypeChuanChuanJi && plan != nil && deviceRunningData.Count > 0 {  
97 94
98 - productRecord, _ := ptr.newProductRecord(companyId, orgId, workStation, device, deviceRunningData, plan)  
99 - //if _, err = deviceRunningRecordRepository.Save(deviceRunningRecord); err != nil {  
100 - // return nil, err  
101 - //}  
102 - SendProductRecordStaticsJob(productRecord) 95 + // 2.更新 设备每日运行记录(汇总) - redis更新 十分钟异步刷库 TODO:这边会有并发问题,加锁
  96 + if addSuccess := deviceDailyRecord.AddDeviceRunningData(deviceRunningData); addSuccess {
  97 + // 3.保存设备生产记录 (统计车间、员工产能) 批次跟数量不为空
  98 + if record.DeviceType == domain.DeviceTypeChuanChuanJi && plan != nil && deviceRunningData.Count > 0 {
  99 + log.Logger.Debug(fmt.Sprintf("设备统计 设备:%v(%v) 当前数量:%v 增加数量:%v",
  100 + deviceDailyRecord.DeviceCode,
  101 + deviceDailyRecord.ProductDate.Local().Format("2006-01-02"),
  102 + deviceRunningRecord.DeviceRunningRecordInfo.TodayTotal,
  103 + deviceRunningRecord.DeviceRunningRecordInfo.Count))
  104 + productRecord, _ := ptr.newProductRecord(companyId, orgId, workStation, device, deviceRunningData, plan)
  105 + // 同步执行
  106 + //productRecordService, _ := NewPGProductRecordService(ptr.transactionContext)
  107 + //productRecordService.EmployeeProductStatics(productRecord)
  108 + //productRecordService.WorkshopProductStatics(productRecord)
  109 + // 异步执行
  110 + SendProductRecordStaticsJob(productRecord)
  111 + }
103 } 112 }
104 -  
105 - // 3.更新 设备每日运行记录(汇总) - redis更新 十分钟异步刷库  
106 - deviceDailyRecord.AddDeviceRunningData(deviceRunningData.CollectionTime, deviceRunningData)  
107 if err = redis.SaveDeviceDailyRunningRecord(deviceDailyRecord); err != nil { 113 if err = redis.SaveDeviceDailyRunningRecord(deviceDailyRecord); err != nil {
108 - //log.Logger.Error(err.Error())  
109 return nil, err 114 return nil, err
110 } 115 }
111 return nil, nil 116 return nil, nil
@@ -153,16 +158,16 @@ func (ptr *PGWorkshopDataConsumeService) newDeviceRunningData(record *domain.Dev @@ -153,16 +158,16 @@ func (ptr *PGWorkshopDataConsumeService) newDeviceRunningData(record *domain.Dev
153 if err != nil { 158 if err != nil {
154 break 159 break
155 } 160 }
156 - data.Temp1 = deviceYouZhaJi.FrontTemp  
157 - data.Temp2 = deviceYouZhaJi.BackTemp 161 + data.Temp1 = utils.Truncate(deviceYouZhaJi.FrontTemp, 1)
  162 + data.Temp2 = utils.Truncate(deviceYouZhaJi.BackTemp, 1)
158 } else { 163 } else {
159 deviceYouZhaJi := &domain.DeviceYouZhaJi2{} 164 deviceYouZhaJi := &domain.DeviceYouZhaJi2{}
160 err = json.Unmarshal(mBytes, deviceYouZhaJi) 165 err = json.Unmarshal(mBytes, deviceYouZhaJi)
161 if err != nil { 166 if err != nil {
162 break 167 break
163 } 168 }
164 - data.Temp1 = deviceYouZhaJi.Temp1  
165 - data.Temp2 = deviceYouZhaJi.Temp2 169 + data.Temp1 = utils.Truncate(deviceYouZhaJi.Temp1, 1)
  170 + data.Temp2 = utils.Truncate(deviceYouZhaJi.Temp2, 1)
166 } 171 }
167 break 172 break
168 //串串机 173 //串串机
@@ -187,7 +192,7 @@ func (ptr *PGWorkshopDataConsumeService) newDeviceRunningData(record *domain.Dev @@ -187,7 +192,7 @@ func (ptr *PGWorkshopDataConsumeService) newDeviceRunningData(record *domain.Dev
187 if err != nil { 192 if err != nil {
188 break 193 break
189 } 194 }
190 - data.Temp1 = deviceSuDongXian.CurrTemp 195 + data.Temp1 = utils.Truncate(deviceSuDongXian.CurrTemp, 1)
191 break 196 break
192 //封口机 197 //封口机
193 case domain.DeviceTypeFengKouJi: 198 case domain.DeviceTypeFengKouJi:
@@ -296,7 +301,7 @@ func (ptr *PGWorkshopDataConsumeService) saveDeviceDailyRunningRecord(companyId, @@ -296,7 +301,7 @@ func (ptr *PGWorkshopDataConsumeService) saveDeviceDailyRunningRecord(companyId,
296 DeviceCode: device.DeviceCode, 301 DeviceCode: device.DeviceCode,
297 ProductDate: utils.GetZeroTime(data.CollectionTime), 302 ProductDate: utils.GetZeroTime(data.CollectionTime),
298 DeviceRunningRecordInfo: recordInfo, 303 DeviceRunningRecordInfo: recordInfo,
299 - CreatedAt: time.Now(), 304 + CreatedAt: data.CollectionTime,
300 UpdatedAt: time.Now(), 305 UpdatedAt: time.Now(),
301 } 306 }
302 if record, err = deviceDailyRunningRecordRepository.Save(record); err != nil { 307 if record, err = deviceDailyRunningRecordRepository.Save(record); err != nil {
@@ -6,6 +6,7 @@ import ( @@ -6,6 +6,7 @@ import (
6 "github.com/go-redis/redis" 6 "github.com/go-redis/redis"
7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" 7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" 8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
9 "time" 10 "time"
10 ) 11 )
11 12
@@ -13,6 +14,7 @@ import ( @@ -13,6 +14,7 @@ import (
13 func GetDeviceDailyRunningRecord(t time.Time, deviceCode string) (*domain.DeviceDailyRunningRecord, error) { 14 func GetDeviceDailyRunningRecord(t time.Time, deviceCode string) (*domain.DeviceDailyRunningRecord, error) {
14 client := GetRedis() 15 client := GetRedis()
15 key := DeviceDailyRunningRecordKey(t, deviceCode) 16 key := DeviceDailyRunningRecordKey(t, deviceCode)
  17 + log.Logger.Debug(fmt.Sprintf("Redis Device:%v GET Key:%v", deviceCode, key))
16 return getDeviceDailyRunningRecord(client, key) 18 return getDeviceDailyRunningRecord(client, key)
17 } 19 }
18 20
@@ -32,7 +34,8 @@ func getDeviceDailyRunningRecord(client *redis.Client, key string) (*domain.Devi @@ -32,7 +34,8 @@ func getDeviceDailyRunningRecord(client *redis.Client, key string) (*domain.Devi
32 // 保存每日设备运行数据 34 // 保存每日设备运行数据
33 func SaveDeviceDailyRunningRecord(record *domain.DeviceDailyRunningRecord) error { 35 func SaveDeviceDailyRunningRecord(record *domain.DeviceDailyRunningRecord) error {
34 client := GetRedis() 36 client := GetRedis()
35 - key := DeviceDailyRunningRecordKey(record.ProductDate.Local(), record.DeviceCode) 37 + key := DeviceDailyRunningRecordKey(record.ProductDate, record.DeviceCode)
  38 + log.Logger.Debug(fmt.Sprintf("Redis Device:%v SET Key:%v Count:%v", record.DeviceCode, key, record.DeviceRunningRecordInfo.Count))
36 recordData, err := json.Marshal(record) 39 recordData, err := json.Marshal(record)
37 result := client.Set(key, recordData, time.Hour*24*5) 40 result := client.Set(key, recordData, time.Hour*24*5)
38 _, err = result.Result() 41 _, err = result.Result()
@@ -42,7 +45,7 @@ func SaveDeviceDailyRunningRecord(record *domain.DeviceDailyRunningRecord) error @@ -42,7 +45,7 @@ func SaveDeviceDailyRunningRecord(record *domain.DeviceDailyRunningRecord) error
42 // 保存每日设备运行数据 45 // 保存每日设备运行数据
43 func RemoveDeviceDailyRunningRecord(t time.Time, deviceCode string) error { 46 func RemoveDeviceDailyRunningRecord(t time.Time, deviceCode string) error {
44 client := GetRedis() 47 client := GetRedis()
45 - key := DeviceDailyRunningRecordKey(t.Local(), deviceCode) 48 + key := DeviceDailyRunningRecordKey(t, deviceCode)
46 result := client.Del(key) 49 result := client.Del(key)
47 _, err := result.Result() 50 _, err := result.Result()
48 return err 51 return err
@@ -408,9 +408,17 @@ func NewSnowflakeId() (int64, error) { @@ -408,9 +408,17 @@ func NewSnowflakeId() (int64, error) {
408 return id.Int64(), nil 408 return id.Int64(), nil
409 } 409 }
410 410
  411 +// Round 保留数值的精度位 四舍五入
411 func Round(value float64, places int32) float64 { 412 func Round(value float64, places int32) float64 {
412 quantity := decimal.NewFromFloat(value) 413 quantity := decimal.NewFromFloat(value)
413 d := quantity.Round(places) 414 d := quantity.Round(places)
414 rsp, _ := d.Float64() 415 rsp, _ := d.Float64()
415 return rsp 416 return rsp
416 } 417 }
  418 +
  419 +// Truncate 截取数值固定长度的 eg:Truncate(99.99,1) Result: 99.9
  420 +func Truncate(value float64, places int32) float64 {
  421 + quantity := decimal.NewFromFloat(value).Truncate(places)
  422 + rsp, _ := quantity.Float64()
  423 + return rsp
  424 +}
@@ -3,6 +3,7 @@ package utils @@ -3,6 +3,7 @@ package utils
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "github.com/stretchr/testify/assert" 5 "github.com/stretchr/testify/assert"
  6 + "math"
6 "testing" 7 "testing"
7 "time" 8 "time"
8 ) 9 )
@@ -67,6 +68,7 @@ func timeParse() { @@ -67,6 +68,7 @@ func timeParse() {
67 fmt.Println("1. str: ", str) 68 fmt.Println("1. str: ", str)
68 t, _ := time.Parse(TIME_LAYOUT, str) 69 t, _ := time.Parse(TIME_LAYOUT, str)
69 fmt.Println("2. Parse time: ", t) 70 fmt.Println("2. Parse time: ", t)
  71 + fmt.Println("2.1. Parse time: ", t.Local(), t.Local().Local())
70 tStr := t.Format(TIME_LAYOUT) 72 tStr := t.Format(TIME_LAYOUT)
71 fmt.Println("3. Format time str: ", tStr) 73 fmt.Println("3. Format time str: ", tStr)
72 name, offset := t.Zone() 74 name, offset := t.Zone()
@@ -102,3 +104,14 @@ func parseWithLocation(name string, timeStr string) (time.Time, error) { @@ -102,3 +104,14 @@ func parseWithLocation(name string, timeStr string) (time.Time, error) {
102 return lt, nil 104 return lt, nil
103 } 105 }
104 } 106 }
  107 +
  108 +func TestRound(t *testing.T) {
  109 + t.Logf("%v", Round(99.999, 1))
  110 + t.Logf("%v", Round(99.999, 2))
  111 +
  112 + t.Logf("%.1f", math.Floor(99.99))
  113 + t.Logf("%v", math.Ceil(99.99))
  114 +
  115 + t.Logf("%.1f", Truncate(99.99, 1))
  116 + t.Logf("%v", Truncate(99, 0))
  117 +}
1 package mqtt 1 package mqtt
2 2
3 import ( 3 import (
  4 + "fmt"
4 pahomqtt "github.com/eclipse/paho.mqtt.golang" 5 pahomqtt "github.com/eclipse/paho.mqtt.golang"
5 logimp "github.com/linmadan/egglib-go/log" 6 logimp "github.com/linmadan/egglib-go/log"
6 "github.com/linmadan/egglib-go/utils/json" 7 "github.com/linmadan/egglib-go/utils/json"
@@ -32,6 +33,7 @@ func OnReceiveData(client pahomqtt.Client, message pahomqtt.Message) { @@ -32,6 +33,7 @@ func OnReceiveData(client pahomqtt.Client, message pahomqtt.Message) {
32 collectionTime, _ = time.ParseInLocation("2006-01-02 - 15:04:05", t.(string), time.Local) 33 collectionTime, _ = time.ParseInLocation("2006-01-02 - 15:04:05", t.(string), time.Local)
33 } 34 }
34 if collectionTime.IsZero() { 35 if collectionTime.IsZero() {
  36 + log.Logger.Error(fmt.Sprintf("采集时间有误:%v ", collectionTime), map[string]interface{}{"data": message})
35 return 37 return
36 } 38 }
37 var mBytes []byte 39 var mBytes []byte
@@ -5,6 +5,7 @@ import ( @@ -5,6 +5,7 @@ import (
5 "github.com/hibiken/asynq" 5 "github.com/hibiken/asynq"
6 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" 6 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" 7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
  8 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" 9 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
9 "os" 10 "os"
10 "os/signal" 11 "os/signal"
@@ -19,7 +20,17 @@ func Run() { @@ -19,7 +20,17 @@ func Run() {
19 }() 20 }()
20 srv := asynq.NewServer( 21 srv := asynq.NewServer(
21 asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS}, 22 asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS},
22 - asynq.Config{Concurrency: 1}, 23 + asynq.Config{
  24 + //Concurrency: 4,
  25 + Queues: map[string]int{
  26 + //"critical": 1,
  27 + "default": 1,
  28 + domainService.FormatQueue(domainService.QueueDevice): 1,
  29 + domainService.FormatQueue(domainService.QueueProduct): 1,
  30 + domainService.FormatQueue(domainService.QueueDefault): 1,
  31 + },
  32 + StrictPriority: true,
  33 + },
23 ) 34 )
24 35
25 h := asynq.NewServeMux() 36 h := asynq.NewServeMux()
@@ -17,8 +17,8 @@ func HandlerProductRecordStatics(c context.Context, t *asynq.Task) error { @@ -17,8 +17,8 @@ func HandlerProductRecordStatics(c context.Context, t *asynq.Task) error {
17 if err := json.Unmarshal(t.Payload(), cmd); err != nil { 17 if err := json.Unmarshal(t.Payload(), cmd); err != nil {
18 return err 18 return err
19 } 19 }
20 - log.Logger.Debug(fmt.Sprintf("【生产记录统计】 消费 生产记录ID:%v 类型:%v 工段:%v(%v) 重量:%v", cmd.ProductRecordId, cmd.ProductRecordType,  
21 - cmd.WorkStation.SectionName, cmd.WorkStation.WorkStationId, cmd.ProductRecordInfo.Weigh)) 20 + log.Logger.Debug(fmt.Sprintf("【生产记录统计】 消费 生产记录ID:%v 类型:%v 工段:%v(%v) 重量:%v 记录时间:%v", cmd.ProductRecordId, cmd.ProductRecordType,
  21 + cmd.WorkStation.SectionName, cmd.WorkStation.WorkStationId, cmd.ProductRecordInfo.Weigh, cmd.CreatedAt))
22 _, err := productPlanService.ProductRecordStatics(cmd) 22 _, err := productPlanService.ProductRecordStatics(cmd)
23 if err != nil { 23 if err != nil {
24 log.Logger.Error(err.Error()) 24 log.Logger.Error(err.Error())