Skip to content

Commit

Permalink
Merge pull request #1785 from winfredLIN/fix-issue1756
Browse files Browse the repository at this point in the history
fix-issue1756: panic in dingTalkRotation function
  • Loading branch information
taolx0 authored Sep 7, 2023
2 parents 682667b + 21997bf commit 9e4e38c
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 9 deletions.
13 changes: 6 additions & 7 deletions sqle/api/controller/v2/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,6 @@ func CancelWorkflowV2(c echo.Context) error {
return controller.JSONBaseErrorReq(c, err)
}

workflowStatus := workflow.Record.Status

user, err := controller.GetCurrentUser(c)
if err != nil {
return controller.JSONBaseErrorReq(c, err)
Expand All @@ -264,6 +262,8 @@ func CancelWorkflowV2(c echo.Context) error {
fmt.Errorf("you are not allow to operate the workflow")))
}

go im.CancelApprove(workflow.ID)

workflow.Record.Status = model.WorkflowStatusCancel
workflow.Record.CurrentWorkflowStepId = 0

Expand All @@ -272,10 +272,6 @@ func CancelWorkflowV2(c echo.Context) error {
return controller.JSONBaseErrorReq(c, err)
}

if workflowStatus == model.WorkflowStatusWaitForAudit {
go im.CancelApprove(workflow.ID)
}

return controller.JSONBaseErrorReq(c, nil)
}

Expand Down Expand Up @@ -323,17 +319,20 @@ func BatchCancelWorkflowsV2(c echo.Context) error {
}

workflows := make([]*model.Workflow, len(req.WorkflowIDList))
workflowIds := make([]uint, 0, len(req.WorkflowIDList))
for i, workflowID := range req.WorkflowIDList {
workflow, err := checkCancelWorkflow(projectName, workflowID)
if err != nil {
return controller.JSONBaseErrorReq(c, err)
}
workflows[i] = workflow

workflowIds = append(workflowIds, workflow.ID)
workflow.Record.Status = model.WorkflowStatusCancel
workflow.Record.CurrentWorkflowStepId = 0
}

go im.BatchCancelApprove(workflowIds)

if err := model.GetStorage().BatchUpdateWorkflowStatus(workflows); err != nil {
return controller.JSONBaseErrorReq(c, err)
}
Expand Down
19 changes: 19 additions & 0 deletions sqle/model/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ const (
ApproveStatusInitialized = "initialized"
ApproveStatusAgree = "agree"
ApproveStatusRefuse = "refuse"
ApproveStatusCancel = "canceled"
)

type DingTalkInstance struct {
Expand All @@ -497,6 +498,24 @@ func (s *Storage) GetDingTalkInstanceByWorkflowID(workflowId uint) (*DingTalkIns
return dti, true, errors.New(errors.ConnectStorageError, err)
}

func (s *Storage) GetDingTalkInstanceListByWorkflowIDs(workflowIds []uint) ([]DingTalkInstance, error) {
var dingTalkInstances []DingTalkInstance
err := s.db.Model(&DingTalkInstance{}).Where("workflow_id IN (?)", workflowIds).Find(&dingTalkInstances).Error
if err != nil {
return nil, err
}
return dingTalkInstances, nil
}

// batch updates ding_talk_instances'status into input status by workflow_ids, the status should be like ApproveStatusXXX in model package.
func (s *Storage) BatchUptateStatusOfDingTalkInstance(workflowIds []uint, status string) error {
err := s.db.Model(&DingTalkInstance{}).Where("workflow_id IN (?)", workflowIds).Updates(map[string]interface{}{"status": status}).Error
if err != nil {
return err
}
return nil
}

func (s *Storage) GetDingTalkInstByStatus(status string) ([]DingTalkInstance, error) {
var dingTalkInstances []DingTalkInstance
err := s.db.Where("status = ?", status).Find(&dingTalkInstances).Error
Expand Down
43 changes: 41 additions & 2 deletions sqle/pkg/im/im.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/actiontech/sqle/sqle/log"
"github.com/actiontech/sqle/sqle/model"
"github.com/actiontech/sqle/sqle/pkg/im/dingding"
"github.com/sirupsen/logrus"
)

var (
Expand Down Expand Up @@ -189,14 +190,52 @@ func CancelApprove(workflowID uint) {
s := model.GetStorage()
dingTalkInst, exist, err := s.GetDingTalkInstanceByWorkflowID(workflowID)
if err != nil {
newLog.Errorf("get dingtalk instance by workflow step id error: %v", err)
newLog.Errorf("get dingtalk instance by workflow id error: %v", err)
return
}
if !exist {
newLog.Infof("dingtalk instance not exist, workflow id: %v", workflowID)
return
}
// 如果在钉钉上已经同意或者拒绝<=>dingtalk instance的status不为initialized
// 则只修改钉钉工单状态为取消,不调用取消钉钉工单的API
if dingTalkInst.Status != model.ApproveStatusInitialized {
newLog.Infof("the dingtalk instance cannot be canceled if its status is not initialized, workflow id: %v", workflowID)
} else {
go DingTalkCancelApprove(s, newLog, dingTalkInst.ApproveInstanceCode)
}
// 关闭工单需要修改工单下的钉钉工单的状态
dingTalkInst.Status = model.ApproveStatusCancel
if err := s.Save(&dingTalkInst); err != nil {
newLog.Errorf("save ding talk instance error: %v", err)
}
}

func BatchCancelApprove(workflowIds []uint) {
newLog := log.NewEntry()
s := model.GetStorage()
instances, err := s.GetDingTalkInstanceListByWorkflowIDs(workflowIds)
if err != nil {
newLog.Errorf("get dingtalk instance list by workflowid slice error: %v", err)
return
}
// batch update ding_talk_instances'status into canceled
err = s.BatchUptateStatusOfDingTalkInstance(workflowIds, model.ApproveStatusCancel)
if err != nil {
newLog.Errorf("batch update ding_talk_instances'status into canceled, error: %v", err)
}
for idx, instance := range instances {
// 如果在钉钉上已经同意或者拒绝<=>dingtalk instance的status不为initialized
// 则只修改钉钉工单状态为取消,不调用取消钉钉工单的API
if instances[idx].Status != model.ApproveStatusInitialized {
newLog.Infof("the dingtalk instance cannot be canceled if its status is not initialized, workflow id: %v", instance.WorkflowId)
continue
}
go DingTalkCancelApprove(s, newLog, instance.ApproveInstanceCode)
}
}

func DingTalkCancelApprove(s *model.Storage, newLog *logrus.Entry, approveInstanceCode string) {
ims, err := s.GetAllIMConfig()
if err != nil {
newLog.Errorf("get im config error: %v", err)
Expand All @@ -215,7 +254,7 @@ func CancelApprove(workflowID uint) {
AppSecret: im.AppSecret,
}

if err := dingTalk.CancelApprovalInstance(dingTalkInst.ApproveInstanceCode); err != nil {
if err := dingTalk.CancelApprovalInstance(approveInstanceCode); err != nil {
newLog.Errorf("cancel dingtalk approval instance error: %v", err)
return
}
Expand Down

0 comments on commit 9e4e38c

Please sign in to comment.