正在显示
100 个修改的文件
包含
3324 行增加
和
219 行删除
1 | -#project | ||
1 | +# 生产制造项目说明 | ||
2 | + | ||
3 | +## 1.数据导入导出模块 | ||
4 | + | ||
5 | +### 1.1.Excel导入流程 | ||
6 | + | ||
7 | +- 原型说明 | ||
8 | + | ||
9 | +选择模板下载、文件上传 | ||
10 | +![](https://doc-press.fjmaimaimai.com/team/frontend/plugins/data-transfer-upload.png) | ||
11 | + | ||
12 | +导入数据检验有错,显示具体错误 | ||
13 | +![](https://timeless-world.oss-cn-shenzhen.aliyuncs.com/opportunity/dev_online/20220225/object/1645791913_Rz2JJkkx6xEXtAFdXDH5eH6NTjfhtjxf.jpg) | ||
14 | + | ||
15 | +- [导入接口文档地址](https://doc-press.fjmaimaimai.com/team/frontend/plugins/business/import.html) | ||
16 | + | ||
17 | + | ||
18 | +``` | ||
19 | +POST/v1/web/file-import | ||
20 | + | ||
21 | +Content-Type multipart/form-data | ||
22 | + | ||
23 | +params: | ||
24 | + | ||
25 | +file 文件 | ||
26 | +code 对应导入模块的编码 | ||
27 | +``` | ||
28 | + | ||
29 | +- ``对接步骤``以导入公司用户模块为例 | ||
30 | + | ||
31 | +1.定义接口导入的``code``为``ADMIN_SYSTEM-MANAGE_BASE_USER`` | ||
32 | +2.根据接口解析导入文件的数据 | ||
33 | +3.调用基础库解析数据并传到后台 | ||
34 | +```go | ||
35 | + | ||
36 | +// 1.解析列 | ||
37 | +excelImport := excel.NewExcelImport() | ||
38 | +excelImport.RowBegin = 3 //第二行开始读取 | ||
39 | +excelImport.DataFields = []excel.DataField{ | ||
40 | + {EnName: "userCode", CnName: "*用户编码"}, | ||
41 | + {EnName: "userName", CnName: "*用户姓名"}, | ||
42 | + {EnName: "org", CnName: "*组织机构"}, | ||
43 | + {EnName: "department", CnName: "*所属部门"}, | ||
44 | + {EnName: "enableStatus", CnName: "*用户状态"}, | ||
45 | + {EnName: "phone", CnName: "*手机号"}, | ||
46 | + {EnName: "employeeType", CnName: "*员工类型"}, | ||
47 | + {EnName: "icCardNumber", CnName: "IC卡号"}, | ||
48 | + {EnName: "email", CnName: "邮箱"}, | ||
49 | +} | ||
50 | +excelData, err := excelImport.OpenExcelFromIoReader(importDataCommand.Reader) | ||
51 | +if err != nil { | ||
52 | + return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error()) | ||
53 | +} | ||
54 | +users := make([]allied_creation_user.BatchAddUserItem, 0) | ||
55 | +for _, v := range excelData { | ||
56 | + if srv.fieldValueAllEmpty(v) { | ||
57 | + continue | ||
58 | + } | ||
59 | + item := allied_creation_user.BatchAddUserItem{ | ||
60 | + CompanyId: importDataCommand.Operator.CompanyId, | ||
61 | + UserType: domain.UserTypeEmployee, | ||
62 | + UserCode: strings.TrimSpace(v["userCode"]), | ||
63 | + Org: strings.TrimSpace(v["org"]), | ||
64 | + Department: strings.TrimSpace(v["department"]), | ||
65 | + UserName: strings.TrimSpace(v["userName"]), | ||
66 | + Phone: strings.TrimSpace(v["phone"]), | ||
67 | + Email: strings.TrimSpace(v["email"]), | ||
68 | + EnableStatus: strings.TrimSpace(v["enableStatus"]), | ||
69 | + EmployeeType: strings.TrimSpace(v["employeeType"]), | ||
70 | + IcCardNumber: strings.TrimSpace(v["icCardNumber"]), | ||
71 | + } | ||
72 | + users = append(users, item) | ||
73 | +} | ||
74 | +// 2.向后台服务发起批量添加请求 | ||
75 | +userGateway := allied_creation_user.NewHttplibAlliedCreationUser(importDataCommand.Operator) | ||
76 | +result, err := userGateway.UserBatchAdd(allied_creation_user.ReqBatchAddUser{ | ||
77 | + Users: users, | ||
78 | + Password: initPassword, | ||
79 | +}) | ||
80 | +``` | ||
81 | + | ||
82 | +```go | ||
83 | +``` | ||
84 | + | ||
85 | +### 2.2 Excel导出流程 | ||
86 | + | ||
87 | +- 功能原型说明 | ||
88 | + | ||
89 | +实现可以自定义选择列进行导出,以及选择导出格式,导出格式有 ``xlsx``\\``csv``,功能如下图所示: | ||
90 | + | ||
91 | +![](https://timeless-world.oss-cn-shenzhen.aliyuncs.com/opportunity/dev_online/20220225/object/1645789890_JbTa22EtANsD3fm2nJ4aH6FJkHzXaHJB.png) | ||
92 | + | ||
93 | +- 前后端交互说明 | ||
94 | + | ||
95 | +``接口定义`` | ||
96 | + | ||
97 | +导出接口 | ||
98 | +```shell | ||
99 | +POST /v1/web/file-export | ||
100 | + | ||
101 | +// request 请求参数 | ||
102 | +{ | ||
103 | + // 业务编码 | ||
104 | + "code":"string" | ||
105 | + // 选择的导出的列 | ||
106 | + "fields":[] | ||
107 | + // 导出文件格式 | ||
108 | + "format":"xlsx" | ||
109 | + // 业务查询条件 | ||
110 | + "where":{} | ||
111 | +} | ||
112 | +``` | ||
113 | + | ||
114 | +导出列查询接口 | ||
115 | + | ||
116 | +```shell | ||
117 | +GET/v1/web/file-export/fields/:code | ||
118 | + | ||
119 | +// response 应答数据 | ||
120 | +{ | ||
121 | + "fields":[ | ||
122 | + { | ||
123 | + "enName":"字段键名", | ||
124 | + "cnName":"字段展示名称", | ||
125 | + "selected":true // 默认勾选 | ||
126 | + } | ||
127 | + ] | ||
128 | +} | ||
129 | +``` | ||
130 | + | ||
131 | +- 交互流程 | ||
132 | + | ||
133 | +1.前台根据 ``导出列查询接口`` 获取可以导出的列; | ||
134 | +2.勾选需要导出的列、文件格式,调用 ``导出接口`` 向后台发起导出数据请求; | ||
135 | + | ||
136 | + | ||
137 | +#### 2.2.1 后端导出实现 | ||
138 | + | ||
139 | +1. 导出数据实现接口 | ||
140 | + | ||
141 | +``` | ||
142 | +type ExcelMaker interface { | ||
143 | + DataFieldList() []DataField //字段元数据列表 | ||
144 | + CellValue(index int, enName string) (value interface{}) //获取单元格字段值 | ||
145 | + DataListLen() int //数据列表大小 | ||
146 | + TableTitle() []string //列表顶部自定义内容 | ||
147 | +} | ||
148 | +``` | ||
149 | + | ||
150 | +如下所示 | ||
151 | +```go | ||
152 | +//ExportCooperationUserData 导出共创用户数据 | ||
153 | +type ExportCooperationUserData struct { | ||
154 | + SourceData []allied_creation_user.UserDetail //具体数据 | ||
155 | + SelectedField []string | ||
156 | +} | ||
157 | + | ||
158 | +var _ excel.ExcelMaker = (*ExportCooperationUserData)(nil) | ||
159 | + | ||
160 | +func (data ExportCooperationUserData) AllFields() []DataFieldOptions { | ||
161 | + return []DataFieldOptions{ | ||
162 | + {EnName: "UserCode", CnName: "用户编码"}, | ||
163 | + {EnName: "UserName", CnName: "用户姓名"}, | ||
164 | + {EnName: "Phone", CnName: "手机号"}, | ||
165 | + {EnName: "CooperationCompany", CnName: "共创公司"}, | ||
166 | + {EnName: "CooperationDeadline", CnName: "共创到期"}, | ||
167 | + {EnName: "EnableStatus", CnName: "状态"}, | ||
168 | + } | ||
169 | +} | ||
170 | + | ||
171 | +func (data ExportCooperationUserData) DataFieldList() []excel.DataField { | ||
172 | + fields := []excel.DataField{} | ||
173 | + allFields := data.AllFields() | ||
174 | + for _, value2 := range allFields { | ||
175 | + if len(data.SelectedField) == 0 || value2.IsDefault { | ||
176 | + fields = append(fields, excel.DataField{EnName: value2.EnName, CnName: value2.CnName}) | ||
177 | + continue | ||
178 | + } | ||
179 | + for _, value3 := range data.SelectedField { | ||
180 | + if value2.EnName == value3 { | ||
181 | + fields = append(fields, excel.DataField{EnName: value2.EnName, CnName: value2.CnName}) | ||
182 | + } | ||
183 | + } | ||
184 | + } | ||
185 | + return fields | ||
186 | +} | ||
187 | + | ||
188 | +func (data ExportCooperationUserData) CellValue(index int, enName string) (value interface{}) { | ||
189 | + if index > data.DataListLen() { | ||
190 | + return "" | ||
191 | + } | ||
192 | + switch enName { | ||
193 | + case "UserCode": | ||
194 | + return data.SourceData[index].UserCode | ||
195 | + case "UserName": | ||
196 | + return data.SourceData[index].UserInfo.UserName | ||
197 | + case "CooperationCompany": | ||
198 | + return data.SourceData[index].CooperationInfo.CooperationCompany | ||
199 | + case "CooperationDeadline": | ||
200 | + if data.SourceData[index].CooperationInfo.CooperationDeadline.IsZero() || data.SourceData[index].CooperationInfo.CooperationDeadline.Unix() == 0 { | ||
201 | + return "" | ||
202 | + } | ||
203 | + return data.SourceData[index].CooperationInfo.CooperationDeadline.Format("2006-01-02") | ||
204 | + case "Phone": | ||
205 | + return data.SourceData[index].UserInfo.Phone | ||
206 | + case "Email": | ||
207 | + return data.SourceData[index].UserInfo.Email | ||
208 | + case "EnableStatus": | ||
209 | + status := data.SourceData[index].EnableStatus | ||
210 | + statusName := "" | ||
211 | + // 状态(1:启用 2:禁用 3:注销) | ||
212 | + switch status { | ||
213 | + case 1: | ||
214 | + statusName = "启用" | ||
215 | + case 2: | ||
216 | + statusName = "禁用" | ||
217 | + case 3: | ||
218 | + statusName = "注销" | ||
219 | + } | ||
220 | + return statusName | ||
221 | + } | ||
222 | + return nil | ||
223 | +} | ||
224 | + | ||
225 | +func (data ExportCooperationUserData) DataListLen() int { | ||
226 | + return len(data.SourceData) | ||
227 | +} | ||
228 | + | ||
229 | +func (data ExportCooperationUserData) TableTitle() []string { | ||
230 | + return nil | ||
231 | +} | ||
232 | +``` | ||
233 | + | ||
234 | +2. 返回文件 | ||
235 | + | ||
236 | +```go | ||
237 | +//返回文件 | ||
238 | +excelTool := excel.NewExcelExport() | ||
239 | +err = excelTool.ExportData(data, "") | ||
240 | +controller.responseExcelByFile(controller.Ctx, excelTool, filename) | ||
241 | + | ||
242 | + | ||
243 | +func (controller *ExcelDataController) responseExcelByFile(ctx *context.Context, excelExport *excel.ExcelExport, fileName string) error { | ||
244 | + ctx.Output.Header("Content-Disposition", "attachment; filename="+fileName) | ||
245 | + ctx.Output.Header("Content-Description", "File Transfer") | ||
246 | + ctx.Output.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") | ||
247 | + ctx.Output.Header("Content-Transfer-Encoding", "binary") | ||
248 | + ctx.Output.Header("Expires", "0") | ||
249 | + ctx.Output.Header("Cache-Control", "must-revalidate") | ||
250 | + ctx.Output.Header("Pragma", "public") | ||
251 | + //跳过保存文件,直接写入ctx.ResponseWriter | ||
252 | + excelExport.ExcelFile.Write(ctx.ResponseWriter) | ||
253 | + return nil | ||
254 | +} | ||
255 | +``` |
@@ -22,6 +22,7 @@ require ( | @@ -22,6 +22,7 @@ require ( | ||
22 | github.com/onsi/ginkgo v1.15.2 | 22 | github.com/onsi/ginkgo v1.15.2 |
23 | github.com/onsi/gomega v1.11.0 | 23 | github.com/onsi/gomega v1.11.0 |
24 | github.com/sergi/go-diff v1.2.0 // indirect | 24 | github.com/sergi/go-diff v1.2.0 // indirect |
25 | + github.com/shopspring/decimal v1.2.0 | ||
25 | github.com/smartystreets/goconvey v1.7.2 // indirect | 26 | github.com/smartystreets/goconvey v1.7.2 // indirect |
26 | github.com/stretchr/testify v1.7.0 | 27 | github.com/stretchr/testify v1.7.0 |
27 | github.com/tidwall/gjson v1.13.0 | 28 | github.com/tidwall/gjson v1.13.0 |
@@ -31,7 +32,6 @@ require ( | @@ -31,7 +32,6 @@ require ( | ||
31 | github.com/yudai/gojsondiff v1.0.0 // indirect | 32 | github.com/yudai/gojsondiff v1.0.0 // indirect |
32 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect | 33 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect |
33 | github.com/yudai/pp v2.0.1+incompatible // indirect | 34 | github.com/yudai/pp v2.0.1+incompatible // indirect |
34 | - golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 | ||
35 | golang.org/x/text v0.3.6 | 35 | golang.org/x/text v0.3.6 |
36 | ) | 36 | ) |
37 | 37 |
@@ -339,6 +339,8 @@ github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI | @@ -339,6 +339,8 @@ github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI | ||
339 | github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg= | 339 | github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg= |
340 | github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= | 340 | github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= |
341 | github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= | 341 | github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= |
342 | +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= | ||
343 | +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= | ||
342 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= | 344 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= |
343 | github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= | 345 | github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= |
344 | github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s= | 346 | github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s= |
@@ -2,6 +2,7 @@ package main | @@ -2,6 +2,7 @@ package main | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/port/mqtt" | ||
5 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/port/task" | 6 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/port/task" |
6 | 7 | ||
7 | "github.com/beego/beego/v2/server/web" | 8 | "github.com/beego/beego/v2/server/web" |
@@ -9,7 +10,6 @@ import ( | @@ -9,7 +10,6 @@ import ( | ||
9 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" | 10 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" |
10 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/redis" | 11 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/redis" |
11 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" | 12 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" |
12 | - "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/port/mqtt" | ||
13 | 13 | ||
14 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/crontab" | 14 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/crontab" |
15 | _ "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" | 15 | _ "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" |
@@ -2,6 +2,8 @@ package dto | @@ -2,6 +2,8 @@ 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" | ||
6 | + "time" | ||
5 | ) | 7 | ) |
6 | 8 | ||
7 | type AttendanceRecordDto struct { | 9 | type AttendanceRecordDto struct { |
@@ -15,7 +17,10 @@ type AttendanceRecordDto struct { | @@ -15,7 +17,10 @@ type AttendanceRecordDto struct { | ||
15 | AttendanceType int `json:"attendanceType,omitempty"` | 17 | AttendanceType int `json:"attendanceType,omitempty"` |
16 | // 生产工人 | 18 | // 生产工人 |
17 | ProductWorker *domain.User `json:"productWorker,omitempty"` | 19 | ProductWorker *domain.User `json:"productWorker,omitempty"` |
18 | - *domain.ProductAttendanceRecordExt | 20 | + // 审核人 |
21 | + ApproveUser *domain.User `json:"approveUser"` | ||
22 | + //*domain.ProductAttendanceRecordExt | ||
23 | + ApproveAt string `json:"approveAt"` | ||
19 | // 工作位置 | 24 | // 工作位置 |
20 | *domain.WorkStation | 25 | *domain.WorkStation |
21 | // 签到 | 26 | // 签到 |
@@ -42,19 +47,32 @@ func (d *AttendanceRecordDto) LoadDto(m *domain.ProductAttendanceRecord, orgId i | @@ -42,19 +47,32 @@ func (d *AttendanceRecordDto) LoadDto(m *domain.ProductAttendanceRecord, orgId i | ||
42 | d.ProductWorker = m.ProductWorker | 47 | d.ProductWorker = m.ProductWorker |
43 | d.WorkStation = m.WorkStation | 48 | d.WorkStation = m.WorkStation |
44 | if !m.SignIn.IsZero() { | 49 | if !m.SignIn.IsZero() { |
45 | - d.SignIn = m.SignIn.Format("15:04:05") | ||
46 | - d.SignDate = m.SignIn.Format("2006-01-02") | 50 | + d.SignIn = m.SignIn.Local().Format("15:04:05") |
51 | + d.SignDate = m.SignIn.Local().Format("2006-01-02") | ||
47 | } | 52 | } |
48 | if !m.SignOut.IsZero() { | 53 | if !m.SignOut.IsZero() { |
49 | - d.SignOut = m.SignOut.Format("15:04:05") | 54 | + d.SignOut = m.SignOut.Local().Format("15:04:05") |
50 | } | 55 | } |
51 | - d.WorkTimeBefore = m.WorkTimeBefore | 56 | + d.WorkTimeBefore = utils.Round(m.WorkTimeBefore, 1) |
52 | d.WorkTimeAfter = m.WorkTimeAfter | 57 | d.WorkTimeAfter = m.WorkTimeAfter |
53 | d.AttendanceStatus = m.AttendanceStatus | 58 | d.AttendanceStatus = m.AttendanceStatus |
54 | d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId) | 59 | d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId) |
55 | if m.Ext != nil { | 60 | if m.Ext != nil { |
56 | d.OrgName = m.Ext.OrgName | 61 | d.OrgName = m.Ext.OrgName |
57 | - d.ProductAttendanceRecordExt = m.Ext.AttendanceExt | 62 | + //d.ProductAttendanceRecordExt = m.Ext.AttendanceExt |
63 | + //if | ||
64 | + if m.Ext.AttendanceExt != nil { | ||
65 | + if m.Ext.AttendanceExt.ApproveUserId > 0 { | ||
66 | + d.ApproveUser = &domain.User{ | ||
67 | + UserId: m.Ext.AttendanceExt.ApproveUserId, | ||
68 | + UserName: m.Ext.AttendanceExt.ApproveUserName, | ||
69 | + } | ||
70 | + } | ||
71 | + if m.Ext.AttendanceExt.ApproveAt > 0 { | ||
72 | + t := time.Unix(m.Ext.AttendanceExt.ApproveAt, 0) | ||
73 | + d.ApproveAt = t.Local().Format("2006-01-02 15:04:05") | ||
74 | + } | ||
75 | + } | ||
58 | } | 76 | } |
59 | return d | 77 | return d |
60 | } | 78 | } |
@@ -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 | ) | 6 | ) |
6 | 7 | ||
7 | type EmployeeAttendanceRecordDto struct { | 8 | type EmployeeAttendanceRecordDto struct { |
@@ -39,9 +40,9 @@ func (d *EmployeeAttendanceRecordDto) LoadDto(m *domain.ProductAttendanceRecord, | @@ -39,9 +40,9 @@ func (d *EmployeeAttendanceRecordDto) LoadDto(m *domain.ProductAttendanceRecord, | ||
39 | d.WorkStation = m.WorkStation | 40 | d.WorkStation = m.WorkStation |
40 | if !m.SignIn.IsZero() { | 41 | if !m.SignIn.IsZero() { |
41 | //d.SignIn = m.SignIn.Format("15:04:05") | 42 | //d.SignIn = m.SignIn.Format("15:04:05") |
42 | - d.SignDate = m.SignIn.Format("2006-01-02") | 43 | + d.SignDate = m.SignIn.Local().Format("2006-01-02") |
43 | } | 44 | } |
44 | - d.WorkTime = m.WorkTimeAfter | 45 | + d.WorkTime = utils.Round(m.WorkTimeAfter, 1) |
45 | //d.WorkTimeAfter = m.WorkTimeAfter | 46 | //d.WorkTimeAfter = m.WorkTimeAfter |
46 | d.AttendanceStatus = m.AttendanceStatus | 47 | d.AttendanceStatus = m.AttendanceStatus |
47 | d.AttendanceTypeDescription = domain.ParticipateTypeDescription(m.AttendanceType) | 48 | d.AttendanceTypeDescription = domain.ParticipateTypeDescription(m.AttendanceType) |
@@ -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 | ) | 6 | ) |
6 | 7 | ||
7 | type WorkshopWorkTimeRecordDto struct { | 8 | type WorkshopWorkTimeRecordDto struct { |
@@ -24,9 +25,14 @@ type WorkshopWorkTimeRecordDto struct { | @@ -24,9 +25,14 @@ type WorkshopWorkTimeRecordDto struct { | ||
24 | func (d *WorkshopWorkTimeRecordDto) LoadDto(m *domain.WorkshopWorkTimeRecord, orgId int) *WorkshopWorkTimeRecordDto { | 25 | func (d *WorkshopWorkTimeRecordDto) LoadDto(m *domain.WorkshopWorkTimeRecord, orgId int) *WorkshopWorkTimeRecordDto { |
25 | d.WorkshopWorkTimeRecordId = m.WorkshopWorkTimeRecordId | 26 | d.WorkshopWorkTimeRecordId = m.WorkshopWorkTimeRecordId |
26 | d.WorkStation = m.WorkStation | 27 | d.WorkStation = m.WorkStation |
27 | - d.WorkshopWorkTimeRecordInfo = m.WorkshopWorkTimeRecordInfo | 28 | + if m.WorkshopWorkTimeRecordInfo != nil { |
29 | + d.WorkshopWorkTimeRecordInfo = &domain.WorkshopWorkTimeRecordInfo{} | ||
30 | + d.WorkshopWorkTimeRecordInfo.EPTWorkTime = utils.Round(m.WorkshopWorkTimeRecordInfo.EPTWorkTime, 1) | ||
31 | + d.WorkshopWorkTimeRecordInfo.EDWorkTime = utils.Round(m.WorkshopWorkTimeRecordInfo.EDWorkTime, 1) | ||
32 | + d.WorkshopWorkTimeRecordInfo.EFTWorkTime = utils.Round(m.WorkshopWorkTimeRecordInfo.EFTWorkTime, 1) | ||
33 | + } | ||
28 | d.WorkStation = m.WorkStation | 34 | d.WorkStation = m.WorkStation |
29 | - d.RecordDate = m.RecordDate.Format("2006-01-02") | 35 | + d.RecordDate = m.RecordDate.Local().Format("2006-01-02") |
30 | d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId) | 36 | d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId) |
31 | if m.Ext != nil { | 37 | if m.Ext != nil { |
32 | d.OrgName = m.Ext.OrgName | 38 | d.OrgName = m.Ext.OrgName |
@@ -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 | // 结束时间 |
@@ -30,7 +30,7 @@ func (attendanceService *AttendanceService) WorkerAttendanceReport(cmd *command. | @@ -30,7 +30,7 @@ func (attendanceService *AttendanceService) WorkerAttendanceReport(cmd *command. | ||
30 | // return nil, err | 30 | // return nil, err |
31 | //} | 31 | //} |
32 | attendanceReportService, _ := domainService.NewPGWorkerAttendanceReportService(transactionContext.(*pgTransaction.TransactionContext)) | 32 | attendanceReportService, _ := domainService.NewPGWorkerAttendanceReportService(transactionContext.(*pgTransaction.TransactionContext)) |
33 | - if _, err := attendanceReportService.Report(constant.MANUFACTURE_DEFAULT_COMPANYID, constant.MANUFACTURE_DEFAULT_COMPANYID, cmd.DeviceZkTeco); err != nil { | 33 | + if _, err := attendanceReportService.Report(constant.MANUFACTURE_DEFAULT_COMPANYID, constant.MANUFACTURE_DEFAULT_ORGID, cmd.DeviceZkTeco); err != nil { |
34 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 34 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
35 | } | 35 | } |
36 | if err := transactionContext.CommitTransaction(); err != nil { | 36 | if err := transactionContext.CommitTransaction(); err != nil { |
@@ -18,20 +18,20 @@ func NewCrontabService(options map[string]interface{}) *CrontabService { | @@ -18,20 +18,20 @@ func NewCrontabService(options map[string]interface{}) *CrontabService { | ||
18 | } | 18 | } |
19 | 19 | ||
20 | func (crontabService *CrontabService) initTask() { | 20 | func (crontabService *CrontabService) initTask() { |
21 | - //拉取物料数据 晚上0时10分执行 | ||
22 | - pullMaterialK3cloud := task.NewTask("pullMaterialK3cloud", "0 10 0 * * *", func(ctx context.Context) error { | 21 | + //拉取物料数据 每5分执行 |
22 | + pullMaterialK3cloud := task.NewTask("pullMaterialK3cloud", "0 */5 0 * * *", func(ctx context.Context) error { | ||
23 | srv := syncdata.PullDataK3CloudService{} | 23 | srv := syncdata.PullDataK3CloudService{} |
24 | return srv.PullMaterialNewest() | 24 | return srv.PullMaterialNewest() |
25 | }) | 25 | }) |
26 | task.AddTask("pullMaterialK3cloud", pullMaterialK3cloud) | 26 | task.AddTask("pullMaterialK3cloud", pullMaterialK3cloud) |
27 | - //拉取物料分组数据 晚上0时10分执行 | ||
28 | - pullMaterialGroupK3cloud := task.NewTask("pullMaterialGroupK3cloud", "0 10 0 * * *", func(ctx context.Context) error { | 27 | + //拉取物料分组数据 每5分执行 |
28 | + pullMaterialGroupK3cloud := task.NewTask("pullMaterialGroupK3cloud", "0 */5 0 * * *", func(ctx context.Context) error { | ||
29 | srv := syncdata.PullDataK3CloudService{} | 29 | srv := syncdata.PullDataK3CloudService{} |
30 | return srv.PullMaterialGroup() | 30 | return srv.PullMaterialGroup() |
31 | }) | 31 | }) |
32 | task.AddTask("pullMaterialGroupK3cloud", pullMaterialGroupK3cloud) | 32 | task.AddTask("pullMaterialGroupK3cloud", pullMaterialGroupK3cloud) |
33 | - //拉取订生产订单数据 晚上0时10分执行 | ||
34 | - PullPrdMoK3cloud := task.NewTask("PullPrdMoK3cloud", "0 10 0 * * *", func(ctx context.Context) error { | 33 | + //拉取订生产订单数据 每5分执行 |
34 | + PullPrdMoK3cloud := task.NewTask("PullPrdMoK3cloud", "0 */5 0 * * *", func(ctx context.Context) error { | ||
35 | srv := syncdata.PullDataK3CloudService{} | 35 | srv := syncdata.PullDataK3CloudService{} |
36 | return srv.PullPrdMoNewest() | 36 | return srv.PullPrdMoNewest() |
37 | }) | 37 | }) |
@@ -42,6 +42,12 @@ func (crontabService *CrontabService) initTask() { | @@ -42,6 +42,12 @@ func (crontabService *CrontabService) initTask() { | ||
42 | 42 | ||
43 | autoApproveRecord := task.NewTask("autoApproveRecord", "0 */2 * * * *", AutoApproveProductRecord) | 43 | autoApproveRecord := task.NewTask("autoApproveRecord", "0 */2 * * * *", AutoApproveProductRecord) |
44 | task.AddTask("autoApproveRecord", autoApproveRecord) | 44 | task.AddTask("autoApproveRecord", autoApproveRecord) |
45 | + | ||
46 | + autoFlushDeviceDailyRunningRecord := task.NewTask("autoFlushDeviceDailyRunningRecord", "0 */1 * * * *", AutoFlushDeviceDailyRunningRecord) | ||
47 | + task.AddTask("autoFlushDeviceDailyRunningRecord", autoFlushDeviceDailyRunningRecord) | ||
48 | + | ||
49 | + autoWorkshopPlanCompletionRecord := task.NewTask("autoFlushDeviceDailyRunningRecord", "0 1 1-10/3 * * *", AutoWorkshopPlanCompletionRecord) | ||
50 | + task.AddTask("autoWorkshopPlanCompletionRecord", autoWorkshopPlanCompletionRecord) | ||
45 | } | 51 | } |
46 | 52 | ||
47 | func (crontabService *CrontabService) StartCrontabTask() { | 53 | func (crontabService *CrontabService) StartCrontabTask() { |
1 | +package crontab | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "fmt" | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/redis" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" | ||
9 | + "time" | ||
10 | +) | ||
11 | + | ||
12 | +// 定时刷新设备每日运行记录 | ||
13 | +func AutoFlushDeviceDailyRunningRecord(ctx context.Context) error { | ||
14 | + defer func() { | ||
15 | + if r := recover(); r != nil { | ||
16 | + log.Logger.Error(fmt.Sprintf("%v", r)) | ||
17 | + } | ||
18 | + }() | ||
19 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
20 | + if err != nil { | ||
21 | + return err | ||
22 | + } | ||
23 | + if err := transactionContext.StartTransaction(); err != nil { | ||
24 | + return err | ||
25 | + } | ||
26 | + defer func() { | ||
27 | + if err != nil { | ||
28 | + log.Logger.Error("【定时刷新设备每日运行记录】 失败:" + err.Error()) | ||
29 | + } | ||
30 | + transactionContext.RollbackTransaction() | ||
31 | + }() | ||
32 | + | ||
33 | + log.Logger.Debug("【定时刷新设备每日运行记录】 启动") | ||
34 | + deviceDailyRunningRecordRepository, _, _ := factory.FastPgDeviceDailyRunningRecord(transactionContext, 0) | ||
35 | + // 获取redis里当天的记录 | ||
36 | + span := time.Duration(20) | ||
37 | + t := time.Now().Add(-time.Minute * span) | ||
38 | + records, err := redis.GetDeviceDailyAllRecord(t) | ||
39 | + if err != nil { | ||
40 | + log.Logger.Error(err.Error()) | ||
41 | + return err | ||
42 | + } | ||
43 | + | ||
44 | + for _, v := range records { | ||
45 | + if v.UpdatedAt.Add(time.Minute * 5).Before(time.Now()) { | ||
46 | + log.Logger.Debug(fmt.Sprintf("【定时刷新设备每日运行记录】 跳过记录 %v 最后更新时间:%v", v, v.UpdatedAt)) | ||
47 | + continue | ||
48 | + } | ||
49 | + | ||
50 | + // 更新设备效率 OEE = tu * pu * qu | ||
51 | + | ||
52 | + if _, err := deviceDailyRunningRecordRepository.Save(v); err != nil { | ||
53 | + log.Logger.Error(err.Error()) | ||
54 | + continue | ||
55 | + } else { | ||
56 | + log.Logger.Debug(fmt.Sprintf("【定时刷新设备每日运行记录】 刷新记录 %v", v)) | ||
57 | + } | ||
58 | + } | ||
59 | + | ||
60 | + if err = transactionContext.CommitTransaction(); err != nil { | ||
61 | + return err | ||
62 | + } | ||
63 | + return nil | ||
64 | +} |
1 | +package crontab | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "fmt" | ||
6 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" | ||
11 | + "time" | ||
12 | +) | ||
13 | + | ||
14 | +// 定时刷新车间计划完成纪录 | ||
15 | +func AutoWorkshopPlanCompletionRecord(ctx context.Context) error { | ||
16 | + defer func() { | ||
17 | + if r := recover(); r != nil { | ||
18 | + log.Logger.Error(fmt.Sprintf("%v", r)) | ||
19 | + } | ||
20 | + }() | ||
21 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
22 | + if err != nil { | ||
23 | + return err | ||
24 | + } | ||
25 | + if err := transactionContext.StartTransaction(); err != nil { | ||
26 | + return err | ||
27 | + } | ||
28 | + defer func() { | ||
29 | + if err != nil { | ||
30 | + log.Logger.Error("【定时刷新设备每日运行记录】 失败:" + err.Error()) | ||
31 | + } | ||
32 | + transactionContext.RollbackTransaction() | ||
33 | + }() | ||
34 | + | ||
35 | + log.Logger.Debug("【定时刷新设备每日运行记录】 启动") | ||
36 | + end := utils.GetZeroTime(time.Now()) | ||
37 | + begin := utils.GetZeroTime(end.Add(-time.Second)) | ||
38 | + approveAttendanceRecordsService, _ := domainService.NewPGWorkshopPlanCompletionRecordService(transactionContext.(*pgTransaction.TransactionContext)) | ||
39 | + | ||
40 | + if err = approveAttendanceRecordsService.WorkshopPlanCompletion(begin, end); err != nil { | ||
41 | + return err | ||
42 | + } | ||
43 | + | ||
44 | + if err = transactionContext.CommitTransaction(); err != nil { | ||
45 | + return err | ||
46 | + } | ||
47 | + return nil | ||
48 | +} |
@@ -26,7 +26,7 @@ type UpdateDeviceCommand struct { | @@ -26,7 +26,7 @@ type UpdateDeviceCommand struct { | ||
26 | // 工段ID | 26 | // 工段ID |
27 | SectionId int `cname:"工段ID" json:"sectionId"` | 27 | SectionId int `cname:"工段ID" json:"sectionId"` |
28 | // 品牌 | 28 | // 品牌 |
29 | - Brand string `cname:"品牌" json:"brand" valid:"Required"` | 29 | + Brand string `cname:"品牌" json:"brand"` |
30 | // 设备状态 1:正常 2:封存 3:报废 | 30 | // 设备状态 1:正常 2:封存 3:报废 |
31 | DeviceStatus int `cname:"设备状态 1:正常 2:封存 3:报废" json:"deviceStatus" valid:"Required"` | 31 | DeviceStatus int `cname:"设备状态 1:正常 2:封存 3:报废" json:"deviceStatus" valid:"Required"` |
32 | // 风险等级 1:高 2:中 3:低 | 32 | // 风险等级 1:高 2:中 3:低 |
1 | package dto | 1 | package dto |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "fmt" | ||
4 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | 5 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" |
5 | ) | 6 | ) |
6 | 7 | ||
@@ -24,7 +25,7 @@ type DeviceDto struct { | @@ -24,7 +25,7 @@ type DeviceDto struct { | ||
24 | // 所属位置 | 25 | // 所属位置 |
25 | *domain.WorkStation | 26 | *domain.WorkStation |
26 | // 生产单个产品的时间(单位:秒) | 27 | // 生产单个产品的时间(单位:秒) |
27 | - UnitProductionSecTime int `json:"unitProductionSecTime"` | 28 | + UnitProductionSecTime string `json:"unitProductionSecTime"` |
28 | 29 | ||
29 | // 组织名称 | 30 | // 组织名称 |
30 | OrgName string `json:"orgName"` | 31 | OrgName string `json:"orgName"` |
@@ -47,7 +48,9 @@ func (d *DeviceDto) LoadDto(m *domain.Device, orgId int) *DeviceDto { | @@ -47,7 +48,9 @@ func (d *DeviceDto) LoadDto(m *domain.Device, orgId int) *DeviceDto { | ||
47 | d.OrgName = m.Ext.OrgName | 48 | d.OrgName = m.Ext.OrgName |
48 | } | 49 | } |
49 | if m.Ext != nil && m.Ext.DeviceExt != nil { | 50 | if m.Ext != nil && m.Ext.DeviceExt != nil { |
50 | - d.UnitProductionSecTime = m.Ext.DeviceExt.UnitProductionSecTime | 51 | + if m.Ext.DeviceExt.UnitProductionSecTime > 0 { |
52 | + d.UnitProductionSecTime = fmt.Sprintf("%v", m.Ext.DeviceExt.UnitProductionSecTime) | ||
53 | + } | ||
51 | } | 54 | } |
52 | return d | 55 | return d |
53 | } | 56 | } |
@@ -350,7 +350,9 @@ func (deviceService *DeviceService) SearchDevice(operateInfo *domain.OperateInfo | @@ -350,7 +350,9 @@ func (deviceService *DeviceService) SearchDevice(operateInfo *domain.OperateInfo | ||
350 | for i := range devices { | 350 | for i := range devices { |
351 | item := devices[i] | 351 | item := devices[i] |
352 | newJobDto := &dto.DeviceDto{} | 352 | newJobDto := &dto.DeviceDto{} |
353 | - newJobDto.WorkStation = workshops.FindWorkStation(item.WorkStation.WorkshopId, item.WorkStation.LineId, item.WorkStation.SectionId) | 353 | + if item.WorkStation != nil && item.WorkStation.WorkshopId > 0 { |
354 | + newJobDto.WorkStation = workshops.FindWorkStationOrNil(item.WorkStation.WorkshopId, item.WorkStation.LineId, item.WorkStation.SectionId) | ||
355 | + } | ||
354 | newJobDto.LoadDto(item, operateInfo.OrgId) | 356 | newJobDto.LoadDto(item, operateInfo.OrgId) |
355 | result = append(result, newJobDto) | 357 | result = append(result, newJobDto) |
356 | } | 358 | } |
@@ -387,6 +387,32 @@ func FastPgWorkshopWorkTimeRecord(transactionContext application.TransactionCont | @@ -387,6 +387,32 @@ func FastPgWorkshopWorkTimeRecord(transactionContext application.TransactionCont | ||
387 | return rep, mod, err | 387 | return rep, mod, err |
388 | } | 388 | } |
389 | 389 | ||
390 | +// FastPgDeviceDailyRunningRecord 快速返回设备每日运行记录 | ||
391 | +// | ||
392 | +// transactionContext 事务 | ||
393 | +// id 对象唯一标识 | ||
394 | +func FastPgDeviceDailyRunningRecord(transactionContext application.TransactionContext, id int, options ...option) (domain.DeviceDailyRunningRecordRepository, *domain.DeviceDailyRunningRecord, error) { | ||
395 | + var rep domain.DeviceDailyRunningRecordRepository | ||
396 | + var mod *domain.DeviceDailyRunningRecord | ||
397 | + var err error | ||
398 | + if value, err := CreateDeviceDailyRunningRecordRepository(map[string]interface{}{ | ||
399 | + "transactionContext": transactionContext, | ||
400 | + }); err != nil { | ||
401 | + return nil, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
402 | + } else { | ||
403 | + rep = value | ||
404 | + } | ||
405 | + if id > 0 { | ||
406 | + if mod, err = rep.FindOne(map[string]interface{}{"deviceDailyRunningRecordId": id}); err != nil { | ||
407 | + if err == domain.ErrorNotFound { | ||
408 | + return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该记录不存在") | ||
409 | + } | ||
410 | + return nil, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
411 | + } | ||
412 | + } | ||
413 | + return rep, mod, err | ||
414 | +} | ||
415 | + | ||
390 | /***** 2.配置 *****/ | 416 | /***** 2.配置 *****/ |
391 | 417 | ||
392 | type FastOptions struct { | 418 | type FastOptions struct { |
@@ -125,3 +125,19 @@ func CreateDeviceCollectionRepository(options map[string]interface{}) (domain.De | @@ -125,3 +125,19 @@ func CreateDeviceCollectionRepository(options map[string]interface{}) (domain.De | ||
125 | } | 125 | } |
126 | return repository.NewDeviceCollectionRepository(transactionContext) | 126 | return repository.NewDeviceCollectionRepository(transactionContext) |
127 | } | 127 | } |
128 | + | ||
129 | +func CreateDeviceRunningRecordRepository(options map[string]interface{}) (domain.DeviceRunningRecordRepository, error) { | ||
130 | + var transactionContext *pg.TransactionContext | ||
131 | + if value, ok := options["transactionContext"]; ok { | ||
132 | + transactionContext = value.(*pg.TransactionContext) | ||
133 | + } | ||
134 | + return repository.NewDeviceRunningRecordRepository(transactionContext) | ||
135 | +} | ||
136 | + | ||
137 | +func CreateDeviceDailyRunningRecordRepository(options map[string]interface{}) (domain.DeviceDailyRunningRecordRepository, error) { | ||
138 | + var transactionContext *pg.TransactionContext | ||
139 | + if value, ok := options["transactionContext"]; ok { | ||
140 | + transactionContext = value.(*pg.TransactionContext) | ||
141 | + } | ||
142 | + return repository.NewDeviceDailyRunningRecordRepository(transactionContext) | ||
143 | +} |
@@ -25,7 +25,7 @@ type CreateProductGroupCommand struct { | @@ -25,7 +25,7 @@ type CreateProductGroupCommand struct { | ||
25 | // 班组长Id | 25 | // 班组长Id |
26 | GroupLeaderId int `cname:"班组长" json:"groupLeaderId,omitempty"` | 26 | GroupLeaderId int `cname:"班组长" json:"groupLeaderId,omitempty"` |
27 | // 帮组成员列表 | 27 | // 帮组成员列表 |
28 | - GroupMembers []int `cname:"帮组成员列表" json:"groupMembers" valid:"Required"` | 28 | + GroupMembers []int `cname:"帮组成员列表" json:"groupMembers"` |
29 | // 上班班次 1:全天 2:白班 4:中班 8:夜班 | 29 | // 上班班次 1:全天 2:白班 4:中班 8:夜班 |
30 | WorkOn int `cname:"上班班次 1:全天 2:白班 4:中班 8:夜班" json:"workOn" valid:"Required"` | 30 | WorkOn int `cname:"上班班次 1:全天 2:白班 4:中班 8:夜班" json:"workOn" valid:"Required"` |
31 | } | 31 | } |
@@ -22,7 +22,7 @@ type UpdateProductGroupCommand struct { | @@ -22,7 +22,7 @@ type UpdateProductGroupCommand struct { | ||
22 | // 班组长Id | 22 | // 班组长Id |
23 | GroupLeaderId int `cname:"班组长" json:"groupLeaderId,omitempty"` | 23 | GroupLeaderId int `cname:"班组长" json:"groupLeaderId,omitempty"` |
24 | // 帮组成员列表 | 24 | // 帮组成员列表 |
25 | - GroupMembers []int `cname:"帮组成员列表" json:"groupMembers" valid:"Required"` | 25 | + GroupMembers []int `cname:"帮组成员列表" json:"groupMembers"` |
26 | // 上班班次 1:全天 2:白班 4:中班 8:夜班 | 26 | // 上班班次 1:全天 2:白班 4:中班 8:夜班 |
27 | WorkOn int `cname:"上班班次 1:全天 2:白班 4:中班 8:夜班" json:"workOn" valid:"Required"` | 27 | WorkOn int `cname:"上班班次 1:全天 2:白班 4:中班 8:夜班" json:"workOn" valid:"Required"` |
28 | } | 28 | } |
@@ -16,9 +16,9 @@ type ProductGroupDto struct { | @@ -16,9 +16,9 @@ type ProductGroupDto struct { | ||
16 | // 班组名称 | 16 | // 班组名称 |
17 | GroupName string `json:"groupName,omitempty"` | 17 | GroupName string `json:"groupName,omitempty"` |
18 | // 班组长 | 18 | // 班组长 |
19 | - GroupLeader string `json:"groupLeader,omitempty"` | 19 | + GroupLeader string `json:"groupLeader"` |
20 | // 帮组成员列表 | 20 | // 帮组成员列表 |
21 | - GroupMembers string `json:"groupMembers,omitempty"` | 21 | + GroupMembers string `json:"groupMembers"` |
22 | // 上班班次 1:全天 2:白班 4:中班 8:夜班 | 22 | // 上班班次 1:全天 2:白班 4:中班 8:夜班 |
23 | WorkOn int `json:"workOn,omitempty"` | 23 | WorkOn int `json:"workOn,omitempty"` |
24 | // 工作位置 | 24 | // 工作位置 |
@@ -32,7 +32,9 @@ type ProductGroupDto struct { | @@ -32,7 +32,9 @@ type ProductGroupDto struct { | ||
32 | func (d *ProductGroupDto) LoadDto(m *domain.ProductGroup, orgId int) *ProductGroupDto { | 32 | func (d *ProductGroupDto) LoadDto(m *domain.ProductGroup, orgId int) *ProductGroupDto { |
33 | d.ProductGroupId = m.ProductGroupId | 33 | d.ProductGroupId = m.ProductGroupId |
34 | d.GroupName = m.GroupName | 34 | d.GroupName = m.GroupName |
35 | - d.GroupLeader = m.GroupLeader.UserName | 35 | + if m.GroupLeader != nil { |
36 | + d.GroupLeader = m.GroupLeader.UserName | ||
37 | + } | ||
36 | var members []string | 38 | var members []string |
37 | for i := range m.GroupMembers { | 39 | for i := range m.GroupMembers { |
38 | members = append(members, m.GroupMembers[i].UserName) | 40 | members = append(members, m.GroupMembers[i].UserName) |
@@ -71,6 +71,31 @@ func (d *ProductGroupEmployeesDtos) LoadDto(groups ...*domain.ProductGroup) { | @@ -71,6 +71,31 @@ func (d *ProductGroupEmployeesDtos) LoadDto(groups ...*domain.ProductGroup) { | ||
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
74 | +func (d *ProductGroupEmployeesDtos) LoadDtoV2(list []*domain.ProductAttendanceRecord, mapGroupUser map[string]*domain.User, keyFunc func(int) string) { | ||
75 | + var mapUser = make(map[int]int) | ||
76 | + for _, v := range list { | ||
77 | + item := &ProductGroupEmployeesDto{} | ||
78 | + item.UserId = v.ProductWorker.UserId | ||
79 | + item.UserName = v.ProductWorker.UserName | ||
80 | + item.ProductGroupId = 0 | ||
81 | + item.GroupName = "" | ||
82 | + if v, ok := mapGroupUser[keyFunc(item.UserId)]; ok { | ||
83 | + item.GroupName = v.GroupName | ||
84 | + item.ProductGroupId = v.GroupId | ||
85 | + item.WorkOnDescription = domain.WorkOnDescriptions(v.WorkOn) | ||
86 | + } | ||
87 | + if len(item.UserName) > 0 { | ||
88 | + item.UserNamePinyin = converter.ToPinYin(item.UserName, "") | ||
89 | + } | ||
90 | + if _, ok := mapUser[item.UserId]; ok { | ||
91 | + continue | ||
92 | + } else { | ||
93 | + mapUser[item.UserId] = item.UserId | ||
94 | + } | ||
95 | + d.Append(item) | ||
96 | + } | ||
97 | +} | ||
98 | + | ||
74 | func NewProductGroupEmployeesDtos() *ProductGroupEmployeesDtos { | 99 | func NewProductGroupEmployeesDtos() *ProductGroupEmployeesDtos { |
75 | return &ProductGroupEmployeesDtos{ | 100 | return &ProductGroupEmployeesDtos{ |
76 | Result: make([]*ProductGroupEmployeesDto, 0), | 101 | Result: make([]*ProductGroupEmployeesDto, 0), |
1 | +package query | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "github.com/beego/beego/v2/core/validation" | ||
6 | + "reflect" | ||
7 | + "strings" | ||
8 | +) | ||
9 | + | ||
10 | +type GetSignInEmployeeQuery struct { | ||
11 | + // 查询偏离量 | ||
12 | + //Offset int `cname:"查询偏离量" json:"offset"` | ||
13 | + // 查询限制 | ||
14 | + //Limit int `cname:"查询限制" json:"limit"` | ||
15 | + // 页码 | ||
16 | + //PageNumber int `cname:"页码" json:"pageNumber,omitempty"` | ||
17 | + // 页数 | ||
18 | + //PageSize int `cname:"页数" json:"pageSize,omitempty"` | ||
19 | + // 当前公司 | ||
20 | + CompanyId int `cname:"当前公司" json:"companyId,omitempty" valid:"Required"` | ||
21 | + // 当前登录的组织 | ||
22 | + OrgId int `cname:"当前登录的组织" json:"orgId,omitempty"` | ||
23 | + // IC卡号 | ||
24 | + IcCardNumber string `cname:"IC卡号" json:"icCardNumber,omitempty"` | ||
25 | +} | ||
26 | + | ||
27 | +func (listProductGroupQuery *GetSignInEmployeeQuery) Valid(validation *validation.Validation) { | ||
28 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
29 | +} | ||
30 | + | ||
31 | +func (listProductGroupQuery *GetSignInEmployeeQuery) ValidateQuery() error { | ||
32 | + valid := validation.Validation{} | ||
33 | + b, err := valid.Valid(listProductGroupQuery) | ||
34 | + if err != nil { | ||
35 | + return err | ||
36 | + } | ||
37 | + if !b { | ||
38 | + elem := reflect.TypeOf(listProductGroupQuery).Elem() | ||
39 | + for _, validErr := range valid.Errors { | ||
40 | + field, isExist := elem.FieldByName(validErr.Field) | ||
41 | + if isExist { | ||
42 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
43 | + } else { | ||
44 | + return fmt.Errorf(validErr.Message) | ||
45 | + } | ||
46 | + } | ||
47 | + } | ||
48 | + return nil | ||
49 | +} |
@@ -45,15 +45,19 @@ func (productGroupService *ProductGroupService) CreateProductGroup(operateInfo * | @@ -45,15 +45,19 @@ func (productGroupService *ProductGroupService) CreateProductGroup(operateInfo * | ||
45 | } | 45 | } |
46 | 46 | ||
47 | var leader *domain.User | 47 | var leader *domain.User |
48 | - var members []*domain.User | 48 | + var members = make([]*domain.User, 0) |
49 | userService := domainService.NewUserService() | 49 | userService := domainService.NewUserService() |
50 | - leader, err = userService.User(cmd.GroupLeaderId) | ||
51 | - if err != nil { | ||
52 | - return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 50 | + if cmd.GroupLeaderId > 0 { |
51 | + leader, err = userService.User(cmd.GroupLeaderId) | ||
52 | + if err != nil { | ||
53 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
54 | + } | ||
53 | } | 55 | } |
54 | - members, err = userService.Users(cmd.GroupMembers) | ||
55 | - if err != nil { | ||
56 | - return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 56 | + if len(cmd.GroupMembers) > 0 { |
57 | + members, err = userService.Users(cmd.GroupMembers) | ||
58 | + if err != nil { | ||
59 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
60 | + } | ||
57 | } | 61 | } |
58 | 62 | ||
59 | var org *domain.Org | 63 | var org *domain.Org |
@@ -130,6 +134,9 @@ func (productGroupService *ProductGroupService) GetProductGroup(getProductGroupQ | @@ -130,6 +134,9 @@ func (productGroupService *ProductGroupService) GetProductGroup(getProductGroupQ | ||
130 | if err := transactionContext.CommitTransaction(); err != nil { | 134 | if err := transactionContext.CommitTransaction(); err != nil { |
131 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 135 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
132 | } | 136 | } |
137 | + //if productGroup.GroupLeader==nil{ | ||
138 | + // productGroup.GroupLeader = &domain.User{} | ||
139 | + //} | ||
133 | return productGroup, nil | 140 | return productGroup, nil |
134 | } | 141 | } |
135 | 142 | ||
@@ -292,15 +299,19 @@ func (productGroupService *ProductGroupService) UpdateProductGroup(cmd *command. | @@ -292,15 +299,19 @@ func (productGroupService *ProductGroupService) UpdateProductGroup(cmd *command. | ||
292 | } | 299 | } |
293 | 300 | ||
294 | var leader *domain.User | 301 | var leader *domain.User |
295 | - var members []*domain.User | 302 | + var members = make([]*domain.User, 0) |
296 | userService := domainService.NewUserService() | 303 | userService := domainService.NewUserService() |
297 | - leader, err = userService.User(cmd.GroupLeaderId) | ||
298 | - if err != nil { | ||
299 | - return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 304 | + if cmd.GroupLeaderId > 0 { |
305 | + leader, err = userService.User(cmd.GroupLeaderId) | ||
306 | + if err != nil { | ||
307 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
308 | + } | ||
300 | } | 309 | } |
301 | - members, err = userService.Users(cmd.GroupMembers) | ||
302 | - if err != nil { | ||
303 | - return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 310 | + if len(cmd.GroupMembers) > 0 { |
311 | + members, err = userService.Users(cmd.GroupMembers) | ||
312 | + if err != nil { | ||
313 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
314 | + } | ||
304 | } | 315 | } |
305 | productGroup.GroupLeader = leader | 316 | productGroup.GroupLeader = leader |
306 | productGroup.GroupMembers = members | 317 | productGroup.GroupMembers = members |
@@ -384,9 +395,7 @@ func (productGroupService *ProductGroupService) SearchProductGroupEmployees(oper | @@ -384,9 +395,7 @@ func (productGroupService *ProductGroupService) SearchProductGroupEmployees(oper | ||
384 | transactionContext.RollbackTransaction() | 395 | transactionContext.RollbackTransaction() |
385 | }() | 396 | }() |
386 | 397 | ||
387 | - //workshops, _ := factory.FastPgWorkshops(transactionContext, operateInfo.CompanyId) | ||
388 | queryOptions := utils.ObjectToMap(cmd) | 398 | queryOptions := utils.ObjectToMap(cmd) |
389 | - //queryOptions = workshops.FindByNameWithQuery(queryOptions, cmd.WorkshopName, cmd.LineName, "") | ||
390 | 399 | ||
391 | var productGroupRepository domain.ProductGroupRepository | 400 | var productGroupRepository domain.ProductGroupRepository |
392 | productGroupRepository, _, _ = factory.FastPgProductGroup(transactionContext, 0) | 401 | productGroupRepository, _, _ = factory.FastPgProductGroup(transactionContext, 0) |
@@ -411,6 +420,86 @@ func (productGroupService *ProductGroupService) SearchProductGroupEmployees(oper | @@ -411,6 +420,86 @@ func (productGroupService *ProductGroupService) SearchProductGroupEmployees(oper | ||
411 | }, nil | 420 | }, nil |
412 | } | 421 | } |
413 | 422 | ||
423 | +// 返回在当前工段上打卡的所有用户 | ||
424 | +func (productGroupService *ProductGroupService) SearchProductGroupEmployeesV2(operateInfo *domain.OperateInfo, cmd *query.SearchProductGroupEmployeesQuery) (int64, interface{}, error) { | ||
425 | + if err := cmd.ValidateQuery(); err != nil { | ||
426 | + return 0, nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
427 | + } | ||
428 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
429 | + if err != nil { | ||
430 | + return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
431 | + } | ||
432 | + if err := transactionContext.StartTransaction(); err != nil { | ||
433 | + return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
434 | + } | ||
435 | + defer func() { | ||
436 | + transactionContext.RollbackTransaction() | ||
437 | + }() | ||
438 | + | ||
439 | + queryOptions := utils.ObjectToMap(cmd) | ||
440 | + queryOptions["signBeginTime"] = utils.GetZeroTime(time.Now()) | ||
441 | + var attendanceRecordRepository domain.ProductAttendanceRecordRepository | ||
442 | + attendanceRecordRepository, _, _ = factory.FastPgAttendance(transactionContext, 0) | ||
443 | + _, productGroups, err := attendanceRecordRepository.Find(queryOptions) | ||
444 | + if err != nil { | ||
445 | + return 0, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
446 | + } | ||
447 | + | ||
448 | + productGroupRepository, _, _ := factory.FastPgProductGroup(transactionContext, 0) | ||
449 | + mapUser, keyFunc := domainService.FindGroupMembers(productGroupRepository, cmd.CompanyId, cmd.OrgId, domain.WorkstationKey(cmd.WorkshopId, cmd.LineId, cmd.SectionId)) | ||
450 | + var results = dto.NewProductGroupEmployeesDtos() | ||
451 | + results.LoadDtoV2(productGroups, mapUser, keyFunc) | ||
452 | + sort.Stable(results) | ||
453 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
454 | + return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
455 | + } | ||
456 | + return int64(len(results.Result)), map[string]interface{}{ | ||
457 | + "employees": results.Result, | ||
458 | + }, nil | ||
459 | +} | ||
460 | + | ||
461 | +// 返回生产班组服务列表 | ||
462 | +func (productGroupService *ProductGroupService) GetSignEmployee(cmd *query.GetSignInEmployeeQuery) (interface{}, error) { | ||
463 | + if err := cmd.ValidateQuery(); err != nil { | ||
464 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
465 | + } | ||
466 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
467 | + if err != nil { | ||
468 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
469 | + } | ||
470 | + if err := transactionContext.StartTransaction(); err != nil { | ||
471 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
472 | + } | ||
473 | + defer func() { | ||
474 | + transactionContext.RollbackTransaction() | ||
475 | + }() | ||
476 | + | ||
477 | + var userService = domainService.NewUserService() | ||
478 | + | ||
479 | + worker, err := userService.UserByICCode(cmd.CompanyId, cmd.OrgId, cmd.IcCardNumber) | ||
480 | + if err != nil || worker == nil || worker.UserId == 0 { | ||
481 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "用户不存在") | ||
482 | + } | ||
483 | + result := map[string]interface{}{ | ||
484 | + "userId": worker.UserId, | ||
485 | + "userName": worker.UserName, | ||
486 | + } | ||
487 | + productGroupRepository, _, _ := factory.FastPgProductGroup(transactionContext, 0) | ||
488 | + mapUser, keyFunc := domainService.FindGroupMembers(productGroupRepository, cmd.CompanyId, cmd.OrgId, "") | ||
489 | + if v, ok := mapUser[keyFunc(worker.UserId)]; ok { | ||
490 | + result["productGroupId"] = v.GroupId | ||
491 | + result["groupName"] = v.GroupName | ||
492 | + result["workOn"] = domain.WorkOnDescriptions(v.WorkOn) | ||
493 | + } | ||
494 | + | ||
495 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
496 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
497 | + } | ||
498 | + return map[string]interface{}{ | ||
499 | + "employee": result, | ||
500 | + }, nil | ||
501 | +} | ||
502 | + | ||
414 | func NewProductGroupService(options map[string]interface{}) *ProductGroupService { | 503 | func NewProductGroupService(options map[string]interface{}) *ProductGroupService { |
415 | newProductGroupService := &ProductGroupService{} | 504 | newProductGroupService := &ProductGroupService{} |
416 | return newProductGroupService | 505 | return newProductGroupService |
@@ -338,8 +338,8 @@ func (productJobService *ProductJobService) SearchProductJob(operateInfo *domain | @@ -338,8 +338,8 @@ func (productJobService *ProductJobService) SearchProductJob(operateInfo *domain | ||
338 | 338 | ||
339 | newJobDto := &dto.ProductJobDto{} | 339 | newJobDto := &dto.ProductJobDto{} |
340 | newJobDto.LoadDto(item, operateInfo.OrgId) | 340 | newJobDto.LoadDto(item, operateInfo.OrgId) |
341 | - newJobDto.WorkStation = workshops.FindWorkStation(item.WorkStation.WorkshopId, item.WorkStation.LineId, item.WorkStation.SectionId) | ||
342 | - newJobDto.WorkStation.Principal = item.WorkStation.Principal | 341 | + newJobDto.WorkStation = workshops.FindWorkStation(item.WorkStation.WorkshopId, item.WorkStation.LineId, item.WorkStation.SectionId, 1) |
342 | + //newJobDto.WorkStation.Principal = item.WorkStation.Principal | ||
343 | result = append(result, newJobDto) | 343 | result = append(result, newJobDto) |
344 | } | 344 | } |
345 | return count, result, nil | 345 | return count, result, nil |
@@ -42,9 +42,11 @@ type CreateProductPlanCommand struct { | @@ -42,9 +42,11 @@ type CreateProductPlanCommand struct { | ||
42 | 42 | ||
43 | func (createProductPlanCommand *CreateProductPlanCommand) Valid(validation *validation.Validation) { | 43 | func (createProductPlanCommand *CreateProductPlanCommand) Valid(validation *validation.Validation) { |
44 | //validation.SetError("CustomValid", "未实现的自定义认证") | 44 | //validation.SetError("CustomValid", "未实现的自定义认证") |
45 | - if err := domain.ValidWorkOn(createProductPlanCommand.WorkOn); err != nil { | ||
46 | - validation.Error(err.Error()) | ||
47 | - return | 45 | + if createProductPlanCommand.WorkOn > 0 { |
46 | + if err := domain.ValidWorkOn(createProductPlanCommand.WorkOn); err != nil { | ||
47 | + validation.Error(err.Error()) | ||
48 | + return | ||
49 | + } | ||
48 | } | 50 | } |
49 | if t, err := time.Parse("2006-01-02", createProductPlanCommand.ProductDate); err != nil { | 51 | if t, err := time.Parse("2006-01-02", createProductPlanCommand.ProductDate); err != nil { |
50 | validation.Error("时间格式有误" + createProductPlanCommand.ProductDate) | 52 | validation.Error("时间格式有误" + createProductPlanCommand.ProductDate) |
@@ -22,7 +22,7 @@ type ReceiveMaterialCommand struct { | @@ -22,7 +22,7 @@ type ReceiveMaterialCommand struct { | ||
22 | // 工段ID | 22 | // 工段ID |
23 | SectionId int `cname:"工段" json:"sectionId" valid:"Required"` | 23 | SectionId int `cname:"工段" json:"sectionId" valid:"Required"` |
24 | // 生产小组ID | 24 | // 生产小组ID |
25 | - ProductGroupId int `cname:"生产小组" json:"productGroupId" valid:"Required"` | 25 | + ProductGroupId int `cname:"生产小组" json:"productGroupId"` |
26 | // 员工Id 用户唯一标识 | 26 | // 员工Id 用户唯一标识 |
27 | EmployeeId int `cname:"员工" json:"employeeId" valid:"Required"` | 27 | EmployeeId int `cname:"员工" json:"employeeId" valid:"Required"` |
28 | // 物料ID | 28 | // 物料ID |
@@ -22,7 +22,7 @@ type ReturnMaterialCommand struct { | @@ -22,7 +22,7 @@ type ReturnMaterialCommand struct { | ||
22 | // 工段ID | 22 | // 工段ID |
23 | SectionId int `cname:"工段" json:"sectionId" valid:"Required"` | 23 | SectionId int `cname:"工段" json:"sectionId" valid:"Required"` |
24 | // 生产小组ID | 24 | // 生产小组ID |
25 | - ProductGroupId int `cname:"生产小组" json:"productGroupId" valid:"Required"` | 25 | + ProductGroupId int `cname:"生产小组" json:"productGroupId"` |
26 | // 员工Id 用户唯一标识 | 26 | // 员工Id 用户唯一标识 |
27 | EmployeeId int `cname:"员工" json:"employeeId" valid:"Required"` | 27 | EmployeeId int `cname:"员工" json:"employeeId" valid:"Required"` |
28 | // 物料ID | 28 | // 物料ID |
@@ -12,7 +12,7 @@ type SetOnlineCommand struct { | @@ -12,7 +12,7 @@ type SetOnlineCommand struct { | ||
12 | // 生产计划ID | 12 | // 生产计划ID |
13 | ProductPlanId int `cname:"生产计划ID" json:"productPlanId" valid:"Required"` | 13 | ProductPlanId int `cname:"生产计划ID" json:"productPlanId" valid:"Required"` |
14 | // 车间ID | 14 | // 车间ID |
15 | - WorkshopId int `cname:"车间ID" json:"workshopId" valid:"Required"` | 15 | + WorkshopId int `cname:"车间ID" json:"workshopId" ` |
16 | // 生产线ID | 16 | // 生产线ID |
17 | LineId int `cname:"生产线ID" json:"lineId" valid:"Required"` | 17 | LineId int `cname:"生产线ID" json:"lineId" valid:"Required"` |
18 | // 工段ID | 18 | // 工段ID |
@@ -22,11 +22,11 @@ type SubmitProductRecordCommand struct { | @@ -22,11 +22,11 @@ type SubmitProductRecordCommand struct { | ||
22 | // 工段ID | 22 | // 工段ID |
23 | SectionId int `cname:"工段" json:"sectionId" valid:"Required"` | 23 | SectionId int `cname:"工段" json:"sectionId" valid:"Required"` |
24 | // 生产小组ID | 24 | // 生产小组ID |
25 | - ProductGroupId int `cname:"生产小组" json:"productGroupId" valid:"Required"` | 25 | + ProductGroupId int `cname:"生产小组" json:"productGroupId"` |
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 | } |
@@ -9,10 +9,10 @@ import ( | @@ -9,10 +9,10 @@ import ( | ||
9 | ) | 9 | ) |
10 | 10 | ||
11 | type SwitchCommand struct { | 11 | type SwitchCommand struct { |
12 | - // 下线计划调度ID | ||
13 | - FromProductPlanDispatchRecordId int `cname:"下线计划ID" json:"fromProductPlanId,omitempty"` | ||
14 | - // 上线计划ID | ||
15 | - ToProductPlanId int `cname:"上线计划ID" json:"toProductPlanId,omitempty"` | 12 | + // 已上线计划ID |
13 | + FromProductPlanDispatchRecordId int `cname:"已上线计划ID" json:"productPlanDispatchRecordId,omitempty" valid:"Required"` | ||
14 | + // 计划ID | ||
15 | + ToProductPlanId int `cname:"计划ID" json:"productPlanId,omitempty" valid:"Required"` | ||
16 | } | 16 | } |
17 | 17 | ||
18 | func (switchCommand *SwitchCommand) Valid(validation *validation.Validation) { | 18 | func (switchCommand *SwitchCommand) Valid(validation *validation.Validation) { |
@@ -47,9 +47,11 @@ type UpdateProductPlanCommand struct { | @@ -47,9 +47,11 @@ type UpdateProductPlanCommand struct { | ||
47 | } | 47 | } |
48 | 48 | ||
49 | func (updateProductPlanCommand *UpdateProductPlanCommand) Valid(validation *validation.Validation) { | 49 | func (updateProductPlanCommand *UpdateProductPlanCommand) Valid(validation *validation.Validation) { |
50 | - if err := domain.ValidWorkOn(updateProductPlanCommand.WorkOn); err != nil { | ||
51 | - validation.Error(err.Error()) | ||
52 | - return | 50 | + if updateProductPlanCommand.WorkOn > 0 { |
51 | + if err := domain.ValidWorkOn(updateProductPlanCommand.WorkOn); err != nil { | ||
52 | + validation.Error(err.Error()) | ||
53 | + return | ||
54 | + } | ||
53 | } | 55 | } |
54 | if t, err := time.Parse("2006-01-02", updateProductPlanCommand.ProductDate); err != nil { | 56 | if t, err := time.Parse("2006-01-02", updateProductPlanCommand.ProductDate); err != nil { |
55 | validation.Error("时间格式有误") | 57 | validation.Error("时间格式有误") |
@@ -7,7 +7,7 @@ import ( | @@ -7,7 +7,7 @@ import ( | ||
7 | 7 | ||
8 | type ProductPlanDispatchRecordDto struct { | 8 | type ProductPlanDispatchRecordDto struct { |
9 | // 生产计划ID | 9 | // 生产计划ID |
10 | - ProductPlanId int `json:"productPlanId,omitempty"` | 10 | + ProductPlanId int `json:"productPlanDispatchRecordId,omitempty"` |
11 | // 批号 | 11 | // 批号 |
12 | BatchNumber string `json:"batchNumber,omitempty"` | 12 | BatchNumber string `json:"batchNumber,omitempty"` |
13 | // 生产日期 | 13 | // 生产日期 |
@@ -42,7 +42,7 @@ type ProductPlanDispatchRecordDto struct { | @@ -42,7 +42,7 @@ type ProductPlanDispatchRecordDto struct { | ||
42 | func (d *ProductPlanDispatchRecordDto) LoadDto(m *domain.ProductPlanDispatchRecord, orgId int) *ProductPlanDispatchRecordDto { | 42 | func (d *ProductPlanDispatchRecordDto) LoadDto(m *domain.ProductPlanDispatchRecord, orgId int) *ProductPlanDispatchRecordDto { |
43 | d.ProductPlanId = m.ProductPlanDispatchRecordId | 43 | d.ProductPlanId = m.ProductPlanDispatchRecordId |
44 | d.BatchNumber = m.BatchNumber | 44 | d.BatchNumber = m.BatchNumber |
45 | - d.ProductDate = m.ProductDate.Format("2006/01/02") | 45 | + d.ProductDate = m.ProductDate.Local().Format("2006-01-02") |
46 | d.WorkStation = m.WorkStation | 46 | d.WorkStation = m.WorkStation |
47 | d.WorkOn = m.PlanDispatchRecordExt.WorkOn | 47 | d.WorkOn = m.PlanDispatchRecordExt.WorkOn |
48 | d.PlanProductName = m.PlanDispatchRecordExt.PlanProductName | 48 | d.PlanProductName = m.PlanDispatchRecordExt.PlanProductName |
@@ -28,6 +28,8 @@ type SearchProductPlanQuery struct { | @@ -28,6 +28,8 @@ type SearchProductPlanQuery struct { | ||
28 | BatchNumber string `cname:"批号" json:"batchNumber"` | 28 | BatchNumber string `cname:"批号" json:"batchNumber"` |
29 | // 车间名称 | 29 | // 车间名称 |
30 | WorkshopName string `cname:"车间名称" json:"workshopName"` | 30 | WorkshopName string `cname:"车间名称" json:"workshopName"` |
31 | + // 车间ID | ||
32 | + WorkshopId int `cname:"车间ID" json:"workshopId"` | ||
31 | } | 33 | } |
32 | 34 | ||
33 | func (cmd *SearchProductPlanQuery) Valid(validation *validation.Validation) { | 35 | func (cmd *SearchProductPlanQuery) Valid(validation *validation.Validation) { |
@@ -395,6 +395,7 @@ func (productPlanService *ProductPlanService) SetOnline(cmd *command.SetOnlineCo | @@ -395,6 +395,7 @@ func (productPlanService *ProductPlanService) SetOnline(cmd *command.SetOnlineCo | ||
395 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 395 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
396 | } | 396 | } |
397 | 397 | ||
398 | + cmd.WorkshopId = productPlan.Workshop.WorkshopId | ||
398 | var workStation *domain.WorkStation | 399 | var workStation *domain.WorkStation |
399 | _, workStation, err = factory.FastPgWorkstation(transactionContext, cmd.WorkshopId, cmd.LineId, cmd.SectionId) | 400 | _, workStation, err = factory.FastPgWorkstation(transactionContext, cmd.WorkshopId, cmd.LineId, cmd.SectionId) |
400 | if err != nil { | 401 | if err != nil { |
@@ -575,7 +576,9 @@ func (productPlanService *ProductPlanService) SearchProductPlanOnlineDispatchRec | @@ -575,7 +576,9 @@ func (productPlanService *ProductPlanService) SearchProductPlanOnlineDispatchRec | ||
575 | } else { | 576 | } else { |
576 | productPlanRepository = value | 577 | productPlanRepository = value |
577 | } | 578 | } |
578 | - count, productPlans, err := productPlanRepository.Find(utils.ObjectToMap(cmd)) | 579 | + queryOptions := utils.ObjectToMap(cmd) |
580 | + queryOptions["planDispatchStatus"] = 1 | ||
581 | + count, productPlans, err := productPlanRepository.Find(queryOptions) | ||
579 | if err != nil { | 582 | if err != nil { |
580 | return 0, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 583 | return 0, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
581 | } | 584 | } |
@@ -16,7 +16,7 @@ type ApproveProductRecordCommand struct { | @@ -16,7 +16,7 @@ type ApproveProductRecordCommand struct { | ||
16 | // 审核后重量 | 16 | // 审核后重量 |
17 | WeighAfter float64 `cname:"审核后重量" json:"weighAfter" valid:"Required"` | 17 | WeighAfter float64 `cname:"审核后重量" json:"weighAfter" valid:"Required"` |
18 | // 审核时间 | 18 | // 审核时间 |
19 | - ApproveAt string `cname:"审核时间" json:"approveAt" valid:"Required"` | 19 | + //ApproveAt string `cname:"审核时间" json:"approveAt" valid:"Required"` |
20 | } | 20 | } |
21 | 21 | ||
22 | func (approveProductRecordCommand *ApproveProductRecordCommand) Valid(validation *validation.Validation) { | 22 | func (approveProductRecordCommand *ApproveProductRecordCommand) Valid(validation *validation.Validation) { |
@@ -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 |
@@ -15,11 +15,13 @@ type ProductLevelTwoRecord struct { | @@ -15,11 +15,13 @@ type ProductLevelTwoRecord struct { | ||
15 | // 上班班次 1:全天 2:白班 4:中班 8:夜班 | 15 | // 上班班次 1:全天 2:白班 4:中班 8:夜班 |
16 | WorkOn int `json:"workOn"` | 16 | WorkOn int `json:"workOn"` |
17 | // 产能 - 审核前 | 17 | // 产能 - 审核前 |
18 | - WeighBefore float64 `json:"weighBefore"` | 18 | + WeighBefore float64 `json:"weightBefore"` |
19 | // 产能-审核后 | 19 | // 产能-审核后 |
20 | - WeighAfter float64 `json:"weighAfter"` | 20 | + WeighAfter float64 `json:"weightAfter"` |
21 | // 审核状态 1:未审核 2:已审核 | 21 | // 审核状态 1:未审核 2:已审核 |
22 | ApproveStatus int `json:"approveStatus"` | 22 | ApproveStatus int `json:"approveStatus"` |
23 | + // 审核人 | ||
24 | + ApproveUser *domain.User `json:"approveUser"` | ||
23 | // 审核时间 | 25 | // 审核时间 |
24 | ApproveAt string `json:"approveAt"` | 26 | ApproveAt string `json:"approveAt"` |
25 | // 计划的产品名称 | 27 | // 计划的产品名称 |
@@ -45,12 +47,13 @@ func (d *ProductLevelTwoRecord) LoadDto(m *domain.ProductRecord, orgId int) *Pro | @@ -45,12 +47,13 @@ func (d *ProductLevelTwoRecord) LoadDto(m *domain.ProductRecord, orgId int) *Pro | ||
45 | d.WeighAfter = m.ProductRecordInfo.WeighAfter | 47 | d.WeighAfter = m.ProductRecordInfo.WeighAfter |
46 | d.ApproveStatus = m.ProductRecordInfo.ApproveStatus | 48 | d.ApproveStatus = m.ProductRecordInfo.ApproveStatus |
47 | if m.ProductRecordInfo.ApproveAt > 0 { | 49 | if m.ProductRecordInfo.ApproveAt > 0 { |
48 | - d.ApproveAt = time.Unix(m.ProductRecordInfo.ApproveAt, 0).Format("2006-01-02 15:04:05") | 50 | + d.ApproveAt = time.Unix(m.ProductRecordInfo.ApproveAt, 0).Local().Format("2006-01-02 15:04:05") |
51 | + d.ApproveUser = m.ProductRecordInfo.ApproveUser | ||
49 | } | 52 | } |
50 | d.PlanProductName = m.ProductRecordInfo.PlanProductName | 53 | d.PlanProductName = m.ProductRecordInfo.PlanProductName |
51 | d.BatchNumber = m.ProductRecordInfo.BatchNumber | 54 | d.BatchNumber = m.ProductRecordInfo.BatchNumber |
52 | - d.CreatedDate = m.CreatedAt.Format("2006-01-02") | ||
53 | - d.CreatedAt = m.CreatedAt.Format("2006-01-02 15:04:05") | 55 | + d.CreatedDate = m.CreatedAt.Local().Format("2006-01-02") |
56 | + d.CreatedAt = m.CreatedAt.Local().Format("2006-01-02 15:04:05") | ||
54 | d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId) | 57 | d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId) |
55 | if m.Ext != nil { | 58 | if m.Ext != nil { |
56 | d.OrgName = m.Ext.OrgName | 59 | d.OrgName = m.Ext.OrgName |
1 | +package query | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "reflect" | ||
6 | + "strings" | ||
7 | + | ||
8 | + "github.com/beego/beego/v2/core/validation" | ||
9 | +) | ||
10 | + | ||
11 | +type CommonStatisticsQuery struct { | ||
12 | + Action string `cname:"查询类别" json:"actionType" valid:"Required"` | ||
13 | + QueryOptions map[string]interface{} `json:"queryOptions"` | ||
14 | +} | ||
15 | + | ||
16 | +func (checkUndertakerQuery *CommonStatisticsQuery) Valid(validation *validation.Validation) { | ||
17 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
18 | +} | ||
19 | + | ||
20 | +func (checkUndertakerQuery *CommonStatisticsQuery) ValidateQuery() error { | ||
21 | + valid := validation.Validation{} | ||
22 | + b, err := valid.Valid(checkUndertakerQuery) | ||
23 | + if err != nil { | ||
24 | + return err | ||
25 | + } | ||
26 | + if !b { | ||
27 | + elem := reflect.TypeOf(checkUndertakerQuery).Elem() | ||
28 | + for _, validErr := range valid.Errors { | ||
29 | + field, isExist := elem.FieldByName(validErr.Field) | ||
30 | + if isExist { | ||
31 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
32 | + } else { | ||
33 | + return fmt.Errorf(validErr.Message) | ||
34 | + } | ||
35 | + } | ||
36 | + } | ||
37 | + return nil | ||
38 | +} |
1 | +package service | ||
2 | + | ||
3 | +import ( | ||
4 | + "github.com/linmadan/egglib-go/core/application" | ||
5 | + "github.com/linmadan/egglib-go/transaction/pg" | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/statistics/query" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService" | ||
9 | +) | ||
10 | + | ||
11 | +// CommonStatisticsService 通用的统计服务 | ||
12 | +type CommonStatisticsService struct { | ||
13 | +} | ||
14 | + | ||
15 | +// CommonStatisticsService 通用的统计服务 | ||
16 | +func (svr *CommonStatisticsService) CommonStatisticsService(cmd *query.CommonStatisticsQuery) (interface{}, error) { | ||
17 | + if err := cmd.ValidateQuery(); err != nil { | ||
18 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
19 | + } | ||
20 | + var err error | ||
21 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
22 | + if err != nil { | ||
23 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
24 | + } | ||
25 | + if err := transactionContext.StartTransaction(); err != nil { | ||
26 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
27 | + } | ||
28 | + defer func() { | ||
29 | + _ = transactionContext.RollbackTransaction() | ||
30 | + }() | ||
31 | + | ||
32 | + statisticsService, _ := domainService.NewPGCommonStatisticsService(transactionContext.(*pg.TransactionContext)) | ||
33 | + response, err := statisticsService.CommonStatistics(cmd.Action, cmd.QueryOptions) | ||
34 | + if err != nil { | ||
35 | + return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error()) | ||
36 | + } | ||
37 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
38 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
39 | + } | ||
40 | + return response, nil | ||
41 | +} | ||
42 | + | ||
43 | +func NewCommonStatisticsService(options map[string]interface{}) *CommonStatisticsService { | ||
44 | + newProductSectionService := &CommonStatisticsService{} | ||
45 | + return newProductSectionService | ||
46 | +} |
1 | +package command | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
6 | + "reflect" | ||
7 | + "strings" | ||
8 | + | ||
9 | + "github.com/beego/beego/v2/core/validation" | ||
10 | +) | ||
11 | + | ||
12 | +type WorkshopDataConsumeCommand struct { | ||
13 | + *domain.DeviceCollection | ||
14 | + // 企业id | ||
15 | + CompanyId int `cname:"企业id" json:"companyId" valid:"Required"` | ||
16 | + // 组织ID | ||
17 | + OrgId int `cname:"组织ID" json:"orgId" valid:"Required"` | ||
18 | +} | ||
19 | + | ||
20 | +func (updateWorkshopCommand *WorkshopDataConsumeCommand) Valid(validation *validation.Validation) { | ||
21 | + | ||
22 | +} | ||
23 | + | ||
24 | +func (updateWorkshopCommand *WorkshopDataConsumeCommand) ValidateCommand() error { | ||
25 | + valid := validation.Validation{} | ||
26 | + b, err := valid.Valid(updateWorkshopCommand) | ||
27 | + if err != nil { | ||
28 | + return err | ||
29 | + } | ||
30 | + if !b { | ||
31 | + elem := reflect.TypeOf(updateWorkshopCommand).Elem() | ||
32 | + for _, validErr := range valid.Errors { | ||
33 | + field, isExist := elem.FieldByName(validErr.Field) | ||
34 | + if isExist { | ||
35 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
36 | + } else { | ||
37 | + return fmt.Errorf(validErr.Message) | ||
38 | + } | ||
39 | + } | ||
40 | + } | ||
41 | + return nil | ||
42 | +} |
@@ -98,6 +98,13 @@ func (workshopService *WorkshopService) GetWorkshop(getWorkshopQuery *query.GetW | @@ -98,6 +98,13 @@ func (workshopService *WorkshopService) GetWorkshop(getWorkshopQuery *query.GetW | ||
98 | if err != nil { | 98 | if err != nil { |
99 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 99 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
100 | } | 100 | } |
101 | + userService := domainService.NewUserService() | ||
102 | + if workshop.Principal.UserId > 0 { | ||
103 | + u, _ := userService.User(workshop.Principal.UserId) | ||
104 | + if u != nil { | ||
105 | + workshop.Principal = u | ||
106 | + } | ||
107 | + } | ||
101 | if workshop == nil { | 108 | if workshop == nil { |
102 | return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(getWorkshopQuery.WorkshopId))) | 109 | return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(getWorkshopQuery.WorkshopId))) |
103 | } else { | 110 | } else { |
1 | +package service | ||
2 | + | ||
3 | +import ( | ||
4 | + "github.com/linmadan/egglib-go/core/application" | ||
5 | + "github.com/linmadan/egglib-go/transaction/pg" | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/workshop/command" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" | ||
10 | +) | ||
11 | + | ||
12 | +func (workshopService *WorkshopService) WorkshopConsume(cmd *command.WorkshopDataConsumeCommand) (interface{}, error) { | ||
13 | + if err := cmd.ValidateCommand(); err != nil { | ||
14 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
15 | + } | ||
16 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
17 | + if err != nil { | ||
18 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
19 | + } | ||
20 | + if err := transactionContext.StartTransaction(); err != nil { | ||
21 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
22 | + } | ||
23 | + defer func() { | ||
24 | + transactionContext.RollbackTransaction() | ||
25 | + }() | ||
26 | + | ||
27 | + consumeService, _ := domainService.NewPGWorkshopDataConsumeService(transactionContext.(*pg.TransactionContext)) | ||
28 | + if _, err := consumeService.Consume(cmd.CompanyId, cmd.OrgId, cmd.DeviceCollection); err != nil { | ||
29 | + log.Logger.Error(err.Error()) | ||
30 | + return nil, err | ||
31 | + } | ||
32 | + | ||
33 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
34 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
35 | + } | ||
36 | + return struct{}{}, nil | ||
37 | +} |
@@ -3,6 +3,7 @@ package constant | @@ -3,6 +3,7 @@ package constant | ||
3 | import "os" | 3 | import "os" |
4 | 4 | ||
5 | var MQTT_TOPIC = "/MQTT" | 5 | var MQTT_TOPIC = "/MQTT" |
6 | + | ||
6 | //设备商提供的测试地址 | 7 | //设备商提供的测试地址 |
7 | //var MQTT_HOST = "175.24.122.87" | 8 | //var MQTT_HOST = "175.24.122.87" |
8 | //var MQTT_PORT = "1883" | 9 | //var MQTT_PORT = "1883" |
@@ -14,13 +15,23 @@ var MQTT_TOPIC = "/MQTT" | @@ -14,13 +15,23 @@ var MQTT_TOPIC = "/MQTT" | ||
14 | //var MQTT_USER = "admin" | 15 | //var MQTT_USER = "admin" |
15 | //var MQTT_PASSWORD = "123456" | 16 | //var MQTT_PASSWORD = "123456" |
16 | 17 | ||
17 | -var MQTT_HOST = "192.168.31.51" | 18 | +//var MQTT_HOST = "192.168.31.51" |
19 | +//var MQTT_PORT = "1883" | ||
20 | +//var MQTT_USER = "" | ||
21 | +//var MQTT_PASSWORD = "" | ||
22 | + | ||
23 | +var MQTT_HOST = "175.24.122.87" | ||
18 | var MQTT_PORT = "1883" | 24 | var MQTT_PORT = "1883" |
19 | -var MQTT_USER = "" | ||
20 | -var MQTT_PASSWORD = "" | 25 | +var MQTT_USER = "user111" |
26 | +var MQTT_PASSWORD = "user111" | ||
21 | 27 | ||
28 | +//内网测试地址 | ||
29 | +//var MQTT_HOST = "192.168.100.222" | ||
30 | +//var MQTT_PORT = "1883" | ||
31 | +//var MQTT_USER = "admin" | ||
32 | +//var MQTT_PASSWORD = "123456" | ||
22 | 33 | ||
23 | -func init(){ | 34 | +func init() { |
24 | if os.Getenv("MQTT_HOST") != "" { | 35 | if os.Getenv("MQTT_HOST") != "" { |
25 | MQTT_HOST = os.Getenv("MQTT_HOST") | 36 | MQTT_HOST = os.Getenv("MQTT_HOST") |
26 | } | 37 | } |
@@ -33,4 +44,4 @@ func init(){ | @@ -33,4 +44,4 @@ func init(){ | ||
33 | if os.Getenv("MQTT_PASSWORD") != "" { | 44 | if os.Getenv("MQTT_PASSWORD") != "" { |
34 | MQTT_PASSWORD = os.Getenv("MQTT_PASSWORD") | 45 | MQTT_PASSWORD = os.Getenv("MQTT_PASSWORD") |
35 | } | 46 | } |
36 | -} | ||
47 | +} |
@@ -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 | +} |
1 | package domain | 1 | package domain |
2 | 2 | ||
3 | -import "time" | 3 | +import ( |
4 | + "fmt" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" | ||
6 | + "time" | ||
7 | +) | ||
4 | 8 | ||
5 | // 设备采集数据 | 9 | // 设备采集数据 |
6 | type DeviceCollection struct { | 10 | type DeviceCollection struct { |
@@ -79,3 +83,7 @@ func (deviceCollection *DeviceCollection) Update(data map[string]interface{}) er | @@ -79,3 +83,7 @@ func (deviceCollection *DeviceCollection) Update(data map[string]interface{}) er | ||
79 | } | 83 | } |
80 | return nil | 84 | return nil |
81 | } | 85 | } |
86 | + | ||
87 | +func TaskDeviceCollection() string { | ||
88 | + return fmt.Sprintf("%v:task:device-collection:report", constant.CACHE_PREFIX) | ||
89 | +} |
@@ -2,49 +2,49 @@ package domain | @@ -2,49 +2,49 @@ package domain | ||
2 | 2 | ||
3 | // 包馅机 | 3 | // 包馅机 |
4 | type DeviceBaoXianJi struct { | 4 | type DeviceBaoXianJi struct { |
5 | - InterSpeed int64 `json:"InterSpeed"` // 内包材速度:内包材运行速率 | ||
6 | - ExterSpeed int64 `json:"ExterSpeed"` // 外包材速度:内包材运行速率 | ||
7 | - KnifeSpeed int64 `json:"KnifeSpeed"` // 切刀速度:切刀运行速率 | ||
8 | - TransSpeed int64 `json:"TransSpeed"` // 输送速度:输送带运行速率 | ||
9 | - Count int64 `json:"Count"` // 生产计数:生产统计数量 | 5 | + InterSpeed int64 `json:"InterSpeed"` // 内包材速度:内包材运行速率 |
6 | + ExterSpeed int64 `json:"ExterSpeed"` // 外包材速度:内包材运行速率 | ||
7 | + KnifeSpeed int64 `json:"KnifeSpeed"` // 切刀速度:切刀运行速率 | ||
8 | + TransSpeed int64 `json:"TransSpeed"` // 输送速度:输送带运行速率 | ||
9 | + Count int64 `json:"Count"` // 生产计数:生产统计数量 | ||
10 | } | 10 | } |
11 | 11 | ||
12 | // 油炸机 | 12 | // 油炸机 |
13 | type DeviceYouZhaJi struct { | 13 | type DeviceYouZhaJi struct { |
14 | - FrontTemp float64 `json:"FontTemp"` // 炸机前段温度:炸机前段当前温度 | ||
15 | - BackTemp float64 `json:"BackTemp"` // 炸机后段温度:炸机后段当前温度 | ||
16 | - TankTemp float64 `json:"TankTemp"` // 储油罐温度 :储油罐当前温度 | ||
17 | - TubeTemp float64 `json:"TubeTemp"` // 管路温度:管路当前温度 | 14 | + FrontTemp float64 `json:"FontTemp"` // 炸机前段温度:炸机前段当前温度 |
15 | + BackTemp float64 `json:"BackTemp"` // 炸机后段温度:炸机后段当前温度 | ||
16 | + TankTemp float64 `json:"TankTemp"` // 储油罐温度 :储油罐当前温度 | ||
17 | + TubeTemp float64 `json:"TubeTemp"` // 管路温度:管路当前温度 | ||
18 | } | 18 | } |
19 | 19 | ||
20 | // 串串机 | 20 | // 串串机 |
21 | type DeviceChuanChuanJi struct { | 21 | type DeviceChuanChuanJi struct { |
22 | - Count int64 `json:"Count"` // 生产计数:生产统计数量 | ||
23 | - Year string `json:"Year"` // 年 | ||
24 | - Month string `json:"Month"` // 月 | ||
25 | - Day string `json:"Day"` // 日 | ||
26 | - ProductType string `json:"ProductType"` // 产品类型:当前产品种类 | 22 | + Count int64 `json:"Count"` // 生产计数:生产统计数量 |
23 | + Year string `json:"Year"` // 年 | ||
24 | + Month string `json:"Month"` // 月 | ||
25 | + Day string `json:"Day"` // 日 | ||
26 | + ProductType string `json:"ProductType"` // 产品类型:当前产品种类 | ||
27 | } | 27 | } |
28 | 28 | ||
29 | // 速冻线 | 29 | // 速冻线 |
30 | type DeviceSuDongXian struct { | 30 | type DeviceSuDongXian struct { |
31 | - CurrTemp float64 `json:"CurrTemp"` // 当前温度:当前温度 | 31 | + CurrTemp float64 `json:"CurrTemp"` // 当前温度:当前温度 |
32 | } | 32 | } |
33 | 33 | ||
34 | // 封口机 | 34 | // 封口机 |
35 | type DeviceFengKouJi struct { | 35 | type DeviceFengKouJi struct { |
36 | - Count int64 `json:"Count"` // 生产计数:生产统计数量 | ||
37 | - Year string `json:"Year"` // 年 | ||
38 | - Month string `json:"Month"` // 月 | ||
39 | - Day string `json:"Day"` // 日 | ||
40 | - ProductType string `json:"ProductType"` // 产品类型:当前产品种类 | 36 | + Count int64 `json:"Count"` // 生产计数:生产统计数量 |
37 | + Year string `json:"Year"` // 年 | ||
38 | + Month string `json:"Month"` // 月 | ||
39 | + Day string `json:"Day"` // 日 | ||
40 | + ProductType string `json:"ProductType"` // 产品类型:当前产品种类 | ||
41 | } | 41 | } |
42 | 42 | ||
43 | // 封箱机 | 43 | // 封箱机 |
44 | type DeviceFengXiangJi struct { | 44 | type DeviceFengXiangJi struct { |
45 | - Count int64 `json:"Count"` // 生产计数:生产统计数量 | ||
46 | - Year string `json:"Year"` // 年 | ||
47 | - Month string `json:"Month"` // 月 | ||
48 | - Day string `json:"Day"` // 日 | ||
49 | - ProductType string `json:"ProductType"` // 产品类型:当前产品种类 | ||
50 | -} | ||
45 | + Count int64 `json:"Count"` // 生产计数:生产统计数量 | ||
46 | + Year string `json:"Year"` // 年 | ||
47 | + Month string `json:"Month"` // 月 | ||
48 | + Day string `json:"Day"` // 日 | ||
49 | + ProductType string `json:"ProductType"` // 产品类型:当前产品种类 | ||
50 | +} |
pkg/domain/device_daily_running_record.go
0 → 100644
1 | +package domain | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" | ||
6 | + "time" | ||
7 | +) | ||
8 | + | ||
9 | +const DefaultTimeWindow = 1 | ||
10 | + | ||
11 | +// 设备每日运行记录(汇总) | ||
12 | +type DeviceDailyRunningRecord struct { | ||
13 | + // 设备每日运行记录ID | ||
14 | + DeviceDailyRunningRecordId int `json:"deviceDailyRunningRecordId"` | ||
15 | + // 企业id | ||
16 | + CompanyId int `json:"companyId"` | ||
17 | + // 组织ID | ||
18 | + OrgId int `json:"orgId"` | ||
19 | + // 工作位置 | ||
20 | + WorkStation *WorkStation `json:"workStation"` | ||
21 | + // 设备Id | ||
22 | + DeviceId int `json:"deviceId"` | ||
23 | + // 设备编号 | ||
24 | + DeviceCode string `json:"deviceCode"` | ||
25 | + // 生产日期 | ||
26 | + ProductDate time.Time `json:"productDate"` | ||
27 | + // 设备运行记录信息 | ||
28 | + DeviceRunningRecordInfo *DeviceRunningRecordInfo `json:"deviceRunningRecordInfo"` | ||
29 | + // 创建时间 | ||
30 | + CreatedAt time.Time `json:"createdAt"` | ||
31 | + // 更新时间 | ||
32 | + UpdatedAt time.Time `json:"updatedAt"` | ||
33 | + // 删除时间 | ||
34 | + DeletedAt time.Time `json:"deletedAt"` | ||
35 | +} | ||
36 | + | ||
37 | +type DeviceDailyRunningRecordRepository interface { | ||
38 | + Save(deviceDailyRunningRecord *DeviceDailyRunningRecord) (*DeviceDailyRunningRecord, error) | ||
39 | + Remove(deviceDailyRunningRecord *DeviceDailyRunningRecord) (*DeviceDailyRunningRecord, error) | ||
40 | + FindOne(queryOptions map[string]interface{}) (*DeviceDailyRunningRecord, error) | ||
41 | + Find(queryOptions map[string]interface{}) (int64, []*DeviceDailyRunningRecord, error) | ||
42 | +} | ||
43 | + | ||
44 | +func (deviceDailyRunningRecord *DeviceDailyRunningRecord) Identify() interface{} { | ||
45 | + if deviceDailyRunningRecord.DeviceDailyRunningRecordId == 0 { | ||
46 | + return nil | ||
47 | + } | ||
48 | + return deviceDailyRunningRecord.DeviceDailyRunningRecordId | ||
49 | +} | ||
50 | + | ||
51 | +func (deviceDailyRunningRecord *DeviceDailyRunningRecord) Update(data map[string]interface{}) error { | ||
52 | + return nil | ||
53 | +} | ||
54 | + | ||
55 | +func (deviceDailyRunningRecord *DeviceDailyRunningRecord) AddDeviceRunningData(t time.Time, data *DeviceRunningData) { | ||
56 | + deviceDailyRunningRecord.DeviceRunningRecordInfo.AddDeviceRunningData(t, data) | ||
57 | + deviceDailyRunningRecord.UpdatedAt = time.Now() | ||
58 | +} | ||
59 | + | ||
60 | +func (deviceDailyRunningRecord *DeviceDailyRunningRecord) String() string { | ||
61 | + return fmt.Sprintf("记录ID:%v 工段:%v 设备:%v", | ||
62 | + deviceDailyRunningRecord.DeviceDailyRunningRecordId, | ||
63 | + deviceDailyRunningRecord.WorkStation.SectionName, | ||
64 | + deviceDailyRunningRecord.DeviceCode, | ||
65 | + ) | ||
66 | +} | ||
67 | + | ||
68 | +// 设备运行记录信息 | ||
69 | +type DeviceRunningRecordInfo struct { | ||
70 | + // 当前状态 | ||
71 | + // bit0: 运行、停止 | ||
72 | + // bit1: 正常、故障 | ||
73 | + CurrentStatus int `json:"currentStatus"` | ||
74 | + // 设备OEE = tu * pu * qu | ||
75 | + OEE float64 `json:"oee"` | ||
76 | + // 时间利用率 TimeUtilization 运行时间 / (当前时间-当日零时) | ||
77 | + TimeUtilization float64 `json:"tu"` | ||
78 | + // 性能利用率 PerformanceUtilization | ||
79 | + // 1. 当前设备实际产出数量/理论数量(理论数量=60*60*12/标准工时) | ||
80 | + // 2. 没有数量100% | ||
81 | + PerformanceUtilization float64 `json:"pu"` | ||
82 | + // 合格率 QualificationUtilization ?设备提交的二级品事串 、 机器上报的是kg | ||
83 | + // 1.按工段的合格率 | ||
84 | + // 2.默认100% | ||
85 | + QualificationUtilization float64 `json:"qu"` | ||
86 | + // 运行时长 单位:分钟 | ||
87 | + UpTime float64 `json:"upTime"` | ||
88 | + // 生成数量 | ||
89 | + Count int `json:"count"` | ||
90 | + // 设备温度 单位:摄氏度 | ||
91 | + Temp float64 `json:"temp"` | ||
92 | + | ||
93 | + // 时间点 | ||
94 | + //TimeLine []string `json:"timeLine"` | ||
95 | + // 时间点对应的设备状态 按小时 1 | ||
96 | + TimeLineDeviceStatus map[string]*HourDeviceStatus `json:"timeLineDeviceStatus"` | ||
97 | + | ||
98 | + // 批次数据 | ||
99 | + // 生产计划ID | ||
100 | + ProductPlanId int `json:"productPlanId,omitempty"` | ||
101 | + | ||
102 | + // 设备名称 | ||
103 | + DeviceName string `json:"deviceName"` | ||
104 | + // 组织名称 | ||
105 | + OrgName string `json:"orgName"` | ||
106 | +} | ||
107 | + | ||
108 | +func NewDeviceRunningRecordInfo() *DeviceRunningRecordInfo { | ||
109 | + return &DeviceRunningRecordInfo{ | ||
110 | + TimeLineDeviceStatus: make(map[string]*HourDeviceStatus), | ||
111 | + } | ||
112 | +} | ||
113 | +func (d *DeviceRunningRecordInfo) AddDeviceRunningData(t time.Time, data *DeviceRunningData) { | ||
114 | + d.CurrentStatus = data.StartupStatus | (1 << data.ComStatus) | ||
115 | + d.ResetUpTime() | ||
116 | + d.Count += data.Count | ||
117 | + //d.Temp = data.FrontTemp | ||
118 | + | ||
119 | + d.Temp = data.Temp1 | ||
120 | + d.AddTimeLineDeviceStatus(t, data) | ||
121 | + | ||
122 | + //d.OEE | ||
123 | + d.TimeUtilization = utils.Round(d.UpTime*100/(time.Now().Sub(utils.GetZeroTime(time.Now())).Minutes()), 2) | ||
124 | + //d.PerformanceUtilization | ||
125 | + //d.QualificationUtilization | ||
126 | +} | ||
127 | + | ||
128 | +// 添加新的设备状态 | ||
129 | +func (d *DeviceRunningRecordInfo) AddTimeLineDeviceStatus(t time.Time, data *DeviceRunningData) { | ||
130 | + if t.IsZero() { | ||
131 | + return | ||
132 | + } | ||
133 | + key := fmt.Sprintf("%v", t.Hour()) | ||
134 | + var v *HourDeviceStatus | ||
135 | + var ok bool | ||
136 | + if v, ok = d.TimeLineDeviceStatus[key]; !ok { | ||
137 | + v = NewHourDeviceStatus() | ||
138 | + d.TimeLineDeviceStatus[key] = v | ||
139 | + } | ||
140 | + v.UpdateUp(t, data.StartupStatus) | ||
141 | + v.UpdateCom(t, data.ComStatus) | ||
142 | +} | ||
143 | + | ||
144 | +// 重置运行时长 | ||
145 | +func (d *DeviceRunningRecordInfo) ResetUpTime() float64 { | ||
146 | + var upTime float64 | ||
147 | + for _, v := range d.TimeLineDeviceStatus { | ||
148 | + t := v.CountTime(v.Up) | ||
149 | + upTime += t.Minutes() | ||
150 | + } | ||
151 | + d.UpTime = upTime | ||
152 | + return upTime | ||
153 | +} | ||
154 | + | ||
155 | +// 重置设备运行OEE | ||
156 | +func (d *DeviceRunningRecordInfo) ResetOEE(pu, qu float64) float64 { | ||
157 | + d.PerformanceUtilization = pu | ||
158 | + d.QualificationUtilization = qu | ||
159 | + d.OEE = (d.TimeUtilization + d.PerformanceUtilization + d.QualificationUtilization) / 3 | ||
160 | + return d.OEE | ||
161 | +} | ||
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(endTime int) map[string]interface{} { | ||
170 | + on := make([][]int, 0) | ||
171 | + off := make([][]int, 0) | ||
172 | + err := make([][]int, 0) | ||
173 | + var begin, end int = 0, 0 | ||
174 | + /* | ||
175 | + 1.故障: 1 0 \ 0 0 | ||
176 | + 2.正常: 1 1 | ||
177 | + 3.停机:0 1 | ||
178 | + */ | ||
179 | + var status = 1 | ||
180 | + // 添加数据 | ||
181 | + addToStatus := func(s []int, status int) { | ||
182 | + switch status { | ||
183 | + case 1: | ||
184 | + err = append(err, s) | ||
185 | + break | ||
186 | + case 2: | ||
187 | + on = append(on, s) | ||
188 | + break | ||
189 | + case 3: | ||
190 | + off = append(off, s) | ||
191 | + break | ||
192 | + } | ||
193 | + } | ||
194 | + // 计算当前状态 | ||
195 | + computeStatus := func(up, com int, index int) int { | ||
196 | + var val = 0 | ||
197 | + if up&index > 0 { | ||
198 | + val |= 1 | ||
199 | + } | ||
200 | + if com&index > 0 { | ||
201 | + val |= 2 | ||
202 | + } | ||
203 | + if val == 1 || val == 0 { | ||
204 | + return 1 //故障 | ||
205 | + } | ||
206 | + if val == 3 { | ||
207 | + return 2 //正常 | ||
208 | + } | ||
209 | + if val == 2 { | ||
210 | + return 3 //停机 | ||
211 | + } | ||
212 | + return 3 // 停机 | ||
213 | + } | ||
214 | + | ||
215 | + for i := 0; i < 24; i++ { | ||
216 | + var index = 1 | ||
217 | + var hds *HourDeviceStatus | ||
218 | + var ok bool | ||
219 | + if hds, ok = d.TimeLineDeviceStatus[fmt.Sprintf("%v", i)]; !ok { | ||
220 | + hds = &HourDeviceStatus{Window: DefaultTimeWindow} | ||
221 | + } | ||
222 | + if i == 0 { | ||
223 | + status = computeStatus(hds.Up, hds.Com, index) // 状态初始化 | ||
224 | + } | ||
225 | + if end >= endTime { | ||
226 | + break | ||
227 | + } | ||
228 | + if hds.Up == 0 && hds.Com == 0 { | ||
229 | + end += 60 / hds.Window | ||
230 | + continue | ||
231 | + } | ||
232 | + for j := 1; j < 60; j++ { | ||
233 | + curStatus := computeStatus(hds.Up, hds.Com, index) | ||
234 | + if curStatus == status { | ||
235 | + end += 1 | ||
236 | + } else { | ||
237 | + addToStatus([]int{begin, end}, status) | ||
238 | + status = curStatus | ||
239 | + begin = end + 1 | ||
240 | + end = begin | ||
241 | + } | ||
242 | + index = index << 1 | ||
243 | + } | ||
244 | + } | ||
245 | + addToStatus([]int{begin, end}, status) | ||
246 | + return map[string]interface{}{ | ||
247 | + "on": on, | ||
248 | + "off": off, | ||
249 | + "err": err, | ||
250 | + } | ||
251 | +} | ||
252 | + | ||
253 | +// 单个小时内的设备状态 | ||
254 | +type HourDeviceStatus struct { | ||
255 | + // 时间窗口 1-60 代表时间段范围 | ||
256 | + // 例如: w=1 则标识下面的状态按1分钟记录一次状态 | ||
257 | + // up 启动 bit0-bit59的位用来存启动状态 1:启动 0:关闭 | ||
258 | + // com通讯 bit0-bit59的位用来存通讯状态 1:正常 0:故障 | ||
259 | + // 如果 w=5 表示按5分钟记录一次状态 使用到 bit0-bit11 | ||
260 | + Window int `json:"w"` | ||
261 | + // 启动 | ||
262 | + // bit0:1 代表 | ||
263 | + Up int `json:"up"` | ||
264 | + // 通讯 | ||
265 | + Com int `json:"com"` | ||
266 | +} | ||
267 | + | ||
268 | +// 更新启动状态 | ||
269 | +func (d *HourDeviceStatus) UpdateUp(t time.Time, up int) { | ||
270 | + m := t.Minute() | ||
271 | + bit := 1 << (m / d.Window) | ||
272 | + if up&1 == 0 { | ||
273 | + return | ||
274 | + } | ||
275 | + if d.Up&bit > 0 { | ||
276 | + return | ||
277 | + } | ||
278 | + d.Up |= bit | ||
279 | + return | ||
280 | +} | ||
281 | + | ||
282 | +// 更新通讯状态 | ||
283 | +func (d *HourDeviceStatus) UpdateCom(t time.Time, c int) { | ||
284 | + m := t.Minute() | ||
285 | + bit := 1 << (m / d.Window) | ||
286 | + if c&1 == 0 { | ||
287 | + return | ||
288 | + } | ||
289 | + if d.Com&bit > 0 { | ||
290 | + return | ||
291 | + } | ||
292 | + d.Com |= bit | ||
293 | + return | ||
294 | +} | ||
295 | + | ||
296 | +// 计算状态持续的时间 | ||
297 | +func (d *HourDeviceStatus) CountTime(v int) time.Duration { | ||
298 | + l := 60 / d.Window | ||
299 | + count := 0 | ||
300 | + index := 1 | ||
301 | + for i := 0; i < l; i++ { | ||
302 | + if index > v { | ||
303 | + break | ||
304 | + } | ||
305 | + if index&v > 0 { | ||
306 | + count++ | ||
307 | + } | ||
308 | + index <<= 1 | ||
309 | + } | ||
310 | + return time.Duration(d.Window*count) * time.Minute | ||
311 | +} | ||
312 | + | ||
313 | +func NewHourDeviceStatus() *HourDeviceStatus { | ||
314 | + return &HourDeviceStatus{ | ||
315 | + Window: DefaultTimeWindow, | ||
316 | + Up: 0, | ||
317 | + Com: 0, | ||
318 | + } | ||
319 | +} |
@@ -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 | } |
pkg/domain/device_running_data.go
0 → 100644
1 | +package domain | ||
2 | + | ||
3 | +import "time" | ||
4 | + | ||
5 | +// 设备运行数据 | ||
6 | +type DeviceRunningData struct { | ||
7 | + // 数据采集ID | ||
8 | + DeviceCollectionId int64 `json:"deviceCollectionId,string"` | ||
9 | + // 车间名 | ||
10 | + WorkShopName string `json:"workShopName"` | ||
11 | + // 采集时间 | ||
12 | + CollectionTime time.Time `json:"collectionTime"` | ||
13 | + // 设备名 | ||
14 | + //DeviceSn string `json:"deviceSn"` | ||
15 | + // 设备编号 | ||
16 | + DeviceCode string `json:"deviceCode"` | ||
17 | + // 设备类型 | ||
18 | + DeviceType string `json:"deviceType"` | ||
19 | + // 启动状态:1:启动,0:停止 | ||
20 | + StartupStatus int `json:"startupStatus"` | ||
21 | + // 通讯状态:1:通讯正常,0:设备未上电或与采集端通讯故障 | ||
22 | + ComStatus int `json:"comStatus"` | ||
23 | + | ||
24 | + // 附加数据 | ||
25 | + // 匹配数目 | ||
26 | + Count int `json:"count"` | ||
27 | + // 炸机前段温度:炸机前段当前温度 YZJ1 油炸机 | ||
28 | + //FrontTemp float64 `json:"frontTemp"` | ||
29 | + // 炸机前段温度:炸机前段当前温度 YZJ2 油炸机 | ||
30 | + Temp1 float64 `json:"temp1"` | ||
31 | + // 当前产品种类(产品编号) | ||
32 | + ProductType string `json:"productType"` | ||
33 | + // 日期 | ||
34 | + Date string `json:"date"` | ||
35 | + | ||
36 | + // 额外数据 | ||
37 | + // 单位数据 比如:1串/0.1kg weight = count * unitQuantity | ||
38 | + UnitQuantity float64 `json:"unitQuantity"` | ||
39 | +} |
pkg/domain/device_running_record.go
0 → 100644
1 | +package domain | ||
2 | + | ||
3 | +import "time" | ||
4 | + | ||
5 | +// 设备运行记录 | ||
6 | +type DeviceRunningRecord struct { | ||
7 | + // 设备运行记录ID | ||
8 | + DeviceRunningRecordId int `json:"deviceRunningRecordId"` | ||
9 | + // 企业id | ||
10 | + CompanyId int `json:"companyId"` | ||
11 | + // 组织ID | ||
12 | + OrgId int `json:"orgId"` | ||
13 | + // 工作位置 | ||
14 | + WorkStation *WorkStation `json:"workStation"` | ||
15 | + // 设备Id | ||
16 | + DeviceId int `json:"deviceId"` | ||
17 | + // 设备编号 | ||
18 | + DeviceCode string `json:"deviceCode"` | ||
19 | + // 设备运行记录信息 | ||
20 | + DeviceRunningRecordInfo *DeviceRunningData `json:"deviceRunningRecordInfo"` | ||
21 | + // 创建时间 | ||
22 | + CreatedAt time.Time `json:"createdAt"` | ||
23 | +} | ||
24 | + | ||
25 | +type DeviceRunningRecordRepository interface { | ||
26 | + Save(deviceRunningRecord *DeviceRunningRecord) (*DeviceRunningRecord, error) | ||
27 | + Remove(deviceRunningRecord *DeviceRunningRecord) (*DeviceRunningRecord, error) | ||
28 | + FindOne(queryOptions map[string]interface{}) (*DeviceRunningRecord, error) | ||
29 | + Find(queryOptions map[string]interface{}) (int64, []*DeviceRunningRecord, error) | ||
30 | +} | ||
31 | + | ||
32 | +func (deviceRunningRecord *DeviceRunningRecord) Identify() interface{} { | ||
33 | + if deviceRunningRecord.DeviceRunningRecordId == 0 { | ||
34 | + return nil | ||
35 | + } | ||
36 | + return deviceRunningRecord.DeviceRunningRecordId | ||
37 | +} | ||
38 | + | ||
39 | +func (deviceRunningRecord *DeviceRunningRecord) Update(data map[string]interface{}) error { | ||
40 | + return nil | ||
41 | +} |
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 "固定" |
@@ -2,6 +2,7 @@ package domain | @@ -2,6 +2,7 @@ package domain | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "errors" | 4 | "errors" |
5 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" | ||
5 | "time" | 6 | "time" |
6 | ) | 7 | ) |
7 | 8 | ||
@@ -74,7 +75,7 @@ func (productAttendanceRecord *ProductAttendanceRecord) ComputeWorkTimeBefore() | @@ -74,7 +75,7 @@ func (productAttendanceRecord *ProductAttendanceRecord) ComputeWorkTimeBefore() | ||
74 | if !productAttendanceRecord.SignOut.After(productAttendanceRecord.SignIn) { | 75 | if !productAttendanceRecord.SignOut.After(productAttendanceRecord.SignIn) { |
75 | return 0 | 76 | return 0 |
76 | } | 77 | } |
77 | - return productAttendanceRecord.SignOut.Sub(productAttendanceRecord.SignIn).Hours() | 78 | + return utils.Round(productAttendanceRecord.SignOut.Sub(productAttendanceRecord.SignIn).Hours(), 1) |
78 | } | 79 | } |
79 | 80 | ||
80 | func (productAttendanceRecord *ProductAttendanceRecord) Approve(approveUser *User, workTimeAfter float64, status int) error { | 81 | func (productAttendanceRecord *ProductAttendanceRecord) Approve(approveUser *User, workTimeAfter float64, status int) error { |
@@ -83,7 +84,10 @@ func (productAttendanceRecord *ProductAttendanceRecord) Approve(approveUser *Use | @@ -83,7 +84,10 @@ func (productAttendanceRecord *ProductAttendanceRecord) Approve(approveUser *Use | ||
83 | } | 84 | } |
84 | productAttendanceRecord.AttendanceStatus = status | 85 | productAttendanceRecord.AttendanceStatus = status |
85 | productAttendanceRecord.WorkTimeAfter = workTimeAfter | 86 | productAttendanceRecord.WorkTimeAfter = workTimeAfter |
86 | - if productAttendanceRecord.Ext != nil && productAttendanceRecord.Ext.AttendanceExt != nil { | 87 | + if productAttendanceRecord.Ext != nil { |
88 | + if productAttendanceRecord.Ext.AttendanceExt == nil { | ||
89 | + productAttendanceRecord.Ext.AttendanceExt = &ProductAttendanceRecordExt{} | ||
90 | + } | ||
87 | productAttendanceRecord.Ext.AttendanceExt.ApproveUserId = approveUser.UserId | 91 | productAttendanceRecord.Ext.AttendanceExt.ApproveUserId = approveUser.UserId |
88 | productAttendanceRecord.Ext.AttendanceExt.ApproveUserName = approveUser.UserName | 92 | productAttendanceRecord.Ext.AttendanceExt.ApproveUserName = approveUser.UserName |
89 | productAttendanceRecord.Ext.AttendanceExt.ApproveAt = time.Now().Unix() | 93 | productAttendanceRecord.Ext.AttendanceExt.ApproveAt = time.Now().Unix() |
@@ -39,6 +39,8 @@ type PlanDispatchRecordExt struct { | @@ -39,6 +39,8 @@ type PlanDispatchRecordExt struct { | ||
39 | ProductPlanId int `json:"productPlanId,omitempty"` | 39 | ProductPlanId int `json:"productPlanId,omitempty"` |
40 | // 计划的产品名称 | 40 | // 计划的产品名称 |
41 | PlanProductName string `json:"planProductName,omitempty"` | 41 | PlanProductName string `json:"planProductName,omitempty"` |
42 | + // 产品编号 编码规则为“CP”+2 位年+2 位月+2 位日+3 位流水码,如 CP211229001 | ||
43 | + ProductCode string `json:"productCode,omitempty"` | ||
42 | // 上班班次 1:全天 2:白班 4:中班 8:夜班 | 44 | // 上班班次 1:全天 2:白班 4:中班 8:夜班 |
43 | WorkOn int `json:"workOn,omitempty"` | 45 | WorkOn int `json:"workOn,omitempty"` |
44 | // 机台 (A、B、C、D 区分机器大小) | 46 | // 机台 (A、B、C、D 区分机器大小) |
@@ -80,7 +82,7 @@ func (productPlanDispatchRecord *ProductPlanDispatchRecord) ChangeStatus(status | @@ -80,7 +82,7 @@ func (productPlanDispatchRecord *ProductPlanDispatchRecord) ChangeStatus(status | ||
80 | } | 82 | } |
81 | 83 | ||
82 | func NewProductPlanDispatchRecord(productPlan *ProductPlan, workStation *WorkStation) *ProductPlanDispatchRecord { | 84 | func NewProductPlanDispatchRecord(productPlan *ProductPlan, workStation *WorkStation) *ProductPlanDispatchRecord { |
83 | - return &ProductPlanDispatchRecord{ | 85 | + record := &ProductPlanDispatchRecord{ |
84 | CompanyId: productPlan.CompanyId, | 86 | CompanyId: productPlan.CompanyId, |
85 | OrgId: productPlan.OrgId, | 87 | OrgId: productPlan.OrgId, |
86 | BatchNumber: productPlan.BatchNumber, | 88 | BatchNumber: productPlan.BatchNumber, |
@@ -92,10 +94,16 @@ func NewProductPlanDispatchRecord(productPlan *ProductPlan, workStation *WorkSta | @@ -92,10 +94,16 @@ func NewProductPlanDispatchRecord(productPlan *ProductPlan, workStation *WorkSta | ||
92 | PlanDispatchRecordExt: &PlanDispatchRecordExt{ | 94 | PlanDispatchRecordExt: &PlanDispatchRecordExt{ |
93 | ProductPlanId: productPlan.ProductPlanId, | 95 | ProductPlanId: productPlan.ProductPlanId, |
94 | PlanProductName: productPlan.PlanProductName, | 96 | PlanProductName: productPlan.PlanProductName, |
95 | - WorkOn: productPlan.WorkOn, | ||
96 | - Machine: productPlan.Machine, | ||
97 | - Remark: productPlan.Remark, | 97 | + //ProductCode: productPlan.Ext.ProductPlanExt.ProductCode, |
98 | + WorkOn: productPlan.WorkOn, | ||
99 | + Machine: productPlan.Machine, | ||
100 | + Remark: productPlan.Remark, | ||
98 | }, | 101 | }, |
99 | Ext: productPlan.Ext, | 102 | Ext: productPlan.Ext, |
100 | } | 103 | } |
104 | + if productPlan.Ext != nil && productPlan.Ext.ProductPlanExt != nil { | ||
105 | + record.PlanDispatchRecordExt.ProductCode = productPlan.Ext.ProductPlanExt.ProductCode | ||
106 | + } | ||
107 | + | ||
108 | + return record | ||
101 | } | 109 | } |
@@ -86,7 +86,10 @@ func (employeeProductRecord *EmployeeProductRecord) UpdateProductWeigh(weigh flo | @@ -86,7 +86,10 @@ func (employeeProductRecord *EmployeeProductRecord) UpdateProductWeigh(weigh flo | ||
86 | if productRecordType == RecordTypeReturnMaterial { | 86 | if productRecordType == RecordTypeReturnMaterial { |
87 | employeeProductRecord.ProductWeigh -= weigh | 87 | employeeProductRecord.ProductWeigh -= weigh |
88 | } | 88 | } |
89 | - employeeProductRecord.ProductRecordInfo.PreStatistics(employeeProductRecord.ProductWeigh, employeeProductRecord.SecondLevelWeigh, 0, 0) | 89 | + if productRecordType == RecordTypeWeigh { |
90 | + employeeProductRecord.ProductWeigh += weigh | ||
91 | + } | ||
92 | + employeeProductRecord.ProductRecordInfo.PreStatistics(employeeProductRecord.ProductWeigh, employeeProductRecord.SecondLevelWeigh, yesterdayWeight, bestWeight) | ||
90 | employeeProductRecord.UpdatedAt = time.Now() | 93 | employeeProductRecord.UpdatedAt = time.Now() |
91 | employeeProductRecord.Version += 1 | 94 | employeeProductRecord.Version += 1 |
92 | } | 95 | } |
@@ -4,8 +4,8 @@ package domain | @@ -4,8 +4,8 @@ package domain | ||
4 | type ProductRecordInfo struct { | 4 | type ProductRecordInfo struct { |
5 | // 生产日期 | 5 | // 生产日期 |
6 | ProductDate string `json:"productDate"` | 6 | ProductDate string `json:"productDate"` |
7 | - // 原始上报数据 | ||
8 | - OriginalWeigh float64 `json:"originalWeigh,omitempty"` | 7 | + // 原始上报数据(kg,串) |
8 | + Original float64 `json:"original,omitempty"` | ||
9 | // 换算后的产能 | 9 | // 换算后的产能 |
10 | Weigh float64 `json:"weigh"` | 10 | Weigh float64 `json:"weigh"` |
11 | // 产能 - 审核前 | 11 | // 产能 - 审核前 |
@@ -58,8 +58,10 @@ func (info *ProductRecordStaticInfo) PreStatistics(productWeight float64, second | @@ -58,8 +58,10 @@ func (info *ProductRecordStaticInfo) PreStatistics(productWeight float64, second | ||
58 | info.InputWeight = productWeight - totalOtherSecondLevelWeigh | 58 | info.InputWeight = productWeight - totalOtherSecondLevelWeigh |
59 | info.OutputWeight = info.InputWeight - secondWeight | 59 | info.OutputWeight = info.InputWeight - secondWeight |
60 | info.SecondLevelWeight = secondWeight | 60 | info.SecondLevelWeight = secondWeight |
61 | - info.YesterdayOutputWeight = yesterdayWeight | ||
62 | - info.BestOutputWeight = bestWeight | 61 | + if info.YesterdayOutputWeight == 0 && info.BestOutputWeight == 0 { |
62 | + info.YesterdayOutputWeight = yesterdayWeight | ||
63 | + info.BestOutputWeight = bestWeight | ||
64 | + } | ||
63 | if bestWeight <= info.InputWeight { | 65 | if bestWeight <= info.InputWeight { |
64 | info.BestOutputWeight = info.OutputWeight | 66 | info.BestOutputWeight = info.OutputWeight |
65 | } | 67 | } |
@@ -68,6 +68,9 @@ func (employeeProductRecord *WorkshopProductRecord) UpdateProductWeigh(weigh flo | @@ -68,6 +68,9 @@ func (employeeProductRecord *WorkshopProductRecord) UpdateProductWeigh(weigh flo | ||
68 | if productRecordType == RecordTypeReturnMaterial { | 68 | if productRecordType == RecordTypeReturnMaterial { |
69 | employeeProductRecord.ProductWeigh -= weigh | 69 | employeeProductRecord.ProductWeigh -= weigh |
70 | } | 70 | } |
71 | + if productRecordType == RecordTypeWeigh { | ||
72 | + employeeProductRecord.ProductWeigh += weigh | ||
73 | + } | ||
71 | employeeProductRecord.ProductRecordInfo.PreStatistics(employeeProductRecord.ProductWeigh, employeeProductRecord.SecondLevelWeigh, 0, 0) | 74 | employeeProductRecord.ProductRecordInfo.PreStatistics(employeeProductRecord.ProductWeigh, employeeProductRecord.SecondLevelWeigh, 0, 0) |
72 | employeeProductRecord.UpdatedAt = time.Now() | 75 | employeeProductRecord.UpdatedAt = time.Now() |
73 | employeeProductRecord.Version += 1 | 76 | employeeProductRecord.Version += 1 |
@@ -9,9 +9,9 @@ const ( | @@ -9,9 +9,9 @@ const ( | ||
9 | // 用户对象 | 9 | // 用户对象 |
10 | type User struct { | 10 | type User struct { |
11 | // 用户Id 用户唯一标识 | 11 | // 用户Id 用户唯一标识 |
12 | - UserId int `json:"userId,omitempty"` | 12 | + UserId int `json:"userId"` |
13 | // 用户姓名 | 13 | // 用户姓名 |
14 | - UserName string `json:"userName,omitempty"` | 14 | + UserName string `json:"userName"` |
15 | // 员工类型 1:固定 2:派遣 3.临时 | 15 | // 员工类型 1:固定 2:派遣 3.临时 |
16 | EmployeeType int `json:"employeeType,omitempty"` | 16 | EmployeeType int `json:"employeeType,omitempty"` |
17 | // IC卡号 | 17 | // IC卡号 |
@@ -24,4 +24,5 @@ type User struct { | @@ -24,4 +24,5 @@ type User struct { | ||
24 | // 额外扩展的参数 | 24 | // 额外扩展的参数 |
25 | GroupId int `json:"-"` | 25 | GroupId int `json:"-"` |
26 | GroupName string `json:"-"` | 26 | GroupName string `json:"-"` |
27 | + WorkOn int `json:"-"` | ||
27 | } | 28 | } |
@@ -23,14 +23,33 @@ type WorkStation struct { | @@ -23,14 +23,33 @@ type WorkStation struct { | ||
23 | } | 23 | } |
24 | 24 | ||
25 | func NewWorkStation(w *Workshop, l *ProductLine, s *ProductSection) *WorkStation { | 25 | func NewWorkStation(w *Workshop, l *ProductLine, s *ProductSection) *WorkStation { |
26 | - return &WorkStation{ | ||
27 | - WorkStationId: fmt.Sprintf("%v.%v.%v", w.WorkshopId, l.LineId, s.SectionId), | ||
28 | - WorkshopId: w.WorkshopId, | ||
29 | - WorkshopName: w.WorkshopName, | ||
30 | - LineId: l.LineId, | ||
31 | - LineName: l.LineName, | ||
32 | - SectionId: s.SectionId, | ||
33 | - SectionName: s.SectionName, | 26 | + item := &WorkStation{ |
27 | + //WorkshopId: w.WorkshopId, | ||
28 | + //WorkshopName: w.WorkshopName, | ||
29 | + //LineId: l.LineId, | ||
30 | + //LineName: l.LineName, | ||
31 | + //SectionId: s.SectionId, | ||
32 | + //SectionName: s.SectionName, | ||
34 | //Principal: w.Principal, | 33 | //Principal: w.Principal, |
35 | } | 34 | } |
35 | + if w != nil && l != nil && s != nil { | ||
36 | + item.WorkStationId = WorkstationKey(w.WorkshopId, l.LineId, s.SectionId) | ||
37 | + } | ||
38 | + if w != nil { | ||
39 | + item.WorkshopId = w.WorkshopId | ||
40 | + item.WorkshopName = w.WorkshopName | ||
41 | + } | ||
42 | + if l != nil { | ||
43 | + item.LineId = l.LineId | ||
44 | + item.LineName = l.LineName | ||
45 | + } | ||
46 | + if s != nil { | ||
47 | + item.SectionId = s.SectionId | ||
48 | + item.SectionName = s.SectionName | ||
49 | + } | ||
50 | + return item | ||
51 | +} | ||
52 | + | ||
53 | +func WorkstationKey(workshopId, lineId, sectionId int) string { | ||
54 | + return fmt.Sprintf("%v.%v.%v", workshopId, lineId, sectionId) | ||
36 | } | 55 | } |
@@ -88,6 +88,10 @@ func (workshop *Workshop) RemoveLine(lineId int) (*ProductLine, error) { | @@ -88,6 +88,10 @@ func (workshop *Workshop) RemoveLine(lineId int) (*ProductLine, error) { | ||
88 | if err != nil { | 88 | if err != nil { |
89 | return nil, err | 89 | return nil, err |
90 | } | 90 | } |
91 | + sections := line.GetProductSections(NotDeleted) | ||
92 | + if len(sections) > 0 { | ||
93 | + return nil, fmt.Errorf("生产线:%v下存在工段,不可删除", line.LineName) | ||
94 | + } | ||
91 | if line.Removed == Deleted { | 95 | if line.Removed == Deleted { |
92 | return nil, fmt.Errorf("生产线:%v已删除", line.LineName) | 96 | return nil, fmt.Errorf("生产线:%v已删除", line.LineName) |
93 | } | 97 | } |
@@ -5,10 +5,24 @@ import "strings" | @@ -5,10 +5,24 @@ import "strings" | ||
5 | /*车间列表*/ | 5 | /*车间列表*/ |
6 | type Workshops []*Workshop | 6 | type Workshops []*Workshop |
7 | 7 | ||
8 | -func (m Workshops) FindWorkStation(workshopId, lineId, sectionId int) *WorkStation { | 8 | +func (m Workshops) FindWorkStation(workshopId, lineId, sectionId int, flag ...int) *WorkStation { |
9 | for i := range m { | 9 | for i := range m { |
10 | item := m[i] | 10 | item := m[i] |
11 | workstation, err := item.FindWorkStation(workshopId, lineId, sectionId) | 11 | workstation, err := item.FindWorkStation(workshopId, lineId, sectionId) |
12 | + if len(flag) > 0 && flag[0] == 1 && workstation != nil { | ||
13 | + workstation.Principal = item.Principal | ||
14 | + } | ||
15 | + if err == nil && workstation != nil { | ||
16 | + return workstation | ||
17 | + } | ||
18 | + } | ||
19 | + return &WorkStation{} //返回空的对象 | ||
20 | +} | ||
21 | + | ||
22 | +func (m Workshops) FindWorkStationOrNil(workshopId, lineId, sectionId int) *WorkStation { | ||
23 | + for i := range m { | ||
24 | + item := m[i] | ||
25 | + workstation, err := item.FindWorkStationOrNil(workshopId, lineId, sectionId) | ||
12 | if err == nil && workstation != nil { | 26 | if err == nil && workstation != nil { |
13 | return workstation | 27 | return workstation |
14 | } | 28 | } |
@@ -39,6 +39,16 @@ func (gateway HttpLibAlliedCreationUser) UserByCode(companyId, orgId int, userCo | @@ -39,6 +39,16 @@ func (gateway HttpLibAlliedCreationUser) UserByCode(companyId, orgId int, userCo | ||
39 | } | 39 | } |
40 | return users[0], nil | 40 | return users[0], nil |
41 | } | 41 | } |
42 | +func (gateway HttpLibAlliedCreationUser) UserByICCode(companyId, orgId int, icCode string) (*models.User, error) { | ||
43 | + _, users, err := gateway.UserSearch(ReqUserSearch{CompanyId: int64(companyId), OrganizationId: int64(orgId), IcCardNumber: icCode, Limit: 1, PullRealTime: true}) | ||
44 | + if err != nil { | ||
45 | + return nil, err | ||
46 | + } | ||
47 | + if len(users) == 0 { | ||
48 | + return nil, fmt.Errorf("用户不存在") | ||
49 | + } | ||
50 | + return users[0], nil | ||
51 | +} | ||
42 | func (gateway HttpLibAlliedCreationUser) Users(userIds []int) ([]*models.User, error) { | 52 | func (gateway HttpLibAlliedCreationUser) Users(userIds []int) ([]*models.User, error) { |
43 | var list = make([]*models.User, 0) | 53 | var list = make([]*models.User, 0) |
44 | for i := range userIds { | 54 | for i := range userIds { |
@@ -42,6 +42,8 @@ type ( | @@ -42,6 +42,8 @@ type ( | ||
42 | InCompanyIds []interface{} `json:"inCompanyIds,omitempty"` | 42 | InCompanyIds []interface{} `json:"inCompanyIds,omitempty"` |
43 | // 用户编号 企业内标识 | 43 | // 用户编号 企业内标识 |
44 | UserCode string `cname:"用户编号" json:"userCode,omitempty"` | 44 | UserCode string `cname:"用户编号" json:"userCode,omitempty"` |
45 | + // IC卡号 | ||
46 | + IcCardNumber string `cname:"IC卡号" json:"icCardNumber,omitempty"` | ||
45 | 47 | ||
46 | // 自定义高级查询 | 48 | // 自定义高级查询 |
47 | AdvancedQuery string `json:"advancedQuery"` | 49 | AdvancedQuery string `json:"advancedQuery"` |
@@ -2,6 +2,7 @@ package dao | @@ -2,6 +2,7 @@ package dao | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | + "github.com/go-pg/pg/v10/orm" | ||
5 | "github.com/linmadan/egglib-go/persistent/pg/sqlbuilder" | 6 | "github.com/linmadan/egglib-go/persistent/pg/sqlbuilder" |
6 | pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | 7 | pgTransaction "github.com/linmadan/egglib-go/transaction/pg" |
7 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | 8 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" |
@@ -34,9 +35,15 @@ func (dao *AttendanceRecordDao) ProductWorkStationAttendanceRecord(companyId, or | @@ -34,9 +35,15 @@ func (dao *AttendanceRecordDao) ProductWorkStationAttendanceRecord(companyId, or | ||
34 | query.Where("org_id = ?", orgId) | 35 | query.Where("org_id = ?", orgId) |
35 | query.Where("work_station->>'workStationId' = ?", workStationId) | 36 | query.Where("work_station->>'workStationId' = ?", workStationId) |
36 | query.Where("sign_in <= ?", productTime) | 37 | query.Where("sign_in <= ?", productTime) |
37 | - query.Where("sign_out >= ?", productTime) | 38 | + query.WhereGroup(func(q *orm.Query) (*orm.Query, error) { |
39 | + query.WhereOr("sign_out >= ?", productTime) | ||
40 | + query.WhereOr("sign_out=?", time.Time{}) | ||
41 | + return q, nil | ||
42 | + }) | ||
43 | + query.DistinctOn("product_worker->>'userId',work_station->>'workStationId'") | ||
44 | + | ||
38 | query.SetOffsetAndLimit(domain.MaxQueryRow) | 45 | query.SetOffsetAndLimit(domain.MaxQueryRow) |
39 | - query.SetOrderDirect("product_attendance_id", "DESC") | 46 | + query.OrderExpr("product_worker->>'userId' asc ,work_station->>'workStationId' asc") |
40 | if count, err := query.SelectAndCount(); err != nil { | 47 | if count, err := query.SelectAndCount(); err != nil { |
41 | return 0, productAttendanceRecords, err | 48 | return 0, productAttendanceRecords, err |
42 | } else { | 49 | } else { |
@@ -94,6 +101,9 @@ func (dao *AttendanceRecordDao) WorkerAttendanceRecords(companyId, orgId, worker | @@ -94,6 +101,9 @@ func (dao *AttendanceRecordDao) WorkerAttendanceRecords(companyId, orgId, worker | ||
94 | query.Where("sign_in >= ?", beginTime) | 101 | query.Where("sign_in >= ?", beginTime) |
95 | query.Where("sign_in <= ?", endTime) | 102 | query.Where("sign_in <= ?", endTime) |
96 | query.Where("attendance_status = ?", domain.AttendanceNotApprove) | 103 | query.Where("attendance_status = ?", domain.AttendanceNotApprove) |
104 | + if len(workStationId) > 0 { | ||
105 | + query.Where("work_station ->>'workStationId' = ?", workStationId) | ||
106 | + } | ||
97 | query.SetOffsetAndLimit(domain.MaxQueryRow) | 107 | query.SetOffsetAndLimit(domain.MaxQueryRow) |
98 | query.SetOrderDirect("product_attendance_id", "DESC") | 108 | query.SetOrderDirect("product_attendance_id", "DESC") |
99 | if count, err := query.SelectAndCount(); err != nil { | 109 | if count, err := query.SelectAndCount(); err != nil { |
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 | +} | ||
86 | + | ||
87 | +// 时段产能 | ||
88 | +func (dao *DeviceDailyRunningRecordDao) TimeSectionProductRecord(companyId, orgId, workshopId int, lineId int, sectionName string, beginTime time.Time, result interface{}) error { | ||
89 | + | ||
90 | + tx := dao.transactionContext.PgTx | ||
91 | + sql := fmt.Sprintf(` | ||
92 | +WITH ts_product as( | ||
93 | + select sum(a.weight) total,a.ts from ( | ||
94 | + select | ||
95 | + cast(device_running_record_info->>'count' as DECIMAL) weight, | ||
96 | + "replace"(to_char(created_at at time ZONE 'Asia/shanghai', 'HH24:') || cast(date_part('minute',created_at) as integer)/30*30, ':0', ':00') ts | ||
97 | + from manufacture.device_running_record | ||
98 | + where | ||
99 | + company_id = ? | ||
100 | + and org_id = ? | ||
101 | + and work_station->>'workshopId'='?' | ||
102 | + and work_station->>'lineId'='?' | ||
103 | + and work_station->>'sectionName'=? | ||
104 | + and device_running_record_info->>'deviceType'='CCJ' | ||
105 | + and created_at >? | ||
106 | + ) a | ||
107 | + group by a.ts | ||
108 | + order by ts | ||
109 | +) | ||
110 | +-- select * from ts_product | ||
111 | +, ts_product_list as ( | ||
112 | + select d.ts,ts_product.total from ( | ||
113 | + select to_char(c.ts::timestamp,'HH24:MI') ts from ( | ||
114 | + select generate_series(a.end - interval '5 hour', | ||
115 | + "replace"(to_char(a.end, 'yyyy-mm-dd HH24:') || cast(date_part('minute',a.end) as integer)/30*30+30, ':0', ':00')::timestamp, | ||
116 | + '30 minute') ts from ( | ||
117 | + select to_timestamp(to_char(now() at time ZONE 'Asia/shanghai','yyyy-mm-dd HH24'),'yyyy-mm-dd HH24') as end | ||
118 | + ) a | ||
119 | + ) c | ||
120 | + ) d left join ts_product on d.ts = ts_product.ts | ||
121 | +) | ||
122 | +SELECT ts, coalesce(total,0) total | ||
123 | +from ts_product_list | ||
124 | +`) | ||
125 | + if _, err := tx.Query(result, sql, companyId, orgId, workshopId, lineId, sectionName, beginTime); err != nil { | ||
126 | + return err | ||
127 | + } | ||
128 | + return nil | ||
129 | +} |
@@ -58,7 +58,8 @@ func (dao *EmployeeProductRecordDao) WorkerBestOutputRecord(companyId, orgId, pl | @@ -58,7 +58,8 @@ func (dao *EmployeeProductRecordDao) WorkerBestOutputRecord(companyId, orgId, pl | ||
58 | query.Where("org_id = ?", orgId) | 58 | query.Where("org_id = ?", orgId) |
59 | query.Where("product_worker ->>'userId' = '?'", workerId) | 59 | query.Where("product_worker ->>'userId' = '?'", workerId) |
60 | query.Where("product_record_info ->>'productPlanId' = '?'", planId) | 60 | query.Where("product_record_info ->>'productPlanId' = '?'", planId) |
61 | - query.Order("product_record_info ->>'outputWeight' DESC") | 61 | + query.OrderExpr("product_record_info ->>'outputWeight' DESC") |
62 | + query.Limit(1) | ||
62 | if err := query.First(); err != nil { | 63 | if err := query.First(); err != nil { |
63 | if err.Error() == "pg: no rows in result set" { | 64 | if err.Error() == "pg: no rows in result set" { |
64 | return nil, domain.ErrorNotFound | 65 | return nil, domain.ErrorNotFound |
@@ -2,10 +2,11 @@ package dao | @@ -2,10 +2,11 @@ package dao | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | - "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" | ||
6 | "strconv" | 5 | "strconv" |
7 | "strings" | 6 | "strings" |
8 | 7 | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" | ||
9 | + | ||
9 | pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | 10 | pgTransaction "github.com/linmadan/egglib-go/transaction/pg" |
10 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models" | 11 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models" |
11 | ) | 12 | ) |
@@ -115,7 +116,7 @@ func (d *MaterialK3cloudDao) SyncDataProudct(version int64, orgName string) erro | @@ -115,7 +116,7 @@ func (d *MaterialK3cloudDao) SyncDataProudct(version int64, orgName string) erro | ||
115 | ) | 116 | ) |
116 | SELECT %v,%v,"join_product_id","number","name","material_group_name", | 117 | SELECT %v,%v,"join_product_id","number","name","material_group_name", |
117 | json_build_object('unit',specification),now(),now(),json_build_object('orgName','%v') | 118 | json_build_object('unit',specification),now(),now(),json_build_object('orgName','%v') |
118 | - FROM "manufacture"."material_k3cloud" WHERE "data_version"=? AND "material_group_number" LIKE '05%%' | 119 | + FROM "manufacture"."material_k3cloud" WHERE "data_version">=? AND "material_group_number" LIKE '05%%' |
119 | ON conflict ( product_id ) DO | 120 | ON conflict ( product_id ) DO |
120 | UPDATE | 121 | UPDATE |
121 | SET ( | 122 | SET ( |
1 | +package dao | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "github.com/linmadan/egglib-go/persistent/pg/sqlbuilder" | ||
6 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/transform" | ||
10 | + "time" | ||
11 | +) | ||
12 | + | ||
13 | +type ProductPlanDispatchRecordDao struct { | ||
14 | + transactionContext *pgTransaction.TransactionContext | ||
15 | +} | ||
16 | + | ||
17 | +func NewProductPlanDispatchRecord(transactionContext *pgTransaction.TransactionContext) (*ProductPlanDispatchRecordDao, error) { | ||
18 | + if transactionContext == nil { | ||
19 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
20 | + } else { | ||
21 | + return &ProductPlanDispatchRecordDao{ | ||
22 | + transactionContext: transactionContext, | ||
23 | + }, nil | ||
24 | + } | ||
25 | +} | ||
26 | + | ||
27 | +// 生产计划对应的批次 | ||
28 | +// 工段 | ||
29 | +// 日期 | ||
30 | +// 产品编号 | ||
31 | +// 调度状态 status | ||
32 | +func (dao *ProductPlanDispatchRecordDao) DeviceProductPlan(companyId, orgId int, workStationId string, date time.Time, productCode string, status int) (*domain.ProductPlanDispatchRecord, error) { | ||
33 | + tx := dao.transactionContext.PgTx | ||
34 | + productPlanDispatchRecordModel := new(models.ProductPlanDispatchRecord) | ||
35 | + query := sqlbuilder.BuildQuery(tx.Model(productPlanDispatchRecordModel), map[string]interface{}{}) | ||
36 | + query.Where("company_id = ?", companyId) | ||
37 | + query.Where("org_id = ?", orgId) | ||
38 | + query.Where("work_station->>'workStationId'=?", workStationId) | ||
39 | + query.Where("product_date = ?", date) | ||
40 | + query.Where("plan_dispatch_status = ?", status) | ||
41 | + query.Where("plan_dispatch_record_ext->>'productCode'=?", productCode) | ||
42 | + query.Order("updated_at desc") | ||
43 | + if err := query.First(); err != nil { | ||
44 | + if err.Error() == "pg: no rows in result set" { | ||
45 | + return nil, domain.ErrorNotFound | ||
46 | + } else { | ||
47 | + return nil, err | ||
48 | + } | ||
49 | + } | ||
50 | + if productPlanDispatchRecordModel.ProductPlanDispatchRecordId == 0 { | ||
51 | + return nil, nil | ||
52 | + } else { | ||
53 | + return transform.TransformToProductPlanDispatchRecordDomainModelFromPgModels(productPlanDispatchRecordModel) | ||
54 | + } | ||
55 | +} |
@@ -124,15 +124,15 @@ func (d *PrdMoK3cloudDao) SyncDataProductPlan(version int64) error { | @@ -124,15 +124,15 @@ func (d *PrdMoK3cloudDao) SyncDataProductPlan(version int64) error { | ||
124 | ) | 124 | ) |
125 | SELECT prd_mo_k3cloud."join_product_plan_id",prd_mo_k3cloud."bill_no", | 125 | SELECT prd_mo_k3cloud."join_product_plan_id",prd_mo_k3cloud."bill_no", |
126 | prd_mo_k3cloud."plan_start_date", | 126 | prd_mo_k3cloud."plan_start_date", |
127 | - json_build_object('workshopId',"workshop"."workshop_id",'workshopName',prd_mo_k3cloud."work_shop_name"), | 127 | + json_build_object('workshopId',COALESCE("workshop"."workshop_id",0),'workshopName',prd_mo_k3cloud."work_shop_name"), |
128 | prd_mo_k3cloud."material_name", json_build_object('unit',prd_mo_k3cloud."unit_name",'quantity',prd_mo_k3cloud."qty"), | 128 | prd_mo_k3cloud."material_name", json_build_object('unit',prd_mo_k3cloud."unit_name",'quantity',prd_mo_k3cloud."qty"), |
129 | 2,prd_mo_k3cloud."description", | 129 | 2,prd_mo_k3cloud."description", |
130 | json_build_object('productPlanExt',json_build_object('productId',prd_mo_k3cloud."join_product_plan_id",'productCode',prd_mo_k3cloud."material_number",'productName',prd_mo_k3cloud."material_name")), | 130 | json_build_object('productPlanExt',json_build_object('productId',prd_mo_k3cloud."join_product_plan_id",'productCode',prd_mo_k3cloud."material_number",'productName',prd_mo_k3cloud."material_name")), |
131 | now(),now() | 131 | now(),now() |
132 | FROM "manufacture"."prd_mo_k3cloud" | 132 | FROM "manufacture"."prd_mo_k3cloud" |
133 | - LEFT JOIN "material_k3cloud" ON "prd_mo_k3cloud"."material_number"="material_k3cloud"."number" | ||
134 | - LEFT JOIN "workshop" ON "workshop"."workshop_name" = "prd_mo_k3cloud"."work_shop_name" | ||
135 | - WHERE prd_mo_k3cloud."data_version"=? | 133 | + LEFT JOIN "manufacture"."material_k3cloud" ON "prd_mo_k3cloud"."material_id"="material_k3cloud"."material_id" |
134 | + LEFT JOIN "manufacture"."workshop" ON "workshop"."workshop_name" = "prd_mo_k3cloud"."work_shop_name" | ||
135 | + WHERE prd_mo_k3cloud."data_version">=? | ||
136 | ON conflict ("product_plan_id") DO | 136 | ON conflict ("product_plan_id") DO |
137 | UPDATE | 137 | UPDATE |
138 | SET ( | 138 | SET ( |
@@ -54,3 +54,82 @@ func (dao *ProductRecordDao) RecentUnApprovedProductRecord(fromLastHour int, rec | @@ -54,3 +54,82 @@ func (dao *ProductRecordDao) RecentUnApprovedProductRecord(fromLastHour int, rec | ||
54 | return int64(count), productAttendanceRecords, nil | 54 | return int64(count), productAttendanceRecords, nil |
55 | } | 55 | } |
56 | } | 56 | } |
57 | + | ||
58 | +// 时段产能 | ||
59 | +func (dao *ProductRecordDao) TimeSectionProductRecord(companyId, orgId, workshopId int, lineId int, sectionName string, beginTime time.Time, result interface{}) error { | ||
60 | + | ||
61 | + tx := dao.transactionContext.PgTx | ||
62 | + sql := fmt.Sprintf(` | ||
63 | +WITH ts_product as( | ||
64 | + select sum(a.weight) total,a.ts from ( | ||
65 | + select | ||
66 | + cast(product_record_info->>'weigh' as DECIMAL) weight, | ||
67 | + "replace"(to_char(created_at at time ZONE 'Asia/shanghai', 'HH24:') || cast(date_part('minute',created_at) as integer)/30*30, ':0', ':00') ts | ||
68 | + from manufacture.product_records | ||
69 | + where | ||
70 | + company_id = ? | ||
71 | + and org_id = ? | ||
72 | + and work_station->>'workshopId'='?' | ||
73 | + and work_station->>'lineId'='?' | ||
74 | + and work_station->>'sectionName'=? | ||
75 | + and product_record_type = 8 | ||
76 | + and created_at >? | ||
77 | + ) a | ||
78 | + group by a.ts | ||
79 | + order by ts | ||
80 | +) | ||
81 | +-- select * from ts_product | ||
82 | +, ts_product_list as ( | ||
83 | + select d.ts,ts_product.total from ( | ||
84 | + select to_char(c.ts::timestamp,'HH24:MI') ts from ( | ||
85 | + select generate_series(a.end - interval '5 hour', | ||
86 | + "replace"(to_char(a.end, 'yyyy-mm-dd HH24:') || cast(date_part('minute',a.end) as integer)/30*30+30, ':0', ':00')::timestamp, | ||
87 | + '30 minute') ts from ( | ||
88 | + select to_timestamp(to_char(now() at time ZONE 'Asia/shanghai','yyyy-mm-dd HH24'),'yyyy-mm-dd HH24') as end | ||
89 | + ) a | ||
90 | + ) c | ||
91 | + ) d left join ts_product on d.ts = ts_product.ts | ||
92 | +) | ||
93 | +SELECT ts, coalesce(total,0) total | ||
94 | +from ts_product_list | ||
95 | +`) | ||
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 { | ||
132 | + return err | ||
133 | + } | ||
134 | + return nil | ||
135 | +} |
1 | +package dao | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models" | ||
8 | + "time" | ||
9 | +) | ||
10 | + | ||
11 | +type WorkshopPlanCompletionRecordDao struct { | ||
12 | + transactionContext *pgTransaction.TransactionContext | ||
13 | +} | ||
14 | + | ||
15 | +func (dao *WorkshopPlanCompletionRecordDao) Records(companyId, orgId int, workshopId int, begin, end time.Time, records interface{}) error { | ||
16 | + tx := dao.transactionContext.PgTx | ||
17 | + sql := fmt.Sprintf(` | ||
18 | +with product_record as ( | ||
19 | +select | ||
20 | +(case when product_record_type=1 then cast(product_record_info->>'weigh' as DECIMAL) | ||
21 | +ELSE -(cast(product_record_info->>'weigh' as DECIMAL)) | ||
22 | +END) as weight, | ||
23 | +cast(product_record_info->>'productPlanId' as INTEGER) plan_id | ||
24 | +--,created_at | ||
25 | +from manufacture.product_records | ||
26 | +where company_id = ? | ||
27 | +and org_id =? | ||
28 | +and work_station->>'workshopId'='?' | ||
29 | +and product_record_type in (1,2) | ||
30 | +and created_at>=? | ||
31 | +and created_at<? | ||
32 | +), product_record_sum as( | ||
33 | + select sum(weight) weight,plan_id from product_record | ||
34 | + GROUP BY plan_id | ||
35 | +) | ||
36 | +select | ||
37 | +plan_devoted->>'weight' plan_weight -- 计划重量 | ||
38 | +, coalesce(b.weight,0) real_weight --批次实际产能 | ||
39 | +,a.product_plan_id | ||
40 | +from manufacture.product_plan a left join product_record_sum b on a.product_plan_id = b.plan_id | ||
41 | +where company_id = ? | ||
42 | +and org_id =? | ||
43 | +and workshop->>'workshopId'='?' | ||
44 | +and created_at >=? | ||
45 | +and created_at<? | ||
46 | +order by created_at desc`) | ||
47 | + if _, err := tx.Query(records, sql, | ||
48 | + companyId, orgId, workshopId, begin, end, | ||
49 | + companyId, orgId, workshopId, begin, end); err != nil { | ||
50 | + return err | ||
51 | + } | ||
52 | + return nil | ||
53 | +} | ||
54 | + | ||
55 | +func (dao *WorkshopPlanCompletionRecordDao) FindOne(companyId, orgId int, workshopId int, begin time.Time) (*models.WorkshopPlanCompletionRecord, error) { | ||
56 | + tx := dao.transactionContext.PgTx | ||
57 | + var record = new(models.WorkshopPlanCompletionRecord) | ||
58 | + q := tx.Model(record) | ||
59 | + q.Where("company_id=?", companyId) | ||
60 | + q.Where("org_id=?", orgId) | ||
61 | + q.Where("workshop_id=?", workshopId) | ||
62 | + q.Where("created_at=?", begin) | ||
63 | + err := q.First() | ||
64 | + if err != nil { | ||
65 | + if err.Error() == "pg: no rows in result set" { | ||
66 | + return nil, domain.ErrorNotFound | ||
67 | + } else { | ||
68 | + return nil, err | ||
69 | + } | ||
70 | + } | ||
71 | + return record, nil | ||
72 | +} | ||
73 | + | ||
74 | +func (dao *WorkshopPlanCompletionRecordDao) Save(record *models.WorkshopPlanCompletionRecord) error { | ||
75 | + tx := dao.transactionContext.PgTx | ||
76 | + if _, err := tx.Model(record).Insert(); err != nil { | ||
77 | + return err | ||
78 | + } | ||
79 | + return nil | ||
80 | +} | ||
81 | + | ||
82 | +func NewWorkshopPlanCompletionRecordDao(transactionContext *pgTransaction.TransactionContext) (*WorkshopPlanCompletionRecordDao, error) { | ||
83 | + if transactionContext == nil { | ||
84 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
85 | + } else { | ||
86 | + return &WorkshopPlanCompletionRecordDao{ | ||
87 | + transactionContext: transactionContext, | ||
88 | + }, nil | ||
89 | + } | ||
90 | +} |
@@ -32,7 +32,7 @@ func (dao *WorkshopProductRecordDao) WorkshopProductRecord(companyId, orgId, pla | @@ -32,7 +32,7 @@ func (dao *WorkshopProductRecordDao) WorkshopProductRecord(companyId, orgId, pla | ||
32 | query := sqlbuilder.BuildQuery(tx.Model(employeeProductRecordModel), map[string]interface{}{}) | 32 | query := sqlbuilder.BuildQuery(tx.Model(employeeProductRecordModel), map[string]interface{}{}) |
33 | query.Where("company_id = ?", companyId) | 33 | query.Where("company_id = ?", companyId) |
34 | query.Where("org_id = ?", orgId) | 34 | query.Where("org_id = ?", orgId) |
35 | - query.Where("product_date = ?", productTime.Format("2006-01-02")) | 35 | + query.Where("product_date = ?", productTime.Local().Format("2006-01-02")) |
36 | query.Where("product_record_info ->>'productPlanId' = '?'", planId) | 36 | query.Where("product_record_info ->>'productPlanId' = '?'", planId) |
37 | if err := query.First(); err != nil { | 37 | if err := query.First(); err != nil { |
38 | if err.Error() == "pg: no rows in result set" { | 38 | if err.Error() == "pg: no rows in result set" { |
@@ -27,6 +27,14 @@ func (svr *UserService) UserByCode(companyId, orgId int, userCode string) (*doma | @@ -27,6 +27,14 @@ func (svr *UserService) UserByCode(companyId, orgId int, userCode string) (*doma | ||
27 | return svr.ToUser(rsp), nil | 27 | return svr.ToUser(rsp), nil |
28 | } | 28 | } |
29 | 29 | ||
30 | +func (svr *UserService) UserByICCode(companyId, orgId int, userCode string) (*domain.User, error) { | ||
31 | + rsp, err := svr.internalUserService.UserByICCode(companyId, orgId, userCode) | ||
32 | + if err != nil { | ||
33 | + return nil, err | ||
34 | + } | ||
35 | + return svr.ToUser(rsp), nil | ||
36 | +} | ||
37 | + | ||
30 | func (svr *UserService) Users(id []int) ([]*domain.User, error) { | 38 | func (svr *UserService) Users(id []int) ([]*domain.User, error) { |
31 | rsp, err := svr.internalUserService.Users(id) | 39 | rsp, err := svr.internalUserService.Users(id) |
32 | if err != nil { | 40 | if err != nil { |
1 | +package domainService | ||
2 | + | ||
3 | +import ( | ||
4 | + "github.com/hibiken/asynq" | ||
5 | + "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/domain" | ||
8 | +) | ||
9 | + | ||
10 | +func SendWorkshopWorkTimeStaticJob(productRecord *domain.ProductAttendanceRecord) error { | ||
11 | + return SendAsyncJob(domain.TaskKeyWorkshopWorkTimeRecordStatics(), productRecord) | ||
12 | +} | ||
13 | + | ||
14 | +func SendProductRecordStaticsJob(productRecord *domain.ProductRecord) error { | ||
15 | + task := asynq.NewTask(domain.TaskKeyPatternProductRecordStatics(), []byte(json.MarshalToString(productRecord))) | ||
16 | + | ||
17 | + client := asynq.NewClient(asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS}) | ||
18 | + _, err := client.Enqueue(task) | ||
19 | + return err | ||
20 | +} | ||
21 | + | ||
22 | +func SendDeviceZkTecoReportJob(productRecord *domain.DeviceZkTeco) error { | ||
23 | + return SendAsyncJob(domain.TaskDeviceZkTecoReport(), productRecord) | ||
24 | +} | ||
25 | + | ||
26 | +func SendWorkshopDeviceData(productRecord *domain.DeviceCollection) error { | ||
27 | + return SendAsyncJob(domain.TaskDeviceCollection(), productRecord) | ||
28 | +} | ||
29 | + | ||
30 | +func SendAsyncJob(queueName string, job interface{}) error { | ||
31 | + task := asynq.NewTask(queueName, []byte(json.MarshalToString(job))) | ||
32 | + | ||
33 | + client := asynq.NewClient(asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS}) | ||
34 | + _, err := client.Enqueue(task) | ||
35 | + return err | ||
36 | +} |
@@ -17,7 +17,7 @@ func (ptr *PGApproveAttendanceRecordsService) BatchApproveAttendanceRecords(opt | @@ -17,7 +17,7 @@ func (ptr *PGApproveAttendanceRecordsService) BatchApproveAttendanceRecords(opt | ||
17 | var productAttendanceRecordRepository, _ = repository.NewProductAttendanceRecordRepository(ptr.transactionContext) | 17 | var productAttendanceRecordRepository, _ = repository.NewProductAttendanceRecordRepository(ptr.transactionContext) |
18 | var attendance *domain.ProductAttendanceRecord | 18 | var attendance *domain.ProductAttendanceRecord |
19 | var err error | 19 | var err error |
20 | - log.Logger.Info("【自动审核考勤记录任务】 启动") | 20 | + log.Logger.Debug("【自动审核考勤记录任务】 启动") |
21 | var user *domain.User = &domain.User{} | 21 | var user *domain.User = &domain.User{} |
22 | userService := NewUserService() | 22 | userService := NewUserService() |
23 | if approveUserId > 0 { | 23 | if approveUserId > 0 { |
1 | +package domainService | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/dao" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" | ||
11 | + "time" | ||
12 | +) | ||
13 | + | ||
14 | +const ( | ||
15 | + // 时段产能统计 | ||
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 = "穿串" | ||
29 | +) | ||
30 | + | ||
31 | +type PGCommonStatisticsService struct { | ||
32 | + transactionContext *pgTransaction.TransactionContext | ||
33 | +} | ||
34 | + | ||
35 | +func (ptr *PGCommonStatisticsService) CommonStatistics(actionType string, queryOptions map[string]interface{}) (interface{}, error) { | ||
36 | + var result interface{} | ||
37 | + var err error | ||
38 | + switch actionType { | ||
39 | + case HourProductiveStatistics: | ||
40 | + result, err = ptr.HourProductiveStatistics(queryOptions) | ||
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 | ||
54 | + } | ||
55 | + return result, err | ||
56 | +} | ||
57 | + | ||
58 | +// 时段产能-统计 (传串设备) | ||
59 | +func (ptr *PGCommonStatisticsService) HourProductiveStatistics(queryOptions map[string]interface{}) (interface{}, error) { | ||
60 | + var request = &HourProductiveStatisticsRequest{} | ||
61 | + if err := utils.LoadQueryObject(queryOptions, request); err != nil { | ||
62 | + return nil, err | ||
63 | + } | ||
64 | + | ||
65 | + workshopRepository, _ := repository.NewWorkshopRepository(ptr.transactionContext) | ||
66 | + type record struct { | ||
67 | + Ts string `json:"ts"` | ||
68 | + Total float64 `json:"total"` | ||
69 | + } | ||
70 | + | ||
71 | + workshop, err := workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}) | ||
72 | + if err != nil || workshop == nil { | ||
73 | + return nil, nil | ||
74 | + } | ||
75 | + productRecordDao, _ := dao.NewDeviceDailyRunningRecordDao(ptr.transactionContext) | ||
76 | + | ||
77 | + var response = make([]interface{}, 0) | ||
78 | + var tmpXData = make([]string, 0) | ||
79 | + for _, v := range workshop.GetProductLines(domain.NotDeleted) { | ||
80 | + var result = make([]*record, 0) | ||
81 | + if err := productRecordDao.TimeSectionProductRecord(request.CompanyId, request.OrgId, request.WorkshopId, v.LineId, SectionNameCCJ, time.Now().Add(-time.Hour*5), &result); err != nil { | ||
82 | + log.Logger.Error(err.Error()) | ||
83 | + continue | ||
84 | + } | ||
85 | + var xData []string = make([]string, 0) | ||
86 | + var values []interface{} = make([]interface{}, 0) | ||
87 | + for _, r := range result { | ||
88 | + xData = append(xData, r.Ts) | ||
89 | + values = append(values, r.Total) | ||
90 | + } | ||
91 | + if len(tmpXData) == 0 { | ||
92 | + tmpXData = xData | ||
93 | + } | ||
94 | + response = append(response, map[string]interface{}{ | ||
95 | + "lineName": v.LineName, | ||
96 | + "data": NewXYData(xData, values), | ||
97 | + }) | ||
98 | + } | ||
99 | + return map[string]interface{}{ | ||
100 | + "xAxis": tmpXData, | ||
101 | + "list": response, | ||
102 | + }, nil | ||
103 | +} | ||
104 | + | ||
105 | +type HourProductiveStatisticsRequest struct { | ||
106 | + CompanyId int `json:"companyId" valid:"Required"` | ||
107 | + OrgId int `json:"orgId" valid:"Required"` | ||
108 | + WorkshopId int `json:"workshopId" valid:"Required"` | ||
109 | +} | ||
110 | + | ||
111 | +func NewXYData(xData []string, values interface{}) interface{} { | ||
112 | + //return map[string]interface{}{ | ||
113 | + //"xAxis": map[string]interface{}{ | ||
114 | + // "data": xData, | ||
115 | + //}, | ||
116 | + //"source": map[string]interface{}{ | ||
117 | + // "value": values, | ||
118 | + //}, | ||
119 | + //} | ||
120 | + return values | ||
121 | +} | ||
122 | + | ||
123 | +// 时段产能-统计 (传串设备) | ||
124 | +func (ptr *PGCommonStatisticsService) DailyProductiveStatistics(queryOptions map[string]interface{}) (interface{}, error) { | ||
125 | + var request = &HourProductiveStatisticsRequest{} | ||
126 | + if err := utils.LoadQueryObject(queryOptions, request); err != nil { | ||
127 | + return nil, err | ||
128 | + } | ||
129 | + | ||
130 | + workshopRepository, _ := repository.NewWorkshopRepository(ptr.transactionContext) | ||
131 | + type record struct { | ||
132 | + Ts string `json:"ts"` | ||
133 | + Total float64 `json:"total"` | ||
134 | + } | ||
135 | + | ||
136 | + workshop, err := workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}) | ||
137 | + if err != nil || workshop == nil { | ||
138 | + return nil, nil | ||
139 | + } | ||
140 | + productRecordDao, _ := dao.NewDeviceDailyRunningRecordDao(ptr.transactionContext) | ||
141 | + | ||
142 | + var response = make([]interface{}, 0) | ||
143 | + var tmpXData = make([]string, 0) | ||
144 | + | ||
145 | + for _, v := range workshop.GetProductLines(domain.NotDeleted) { | ||
146 | + var result = make([]*record, 0) | ||
147 | + if err := productRecordDao.TimeSectionRunningRecord(request.CompanyId, request.OrgId, request.WorkshopId, v.LineId, SectionNameCCJ, time.Now().Add(-time.Hour*24*7), &result); err != nil { | ||
148 | + log.Logger.Error(err.Error()) | ||
149 | + continue | ||
150 | + } | ||
151 | + var xData []string = make([]string, 0) | ||
152 | + var values []interface{} = make([]interface{}, 0) | ||
153 | + for _, r := range result { | ||
154 | + xData = append(xData, r.Ts) | ||
155 | + values = append(values, r.Total) | ||
156 | + } | ||
157 | + if len(tmpXData) == 0 { | ||
158 | + tmpXData = xData | ||
159 | + } | ||
160 | + response = append(response, map[string]interface{}{ | ||
161 | + "lineName": v.LineName, | ||
162 | + "data": NewXYData(xData, values), | ||
163 | + }) | ||
164 | + } | ||
165 | + return map[string]interface{}{ | ||
166 | + "recent_7_day": map[string]interface{}{ | ||
167 | + "xAxis": tmpXData, | ||
168 | + "list": response, | ||
169 | + }, | ||
170 | + }, nil | ||
171 | +} | ||
172 | + | ||
173 | +// 二级品占比 | ||
174 | +func (ptr *PGCommonStatisticsService) ProportionOfSecondLevelStatistics(queryOptions map[string]interface{}) (interface{}, error) { | ||
175 | + var request = &HourProductiveStatisticsRequest{} | ||
176 | + if err := utils.LoadQueryObject(queryOptions, request); err != nil { | ||
177 | + return nil, err | ||
178 | + } | ||
179 | + | ||
180 | + workshopRepository, _ := repository.NewWorkshopRepository(ptr.transactionContext) | ||
181 | + type record struct { | ||
182 | + Sname string `json:"sname"` | ||
183 | + Rate float64 `json:"rate"` | ||
184 | + } | ||
185 | + | ||
186 | + workshop, err := workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}) | ||
187 | + if err != nil || workshop == nil { | ||
188 | + return nil, nil | ||
189 | + } | ||
190 | + productRecordDao, _ := dao.NewProductRecordDao(ptr.transactionContext) | ||
191 | + | ||
192 | + var input = []struct { | ||
193 | + name string | ||
194 | + t time.Time | ||
195 | + }{ | ||
196 | + {"today", utils.GetZeroTime(time.Now())}, | ||
197 | + {"current_week", utils.GetCurrentWeekFirstDay(time.Now())}, | ||
198 | + {"current_month", utils.GetCurrentMonthFirstDay(time.Now())}, | ||
199 | + } | ||
200 | + | ||
201 | + var response = make(map[string]interface{}) | ||
202 | + for _, v := range input { | ||
203 | + var result = make([]*record, 0) | ||
204 | + if err := productRecordDao.ProportionOfSecondLevelRecord(request.CompanyId, request.OrgId, request.WorkshopId, v.t, &result); err != nil { | ||
205 | + log.Logger.Error(err.Error()) | ||
206 | + return nil, err | ||
207 | + } | ||
208 | + response[v.name] = result | ||
209 | + } | ||
210 | + | ||
211 | + return response, nil | ||
212 | +} | ||
213 | + | ||
214 | +// 车间生产效率统计 | ||
215 | +func (ptr *PGCommonStatisticsService) WorkshopProductionEfficiencyStatistics(queryOptions map[string]interface{}) (interface{}, error) { | ||
216 | + var request = &HourProductiveStatisticsRequest{} | ||
217 | + if err := utils.LoadQueryObject(queryOptions, request); err != nil { | ||
218 | + return nil, err | ||
219 | + } | ||
220 | + | ||
221 | + workshopRepository, _ := repository.NewWorkshopRepository(ptr.transactionContext) | ||
222 | + type record struct { | ||
223 | + Oee float64 `json:"oee"` | ||
224 | + Pu float64 `json:"pu"` | ||
225 | + Tu float64 `json:"tu"` | ||
226 | + Qu float64 `json:"qu"` | ||
227 | + } | ||
228 | + | ||
229 | + workshop, err := workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}) | ||
230 | + if err != nil || workshop == nil { | ||
231 | + return nil, nil | ||
232 | + } | ||
233 | + productRecordDao, _ := dao.NewDeviceDailyRunningRecordDao(ptr.transactionContext) | ||
234 | + | ||
235 | + var input = []struct { | ||
236 | + name string | ||
237 | + t time.Time | ||
238 | + }{ | ||
239 | + {"today", utils.GetZeroTime(time.Now())}, | ||
240 | + {"current_week", utils.GetCurrentWeekFirstDay(time.Now())}, | ||
241 | + {"current_month", utils.GetCurrentMonthFirstDay(time.Now())}, | ||
242 | + } | ||
243 | + | ||
244 | + var response = make(map[string]interface{}) | ||
245 | + for _, v := range input { | ||
246 | + var result = record{} | ||
247 | + if err := productRecordDao.WorkshopProductionEfficiencyStatistics(request.CompanyId, request.OrgId, request.WorkshopId, v.t, &result); err != nil { | ||
248 | + log.Logger.Error(err.Error()) | ||
249 | + return nil, err | ||
250 | + } | ||
251 | + response[v.name] = result | ||
252 | + } | ||
253 | + | ||
254 | + return response, nil | ||
255 | +} | ||
256 | + | ||
257 | +// 设备运行统计 | ||
258 | +func (ptr *PGCommonStatisticsService) DeviceRunningStatistics(queryOptions map[string]interface{}) (interface{}, error) { | ||
259 | + var request = &DeviceRunningStatisticRequest{} | ||
260 | + if err := utils.LoadQueryObject(queryOptions, request); err != nil { | ||
261 | + return nil, err | ||
262 | + } | ||
263 | + | ||
264 | + deviceRepository, _ := repository.NewDeviceRepository(ptr.transactionContext) | ||
265 | + deviceRunningRecordRepository, _ := repository.NewDeviceDailyRunningRecordRepository(ptr.transactionContext) | ||
266 | + | ||
267 | + var t time.Time | ||
268 | + var err error | ||
269 | + if len(request.Date) > 0 { | ||
270 | + t, err = time.ParseInLocation("2006-01-02", request.Date, time.Local) | ||
271 | + if err != nil { | ||
272 | + log.Logger.Error(err.Error()) | ||
273 | + } | ||
274 | + } | ||
275 | + _, devices, err := deviceRepository.Find(map[string]interface{}{"companyId": request.CompanyId, "orgId": request.OrgId, "workshopId": request.WorkshopId, "lineId": request.LineId}) | ||
276 | + if err != nil { | ||
277 | + return nil, err | ||
278 | + } | ||
279 | + | ||
280 | + var response = make([]interface{}, 0) | ||
281 | + _, dailyRecords, err := deviceRunningRecordRepository.Find(map[string]interface{}{"companyId": request.CompanyId, "orgId": request.OrgId, "productDate": t}) | ||
282 | + for i := 0; i < len(devices); i++ { | ||
283 | + d := devices[i] | ||
284 | + if d.Ext == nil || d.Ext.DeviceExt == nil || d.Ext.DeviceExt.IsProductDevice == 0 { | ||
285 | + continue | ||
286 | + } | ||
287 | + var r *domain.DeviceDailyRunningRecord | ||
288 | + item := make(map[string]interface{}) | ||
289 | + //item["id"] = uuid.New().String() | ||
290 | + item["orgName"] = d.Ext.OrgName | ||
291 | + if d.WorkStation != nil { | ||
292 | + item["workshopName"] = d.WorkStation.WorkshopName | ||
293 | + item["lineName"] = d.WorkStation.LineName | ||
294 | + item["deviceName"] = d.DeviceName | ||
295 | + item["oee"] = 0 | ||
296 | + item["status"] = []struct{}{} | ||
297 | + } | ||
298 | + for j := 0; j < len(dailyRecords); j++ { | ||
299 | + if d.DeviceCode == dailyRecords[j].DeviceCode { | ||
300 | + r = dailyRecords[j] | ||
301 | + item["oee"] = r.DeviceRunningRecordInfo.OEE | ||
302 | + break | ||
303 | + } | ||
304 | + } | ||
305 | + if r != nil { | ||
306 | + m := r.UpdatedAt.Local().Hour()*60 + r.UpdatedAt.Minute() | ||
307 | + if r.UpdatedAt.Before(utils.GetZeroTime(time.Now())) { | ||
308 | + m = 60 * 24 | ||
309 | + } | ||
310 | + item["status"] = r.DeviceRunningRecordInfo.HourDeviceStatusDetail(m) | ||
311 | + item["status_info"] = r.DeviceRunningRecordInfo.TimeLineDeviceStatus | ||
312 | + } | ||
313 | + response = append(response, item) | ||
314 | + } | ||
315 | + return map[string]interface{}{ | ||
316 | + "devices": response, | ||
317 | + }, nil | ||
318 | +} | ||
319 | + | ||
320 | +type DeviceRunningStatisticRequest struct { | ||
321 | + CompanyId int `json:"companyId" valid:"Required"` | ||
322 | + OrgId int `json:"orgId" valid:"Required"` | ||
323 | + WorkshopId int `json:"workshopId"` | ||
324 | + LineId int `json:"lineId""` | ||
325 | + Date string `json:"date"` | ||
326 | +} | ||
327 | + | ||
328 | +func NewPGCommonStatisticsService(transactionContext *pgTransaction.TransactionContext) (*PGCommonStatisticsService, error) { | ||
329 | + if transactionContext == nil { | ||
330 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
331 | + } else { | ||
332 | + return &PGCommonStatisticsService{ | ||
333 | + transactionContext: transactionContext, | ||
334 | + }, nil | ||
335 | + } | ||
336 | +} |
1 | package domainService | 1 | package domainService |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "errors" | ||
4 | "fmt" | 5 | "fmt" |
5 | - "github.com/hibiken/asynq" | ||
6 | "github.com/linmadan/egglib-go/core/application" | 6 | "github.com/linmadan/egglib-go/core/application" |
7 | pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | 7 | pgTransaction "github.com/linmadan/egglib-go/transaction/pg" |
8 | - "github.com/linmadan/egglib-go/utils/json" | ||
9 | - "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" | ||
10 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | 8 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" |
11 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository" | 9 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository" |
12 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" | 10 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" |
@@ -32,11 +30,11 @@ type SubmitOptions struct { | @@ -32,11 +30,11 @@ type SubmitOptions struct { | ||
32 | // 工段ID | 30 | // 工段ID |
33 | SectionId int `cname:"工段" json:"sectionId" valid:"Required"` | 31 | SectionId int `cname:"工段" json:"sectionId" valid:"Required"` |
34 | // 生产小组ID | 32 | // 生产小组ID |
35 | - ProductGroupId int `cname:"生产小组" json:"productGroupId" valid:"Required"` | 33 | + ProductGroupId int `cname:"生产小组" json:"productGroupId"` |
36 | // 员工Id 用户唯一标识 | 34 | // 员工Id 用户唯一标识 |
37 | EmployeeId int `cname:"员工" json:"employeeId" valid:"Required"` | 35 | EmployeeId int `cname:"员工" json:"employeeId" valid:"Required"` |
38 | // 物料ID | 36 | // 物料ID |
39 | - UnitConversionId int `cname:"物料ID" json:"unitConversionId" valid:"Required"` | 37 | + UnitConversionId int `cname:"物料ID" json:"unitConversionId"` |
40 | // 重量 | 38 | // 重量 |
41 | Weigh float64 `cname:"重量" json:"weigh" valid:"Required"` | 39 | Weigh float64 `cname:"重量" json:"weigh" valid:"Required"` |
42 | } | 40 | } |
@@ -73,8 +71,10 @@ func (ptr *PGProductRecordService) SubmitProductRecord(productRecordType int, qu | @@ -73,8 +71,10 @@ func (ptr *PGProductRecordService) SubmitProductRecord(productRecordType int, qu | ||
73 | if workshop, err = workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}); err != nil { | 71 | if workshop, err = workshopRepository.FindOne(map[string]interface{}{"workshopId": request.WorkshopId}); err != nil { |
74 | return nil, err | 72 | return nil, err |
75 | } | 73 | } |
76 | - if uc, err = unitConversionRepository.FindOne(map[string]interface{}{"unitConversionId": request.UnitConversionId}); err != nil { | ||
77 | - return nil, err | 74 | + if request.UnitConversionId > 0 { |
75 | + if uc, err = unitConversionRepository.FindOne(map[string]interface{}{"unitConversionId": request.UnitConversionId}); err != nil { | ||
76 | + return nil, err | ||
77 | + } | ||
78 | } | 78 | } |
79 | if workstation, err = workshop.FindWorkStation(request.WorkshopId, request.LineId, request.SectionId); err != nil { | 79 | if workstation, err = workshop.FindWorkStation(request.WorkshopId, request.LineId, request.SectionId); err != nil { |
80 | return nil, err | 80 | return nil, err |
@@ -97,6 +97,12 @@ func (ptr *PGProductRecordService) SubmitProductRecord(productRecordType int, qu | @@ -97,6 +97,12 @@ func (ptr *PGProductRecordService) SubmitProductRecord(productRecordType int, qu | ||
97 | if productRecordType == domain.RecordTypeReceiveMaterial || productRecordType == domain.RecordTypeReturnMaterial { | 97 | if productRecordType == domain.RecordTypeReceiveMaterial || productRecordType == domain.RecordTypeReturnMaterial { |
98 | weight = (weight / uc.FromUnitQuantity.Quantity) * uc.ToUnitQuantity.Quantity | 98 | weight = (weight / uc.FromUnitQuantity.Quantity) * uc.ToUnitQuantity.Quantity |
99 | } | 99 | } |
100 | + // 退料、需要判断用户是否有领过料 | ||
101 | + if productRecordType == domain.RecordTypeReturnMaterial { | ||
102 | + if _, records, err := productRecordRepository.Find(map[string]interface{}{"companyId": request.CompanyId, "orgId": request.OrgId, "employeeId": user.UserId, "productPlanId": plan.ProductPlanId, "productRecordType": domain.RecordTypeReceiveMaterial, "limit": 1}); err == nil && len(records) == 0 { | ||
103 | + return nil, errors.New("当前批次未进行领料,无法退料") | ||
104 | + } | ||
105 | + } | ||
100 | 106 | ||
101 | record := &domain.ProductRecord{ | 107 | record := &domain.ProductRecord{ |
102 | CompanyId: request.CompanyId, | 108 | CompanyId: request.CompanyId, |
@@ -107,8 +113,8 @@ func (ptr *PGProductRecordService) SubmitProductRecord(productRecordType int, qu | @@ -107,8 +113,8 @@ func (ptr *PGProductRecordService) SubmitProductRecord(productRecordType int, qu | ||
107 | CreatedAt: time.Now(), | 113 | CreatedAt: time.Now(), |
108 | UpdatedAt: time.Now(), | 114 | UpdatedAt: time.Now(), |
109 | ProductRecordInfo: &domain.ProductRecordInfo{ | 115 | ProductRecordInfo: &domain.ProductRecordInfo{ |
110 | - ProductDate: plan.ProductDate.Format("2006-01-02"), | ||
111 | - OriginalWeigh: request.Weigh, | 116 | + ProductDate: plan.ProductDate.Local().Format("2006-01-02"), |
117 | + Original: request.Weigh, | ||
112 | Weigh: weight, | 118 | Weigh: weight, |
113 | WeighBefore: weight, | 119 | WeighBefore: weight, |
114 | UnitConversionId: request.UnitConversionId, | 120 | UnitConversionId: request.UnitConversionId, |
@@ -168,7 +174,7 @@ func (ptr *PGProductRecordService) BatchApprove(list []*domain.ProductRecord, ap | @@ -168,7 +174,7 @@ func (ptr *PGProductRecordService) BatchApprove(list []*domain.ProductRecord, ap | ||
168 | var productRecordRepository, _ = repository.NewProductRecordRepository(ptr.transactionContext) | 174 | var productRecordRepository, _ = repository.NewProductRecordRepository(ptr.transactionContext) |
169 | var record *domain.ProductRecord | 175 | var record *domain.ProductRecord |
170 | var err error | 176 | var err error |
171 | - log.Logger.Info("【自动审核二级品记录任务】 启动") | 177 | + log.Logger.Debug("【自动审核二级品记录任务】 启动") |
172 | var user *domain.User = &domain.User{} | 178 | var user *domain.User = &domain.User{} |
173 | userService := NewUserService() | 179 | userService := NewUserService() |
174 | if approveUserId > 0 { | 180 | if approveUserId > 0 { |
@@ -207,14 +213,6 @@ func (ptr *PGProductRecordService) BatchApprove(list []*domain.ProductRecord, ap | @@ -207,14 +213,6 @@ func (ptr *PGProductRecordService) BatchApprove(list []*domain.ProductRecord, ap | ||
207 | return struct{}{}, nil | 213 | return struct{}{}, nil |
208 | } | 214 | } |
209 | 215 | ||
210 | -func SendProductRecordStaticsJob(productRecord *domain.ProductRecord) error { | ||
211 | - task := asynq.NewTask(domain.TaskKeyPatternProductRecordStatics(), []byte(json.MarshalToString(productRecord))) | ||
212 | - | ||
213 | - client := asynq.NewClient(asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS}) | ||
214 | - _, err := client.Enqueue(task) | ||
215 | - return err | ||
216 | -} | ||
217 | - | ||
218 | func NewPGProductRecordService(transactionContext *pgTransaction.TransactionContext) (*PGProductRecordService, error) { | 216 | func NewPGProductRecordService(transactionContext *pgTransaction.TransactionContext) (*PGProductRecordService, error) { |
219 | if transactionContext == nil { | 217 | if transactionContext == nil { |
220 | return nil, fmt.Errorf("transactionContext参数不能为nil") | 218 | return nil, fmt.Errorf("transactionContext参数不能为nil") |
@@ -16,6 +16,10 @@ const ( | @@ -16,6 +16,10 @@ const ( | ||
16 | ProductSection4 = "包装" | 16 | ProductSection4 = "包装" |
17 | ) | 17 | ) |
18 | 18 | ||
19 | +const ( | ||
20 | + DefaultCCJUnitQuantity = 0.2 //kg 穿串机默认的换算数量 1串/0.1千克 | ||
21 | +) | ||
22 | + | ||
19 | //EmployeeProductStatics 员工产能统计 | 23 | //EmployeeProductStatics 员工产能统计 |
20 | func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain.ProductRecord) (interface{}, error) { | 24 | func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain.ProductRecord) (interface{}, error) { |
21 | 25 | ||
@@ -56,7 +60,10 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain. | @@ -56,7 +60,10 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain. | ||
56 | default: | 60 | default: |
57 | return nil, nil //ptr.personalProductStatics(productRecord) | 61 | return nil, nil //ptr.personalProductStatics(productRecord) |
58 | } | 62 | } |
59 | - | 63 | + if planId == 0 { |
64 | + log.Logger.Debug(fmt.Sprintf("工段:%v product_record 编号:%v 批次为0", productRecord.WorkStation.WorkStationId, productRecord.ProductRecordId)) | ||
65 | + return nil, nil | ||
66 | + } | ||
60 | productPlan, err = productPlanRepository.FindOne(map[string]interface{}{"productPlanId": planId}) | 67 | productPlan, err = productPlanRepository.FindOne(map[string]interface{}{"productPlanId": planId}) |
61 | if err != nil { | 68 | if err != nil { |
62 | return nil, err | 69 | return nil, err |
@@ -66,7 +73,7 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain. | @@ -66,7 +73,7 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain. | ||
66 | // 1.查询员工 -》 员工打卡记录 工位+打卡日期 | 73 | // 1.查询员工 -》 员工打卡记录 工位+打卡日期 |
67 | // 2.打卡记录的时间区间 在生产记录上报的时间范围内 | 74 | // 2.打卡记录的时间区间 在生产记录上报的时间范围内 |
68 | attendanceRecordDao, _ := dao.NewAttendanceRecordDao(ptr.transactionContext) | 75 | attendanceRecordDao, _ := dao.NewAttendanceRecordDao(ptr.transactionContext) |
69 | - _, attendanceRecords, err := attendanceRecordDao.ProductWorkStationAttendanceRecord(cid, oid, productRecord.WorkStation.WorkStationId, productRecord.CreatedAt) | 76 | + _, attendanceRecords, err := attendanceRecordDao.ProductWorkStationAttendanceRecord(cid, oid, productRecord.WorkStation.WorkStationId, time.Now()) //, productRecord.CreatedAt |
70 | if err != nil || len(attendanceRecords) == 0 { | 77 | if err != nil || len(attendanceRecords) == 0 { |
71 | return nil, err | 78 | return nil, err |
72 | } | 79 | } |
@@ -97,13 +104,15 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain. | @@ -97,13 +104,15 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain. | ||
97 | yesterdayOutputWeight float64 = 0 | 104 | yesterdayOutputWeight float64 = 0 |
98 | bestOutputWeight float64 = 0 | 105 | bestOutputWeight float64 = 0 |
99 | ) | 106 | ) |
100 | - if record, e := employeeProductRecordDao.WorkerProductRecord(cid, oid, planId, r.ProductWorker.UserId, productRecord.CreatedAt.AddDate(0, 0, -1)); e == nil && record != nil { | ||
101 | - yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight | ||
102 | - bestOutputWeight = record.ProductRecordInfo.BestOutputWeight | ||
103 | - | ||
104 | - } else { | ||
105 | - if record, e := employeeProductRecordDao.WorkerBestOutputRecord(cid, oid, planId, r.ProductWorker.UserId); e == nil && record != nil { | 107 | + if employeeProductRecord.ProductRecordInfo.BestOutputWeight > 0 { |
108 | + if record, e := employeeProductRecordDao.WorkerProductRecord(cid, oid, planId, r.ProductWorker.UserId, productRecord.CreatedAt.AddDate(0, 0, -1)); e == nil && record != nil { | ||
106 | yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight | 109 | yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight |
110 | + bestOutputWeight = record.ProductRecordInfo.BestOutputWeight | ||
111 | + | ||
112 | + } else { | ||
113 | + if record, e := employeeProductRecordDao.WorkerBestOutputRecord(cid, oid, planId, r.ProductWorker.UserId); e == nil && record != nil { | ||
114 | + yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight | ||
115 | + } | ||
107 | } | 116 | } |
108 | } | 117 | } |
109 | 118 | ||
@@ -139,7 +148,7 @@ func newEmployeeProductRecord(productRecord *domain.ProductRecord, participateTy | @@ -139,7 +148,7 @@ func newEmployeeProductRecord(productRecord *domain.ProductRecord, participateTy | ||
139 | Ext: productPlan.Ext, | 148 | Ext: productPlan.Ext, |
140 | Version: 1, | 149 | Version: 1, |
141 | ProductRecordInfo: &domain.ProductRecordStaticInfo{ | 150 | ProductRecordInfo: &domain.ProductRecordStaticInfo{ |
142 | - ProductDate: productRecord.CreatedAt.Format("2006-01-02"), | 151 | + ProductDate: productRecord.CreatedAt.Local().Format("2006-01-02"), |
143 | ProductPlanId: productRecord.ProductRecordInfo.ProductPlanId, | 152 | ProductPlanId: productRecord.ProductRecordInfo.ProductPlanId, |
144 | PlanProductName: productRecord.ProductRecordInfo.PlanProductName, | 153 | PlanProductName: productRecord.ProductRecordInfo.PlanProductName, |
145 | BatchNumber: productRecord.ProductRecordInfo.BatchNumber, | 154 | BatchNumber: productRecord.ProductRecordInfo.BatchNumber, |
@@ -191,6 +200,7 @@ func FindGroupMembers(productGroupRepository domain.ProductGroupRepository, comp | @@ -191,6 +200,7 @@ func FindGroupMembers(productGroupRepository domain.ProductGroupRepository, comp | ||
191 | u := groups[i].GroupMembers[j] | 200 | u := groups[i].GroupMembers[j] |
192 | u.GroupId = groups[i].ProductGroupId | 201 | u.GroupId = groups[i].ProductGroupId |
193 | u.GroupName = groups[i].GroupName | 202 | u.GroupName = groups[i].GroupName |
203 | + u.WorkOn = groups[i].WorkOn | ||
194 | result[keyFunc(u.UserId)] = u | 204 | result[keyFunc(u.UserId)] = u |
195 | } | 205 | } |
196 | } | 206 | } |
@@ -236,13 +246,15 @@ func (ptr *PGProductRecordService) personalProductStatics(productRecord *domain. | @@ -236,13 +246,15 @@ func (ptr *PGProductRecordService) personalProductStatics(productRecord *domain. | ||
236 | yesterdayOutputWeight float64 = 0 | 246 | yesterdayOutputWeight float64 = 0 |
237 | bestOutputWeight float64 = 0 | 247 | bestOutputWeight float64 = 0 |
238 | ) | 248 | ) |
239 | - if record, e := employeeProductRecordDao.WorkerProductRecord(cid, oid, planId, productRecord.ProductWorker.UserId, productRecord.CreatedAt.AddDate(0, 0, -1)); e == nil && record != nil { | ||
240 | - yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight | ||
241 | - bestOutputWeight = record.ProductRecordInfo.BestOutputWeight | ||
242 | - | ||
243 | - } else { | ||
244 | - if record, e := employeeProductRecordDao.WorkerBestOutputRecord(cid, oid, planId, productRecord.ProductWorker.UserId); e == nil && record != nil { | 249 | + if employeeProductRecord.ProductRecordInfo.BestOutputWeight == 0 { |
250 | + if record, e := employeeProductRecordDao.WorkerProductRecord(cid, oid, planId, productRecord.ProductWorker.UserId, productRecord.CreatedAt.AddDate(0, 0, -1)); e == nil && record != nil { | ||
245 | yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight | 251 | yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight |
252 | + bestOutputWeight = record.ProductRecordInfo.BestOutputWeight | ||
253 | + | ||
254 | + } else { | ||
255 | + if record, e := employeeProductRecordDao.WorkerBestOutputRecord(cid, oid, planId, productRecord.ProductWorker.UserId); e == nil && record != nil { | ||
256 | + yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight | ||
257 | + } | ||
246 | } | 258 | } |
247 | } | 259 | } |
248 | 260 | ||
@@ -271,7 +283,10 @@ func (ptr *PGProductRecordService) WorkshopProductStatics(productRecord *domain. | @@ -271,7 +283,10 @@ func (ptr *PGProductRecordService) WorkshopProductStatics(productRecord *domain. | ||
271 | productPlan *domain.ProductPlan | 283 | productPlan *domain.ProductPlan |
272 | err error | 284 | err error |
273 | ) | 285 | ) |
274 | - | 286 | + if planId == 0 { |
287 | + log.Logger.Debug(fmt.Sprintf("工段:%v product_record 编号:%v 批次为0", productRecord.WorkStation.WorkStationId, productRecord.ProductRecordId)) | ||
288 | + return nil, nil | ||
289 | + } | ||
275 | productPlan, err = productPlanRepository.FindOne(map[string]interface{}{"productPlanId": planId}) | 290 | productPlan, err = productPlanRepository.FindOne(map[string]interface{}{"productPlanId": planId}) |
276 | if err != nil { | 291 | if err != nil { |
277 | return nil, err | 292 | return nil, err |
@@ -320,7 +335,7 @@ func newWorkshopProductRecord(productRecord *domain.ProductRecord, productPlan * | @@ -320,7 +335,7 @@ func newWorkshopProductRecord(productRecord *domain.ProductRecord, productPlan * | ||
320 | WorkStation: productRecord.WorkStation, | 335 | WorkStation: productRecord.WorkStation, |
321 | //WorkOn: productPlan.WorkOn, | 336 | //WorkOn: productPlan.WorkOn, |
322 | //ParticipateType: participateType, | 337 | //ParticipateType: participateType, |
323 | - ProductDate: productRecord.CreatedAt.Format("2006-01-02"), | 338 | + ProductDate: productRecord.CreatedAt.Local().Format("2006-01-02"), |
324 | ProductWeigh: 0, | 339 | ProductWeigh: 0, |
325 | SecondLevelWeigh: 0, | 340 | SecondLevelWeigh: 0, |
326 | CreatedAt: time.Now(), | 341 | CreatedAt: time.Now(), |
@@ -328,7 +343,7 @@ func newWorkshopProductRecord(productRecord *domain.ProductRecord, productPlan * | @@ -328,7 +343,7 @@ func newWorkshopProductRecord(productRecord *domain.ProductRecord, productPlan * | ||
328 | Ext: productPlan.Ext, | 343 | Ext: productPlan.Ext, |
329 | Version: 1, | 344 | Version: 1, |
330 | ProductRecordInfo: &domain.ProductRecordStaticInfo{ | 345 | ProductRecordInfo: &domain.ProductRecordStaticInfo{ |
331 | - ProductDate: productRecord.CreatedAt.Format("2006-01-02"), | 346 | + ProductDate: productRecord.CreatedAt.Local().Format("2006-01-02"), |
332 | ProductPlanId: productRecord.ProductRecordInfo.ProductPlanId, | 347 | ProductPlanId: productRecord.ProductRecordInfo.ProductPlanId, |
333 | PlanProductName: productRecord.ProductRecordInfo.PlanProductName, | 348 | PlanProductName: productRecord.ProductRecordInfo.PlanProductName, |
334 | BatchNumber: productRecord.ProductRecordInfo.BatchNumber, | 349 | BatchNumber: productRecord.ProductRecordInfo.BatchNumber, |
@@ -23,11 +23,11 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain. | @@ -23,11 +23,11 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain. | ||
23 | attendanceRecordRepository, _ = repository.NewProductAttendanceRecordRepository(ptr.transactionContext) | 23 | attendanceRecordRepository, _ = repository.NewProductAttendanceRecordRepository(ptr.transactionContext) |
24 | isSignIn = true | 24 | isSignIn = true |
25 | record *domain.ProductAttendanceRecord | 25 | record *domain.ProductAttendanceRecord |
26 | - workStationId string //具体工位 | ||
27 | - workStation *domain.WorkStation | ||
28 | - attendanceType int = domain.ParticipateNormal | ||
29 | - worker *domain.User | ||
30 | - org *domain.Org | 26 | + //workStationId string //具体工位 |
27 | + workStation *domain.WorkStation | ||
28 | + attendanceType int = domain.ParticipateNormal | ||
29 | + worker *domain.User | ||
30 | + org *domain.Org | ||
31 | ) | 31 | ) |
32 | 32 | ||
33 | if err := report.Valid(); err != nil { | 33 | if err := report.Valid(); err != nil { |
@@ -68,19 +68,42 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain. | @@ -68,19 +68,42 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain. | ||
68 | 68 | ||
69 | beginTime := utils.GetZeroTime(report.ActionTime) | 69 | beginTime := utils.GetZeroTime(report.ActionTime) |
70 | endTime := report.ActionTime | 70 | endTime := report.ActionTime |
71 | - _, records, _ := attendanceRecordDao.WorkerAttendanceRecords(cid, oid, worker.UserId, workStationId, beginTime, endTime) | 71 | + _, records, _ := attendanceRecordDao.WorkerAttendanceRecords(cid, oid, worker.UserId, "", beginTime, endTime) |
72 | for i := 0; i < len(records); i++ { | 72 | for i := 0; i < len(records); i++ { |
73 | r := records[i] | 73 | r := records[i] |
74 | + if workStation.WorkStationId == r.WorkStation.WorkStationId { | ||
75 | + continue | ||
76 | + } | ||
77 | + if !utils.TimeIsZero(r.SignIn) && utils.TimeIsZero(r.SignOut) { | ||
78 | + if utils.TimeAfterEqual(report.ActionTime, r.SignIn) { | ||
79 | + r.SignOut = report.ActionTime | ||
80 | + r.WorkTimeBefore = r.ComputeWorkTimeBefore() | ||
81 | + log.Logger.Debug(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 在其他工段打卡 下线当前工段:%v 签退 %v", worker.UserName, worker.UserId, r.WorkStation.SectionName, report)) | ||
82 | + if _, err = attendanceRecordRepository.Save(r); err != nil { | ||
83 | + return nil, err | ||
84 | + } | ||
85 | + } else { | ||
86 | + log.Logger.Debug(fmt.Sprintf("【考勤汇报】 考勤记录不合法,操作时间小于签到时间 考勤ID:%v 用户:%v 打卡时间:%v", r.ProductAttendanceId, worker.UserId, report.ActionTime)) | ||
87 | + return struct{}{}, nil | ||
88 | + } | ||
89 | + break | ||
90 | + } | ||
91 | + } | ||
92 | + for i := 0; i < len(records); i++ { | ||
93 | + r := records[i] | ||
94 | + if workStation.WorkStationId != r.WorkStation.WorkStationId { | ||
95 | + continue | ||
96 | + } | ||
74 | // 操作时间 < 签到时间 | 97 | // 操作时间 < 签到时间 |
75 | if utils.TimeAfterEqual(r.SignIn, report.ActionTime) { | 98 | if utils.TimeAfterEqual(r.SignIn, report.ActionTime) { |
76 | - log.Logger.Info(fmt.Sprintf("【考勤汇报】 考勤记录不合法,操作时间小于签到时间 考勤ID:%v 用户:%v 打卡时间:%v", r.ProductAttendanceId, worker.UserId, report.ActionTime)) | 99 | + log.Logger.Debug(fmt.Sprintf("【考勤汇报】 考勤记录不合法,操作时间小于签到时间 考勤ID:%v 用户:%v 打卡时间:%v", r.ProductAttendanceId, worker.UserId, report.ActionTime)) |
77 | return struct{}{}, nil | 100 | return struct{}{}, nil |
78 | } | 101 | } |
79 | // 存在完整打卡记录 | 102 | // 存在完整打卡记录 |
80 | // 1. 如果在区间内,退出 | 103 | // 1. 如果在区间内,退出 |
81 | if !utils.TimeIsZero(r.SignIn) && !utils.TimeIsZero(r.SignOut) { | 104 | if !utils.TimeIsZero(r.SignIn) && !utils.TimeIsZero(r.SignOut) { |
82 | if utils.TimeBeforeEqual(r.SignIn, report.ActionTime) && utils.TimeAfterEqual(r.SignOut, report.ActionTime) { | 105 | if utils.TimeBeforeEqual(r.SignIn, report.ActionTime) && utils.TimeAfterEqual(r.SignOut, report.ActionTime) { |
83 | - log.Logger.Info(fmt.Sprintf("【考勤汇报】 已存在同一时间段的考勤记录 考勤ID:%v 用户:%v 打卡时间:%v", r.ProductAttendanceId, worker.UserId, report.ActionTime)) | 106 | + log.Logger.Debug(fmt.Sprintf("【考勤汇报】 已存在同一时间段的考勤记录 考勤ID:%v 用户:%v 打卡时间:%v", r.ProductAttendanceId, worker.UserId, report.ActionTime)) |
84 | return struct{}{}, nil | 107 | return struct{}{}, nil |
85 | } | 108 | } |
86 | continue | 109 | continue |
@@ -88,6 +111,11 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain. | @@ -88,6 +111,11 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain. | ||
88 | // 存在未结束的打卡记录 | 111 | // 存在未结束的打卡记录 |
89 | // 1.满足条件-签退 | 112 | // 1.满足条件-签退 |
90 | if !utils.TimeIsZero(r.SignIn) && utils.TimeIsZero(r.SignOut) { | 113 | if !utils.TimeIsZero(r.SignIn) && utils.TimeIsZero(r.SignOut) { |
114 | + // 五分钟内重复打卡不算数 | ||
115 | + if r.SignIn.Add(time.Minute * 5).After(report.ActionTime) { | ||
116 | + log.Logger.Debug(fmt.Sprintf("【考勤汇报】 打卡未满五分钟 考勤ID:%v 用户:%v 打卡时间:%v", r.ProductAttendanceId, worker.UserId, report.ActionTime)) | ||
117 | + return struct{}{}, nil | ||
118 | + } | ||
91 | if utils.TimeBeforeEqual(r.SignIn, report.ActionTime) { | 119 | if utils.TimeBeforeEqual(r.SignIn, report.ActionTime) { |
92 | isSignIn = false | 120 | isSignIn = false |
93 | record = r | 121 | record = r |
@@ -115,11 +143,11 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain. | @@ -115,11 +143,11 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain. | ||
115 | ProductGroupId: groupId, | 143 | ProductGroupId: groupId, |
116 | }), | 144 | }), |
117 | } | 145 | } |
118 | - log.Logger.Info(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 签到 %v", worker.UserName, worker.UserId, report)) | 146 | + log.Logger.Debug(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 签到 %v", worker.UserName, worker.UserId, report)) |
119 | } else { | 147 | } else { |
120 | record.SignOut = report.ActionTime | 148 | record.SignOut = report.ActionTime |
121 | record.WorkTimeBefore = record.ComputeWorkTimeBefore() | 149 | record.WorkTimeBefore = record.ComputeWorkTimeBefore() |
122 | - log.Logger.Info(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 签退 %v", worker.UserName, worker.UserId, report)) | 150 | + log.Logger.Debug(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 签退 %v", worker.UserName, worker.UserId, report)) |
123 | } | 151 | } |
124 | 152 | ||
125 | if _, err = attendanceRecordRepository.Save(record); err != nil { | 153 | if _, err = attendanceRecordRepository.Save(record); err != nil { |
1 | +package domainService | ||
2 | + | ||
3 | +import ( | ||
4 | + "encoding/json" | ||
5 | + "fmt" | ||
6 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/dao" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/redis" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository" | ||
11 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" | ||
12 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" | ||
13 | + "strconv" | ||
14 | + "time" | ||
15 | +) | ||
16 | + | ||
17 | +type PGWorkshopDataConsumeService struct { | ||
18 | + transactionContext *pgTransaction.TransactionContext | ||
19 | +} | ||
20 | + | ||
21 | +// 消费设备生产数据 | ||
22 | +func (ptr *PGWorkshopDataConsumeService) Consume(companyId, orgId int, record *domain.DeviceCollection) (interface{}, error) { | ||
23 | + var ( | ||
24 | + deviceRunningData *domain.DeviceRunningData | ||
25 | + deviceRunningRecord *domain.DeviceRunningRecord | ||
26 | + deviceDailyRecord *domain.DeviceDailyRunningRecord | ||
27 | + workStation *domain.WorkStation | ||
28 | + device *domain.Device | ||
29 | + planId int | ||
30 | + err error | ||
31 | + plan *domain.ProductPlanDispatchRecord | ||
32 | + datetime time.Time | ||
33 | + ) | ||
34 | + var ( | ||
35 | + deviceRepository, _ = repository.NewDeviceRepository(ptr.transactionContext) | ||
36 | + deviceRunningRecordRepository, _ = repository.NewDeviceRunningRecordRepository(ptr.transactionContext) | ||
37 | + ) | ||
38 | + | ||
39 | + if deviceRunningData, err = ptr.newDeviceRunningData(record); err != nil { | ||
40 | + return nil, err | ||
41 | + } | ||
42 | + | ||
43 | + // 0.初始化 从缓存捞数据、没取到查询库 | ||
44 | + deviceDailyRecord, err = redis.GetDeviceDailyRunningRecord(time.Now(), deviceRunningData.DeviceCode) | ||
45 | + if err == domain.ErrorNotFound { | ||
46 | + err = nil | ||
47 | + } | ||
48 | + if err != nil { | ||
49 | + return nil, err | ||
50 | + } | ||
51 | + | ||
52 | + if deviceDailyRecord != nil { | ||
53 | + workStation = deviceDailyRecord.WorkStation | ||
54 | + planId = deviceDailyRecord.DeviceRunningRecordInfo.ProductPlanId | ||
55 | + device = &domain.Device{ | ||
56 | + DeviceId: deviceDailyRecord.DeviceId, | ||
57 | + DeviceCode: deviceDailyRecord.DeviceCode, | ||
58 | + } | ||
59 | + } else { | ||
60 | + | ||
61 | + // 0.1.查询记录对应的工段、批次 | ||
62 | + // 0.2.保存一天当日记录 | ||
63 | + if device, err = deviceRepository.FindOne(map[string]interface{}{"companyId": companyId, "orgId": orgId, "deviceCode": deviceRunningData.DeviceCode}); err != nil { | ||
64 | + log.Logger.Error(fmt.Sprintf("【设备数据-消费】 未找到设备:%v 数据数据", deviceRunningData.DeviceCode)) | ||
65 | + return nil, nil | ||
66 | + } | ||
67 | + workStation = device.WorkStation | ||
68 | + | ||
69 | + var saveErr error | ||
70 | + if deviceDailyRecord, saveErr = ptr.saveDeviceDailyRunningRecord(companyId, orgId, workStation, device, planId, deviceRunningData); err != nil { | ||
71 | + return nil, err | ||
72 | + } | ||
73 | + defer func() { | ||
74 | + if saveErr != nil { | ||
75 | + redis.RemoveDeviceDailyRunningRecord(time.Now(), deviceRunningData.DeviceCode) | ||
76 | + } | ||
77 | + }() | ||
78 | + } | ||
79 | + | ||
80 | + // 封箱机、串串机需要定位到批次 | ||
81 | + if record.DeviceType == domain.DeviceTypeFengXiangJi || record.DeviceType == domain.DeviceTypeChuanChuanJi { | ||
82 | + datetime, _ = time.Parse("2006-01-02", deviceRunningData.Date) | ||
83 | + if plan, err = ptr.findDeviceProductPlan(companyId, orgId, workStation.WorkStationId, datetime, deviceRunningData.ProductType); err != nil { | ||
84 | + log.Logger.Error(err.Error()) | ||
85 | + } else { | ||
86 | + planId = plan.PlanDispatchRecordExt.ProductPlanId | ||
87 | + } | ||
88 | + } | ||
89 | + | ||
90 | + // 1.保存设备运行记录 | ||
91 | + deviceRunningRecord, _ = ptr.newDeviceRunningRecord(companyId, orgId, workStation, device, deviceRunningData) | ||
92 | + if _, err = deviceRunningRecordRepository.Save(deviceRunningRecord); err != nil { | ||
93 | + return nil, err | ||
94 | + } | ||
95 | + // 2.保存设备生产记录 | ||
96 | + if record.DeviceType == domain.DeviceTypeChuanChuanJi && plan != nil { | ||
97 | + | ||
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) | ||
103 | + } | ||
104 | + | ||
105 | + // 3.更新 设备每日运行记录(汇总) - redis更新 十分钟异步刷库 | ||
106 | + deviceDailyRecord.AddDeviceRunningData(deviceRunningData.CollectionTime, deviceRunningData) | ||
107 | + if err = redis.SaveDeviceDailyRunningRecord(deviceDailyRecord); err != nil { | ||
108 | + return nil, err | ||
109 | + } | ||
110 | + return nil, nil | ||
111 | +} | ||
112 | + | ||
113 | +func (ptr *PGWorkshopDataConsumeService) newDeviceRunningData(record *domain.DeviceCollection) (*domain.DeviceRunningData, error) { | ||
114 | + var err error | ||
115 | + var unitQuantity float64 = DefaultCCJUnitQuantity // 单位数量 | ||
116 | + var data = &domain.DeviceRunningData{ | ||
117 | + DeviceCollectionId: record.DeviceCollectionId, | ||
118 | + WorkShopName: record.WorkShopName, | ||
119 | + CollectionTime: record.CollectionTime, | ||
120 | + DeviceCode: record.DeviceSn, | ||
121 | + DeviceType: record.DeviceType, | ||
122 | + StartupStatus: int(record.StartupStatus), | ||
123 | + ComStatus: int(record.ComStatus), | ||
124 | + //UnitQuantity: unitQuantity, | ||
125 | + } | ||
126 | + var mBytes []byte | ||
127 | + if mBytes, err = json.Marshal(record.Values); err != nil { | ||
128 | + return nil, err | ||
129 | + } | ||
130 | + var formatDate = func(y, m, d string) (string, error) { | ||
131 | + yd, _ := strconv.Atoi(y) | ||
132 | + md, _ := strconv.Atoi(m) | ||
133 | + dd, _ := strconv.Atoi(d) | ||
134 | + t := time.Date(yd, time.Month(md), dd, 0, 0, 0, 0, time.Local) | ||
135 | + return t.Local().Format("2006-01-02"), nil | ||
136 | + } | ||
137 | + switch record.DeviceType { | ||
138 | + //包馅机 | ||
139 | + case domain.DeviceTypeBaoXianJi: | ||
140 | + deviceBaoXianJi := &domain.DeviceBaoXianJi{} | ||
141 | + err = json.Unmarshal(mBytes, deviceBaoXianJi) | ||
142 | + if err != nil { | ||
143 | + break | ||
144 | + } | ||
145 | + data.Count = int(deviceBaoXianJi.Count) | ||
146 | + break | ||
147 | + //油炸机 | ||
148 | + case domain.DeviceTypeYouZhaJi: | ||
149 | + deviceYouZhaJi := &domain.DeviceYouZhaJi{} | ||
150 | + err = json.Unmarshal(mBytes, deviceYouZhaJi) | ||
151 | + if err != nil { | ||
152 | + break | ||
153 | + } | ||
154 | + data.Temp1 = deviceYouZhaJi.FrontTemp | ||
155 | + break | ||
156 | + //串串机 | ||
157 | + case domain.DeviceTypeChuanChuanJi: | ||
158 | + deviceChuanChuanJi := &domain.DeviceChuanChuanJi{} | ||
159 | + err = json.Unmarshal(mBytes, deviceChuanChuanJi) | ||
160 | + if err != nil { | ||
161 | + break | ||
162 | + } | ||
163 | + data.Count = int(deviceChuanChuanJi.Count) | ||
164 | + data.ProductType = deviceChuanChuanJi.ProductType | ||
165 | + if data.Date, err = formatDate(deviceChuanChuanJi.Year, deviceChuanChuanJi.Month, deviceChuanChuanJi.Day); err != nil { | ||
166 | + return nil, err | ||
167 | + } | ||
168 | + data.UnitQuantity = unitQuantity | ||
169 | + break | ||
170 | + //速冻线 | ||
171 | + case domain.DeviceTypeSuDongXian: | ||
172 | + deviceSuDongXian := &domain.DeviceSuDongXian{} | ||
173 | + err = json.Unmarshal(mBytes, deviceSuDongXian) | ||
174 | + if err != nil { | ||
175 | + break | ||
176 | + } | ||
177 | + data.Temp1 = deviceSuDongXian.CurrTemp | ||
178 | + break | ||
179 | + //封口机 | ||
180 | + case domain.DeviceTypeFengKouJi: | ||
181 | + deviceFengKouJi := &domain.DeviceFengKouJi{} | ||
182 | + err = json.Unmarshal(mBytes, deviceFengKouJi) | ||
183 | + if err != nil { | ||
184 | + break | ||
185 | + } | ||
186 | + data.Count = int(deviceFengKouJi.Count) | ||
187 | + data.ProductType = deviceFengKouJi.ProductType | ||
188 | + if data.Date, err = formatDate(deviceFengKouJi.Year, deviceFengKouJi.Month, deviceFengKouJi.Day); err != nil { | ||
189 | + return nil, err | ||
190 | + } | ||
191 | + break | ||
192 | + //封箱机 | ||
193 | + case domain.DeviceTypeFengXiangJi: | ||
194 | + deviceFengXiangJi := &domain.DeviceFengXiangJi{} | ||
195 | + err = json.Unmarshal(mBytes, deviceFengXiangJi) | ||
196 | + if err != nil { | ||
197 | + break | ||
198 | + } | ||
199 | + data.Count = int(deviceFengXiangJi.Count) | ||
200 | + data.ProductType = deviceFengXiangJi.ProductType | ||
201 | + if data.Date, err = formatDate(deviceFengXiangJi.Year, deviceFengXiangJi.Month, deviceFengXiangJi.Day); err != nil { | ||
202 | + return nil, err | ||
203 | + } | ||
204 | + break | ||
205 | + //打浆机 | ||
206 | + case domain.DeviceTypeDaJiangJi: | ||
207 | + default: | ||
208 | + } | ||
209 | + return data, nil | ||
210 | +} | ||
211 | + | ||
212 | +func (ptr *PGWorkshopDataConsumeService) newDeviceRunningRecord(companyId, orgId int, workStation *domain.WorkStation, device *domain.Device, data *domain.DeviceRunningData) (*domain.DeviceRunningRecord, error) { | ||
213 | + return &domain.DeviceRunningRecord{ | ||
214 | + CompanyId: companyId, | ||
215 | + OrgId: orgId, | ||
216 | + WorkStation: workStation, | ||
217 | + DeviceId: device.DeviceId, | ||
218 | + DeviceCode: device.DeviceCode, | ||
219 | + DeviceRunningRecordInfo: data, | ||
220 | + CreatedAt: time.Now(), | ||
221 | + }, nil | ||
222 | +} | ||
223 | + | ||
224 | +func (ptr *PGWorkshopDataConsumeService) newProductRecord(companyId int, orgId int, workStation *domain.WorkStation, device *domain.Device, data *domain.DeviceRunningData, plan *domain.ProductPlanDispatchRecord) (*domain.ProductRecord, error) { | ||
225 | + result := &domain.ProductRecord{ | ||
226 | + CompanyId: companyId, | ||
227 | + OrgId: orgId, | ||
228 | + WorkStation: workStation, | ||
229 | + ProductRecordType: domain.RecordTypeWeigh, | ||
230 | + ProductWorker: &domain.User{}, | ||
231 | + CreatedAt: data.CollectionTime, | ||
232 | + UpdatedAt: time.Now(), | ||
233 | + ProductRecordInfo: &domain.ProductRecordInfo{ | ||
234 | + ProductDate: data.CollectionTime.Local().Format("2006-01-02"), | ||
235 | + Original: float64(data.Count), | ||
236 | + Weigh: float64(data.Count) * DefaultCCJUnitQuantity, | ||
237 | + WeighBefore: float64(data.Count) * DefaultCCJUnitQuantity, | ||
238 | + ApproveStatus: domain.AttendanceNotApprove, | ||
239 | + ProductPlanId: plan.PlanDispatchRecordExt.ProductPlanId, | ||
240 | + PlanProductName: plan.PlanDispatchRecordExt.PlanProductName, | ||
241 | + BatchNumber: plan.BatchNumber, | ||
242 | + }, | ||
243 | + Ext: domain.NewExt(""), | ||
244 | + } | ||
245 | + if device.Ext != nil { | ||
246 | + result.Ext = domain.NewExt(device.Ext.OrgName) | ||
247 | + } | ||
248 | + return result, nil | ||
249 | +} | ||
250 | + | ||
251 | +func (ptr *PGWorkshopDataConsumeService) saveDeviceDailyRunningRecord(companyId, orgId int, workStation *domain.WorkStation, device *domain.Device, planId int, data *domain.DeviceRunningData) (*domain.DeviceDailyRunningRecord, error) { | ||
252 | + var ( | ||
253 | + record *domain.DeviceDailyRunningRecord | ||
254 | + err error | ||
255 | + ) | ||
256 | + deviceDailyRunningRecordRepository, _ := repository.NewDeviceDailyRunningRecordRepository(ptr.transactionContext) | ||
257 | + if record, err = deviceDailyRunningRecordRepository.FindOne(map[string]interface{}{ | ||
258 | + "workStationId": workStation.WorkStationId, | ||
259 | + "deviceCode": data.DeviceCode, | ||
260 | + "productDate": utils.GetZeroTime(time.Now()), | ||
261 | + }); err != nil { | ||
262 | + if err != domain.ErrorNotFound { | ||
263 | + return nil, err | ||
264 | + } | ||
265 | + } | ||
266 | + if record != nil { | ||
267 | + return record, nil | ||
268 | + } | ||
269 | + recordInfo := domain.NewDeviceRunningRecordInfo() | ||
270 | + recordInfo.ProductPlanId = planId | ||
271 | + recordInfo.DeviceName = device.DeviceName | ||
272 | + recordInfo.OrgName = device.Ext.OrgName | ||
273 | + record = &domain.DeviceDailyRunningRecord{ | ||
274 | + CompanyId: companyId, | ||
275 | + OrgId: orgId, | ||
276 | + WorkStation: workStation, | ||
277 | + DeviceId: device.DeviceId, | ||
278 | + DeviceCode: device.DeviceCode, | ||
279 | + ProductDate: utils.GetZeroTime(time.Now()), | ||
280 | + DeviceRunningRecordInfo: recordInfo, | ||
281 | + CreatedAt: time.Now(), | ||
282 | + UpdatedAt: time.Now(), | ||
283 | + } | ||
284 | + if record, err = deviceDailyRunningRecordRepository.Save(record); err != nil { | ||
285 | + return nil, err | ||
286 | + } | ||
287 | + | ||
288 | + if device.MarkAsProductDevice() { | ||
289 | + deviceRepository, _ := repository.NewDeviceRepository(ptr.transactionContext) | ||
290 | + if device, err = deviceRepository.Save(device); err != nil { | ||
291 | + return nil, err | ||
292 | + } | ||
293 | + } | ||
294 | + return record, nil | ||
295 | +} | ||
296 | + | ||
297 | +// 查找设备的生产计划,如果计划没有上线的话将他上线 | ||
298 | +func (ptr *PGWorkshopDataConsumeService) findDeviceProductPlan(companyId, orgId int, workStationId string, date time.Time, productCode string) (*domain.ProductPlanDispatchRecord, error) { | ||
299 | + planDispatchRecordDao, _ := dao.NewProductPlanDispatchRecord(ptr.transactionContext) | ||
300 | + planDispatchRecordRepository, _ := repository.NewProductPlanDispatchRecordRepository(ptr.transactionContext) | ||
301 | + var setPlanOnline = false | ||
302 | + record, err := planDispatchRecordDao.DeviceProductPlan(companyId, orgId, workStationId, date, productCode, domain.PlanOnline) | ||
303 | + if err == domain.ErrorNotFound { | ||
304 | + if record, err = planDispatchRecordDao.DeviceProductPlan(companyId, orgId, workStationId, date, productCode, domain.PlanOffline); err != nil { | ||
305 | + return nil, err | ||
306 | + } else { | ||
307 | + setPlanOnline = true | ||
308 | + } | ||
309 | + } | ||
310 | + if setPlanOnline { | ||
311 | + record.ChangeStatus(domain.PlanOnline) | ||
312 | + if record, err = planDispatchRecordRepository.Save(record); err != nil { | ||
313 | + return nil, err | ||
314 | + } | ||
315 | + } | ||
316 | + return record, nil | ||
317 | +} | ||
318 | + | ||
319 | +func NewPGWorkshopDataConsumeService(transactionContext *pgTransaction.TransactionContext) (*PGWorkshopDataConsumeService, error) { | ||
320 | + if transactionContext == nil { | ||
321 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
322 | + } else { | ||
323 | + return &PGWorkshopDataConsumeService{ | ||
324 | + transactionContext: transactionContext, | ||
325 | + }, nil | ||
326 | + } | ||
327 | +} |
1 | +package domainService | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
6 | + "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/infrastructure/dao" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository" | ||
11 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" | ||
12 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" | ||
13 | + "time" | ||
14 | +) | ||
15 | + | ||
16 | +type PGWorkshopPlanCompletionRecordService struct { | ||
17 | + transactionContext *pgTransaction.TransactionContext | ||
18 | +} | ||
19 | + | ||
20 | +func NewPGWorkshopPlanCompletionRecordService(transactionContext *pgTransaction.TransactionContext) (*PGWorkshopPlanCompletionRecordService, error) { | ||
21 | + if transactionContext == nil { | ||
22 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
23 | + } else { | ||
24 | + return &PGWorkshopPlanCompletionRecordService{ | ||
25 | + transactionContext: transactionContext, | ||
26 | + }, nil | ||
27 | + } | ||
28 | +} | ||
29 | + | ||
30 | +// 车间完成统计 | ||
31 | +func (ptr *PGWorkshopPlanCompletionRecordService) WorkshopPlanCompletion(begin time.Time, end time.Time) error { | ||
32 | + type record struct { | ||
33 | + PlanWeight float64 `json:"plan_weight"` | ||
34 | + RealWeight float64 `json:"real_weight"` | ||
35 | + ProductPlanId float64 `json:"product_plan_id"` | ||
36 | + } | ||
37 | + cid := constant.MANUFACTURE_DEFAULT_COMPANYID | ||
38 | + oid := constant.MANUFACTURE_DEFAULT_ORGID | ||
39 | + workshopRepository, _ := repository.NewWorkshopRepository(ptr.transactionContext) | ||
40 | + _, workshops, err := workshopRepository.Find(map[string]interface{}{"companyId": cid, "orgId": oid}) | ||
41 | + if err != nil { | ||
42 | + return err | ||
43 | + } | ||
44 | + if len(workshops) == 0 { | ||
45 | + return nil | ||
46 | + } | ||
47 | + workshopProductRecordDao, _ := dao.NewWorkshopPlanCompletionRecordDao(ptr.transactionContext) | ||
48 | + for i := range workshops { | ||
49 | + var result = make([]*record, 0) | ||
50 | + if err := workshopProductRecordDao.Records(cid, oid, workshops[i].WorkshopId, begin, end, &result); err != nil { | ||
51 | + log.Logger.Error(err.Error()) | ||
52 | + continue | ||
53 | + } | ||
54 | + var totalPlan float64 = 0 | ||
55 | + var totalReal float64 = 0 | ||
56 | + for _, v := range result { | ||
57 | + totalPlan += v.PlanWeight | ||
58 | + totalReal += v.RealWeight | ||
59 | + } | ||
60 | + var completionRate float64 | ||
61 | + if !(totalPlan == 0 || totalReal == 0) { | ||
62 | + completionRate = utils.Round(totalReal*100.0/totalPlan, 0) | ||
63 | + } | ||
64 | + | ||
65 | + var record *models.WorkshopPlanCompletionRecord | ||
66 | + if record, err = workshopProductRecordDao.FindOne(cid, oid, workshops[i].WorkshopId, begin); err == domain.ErrorNotFound && record == nil { | ||
67 | + record = &models.WorkshopPlanCompletionRecord{ | ||
68 | + CompanyId: cid, | ||
69 | + OrgId: oid, | ||
70 | + WorkshopId: workshops[i].WorkshopId, | ||
71 | + WorkshopName: workshops[i].WorkshopName, | ||
72 | + CreatedAt: begin, | ||
73 | + Plan: totalPlan, | ||
74 | + Real: totalReal, | ||
75 | + Rate: completionRate, | ||
76 | + } | ||
77 | + if err := workshopProductRecordDao.Save(record); err != nil { | ||
78 | + return err | ||
79 | + } | ||
80 | + } | ||
81 | + } | ||
82 | + | ||
83 | + return nil | ||
84 | +} |
@@ -3,10 +3,7 @@ package domainService | @@ -3,10 +3,7 @@ package domainService | ||
3 | import ( | 3 | import ( |
4 | "errors" | 4 | "errors" |
5 | "fmt" | 5 | "fmt" |
6 | - "github.com/hibiken/asynq" | ||
7 | pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | 6 | pgTransaction "github.com/linmadan/egglib-go/transaction/pg" |
8 | - "github.com/linmadan/egglib-go/utils/json" | ||
9 | - "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" | ||
10 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | 7 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" |
11 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository" | 8 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository" |
12 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" | 9 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" |
@@ -58,22 +55,6 @@ func (ptr *PGWorkshopWorkTimeStaticService) WorkshopWorkTimeStatic(productRecord | @@ -58,22 +55,6 @@ func (ptr *PGWorkshopWorkTimeStaticService) WorkshopWorkTimeStatic(productRecord | ||
58 | return record, nil | 55 | return record, nil |
59 | } | 56 | } |
60 | 57 | ||
61 | -func SendWorkshopWorkTimeStaticJob(productRecord *domain.ProductAttendanceRecord) error { | ||
62 | - return SendAsyncJob(domain.TaskKeyWorkshopWorkTimeRecordStatics(), productRecord) | ||
63 | -} | ||
64 | - | ||
65 | -func SenDeviceZkTecoReportJob(productRecord *domain.DeviceZkTeco) error { | ||
66 | - return SendAsyncJob(domain.TaskDeviceZkTecoReport(), productRecord) | ||
67 | -} | ||
68 | - | ||
69 | -func SendAsyncJob(queueName string, job interface{}) error { | ||
70 | - task := asynq.NewTask(queueName, []byte(json.MarshalToString(job))) | ||
71 | - | ||
72 | - client := asynq.NewClient(asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS}) | ||
73 | - _, err := client.Enqueue(task) | ||
74 | - return err | ||
75 | -} | ||
76 | - | ||
77 | func NewPGWorkshopWorkTimeStaticService(transactionContext *pgTransaction.TransactionContext) (*PGWorkshopWorkTimeStaticService, error) { | 58 | func NewPGWorkshopWorkTimeStaticService(transactionContext *pgTransaction.TransactionContext) (*PGWorkshopWorkTimeStaticService, error) { |
78 | if transactionContext == nil { | 59 | if transactionContext == nil { |
79 | return nil, fmt.Errorf("transactionContext参数不能为nil") | 60 | return nil, fmt.Errorf("transactionContext参数不能为nil") |
@@ -4,6 +4,7 @@ import ( | @@ -4,6 +4,7 @@ import ( | ||
4 | "fmt" | 4 | "fmt" |
5 | pahomqtt "github.com/eclipse/paho.mqtt.golang" | 5 | pahomqtt "github.com/eclipse/paho.mqtt.golang" |
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/log" | ||
7 | "time" | 8 | "time" |
8 | ) | 9 | ) |
9 | 10 | ||
@@ -26,21 +27,26 @@ func (subscribeClient *SubscribeClient) options() *pahomqtt.ClientOptions { | @@ -26,21 +27,26 @@ func (subscribeClient *SubscribeClient) options() *pahomqtt.ClientOptions { | ||
26 | opts.SetKeepAlive(2 * time.Second) | 27 | opts.SetKeepAlive(2 * time.Second) |
27 | opts.SetPingTimeout(1 * time.Second) | 28 | opts.SetPingTimeout(1 * time.Second) |
28 | opts.CleanSession = false | 29 | opts.CleanSession = false |
29 | - opts.SetClientID("test") | 30 | + //opts.SetClientID("test") |
30 | //opts.Order = true | 31 | //opts.Order = true |
31 | return opts | 32 | return opts |
32 | } | 33 | } |
33 | 34 | ||
34 | -func (subscribeClient *SubscribeClient) Connect() *SubscribeClient{ | 35 | +func (subscribeClient *SubscribeClient) Connect() *SubscribeClient { |
35 | opts := subscribeClient.options() | 36 | opts := subscribeClient.options() |
36 | fmt.Println("start connect......") | 37 | fmt.Println("start connect......") |
37 | opts.OnConnectionLost = func(c pahomqtt.Client, err error) { | 38 | opts.OnConnectionLost = func(c pahomqtt.Client, err error) { |
39 | + defer func() { | ||
40 | + if r := recover(); r != nil { | ||
41 | + log.Logger.Error(fmt.Sprintf("%v", r)) | ||
42 | + } | ||
43 | + }() | ||
38 | fmt.Println("Connect error:", err) | 44 | fmt.Println("Connect error:", err) |
39 | for { | 45 | for { |
40 | fmt.Println("reconnect server") | 46 | fmt.Println("reconnect server") |
41 | token := subscribeClient.client.Connect() | 47 | token := subscribeClient.client.Connect() |
42 | token.Wait() | 48 | token.Wait() |
43 | - fmt.Println("server Connect status:",subscribeClient.client.IsConnectionOpen()) | 49 | + fmt.Println("server Connect status:", subscribeClient.client.IsConnectionOpen()) |
44 | if subscribeClient.client.IsConnectionOpen() { | 50 | if subscribeClient.client.IsConnectionOpen() { |
45 | break | 51 | break |
46 | } | 52 | } |
@@ -48,7 +54,7 @@ func (subscribeClient *SubscribeClient) Connect() *SubscribeClient{ | @@ -48,7 +54,7 @@ func (subscribeClient *SubscribeClient) Connect() *SubscribeClient{ | ||
48 | } | 54 | } |
49 | } | 55 | } |
50 | opts.OnConnect = func(c pahomqtt.Client) { | 56 | opts.OnConnect = func(c pahomqtt.Client) { |
51 | - c.Subscribe(subscribeClient.topic,0,subscribeClient.handler) | 57 | + c.Subscribe(subscribeClient.topic, 0, subscribeClient.handler) |
52 | } | 58 | } |
53 | subscribeClient.client = pahomqtt.NewClient(opts) | 59 | subscribeClient.client = pahomqtt.NewClient(opts) |
54 | token := subscribeClient.client.Connect() | 60 | token := subscribeClient.client.Connect() |
@@ -56,21 +62,21 @@ func (subscribeClient *SubscribeClient) Connect() *SubscribeClient{ | @@ -56,21 +62,21 @@ func (subscribeClient *SubscribeClient) Connect() *SubscribeClient{ | ||
56 | return subscribeClient | 62 | return subscribeClient |
57 | } | 63 | } |
58 | 64 | ||
59 | -func (subscribeClient *SubscribeClient) Subscribe(topic string, messageHandler pahomqtt.MessageHandler){ | 65 | +func (subscribeClient *SubscribeClient) Subscribe(topic string, messageHandler pahomqtt.MessageHandler) { |
60 | subscribeClient.topic = topic | 66 | subscribeClient.topic = topic |
61 | subscribeClient.handler = messageHandler | 67 | subscribeClient.handler = messageHandler |
62 | - token := subscribeClient.client.Subscribe(topic,0,messageHandler) | 68 | + token := subscribeClient.client.Subscribe(topic, 0, messageHandler) |
63 | token.Wait() | 69 | token.Wait() |
64 | token.Done() | 70 | token.Done() |
65 | } | 71 | } |
66 | 72 | ||
67 | -func StartSubscribe(topic string,handler MessageHandler){ | 73 | +func StartSubscribe(topic string, handler MessageHandler) { |
68 | defer func() { | 74 | defer func() { |
69 | - if err := recover();err != nil { | 75 | + if err := recover(); err != nil { |
70 | fmt.Println(err) | 76 | fmt.Println(err) |
71 | - StartSubscribe(topic,handler) | 77 | + StartSubscribe(topic, handler) |
72 | } | 78 | } |
73 | }() | 79 | }() |
74 | fmt.Println("start subscribe...") | 80 | fmt.Println("start subscribe...") |
75 | - NewSubscribeClient().Connect().Subscribe(topic,pahomqtt.MessageHandler(handler)) | ||
76 | -} | ||
81 | + NewSubscribeClient().Connect().Subscribe(topic, pahomqtt.MessageHandler(handler)) | ||
82 | +} |
@@ -45,6 +45,9 @@ func init() { | @@ -45,6 +45,9 @@ func init() { | ||
45 | (*models.WorkshopProductRecord)(nil), | 45 | (*models.WorkshopProductRecord)(nil), |
46 | (*models.WorkshopWorkTimeRecord)(nil), | 46 | (*models.WorkshopWorkTimeRecord)(nil), |
47 | (*models.ProductPlanDispatchRecord)(nil), | 47 | (*models.ProductPlanDispatchRecord)(nil), |
48 | + (*models.DeviceDailyRunningRecord)(nil), | ||
49 | + (*models.DeviceRunningRecord)(nil), | ||
50 | + (*models.WorkshopPlanCompletionRecord)(nil), | ||
48 | } { | 51 | } { |
49 | err := DB.Model(model).CreateTable(&orm.CreateTableOptions{ | 52 | err := DB.Model(model).CreateTable(&orm.CreateTableOptions{ |
50 | Temp: false, | 53 | Temp: false, |
1 | +package models | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
5 | + "time" | ||
6 | +) | ||
7 | + | ||
8 | +type DeviceDailyRunningRecord struct { | ||
9 | + tableName string `comment:"设备每日运行记录(汇总)" pg:"manufacture.device_daily_running_record"` | ||
10 | + // 设备每日运行记录ID | ||
11 | + DeviceDailyRunningRecordId int `comment:"设备每日运行记录ID" pg:"pk:device_daily_running_record_id"` | ||
12 | + // 企业id | ||
13 | + CompanyId int `comment:"企业id"` | ||
14 | + // 组织ID | ||
15 | + OrgId int `comment:"组织ID"` | ||
16 | + // 工作位置 | ||
17 | + WorkStation *domain.WorkStation `comment:"工作位置"` | ||
18 | + // 设备Id | ||
19 | + DeviceId int `comment:"设备Id"` | ||
20 | + // 设备编号 | ||
21 | + DeviceCode string `comment:"设备编号"` | ||
22 | + // 生产日期 | ||
23 | + ProductDate time.Time `json:"productDate"` | ||
24 | + // 设备运行记录信息 | ||
25 | + DeviceRunningRecordInfo *domain.DeviceRunningRecordInfo `comment:"设备运行记录信息"` | ||
26 | + // 创建时间 | ||
27 | + CreatedAt time.Time `comment:"创建时间"` | ||
28 | + // 更新时间 | ||
29 | + UpdatedAt time.Time `comment:"更新时间"` | ||
30 | + // 删除时间 | ||
31 | + DeletedAt time.Time `comment:"删除时间"` | ||
32 | +} |
1 | +package models | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
5 | + "time" | ||
6 | +) | ||
7 | + | ||
8 | +type DeviceRunningRecord struct { | ||
9 | + tableName string `comment:"设备运行记录" pg:"manufacture.device_running_record"` | ||
10 | + // 设备运行记录ID | ||
11 | + DeviceRunningRecordId int `comment:"设备运行记录ID" pg:"pk:device_running_record_id"` | ||
12 | + // 企业id | ||
13 | + CompanyId int `comment:"企业id"` | ||
14 | + // 组织ID | ||
15 | + OrgId int `comment:"组织ID"` | ||
16 | + // 工作位置 | ||
17 | + WorkStation *domain.WorkStation `comment:"工作位置"` | ||
18 | + // 设备Id | ||
19 | + DeviceId int `comment:"设备Id"` | ||
20 | + // 设备编号 | ||
21 | + DeviceCode string `comment:"设备编号"` | ||
22 | + // 设备运行记录信息 | ||
23 | + DeviceRunningRecordInfo *domain.DeviceRunningData `comment:"设备运行记录信息"` | ||
24 | + // 创建时间 | ||
25 | + CreatedAt time.Time `comment:"创建时间"` | ||
26 | +} |
1 | +package models | ||
2 | + | ||
3 | +import ( | ||
4 | + "time" | ||
5 | +) | ||
6 | + | ||
7 | +// 车间计划完成记录 | ||
8 | +type WorkshopPlanCompletionRecord struct { | ||
9 | + tableName string `comment:"车间" pg:"manufacture.workshop_plan_completion_record"` | ||
10 | + WorkshopPlanCompletionRecordId int `comment:"车间计划完成记录ID" pg:"pk:workshop_plan_completion_record_id"` | ||
11 | + // 企业id | ||
12 | + CompanyId int `comment:"企业id"` | ||
13 | + // 组织ID | ||
14 | + OrgId int `comment:"组织ID"` | ||
15 | + // 生产计划ID | ||
16 | + //ProductPlanId int `comment:"生产计划ID" pg:"pk:product_plan_id"` | ||
17 | + // 工作位置 | ||
18 | + //WorkStation *domain.WorkStation `comment:"工作位置"` | ||
19 | + // 车间ID | ||
20 | + WorkshopId int `comment:"车间"` | ||
21 | + // 车间名称 | ||
22 | + WorkshopName string `comment:"车间名称"` | ||
23 | + // 创建时间 | ||
24 | + CreatedAt time.Time `comment:"创建时间"` | ||
25 | + // 计划生成 | ||
26 | + Plan float64 `comment:"计划生成" pg:",use_zero"` | ||
27 | + // 计划生成 | ||
28 | + Real float64 `comment:"实际生产" pg:",use_zero"` | ||
29 | + // 完成率 | ||
30 | + Rate float64 `comment:"完成率" pg:",use_zero"` | ||
31 | +} |
1 | +package transform | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models" | ||
6 | +) | ||
7 | + | ||
8 | +func TransformToDeviceDailyRunningRecordDomainModelFromPgModels(deviceDailyRunningRecordModel *models.DeviceDailyRunningRecord) (*domain.DeviceDailyRunningRecord, error) { | ||
9 | + return &domain.DeviceDailyRunningRecord{ | ||
10 | + DeviceDailyRunningRecordId: deviceDailyRunningRecordModel.DeviceDailyRunningRecordId, | ||
11 | + CompanyId: deviceDailyRunningRecordModel.CompanyId, | ||
12 | + OrgId: deviceDailyRunningRecordModel.OrgId, | ||
13 | + WorkStation: deviceDailyRunningRecordModel.WorkStation, | ||
14 | + DeviceId: deviceDailyRunningRecordModel.DeviceId, | ||
15 | + DeviceCode: deviceDailyRunningRecordModel.DeviceCode, | ||
16 | + ProductDate: deviceDailyRunningRecordModel.ProductDate, | ||
17 | + DeviceRunningRecordInfo: deviceDailyRunningRecordModel.DeviceRunningRecordInfo, | ||
18 | + CreatedAt: deviceDailyRunningRecordModel.CreatedAt, | ||
19 | + UpdatedAt: deviceDailyRunningRecordModel.UpdatedAt, | ||
20 | + DeletedAt: deviceDailyRunningRecordModel.DeletedAt, | ||
21 | + }, nil | ||
22 | +} |
1 | +package transform | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models" | ||
6 | +) | ||
7 | + | ||
8 | +func TransformToDeviceRunningRecordDomainModelFromPgModels(deviceRunningRecordModel *models.DeviceRunningRecord) (*domain.DeviceRunningRecord, error) { | ||
9 | + return &domain.DeviceRunningRecord{ | ||
10 | + DeviceRunningRecordId: deviceRunningRecordModel.DeviceRunningRecordId, | ||
11 | + CompanyId: deviceRunningRecordModel.CompanyId, | ||
12 | + OrgId: deviceRunningRecordModel.OrgId, | ||
13 | + WorkStation: deviceRunningRecordModel.WorkStation, | ||
14 | + DeviceId: deviceRunningRecordModel.DeviceId, | ||
15 | + DeviceCode: deviceRunningRecordModel.DeviceCode, | ||
16 | + DeviceRunningRecordInfo: deviceRunningRecordModel.DeviceRunningRecordInfo, | ||
17 | + CreatedAt: deviceRunningRecordModel.CreatedAt, | ||
18 | + }, nil | ||
19 | +} |
1 | +package redis | ||
2 | + | ||
3 | +import ( | ||
4 | + "encoding/json" | ||
5 | + "fmt" | ||
6 | + "github.com/go-redis/redis" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
9 | + "time" | ||
10 | +) | ||
11 | + | ||
12 | +// 获取每日设备运行数据 | ||
13 | +func GetDeviceDailyRunningRecord(t time.Time, deviceCode string) (*domain.DeviceDailyRunningRecord, error) { | ||
14 | + client := GetRedis() | ||
15 | + key := DeviceDailyRunningRecordKey(t, deviceCode) | ||
16 | + return getDeviceDailyRunningRecord(client, key) | ||
17 | +} | ||
18 | + | ||
19 | +func getDeviceDailyRunningRecord(client *redis.Client, key string) (*domain.DeviceDailyRunningRecord, error) { | ||
20 | + result := client.Get(key) | ||
21 | + data, err := result.Bytes() | ||
22 | + if err == redis.Nil { | ||
23 | + return nil, domain.ErrorNotFound | ||
24 | + } | ||
25 | + var record = &domain.DeviceDailyRunningRecord{} | ||
26 | + if err = json.Unmarshal(data, record); err != nil { | ||
27 | + return nil, err | ||
28 | + } | ||
29 | + return record, nil | ||
30 | +} | ||
31 | + | ||
32 | +// 保存每日设备运行数据 | ||
33 | +func SaveDeviceDailyRunningRecord(record *domain.DeviceDailyRunningRecord) error { | ||
34 | + client := GetRedis() | ||
35 | + key := DeviceDailyRunningRecordKey(record.CreatedAt, record.DeviceCode) | ||
36 | + recordData, err := json.Marshal(record) | ||
37 | + result := client.Set(key, recordData, time.Hour*24*5) | ||
38 | + _, err = result.Result() | ||
39 | + return err | ||
40 | +} | ||
41 | + | ||
42 | +// 保存每日设备运行数据 | ||
43 | +func RemoveDeviceDailyRunningRecord(t time.Time, deviceCode string) error { | ||
44 | + client := GetRedis() | ||
45 | + key := DeviceDailyRunningRecordKey(t, deviceCode) | ||
46 | + result := client.Del(key) | ||
47 | + _, err := result.Result() | ||
48 | + return err | ||
49 | +} | ||
50 | + | ||
51 | +func DeviceDailyRunningRecordKey(t time.Time, deviceCode string) string { | ||
52 | + str := fmt.Sprintf("%v:device-daily-record:%v-%v:%v:%v", constant.CACHE_PREFIX, constant.MANUFACTURE_DEFAULT_COMPANYID, constant.MANUFACTURE_DEFAULT_ORGID, t.Format("2006-01-02"), deviceCode) | ||
53 | + return str | ||
54 | +} | ||
55 | + | ||
56 | +// 获取设备每日所有数据记录 | ||
57 | +func GetDeviceDailyAllRecord(t time.Time) ([]*domain.DeviceDailyRunningRecord, error) { | ||
58 | + client := GetRedis() | ||
59 | + sliceResult := client.Keys(DeviceDailyAllRecordKey(t)) | ||
60 | + keys, err := sliceResult.Result() | ||
61 | + var records = make([]*domain.DeviceDailyRunningRecord, 0) | ||
62 | + if err != nil { | ||
63 | + return nil, err | ||
64 | + } | ||
65 | + for _, v := range keys { | ||
66 | + record, err := getDeviceDailyRunningRecord(client, v) | ||
67 | + if err != nil { | ||
68 | + return nil, err | ||
69 | + } | ||
70 | + records = append(records, record) | ||
71 | + } | ||
72 | + return records, nil | ||
73 | +} | ||
74 | + | ||
75 | +func DeviceDailyAllRecordKey(t time.Time) string { | ||
76 | + str := fmt.Sprintf("%v:device-daily-record:%v-%v:%v:*", constant.CACHE_PREFIX, constant.MANUFACTURE_DEFAULT_COMPANYID, constant.MANUFACTURE_DEFAULT_ORGID, t.Format("2006-01-02")) | ||
77 | + return str | ||
78 | +} |
1 | +package repository | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "github.com/go-pg/pg/v10" | ||
6 | + "time" | ||
7 | + | ||
8 | + "github.com/linmadan/egglib-go/persistent/pg/sqlbuilder" | ||
9 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
10 | + "github.com/linmadan/egglib-go/utils/snowflake" | ||
11 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
12 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models" | ||
13 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/transform" | ||
14 | +) | ||
15 | + | ||
16 | +type DeviceDailyRunningRecordRepository struct { | ||
17 | + transactionContext *pgTransaction.TransactionContext | ||
18 | +} | ||
19 | + | ||
20 | +func (repository *DeviceDailyRunningRecordRepository) nextIdentify() (int64, error) { | ||
21 | + IdWorker, err := snowflake.NewIdWorker(1) | ||
22 | + if err != nil { | ||
23 | + return 0, err | ||
24 | + } | ||
25 | + id, err := IdWorker.NextId() | ||
26 | + return id, err | ||
27 | +} | ||
28 | +func (repository *DeviceDailyRunningRecordRepository) Save(deviceDailyRunningRecord *domain.DeviceDailyRunningRecord) (*domain.DeviceDailyRunningRecord, error) { | ||
29 | + sqlBuildFields := []string{ | ||
30 | + "device_daily_running_record_id", | ||
31 | + "company_id", | ||
32 | + "org_id", | ||
33 | + "work_station", | ||
34 | + "device_id", | ||
35 | + "device_code", | ||
36 | + "product_date", | ||
37 | + "device_running_record_info", | ||
38 | + "created_at", | ||
39 | + "updated_at", | ||
40 | + "deleted_at", | ||
41 | + } | ||
42 | + insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "device_daily_running_record_id", "deleted_at")) | ||
43 | + insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "device_daily_running_record_id", "deleted_at")) | ||
44 | + returningFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlBuildFields) | ||
45 | + updateFields := sqlbuilder.RemoveSqlFields(sqlBuildFields, "device_daily_running_record_id", "deleted_at") | ||
46 | + updateFieldsSnippet := sqlbuilder.SqlUpdateFieldsSnippet(updateFields) | ||
47 | + tx := repository.transactionContext.PgTx | ||
48 | + if deviceDailyRunningRecord.Identify() == nil { | ||
49 | + if _, err := tx.QueryOne( | ||
50 | + pg.Scan( | ||
51 | + &deviceDailyRunningRecord.DeviceDailyRunningRecordId, | ||
52 | + &deviceDailyRunningRecord.CompanyId, | ||
53 | + &deviceDailyRunningRecord.OrgId, | ||
54 | + &deviceDailyRunningRecord.WorkStation, | ||
55 | + &deviceDailyRunningRecord.DeviceId, | ||
56 | + &deviceDailyRunningRecord.DeviceCode, | ||
57 | + &deviceDailyRunningRecord.ProductDate, | ||
58 | + &deviceDailyRunningRecord.DeviceRunningRecordInfo, | ||
59 | + &deviceDailyRunningRecord.CreatedAt, | ||
60 | + &deviceDailyRunningRecord.UpdatedAt, | ||
61 | + &deviceDailyRunningRecord.DeletedAt, | ||
62 | + ), | ||
63 | + fmt.Sprintf("INSERT INTO manufacture.device_daily_running_record (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet), | ||
64 | + //deviceDailyRunningRecord.DeviceDailyRunningRecordId, | ||
65 | + deviceDailyRunningRecord.CompanyId, | ||
66 | + deviceDailyRunningRecord.OrgId, | ||
67 | + deviceDailyRunningRecord.WorkStation, | ||
68 | + deviceDailyRunningRecord.DeviceId, | ||
69 | + deviceDailyRunningRecord.DeviceCode, | ||
70 | + deviceDailyRunningRecord.ProductDate, | ||
71 | + deviceDailyRunningRecord.DeviceRunningRecordInfo, | ||
72 | + deviceDailyRunningRecord.CreatedAt, | ||
73 | + deviceDailyRunningRecord.UpdatedAt, | ||
74 | + //deviceDailyRunningRecord.DeletedAt, | ||
75 | + ); err != nil { | ||
76 | + return deviceDailyRunningRecord, err | ||
77 | + } | ||
78 | + } else { | ||
79 | + if _, err := tx.QueryOne( | ||
80 | + pg.Scan( | ||
81 | + &deviceDailyRunningRecord.DeviceDailyRunningRecordId, | ||
82 | + &deviceDailyRunningRecord.CompanyId, | ||
83 | + &deviceDailyRunningRecord.OrgId, | ||
84 | + &deviceDailyRunningRecord.WorkStation, | ||
85 | + &deviceDailyRunningRecord.DeviceId, | ||
86 | + &deviceDailyRunningRecord.DeviceCode, | ||
87 | + &deviceDailyRunningRecord.ProductDate, | ||
88 | + &deviceDailyRunningRecord.DeviceRunningRecordInfo, | ||
89 | + &deviceDailyRunningRecord.CreatedAt, | ||
90 | + &deviceDailyRunningRecord.UpdatedAt, | ||
91 | + &deviceDailyRunningRecord.DeletedAt, | ||
92 | + ), | ||
93 | + fmt.Sprintf("UPDATE manufacture.device_daily_running_record SET %s WHERE device_daily_running_record_id=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet), | ||
94 | + //deviceDailyRunningRecord.DeviceDailyRunningRecordId, | ||
95 | + deviceDailyRunningRecord.CompanyId, | ||
96 | + deviceDailyRunningRecord.OrgId, | ||
97 | + deviceDailyRunningRecord.WorkStation, | ||
98 | + deviceDailyRunningRecord.DeviceId, | ||
99 | + deviceDailyRunningRecord.DeviceCode, | ||
100 | + deviceDailyRunningRecord.ProductDate, | ||
101 | + deviceDailyRunningRecord.DeviceRunningRecordInfo, | ||
102 | + deviceDailyRunningRecord.CreatedAt, | ||
103 | + deviceDailyRunningRecord.UpdatedAt, | ||
104 | + //deviceDailyRunningRecord.DeletedAt, | ||
105 | + deviceDailyRunningRecord.Identify(), | ||
106 | + ); err != nil { | ||
107 | + return deviceDailyRunningRecord, err | ||
108 | + } | ||
109 | + } | ||
110 | + return deviceDailyRunningRecord, nil | ||
111 | +} | ||
112 | +func (repository *DeviceDailyRunningRecordRepository) Remove(deviceDailyRunningRecord *domain.DeviceDailyRunningRecord) (*domain.DeviceDailyRunningRecord, error) { | ||
113 | + tx := repository.transactionContext.PgTx | ||
114 | + deviceDailyRunningRecordModel := new(models.DeviceDailyRunningRecord) | ||
115 | + deviceDailyRunningRecordModel.DeviceDailyRunningRecordId = deviceDailyRunningRecord.Identify().(int) | ||
116 | + if _, err := tx.Model(deviceDailyRunningRecordModel).WherePK().Delete(); err != nil { | ||
117 | + return deviceDailyRunningRecord, err | ||
118 | + } | ||
119 | + return deviceDailyRunningRecord, nil | ||
120 | +} | ||
121 | +func (repository *DeviceDailyRunningRecordRepository) FindOne(queryOptions map[string]interface{}) (*domain.DeviceDailyRunningRecord, error) { | ||
122 | + tx := repository.transactionContext.PgTx | ||
123 | + deviceDailyRunningRecordModel := new(models.DeviceDailyRunningRecord) | ||
124 | + query := sqlbuilder.BuildQuery(tx.Model(deviceDailyRunningRecordModel), queryOptions) | ||
125 | + query.SetWhereByQueryOption("work_station->>'workStationId'=?", "workStationId") | ||
126 | + query.SetWhereByQueryOption("device_code=? ", "deviceCode") | ||
127 | + query.SetWhereByQueryOption("product_date=? ", "productDate") | ||
128 | + query.SetWhereByQueryOption("device_daily_running_record.device_daily_running_record_id = ?", "deviceDailyRunningRecordId") | ||
129 | + if err := query.First(); err != nil { | ||
130 | + if err.Error() == "pg: no rows in result set" { | ||
131 | + return nil, domain.ErrorNotFound | ||
132 | + } else { | ||
133 | + return nil, err | ||
134 | + } | ||
135 | + } | ||
136 | + if deviceDailyRunningRecordModel.DeviceDailyRunningRecordId == 0 { | ||
137 | + return nil, nil | ||
138 | + } else { | ||
139 | + return transform.TransformToDeviceDailyRunningRecordDomainModelFromPgModels(deviceDailyRunningRecordModel) | ||
140 | + } | ||
141 | +} | ||
142 | +func (repository *DeviceDailyRunningRecordRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.DeviceDailyRunningRecord, error) { | ||
143 | + tx := repository.transactionContext.PgTx | ||
144 | + var deviceDailyRunningRecordModels []*models.DeviceDailyRunningRecord | ||
145 | + deviceDailyRunningRecords := make([]*domain.DeviceDailyRunningRecord, 0) | ||
146 | + query := sqlbuilder.BuildQuery(tx.Model(&deviceDailyRunningRecordModels), queryOptions) | ||
147 | + query.SetWhereByQueryOption("company_id = ?", "companyId") | ||
148 | + query.SetWhereByQueryOption("org_id = ?", "orgId") | ||
149 | + if v, ok := queryOptions["productDate"]; ok && !(v.(time.Time)).IsZero() { | ||
150 | + query.Where(`product_date = ?`, v) | ||
151 | + } | ||
152 | + query.SetOffsetAndLimit(20) | ||
153 | + query.SetOrderDirect("device_daily_running_record_id", "DESC") | ||
154 | + if count, err := query.SelectAndCount(); err != nil { | ||
155 | + return 0, deviceDailyRunningRecords, err | ||
156 | + } else { | ||
157 | + for _, deviceDailyRunningRecordModel := range deviceDailyRunningRecordModels { | ||
158 | + if deviceDailyRunningRecord, err := transform.TransformToDeviceDailyRunningRecordDomainModelFromPgModels(deviceDailyRunningRecordModel); err != nil { | ||
159 | + return 0, deviceDailyRunningRecords, err | ||
160 | + } else { | ||
161 | + deviceDailyRunningRecords = append(deviceDailyRunningRecords, deviceDailyRunningRecord) | ||
162 | + } | ||
163 | + } | ||
164 | + return int64(count), deviceDailyRunningRecords, nil | ||
165 | + } | ||
166 | +} | ||
167 | +func NewDeviceDailyRunningRecordRepository(transactionContext *pgTransaction.TransactionContext) (*DeviceDailyRunningRecordRepository, error) { | ||
168 | + if transactionContext == nil { | ||
169 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
170 | + } else { | ||
171 | + return &DeviceDailyRunningRecordRepository{ | ||
172 | + transactionContext: transactionContext, | ||
173 | + }, nil | ||
174 | + } | ||
175 | +} |
@@ -174,6 +174,12 @@ func (repository *DeviceRepository) Find(queryOptions map[string]interface{}) (i | @@ -174,6 +174,12 @@ func (repository *DeviceRepository) Find(queryOptions map[string]interface{}) (i | ||
174 | if v, ok := queryOptions["inDeviceId"]; ok && len(v.([]int)) > 0 { | 174 | if v, ok := queryOptions["inDeviceId"]; ok && len(v.([]int)) > 0 { |
175 | query.Where(`device_id in (?)`, pg.In(v)) | 175 | query.Where(`device_id in (?)`, pg.In(v)) |
176 | } | 176 | } |
177 | + if v, ok := queryOptions["workshopId"]; ok && (v.(int)) > 0 { | ||
178 | + query.Where(`work_station->>'workshopId'='?'`, v) | ||
179 | + } | ||
180 | + if v, ok := queryOptions["lineId"]; ok && (v.(int)) > 0 { | ||
181 | + query.Where(`work_station->>'lineId'='?'`, v) | ||
182 | + } | ||
177 | query.SetWhereByQueryOption("device_code = ?", "deviceCode") | 183 | query.SetWhereByQueryOption("device_code = ?", "deviceCode") |
178 | query.SetWhereByQueryOption("device_status = ?", "deviceStatus") | 184 | query.SetWhereByQueryOption("device_status = ?", "deviceStatus") |
179 | if v, ok := queryOptions["deviceName"]; ok && len(v.(string)) > 0 { | 185 | if v, ok := queryOptions["deviceName"]; ok && len(v.(string)) > 0 { |
1 | +package repository | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "github.com/go-pg/pg/v10" | ||
6 | + | ||
7 | + "github.com/linmadan/egglib-go/persistent/pg/sqlbuilder" | ||
8 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
9 | + "github.com/linmadan/egglib-go/utils/snowflake" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" | ||
11 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models" | ||
12 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/transform" | ||
13 | +) | ||
14 | + | ||
15 | +type DeviceRunningRecordRepository struct { | ||
16 | + transactionContext *pgTransaction.TransactionContext | ||
17 | +} | ||
18 | + | ||
19 | +func (repository *DeviceRunningRecordRepository) nextIdentify() (int64, error) { | ||
20 | + IdWorker, err := snowflake.NewIdWorker(1) | ||
21 | + if err != nil { | ||
22 | + return 0, err | ||
23 | + } | ||
24 | + id, err := IdWorker.NextId() | ||
25 | + return id, err | ||
26 | +} | ||
27 | +func (repository *DeviceRunningRecordRepository) Save(deviceRunningRecord *domain.DeviceRunningRecord) (*domain.DeviceRunningRecord, error) { | ||
28 | + sqlBuildFields := []string{ | ||
29 | + "device_running_record_id", | ||
30 | + "company_id", | ||
31 | + "org_id", | ||
32 | + "work_station", | ||
33 | + "device_id", | ||
34 | + "device_code", | ||
35 | + "device_running_record_info", | ||
36 | + "created_at", | ||
37 | + } | ||
38 | + insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "device_running_record_id")) | ||
39 | + insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "device_running_record_id")) | ||
40 | + returningFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlBuildFields) | ||
41 | + updateFields := sqlbuilder.RemoveSqlFields(sqlBuildFields, "device_running_record_id") | ||
42 | + updateFieldsSnippet := sqlbuilder.SqlUpdateFieldsSnippet(updateFields) | ||
43 | + tx := repository.transactionContext.PgTx | ||
44 | + if deviceRunningRecord.Identify() == nil { | ||
45 | + if _, err := tx.QueryOne( | ||
46 | + pg.Scan( | ||
47 | + &deviceRunningRecord.DeviceRunningRecordId, | ||
48 | + &deviceRunningRecord.CompanyId, | ||
49 | + &deviceRunningRecord.OrgId, | ||
50 | + &deviceRunningRecord.WorkStation, | ||
51 | + &deviceRunningRecord.DeviceId, | ||
52 | + &deviceRunningRecord.DeviceCode, | ||
53 | + &deviceRunningRecord.DeviceRunningRecordInfo, | ||
54 | + &deviceRunningRecord.CreatedAt, | ||
55 | + ), | ||
56 | + fmt.Sprintf("INSERT INTO manufacture.device_running_record (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet), | ||
57 | + //deviceRunningRecord.DeviceRunningRecordId, | ||
58 | + deviceRunningRecord.CompanyId, | ||
59 | + deviceRunningRecord.OrgId, | ||
60 | + deviceRunningRecord.WorkStation, | ||
61 | + deviceRunningRecord.DeviceId, | ||
62 | + deviceRunningRecord.DeviceCode, | ||
63 | + deviceRunningRecord.DeviceRunningRecordInfo, | ||
64 | + deviceRunningRecord.CreatedAt, | ||
65 | + ); err != nil { | ||
66 | + return deviceRunningRecord, err | ||
67 | + } | ||
68 | + } else { | ||
69 | + if _, err := tx.QueryOne( | ||
70 | + pg.Scan( | ||
71 | + &deviceRunningRecord.DeviceRunningRecordId, | ||
72 | + &deviceRunningRecord.CompanyId, | ||
73 | + &deviceRunningRecord.OrgId, | ||
74 | + &deviceRunningRecord.WorkStation, | ||
75 | + &deviceRunningRecord.DeviceId, | ||
76 | + &deviceRunningRecord.DeviceCode, | ||
77 | + &deviceRunningRecord.DeviceRunningRecordInfo, | ||
78 | + &deviceRunningRecord.CreatedAt, | ||
79 | + ), | ||
80 | + fmt.Sprintf("UPDATE manufacture.device_running_record SET %s WHERE device_running_record_id=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet), | ||
81 | + //deviceRunningRecord.DeviceRunningRecordId, | ||
82 | + deviceRunningRecord.CompanyId, | ||
83 | + deviceRunningRecord.OrgId, | ||
84 | + deviceRunningRecord.WorkStation, | ||
85 | + deviceRunningRecord.DeviceId, | ||
86 | + deviceRunningRecord.DeviceCode, | ||
87 | + deviceRunningRecord.DeviceRunningRecordInfo, | ||
88 | + deviceRunningRecord.CreatedAt, | ||
89 | + deviceRunningRecord.Identify(), | ||
90 | + ); err != nil { | ||
91 | + return deviceRunningRecord, err | ||
92 | + } | ||
93 | + } | ||
94 | + return deviceRunningRecord, nil | ||
95 | +} | ||
96 | +func (repository *DeviceRunningRecordRepository) Remove(deviceRunningRecord *domain.DeviceRunningRecord) (*domain.DeviceRunningRecord, error) { | ||
97 | + tx := repository.transactionContext.PgTx | ||
98 | + deviceRunningRecordModel := new(models.DeviceRunningRecord) | ||
99 | + deviceRunningRecordModel.DeviceRunningRecordId = deviceRunningRecord.Identify().(int) | ||
100 | + if _, err := tx.Model(deviceRunningRecordModel).WherePK().Delete(); err != nil { | ||
101 | + return deviceRunningRecord, err | ||
102 | + } | ||
103 | + return deviceRunningRecord, nil | ||
104 | +} | ||
105 | +func (repository *DeviceRunningRecordRepository) FindOne(queryOptions map[string]interface{}) (*domain.DeviceRunningRecord, error) { | ||
106 | + tx := repository.transactionContext.PgTx | ||
107 | + deviceRunningRecordModel := new(models.DeviceRunningRecord) | ||
108 | + query := sqlbuilder.BuildQuery(tx.Model(deviceRunningRecordModel), queryOptions) | ||
109 | + query.SetWhereByQueryOption("device_running_record.device_running_record_id = ?", "deviceRunningRecordId") | ||
110 | + if err := query.First(); err != nil { | ||
111 | + if err.Error() == "pg: no rows in result set" { | ||
112 | + return nil, fmt.Errorf("没有此资源") | ||
113 | + } else { | ||
114 | + return nil, err | ||
115 | + } | ||
116 | + } | ||
117 | + if deviceRunningRecordModel.DeviceRunningRecordId == 0 { | ||
118 | + return nil, nil | ||
119 | + } else { | ||
120 | + return transform.TransformToDeviceRunningRecordDomainModelFromPgModels(deviceRunningRecordModel) | ||
121 | + } | ||
122 | +} | ||
123 | +func (repository *DeviceRunningRecordRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.DeviceRunningRecord, error) { | ||
124 | + tx := repository.transactionContext.PgTx | ||
125 | + var deviceRunningRecordModels []*models.DeviceRunningRecord | ||
126 | + deviceRunningRecords := make([]*domain.DeviceRunningRecord, 0) | ||
127 | + query := sqlbuilder.BuildQuery(tx.Model(&deviceRunningRecordModels), queryOptions) | ||
128 | + query.SetOffsetAndLimit(20) | ||
129 | + query.SetOrderDirect("device_running_record_id", "DESC") | ||
130 | + if count, err := query.SelectAndCount(); err != nil { | ||
131 | + return 0, deviceRunningRecords, err | ||
132 | + } else { | ||
133 | + for _, deviceRunningRecordModel := range deviceRunningRecordModels { | ||
134 | + if deviceRunningRecord, err := transform.TransformToDeviceRunningRecordDomainModelFromPgModels(deviceRunningRecordModel); err != nil { | ||
135 | + return 0, deviceRunningRecords, err | ||
136 | + } else { | ||
137 | + deviceRunningRecords = append(deviceRunningRecords, deviceRunningRecord) | ||
138 | + } | ||
139 | + } | ||
140 | + return int64(count), deviceRunningRecords, nil | ||
141 | + } | ||
142 | +} | ||
143 | +func NewDeviceRunningRecordRepository(transactionContext *pgTransaction.TransactionContext) (*DeviceRunningRecordRepository, error) { | ||
144 | + if transactionContext == nil { | ||
145 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
146 | + } else { | ||
147 | + return &DeviceRunningRecordRepository{ | ||
148 | + transactionContext: transactionContext, | ||
149 | + }, nil | ||
150 | + } | ||
151 | +} |
@@ -166,6 +166,9 @@ func (repository *ProductAttendanceRecordRepository) Find(queryOptions map[strin | @@ -166,6 +166,9 @@ func (repository *ProductAttendanceRecordRepository) Find(queryOptions map[strin | ||
166 | query := sqlbuilder.BuildQuery(tx.Model(&productAttendanceRecordModels), queryOptions) | 166 | query := sqlbuilder.BuildQuery(tx.Model(&productAttendanceRecordModels), queryOptions) |
167 | query.SetWhereByQueryOption("company_id = ?", "companyId") | 167 | query.SetWhereByQueryOption("company_id = ?", "companyId") |
168 | query.SetWhereByQueryOption("org_id = ?", "orgId") | 168 | query.SetWhereByQueryOption("org_id = ?", "orgId") |
169 | + query.SetWhereByQueryOption("work_station->>'workshopId'='?'", "workshopId") | ||
170 | + query.SetWhereByQueryOption("work_station->>'lineId'='?'", "lineId") | ||
171 | + query.SetWhereByQueryOption("work_station->>'sectionId'='?'", "sectionId") | ||
169 | query.SetWhereByQueryOption("attendance_status & ? >0", "attendanceStatus") | 172 | query.SetWhereByQueryOption("attendance_status & ? >0", "attendanceStatus") |
170 | if v, ok := queryOptions["inOrgIds"]; ok && len(v.([]int)) > 0 { | 173 | if v, ok := queryOptions["inOrgIds"]; ok && len(v.([]int)) > 0 { |
171 | query.Where(`org_id in (?)`, pg.In(v)) | 174 | query.Where(`org_id in (?)`, pg.In(v)) |
@@ -188,6 +191,9 @@ func (repository *ProductAttendanceRecordRepository) Find(queryOptions map[strin | @@ -188,6 +191,9 @@ func (repository *ProductAttendanceRecordRepository) Find(queryOptions map[strin | ||
188 | if v, ok := queryOptions["signEndTime"]; ok && !((v.(time.Time)).IsZero()) { | 191 | if v, ok := queryOptions["signEndTime"]; ok && !((v.(time.Time)).IsZero()) { |
189 | query.Where("created_at<?", v.(time.Time)) | 192 | query.Where("created_at<?", v.(time.Time)) |
190 | } | 193 | } |
194 | + if v, ok := queryOptions["employeeType"]; ok && (v.(int)) > 0 { | ||
195 | + query.Where("product_worker->>'employeeType'='?'", v.(int)) | ||
196 | + } | ||
191 | query.SetOffsetAndLimit(domain.MaxQueryRow) | 197 | query.SetOffsetAndLimit(domain.MaxQueryRow) |
192 | query.SetOrderDirect("product_attendance_id", "DESC") | 198 | query.SetOrderDirect("product_attendance_id", "DESC") |
193 | if count, err := query.SelectAndCount(); err != nil { | 199 | if count, err := query.SelectAndCount(); err != nil { |
@@ -150,6 +150,16 @@ func (repository *ProductPlanDispatchRecordRepository) Find(queryOptions map[str | @@ -150,6 +150,16 @@ func (repository *ProductPlanDispatchRecordRepository) Find(queryOptions map[str | ||
150 | var productPlanDispatchRecordModels []*models.ProductPlanDispatchRecord | 150 | var productPlanDispatchRecordModels []*models.ProductPlanDispatchRecord |
151 | productPlanDispatchRecords := make([]*domain.ProductPlanDispatchRecord, 0) | 151 | productPlanDispatchRecords := make([]*domain.ProductPlanDispatchRecord, 0) |
152 | query := sqlbuilder.BuildQuery(tx.Model(&productPlanDispatchRecordModels), queryOptions) | 152 | query := sqlbuilder.BuildQuery(tx.Model(&productPlanDispatchRecordModels), queryOptions) |
153 | + query.SetWhereByQueryOption("company_id = ?", "companyId") | ||
154 | + query.SetWhereByQueryOption("org_id = ?", "orgId") | ||
155 | + query.SetWhereByQueryOption("work_station->>'workshopId'='?'", "workshopId") | ||
156 | + if v, ok := queryOptions["batchNumber"]; ok && len(v.(string)) > 0 { | ||
157 | + query.Where(fmt.Sprintf(`batch_number like '%%%v%%'`, v)) | ||
158 | + } | ||
159 | + if v, ok := queryOptions["workshopName"]; ok && len(v.(string)) > 0 { | ||
160 | + query.Where(fmt.Sprintf(`work_station->>'workshopName' like '%%%v%%'`, v)) | ||
161 | + } | ||
162 | + query.SetWhereByQueryOption("plan_dispatch_status=?", "planDispatchStatus") | ||
153 | query.SetOffsetAndLimit(domain.MaxQueryRow) | 163 | query.SetOffsetAndLimit(domain.MaxQueryRow) |
154 | query.SetOrderDirect("product_plan_dispatch_record_id", "DESC") | 164 | query.SetOrderDirect("product_plan_dispatch_record_id", "DESC") |
155 | if count, err := query.SelectAndCount(); err != nil { | 165 | if count, err := query.SelectAndCount(); err != nil { |
@@ -174,7 +174,7 @@ func (repository *ProductPlanRepository) Find(queryOptions map[string]interface{ | @@ -174,7 +174,7 @@ func (repository *ProductPlanRepository) Find(queryOptions map[string]interface{ | ||
174 | query := sqlbuilder.BuildQuery(tx.Model(&productPlanModels), queryOptions) | 174 | query := sqlbuilder.BuildQuery(tx.Model(&productPlanModels), queryOptions) |
175 | query.SetWhereByQueryOption("company_id = ?", "companyId") | 175 | query.SetWhereByQueryOption("company_id = ?", "companyId") |
176 | query.SetWhereByQueryOption("org_id = ?", "orgId") | 176 | query.SetWhereByQueryOption("org_id = ?", "orgId") |
177 | - | 177 | + query.SetWhereByQueryOption("work_station->>'workshopId'='?'", "workshopId") |
178 | if v, ok := queryOptions["batchNumber"]; ok && len(v.(string)) > 0 { | 178 | if v, ok := queryOptions["batchNumber"]; ok && len(v.(string)) > 0 { |
179 | query.Where(fmt.Sprintf(`batch_number like '%%%v%%'`, v)) | 179 | query.Where(fmt.Sprintf(`batch_number like '%%%v%%'`, v)) |
180 | } | 180 | } |
@@ -174,6 +174,12 @@ func (repository *ProductRecordRepository) Find(queryOptions map[string]interfac | @@ -174,6 +174,12 @@ func (repository *ProductRecordRepository) Find(queryOptions map[string]interfac | ||
174 | if v, ok := queryOptions["batchNumber"]; ok && len(v.(string)) > 0 { | 174 | if v, ok := queryOptions["batchNumber"]; ok && len(v.(string)) > 0 { |
175 | query.Where(fmt.Sprintf(`product_record_info->>'batchNumber' like '%%%v%%'`, v)) | 175 | query.Where(fmt.Sprintf(`product_record_info->>'batchNumber' like '%%%v%%'`, v)) |
176 | } | 176 | } |
177 | + if v, ok := queryOptions["employeeId"]; ok && v.(int) > 0 { | ||
178 | + query.Where(fmt.Sprintf(`product_worker->>'userId' = '%v'`, v)) | ||
179 | + } | ||
180 | + if v, ok := queryOptions["productPlanId"]; ok && v.(int) > 0 { | ||
181 | + query.Where(fmt.Sprintf(`product_record_info->>'productPlanId' = '%v'`, v)) | ||
182 | + } | ||
177 | query.SetOffsetAndLimit(domain.MaxQueryRow) | 183 | query.SetOffsetAndLimit(domain.MaxQueryRow) |
178 | query.SetOrderDirect("product_record_id", "DESC") | 184 | query.SetOrderDirect("product_record_id", "DESC") |
179 | if count, err := query.SelectAndCount(); err != nil { | 185 | if count, err := query.SelectAndCount(); err != nil { |
@@ -107,6 +107,14 @@ func (repository *WorkshopWorkTimeRecordRepository) FindOne(queryOptions map[str | @@ -107,6 +107,14 @@ func (repository *WorkshopWorkTimeRecordRepository) FindOne(queryOptions map[str | ||
107 | tx := repository.transactionContext.PgTx | 107 | tx := repository.transactionContext.PgTx |
108 | workshopWorkTimeRecordModel := new(models.WorkshopWorkTimeRecord) | 108 | workshopWorkTimeRecordModel := new(models.WorkshopWorkTimeRecord) |
109 | query := sqlbuilder.BuildQuery(tx.Model(workshopWorkTimeRecordModel), queryOptions) | 109 | query := sqlbuilder.BuildQuery(tx.Model(workshopWorkTimeRecordModel), queryOptions) |
110 | + query.SetWhereByQueryOption("company_id = ?", "companyId") | ||
111 | + query.SetWhereByQueryOption("org_id = ?", "orgId") | ||
112 | + if v, ok := queryOptions["workStationId"]; ok && len(v.(string)) > 0 { | ||
113 | + query.Where(`work_station->>'workStationId' = ?`, v) | ||
114 | + } | ||
115 | + if v, ok := queryOptions["recordDate"]; ok { | ||
116 | + query.Where("record_date=?", v) | ||
117 | + } | ||
110 | query.SetWhereByQueryOption("workshop_work_time_record.workshop_work_time_record_id = ?", "workshopWorkTimeRecordId") | 118 | query.SetWhereByQueryOption("workshop_work_time_record.workshop_work_time_record_id = ?", "workshopWorkTimeRecordId") |
111 | if err := query.First(); err != nil { | 119 | if err := query.First(); err != nil { |
112 | if err.Error() == "pg: no rows in result set" { | 120 | if err.Error() == "pg: no rows in result set" { |
@@ -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) |
@@ -7,6 +7,7 @@ import ( | @@ -7,6 +7,7 @@ import ( | ||
7 | "github.com/beego/beego/v2/core/validation" | 7 | "github.com/beego/beego/v2/core/validation" |
8 | "github.com/bwmarrin/snowflake" | 8 | "github.com/bwmarrin/snowflake" |
9 | jsonlib "github.com/linmadan/egglib-go/utils/json" | 9 | jsonlib "github.com/linmadan/egglib-go/utils/json" |
10 | + "github.com/shopspring/decimal" | ||
10 | "io" | 11 | "io" |
11 | "reflect" | 12 | "reflect" |
12 | "strconv" | 13 | "strconv" |
@@ -381,6 +382,7 @@ func SubStr(str string, start, length int) string { | @@ -381,6 +382,7 @@ func SubStr(str string, start, length int) string { | ||
381 | return string(rs[start:end]) | 382 | return string(rs[start:end]) |
382 | } | 383 | } |
383 | 384 | ||
385 | + | ||
384 | //生成新ID | 386 | //生成新ID |
385 | var snowFlakeNode *snowflake.Node | 387 | var snowFlakeNode *snowflake.Node |
386 | 388 | ||
@@ -395,4 +397,12 @@ func NewSnowflakeId() (int64, error) { | @@ -395,4 +397,12 @@ func NewSnowflakeId() (int64, error) { | ||
395 | // Generate a snowflake ID. | 397 | // Generate a snowflake ID. |
396 | id := snowFlakeNode.Generate() | 398 | id := snowFlakeNode.Generate() |
397 | return id.Int64(), nil | 399 | return id.Int64(), nil |
398 | -} | ||
400 | +} | ||
401 | + | ||
402 | +func Round(value float64, places int32) float64 { | ||
403 | + quantity := decimal.NewFromFloat(value) | ||
404 | + d := quantity.Round(places) | ||
405 | + rsp, _ := d.Float64() | ||
406 | + return rsp | ||
407 | +} | ||
408 | + |
-
请 注册 或 登录 后发表评论