You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

569 lines
14 KiB
Go

package model
import (
"database/sql/driver"
"encoding/json"
"errors"
"fmt"
"github.com/fonchain_enterprise/fonchain-approval/api/approval"
2 years ago
"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"
)
type KeyInfo struct {
ApprovalKey string
ApprovalName string
ApprovalType string
ApprovalValue string
}
type KeyInfos []KeyInfo
// 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"`
ValueJson KeyInfos `gorm:"type:json;column:value_json;default:null;comment:自定义信息" json:"valueJson"`
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"`
}
func (j *KeyInfos) Scan(src interface{}) error {
return json.Unmarshal(src.([]byte), j)
}
func (j KeyInfos) Value() (driver.Value, error) {
v, err := json.Marshal(j)
return string(v), err
}
const (
TypeContent = "content"
TypeWork = "work"
TypeExhibition = "exhibition"
TypeShow = "show"
TypeBundle = "bundle"
)
const (
StatusDoing = 1
StatusOk = 2
StatusFail = 3
)
const (
StatusNeedViewed = 4
StatusViewed = 5
)
type ApprovalContentInterface interface {
2 years ago
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 preValidateExhibition(in *approval.CreateRequest) error {
if in.Type != TypeExhibition {
return nil
}
total := GetExhibitionNumByUser(in.Domain, in.SubmitterID)
if total <= 0 {
return errors.New("您现在可选数量为0请先申请画展包数量")
}
if len(in.Exhibition.ApprovalExhibitions) > int(total) {
errStr := fmt.Sprintf("您现在可选数量为%d申请画展包数量为 %d", len(in.Exhibition.ApprovalExhibitions), total)
return errors.New(errStr)
}
return nil
}
/*
func preValidateExhibition(in *approval.CreateRequest) error {
var entity *Bundle
if in.Type != TypeExhibition {
return nil
}
if in.Exhibition == nil || in.Exhibition.PidApprovalID == 0 {
return errors.New(msg.ErrorApprovalType)
}
if err := DB.Where(Bundle{ApprovalID: in.Exhibition.PidApprovalID}).First(&entity).Error; err != nil {
return err
}
if len(in.Exhibition.ApprovalExhibitions) != int(entity.ApplicationsNum) {
return errors.New(msg.ErrorWrongNum)
}
return nil
}
*/
// GetExhibitionNumByUser 获取用户可以使用的画展包数量
func GetExhibitionNumByUser(domain string, submitterID uint64) int64 {
var total, usedNum int64
//已经使用的
str := `SELECT SUM(exhibition.num) AS total FROM exhibition
left join approval ON approval.id = exhibition.approval_id WHERE approval.STATUS != ?
2 years ago
AND approval.domain = ? AND approval.submitter_id = ? AND approval.type = ? AND approval.deleted_at=0`
DB.Raw(str, StatusFail, domain, submitterID, TypeExhibition).Scan(&usedNum)
fmt.Println("已经使用", usedNum)
//所有的
str1 := `SELECT SUM(bundle.applications_num) AS total FROM bundle
left join approval ON approval.id = bundle.approval_id WHERE approval.STATUS = ?
2 years ago
AND approval.domain = ? AND approval.submitter_id = ? AND approval.type = ? AND approval.deleted_at=0`
DB.Raw(str1, StatusOk, domain, submitterID, TypeBundle).Scan(&total)
fmt.Println("所有申请的", total)
return total - usedNum
}
2 years ago
func StoreApproval(in *approval.CreateRequest) (*Approval, error) {
var entity *Approval
if err1 := preValidateExhibition(in); err1 != nil {
return entity, err1
}
err := DB.Transaction(func(tx *gorm.DB) error {
setting, terr := GetApprovalSettingFromKeyWord(in.Domain, in.Type)
2 years ago
fmt.Println("1-----", terr, setting)
2 years ago
if terr != nil || setting == nil {
return errors.New("抄送人没有配置")
}
2 years ago
approvalUsers := setting.GetCombineApproveUsers(FormatApproveUsers(in.ApprovalUsers))
fmt.Println("2-----", approvalUsers)
// 保存基本信息
entity = &Approval{
Domain: &in.Domain,
SubmitterID: in.SubmitterID,
SubmitterName: in.SubmitterName,
CopyUsers: setting.CopyUsers,
ApprovalUsers: approvalUsers,
Type: in.Type,
Content: in.Content,
ValueJson: ToKeyInfos(in.CustomizeInfo),
Status: StatusDoing,
Level: uint8(len(approvalUsers)),
NowLevel: 1,
NowUserId: approvalUsers[0].ID,
NowUserName: approvalUsers[0].Name,
}
fmt.Println(3)
if err := DB.Create(&entity).Error; err != nil {
return err
}
// 不同类型保存不同的结构体
fmt.Println(41, entity)
err := entity.SaveContent(in)
fmt.Println(4)
if err != nil {
return err
}
fmt.Println(5)
return BatchSave(approvalUsers, entity.ID)
})
2 years ago
//fmt.Println("nil", entity)
//fmt.Println("nil", entity.ID)
return entity, err
}
func Viewed(in *approval.ViewedRequest) error {
var entity *Approval
var err error
var isView = false
if err = DB.First(&entity, in.ID).Error; err != nil {
return errors.New(msg.ErrorNotFound)
}
if entity.Status != StatusOk {
return errors.New(msg.ErrorDoingNotView)
}
copyUsers := entity.CopyUsers
for i, temp := range copyUsers {
if temp.ID == in.UserID {
if temp.IsViewed == true {
return errors.New(msg.ErrorAlreadySettingView)
}
isView = true
temp.IsViewed = isView
copyUsers[i] = temp
}
}
if isView == false {
return errors.New(msg.ErrorSettingView)
}
return DB.Model(&Approval{}).Where(&Approval{ID: in.ID}).Updates(&Approval{CopyUsers: copyUsers}).Error
}
2 years ago
func UpdateApproval(in *approval.CreateRequest) (*Approval, error) {
var entity *Approval
if err1 := preValidateExhibition(in); err1 != nil {
return entity, err1
}
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)
}
// 保存基本信息
2 years ago
upEntity := &Approval{
Content: in.Content,
}
if entity.Status == StatusFail {
upEntity.Status = StatusDoing
}
2 years ago
if err := DB.Where(&Approval{ID: in.ID}).Updates(&upEntity).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: StatusDoing}).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(approval_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: StatusDoing, 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
}
2 years ago
func (m *Approval) SaveApprovalContent(in *approval.CreateRequest, a *Approval) error {
return nil
}
2 years ago
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)
}
2 years ago
func (m *Approval) BuildResContent(a *Approval, request *approval.CreateRequest) {
}
2 years ago
func (m *Approval) SetResContent(request *approval.CreateRequest) error {
factory, err := getApprovalContentFactory(m.Type)
if err != nil {
return err
}
factory.BuildResContent(m, request)
return nil
}
2 years ago
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
}
2 years ago
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 MyWorkApprovals(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(approval_users,JSON_OBJECT('ID', ?))", in.UserID).
Where("status != ?", StatusDoing). //完成,我参与审批
Or(DB.Where("now_user_id", in.UserID).Where("status = ?", StatusDoing)). //进行中,当前审批人是我,
Or(DB.Where("JSON_CONTAINS(copy_users,JSON_OBJECT('ID', ?))", in.UserID).Where("status = ?", StatusOk))) //抄送人(完成抄送)
}
if in.Status != 0 {
modelObj = modelObj.Where(&Approval{Status: int8(in.Status)})
}
modelObj.Count(&count)
2 years ago
modelObj.Limit(int(in.PageSize)).Offset(page.GetOffset(in.Page, in.PageSize)).Order("id desc").Find(&list)
return list, count
}
func MySubmitApprovals(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.Status != 0 {
modelObj = modelObj.Where(&Approval{Status: int8(in.Status)})
}
if in.Type != "" {
modelObj = modelObj.Where(&Approval{Type: in.Type})
}
modelObj = modelObj.Where(&Approval{SubmitterID: in.UserID})
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
m.Reply = reply
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
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
}
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
}
}