正在显示
16 个修改的文件
包含
443 行增加
和
12 行删除
@@ -34,8 +34,10 @@ type SearchEmployeeAttendanceQuery struct { | @@ -34,8 +34,10 @@ type SearchEmployeeAttendanceQuery struct { | ||
34 | SectionName string `cname:"工段名称" json:"sectionName,omitempty"` | 34 | SectionName string `cname:"工段名称" json:"sectionName,omitempty"` |
35 | // 姓名 | 35 | // 姓名 |
36 | UserName string `cname:"姓名" json:"userName,omitempty"` | 36 | UserName string `cname:"姓名" json:"userName,omitempty"` |
37 | - // 考勤状态 1.未审核 2:已审核 4.自动审核 | ||
38 | - AttendanceStatus int `cname:"考勤状态 1.未审核 2:已审核 4.自动审核" json:"attendanceStatus,omitempty"` | 37 | + // 考勤状态 1.未审核 2:已审核 3.自动审核 |
38 | + AttendanceStatus int `cname:"考勤状态 1.未审核 2:已审核 3.自动审核" json:"attendanceStatus,omitempty"` | ||
39 | + // 员工类型 1:固定 2:派遣 3.临时 | ||
40 | + EmployeeType int `cname:"1:固定 2:派遣 3.临时" json:"employeeType,omitempty"` | ||
39 | // 开始时间 | 41 | // 开始时间 |
40 | BeginTime string `cname:"开始时间" json:"beginTime"` | 42 | BeginTime string `cname:"开始时间" json:"beginTime"` |
41 | // 结束时间 | 43 | // 结束时间 |
@@ -26,7 +26,7 @@ type SubmitProductRecordCommand struct { | @@ -26,7 +26,7 @@ type SubmitProductRecordCommand struct { | ||
26 | // 员工Id 用户唯一标识 | 26 | // 员工Id 用户唯一标识 |
27 | EmployeeId int `cname:"员工" json:"employeeId" valid:"Required"` | 27 | EmployeeId int `cname:"员工" json:"employeeId" valid:"Required"` |
28 | // 物料ID | 28 | // 物料ID |
29 | - UnitConversionId int `cname:"物料ID" json:"unitConversionId" valid:"Required"` | 29 | + UnitConversionId int `cname:"物料ID" json:"unitConversionId"` |
30 | // 重量 | 30 | // 重量 |
31 | Weigh float64 `cname:"重量" json:"weigh" valid:"Required"` | 31 | Weigh float64 `cname:"重量" json:"weigh" valid:"Required"` |
32 | } | 32 | } |
@@ -8,6 +8,8 @@ type EmployeeProductRecordDto struct { | @@ -8,6 +8,8 @@ type EmployeeProductRecordDto struct { | ||
8 | // 生产工人 | 8 | // 生产工人 |
9 | ProductWorker *domain.User `json:"productWorker,omitempty"` | 9 | ProductWorker *domain.User `json:"productWorker,omitempty"` |
10 | *domain.WorkStation | 10 | *domain.WorkStation |
11 | + // 上班班次 1:全天 2:白班 4:中班 8:夜班 | ||
12 | + WorkOn int `json:"workOn"` | ||
11 | // 生产日期 | 13 | // 生产日期 |
12 | //ProductDate string `json:"productDate"` | 14 | //ProductDate string `json:"productDate"` |
13 | // 计划的产品名称 | 15 | // 计划的产品名称 |
@@ -29,15 +31,19 @@ type EmployeeProductRecordDto struct { | @@ -29,15 +31,19 @@ type EmployeeProductRecordDto struct { | ||
29 | // 合格率 百分比 | 31 | // 合格率 百分比 |
30 | QualificationRate int `json:"qualificationRate"` | 32 | QualificationRate int `json:"qualificationRate"` |
31 | // 考勤类型 1.正常 2.支援 | 33 | // 考勤类型 1.正常 2.支援 |
32 | - ParticipateTypeDescription string `json:"participateTypeDescription,omitempty"` | 34 | + ParticipateTypeDescription string `json:"participateTypeDescription"` |
33 | // 员工类型描述 1:固定 2:派遣 3.临时 | 35 | // 员工类型描述 1:固定 2:派遣 3.临时 |
34 | - EmployeeTypeDescription string `json:"employeeTypeDescription,omitempty"` | 36 | + EmployeeTypeDescription string `json:"employeeTypeDescription"` |
37 | + // 上班班次 1:全天 2:白班 4:中班 8:夜班 | ||
38 | + WorkOnDescription string `json:"workOnDescription,omitempty"` | ||
35 | } | 39 | } |
36 | 40 | ||
37 | func (d *EmployeeProductRecordDto) LoadDto(m *domain.EmployeeProductRecord, orgId int) *EmployeeProductRecordDto { | 41 | func (d *EmployeeProductRecordDto) LoadDto(m *domain.EmployeeProductRecord, orgId int) *EmployeeProductRecordDto { |
38 | d.EmployeeProductRecordId = m.EmployeeProductRecordId | 42 | d.EmployeeProductRecordId = m.EmployeeProductRecordId |
39 | d.ProductWorker = m.ProductWorker | 43 | d.ProductWorker = m.ProductWorker |
40 | d.WorkStation = m.WorkStation | 44 | d.WorkStation = m.WorkStation |
45 | + d.WorkOn = m.WorkOn | ||
46 | + | ||
41 | d.PlanProductName = m.ProductRecordInfo.PlanProductName | 47 | d.PlanProductName = m.ProductRecordInfo.PlanProductName |
42 | d.BatchNumber = m.ProductRecordInfo.BatchNumber | 48 | d.BatchNumber = m.ProductRecordInfo.BatchNumber |
43 | d.ParticipateType = m.ParticipateType | 49 | d.ParticipateType = m.ParticipateType |
@@ -47,6 +53,7 @@ func (d *EmployeeProductRecordDto) LoadDto(m *domain.EmployeeProductRecord, orgI | @@ -47,6 +53,7 @@ func (d *EmployeeProductRecordDto) LoadDto(m *domain.EmployeeProductRecord, orgI | ||
47 | d.CreatedAt = m.CreatedAt.Format("2006-01-02") | 53 | d.CreatedAt = m.CreatedAt.Format("2006-01-02") |
48 | d.ParticipateTypeDescription = domain.ParticipateTypeDescription(m.ParticipateType) | 54 | d.ParticipateTypeDescription = domain.ParticipateTypeDescription(m.ParticipateType) |
49 | d.EmployeeTypeDescription = domain.EmployeeTypeDescription(m.ProductWorker.EmployeeType) | 55 | d.EmployeeTypeDescription = domain.EmployeeTypeDescription(m.ProductWorker.EmployeeType) |
56 | + d.WorkOnDescription = domain.WorkOnDescriptions(m.WorkOn) | ||
50 | d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId) | 57 | d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId) |
51 | if m.Ext != nil { | 58 | if m.Ext != nil { |
52 | d.OrgName = m.Ext.OrgName | 59 | d.OrgName = m.Ext.OrgName |
@@ -127,6 +127,16 @@ func (device *Device) Valid() error { | @@ -127,6 +127,16 @@ func (device *Device) Valid() error { | ||
127 | return nil | 127 | return nil |
128 | } | 128 | } |
129 | 129 | ||
130 | +// 标记为生产设备 | ||
131 | +func (device *Device) MarkAsProductDevice() bool { | ||
132 | + if device.Ext.DeviceExt.IsProductDevice == 1 { | ||
133 | + return false | ||
134 | + } | ||
135 | + device.Ext.DeviceExt.IsProductDevice = 1 | ||
136 | + device.UpdatedAt = time.Now() | ||
137 | + return true | ||
138 | +} | ||
139 | + | ||
130 | // 导入设备数据体 | 140 | // 导入设备数据体 |
131 | type ImportDeviceItem struct { | 141 | type ImportDeviceItem struct { |
132 | // 设备编号 | 142 | // 设备编号 |
@@ -183,3 +193,13 @@ func (item *ImportDeviceItem) Valid() error { | @@ -183,3 +193,13 @@ func (item *ImportDeviceItem) Valid() error { | ||
183 | } | 193 | } |
184 | return nil | 194 | return nil |
185 | } | 195 | } |
196 | + | ||
197 | +type Devices []*Device | ||
198 | + | ||
199 | +func (devices Devices) ToMap() map[string]*Device { | ||
200 | + var resp = make(map[string]*Device) | ||
201 | + for _, v := range devices { | ||
202 | + resp[v.DeviceCode] = v | ||
203 | + } | ||
204 | + return resp | ||
205 | +} |
@@ -98,6 +98,11 @@ type DeviceRunningRecordInfo struct { | @@ -98,6 +98,11 @@ type DeviceRunningRecordInfo struct { | ||
98 | // 批次数据 | 98 | // 批次数据 |
99 | // 生产计划ID | 99 | // 生产计划ID |
100 | ProductPlanId int `json:"productPlanId,omitempty"` | 100 | ProductPlanId int `json:"productPlanId,omitempty"` |
101 | + | ||
102 | + // 设备名称 | ||
103 | + DeviceName string `json:"deviceName"` | ||
104 | + // 组织名称 | ||
105 | + OrgName string `json:"orgName"` | ||
101 | } | 106 | } |
102 | 107 | ||
103 | func NewDeviceRunningRecordInfo() *DeviceRunningRecordInfo { | 108 | func NewDeviceRunningRecordInfo() *DeviceRunningRecordInfo { |
@@ -155,6 +160,18 @@ func (d *DeviceRunningRecordInfo) ResetOEE(pu, qu float64) float64 { | @@ -155,6 +160,18 @@ func (d *DeviceRunningRecordInfo) ResetOEE(pu, qu float64) float64 { | ||
155 | return d.OEE | 160 | return d.OEE |
156 | } | 161 | } |
157 | 162 | ||
163 | +// 详细的小时设备数据 | ||
164 | +// 0:00 1 | ||
165 | +// 0:59 2 | ||
166 | +// 23:00 1 | ||
167 | +// 23:59 2 | ||
168 | +// [{"min":1,"time":"00:01","status":1}] | ||
169 | +func (d *DeviceRunningRecordInfo) HourDeviceStatusDetail() { | ||
170 | + for i := 0; i < 24; i++ { | ||
171 | + | ||
172 | + } | ||
173 | +} | ||
174 | + | ||
158 | // 单个小时内的设备状态 | 175 | // 单个小时内的设备状态 |
159 | type HourDeviceStatus struct { | 176 | type HourDeviceStatus struct { |
160 | // 时间窗口 1-60 代表时间段范围 | 177 | // 时间窗口 1-60 代表时间段范围 |
@@ -4,4 +4,6 @@ package domain | @@ -4,4 +4,6 @@ package domain | ||
4 | type DeviceExt struct { | 4 | type DeviceExt struct { |
5 | // 生产单个产品的时间(单位:秒) | 5 | // 生产单个产品的时间(单位:秒) |
6 | UnitProductionSecTime int `json:"unitProductionSecTime"` | 6 | UnitProductionSecTime int `json:"unitProductionSecTime"` |
7 | + // 是否是车间设备,如果这个设备有上报过数据,标记 1 默认0 | ||
8 | + IsProductDevice int `json:"isProductDevice"` | ||
7 | } | 9 | } |
1 | package domain | 1 | package domain |
2 | 2 | ||
3 | -import "fmt" | 3 | +import ( |
4 | + "fmt" | ||
5 | + "strings" | ||
6 | +) | ||
4 | 7 | ||
5 | const MaxQueryRow = 10000 | 8 | const MaxQueryRow = 10000 |
6 | 9 | ||
@@ -121,6 +124,11 @@ func WorkOnDescription(workOn int) []string { | @@ -121,6 +124,11 @@ func WorkOnDescription(workOn int) []string { | ||
121 | return result | 124 | return result |
122 | } | 125 | } |
123 | 126 | ||
127 | +func WorkOnDescriptions(workOn int) string { | ||
128 | + r := WorkOnDescription(workOn) | ||
129 | + return strings.Join(r, ",") | ||
130 | +} | ||
131 | + | ||
124 | func EmployeeTypeDescription(employeeType int) string { | 132 | func EmployeeTypeDescription(employeeType int) string { |
125 | if employeeType == 1 { | 133 | if employeeType == 1 { |
126 | return "固定" | 134 | return "固定" |
1 | +package dao | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
6 | + "time" | ||
7 | +) | ||
8 | + | ||
9 | +type DeviceDailyRunningRecordDao struct { | ||
10 | + transactionContext *pgTransaction.TransactionContext | ||
11 | +} | ||
12 | + | ||
13 | +func NewDeviceDailyRunningRecordDao(transactionContext *pgTransaction.TransactionContext) (*DeviceDailyRunningRecordDao, error) { | ||
14 | + if transactionContext == nil { | ||
15 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
16 | + } else { | ||
17 | + return &DeviceDailyRunningRecordDao{ | ||
18 | + transactionContext: transactionContext, | ||
19 | + }, nil | ||
20 | + } | ||
21 | +} | ||
22 | + | ||
23 | +// 时段产能 | ||
24 | +func (dao *DeviceDailyRunningRecordDao) TimeSectionRunningRecord(companyId, orgId, workshopId int, lineId int, sectionName string, beginTime time.Time, result interface{}) error { | ||
25 | + | ||
26 | + tx := dao.transactionContext.PgTx | ||
27 | + sql := fmt.Sprintf(` | ||
28 | + | ||
29 | +WITH ts_product as( | ||
30 | + select sum(a.weight) total,a.ts from ( | ||
31 | + select | ||
32 | + cast(device_running_record_info->>'count' as DECIMAL) weight, | ||
33 | + to_char(product_date at time ZONE 'Asia/shanghai', 'mm:dd') ts | ||
34 | + from manufacture.device_daily_running_record | ||
35 | + where | ||
36 | + company_id = ? | ||
37 | + and org_id = ? | ||
38 | + and work_station->>'workshopId'='?' | ||
39 | + and work_station->>'lineId'='?' | ||
40 | + and work_station->>'sectionName'=? | ||
41 | + and created_at >? | ||
42 | + ) a | ||
43 | + group by a.ts | ||
44 | + order by ts | ||
45 | +) | ||
46 | +-- select * from ts_product | ||
47 | +, ts_product_list as ( | ||
48 | + select d.ts,ts_product.total from ( | ||
49 | + select to_char(c.ts::timestamp,'mm:dd') ts from ( | ||
50 | + select generate_series(now() - interval '6 day',now(),'1 day') ts | ||
51 | + ) c ) d left join ts_product on d.ts = ts_product.ts | ||
52 | +) | ||
53 | +SELECT ts, coalesce(total,0) total | ||
54 | +from ts_product_list | ||
55 | +`) | ||
56 | + if _, err := tx.Query(result, sql, companyId, orgId, workshopId, lineId, sectionName, beginTime); err != nil { | ||
57 | + return err | ||
58 | + } | ||
59 | + return nil | ||
60 | +} | ||
61 | + | ||
62 | +func (dao *DeviceDailyRunningRecordDao) WorkshopProductionEfficiencyStatistics(companyId, orgId, workshopId int, beginTime time.Time, result interface{}) error { | ||
63 | + | ||
64 | + tx := dao.transactionContext.PgTx | ||
65 | + sql := fmt.Sprintf(` | ||
66 | +with device_running as( | ||
67 | +select | ||
68 | +cast(device_running_record_info->>'oee' as DECIMAL) oee, | ||
69 | +cast(device_running_record_info->>'tu' as DECIMAL) tu, | ||
70 | +cast(device_running_record_info->>'pu' as DECIMAL) pu, | ||
71 | +cast(device_running_record_info->>'qu' as DECIMAL) qu | ||
72 | +from manufacture.device_daily_running_record | ||
73 | +where | ||
74 | +company_id = ? | ||
75 | +and org_id = ? | ||
76 | +and work_station->>'workshopId'='?' | ||
77 | +and created_at>=? | ||
78 | +) | ||
79 | +select round(avg(oee),1) oee,round(avg(tu),1) tu,round(avg(pu),1)pu, round(avg(qu),1) qu from device_running | ||
80 | + `) | ||
81 | + if _, err := tx.Query(result, sql, companyId, orgId, workshopId, beginTime); err != nil { | ||
82 | + return err | ||
83 | + } | ||
84 | + return nil | ||
85 | +} |
@@ -56,7 +56,7 @@ func (dao *ProductRecordDao) RecentUnApprovedProductRecord(fromLastHour int, rec | @@ -56,7 +56,7 @@ func (dao *ProductRecordDao) RecentUnApprovedProductRecord(fromLastHour int, rec | ||
56 | } | 56 | } |
57 | 57 | ||
58 | // 时段产能 | 58 | // 时段产能 |
59 | -func (dao *ProductRecordDao) TimeSectionProductRecord(companyId, orgId, workshopId int, lineId int, beginTime time.Time, result interface{}) error { | 59 | +func (dao *ProductRecordDao) TimeSectionProductRecord(companyId, orgId, workshopId int, lineId int, sectionName string, beginTime time.Time, result interface{}) error { |
60 | 60 | ||
61 | tx := dao.transactionContext.PgTx | 61 | tx := dao.transactionContext.PgTx |
62 | sql := fmt.Sprintf(` | 62 | sql := fmt.Sprintf(` |
@@ -71,6 +71,7 @@ WITH ts_product as( | @@ -71,6 +71,7 @@ WITH ts_product as( | ||
71 | and org_id = ? | 71 | and org_id = ? |
72 | and work_station->>'workshopId'='?' | 72 | and work_station->>'workshopId'='?' |
73 | and work_station->>'lineId'='?' | 73 | and work_station->>'lineId'='?' |
74 | + and work_station->>'sectionName'=? | ||
74 | and product_record_type = 8 | 75 | and product_record_type = 8 |
75 | and created_at >? | 76 | and created_at >? |
76 | ) a | 77 | ) a |
@@ -92,7 +93,42 @@ WITH ts_product as( | @@ -92,7 +93,42 @@ WITH ts_product as( | ||
92 | SELECT ts, coalesce(total,0) total | 93 | SELECT ts, coalesce(total,0) total |
93 | from ts_product_list | 94 | from ts_product_list |
94 | `) | 95 | `) |
95 | - if _, err := tx.Query(result, sql, companyId, orgId, workshopId, lineId, beginTime); err != nil { | 96 | + if _, err := tx.Query(result, sql, companyId, orgId, workshopId, lineId, sectionName, beginTime); err != nil { |
97 | + return err | ||
98 | + } | ||
99 | + return nil | ||
100 | +} | ||
101 | + | ||
102 | +// 二级品比重 | ||
103 | +func (dao *ProductRecordDao) ProportionOfSecondLevelRecord(companyId, orgId, workshopId int, beginTime time.Time, result interface{}) error { | ||
104 | + | ||
105 | + tx := dao.transactionContext.PgTx | ||
106 | + sql := fmt.Sprintf(` | ||
107 | +with item_product as ( | ||
108 | +select sum(a.weight) item_total,max(sname) sname from ( | ||
109 | + select cast(product_record_info->>'weigh' as DECIMAL) weight | ||
110 | + ,work_station->>'sectionName' sname | ||
111 | + ,work_station->>'workStationId' workStationId | ||
112 | + from manufacture.product_records | ||
113 | + where company_id = ? | ||
114 | + and org_id = ? | ||
115 | + and work_station->>'workshopId'='?' | ||
116 | + and product_record_type = 8 | ||
117 | + and product_record_info->>'approveStatus'='2' | ||
118 | + and created_at >=? | ||
119 | + and work_station->>'sectionName' in ('打料','成型','穿串','包装') | ||
120 | +) a | ||
121 | +group by a.workStationId | ||
122 | +) | ||
123 | +--select * from item_product | ||
124 | +,item_product_rate as( | ||
125 | +select sname,round(item_total/(select sum(item_total) from item_product)*100, 0) as rate from item_product | ||
126 | +) | ||
127 | +--select * from item_product_rate | ||
128 | +select a.sname, coalesce(b.rate,0) rate from ( | ||
129 | + select unnest(ARRAY ['打料','成型','穿串','包装']) sname | ||
130 | +) a left join item_product_rate b on a.sname=b.sname`) | ||
131 | + if _, err := tx.Query(result, sql, companyId, orgId, workshopId, beginTime); err != nil { | ||
96 | return err | 132 | return err |
97 | } | 133 | } |
98 | return nil | 134 | return nil |
@@ -14,6 +14,18 @@ import ( | @@ -14,6 +14,18 @@ import ( | ||
14 | const ( | 14 | const ( |
15 | // 时段产能统计 | 15 | // 时段产能统计 |
16 | HourProductiveStatistics = "HourProductiveStatistics" | 16 | HourProductiveStatistics = "HourProductiveStatistics" |
17 | + // 产能对比 | ||
18 | + DailyProductiveStatistics = "DailyProductiveStatistics" | ||
19 | + // 二级品比重 | ||
20 | + ProportionOfSecondLevelStatistics = "ProportionOfSecondLevelStatistics" | ||
21 | + // 车间生产效率 | ||
22 | + WorkshopProductionEfficiencyStatistics = "WorkshopProductionEfficiencyStatistics" | ||
23 | + // 设备运行统计 | ||
24 | + DeviceRunningStatistics = "DeviceRunningStatistics" | ||
25 | +) | ||
26 | + | ||
27 | +const ( | ||
28 | + SectionNameCCJ = "穿串" | ||
17 | ) | 29 | ) |
18 | 30 | ||
19 | type PGCommonStatisticsService struct { | 31 | type PGCommonStatisticsService struct { |
@@ -27,6 +39,18 @@ func (ptr *PGCommonStatisticsService) CommonStatistics(actionType string, queryO | @@ -27,6 +39,18 @@ func (ptr *PGCommonStatisticsService) CommonStatistics(actionType string, queryO | ||
27 | case HourProductiveStatistics: | 39 | case HourProductiveStatistics: |
28 | result, err = ptr.HourProductiveStatistics(queryOptions) | 40 | result, err = ptr.HourProductiveStatistics(queryOptions) |
29 | break | 41 | break |
42 | + case DailyProductiveStatistics: | ||
43 | + result, err = ptr.DailyProductiveStatistics(queryOptions) | ||
44 | + break | ||
45 | + case ProportionOfSecondLevelStatistics: | ||
46 | + result, err = ptr.ProportionOfSecondLevelStatistics(queryOptions) | ||
47 | + break | ||
48 | + case WorkshopProductionEfficiencyStatistics: | ||
49 | + result, err = ptr.WorkshopProductionEfficiencyStatistics(queryOptions) | ||
50 | + break | ||
51 | + case DeviceRunningStatistics: | ||
52 | + result, err = ptr.DeviceRunningStatistics(queryOptions) | ||
53 | + break | ||
30 | } | 54 | } |
31 | return result, err | 55 | return result, err |
32 | } | 56 | } |
@@ -53,7 +77,7 @@ func (ptr *PGCommonStatisticsService) HourProductiveStatistics(queryOptions map[ | @@ -53,7 +77,7 @@ func (ptr *PGCommonStatisticsService) HourProductiveStatistics(queryOptions map[ | ||
53 | var response = make([]interface{}, 0) | 77 | var response = make([]interface{}, 0) |
54 | for _, v := range workshop.GetProductLines(domain.NotDeleted) { | 78 | for _, v := range workshop.GetProductLines(domain.NotDeleted) { |
55 | var result = make([]*record, 0) | 79 | var result = make([]*record, 0) |
56 | - if err := productRecordDao.TimeSectionProductRecord(request.CompanyId, request.OrgId, request.WorkshopId, v.LineId, time.Now().Add(-time.Hour*5), &result); err != nil { | 80 | + if err := productRecordDao.TimeSectionProductRecord(request.CompanyId, request.OrgId, request.WorkshopId, v.LineId, SectionNameCCJ, time.Now().Add(-time.Hour*5), &result); err != nil { |
57 | log.Logger.Error(err.Error()) | 81 | log.Logger.Error(err.Error()) |
58 | continue | 82 | continue |
59 | } | 83 | } |
@@ -88,6 +112,195 @@ func NewXYData(xData []string, values interface{}) interface{} { | @@ -88,6 +112,195 @@ func NewXYData(xData []string, values interface{}) interface{} { | ||
88 | } | 112 | } |
89 | } | 113 | } |
90 | 114 | ||
115 | +// 时段产能-统计 (传串设备) | ||
116 | +func (ptr *PGCommonStatisticsService) DailyProductiveStatistics(queryOptions map[string]interface{}) (interface{}, error) { | ||
117 | + var request = &HourProductiveStatisticsRequest{} | ||
118 | + if err := utils.LoadQueryObject(queryOptions, request); err != nil { | ||
119 | + return nil, err | ||
120 | + } | ||
121 | + | ||
122 | + workshopRepository, _ := repository.NewWorkshopRepository(ptr.transactionContext) | ||
123 | + type record struct { | ||
124 | + Ts string `json:"ts"` | ||
125 | + Total float64 `json:"total"` | ||
126 | + } | ||
127 | + | ||
128 | + workshop, err := workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}) | ||
129 | + if err != nil || workshop == nil { | ||
130 | + return nil, nil | ||
131 | + } | ||
132 | + productRecordDao, _ := dao.NewDeviceDailyRunningRecordDao(ptr.transactionContext) | ||
133 | + | ||
134 | + var response = make([]interface{}, 0) | ||
135 | + for _, v := range workshop.GetProductLines(domain.NotDeleted) { | ||
136 | + var result = make([]*record, 0) | ||
137 | + if err := productRecordDao.TimeSectionRunningRecord(request.CompanyId, request.OrgId, request.WorkshopId, v.LineId, SectionNameCCJ, time.Now().Add(-time.Hour*24*7), &result); err != nil { | ||
138 | + log.Logger.Error(err.Error()) | ||
139 | + continue | ||
140 | + } | ||
141 | + var xData []string = make([]string, 0) | ||
142 | + var values []interface{} = make([]interface{}, 0) | ||
143 | + for _, r := range result { | ||
144 | + xData = append(xData, r.Ts) | ||
145 | + values = append(values, r.Total) | ||
146 | + } | ||
147 | + response = append(response, map[string]interface{}{ | ||
148 | + "lineName": v.LineName, | ||
149 | + "data": NewXYData(xData, values), | ||
150 | + }) | ||
151 | + } | ||
152 | + return map[string]interface{}{ | ||
153 | + "recent_7_day": response, | ||
154 | + }, nil | ||
155 | +} | ||
156 | + | ||
157 | +// 二级品占比 | ||
158 | +func (ptr *PGCommonStatisticsService) ProportionOfSecondLevelStatistics(queryOptions map[string]interface{}) (interface{}, error) { | ||
159 | + var request = &HourProductiveStatisticsRequest{} | ||
160 | + if err := utils.LoadQueryObject(queryOptions, request); err != nil { | ||
161 | + return nil, err | ||
162 | + } | ||
163 | + | ||
164 | + workshopRepository, _ := repository.NewWorkshopRepository(ptr.transactionContext) | ||
165 | + type record struct { | ||
166 | + Sname string `json:"sname"` | ||
167 | + Rate float64 `json:"rate"` | ||
168 | + } | ||
169 | + | ||
170 | + workshop, err := workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}) | ||
171 | + if err != nil || workshop == nil { | ||
172 | + return nil, nil | ||
173 | + } | ||
174 | + productRecordDao, _ := dao.NewProductRecordDao(ptr.transactionContext) | ||
175 | + | ||
176 | + var input = []struct { | ||
177 | + name string | ||
178 | + t time.Time | ||
179 | + }{ | ||
180 | + {"today", utils.GetZeroTime(time.Now())}, | ||
181 | + {"current_week", utils.GetCurrentWeekFirstDay(time.Now())}, | ||
182 | + {"current_month", utils.GetCurrentMonthFirstDay(time.Now())}, | ||
183 | + } | ||
184 | + | ||
185 | + var response = make(map[string]interface{}) | ||
186 | + for _, v := range input { | ||
187 | + var result = make([]*record, 0) | ||
188 | + if err := productRecordDao.ProportionOfSecondLevelRecord(request.CompanyId, request.OrgId, request.WorkshopId, v.t, &result); err != nil { | ||
189 | + log.Logger.Error(err.Error()) | ||
190 | + return nil, err | ||
191 | + } | ||
192 | + response[v.name] = result | ||
193 | + } | ||
194 | + | ||
195 | + return response, nil | ||
196 | +} | ||
197 | + | ||
198 | +// 车间生产效率统计 | ||
199 | +func (ptr *PGCommonStatisticsService) WorkshopProductionEfficiencyStatistics(queryOptions map[string]interface{}) (interface{}, error) { | ||
200 | + var request = &HourProductiveStatisticsRequest{} | ||
201 | + if err := utils.LoadQueryObject(queryOptions, request); err != nil { | ||
202 | + return nil, err | ||
203 | + } | ||
204 | + | ||
205 | + workshopRepository, _ := repository.NewWorkshopRepository(ptr.transactionContext) | ||
206 | + type record struct { | ||
207 | + Oee float64 `json:"oee"` | ||
208 | + Pu float64 `json:"pu"` | ||
209 | + Tu float64 `json:"tu"` | ||
210 | + Qu float64 `json:"qu"` | ||
211 | + } | ||
212 | + | ||
213 | + workshop, err := workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}) | ||
214 | + if err != nil || workshop == nil { | ||
215 | + return nil, nil | ||
216 | + } | ||
217 | + productRecordDao, _ := dao.NewDeviceDailyRunningRecordDao(ptr.transactionContext) | ||
218 | + | ||
219 | + var input = []struct { | ||
220 | + name string | ||
221 | + t time.Time | ||
222 | + }{ | ||
223 | + {"today", utils.GetZeroTime(time.Now())}, | ||
224 | + {"current_week", utils.GetCurrentWeekFirstDay(time.Now())}, | ||
225 | + {"current_month", utils.GetCurrentMonthFirstDay(time.Now())}, | ||
226 | + } | ||
227 | + | ||
228 | + var response = make(map[string]interface{}) | ||
229 | + for _, v := range input { | ||
230 | + var result = make([]*record, 0) | ||
231 | + if err := productRecordDao.WorkshopProductionEfficiencyStatistics(request.CompanyId, request.OrgId, request.WorkshopId, v.t, &result); err != nil { | ||
232 | + log.Logger.Error(err.Error()) | ||
233 | + return nil, err | ||
234 | + } | ||
235 | + response[v.name] = result | ||
236 | + } | ||
237 | + | ||
238 | + return response, nil | ||
239 | +} | ||
240 | + | ||
241 | +// 设备运行统计 | ||
242 | +func (ptr *PGCommonStatisticsService) DeviceRunningStatistics(queryOptions map[string]interface{}) (interface{}, error) { | ||
243 | + var request = &DeviceRunningStatisticRequest{} | ||
244 | + if err := utils.LoadQueryObject(queryOptions, request); err != nil { | ||
245 | + return nil, err | ||
246 | + } | ||
247 | + | ||
248 | + workshopRepository, _ := repository.NewWorkshopRepository(ptr.transactionContext) | ||
249 | + deviceRepository, _ := repository.NewDeviceRepository(ptr.transactionContext) | ||
250 | + deviceRunningRecordRepository, _ := repository.NewDeviceDailyRunningRecordRepository(ptr.transactionContext) | ||
251 | + | ||
252 | + workshop, err := workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}) | ||
253 | + if err != nil || workshop == nil { | ||
254 | + return nil, nil | ||
255 | + } | ||
256 | + | ||
257 | + _, devices, err := deviceRepository.Find(map[string]interface{}{"companyId": request.CompanyId, "orgId": request.OrgId, "workshopId": request.WorkshopId, "lineId": request.LineId}) | ||
258 | + if err != nil { | ||
259 | + return nil, err | ||
260 | + } | ||
261 | + | ||
262 | + var response = make([]interface{}, 0) | ||
263 | + _, dailyRecords, err := deviceRunningRecordRepository.Find(map[string]interface{}{"companyId": request.CompanyId, "orgId": request.OrgId, "productDate": request.Date}) | ||
264 | + for i := 0; i < len(devices); i++ { | ||
265 | + d := devices[i] | ||
266 | + if d.Ext == nil || d.Ext.DeviceExt == nil || d.Ext.DeviceExt.IsProductDevice == 0 { | ||
267 | + continue | ||
268 | + } | ||
269 | + var r *domain.DeviceDailyRunningRecord | ||
270 | + item := make(map[string]interface{}) | ||
271 | + item["orgName"] = d.Ext.OrgName | ||
272 | + if d.WorkStation != nil { | ||
273 | + item["workshopName"] = d.WorkStation.WorkshopName | ||
274 | + item["lineName"] = d.WorkStation.LineName | ||
275 | + item["deviceName"] = d.DeviceName | ||
276 | + item["oee"] = 0 | ||
277 | + item["status"] = []struct{}{} | ||
278 | + } | ||
279 | + for j := 0; j < len(dailyRecords); j++ { | ||
280 | + if d.DeviceCode == dailyRecords[j].DeviceCode { | ||
281 | + r = dailyRecords[j] | ||
282 | + item["oee"] = r.DeviceRunningRecordInfo.OEE | ||
283 | + break | ||
284 | + } | ||
285 | + } | ||
286 | + if r != nil { | ||
287 | + item["status"] = r.DeviceRunningRecordInfo.TimeLineDeviceStatus | ||
288 | + } | ||
289 | + response = append(response, item) | ||
290 | + } | ||
291 | + return map[string]interface{}{ | ||
292 | + "devices": response, | ||
293 | + }, nil | ||
294 | +} | ||
295 | + | ||
296 | +type DeviceRunningStatisticRequest struct { | ||
297 | + CompanyId int `json:"companyId" valid:"Required"` | ||
298 | + OrgId int `json:"orgId" valid:"Required"` | ||
299 | + WorkshopId int `json:"workshopId" valid:"Required"` | ||
300 | + LineId int `json:"lineId""` | ||
301 | + Date string `json:"date"` | ||
302 | +} | ||
303 | + | ||
91 | func NewPGCommonStatisticsService(transactionContext *pgTransaction.TransactionContext) (*PGCommonStatisticsService, error) { | 304 | func NewPGCommonStatisticsService(transactionContext *pgTransaction.TransactionContext) (*PGCommonStatisticsService, error) { |
92 | if transactionContext == nil { | 305 | if transactionContext == nil { |
93 | return nil, fmt.Errorf("transactionContext参数不能为nil") | 306 | return nil, fmt.Errorf("transactionContext参数不能为nil") |
@@ -36,7 +36,7 @@ type SubmitOptions struct { | @@ -36,7 +36,7 @@ type SubmitOptions struct { | ||
36 | // 员工Id 用户唯一标识 | 36 | // 员工Id 用户唯一标识 |
37 | EmployeeId int `cname:"员工" json:"employeeId" valid:"Required"` | 37 | EmployeeId int `cname:"员工" json:"employeeId" valid:"Required"` |
38 | // 物料ID | 38 | // 物料ID |
39 | - UnitConversionId int `cname:"物料ID" json:"unitConversionId" valid:"Required"` | 39 | + UnitConversionId int `cname:"物料ID" json:"unitConversionId"` |
40 | // 重量 | 40 | // 重量 |
41 | Weigh float64 `cname:"重量" json:"weigh" valid:"Required"` | 41 | Weigh float64 `cname:"重量" json:"weigh" valid:"Required"` |
42 | } | 42 | } |
@@ -73,8 +73,10 @@ func (ptr *PGProductRecordService) SubmitProductRecord(productRecordType int, qu | @@ -73,8 +73,10 @@ func (ptr *PGProductRecordService) SubmitProductRecord(productRecordType int, qu | ||
73 | if workshop, err = workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}); err != nil { | 73 | if workshop, err = workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}); err != nil { |
74 | return nil, err | 74 | return nil, err |
75 | } | 75 | } |
76 | - if uc, err = unitConversionRepository.FindOne(map[string]interface{}{"unitConversionId": request.UnitConversionId}); err != nil { | ||
77 | - return nil, err | 76 | + if request.UnitConversionId > 0 { |
77 | + if uc, err = unitConversionRepository.FindOne(map[string]interface{}{"unitConversionId": request.UnitConversionId}); err != nil { | ||
78 | + return nil, err | ||
79 | + } | ||
78 | } | 80 | } |
79 | if workstation, err = workshop.FindWorkStation(request.WorkshopId, request.LineId, request.SectionId); err != nil { | 81 | if workstation, err = workshop.FindWorkStation(request.WorkshopId, request.LineId, request.SectionId); err != nil { |
80 | return nil, err | 82 | return nil, err |
@@ -248,6 +248,8 @@ func (ptr *PGWorkshopDataConsumeService) saveDeviceDailyRunningRecord(companyId, | @@ -248,6 +248,8 @@ func (ptr *PGWorkshopDataConsumeService) saveDeviceDailyRunningRecord(companyId, | ||
248 | } | 248 | } |
249 | recordInfo := domain.NewDeviceRunningRecordInfo() | 249 | recordInfo := domain.NewDeviceRunningRecordInfo() |
250 | recordInfo.ProductPlanId = planId | 250 | recordInfo.ProductPlanId = planId |
251 | + recordInfo.DeviceName = device.DeviceName | ||
252 | + recordInfo.OrgName = device.Ext.OrgName | ||
251 | record = &domain.DeviceDailyRunningRecord{ | 253 | record = &domain.DeviceDailyRunningRecord{ |
252 | CompanyId: companyId, | 254 | CompanyId: companyId, |
253 | OrgId: orgId, | 255 | OrgId: orgId, |
@@ -262,6 +264,13 @@ func (ptr *PGWorkshopDataConsumeService) saveDeviceDailyRunningRecord(companyId, | @@ -262,6 +264,13 @@ func (ptr *PGWorkshopDataConsumeService) saveDeviceDailyRunningRecord(companyId, | ||
262 | if record, err = deviceDailyRunningRecordRepository.Save(record); err != nil { | 264 | if record, err = deviceDailyRunningRecordRepository.Save(record); err != nil { |
263 | return nil, err | 265 | return nil, err |
264 | } | 266 | } |
267 | + | ||
268 | + if device.MarkAsProductDevice() { | ||
269 | + deviceRepository, _ := repository.NewDeviceRepository(ptr.transactionContext) | ||
270 | + if device, err = deviceRepository.Save(device); err != nil { | ||
271 | + return nil, err | ||
272 | + } | ||
273 | + } | ||
265 | return record, nil | 274 | return record, nil |
266 | } | 275 | } |
267 | 276 |
@@ -143,6 +143,11 @@ func (repository *DeviceDailyRunningRecordRepository) Find(queryOptions map[stri | @@ -143,6 +143,11 @@ func (repository *DeviceDailyRunningRecordRepository) Find(queryOptions map[stri | ||
143 | var deviceDailyRunningRecordModels []*models.DeviceDailyRunningRecord | 143 | var deviceDailyRunningRecordModels []*models.DeviceDailyRunningRecord |
144 | deviceDailyRunningRecords := make([]*domain.DeviceDailyRunningRecord, 0) | 144 | deviceDailyRunningRecords := make([]*domain.DeviceDailyRunningRecord, 0) |
145 | query := sqlbuilder.BuildQuery(tx.Model(&deviceDailyRunningRecordModels), queryOptions) | 145 | query := sqlbuilder.BuildQuery(tx.Model(&deviceDailyRunningRecordModels), queryOptions) |
146 | + query.SetWhereByQueryOption("company_id = ?", "companyId") | ||
147 | + query.SetWhereByQueryOption("org_id = ?", "orgId") | ||
148 | + if v, ok := queryOptions["productDate"]; ok && len(v.(string)) > 0 { | ||
149 | + query.Where(`product_date = ?`, v) | ||
150 | + } | ||
146 | query.SetOffsetAndLimit(20) | 151 | query.SetOffsetAndLimit(20) |
147 | query.SetOrderDirect("device_daily_running_record_id", "DESC") | 152 | query.SetOrderDirect("device_daily_running_record_id", "DESC") |
148 | if count, err := query.SelectAndCount(); err != nil { | 153 | if count, err := query.SelectAndCount(); err != nil { |
@@ -188,6 +188,9 @@ func (repository *ProductAttendanceRecordRepository) Find(queryOptions map[strin | @@ -188,6 +188,9 @@ func (repository *ProductAttendanceRecordRepository) Find(queryOptions map[strin | ||
188 | if v, ok := queryOptions["signEndTime"]; ok && !((v.(time.Time)).IsZero()) { | 188 | if v, ok := queryOptions["signEndTime"]; ok && !((v.(time.Time)).IsZero()) { |
189 | query.Where("created_at<?", v.(time.Time)) | 189 | query.Where("created_at<?", v.(time.Time)) |
190 | } | 190 | } |
191 | + if v, ok := queryOptions["employeeType"]; ok && (v.(int)) > 0 { | ||
192 | + query.Where("product_worker->>'employeeType'='?'", v.(int)) | ||
193 | + } | ||
191 | query.SetOffsetAndLimit(domain.MaxQueryRow) | 194 | query.SetOffsetAndLimit(domain.MaxQueryRow) |
192 | query.SetOrderDirect("product_attendance_id", "DESC") | 195 | query.SetOrderDirect("product_attendance_id", "DESC") |
193 | if count, err := query.SelectAndCount(); err != nil { | 196 | if count, err := query.SelectAndCount(); err != nil { |
@@ -29,6 +29,24 @@ func GetNextMonthFirstDay(d time.Time) time.Time { | @@ -29,6 +29,24 @@ func GetNextMonthFirstDay(d time.Time) time.Time { | ||
29 | return GetZeroTime(d) | 29 | return GetZeroTime(d) |
30 | } | 30 | } |
31 | 31 | ||
32 | +// GetNextMonthFirstDay 获取传入的时间所在月份的最后一天,即某月最后一天的23:59:59。如传入time.Now(), 返回当前月份的最后一天的23:59:59。 | ||
33 | +func GetCurrentMonthFirstDay(t time.Time) time.Time { | ||
34 | + y, m, d := t.Date() | ||
35 | + result := time.Date(y, m, d, 0, 0, 0, 0, time.Local) | ||
36 | + return result | ||
37 | +} | ||
38 | + | ||
39 | +func GetCurrentWeekFirstDay(t time.Time) time.Time { | ||
40 | + d := t.Weekday() | ||
41 | + result := GetZeroTime(t) | ||
42 | + if d == time.Sunday { | ||
43 | + result = result.Add(-time.Hour * 24 * 6) | ||
44 | + } else { | ||
45 | + result = result.Add(-time.Hour * 24 * (time.Duration(d) - 1)) | ||
46 | + } | ||
47 | + return result | ||
48 | +} | ||
49 | + | ||
32 | // GetZeroTime 获取某一天的0点时间 | 50 | // GetZeroTime 获取某一天的0点时间 |
33 | func GetZeroTime(d time.Time) time.Time { | 51 | func GetZeroTime(d time.Time) time.Time { |
34 | return time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, time.Local) | 52 | return time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, time.Local) |
@@ -9,4 +9,8 @@ func init() { | @@ -9,4 +9,8 @@ func init() { | ||
9 | web.Router("/statistics", &controllers.StatisticsController{}, "Post:CommonStatisticsService") | 9 | web.Router("/statistics", &controllers.StatisticsController{}, "Post:CommonStatisticsService") |
10 | c := &controllers.StatisticsController{} | 10 | c := &controllers.StatisticsController{} |
11 | web.Post("/statistics/hour-productive", c.CommonStatisticsHandler("HourProductiveStatistics")) | 11 | web.Post("/statistics/hour-productive", c.CommonStatisticsHandler("HourProductiveStatistics")) |
12 | + web.Post("/statistics/daily-productive-statistics", c.CommonStatisticsHandler("DailyProductiveStatistics")) | ||
13 | + web.Post("/statistics/proportion-of-second-level-statistics", c.CommonStatisticsHandler("ProportionOfSecondLevelStatistics")) | ||
14 | + web.Post("/statistics/workshop-production-efficiency-statistics", c.CommonStatisticsHandler("WorkshopProductionEfficiencyStatistics")) | ||
15 | + web.Post("/statistics/device-running-statistics", c.CommonStatisticsHandler("DeviceRunningStatistics")) | ||
12 | } | 16 | } |
-
请 注册 或 登录 后发表评论