作者 yangfu

feat:

1.数据采集汇报
2.文档修改
正在显示 34 个修改的文件 包含 1002 行增加56 行删除
#project
\ No newline at end of file
# 生产制造项目说明
## 1.数据导入导出模块
### 1.1.Excel导入流程
- 原型说明
选择模板下载、文件上传
![](https://doc-press.fjmaimaimai.com/team/frontend/plugins/data-transfer-upload.png)
导入数据检验有错,显示具体错误
![](https://timeless-world.oss-cn-shenzhen.aliyuncs.com/opportunity/dev_online/20220225/object/1645791913_Rz2JJkkx6xEXtAFdXDH5eH6NTjfhtjxf.jpg)
- [导入接口文档地址](https://doc-press.fjmaimaimai.com/team/frontend/plugins/business/import.html)
```
POST/v1/web/file-import
Content-Type multipart/form-data
params:
file 文件
code 对应导入模块的编码
```
- ``对接步骤``以导入公司用户模块为例
1.定义接口导入的``code``为``ADMIN_SYSTEM-MANAGE_BASE_USER``
2.根据接口解析导入文件的数据
3.调用基础库解析数据并传到后台
```go
// 1.解析列
excelImport := excel.NewExcelImport()
excelImport.RowBegin = 3 //第二行开始读取
excelImport.DataFields = []excel.DataField{
{EnName: "userCode", CnName: "*用户编码"},
{EnName: "userName", CnName: "*用户姓名"},
{EnName: "org", CnName: "*组织机构"},
{EnName: "department", CnName: "*所属部门"},
{EnName: "enableStatus", CnName: "*用户状态"},
{EnName: "phone", CnName: "*手机号"},
{EnName: "employeeType", CnName: "*员工类型"},
{EnName: "icCardNumber", CnName: "IC卡号"},
{EnName: "email", CnName: "邮箱"},
}
excelData, err := excelImport.OpenExcelFromIoReader(importDataCommand.Reader)
if err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
users := make([]allied_creation_user.BatchAddUserItem, 0)
for _, v := range excelData {
if srv.fieldValueAllEmpty(v) {
continue
}
item := allied_creation_user.BatchAddUserItem{
CompanyId: importDataCommand.Operator.CompanyId,
UserType: domain.UserTypeEmployee,
UserCode: strings.TrimSpace(v["userCode"]),
Org: strings.TrimSpace(v["org"]),
Department: strings.TrimSpace(v["department"]),
UserName: strings.TrimSpace(v["userName"]),
Phone: strings.TrimSpace(v["phone"]),
Email: strings.TrimSpace(v["email"]),
EnableStatus: strings.TrimSpace(v["enableStatus"]),
EmployeeType: strings.TrimSpace(v["employeeType"]),
IcCardNumber: strings.TrimSpace(v["icCardNumber"]),
}
users = append(users, item)
}
// 2.向后台服务发起批量添加请求
userGateway := allied_creation_user.NewHttplibAlliedCreationUser(importDataCommand.Operator)
result, err := userGateway.UserBatchAdd(allied_creation_user.ReqBatchAddUser{
Users: users,
Password: initPassword,
})
```
```go
```
### 2.2 Excel导出流程
- 功能原型说明
实现可以自定义选择列进行导出,以及选择导出格式,导出格式有 ``xlsx``\\``csv``,功能如下图所示:
![](https://timeless-world.oss-cn-shenzhen.aliyuncs.com/opportunity/dev_online/20220225/object/1645789890_JbTa22EtANsD3fm2nJ4aH6FJkHzXaHJB.png)
- 前后端交互说明
``接口定义``
导出接口
```shell
POST /v1/web/file-export
// request 请求参数
{
// 业务编码
"code":"string"
// 选择的导出的列
"fields":[]
// 导出文件格式
"format":"xlsx"
// 业务查询条件
"where":{}
}
```
导出列查询接口
```shell
GET/v1/web/file-export/fields/:code
// response 应答数据
{
"fields":[
{
"enName":"字段键名",
"cnName":"字段展示名称",
"selected":true // 默认勾选
}
]
}
```
- 交互流程
1.前台根据 ``导出列查询接口`` 获取可以导出的列;
2.勾选需要导出的列、文件格式,调用 ``导出接口`` 向后台发起导出数据请求;
#### 2.2.1 后端导出实现
1. 导出数据实现接口
```
type ExcelMaker interface {
DataFieldList() []DataField //字段元数据列表
CellValue(index int, enName string) (value interface{}) //获取单元格字段值
DataListLen() int //数据列表大小
TableTitle() []string //列表顶部自定义内容
}
```
如下所示
```go
//ExportCooperationUserData 导出共创用户数据
type ExportCooperationUserData struct {
SourceData []allied_creation_user.UserDetail //具体数据
SelectedField []string
}
var _ excel.ExcelMaker = (*ExportCooperationUserData)(nil)
func (data ExportCooperationUserData) AllFields() []DataFieldOptions {
return []DataFieldOptions{
{EnName: "UserCode", CnName: "用户编码"},
{EnName: "UserName", CnName: "用户姓名"},
{EnName: "Phone", CnName: "手机号"},
{EnName: "CooperationCompany", CnName: "共创公司"},
{EnName: "CooperationDeadline", CnName: "共创到期"},
{EnName: "EnableStatus", CnName: "状态"},
}
}
func (data ExportCooperationUserData) DataFieldList() []excel.DataField {
fields := []excel.DataField{}
allFields := data.AllFields()
for _, value2 := range allFields {
if len(data.SelectedField) == 0 || value2.IsDefault {
fields = append(fields, excel.DataField{EnName: value2.EnName, CnName: value2.CnName})
continue
}
for _, value3 := range data.SelectedField {
if value2.EnName == value3 {
fields = append(fields, excel.DataField{EnName: value2.EnName, CnName: value2.CnName})
}
}
}
return fields
}
func (data ExportCooperationUserData) CellValue(index int, enName string) (value interface{}) {
if index > data.DataListLen() {
return ""
}
switch enName {
case "UserCode":
return data.SourceData[index].UserCode
case "UserName":
return data.SourceData[index].UserInfo.UserName
case "CooperationCompany":
return data.SourceData[index].CooperationInfo.CooperationCompany
case "CooperationDeadline":
if data.SourceData[index].CooperationInfo.CooperationDeadline.IsZero() || data.SourceData[index].CooperationInfo.CooperationDeadline.Unix() == 0 {
return ""
}
return data.SourceData[index].CooperationInfo.CooperationDeadline.Format("2006-01-02")
case "Phone":
return data.SourceData[index].UserInfo.Phone
case "Email":
return data.SourceData[index].UserInfo.Email
case "EnableStatus":
status := data.SourceData[index].EnableStatus
statusName := ""
// 状态(1:启用 2:禁用 3:注销)
switch status {
case 1:
statusName = "启用"
case 2:
statusName = "禁用"
case 3:
statusName = "注销"
}
return statusName
}
return nil
}
func (data ExportCooperationUserData) DataListLen() int {
return len(data.SourceData)
}
func (data ExportCooperationUserData) TableTitle() []string {
return nil
}
```
2. 返回文件
```go
//返回文件
excelTool := excel.NewExcelExport()
err = excelTool.ExportData(data, "")
controller.responseExcelByFile(controller.Ctx, excelTool, filename)
func (controller *ExcelDataController) responseExcelByFile(ctx *context.Context, excelExport *excel.ExcelExport, fileName string) error {
ctx.Output.Header("Content-Disposition", "attachment; filename="+fileName)
ctx.Output.Header("Content-Description", "File Transfer")
ctx.Output.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
ctx.Output.Header("Content-Transfer-Encoding", "binary")
ctx.Output.Header("Expires", "0")
ctx.Output.Header("Cache-Control", "must-revalidate")
ctx.Output.Header("Pragma", "public")
//跳过保存文件,直接写入ctx.ResponseWriter
excelExport.ExcelFile.Write(ctx.ResponseWriter)
return nil
}
```
... ...
... ... @@ -2,6 +2,7 @@ package main
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/port/mqtt"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/port/task"
"github.com/beego/beego/v2/server/web"
... ... @@ -33,7 +34,7 @@ func main() {
log.Logger.Debug("server start ....")
log.Logger.Debug(fmt.Sprintf("ENABLE_KAFKA_LOG:%v", constant.ENABLE_KAFKA_LOG))
//go mqtt.Start()
go mqtt.Start()
go task.Run()
cron := crontab.NewCrontabService(nil)
cron.StartCrontabTask()
... ...
... ... @@ -2,6 +2,7 @@ package dto
import (
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"time"
)
type AttendanceRecordDto struct {
... ... @@ -15,7 +16,10 @@ type AttendanceRecordDto struct {
AttendanceType int `json:"attendanceType,omitempty"`
// 生产工人
ProductWorker *domain.User `json:"productWorker,omitempty"`
*domain.ProductAttendanceRecordExt
// 审核人
ApproveUser *domain.User `json:"approveUser"`
//*domain.ProductAttendanceRecordExt
ApproveAt string `json:"approveAt"`
// 工作位置
*domain.WorkStation
// 签到
... ... @@ -54,7 +58,20 @@ func (d *AttendanceRecordDto) LoadDto(m *domain.ProductAttendanceRecord, orgId i
d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId)
if m.Ext != nil {
d.OrgName = m.Ext.OrgName
d.ProductAttendanceRecordExt = m.Ext.AttendanceExt
//d.ProductAttendanceRecordExt = m.Ext.AttendanceExt
//if
if m.Ext.AttendanceExt != nil {
if m.Ext.AttendanceExt.ApproveUserId > 0 {
d.ApproveUser = &domain.User{
UserId: m.Ext.AttendanceExt.ApproveUserId,
UserName: m.Ext.AttendanceExt.ApproveUserName,
}
}
if m.Ext.AttendanceExt.ApproveAt > 0 {
t := time.Unix(m.Ext.AttendanceExt.ApproveAt, 0)
d.ApproveAt = t.Format("2006-01-02 15:04:05")
}
}
}
return d
}
... ...
package crontab
import (
"context"
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
)
// 定时刷新设备每日运行记录
func AutoFreshDeviceDailyRunningRecord(ctx context.Context) error {
defer func() {
if r := recover(); r != nil {
log.Logger.Error(fmt.Sprintf("%v", r))
}
}()
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return err
}
if err := transactionContext.StartTransaction(); err != nil {
return err
}
defer func() {
if err != nil {
log.Logger.Error("【定时刷新设备每日运行记录】 失败:" + err.Error())
}
transactionContext.RollbackTransaction()
}()
//deviceDailyRunningRecordRepository,_,_:= factory.FastPgDeviceDailyRunningRecord(transactionContext,0)
//
//// 获取redis里当天的记录
//t :=time.Now().Add(-time.Minute*20)
if err = transactionContext.CommitTransaction(); err != nil {
return err
}
return nil
}
... ...
... ... @@ -387,6 +387,32 @@ func FastPgWorkshopWorkTimeRecord(transactionContext application.TransactionCont
return rep, mod, err
}
// FastPgDeviceDailyRunningRecord 快速返回设备每日运行记录
//
// transactionContext 事务
// id 对象唯一标识
func FastPgDeviceDailyRunningRecord(transactionContext application.TransactionContext, id int, options ...option) (domain.DeviceDailyRunningRecordRepository, *domain.DeviceDailyRunningRecord, error) {
var rep domain.DeviceDailyRunningRecordRepository
var mod *domain.DeviceDailyRunningRecord
var err error
if value, err := CreateDeviceDailyRunningRecordRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
rep = value
}
if id > 0 {
if mod, err = rep.FindOne(map[string]interface{}{"deviceDailyRunningRecordId": id}); err != nil {
if err == domain.ErrorNotFound {
return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该记录不存在")
}
return nil, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
}
return rep, mod, err
}
/***** 2.配置 *****/
type FastOptions struct {
... ...
... ... @@ -20,6 +20,8 @@ type ProductLevelTwoRecord struct {
WeighAfter float64 `json:"weighAfter"`
// 审核状态 1:未审核 2:已审核
ApproveStatus int `json:"approveStatus"`
// 审核人
ApproveUser *domain.User `json:"approveUser"`
// 审核时间
ApproveAt string `json:"approveAt"`
// 计划的产品名称
... ... @@ -46,6 +48,7 @@ func (d *ProductLevelTwoRecord) LoadDto(m *domain.ProductRecord, orgId int) *Pro
d.ApproveStatus = m.ProductRecordInfo.ApproveStatus
if m.ProductRecordInfo.ApproveAt > 0 {
d.ApproveAt = time.Unix(m.ProductRecordInfo.ApproveAt, 0).Format("2006-01-02 15:04:05")
d.ApproveUser = m.ProductRecordInfo.ApproveUser
}
d.PlanProductName = m.ProductRecordInfo.PlanProductName
d.BatchNumber = m.ProductRecordInfo.BatchNumber
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type WorkshopDataConsumeCommand struct {
*domain.DeviceCollection
// 企业id
CompanyId int `cname:"企业id" json:"companyId" valid:"Required"`
// 组织ID
OrgId int `cname:"组织ID" json:"orgId" valid:"Required"`
}
func (updateWorkshopCommand *WorkshopDataConsumeCommand) Valid(validation *validation.Validation) {
}
func (updateWorkshopCommand *WorkshopDataConsumeCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(updateWorkshopCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(updateWorkshopCommand).Elem()
for _, validErr := range valid.Errors {
field, isExist := elem.FieldByName(validErr.Field)
if isExist {
return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
} else {
return fmt.Errorf(validErr.Message)
}
}
}
return nil
}
... ...
package service
import (
"github.com/linmadan/egglib-go/core/application"
"github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/workshop/command"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
)
func (workshopService *WorkshopService) WorkshopConsume(cmd *command.WorkshopDataConsumeCommand) (interface{}, error) {
if err := cmd.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
consumeService, _ := domainService.NewPGWorkshopDataConsumeService(transactionContext.(*pg.TransactionContext))
if _, err := consumeService.Consume(cmd.CompanyId, cmd.OrgId, cmd.DeviceCollection); err != nil {
log.Logger.Error(err.Error())
return nil, err
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct{}{}, nil
}
... ...
package domain
import "time"
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"time"
)
// 设备采集数据
type DeviceCollection struct {
... ... @@ -76,3 +80,7 @@ func (deviceCollection *DeviceCollection) Update(data map[string]interface{}) er
}
return nil
}
func TaskDeviceCollection() string {
return fmt.Sprintf("%v:task:device-collection:report", constant.CACHE_PREFIX)
}
... ...
... ... @@ -22,6 +22,8 @@ type DeviceDailyRunningRecord struct {
DeviceId int `json:"deviceId"`
// 设备编号
DeviceCode string `json:"deviceCode"`
// 生产日期
ProductDate time.Time `json:"productDate"`
// 设备运行记录信息
DeviceRunningRecordInfo *DeviceRunningRecordInfo `json:"deviceRunningRecordInfo"`
// 创建时间
... ... @@ -79,6 +81,10 @@ type DeviceRunningRecordInfo struct {
//TimeLine []string `json:"timeLine"`
// 时间点对应的设备状态 按小时 1
TimeLineDeviceStatus map[string]*HourDeviceStatus `json:"timeLineDeviceStatus"`
// 批次数据
// 生产计划ID
ProductPlanId int `json:"productPlanId,omitempty"`
}
func NewDeviceRunningRecordInfo() *DeviceRunningRecordInfo {
... ... @@ -87,15 +93,12 @@ func NewDeviceRunningRecordInfo() *DeviceRunningRecordInfo {
}
}
func (d *DeviceRunningRecordInfo) AddDeviceRunningData(t time.Time, data *DeviceRunningData) {
d.CurrentStatus = data.StartupState | (1 << data.ComStatus)
d.CurrentStatus = data.StartupStatus | (1 << data.ComStatus)
d.ResetUpTime()
d.Count += data.Count
//d.Temp = data.FrontTemp
if data.Temp1 > 0 {
d.Temp = data.Temp1
} else if data.FrontTemp > 0 {
d.Temp = data.FrontTemp
}
d.AddTimeLineDeviceStatus(t, data)
//d.OEE
... ... @@ -116,7 +119,7 @@ func (d *DeviceRunningRecordInfo) AddTimeLineDeviceStatus(t time.Time, data *Dev
v = NewHourDeviceStatus()
d.TimeLineDeviceStatus[key] = v
}
v.UpdateUp(t, data.StartupState)
v.UpdateUp(t, data.StartupStatus)
v.UpdateCom(t, data.ComStatus)
}
... ...
package domain
import "time"
// 设备运行数据
type DeviceRunningData struct {
// 数据采集ID
DeviceCollectionId int64 `json:"deviceCollectionId,string"`
// 车间名
WorkShopName string `json:"workShopName"`
// 采集时间
CollectionTime time.Time `json:"collectionTime"`
// 设备名
//DeviceSn string `json:"deviceSn"`
// 设备编号
DeviceCode string `json:"deviceCode"`
// 设备类型
DeviceType string `json:"deviceType"`
// 启动状态:1:启动,0:停止
StartupState int `json:"startupState"`
StartupStatus int `json:"startupStatus"`
// 通讯状态:1:通讯正常,0:设备未上电或与采集端通讯故障
ComStatus int `json:"comStatus"`
// 附加数据
// 匹配数目
Count int `json:"count"`
// 炸机前段温度:炸机前段当前温度 YZJ1 油炸机
FrontTemp float64 `json:"frontTemp"`
//FrontTemp float64 `json:"frontTemp"`
// 炸机前段温度:炸机前段当前温度 YZJ2 油炸机
Temp1 float64 `json:"temp1"`
// 当前产品种类(产品编号)
ProductType string `json:"productType"`
// 设备编号
DeviceCode string `json:"deviceCode"`
// 日期
Date string `json:"date"`
}
... ...
... ... @@ -17,7 +17,7 @@ type DeviceRunningRecord struct {
// 设备编号
DeviceCode string `json:"deviceCode"`
// 设备运行记录信息
DeviceRunningRecordInfo string `json:"deviceRunningRecordInfo"`
DeviceRunningRecordInfo *DeviceRunningData `json:"deviceRunningRecordInfo"`
// 创建时间
CreatedAt time.Time `json:"createdAt"`
}
... ...
... ... @@ -83,7 +83,10 @@ func (productAttendanceRecord *ProductAttendanceRecord) Approve(approveUser *Use
}
productAttendanceRecord.AttendanceStatus = status
productAttendanceRecord.WorkTimeAfter = workTimeAfter
if productAttendanceRecord.Ext != nil && productAttendanceRecord.Ext.AttendanceExt != nil {
if productAttendanceRecord.Ext != nil {
if productAttendanceRecord.Ext.AttendanceExt == nil {
productAttendanceRecord.Ext.AttendanceExt = &ProductAttendanceRecordExt{}
}
productAttendanceRecord.Ext.AttendanceExt.ApproveUserId = approveUser.UserId
productAttendanceRecord.Ext.AttendanceExt.ApproveUserName = approveUser.UserName
productAttendanceRecord.Ext.AttendanceExt.ApproveAt = time.Now().Unix()
... ...
... ... @@ -39,6 +39,8 @@ type PlanDispatchRecordExt struct {
ProductPlanId int `json:"productPlanId,omitempty"`
// 计划的产品名称
PlanProductName string `json:"planProductName,omitempty"`
// 产品编号 编码规则为“CP”+2 位年+2 位月+2 位日+3 位流水码,如 CP211229001
ProductCode string `json:"productCode,omitempty"`
// 上班班次 1:全天 2:白班 4:中班 8:夜班
WorkOn int `json:"workOn,omitempty"`
// 机台 (A、B、C、D 区分机器大小)
... ... @@ -80,7 +82,7 @@ func (productPlanDispatchRecord *ProductPlanDispatchRecord) ChangeStatus(status
}
func NewProductPlanDispatchRecord(productPlan *ProductPlan, workStation *WorkStation) *ProductPlanDispatchRecord {
return &ProductPlanDispatchRecord{
record := &ProductPlanDispatchRecord{
CompanyId: productPlan.CompanyId,
OrgId: productPlan.OrgId,
BatchNumber: productPlan.BatchNumber,
... ... @@ -92,10 +94,16 @@ func NewProductPlanDispatchRecord(productPlan *ProductPlan, workStation *WorkSta
PlanDispatchRecordExt: &PlanDispatchRecordExt{
ProductPlanId: productPlan.ProductPlanId,
PlanProductName: productPlan.PlanProductName,
//ProductCode: productPlan.Ext.ProductPlanExt.ProductCode,
WorkOn: productPlan.WorkOn,
Machine: productPlan.Machine,
Remark: productPlan.Remark,
},
Ext: productPlan.Ext,
}
if productPlan.Ext != nil && productPlan.Ext.ProductPlanExt != nil {
record.PlanDispatchRecordExt.ProductCode = productPlan.Ext.ProductPlanExt.ProductCode
}
return record
}
... ...
package dao
import (
"fmt"
"github.com/linmadan/egglib-go/persistent/pg/sqlbuilder"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/transform"
"time"
)
type ProductPlanDispatchRecordDao struct {
transactionContext *pgTransaction.TransactionContext
}
func NewProductPlanDispatchRecord(transactionContext *pgTransaction.TransactionContext) (*ProductPlanDispatchRecordDao, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &ProductPlanDispatchRecordDao{
transactionContext: transactionContext,
}, nil
}
}
// 生产计划对应的批次
// 工段
// 日期
// 产品编号
// 调度状态 status
func (dao *ProductPlanDispatchRecordDao) DeviceProductPlan(companyId, orgId int, workStationId string, date time.Time, productCode string, status int) (*domain.ProductPlanDispatchRecord, error) {
tx := dao.transactionContext.PgTx
productPlanDispatchRecordModel := new(models.ProductPlanDispatchRecord)
query := sqlbuilder.BuildQuery(tx.Model(productPlanDispatchRecordModel), map[string]interface{}{})
query.Where("company_id = ?", companyId)
query.Where("org_id = ?", orgId)
query.Where("work_station->>'workStationId'=?", workStationId)
query.Where("product_date = ?", date)
query.Where("plan_dispatch_status = ?", status)
query.Where("plan_dispatch_record_ext->>'productCode'=?", productCode)
query.Order("updated_at desc")
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, domain.ErrorNotFound
} else {
return nil, err
}
}
if productPlanDispatchRecordModel.ProductPlanDispatchRecordId == 0 {
return nil, nil
} else {
return transform.TransformToProductPlanDispatchRecordDomainModelFromPgModels(productPlanDispatchRecordModel)
}
}
... ...
package domainService
import (
"github.com/hibiken/asynq"
"github.com/linmadan/egglib-go/utils/json"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
)
func SendWorkshopWorkTimeStaticJob(productRecord *domain.ProductAttendanceRecord) error {
return SendAsyncJob(domain.TaskKeyWorkshopWorkTimeRecordStatics(), productRecord)
}
func SendDeviceZkTecoReportJob(productRecord *domain.DeviceZkTeco) error {
return SendAsyncJob(domain.TaskDeviceZkTecoReport(), productRecord)
}
func SendWorkshopDeviceData(productRecord *domain.DeviceCollection) error {
return SendAsyncJob(domain.TaskDeviceCollection(), productRecord)
}
func SendAsyncJob(queueName string, job interface{}) error {
task := asynq.NewTask(queueName, []byte(json.MarshalToString(job)))
client := asynq.NewClient(asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS})
_, err := client.Enqueue(task)
return err
}
... ...
package domainService
import (
"encoding/json"
"fmt"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/dao"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/redis"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
"strconv"
"time"
)
type PGWorkshopDataConsumeService struct {
transactionContext *pgTransaction.TransactionContext
}
// 消费设备生产数据
func (ptr *PGWorkshopDataConsumeService) Consume(companyId, orgId int, record *domain.DeviceCollection) (interface{}, error) {
var (
deviceRunningData *domain.DeviceRunningData
deviceRunningRecord *domain.DeviceRunningRecord
deviceDailyRecord *domain.DeviceDailyRunningRecord
workStation *domain.WorkStation
device *domain.Device
planId int
err error
plan *domain.ProductPlanDispatchRecord
datetime time.Time
)
var (
deviceRepository, _ = repository.NewDeviceRepository(ptr.transactionContext)
deviceRunningRecordRepository, _ = repository.NewDeviceRunningRecordRepository(ptr.transactionContext)
)
if deviceRunningData, err = ptr.newDeviceRunningData(record); err != nil {
return nil, err
}
// 0.初始化 从缓存捞数据、没取到查询库
deviceDailyRecord, err = redis.GetDeviceDailyRunningRecord(time.Now(), deviceRunningData.DeviceCode)
if err == domain.ErrorNotFound {
err = nil
}
if err != nil {
return nil, err
}
if deviceDailyRecord != nil {
workStation = deviceDailyRecord.WorkStation
planId = deviceDailyRecord.DeviceRunningRecordInfo.ProductPlanId
device = &domain.Device{
DeviceId: deviceDailyRecord.DeviceId,
DeviceCode: deviceDailyRecord.DeviceCode,
}
} else {
// 0.1.查询记录对应的工段、批次
// 0.2.保存一天当日记录
if device, err = deviceRepository.FindOne(map[string]interface{}{"companyId": companyId, "orgId": orgId, "deviceCode": deviceRunningData.DeviceCode}); err != nil {
log.Logger.Error(fmt.Sprintf("【设备数据-消费】 未找到设备:%v 数据数据", deviceRunningData.DeviceCode))
return nil, nil
}
workStation = device.WorkStation
// 封箱机、串串机需要定位到批次
if record.DeviceType == domain.DeviceTypeFengXiangJi && record.DeviceType == domain.DeviceTypeChuanChuanJi {
datetime, _ = time.Parse("2006-01-02", deviceRunningData.Date)
if plan, err = ptr.findDeviceProductPlan(companyId, orgId, workStation.WorkStationId, datetime, deviceRunningData.DeviceCode); err != nil {
log.Logger.Error(err.Error())
} else {
planId = plan.PlanDispatchRecordExt.ProductPlanId
}
}
var saveErr error
if deviceDailyRecord, saveErr = ptr.saveDeviceDailyRunningRecord(companyId, orgId, workStation, device, planId, deviceRunningData); err != nil {
return nil, err
}
defer func() {
if saveErr != nil {
redis.RemoveDeviceDailyRunningRecord(time.Now(), deviceRunningData.DeviceCode)
}
}()
}
// 1.保存设备运行记录
deviceRunningRecord, _ = ptr.newDeviceRunningRecord(companyId, orgId, workStation, device, deviceRunningData)
if _, err = deviceRunningRecordRepository.Save(deviceRunningRecord); err != nil {
return nil, err
}
// 2.保存设备生产记录
// 3.更新 设备每日运行记录(汇总) - redis更新 十分钟异步刷库
deviceDailyRecord.DeviceRunningRecordInfo.AddDeviceRunningData(deviceRunningData.CollectionTime, deviceRunningData)
if err = redis.SaveDeviceDailyRunningRecord(deviceDailyRecord); err != nil {
return nil, err
}
return nil, nil
}
func (ptr *PGWorkshopDataConsumeService) newDeviceRunningData(record *domain.DeviceCollection) (*domain.DeviceRunningData, error) {
var err error
var data = &domain.DeviceRunningData{
DeviceCollectionId: record.DeviceCollectionId,
WorkShopName: record.WorkShopName,
CollectionTime: record.CollectionTime,
DeviceCode: record.DeviceSn,
DeviceType: record.DeviceType,
StartupStatus: int(record.StartupStatus),
ComStatus: int(record.ComStatus),
}
var mBytes []byte
if mBytes, err = json.Marshal(record.Values); err != nil {
return nil, err
}
var formatDate = func(y, m, d string) (string, error) {
yd, _ := strconv.Atoi(y)
md, _ := strconv.Atoi(m)
dd, _ := strconv.Atoi(d)
t := time.Date(yd, time.Month(md), dd, 0, 0, 0, 0, time.Local)
return t.Format("2006-01-02"), nil
}
switch record.DeviceType {
//包馅机
case domain.DeviceTypeBaoXianJi:
deviceBaoXianJi := &domain.DeviceBaoXianJi{}
err = json.Unmarshal(mBytes, deviceBaoXianJi)
if err != nil {
break
}
data.Count = int(deviceBaoXianJi.Count)
break
//油炸机
case domain.DeviceTypeYouZhaJi:
deviceYouZhaJi := &domain.DeviceYouZhaJi{}
err = json.Unmarshal(mBytes, deviceYouZhaJi)
if err != nil {
break
}
data.Temp1 = deviceYouZhaJi.FrontTemp
break
//串串机
case domain.DeviceTypeChuanChuanJi:
deviceChuanChuanJi := &domain.DeviceChuanChuanJi{}
err = json.Unmarshal(mBytes, deviceChuanChuanJi)
if err != nil {
break
}
data.Count = int(deviceChuanChuanJi.Count)
data.ProductType = deviceChuanChuanJi.ProductType
if data.Date, err = formatDate(deviceChuanChuanJi.Year, deviceChuanChuanJi.Month, deviceChuanChuanJi.Day); err != nil {
return nil, err
}
break
//速冻线
case domain.DeviceTypeSuDongXian:
deviceSuDongXian := &domain.DeviceSuDongXian{}
err = json.Unmarshal(mBytes, deviceSuDongXian)
if err != nil {
break
}
data.Temp1 = deviceSuDongXian.CurrTemp
break
//封口机
case domain.DeviceTypeFengKouJi:
deviceFengKouJi := &domain.DeviceFengKouJi{}
err = json.Unmarshal(mBytes, deviceFengKouJi)
if err != nil {
break
}
data.Count = int(deviceFengKouJi.Count)
data.ProductType = deviceFengKouJi.ProductType
if data.Date, err = formatDate(deviceFengKouJi.Year, deviceFengKouJi.Month, deviceFengKouJi.Day); err != nil {
return nil, err
}
break
//封箱机
case domain.DeviceTypeFengXiangJi:
deviceFengXiangJi := &domain.DeviceFengXiangJi{}
err = json.Unmarshal(mBytes, deviceFengXiangJi)
if err != nil {
break
}
data.Count = int(deviceFengXiangJi.Count)
data.ProductType = deviceFengXiangJi.ProductType
if data.Date, err = formatDate(deviceFengXiangJi.Year, deviceFengXiangJi.Month, deviceFengXiangJi.Day); err != nil {
return nil, err
}
break
//打浆机
case domain.DeviceTypeDaJiangJi:
default:
}
return data, nil
}
func (ptr *PGWorkshopDataConsumeService) newDeviceRunningRecord(companyId, orgId int, workStation *domain.WorkStation, device *domain.Device, data *domain.DeviceRunningData) (*domain.DeviceRunningRecord, error) {
return &domain.DeviceRunningRecord{
CompanyId: companyId,
OrgId: orgId,
WorkStation: workStation,
DeviceId: device.DeviceId,
DeviceCode: device.DeviceCode,
DeviceRunningRecordInfo: data,
CreatedAt: time.Now(),
}, nil
}
func (ptr *PGWorkshopDataConsumeService) newProductRecord(companyId int, org *domain.Org, workStation *domain.WorkStation, device *domain.Device, data *domain.DeviceRunningData, planId int) (*domain.ProductRecord, error) {
return &domain.ProductRecord{
CompanyId: companyId,
OrgId: org.OrgId,
WorkStation: workStation,
ProductRecordType: domain.RecordTypeWeigh,
ProductWorker: &domain.User{},
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
ProductRecordInfo: &domain.ProductRecordInfo{
ProductDate: data.CollectionTime.Format("2006-01-02"),
Original: float64(data.Count),
Weigh: float64(data.Count),
WeighBefore: float64(data.Count),
ApproveStatus: domain.AttendanceNotApprove,
ProductPlanId: planId,
},
Ext: domain.NewExt(org.OrgName),
}, nil
}
func (ptr *PGWorkshopDataConsumeService) saveDeviceDailyRunningRecord(companyId, orgId int, workStation *domain.WorkStation, device *domain.Device, planId int, data *domain.DeviceRunningData) (*domain.DeviceDailyRunningRecord, error) {
var (
record *domain.DeviceDailyRunningRecord
err error
)
deviceDailyRunningRecordRepository, _ := repository.NewDeviceDailyRunningRecordRepository(ptr.transactionContext)
if record, err = deviceDailyRunningRecordRepository.FindOne(map[string]interface{}{
"workStationId": workStation.WorkStationId,
"deviceCode": data.DeviceCode,
"productDate": utils.GetZeroTime(time.Now()),
}); err != nil {
if err != domain.ErrorNotFound {
return nil, err
}
}
if record != nil {
return record, nil
}
recordInfo := domain.NewDeviceRunningRecordInfo()
recordInfo.ProductPlanId = planId
record = &domain.DeviceDailyRunningRecord{
CompanyId: companyId,
OrgId: orgId,
WorkStation: workStation,
DeviceId: device.DeviceId,
DeviceCode: device.DeviceCode,
ProductDate: utils.GetZeroTime(time.Now()),
DeviceRunningRecordInfo: recordInfo,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
if record, err = deviceDailyRunningRecordRepository.Save(record); err != nil {
return nil, err
}
return record, nil
}
// 查找设备的生产计划,如果计划没有上线的话将他上线
func (ptr *PGWorkshopDataConsumeService) findDeviceProductPlan(companyId, orgId int, workStationId string, date time.Time, productCode string) (*domain.ProductPlanDispatchRecord, error) {
planDispatchRecordDao, _ := dao.NewProductPlanDispatchRecord(ptr.transactionContext)
planDispatchRecordRepository, _ := repository.NewProductPlanDispatchRecordRepository(ptr.transactionContext)
var setPlanOnline = false
record, err := planDispatchRecordDao.DeviceProductPlan(companyId, orgId, workStationId, date, productCode, domain.PlanOnline)
if err == domain.ErrorNotFound {
if record, err = planDispatchRecordDao.DeviceProductPlan(companyId, orgId, workStationId, date, productCode, domain.PlanOffline); err != nil {
return nil, err
} else {
setPlanOnline = true
}
}
if setPlanOnline {
record.ChangeStatus(domain.PlanOnline)
if record, err = planDispatchRecordRepository.Save(record); err != nil {
return nil, err
}
}
return record, nil
}
func NewPGWorkshopDataConsumeService(transactionContext *pgTransaction.TransactionContext) (*PGWorkshopDataConsumeService, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &PGWorkshopDataConsumeService{
transactionContext: transactionContext,
}, nil
}
}
... ...
... ... @@ -3,10 +3,7 @@ package domainService
import (
"errors"
"fmt"
"github.com/hibiken/asynq"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"github.com/linmadan/egglib-go/utils/json"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
... ... @@ -58,22 +55,6 @@ func (ptr *PGWorkshopWorkTimeStaticService) WorkshopWorkTimeStatic(productRecord
return record, nil
}
func SendWorkshopWorkTimeStaticJob(productRecord *domain.ProductAttendanceRecord) error {
return SendAsyncJob(domain.TaskKeyWorkshopWorkTimeRecordStatics(), productRecord)
}
func SendDeviceZkTecoReportJob(productRecord *domain.DeviceZkTeco) error {
return SendAsyncJob(domain.TaskDeviceZkTecoReport(), productRecord)
}
func SendAsyncJob(queueName string, job interface{}) error {
task := asynq.NewTask(queueName, []byte(json.MarshalToString(job)))
client := asynq.NewClient(asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS})
_, err := client.Enqueue(task)
return err
}
func NewPGWorkshopWorkTimeStaticService(transactionContext *pgTransaction.TransactionContext) (*PGWorkshopWorkTimeStaticService, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
... ...
... ... @@ -44,6 +44,8 @@ func init() {
(*models.WorkshopProductRecord)(nil),
(*models.WorkshopWorkTimeRecord)(nil),
(*models.ProductPlanDispatchRecord)(nil),
(*models.DeviceDailyRunningRecord)(nil),
(*models.DeviceRunningRecord)(nil),
} {
err := DB.Model(model).CreateTable(&orm.CreateTableOptions{
Temp: false,
... ...
... ... @@ -19,6 +19,8 @@ type DeviceDailyRunningRecord struct {
DeviceId int `comment:"设备Id"`
// 设备编号
DeviceCode string `comment:"设备编号"`
// 生产日期
ProductDate time.Time `json:"productDate"`
// 设备运行记录信息
DeviceRunningRecordInfo *domain.DeviceRunningRecordInfo `comment:"设备运行记录信息"`
// 创建时间
... ...
... ... @@ -20,7 +20,7 @@ type DeviceRunningRecord struct {
// 设备编号
DeviceCode string `comment:"设备编号"`
// 设备运行记录信息
DeviceRunningRecordInfo string `comment:"设备运行记录信息"`
DeviceRunningRecordInfo *domain.DeviceRunningData `comment:"设备运行记录信息"`
// 创建时间
CreatedAt time.Time `comment:"创建时间"`
}
... ...
... ... @@ -13,6 +13,7 @@ func TransformToDeviceDailyRunningRecordDomainModelFromPgModels(deviceDailyRunni
WorkStation: deviceDailyRunningRecordModel.WorkStation,
DeviceId: deviceDailyRunningRecordModel.DeviceId,
DeviceCode: deviceDailyRunningRecordModel.DeviceCode,
ProductDate: deviceDailyRunningRecordModel.ProductDate,
DeviceRunningRecordInfo: deviceDailyRunningRecordModel.DeviceRunningRecordInfo,
CreatedAt: deviceDailyRunningRecordModel.CreatedAt,
UpdatedAt: deviceDailyRunningRecordModel.UpdatedAt,
... ...
package redis
import (
"encoding/json"
"fmt"
"github.com/go-redis/redis"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"time"
)
// 获取每日设备运行数据
func GetDeviceDailyRunningRecord(t time.Time, deviceCode string) (*domain.DeviceDailyRunningRecord, error) {
client := GetRedis()
key := DeviceDailyRunningRecordKey(t, deviceCode)
result := client.Get(key)
data, err := result.Bytes()
if err == redis.Nil {
return nil, domain.ErrorNotFound
}
var record = &domain.DeviceDailyRunningRecord{}
if err = json.Unmarshal(data, record); err != nil {
return nil, err
}
return record, nil
}
// 保存每日设备运行数据
func SaveDeviceDailyRunningRecord(record *domain.DeviceDailyRunningRecord) error {
client := GetRedis()
key := DeviceDailyRunningRecordKey(record.CreatedAt, record.DeviceCode)
recordData, err := json.Marshal(record)
result := client.Set(key, recordData, time.Hour*24*5)
_, err = result.Result()
return err
}
// 保存每日设备运行数据
func RemoveDeviceDailyRunningRecord(t time.Time, deviceCode string) error {
client := GetRedis()
key := DeviceDailyRunningRecordKey(t, deviceCode)
result := client.Del(key)
_, err := result.Result()
return err
}
func DeviceDailyRunningRecordKey(t time.Time, deviceCode string) string {
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)
return str
}
... ...
... ... @@ -32,15 +32,16 @@ func (repository *DeviceDailyRunningRecordRepository) Save(deviceDailyRunningRec
"work_station",
"device_id",
"device_code",
"product_date",
"device_running_record_info",
"created_at",
"updated_at",
"deleted_at",
}
insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlBuildFields)
insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlBuildFields)
insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "device_daily_running_record_id", "deleted_at"))
insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "device_daily_running_record_id", "deleted_at"))
returningFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlBuildFields)
updateFields := sqlbuilder.RemoveSqlFields(sqlBuildFields, "deviceDailyRunningRecord_id")
updateFields := sqlbuilder.RemoveSqlFields(sqlBuildFields, "device_daily_running_record_id", "deleted_at")
updateFieldsSnippet := sqlbuilder.SqlUpdateFieldsSnippet(updateFields)
tx := repository.transactionContext.PgTx
if deviceDailyRunningRecord.Identify() == nil {
... ... @@ -52,22 +53,24 @@ func (repository *DeviceDailyRunningRecordRepository) Save(deviceDailyRunningRec
&deviceDailyRunningRecord.WorkStation,
&deviceDailyRunningRecord.DeviceId,
&deviceDailyRunningRecord.DeviceCode,
&deviceDailyRunningRecord.ProductDate,
&deviceDailyRunningRecord.DeviceRunningRecordInfo,
&deviceDailyRunningRecord.CreatedAt,
&deviceDailyRunningRecord.UpdatedAt,
&deviceDailyRunningRecord.DeletedAt,
),
fmt.Sprintf("INSERT INTO manufacture.device_daily_running_record (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet),
deviceDailyRunningRecord.DeviceDailyRunningRecordId,
//deviceDailyRunningRecord.DeviceDailyRunningRecordId,
deviceDailyRunningRecord.CompanyId,
deviceDailyRunningRecord.OrgId,
deviceDailyRunningRecord.WorkStation,
deviceDailyRunningRecord.DeviceId,
deviceDailyRunningRecord.DeviceCode,
deviceDailyRunningRecord.ProductDate,
deviceDailyRunningRecord.DeviceRunningRecordInfo,
deviceDailyRunningRecord.CreatedAt,
deviceDailyRunningRecord.UpdatedAt,
deviceDailyRunningRecord.DeletedAt,
//deviceDailyRunningRecord.DeletedAt,
); err != nil {
return deviceDailyRunningRecord, err
}
... ... @@ -80,22 +83,24 @@ func (repository *DeviceDailyRunningRecordRepository) Save(deviceDailyRunningRec
&deviceDailyRunningRecord.WorkStation,
&deviceDailyRunningRecord.DeviceId,
&deviceDailyRunningRecord.DeviceCode,
&deviceDailyRunningRecord.ProductDate,
&deviceDailyRunningRecord.DeviceRunningRecordInfo,
&deviceDailyRunningRecord.CreatedAt,
&deviceDailyRunningRecord.UpdatedAt,
&deviceDailyRunningRecord.DeletedAt,
),
fmt.Sprintf("UPDATE manufacture.device_daily_running_record SET %s WHERE device_daily_running_record_id=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet),
deviceDailyRunningRecord.DeviceDailyRunningRecordId,
//deviceDailyRunningRecord.DeviceDailyRunningRecordId,
deviceDailyRunningRecord.CompanyId,
deviceDailyRunningRecord.OrgId,
deviceDailyRunningRecord.WorkStation,
deviceDailyRunningRecord.DeviceId,
deviceDailyRunningRecord.DeviceCode,
deviceDailyRunningRecord.ProductDate,
deviceDailyRunningRecord.DeviceRunningRecordInfo,
deviceDailyRunningRecord.CreatedAt,
deviceDailyRunningRecord.UpdatedAt,
deviceDailyRunningRecord.DeletedAt,
//deviceDailyRunningRecord.DeletedAt,
deviceDailyRunningRecord.Identify(),
); err != nil {
return deviceDailyRunningRecord, err
... ... @@ -116,10 +121,13 @@ func (repository *DeviceDailyRunningRecordRepository) FindOne(queryOptions map[s
tx := repository.transactionContext.PgTx
deviceDailyRunningRecordModel := new(models.DeviceDailyRunningRecord)
query := sqlbuilder.BuildQuery(tx.Model(deviceDailyRunningRecordModel), queryOptions)
query.SetWhereByQueryOption("work_station->>'workStationId'=?", "workStationId")
query.SetWhereByQueryOption("device_code=? ", "deviceCode")
query.SetWhereByQueryOption("product_date=? ", "productDate")
query.SetWhereByQueryOption("device_daily_running_record.device_daily_running_record_id = ?", "deviceDailyRunningRecordId")
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, fmt.Errorf("没有此资源")
return nil, domain.ErrorNotFound
} else {
return nil, err
}
... ...
... ... @@ -53,7 +53,7 @@ func (repository *DeviceRunningRecordRepository) Save(deviceRunningRecord *domai
&deviceRunningRecord.DeviceRunningRecordInfo,
&deviceRunningRecord.CreatedAt,
),
fmt.Sprintf("INSERT INTO device_running_records (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet),
fmt.Sprintf("INSERT INTO manufacture.device_running_record (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet),
//deviceRunningRecord.DeviceRunningRecordId,
deviceRunningRecord.CompanyId,
deviceRunningRecord.OrgId,
... ... @@ -77,7 +77,7 @@ func (repository *DeviceRunningRecordRepository) Save(deviceRunningRecord *domai
&deviceRunningRecord.DeviceRunningRecordInfo,
&deviceRunningRecord.CreatedAt,
),
fmt.Sprintf("UPDATE device_running_records SET %s WHERE device_running_record_id=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet),
fmt.Sprintf("UPDATE manufacture.device_running_record SET %s WHERE device_running_record_id=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet),
//deviceRunningRecord.DeviceRunningRecordId,
deviceRunningRecord.CompanyId,
deviceRunningRecord.OrgId,
... ...
... ... @@ -150,6 +150,15 @@ func (repository *ProductPlanDispatchRecordRepository) Find(queryOptions map[str
var productPlanDispatchRecordModels []*models.ProductPlanDispatchRecord
productPlanDispatchRecords := make([]*domain.ProductPlanDispatchRecord, 0)
query := sqlbuilder.BuildQuery(tx.Model(&productPlanDispatchRecordModels), queryOptions)
query.SetWhereByQueryOption("company_id = ?", "companyId")
query.SetWhereByQueryOption("org_id = ?", "orgId")
query.SetWhereByQueryOption("work_station->>'workshopId'='?'", "workshopId")
if v, ok := queryOptions["batchNumber"]; ok && len(v.(string)) > 0 {
query.Where(fmt.Sprintf(`batch_number like '%%%v%%'`, v))
}
if v, ok := queryOptions["workshopName"]; ok && len(v.(string)) > 0 {
query.Where(fmt.Sprintf(`workshop->>'workshopName' like '%%%v%%'`, v))
}
query.SetWhereByQueryOption("plan_dispatch_status=?", "planDispatchStatus")
query.SetOffsetAndLimit(domain.MaxQueryRow)
query.SetOrderDirect("product_plan_dispatch_record_id", "DESC")
... ...
... ... @@ -63,6 +63,10 @@ func (controller *AttendanceController) ApproveAttendance() {
attendanceService := service.NewAttendanceService(nil)
approveAttendanceCommand := &command.ApproveAttendanceCommand{}
controller.Unmarshal(approveAttendanceCommand)
if approveAttendanceCommand.ApproveUserId == 0 {
operateInfo := ParseOperateInfo(controller.BaseController)
approveAttendanceCommand.ApproveUserId = operateInfo.UserId
}
data, err := attendanceService.ApproveAttendance(approveAttendanceCommand)
controller.Response(data, err)
}
... ...
... ... @@ -63,6 +63,10 @@ func (controller *ProductRecordController) ApproveProductRecord() {
productRecordService := service.NewProductRecordService(nil)
approveProductRecordCommand := &command.ApproveProductRecordCommand{}
controller.Unmarshal(approveProductRecordCommand)
if approveProductRecordCommand.ApproveUserId == 0 {
operateInfo := ParseOperateInfo(controller.BaseController)
approveProductRecordCommand.ApproveUserId = operateInfo.UserId
}
data, err := productRecordService.ApproveProductRecord(approveProductRecordCommand)
controller.Response(data, err)
}
... ...
... ... @@ -3,6 +3,8 @@ package controllers
import (
"github.com/linmadan/egglib-go/web/beego"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/syncdata"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
)
type TestController struct {
... ... @@ -26,3 +28,10 @@ func (c *TestController) InvokPullPrdMoNewest() {
err := srv.PullPrdMoNewest()
c.Response(nil, err)
}
func (c *TestController) CreateDeviceCollection() {
data := &domain.DeviceCollection{}
Must(c.Unmarshal(data))
domainService.SendWorkshopDeviceData(data)
c.Response(nil, nil)
}
... ...
... ... @@ -9,4 +9,6 @@ func init() {
web.Router("/TestController/PullMaterialNewest", &controllers.TestController{}, "Get:InvokPullMaterialNewest")
web.Router("/TestController/PullMaterialGroup", &controllers.TestController{}, "Get:InvokPullMaterialGroup")
web.Router("/TestController/InvokPullPrdMoNewest", &controllers.TestController{}, "Get:InvokPullPrdMoNewest")
web.Router("/test/create-device-collection", &controllers.TestController{}, "Post:CreateDeviceCollection")
}
... ...
... ... @@ -6,8 +6,8 @@ import (
"github.com/tidwall/gjson"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/mqtt"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/redis"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
"time"
... ... @@ -101,11 +101,15 @@ func Start() {
case domain.DeviceTypeDaJiangJi:
default:
}
workShopBytes, err := json.Marshal(deviceCollection)
if err != nil {
continue
}
err = redis.GetRedis().LPush(constant.REDIS_WORKSHOP_KEY, string(workShopBytes)).Err()
//workShopBytes, err := json.Marshal(deviceCollection)
//if err != nil {
// continue
//}
//err = redis.GetRedis().LPush(constant.REDIS_WORKSHOP_KEY, string(workShopBytes)).Err()
//if err != nil {
// log.Logger.Error("车间设备数据加入redis失败:" + err.Error())
//}
err = domainService.SendWorkshopDeviceData(deviceCollection)
if err != nil {
log.Logger.Error("车间设备数据加入redis失败:" + err.Error())
}
... ...
... ... @@ -21,6 +21,7 @@ func Run() {
h.HandleFunc(domain.TaskKeyPatternProductRecordStatics(), HandlerProductRecordStatics)
h.HandleFunc(domain.TaskKeyWorkshopWorkTimeRecordStatics(), WorkshopWorkTimeRecordStatics)
h.HandleFunc(domain.TaskDeviceZkTecoReport(), WorkerAttendanceReport)
h.HandleFunc(domain.TaskDeviceCollection(), WorkshopDataConsumer)
log.Logger.Info("aysnq task running ...")
// Run blocks and waits for os signal to terminate the program.
if err := srv.Run(h); err != nil {
... ...
... ... @@ -14,8 +14,9 @@ import (
func WorkshopWorkTimeRecordStatics(c context.Context, t *asynq.Task) error {
svr := service.NewAttendanceService(nil)
cmd := &command.WorkshopWorkTimeRecordStaticsCommand{}
if err := json.Unmarshal(t.Payload(), cmd); err != nil || cmd == nil {
return err
if err := json.Unmarshal(t.Payload(), cmd); err != nil {
log.Logger.Error("【考勤记录统计】 数据解析" + err.Error())
return nil
}
log.Logger.Debug(fmt.Sprintf("【考勤记录统计】 消费 记录ID:%v 时间:%v", cmd.ProductAttendanceId, cmd.WorkTimeBefore))
_, err := svr.WorkshopWorkTimeRecordStatics(cmd)
... ...
package task
import (
"context"
"encoding/json"
"fmt"
"github.com/hibiken/asynq"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/workshop/command"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/workshop/service"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
)
// 车间数据消费
func WorkshopDataConsumer(c context.Context, t *asynq.Task) error {
svr := service.NewWorkshopService(nil)
cmd := &command.WorkshopDataConsumeCommand{}
if err := json.Unmarshal(t.Payload(), cmd); err != nil {
return err
}
log.Logger.Debug(fmt.Sprintf("【车间数据消费】 消费 设备:%v 消息号:%v 时间:%v ", cmd.DeviceCollection.DeviceSn, cmd.DeviceCollectionId, cmd.CollectionTime))
cmd.CompanyId = constant.MANUFACTURE_DEFAULT_COMPANYID
cmd.OrgId = constant.MANUFACTURE_DEFAULT_ORGID
_, err := svr.WorkshopConsume(cmd)
if err != nil {
log.Logger.Error(err.Error())
}
return nil
}
... ...