作者 庄敏学

Merge branch 'dev' of http://gitlab.fjmaimaimai.com/allied-creation/allied-creat…

…ion-manufacture into dev
正在显示 47 个修改的文件 包含 772 行增加126 行删除
... ... @@ -97,4 +97,24 @@ spec:
- name: HTTP_PORT
value: "8082"
- name: SERVICE_ENV
value: "dev"
\ No newline at end of file
value: "dev"
- name: SUPLUS_ADMIN_BASE_HOST
value: "http://suplus-admin-base-dev.fjmaimaimai.com"
- name: ALLIED_CREATION_GATEWAY_HOST
value: "https://allied-creation-gateway-test.fjmaimaimai.com"
- name: ALLIED_CREATION_USER_HOST
value: "https://allied-creation-user-test.fjmaimaimai.com"
- name: ALLIED_CREATION_COOPERATION_HOST
value: "https://allied-creation-cooperation-test.fjmaimaimai.com"
- name: ALLIED_CREATION_BASIC_HOST
value: "https://allied-creation-basic-test.fjmaimaimai.com"
- name: ALLIED_CREATION_MANUFACTURE_HOST
value: "http://allied-creation-manufacture-test.fjmaimaimai.com"
- name: SMS_SERVE_HOST
value: "https://sms.fjmaimaimai.com:9897"
- name: SUPLUS_SALE_APP
value: "http://suplus-sale-app-gateway-test.fjmaimaimai.com"
- name: MANUFACTURE_DEFAULT_COMPANYID
value: "23"
- name: MANUFACTURE_DEFAULT_ORGID
value: "487"
\ No newline at end of file
... ...
... ... @@ -20,9 +20,6 @@ import (
)
func main() {
log.Logger.Info("server start ....")
log.Logger.Info(fmt.Sprintf("ENABLE_KAFKA_LOG:%v", constant.ENABLE_KAFKA_LOG))
if constant.ENABLE_KAFKA_LOG {
w, _ := logrus.NewKafkaWriter(constant.KAFKA_HOST, constant.TOPIC_LOG_STASH, false)
log.Logger.AddHook(w)
... ... @@ -34,6 +31,9 @@ func main() {
})
log.Logger.AddHook(bw)
redis.InitRedis()
log.Logger.Debug("server start ....")
log.Logger.Debug(fmt.Sprintf("ENABLE_KAFKA_LOG:%v", constant.ENABLE_KAFKA_LOG))
go mqtt.Start()
go task.Run()
cron := crontab.NewCrontabService(nil)
... ...
package command
import (
"fmt"
"github.com/beego/beego/v2/core/validation"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"reflect"
"strings"
)
type WorkerAttendanceReportCommand struct {
*domain.DeviceZkTeco
}
func (removeProductRecordCommand *WorkerAttendanceReportCommand) Valid(validation *validation.Validation) {
//validation.SetError("CustomValid", "未实现的自定义认证")
}
func (removeProductRecordCommand *WorkerAttendanceReportCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(removeProductRecordCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(removeProductRecordCommand).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"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/attendance/command"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
)
func (attendanceService *AttendanceService) WorkerAttendanceReport(cmd *command.WorkerAttendanceReportCommand) (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()
}()
//svr, _ := domainService.NewPGWorkshopWorkTimeStaticService(transactionContext.(*pgTransaction.TransactionContext))
//if _, err := svr.WorkshopWorkTimeStatic(cmd.ProductAttendanceRecord); err != nil {
// log.Logger.Error(err.Error())
// return nil, err
//}
attendanceReportService, _ := domainService.NewPGWorkerAttendanceReportService(transactionContext.(*pgTransaction.TransactionContext))
if _, err := attendanceReportService.Report(constant.MANUFACTURE_DEFAULT_COMPANYID, constant.MANUFACTURE_DEFAULT_COMPANYID, cmd.DeviceZkTeco); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct{}{}, nil
}
... ...
... ... @@ -37,7 +37,7 @@ func (crontabService *CrontabService) initTask() {
})
task.AddTask("PullPrdMoK3cloud", PullPrdMoK3cloud)
autoApproveAttendanceRecord := task.NewTask("autoApproveAttendanceRecord", "0 */1 * * * *", AutoApproveProductAttendanceRecord)
autoApproveAttendanceRecord := task.NewTask("autoApproveAttendanceRecord", "0 */2 * * * *", AutoApproveProductAttendanceRecord)
task.AddTask("autoApproveAttendanceRecord", autoApproveAttendanceRecord)
autoApproveRecord := task.NewTask("autoApproveRecord", "0 */2 * * * *", AutoApproveProductRecord)
... ...
... ... @@ -350,7 +350,7 @@ func (deviceService *DeviceService) SearchDevice(operateInfo *domain.OperateInfo
for i := range devices {
item := devices[i]
newJobDto := &dto.DeviceDto{}
item.WorkStation = workshops.FindWorkStation(item.WorkStation.WorkshopId, item.WorkStation.LineId, item.WorkStation.SectionId)
newJobDto.WorkStation = workshops.FindWorkStation(item.WorkStation.WorkshopId, item.WorkStation.LineId, item.WorkStation.SectionId)
newJobDto.LoadDto(item, operateInfo.OrgId)
result = append(result, newJobDto)
}
... ...
... ... @@ -328,8 +328,8 @@ func (productCalendarService *ProductCalendarService) UpdateProductCalendar(cmd
}
// 返回工厂日历服务列表
func (productCalendarService *ProductCalendarService) SearchProductCalendar(operateInfo *domain.OperateInfo, listProductCalendarQuery *query.SearchProductCalendarQuery) (int64, interface{}, error) {
if err := listProductCalendarQuery.ValidateQuery(); err != nil {
func (productCalendarService *ProductCalendarService) SearchProductCalendar(operateInfo *domain.OperateInfo, cmd *query.SearchProductCalendarQuery) (int64, interface{}, error) {
if err := cmd.ValidateQuery(); err != nil {
return 0, nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
... ... @@ -345,7 +345,12 @@ func (productCalendarService *ProductCalendarService) SearchProductCalendar(oper
var productCalendarRepository domain.ProductCalendarRepository
productCalendarRepository, _, _ = factory.FastPgProductCalendar(transactionContext, 0)
count, productCalendars, err := productCalendarRepository.Find(utils.ObjectToMap(listProductCalendarQuery))
workshops, _ := factory.FastPgWorkshops(transactionContext, operateInfo.CompanyId)
queryOptions := utils.ObjectToMap(cmd)
delete(queryOptions, "workshopName")
queryOptions = workshops.FindByNameWithQuery(queryOptions, cmd.WorkshopName, "", "")
count, productCalendars, err := productCalendarRepository.Find(queryOptions)
if err != nil {
return 0, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
... ... @@ -358,6 +363,7 @@ func (productCalendarService *ProductCalendarService) SearchProductCalendar(oper
item := productCalendars[i]
newJobDto := &dto.ProductCalendarDto{}
newJobDto.LoadDto(item, operateInfo.OrgId)
newJobDto.WorkStation = workshops.FindWorkStation(item.WorkStation.WorkshopId, item.WorkStation.LineId, item.WorkStation.SectionId)
result = append(result, newJobDto)
}
... ...
... ... @@ -2,6 +2,7 @@ package dto
import (
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils/converter"
"strings"
)
... ... @@ -19,6 +20,7 @@ type ProductGroupEmployeesDto struct {
WorkOnDescription string `json:"workOn,omitempty"`
// 工作位置键值 (车间ID+'.'+生产线ID+'.'+工段ID)
//WorkStationId string `json:"workStationId,omitempty"`
UserNamePinyin string `json:"pinyin"`
}
func NewProductGroupEmployeesDto(group *domain.ProductGroup) []*ProductGroupEmployeesDto {
... ... @@ -41,6 +43,9 @@ func NewGroupEmployee(group *domain.ProductGroup, u *domain.User) *ProductGroupE
workOns := domain.WorkOnDescription(group.WorkOn)
item.WorkOnDescription = strings.Join(workOns, ",")
//item.WorkStationId = group.WorkStation.WorkStationId
if len(item.UserName) > 0 {
item.UserNamePinyin = converter.ToPinYin(item.UserName, "")
}
return item
}
... ... @@ -72,3 +77,11 @@ func NewProductGroupEmployeesDtos() *ProductGroupEmployeesDtos {
MapResult: make(map[int]*ProductGroupEmployeesDto),
}
}
func (ms *ProductGroupEmployeesDtos) Len() int { return len(ms.Result) }
func (ms *ProductGroupEmployeesDtos) Less(i, j int) bool {
return ms.Result[i].UserNamePinyin < ms.Result[j].UserNamePinyin
}
func (ms *ProductGroupEmployeesDtos) Swap(i, j int) {
ms.Result[i], ms.Result[j] = ms.Result[j], ms.Result[i]
}
... ...
... ... @@ -11,6 +11,7 @@ import (
"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/utils"
"sort"
"time"
)
... ... @@ -358,7 +359,7 @@ func (productGroupService *ProductGroupService) SearchProductGroup(operateInfo *
item := productGroups[i]
newItem := &dto.ProductGroupDto{}
newItem.LoadDto(productGroups[i], operateInfo.OrgId)
item.WorkStation = workshops.FindWorkStation(item.WorkStation.WorkshopId, item.WorkStation.LineId, item.WorkStation.SectionId)
newItem.WorkStation = workshops.FindWorkStation(item.WorkStation.WorkshopId, item.WorkStation.LineId, item.WorkStation.SectionId)
results = append(results, newItem)
}
if err := transactionContext.CommitTransaction(); err != nil {
... ... @@ -401,6 +402,7 @@ func (productGroupService *ProductGroupService) SearchProductGroupEmployees(oper
items := dto.NewProductGroupEmployeesDto(item)
results.Append(items...)
}
sort.Stable(results)
if err := transactionContext.CommitTransaction(); err != nil {
return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
... ...
... ... @@ -335,9 +335,11 @@ func (productJobService *ProductJobService) SearchProductJob(operateInfo *domain
var result = make([]*dto.ProductJobDto, 0)
for i := range productJobs {
item := productJobs[i]
item.WorkStation = workshops.FindWorkStation(item.WorkStation.WorkshopId, item.WorkStation.LineId, item.WorkStation.SectionId)
newJobDto := &dto.ProductJobDto{}
newJobDto.LoadDto(item, operateInfo.OrgId)
newJobDto.WorkStation = workshops.FindWorkStation(item.WorkStation.WorkshopId, item.WorkStation.LineId, item.WorkStation.SectionId)
newJobDto.WorkStation.Principal = item.WorkStation.Principal
result = append(result, newJobDto)
}
return count, result, nil
... ...
... ... @@ -17,7 +17,7 @@ type CreateProductPlanCommand struct {
// 车间ID
WorkshopId int `cname:"车间ID" json:"workshopId" valid:"Required"`
// 批号
BatchNumber string `cname:"批号" json:"batchNumber" valid:"Required"`
BatchNumber string `cname:"批号" json:"batchNumber"`
// 生产日期
ProductDate string `cname:"生产日期" json:"productDate" valid:"Required"`
// 上班班次 1:全天 2:白班 4:中班 8:夜班
... ... @@ -28,17 +28,14 @@ type CreateProductPlanCommand struct {
//PlanProductName string `cname:"计划的产品名称" json:"planProductName"`
// 产品ID
ProductId int `cname:"产品ID" json:"productId" valid:"Required"`
// 投入量规格 默认份
DevotedUnit string `cname:"投入量规格" json:"devotedUnit" `
// 数量(保留两位小数)
Quantity float64 `cname:"数量(保留两位小数)" json:"quantity" valid:"Required"`
// 单位
//Unit string `cname:"单位" json:"unit" `
// 单份重量(原材料)
//nitWeight float64 `cname:"单份重量(原材料)" json:"unitWeight" valid:"Required"`
// 重量
Weight float64 `cname:"重量" json:"weight" valid:"Required"`
// 备注
Remark string `cname:"备注" json:"remark"`
// 生产日期
ProductDateTime time.Time `cname:"生产日期" json:"-" `
}
... ... @@ -49,8 +46,8 @@ func (createProductPlanCommand *CreateProductPlanCommand) Valid(validation *vali
validation.Error(err.Error())
return
}
if t, err := time.Parse("2006/01/02", createProductPlanCommand.ProductDate); err != nil {
validation.Error("时间格式有误 2006/01/02")
if t, err := time.Parse("2006-01-02", createProductPlanCommand.ProductDate); err != nil {
validation.Error("时间格式有误" + createProductPlanCommand.ProductDate)
return
} else {
createProductPlanCommand.ProductDateTime = t
... ...
... ... @@ -19,7 +19,7 @@ type UpdateProductPlanCommand struct {
// 车间ID
WorkshopId int `cname:"车间ID" json:"workshopId" valid:"Required"`
// 批号
BatchNumber string `cname:"批号" json:"batchNumber" valid:"Required"`
BatchNumber string `cname:"批号" json:"batchNumber"`
// 生产日期
ProductDate string `cname:"生产日期" json:"productDate" valid:"Required"`
// 上班班次 1:全天 2:白班 4:中班 8:夜班
... ... @@ -30,6 +30,8 @@ type UpdateProductPlanCommand struct {
PlanProductName string `cname:"计划的产品名称" json:"planProductName"`
// 产品ID
ProductId int `cname:"产品ID" json:"productId" valid:"Required"`
// 投入量规格 默认份
DevotedUnit string `cname:"投入量规格" json:"devotedUnit" `
// 数量(保留两位小数)
Quantity float64 `cname:"数量(保留两位小数)" json:"quantity" valid:"Required"`
// 单位
... ... @@ -39,7 +41,7 @@ type UpdateProductPlanCommand struct {
// 重量
Weight float64 `cname:"重量" json:"weight"`
// 备注
Remark string `cname:"备注" json:"remark" valid:"Required"`
Remark string `cname:"备注" json:"remark"`
// 生产日期
ProductDateTime time.Time `cname:"生产日期" json:"productDateTime" `
}
... ... @@ -49,8 +51,8 @@ func (updateProductPlanCommand *UpdateProductPlanCommand) Valid(validation *vali
validation.Error(err.Error())
return
}
if t, err := time.Parse("2006/01/02", updateProductPlanCommand.ProductDate); err != nil {
validation.Error("时间格式有误 2006/01/02")
if t, err := time.Parse("2006-01-02", updateProductPlanCommand.ProductDate); err != nil {
validation.Error("时间格式有误")
return
} else {
updateProductPlanCommand.ProductDateTime = t
... ...
... ... @@ -23,9 +23,13 @@ type ProductPlanDto struct {
// 上班班次描述
WorkOnDescription string `json:"workOnDescription"`
// 机台 (A、B、C、D 区分机器大小)
Machine string `json:"machine,omitempty"`
Machine string `json:"machine"`
// 产品ID
ProductId int `json:"productId,omitempty"`
// 计划的产品名称
PlanProductName string `json:"planProductName,omitempty"`
// 投入量规格 默认份
DevotedUnit string `json:"devotedUnit" `
// 计划投入
*domain.UnitQuantity
// 计划状态 (1:上线 2:下线 默认下线)
... ... @@ -45,12 +49,19 @@ type ProductPlanDto struct {
func (d *ProductPlanDto) LoadDto(m *domain.ProductPlan, orgId int) *ProductPlanDto {
d.ProductPlanId = m.ProductPlanId
d.BatchNumber = m.BatchNumber
d.ProductDate = m.ProductDate.Format("2006/01/02")
d.ProductDate = m.ProductDate.Format("2006-01-02")
d.WorkshopId = m.Workshop.WorkshopId
d.WorkshopName = m.Workshop.WorkshopName
d.WorkOn = m.WorkOn
d.Machine = m.Machine
d.PlanProductName = m.PlanProductName
d.UnitQuantity = m.PlanDevoted
d.DevotedUnit = "份"
if m.Ext.ProductPlanExt != nil {
d.DevotedUnit = m.Ext.ProductPlanExt.DevotedUnit
d.ProductId = m.Ext.ProductPlanExt.ProductId
}
d.PlanStatus = m.PlanStatus
d.TotalProduct = 0
d.Remark = m.Remark
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/productPlan/query"
"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/redis"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
"time"
... ... @@ -61,6 +62,16 @@ func (productPlanService *ProductPlanService) CreateProductPlan(cmd *command.Cre
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if len(cmd.BatchNumber) == 0 {
generator := redis.NewPlanBatchCodeCache(cmd.CompanyId)
code, err := redis.GenCode(generator)
if err != nil {
log.Logger.Error(err.Error())
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "服务器异常")
}
cmd.BatchNumber = code
}
newProductPlan := &domain.ProductPlan{
CompanyId: cmd.CompanyId,
OrgId: cmd.OrgId,
... ... @@ -86,8 +97,10 @@ func (productPlanService *ProductPlanService) CreateProductPlan(cmd *command.Cre
ProductCode: product.ProductCode,
ProductName: product.ProductName,
//ProductSpec: product.ProductSpec,
DevotedUnit: cmd.DevotedUnit,
}),
}
if cmd.Weight > 0 {
newProductPlan.PlanDevoted.Weight = cmd.Weight
}
... ... @@ -261,7 +274,7 @@ func (productPlanService *ProductPlanService) UpdateProductPlan(cmd *command.Upd
ProductId: product.ProductId,
ProductCode: product.ProductCode,
ProductName: product.ProductName,
//ProductSpec: product.ProductSpec,
DevotedUnit: cmd.DevotedUnit,
})
productPlan.PlanDevoted.UnitWeight = product.ProductSpec.UnitWeight
cmd.PlanProductName = product.ProductName
... ...
package syncdata
import (
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
"strconv"
"strings"
"time"
... ... @@ -181,8 +183,15 @@ func (srv *PullDataK3CloudService) PullMaterial(timeFilter time.Time) error {
if err != nil {
return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
var userService = domainService.NewUserService()
org, err := userService.Organization(constant.MANUFACTURE_DEFAULT_ORGID)
if err != nil {
return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
//MaterialK3cloud表数据到Proudct表
err = materialDao.SyncDataProudct(nowTime.Unix())
err = materialDao.SyncDataProudct(nowTime.Unix(), org.OrgName)
if err != nil {
return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
... ...
... ... @@ -175,7 +175,7 @@ func (workshopService *WorkshopService) RemoveWorkshop(removeWorkshopCommand *co
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeWorkshopCommand.WorkshopId)))
}
if !workshop.CanRemove() {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "当车间下存在线别")
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "当前车间下存在线别,不可删除")
}
if workshop, err := workshopRepository.Remove(workshop); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
... ...
package constant
import (
"os"
"strconv"
)
var (
// 生产制造 - 称重系统 - 默认公司
MANUFACTURE_DEFAULT_COMPANYID = 1
// 生产制造 - 称重系统 - 默认组织
MANUFACTURE_DEFAULT_ORGID = 1
)
func init() {
if os.Getenv("MANUFACTURE_DEFAULT_COMPANYID") != "" {
MANUFACTURE_DEFAULT_COMPANYID, _ = strconv.Atoi(os.Getenv("MANUFACTURE_DEFAULT_COMPANYID"))
}
if os.Getenv("MANUFACTURE_DEFAULT_ORGID") != "" {
MANUFACTURE_DEFAULT_ORGID, _ = strconv.Atoi(os.Getenv("MANUFACTURE_DEFAULT_ORGID"))
}
}
... ...
package domain
import "time"
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"time"
)
type DeviceZkTeco struct {
Sn string `json:"sn"` // 设备号
UserNo string `json:"userNo"` // 用户编码
ActionTime time.Time `json:"actionTime"` // 操作时间
}
func (m *DeviceZkTeco) Valid() error {
if len(m.Sn) == 0 {
return fmt.Errorf("设备号不能为空")
}
if len(m.UserNo) == 0 {
return fmt.Errorf("用户编码不能为空")
}
if m.ActionTime.IsZero() {
return fmt.Errorf("操作时间不能为空")
}
return nil
}
func (m *DeviceZkTeco) String() string {
return fmt.Sprintf("设备号:%v 用户编码:%v 操作时间:%v", m.Sn, m.UserNo, m.ActionTime)
}
func TaskDeviceZkTecoReport() string {
return fmt.Sprintf("%v:task:device-zk-teco:report", constant.CACHE_PREFIX)
}
... ...
... ... @@ -10,4 +10,6 @@ type ProductPlanExt struct {
ProductName string `json:"productName,omitempty"`
// 产品规格
//ProductSpec *UnitQuantity `json:"productSpec,omitempty"`
// 投入量规格 默认份
DevotedUnit string `json:"devotedUnit" `
}
... ...
... ... @@ -3,8 +3,8 @@ package domain
import "time"
const (
ParticipateNormal = 1
ParticipateSupport = 2
ParticipateNormal = 1 // 正常
ParticipateSupport = 2 // 支援
)
const (
... ... @@ -28,7 +28,7 @@ type EmployeeProductRecord struct {
WorkOn int `json:"workOn"`
// 参与类型 1:正常 2:支援
ParticipateType int `json:"participateType"`
// 产能
// 初始产能
ProductWeigh float64 `json:"productWeigh"`
// 二级品产能
SecondLevelWeigh float64 `json:"secondLevelWeigh"`
... ... @@ -67,21 +67,18 @@ func (employeeProductRecord *EmployeeProductRecord) Update(data map[string]inter
}
// 更新生产量
func (employeeProductRecord *EmployeeProductRecord) UpdateProductWeigh(weigh float64, productRecordType int, sectionName string) {
func (employeeProductRecord *EmployeeProductRecord) UpdateProductWeigh(weigh float64, productRecordType int, sectionName string, yesterdayWeight float64, bestWeight float64) {
if employeeProductRecord.ProductRecordInfo.OtherSectionSecondLevelWeigh == nil {
employeeProductRecord.ProductRecordInfo.OtherSectionSecondLevelWeigh = make(map[string]float64)
}
if productRecordType == RecordTypeSecondLevelWeigh {
// 当前工段
if employeeProductRecord.WorkStation.SectionName == sectionName {
employeeProductRecord.SecondLevelWeigh += weigh
} else {
if _, ok := employeeProductRecord.ProductRecordInfo.OtherSectionSecondLevelWeigh[sectionName]; ok {
employeeProductRecord.ProductRecordInfo.OtherSectionSecondLevelWeigh[sectionName] += weigh //存关联级的二级品
} else {
employeeProductRecord.ProductRecordInfo.OtherSectionSecondLevelWeigh[sectionName] = weigh
}
// 其他工段的二级品
employeeProductRecord.ProductRecordInfo.AddSectionWeight(sectionName, weigh)
}
employeeProductRecord.ProductRecordInfo.TotalOtherSecondLevelWeigh = employeeProductRecord.ProductRecordInfo.OtherSecondLevelWeigh() // 预先统计其他二级品占比
}
if productRecordType == RecordTypeReceiveMaterial {
employeeProductRecord.ProductWeigh += weigh
... ... @@ -89,6 +86,7 @@ func (employeeProductRecord *EmployeeProductRecord) UpdateProductWeigh(weigh flo
if productRecordType == RecordTypeReturnMaterial {
employeeProductRecord.ProductWeigh -= weigh
}
employeeProductRecord.ProductRecordInfo.PreStatistics(employeeProductRecord.ProductWeigh, employeeProductRecord.SecondLevelWeigh, 0, 0)
employeeProductRecord.UpdatedAt = time.Now()
employeeProductRecord.Version += 1
}
... ...
... ... @@ -9,13 +9,26 @@ type ProductRecordStaticInfo struct {
PlanProductName string `json:"planProductName,omitempty"`
// 批号
BatchNumber string `json:"batchNumber,omitempty"`
// 生产小组ID
ProductGroupId int `json:"productGroupId,omitempty"`
TotalOtherSecondLevelWeigh float64 `json:"otherSecondLevelWeigh"`
// 投入量
InputWeight float64 `json:"inputWeight,omitempty"`
// 产出量
OutputWeight float64 `json:"outputWeight,omitempty"`
// 二级品重量
SecondLevelWeight float64 `json:"secondLevelWeight"`
// 昨天产出量
YesterdayOutputWeight float64 `json:"yesterdayOutputWeight"`
// 历史最好产出量
BestOutputWeight float64 `json:"bestOutputWeight"`
// 合格率
QualificationRate int `json:"qualificationRate"`
// 其他工段二级品的重量合计
TotalOtherSecondLevelWeigh float64 `json:"totalOtherSecondLevelWeigh"`
// 保存其他工段二级品的重量
OtherSectionSecondLevelWeigh map[string]float64 `json:"sectionSecondLevelWeigh"`
OtherSectionSecondLevelWeigh map[string]float64 `json:"otherSectionSecondLevelWeigh"`
}
func (info *ProductRecordStaticInfo) OtherSecondLevelWeigh() float64 {
... ... @@ -25,3 +38,31 @@ func (info *ProductRecordStaticInfo) OtherSecondLevelWeigh() float64 {
}
return result
}
// AddSectionWeight 添加工段的二级品
func (info *ProductRecordStaticInfo) AddSectionWeight(section string, weight float64) {
if _, ok := info.OtherSectionSecondLevelWeigh[section]; ok {
info.OtherSectionSecondLevelWeigh[section] += weight //存关联级的二级品
} else {
info.OtherSectionSecondLevelWeigh[section] = weight
}
}
// 预统计
// productWeight 初始产能
// secondWeight 二级品重量
// yesterdayWeight 昨天产能
// bestWeight 最佳产能
func (info *ProductRecordStaticInfo) PreStatistics(productWeight float64, secondWeight float64, yesterdayWeight float64, bestWeight float64) {
totalOtherSecondLevelWeigh := info.OtherSecondLevelWeigh()
info.InputWeight = productWeight - totalOtherSecondLevelWeigh
info.OutputWeight = info.InputWeight - secondWeight
info.SecondLevelWeight = secondWeight
info.YesterdayOutputWeight = yesterdayWeight
info.BestOutputWeight = bestWeight
if bestWeight <= info.InputWeight {
info.BestOutputWeight = info.OutputWeight
}
info.TotalOtherSecondLevelWeigh = totalOtherSecondLevelWeigh
info.QualificationRate = int(info.OutputWeight / info.InputWeight * 100)
}
... ...
... ... @@ -58,12 +58,8 @@ func (employeeProductRecord *WorkshopProductRecord) UpdateProductWeigh(weigh flo
if employeeProductRecord.WorkStation.SectionName == sectionName {
employeeProductRecord.SecondLevelWeigh += weigh
} else {
if _, ok := employeeProductRecord.ProductRecordInfo.OtherSectionSecondLevelWeigh[sectionName]; ok {
employeeProductRecord.ProductRecordInfo.OtherSectionSecondLevelWeigh[sectionName] += weigh //存关联级的二级品
} else {
employeeProductRecord.ProductRecordInfo.OtherSectionSecondLevelWeigh[sectionName] = weigh
}
employeeProductRecord.ProductRecordInfo.TotalOtherSecondLevelWeigh = employeeProductRecord.ProductRecordInfo.OtherSecondLevelWeigh() // 预先统计其他二级品占比
// 其他工段的二级品
employeeProductRecord.ProductRecordInfo.AddSectionWeight(sectionName, weigh)
}
}
if productRecordType == RecordTypeReceiveMaterial {
... ... @@ -72,6 +68,7 @@ func (employeeProductRecord *WorkshopProductRecord) UpdateProductWeigh(weigh flo
if productRecordType == RecordTypeReturnMaterial {
employeeProductRecord.ProductWeigh -= weigh
}
employeeProductRecord.ProductRecordInfo.PreStatistics(employeeProductRecord.ProductWeigh, employeeProductRecord.SecondLevelWeigh, 0, 0)
employeeProductRecord.UpdatedAt = time.Now()
employeeProductRecord.Version += 1
}
... ...
... ... @@ -20,4 +20,8 @@ type User struct {
Avatar string `json:"avatar,omitempty"`
// 手机号码
Phone string `json:"phone,omitempty"`
// 额外扩展的参数
GroupId int `json:"-"`
GroupName string `json:"-"`
}
... ...
... ... @@ -104,6 +104,14 @@ func (workshop *Workshop) UpdateLine(lineId int, lineName string) error {
if line.Removed == Deleted {
return fmt.Errorf("生产线:%v已删除", line.LineName)
}
for _, v := range workshop.ProductLines {
if v.Removed == Deleted {
continue
}
if v.LineName == lineName && v.LineId != lineId {
return fmt.Errorf("生产线:%v已存在", lineName)
}
}
line.LineName = lineName
return nil
}
... ... @@ -174,6 +182,21 @@ func (workshop *Workshop) UpdateSection(lineId, sectionId int, sectionName strin
if section.Removed == Deleted {
return fmt.Errorf("工段:%v已删除", section.SectionName)
}
// 当前线下面工段不能重复
line, err := workshop.FindLine(lineId)
if err != nil {
return err
}
for _, v := range line.ProductSections {
if v.Removed == Deleted {
continue
}
if v.SectionName == sectionName && v.SectionId != sectionId {
return fmt.Errorf("工段:%v已存在", sectionName)
}
}
section.SectionName = sectionName
return nil
}
... ...
... ... @@ -29,6 +29,16 @@ func NewHttpLibAlliedCreationUser(host string) *HttpLibAlliedCreationUser {
func (gateway HttpLibAlliedCreationUser) User(userId int) (*models.User, error) {
return gateway.UserGet(ReqGetUser{UserId: userId})
}
func (gateway HttpLibAlliedCreationUser) UserByCode(companyId, orgId int, userCode string) (*models.User, error) {
_, users, err := gateway.UserSearch(ReqUserSearch{CompanyId: int64(companyId), OrganizationId: int64(orgId), UserCode: userCode, Limit: 1, PullRealTime: true})
if err != nil {
return nil, err
}
if len(users) == 0 {
return nil, fmt.Errorf("用户不存在")
}
return users[0], nil
}
func (gateway HttpLibAlliedCreationUser) Users(userIds []int) ([]*models.User, error) {
var list = make([]*models.User, 0)
for i := range userIds {
... ...
... ... @@ -40,6 +40,8 @@ type (
InEnableStatus []int `cname:"状态(1:启用 2:禁用 3:注销)" json:"inEnableStatus,omitempty"`
// 匹配多个公司
InCompanyIds []interface{} `json:"inCompanyIds,omitempty"`
// 用户编号 企业内标识
UserCode string `cname:"用户编号" json:"userCode,omitempty"`
// 自定义高级查询
AdvancedQuery string `json:"advancedQuery"`
... ...
... ... @@ -80,3 +80,32 @@ func (dao *AttendanceRecordDao) RecentUnApprovedAttendanceRecord(fromLastHour in
return int64(count), productAttendanceRecords, nil
}
}
func (dao *AttendanceRecordDao) WorkerAttendanceRecords(companyId, orgId, workerId int, workStationId string, beginTime, endTime time.Time) (int64, []*domain.ProductAttendanceRecord, error) {
tx := dao.transactionContext.PgTx
//endTime := time.Now()
//beginTime := endTime.Add(-(time.Hour * time.Duration(recentDay*24)))
var productAttendanceRecordModels []*models.ProductAttendanceRecord
productAttendanceRecords := make([]*domain.ProductAttendanceRecord, 0)
query := sqlbuilder.BuildQuery(tx.Model(&productAttendanceRecordModels), map[string]interface{}{})
query.Where("company_id =?", companyId)
query.Where("org_id =?", orgId)
query.Where("product_worker ->>'userId' = '?'", workerId)
query.Where("sign_in >= ?", beginTime)
query.Where("sign_in <= ?", endTime)
query.Where("attendance_status = ?", domain.AttendanceNotApprove)
query.SetOffsetAndLimit(domain.MaxQueryRow)
query.SetOrderDirect("product_attendance_id", "DESC")
if count, err := query.SelectAndCount(); err != nil {
return 0, productAttendanceRecords, err
} else {
for _, productAttendanceRecordModel := range productAttendanceRecordModels {
if productAttendanceRecord, err := transform.TransformToProductAttendanceRecordDomainModelFromPgModels(productAttendanceRecordModel); err != nil {
return 0, productAttendanceRecords, err
} else {
productAttendanceRecords = append(productAttendanceRecords, productAttendanceRecord)
}
}
return int64(count), productAttendanceRecords, nil
}
}
... ...
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"
)
type DeviceDao struct {
transactionContext *pgTransaction.TransactionContext
}
func NewDeviceDao(transactionContext *pgTransaction.TransactionContext) (*DeviceDao, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &DeviceDao{
transactionContext: transactionContext,
}, nil
}
}
func (d *DeviceDao) FindDeviceByDeviceCode(companyId, orgId int, deviceCode string) (*domain.Device, error) {
tx := d.transactionContext.PgTx
deviceModel := new(models.Device)
query := sqlbuilder.BuildQuery(tx.Model(deviceModel), map[string]interface{}{})
query.Where("company_id = ?", companyId)
query.Where("org_id = ?", orgId)
query.Where("device_code = ?", deviceCode)
//if v, ok := queryOptions["includeDeleted"]; ok && v.(bool) {
// query.AllWithDeleted()
//}
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, domain.ErrorNotFound
} else {
return nil, err
}
}
if deviceModel.DeviceId == 0 {
return nil, nil
} else {
return transform.TransformToDeviceDomainModelFromPgModels(deviceModel)
}
return nil, nil
}
... ...
... ... @@ -49,6 +49,30 @@ func (dao *EmployeeProductRecordDao) WorkerProductRecord(companyId, orgId, planI
}
}
// 员工对应批次 最好生产记录
func (dao *EmployeeProductRecordDao) WorkerBestOutputRecord(companyId, orgId, planId, workerId int) (*domain.EmployeeProductRecord, error) {
tx := dao.transactionContext.PgTx
employeeProductRecordModel := new(models.EmployeeProductRecord)
query := sqlbuilder.BuildQuery(tx.Model(employeeProductRecordModel), map[string]interface{}{})
query.Where("company_id = ?", companyId)
query.Where("org_id = ?", orgId)
query.Where("product_worker ->>'userId' = '?'", workerId)
query.Where("product_record_info ->>'productPlanId' = '?'", planId)
query.Order("product_record_info ->>'outputWeight' 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 employeeProductRecordModel.EmployeeProductRecordId == 0 {
return nil, domain.ErrorNotFound
} else {
return transform.TransformToEmployeeProductRecordDomainModelFromPgModels(employeeProductRecordModel)
}
}
func (dao *EmployeeProductRecordDao) SearchEmployeeProductRecord(queryOptions map[string]interface{}) (int64, []*domain.EmployeeProductRecord, error) {
tx := dao.transactionContext.PgTx
var employeeProductRecordModels []*models.EmployeeProductRecord
... ...
... ... @@ -2,6 +2,7 @@ package dao
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"strconv"
"strings"
... ... @@ -106,15 +107,15 @@ func (d *MaterialK3cloudDao) SyncDataMaterialK3cloud(data []models.MaterialK3clo
}
//SyncDataProudct 同步MaterialK3cloud表数据到Proudct表
func (d *MaterialK3cloudDao) SyncDataProudct(version int64) error {
func (d *MaterialK3cloudDao) SyncDataProudct(version int64, orgName string) error {
// -- 插入或者更新
sql := `INSERT INTO "manufacture"."product"(
sql := fmt.Sprintf(`INSERT INTO "manufacture"."product"(
"company_id", "org_id", "product_id", "product_code", "product_name",
"product_category", "product_spec", "created_at", "updated_at"
"product_category", "product_spec", "created_at", "updated_at","ext"
)
SELECT 0,use_org_id,"join_product_id","number","name","material_group_name",
json_build_object('unit',specification),now(),now()
FROM "manufacture"."material_k3cloud" WHERE "data_version"=? AND "material_group_number" LIKE '05%'
SELECT %v,%v,"join_product_id","number","name","material_group_name",
json_build_object('unit',specification),now(),now(),json_build_object('orgName','%v')
FROM "manufacture"."material_k3cloud" WHERE "data_version"=? AND "material_group_number" LIKE '05%%'
ON conflict ( product_id ) DO
UPDATE
SET (
... ... @@ -122,7 +123,7 @@ func (d *MaterialK3cloudDao) SyncDataProudct(version int64) error {
"product_category", "product_spec", "updated_at")=(
EXCLUDED."company_id", EXCLUDED."org_id",EXCLUDED."product_id",
EXCLUDED."product_code",EXCLUDED."product_name",EXCLUDED."product_category",
EXCLUDED."product_spec", EXCLUDED."updated_at") `
EXCLUDED."product_spec", EXCLUDED."updated_at") `, constant.MANUFACTURE_DEFAULT_COMPANYID, constant.MANUFACTURE_DEFAULT_ORGID, orgName)
_, err := d.transactionContext.PgTx.Exec(sql, version)
return err
}
... ...
... ... @@ -19,6 +19,14 @@ func (svr *UserService) User(id int) (*domain.User, error) {
return svr.ToUser(rsp), nil
}
func (svr *UserService) UserByCode(companyId, orgId int, userCode string) (*domain.User, error) {
rsp, err := svr.internalUserService.UserByCode(companyId, orgId, userCode)
if err != nil {
return nil, err
}
return svr.ToUser(rsp), nil
}
func (svr *UserService) Users(id []int) ([]*domain.User, error) {
rsp, err := svr.internalUserService.Users(id)
if err != nil {
... ...
... ... @@ -12,6 +12,7 @@ type PGApproveAttendanceRecordsService struct {
transactionContext *pgTransaction.TransactionContext
}
// 批量审核考勤记录
func (ptr *PGApproveAttendanceRecordsService) BatchApproveAttendanceRecords(opt *domain.OperateInfo, list []*domain.ProductAttendanceRecord, approveUserId int, workTime float64, status int) (interface{}, error) {
var productAttendanceRecordRepository, _ = repository.NewProductAttendanceRecordRepository(ptr.transactionContext)
var attendance *domain.ProductAttendanceRecord
... ...
... ... @@ -80,6 +80,7 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain.
if _, ok := groupMembers[groupMembersKeyFunc(r.ProductWorker.UserId)]; !ok {
participateType = domain.ParticipateSupport
}
var employeeProductRecord *domain.EmployeeProductRecord
employeeProductRecord, err = employeeProductRecordDao.WorkerProductRecord(cid, oid, productRecord.ProductRecordInfo.ProductPlanId, r.ProductWorker.UserId, productRecord.CreatedAt)
if err == domain.ErrorNotFound {
... ... @@ -90,7 +91,23 @@ func (ptr *PGProductRecordService) EmployeeProductStatics(productRecord *domain.
continue
}
}
employeeProductRecord.UpdateProductWeigh(productRecord.ProductRecordInfo.Weigh, productRecord.ProductRecordType, productRecord.WorkStation.SectionName)
// 查询当前员工 昨日产能 、历史最好产能
var (
yesterdayOutputWeight float64 = 0
bestOutputWeight float64 = 0
)
if record, e := employeeProductRecordDao.WorkerProductRecord(cid, oid, planId, r.ProductWorker.UserId, productRecord.CreatedAt.AddDate(0, 0, -1)); e == nil && record != nil {
yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight
bestOutputWeight = record.ProductRecordInfo.BestOutputWeight
} else {
if record, e := employeeProductRecordDao.WorkerBestOutputRecord(cid, oid, planId, r.ProductWorker.UserId); e == nil && record != nil {
yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight
}
}
employeeProductRecord.UpdateProductWeigh(productRecord.ProductRecordInfo.Weigh, productRecord.ProductRecordType, productRecord.WorkStation.SectionName, yesterdayOutputWeight, bestOutputWeight)
if employeeProductRecord, err = employeeProductRecordRepository.Save(employeeProductRecord); err != nil {
// TODO:异常处理
... ... @@ -172,6 +189,8 @@ func FindGroupMembers(productGroupRepository domain.ProductGroupRepository, comp
//g:=groups[i]
for j := range groups[i].GroupMembers {
u := groups[i].GroupMembers[j]
u.GroupId = groups[i].ProductGroupId
u.GroupName = groups[i].GroupName
result[keyFunc(u.UserId)] = u
}
}
... ... @@ -211,7 +230,23 @@ func (ptr *PGProductRecordService) personalProductStatics(productRecord *domain.
if err == domain.ErrorNotFound {
employeeProductRecord = newEmployeeProductRecord(productRecord, participateType, productPlan, productRecord.ProductWorker)
}
employeeProductRecord.UpdateProductWeigh(productRecord.ProductRecordInfo.Weigh, productRecord.ProductRecordType, productRecord.WorkStation.SectionName)
// 查询当前员工 昨日产能 、历史最好产能
var (
yesterdayOutputWeight float64 = 0
bestOutputWeight float64 = 0
)
if record, e := employeeProductRecordDao.WorkerProductRecord(cid, oid, planId, productRecord.ProductWorker.UserId, productRecord.CreatedAt.AddDate(0, 0, -1)); e == nil && record != nil {
yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight
bestOutputWeight = record.ProductRecordInfo.BestOutputWeight
} else {
if record, e := employeeProductRecordDao.WorkerBestOutputRecord(cid, oid, planId, productRecord.ProductWorker.UserId); e == nil && record != nil {
yesterdayOutputWeight = record.ProductRecordInfo.OutputWeight
}
}
employeeProductRecord.UpdateProductWeigh(productRecord.ProductRecordInfo.Weigh, productRecord.ProductRecordType, productRecord.WorkStation.SectionName, yesterdayOutputWeight, bestOutputWeight)
if employeeProductRecord, err = employeeProductRecordRepository.Save(employeeProductRecord); err != nil {
// TODO:异常处理
... ...
package domainService
import (
"fmt"
"github.com/linmadan/egglib-go/core/application"
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/repository"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
"time"
)
type PGWorkerAttendanceReportService struct {
transactionContext *pgTransaction.TransactionContext
}
// 考勤汇报
func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain.DeviceZkTeco) (interface{}, error) {
var (
attendanceRecordDao, _ = dao.NewAttendanceRecordDao(ptr.transactionContext)
attendanceRecordRepository, _ = repository.NewProductAttendanceRecordRepository(ptr.transactionContext)
isSignIn = true
record *domain.ProductAttendanceRecord
workStationId string //具体工位
workStation *domain.WorkStation
attendanceType int = domain.ParticipateNormal
worker *domain.User
org *domain.Org
)
if err := report.Valid(); err != nil {
return nil, err
}
var (
device *domain.Device
err error
productGroupRepository, _ = repository.NewProductGroupRepository(ptr.transactionContext)
groupId = 0
groupName = ""
)
deviceRepository, _ := dao.NewDeviceDao(ptr.transactionContext)
if device, err = deviceRepository.FindDeviceByDeviceCode(cid, oid, report.Sn); err != nil {
return nil, err
}
workStation = device.WorkStation
var userService = NewUserService()
org, err = userService.Organization(oid)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
worker, err = userService.UserByCode(cid, oid, report.UserNo)
if err != nil {
return nil, err
}
groupMembers, groupMembersKeyFunc := FindGroupMembers(productGroupRepository, cid, oid, workStation.WorkStationId)
if v, ok := groupMembers[groupMembersKeyFunc(worker.UserId)]; !ok {
attendanceType = domain.ParticipateSupport
} else {
groupId = v.GroupId
groupName = v.GroupName
}
beginTime := utils.GetZeroTime(report.ActionTime)
endTime := report.ActionTime
_, records, _ := attendanceRecordDao.WorkerAttendanceRecords(cid, oid, worker.UserId, workStationId, beginTime, endTime)
for i := 0; i < len(records); i++ {
r := records[i]
// 操作时间 < 签到时间
if utils.TimeAfterEqual(r.SignIn, report.ActionTime) {
log.Logger.Info(fmt.Sprintf("【考勤汇报】 考勤记录不合法,操作时间小于签到时间 考勤ID:%v 用户:%v 打卡时间:%v", r.ProductAttendanceId, worker.UserId, report.ActionTime))
return struct{}{}, nil
}
// 存在完整打卡记录
// 1. 如果在区间内,退出
if !utils.TimeIsZero(r.SignIn) && !utils.TimeIsZero(r.SignOut) {
if utils.TimeBeforeEqual(r.SignIn, report.ActionTime) && utils.TimeAfterEqual(r.SignOut, report.ActionTime) {
log.Logger.Info(fmt.Sprintf("【考勤汇报】 已存在同一时间段的考勤记录 考勤ID:%v 用户:%v 打卡时间:%v", r.ProductAttendanceId, worker.UserId, report.ActionTime))
return struct{}{}, nil
}
continue
}
// 存在未结束的打卡记录
// 1.满足条件-签退
if !utils.TimeIsZero(r.SignIn) && utils.TimeIsZero(r.SignOut) {
if utils.TimeBeforeEqual(r.SignIn, report.ActionTime) {
isSignIn = false
record = r
break
}
}
}
if isSignIn || record == nil {
record = &domain.ProductAttendanceRecord{
CompanyId: cid,
OrgId: oid,
AttendanceType: attendanceType,
ProductWorker: worker,
WorkStation: workStation,
SignIn: report.ActionTime,
//SignOut: cmd.SignOut,
AttendanceStatus: domain.AttendanceNotApprove,
WorkTimeBefore: 0,
WorkTimeAfter: 0,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Ext: domain.NewExt(org.OrgName).WithAttendanceExt(&domain.ProductAttendanceRecordExt{
GroupName: groupName,
ProductGroupId: groupId,
}),
}
log.Logger.Info(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 签到 %v", worker.UserName, worker.UserId, report))
} else {
record.SignOut = report.ActionTime
record.WorkTimeBefore = record.ComputeWorkTimeBefore()
log.Logger.Info(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 签退 %v", worker.UserName, worker.UserId, report))
}
if _, err = attendanceRecordRepository.Save(record); err != nil {
return nil, err
}
return struct{}{}, nil
}
func NewPGWorkerAttendanceReportService(transactionContext *pgTransaction.TransactionContext) (*PGWorkerAttendanceReportService, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &PGWorkerAttendanceReportService{
transactionContext: transactionContext,
}, nil
}
}
... ...
package domainService
//import (
// "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/repository"
//)
//
//type PGWorkshopService struct {
// transactionContext *pgTransaction.TransactionContext
//}
//
//func(ptr *PGWorkshopService)CompanyWorkshops(companyId int)(domain.Workshops,error){
// workshopRepository,_:= repository.NewWorkshopRepository(ptr.transactionContext)
// _,workshops,err:= workshopRepository.Find(map[string]interface{}{"companyId":companyId})
// if err!=nil{
// return nil,err
// }
// if len(workshops)==0{
// workshops = make([]*domain.Workshop,0)
// }
// return workshops,nil
//}
//
//func NewPGWorkshopService(transactionContext *pgTransaction.TransactionContext) (*PGWorkshopService, error) {
// if transactionContext == nil {
// return nil, fmt.Errorf("transactionContext参数不能为nil")
// } else {
// return &PGWorkshopService{
// transactionContext: transactionContext,
// }, nil
// }
//}
... ... @@ -59,7 +59,15 @@ func (ptr *PGWorkshopWorkTimeStaticService) WorkshopWorkTimeStatic(productRecord
}
func SendWorkshopWorkTimeStaticJob(productRecord *domain.ProductAttendanceRecord) error {
task := asynq.NewTask(domain.TaskKeyWorkshopWorkTimeRecordStatics(), []byte(json.MarshalToString(productRecord)))
return SendAsyncJob(domain.TaskKeyWorkshopWorkTimeRecordStatics(), productRecord)
}
func SenDeviceZkTecoReportJob(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)
... ...
package pg
import (
"context"
"fmt"
"github.com/beego/beego/v2/core/logs"
"log"
"reflect"
"github.com/go-pg/pg/v10"
"github.com/go-pg/pg/v10/orm"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models"
"github.com/linmadan/egglib-go/persistent/pg/hooks"
)
var DB *pg.DB
... ... @@ -22,7 +23,7 @@ func init() {
Addr: fmt.Sprintf("%s:%s", constant.POSTGRESQL_HOST, constant.POSTGRESQL_PORT),
})
if !constant.DISABLE_SQL_GENERATE_PRINT {
DB.AddQueryHook(hooks.SqlGeneratePrintHook{})
DB.AddQueryHook(SqlGeneratePrintHook{})
}
if !constant.DISABLE_CREATE_TABLE {
for _, model := range []interface{}{
... ... @@ -59,6 +60,23 @@ func init() {
}
}
type SqlGeneratePrintHook struct{}
func (hook SqlGeneratePrintHook) BeforeQuery(c context.Context, q *pg.QueryEvent) (context.Context, error) {
return c, nil
}
func (hook SqlGeneratePrintHook) AfterQuery(c context.Context, q *pg.QueryEvent) error {
sqlStr, err := q.FormattedQuery()
if err != nil {
return err
}
//log.Logger.Debug(string(sqlStr))
log.Println(string(sqlStr))
logs.Debug(string(sqlStr))
return nil
}
func AddComments(db *pg.DB, model interface{}) {
tableName := db.Model(model).TableModel().Table().SQLName
columnsMap := make(map[string]*orm.Field)
... ...
... ... @@ -61,3 +61,28 @@ func NewProductCodeCache(id int) ProductCodeCache {
Time: time.Now(),
}
}
type PlanBatchCodeCache struct {
CompanyId int
Time time.Time
}
func (ca PlanBatchCodeCache) CacheKey() string {
str := fmt.Sprintf("%v:plan-batch-code:%v:%v", constant.CACHE_PREFIX, ca.CompanyId, ca.Time.Format("20060102"))
return str
}
func (ca PlanBatchCodeCache) Format(index int) string {
if index <= 999 {
return fmt.Sprintf("%v%03d", ca.Time.Format("20060102"), index)
}
return fmt.Sprintf("%v%d", ca.Time.Format("20060102"), index)
}
func (ca PlanBatchCodeCache) Expire() time.Duration {
return time.Hour * 24
}
func NewPlanBatchCodeCache(id int) PlanBatchCodeCache {
return PlanBatchCodeCache{
CompanyId: id,
Time: time.Now(),
}
}
... ...
... ... @@ -6,6 +6,7 @@ import (
"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"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
"github.com/linmadan/egglib-go/persistent/pg/sqlbuilder"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
... ... @@ -161,8 +162,8 @@ func (repository *ProductCalendarRepository) Find(queryOptions map[string]interf
}
query.SetWhereByQueryOption("work_station->>'workStationId'=?", "workStationId")
query.SetWhereByQueryOption("work_on & ? >0", "workOn")
if v, ok := queryOptions["workshopName"]; ok && len(v.(string)) > 0 {
query.Where(fmt.Sprintf(`work_station->>'workshopName' like '%%%v%%'`, v))
if v, ok := queryOptions["inWorkshopIds"]; ok && len(v.([]int)) > 0 {
query.Where(`work_station->>'workshopId' in (?)`, pg.In(utils.ToArrayString(v.([]int))))
}
query.SetOffsetAndLimit(domain.MaxQueryRow)
query.SetOrderDirect("product_calendar_id", "DESC")
... ...
... ... @@ -174,7 +174,6 @@ func (repository *ProductPlanRepository) Find(queryOptions map[string]interface{
query := sqlbuilder.BuildQuery(tx.Model(&productPlanModels), queryOptions)
query.SetWhereByQueryOption("company_id = ?", "companyId")
query.SetWhereByQueryOption("org_id = ?", "orgId")
query.SetWhereByQueryOption("batch_number=?", "batchNumber")
if v, ok := queryOptions["batchNumber"]; ok && len(v.(string)) > 0 {
query.Where(fmt.Sprintf(`batch_number like '%%%v%%'`, v))
... ...
... ... @@ -12,5 +12,9 @@ func ToPinYin(hans string, sep string) string {
for i := range tmp {
result = append(result, tmp[i]...)
}
return strings.Join(result, sep)
py := strings.Join(result, sep)
if len(py) == 0 {
return strings.ToLower(hans)
}
return py
}
... ...
... ... @@ -50,3 +50,33 @@ func TransformTimestampToTime(timeStamp int64) time.Time {
//(myTime)
return time.Date(myTime.Year(), myTime.Month(), myTime.Day(), myTime.Hour(), myTime.Minute(), myTime.Second(), 0, time.Local)
}
func TimeIsZero(d time.Time) bool {
if d.IsZero() {
return true
}
if d.Equal(time.Date(1, 1, 1, 0, 0, 0, 0, time.Local)) {
return true
}
return false
}
func TimeAfterEqual(t1, t2 time.Time) bool {
if t1.After(t2) {
return true
}
if t1.Equal(t2) {
return true
}
return false
}
func TimeBeforeEqual(t1, t2 time.Time) bool {
if t1.Before(t2) {
return true
}
if t1.Equal(t2) {
return true
}
return false
}
... ...
package controllers
import (
"encoding/json"
"github.com/linmadan/egglib-go/web/beego"
"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/redis"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
"strings"
"time"
)
... ... @@ -28,8 +26,9 @@ func (controller *DeviceZKTecoController) PostCdata() {
mTime, err := time.ParseInLocation("2006-01-02 15:04:05", bodyList[1], time.Local)
if err == nil {
data.ActionTime = mTime
mBytes, _ := json.Marshal(data)
redis.GetRedis().LPush(constant.REDIS_ZKTECO_KEY, mBytes)
//mBytes, _ := json.Marshal(data)
//redis.GetRedis().LPush(domain.TaskDeviceZkTecoReport(), mBytes)
domainService.SenDeviceZkTecoReportJob(data)
}
}
controller.Response(data, nil)
... ...
package task
import (
"context"
"encoding/json"
"fmt"
"github.com/hibiken/asynq"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/productRecord/command"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/productRecord/service"
"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/log"
... ... @@ -25,6 +20,7 @@ func Run() {
// ... Register handlers
h.HandleFunc(domain.TaskKeyPatternProductRecordStatics(), HandlerProductRecordStatics)
h.HandleFunc(domain.TaskKeyWorkshopWorkTimeRecordStatics(), WorkshopWorkTimeRecordStatics)
h.HandleFunc(domain.TaskDeviceZkTecoReport(), WorkerAttendanceReport)
log.Logger.Info("aysnq task running ...")
// Run blocks and waits for os signal to terminate the program.
if err := srv.Run(h); err != nil {
... ... @@ -36,19 +32,3 @@ func Run() {
log.Logger.Info("aysnq task stopping ...")
srv.Shutdown()
}
// 生产记录统计
func HandlerProductRecordStatics(c context.Context, t *asynq.Task) error {
productPlanService := service.NewProductRecordService(nil)
cmd := &command.ProductRecordStaticsCommand{}
if err := json.Unmarshal(t.Payload(), cmd); err != nil {
return err
}
log.Logger.Debug(fmt.Sprintf("【生产记录统计】 消费 生产记录ID:%v 类型:%v 工段:%v(%v) 重量:%v", cmd.ProductRecordId, cmd.ProductRecordType,
cmd.WorkStation.SectionName, cmd.WorkStation.WorkStationId, cmd.ProductRecordInfo.Weigh))
_, err := productPlanService.ProductRecordStatics(cmd)
if err != nil {
log.Logger.Error(err.Error())
}
return err
}
... ...
package task
import (
"context"
"encoding/json"
"fmt"
"github.com/hibiken/asynq"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/productRecord/command"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/productRecord/service"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
)
// 生产记录统计
func HandlerProductRecordStatics(c context.Context, t *asynq.Task) error {
productPlanService := service.NewProductRecordService(nil)
cmd := &command.ProductRecordStaticsCommand{}
if err := json.Unmarshal(t.Payload(), cmd); err != nil {
return err
}
log.Logger.Debug(fmt.Sprintf("【生产记录统计】 消费 生产记录ID:%v 类型:%v 工段:%v(%v) 重量:%v", cmd.ProductRecordId, cmd.ProductRecordType,
cmd.WorkStation.SectionName, cmd.WorkStation.WorkStationId, cmd.ProductRecordInfo.Weigh))
_, err := productPlanService.ProductRecordStatics(cmd)
if err != nil {
log.Logger.Error(err.Error())
}
return err
}
... ...
... ... @@ -14,7 +14,7 @@ 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 {
if err := json.Unmarshal(t.Payload(), cmd); err != nil || cmd == nil {
return err
}
log.Logger.Debug(fmt.Sprintf("【考勤记录统计】 消费 记录ID:%v 时间:%v", cmd.ProductAttendanceId, cmd.WorkTimeBefore))
... ...
package task
import (
"context"
"encoding/json"
"fmt"
"github.com/hibiken/asynq"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/attendance/command"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/attendance/service"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
)
// 员工工时汇报
func WorkerAttendanceReport(c context.Context, t *asynq.Task) error {
svr := service.NewAttendanceService(nil)
cmd := &command.WorkerAttendanceReportCommand{}
if err := json.Unmarshal(t.Payload(), cmd); err != nil {
return err
}
log.Logger.Debug(fmt.Sprintf("【员工考勤记录汇报】 消费 设备:%v 用户编号:%v 时间:%v ", cmd.Sn, cmd.UserNo, cmd.DeviceZkTeco))
_, err := svr.WorkerAttendanceReport(cmd)
if err != nil {
log.Logger.Error(err.Error())
}
return nil
}
... ...