package model import ( "errors" "github.com/fonchain_enterprise/fonchain-approval/api/approval" "github.com/fonchain_enterprise/fonchain-approval/pkg/common/page" msg "github.com/fonchain_enterprise/fonchain-approval/pkg/m" "gorm.io/gorm" "gorm.io/plugin/soft_delete" "time" ) // Approval 审批 type Approval struct { ID uint64 `gorm:"primaryKey;column:id" json:"id"` DeletedAt soft_delete.DeletedAt `gorm:"column:deleted_at" json:"deletedAt"` CreatedAt time.Time `gorm:"column:created_at" json:"createdAt"` UpdatedAt time.Time `gorm:"column:updated_at" json:"updatedAt"` SubmitterID uint64 `gorm:"column:submitter_id" json:"submitterId"` Status int8 `gorm:"column:status" json:"status"` SubmitterName string `gorm:"column:submitter_name" json:"submitterName"` CopyUsers CopyUsers `gorm:"column:copy_users" json:"copyUsers"` ApprovalUsers ApprovalUsers `gorm:"column:approval_users" json:"approvalUsers"` Type string `gorm:"column:type" json:"type"` Level uint8 `gorm:"column:level" json:"level"` NowLevel uint8 `gorm:"column:now_level" json:"nowLevel"` NowUserId uint64 `gorm:"column:now_user_id" json:"nowUserId"` NowUserName string `gorm:"column:now_user_name" json:"nowUserName"` Content string `gorm:"column:content" json:"content"` Reply string `gorm:"column:reply" json:"reply"` Domain *string `gorm:"column:domain" json:"domain"` Show *Show `gorm:"foreignKey:ApprovalID" json:"Show"` Work *Work `gorm:"foreignKey:ApprovalID" json:"Work"` Bundle *Bundle `gorm:"foreignKey:ApprovalID" json:"Bundle"` Exhibition *Exhibition `gorm:"foreignKey:ApprovalID" json:"Exhibition"` ApprovalWorkFlows []*ApprovalWorkFlow `gorm:"foreignKey:ApprovalID" json:"ApprovalWorkFlows"` } const ( TypeContent = "content" TypeWork = "work" TypeExhibition = "exhibition" TypeShow = "show" TypeBundle = "bundle" ) const ( StatusDoing = 0 StatusOk = 1 StatusFail = 2 ) type ApprovalContentInterface interface { SaveApprovalContent(in *approval.CreateRequest, a *Approval) error UpdateApprovalContent(in *approval.CreateRequest, a *Approval) error BuildResContent(a *Approval, request *approval.CreateRequest) DeleteApproval(p *Approval) error } // TableName get sql table name.获取数据库表名 func (m *Approval) TableName() string { return "approval" } func StoreApproval(in *approval.CreateRequest) (*Approval, error) { var entity *Approval err := DB.Transaction(func(tx *gorm.DB) error { setting, terr := GetApprovalSettingFromKeyWord(in.Domain, in.Type) if terr != nil { return terr } // 保存基本信息 entity = &Approval{ Domain: &in.Domain, SubmitterID: in.SubmitterID, SubmitterName: in.SubmitterName, CopyUsers: setting.CopyUsers, ApprovalUsers: setting.ApprovalUsers, Type: in.Type, Content: in.Content, Level: uint8(len(setting.ApprovalUsers)), NowLevel: 1, NowUserId: setting.ApprovalUsers[0].ID, NowUserName: setting.ApprovalUsers[0].Name, } if err := DB.Create(&entity).Error; err != nil { return err } // 不同类型保存不同的结构体 err := entity.SaveContent(in) if err != nil { return err } return BatchSave(setting.ApprovalUsers, entity.ID) }) return entity, err } func Viewed(in *approval.ViewedRequest) error { var entity *Approval var err error if err = DB.First(&entity, in.ID).Error; err != nil { return errors.New(msg.ErrorNotFound) } copyUsers := entity.CopyUsers for i, temp := range copyUsers { if temp.ID == in.UserID { temp.IsViewed = true copyUsers[i] = temp } } return DB.Model(&Approval{}).Where(&Approval{ID: in.ID}).Updates(&Approval{CopyUsers: copyUsers}).Error } func UpdateApproval(in *approval.CreateRequest) (*Approval, error) { var entity *Approval err := DB.Transaction(func(tx *gorm.DB) error { if departErr := DB.First(&entity, in.ID).Error; departErr != nil { return errors.New(msg.ErrorNotFound) } if entity.Type != in.Type { return errors.New(msg.ErrorChangeType) } if entity.Status != StatusDoing { return errors.New(msg.ErrorWrongStatus) } else if in.Status != StatusDoing { //审批 // 保存基本信息 entity = &Approval{ ID: in.ID, Status: int8(in.Status), Reply: in.Reply, } return DB.Save(&entity).Error } // 保存基本信息 entity = &Approval{ ID: in.ID, //Domain: in.Domain, //SubmitterID: in.SubmitterId, //SubmitterName: in.SubmitterName, //ApproverID: in.ApproverId, //ApproverName: in.ApproverName, //CopyUsers: FormatCopyUsers(in.CopyUsers), //Type: in.Type, Content: in.Content, Reply: in.Reply, } if err := DB.Where(&Approval{ID: in.ID}).Updates(&entity).Error; err != nil { return err } // 不同类型保存不同的结构体 err := entity.UpdateContent(in) return err }) return entity, err } func approvalCalc(filter *Approval) *approval.Information { var num int64 info := &approval.Information{ Total: 0, DoingTotal: 0, SuccessTotal: 0, FailTotal: 0, } DB.Model(&Approval{}).Where(&filter).Count(&num) info.Total = uint64(num) DB.Model(&Approval{}).Where(&filter).Where(&Approval{Status: StatusOk}).Count(&num) info.DoingTotal = uint64(num) DB.Model(&Approval{}).Where(&filter).Where(&Approval{Status: StatusOk}).Count(&num) info.SuccessTotal = uint64(num) DB.Model(&Approval{}).Where(&filter).Where(&Approval{Status: StatusFail}).Count(&num) info.FailTotal = uint64(num) return info } func approvalCalcJson(domain string, userId uint64) *approval.Information { var num int64 var jsonStr = "JSON_CONTAINS(approve_users,JSON_OBJECT('ID', ?))" info := &approval.Information{ Total: 0, DoingTotal: 0, SuccessTotal: 0, FailTotal: 0, } DB.Model(&Approval{}).Where(jsonStr, userId).Count(&num) info.Total = uint64(num) DB.Model(&Approval{}).Where(jsonStr, userId).Where(&Approval{Status: StatusOk, Domain: &domain}).Count(&num) info.DoingTotal = uint64(num) DB.Model(&Approval{}).Where(jsonStr, userId).Where(&Approval{Status: StatusOk, Domain: &domain}).Count(&num) info.SuccessTotal = uint64(num) DB.Model(&Approval{}).Where(jsonStr, userId).Where(&Approval{Status: StatusFail, Domain: &domain}).Count(&num) info.FailTotal = uint64(num) return info } // ApprovalInfo 统计 func ApprovalInfo(in *approval.InformationRequest) (*approval.InformationResponse, error) { response := &approval.InformationResponse{ MySubmitInfo: approvalCalc(&Approval{Domain: &in.Domain, SubmitterID: in.UserID}), SubmitMeInfo: approvalCalcJson(in.Domain, in.UserID), DomainInfo: approvalCalc(&Approval{Domain: &in.Domain}), } return response, nil } func (m *Approval) SaveApprovalContent(in *approval.CreateRequest, a *Approval) error { return nil } func (m *Approval) UpdateApprovalContent(in *approval.CreateRequest, a *Approval) error { return nil } func (m *Approval) DeleteApproval(p *Approval) error { return nil } func (m *Approval) DeleteContent() error { factory, err := getApprovalContentFactory(m.Type) if err != nil { return err } return factory.DeleteApproval(m) } func (m *Approval) BuildResContent(a *Approval, request *approval.CreateRequest) { } func (m *Approval) SetResContent(request *approval.CreateRequest) error { factory, err := getApprovalContentFactory(m.Type) if err != nil { return err } factory.BuildResContent(m, request) return nil } func (m *Approval) SaveContent(in *approval.CreateRequest) error { factory, err := getApprovalContentFactory(in.Type) if err != nil { return err } err = factory.SaveApprovalContent(in, m) return err } func (m *Approval) UpdateContent(in *approval.CreateRequest) error { factory, err := getApprovalContentFactory(in.Type) if err != nil { return err } err = factory.UpdateApprovalContent(in, m) return err } func ApprovalList(in *approval.ListRequest) ([]*Approval, int64) { var list []*Approval var count int64 //list modelObj := DB.Model(&Approval{}). Preload("Show"). Preload("Work.ApprovalWorks"). Preload("Bundle"). Preload("ApprovalWorkFlows"). Preload("Exhibition.ApprovalExhibitions") if in.Type != "" { modelObj = modelObj.Where(&Approval{Type: in.Type}) } if in.UserID != 0 { modelObj = modelObj.Where(DB.Where("JSON_CONTAINS(approve_users,JSON_OBJECT('ID', ?))", in.UserID). Or("JSON_CONTAINS(copy_users,JSON_OBJECT('ID', ?))", in.UserID)) } if in.Status != 0 { modelObj = modelObj.Where(&Approval{Status: int8(in.Status)}) } modelObj.Count(&count) modelObj.Limit(int(in.PageSize)).Offset(page.GetOffset(in.Page, in.PageSize)).Order("id desc").Find(&list) return list, count } func (m *Approval) Pass(reply string, workFlowId uint64) error { return m.operateStatus(StatusOk, reply, workFlowId) } func (m *Approval) Refuse(reply string, workFlowId uint64) error { return m.operateStatus(StatusFail, reply, workFlowId) } func (m *Approval) operateStatus(status uint8, reply string, workFlowId uint64) error { var workFlow ApprovalWorkFlow if err := DB.Model(&ApprovalWorkFlow{ApprovalID: m.ID, Status: StatusDoing}).First(&workFlow, workFlowId).Error; err != nil { return err } if m.NowLevel != workFlow.Level { return errors.New(msg.ErrorOperate) } if status == StatusFail { //拒绝 m.Status = StatusFail m.Reply = reply if err := DB.Save(m).Error; err != nil { return err } return workFlow.Refuse(reply) } //层级审批通过 if m.Level == m.NowLevel { // 整个审批通过 m.Status = StatusOk } else { //审批层级通过 m.NowLevel = workFlow.Level + 1 nextFlow, err := GetWorkFlowByLevel(m.ID, m.NowLevel) if err != nil { return err } m.NowUserId = nextFlow.UserId m.NowUserName = nextFlow.Name } m.Reply = reply if err := DB.Save(m).Error; err != nil { return err } return workFlow.Pass(reply) } func getApprovalContentFactory(typeFiled string) (ApprovalContentInterface, error) { switch typeFiled { case TypeContent: return &Approval{}, nil case TypeShow: return &Show{}, nil case TypeWork: return &Work{}, nil case TypeBundle: return &Bundle{}, nil case TypeExhibition: return &Exhibition{}, nil default: return &Approval{}, nil } }