2024-11-14 17:02:41 +08:00
|
|
|
package flow_definition
|
|
|
|
|
|
|
|
import (
|
2024-11-19 17:03:12 +08:00
|
|
|
"approveflow/app/provider/abstract/connect"
|
2024-11-14 17:02:41 +08:00
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"github.com/Superdanda/hade/framework"
|
|
|
|
"github.com/Superdanda/hade/framework/contract"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
type FlowDefinitionService struct {
|
|
|
|
container framework.Container
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) CreateFlow(ctx context.Context, flow *ApprovalFlow) error {
|
|
|
|
return f.GetFlowRepository().SaveFlow(ctx, flow)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) GetFlow(ctx context.Context, flowID int64) (*ApprovalFlow, error) {
|
|
|
|
return f.GetFlowRepository().GetFlowByID(ctx, flowID)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) GetFlowPage(ctx context.Context, pageNum, pageSize int, flow *ApprovalFlow) ([]*ApprovalFlow, int64, error) {
|
|
|
|
return f.GetFlowRepository().ListFlows(ctx, pageNum, pageSize, flow)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) UpdateFlow(ctx context.Context, flow *ApprovalFlow) error {
|
|
|
|
return f.GetFlowRepository().SaveFlow(ctx, flow)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) DeleteFlow(ctx context.Context, flowID int64) error {
|
|
|
|
flowById, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
flowById.Delete()
|
|
|
|
return f.GetFlowRepository().SaveFlow(ctx, flowById)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) AddStepWithPosition(ctx context.Context, flowID int64, step *ApprovalStep, fromStepId string, toStepKey string) error {
|
|
|
|
return f.handlerFlow(ctx, flowID, func(ctx context.Context, flow *ApprovalFlow) error {
|
|
|
|
fromStep, err := flow.GetStepByKey(fromStepId)
|
2024-11-19 17:03:12 +08:00
|
|
|
toStep, err := flow.GetStepByKey(toStepKey)
|
2024-11-14 17:02:41 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-11-19 17:03:12 +08:00
|
|
|
err = connect.InsertNodeBetween(flow, fromStep, toStep, step)
|
2024-11-14 17:02:41 +08:00
|
|
|
return err
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) AddStep(ctx context.Context, flowID int64, step *ApprovalStep) error {
|
|
|
|
flowById, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = flowById.AddStep(step)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return f.GetFlowRepository().SaveFlow(ctx, flowById)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) GetSteps(ctx context.Context, flowID int64) ([]*ApprovalStep, error) {
|
|
|
|
flowById, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return flowById.Steps, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) UpdateStep(ctx context.Context, flowID int64, step *ApprovalStep) error {
|
|
|
|
flowById, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
steps := flowById.Steps
|
|
|
|
for index, stepExist := range steps {
|
|
|
|
if stepExist.ID == step.ID {
|
|
|
|
steps[index] = step
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) DeleteStep(ctx context.Context, flowID int64, stepID int64) error {
|
|
|
|
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
|
|
|
|
step.Delete()
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) AddRule(ctx context.Context, flowID int64, stepID int64, rule *ApprovalRule) error {
|
|
|
|
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
|
|
|
|
step.Rules = append(step.Rules, rule)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) GetRules(ctx context.Context, flowID int64, stepID int64) ([]*ApprovalRule, error) {
|
|
|
|
_, id, err := f.findStepByStepId(ctx, flowID, stepID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return id.Rules, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) UpdateRule(ctx context.Context, flowID int64, stepID int64, rule *ApprovalRule) error {
|
|
|
|
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
|
|
|
|
existingRule, err := step.GetRuleById(rule.ID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// Update the fields of the existing rule
|
|
|
|
existingRule.Name = rule.Name
|
|
|
|
existingRule.Action = rule.Action
|
|
|
|
existingRule.Priority = rule.Priority
|
|
|
|
existingRule.ConditionExpression = rule.ConditionExpression
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) DeleteRule(ctx context.Context, flowID int64, stepID int64, ruleID int64) error {
|
|
|
|
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
|
|
|
|
rule, err := step.GetRuleById(ruleID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
rule.Delete()
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) AddDynamicStepConfig(ctx context.Context, flowID int64, stepID int64, config *DynamicApprovalStepConfig) error {
|
|
|
|
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
|
|
|
|
step.AddDynamicConfig(config)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) GetDynamicStepConfigs(ctx context.Context, flowID int64) ([]*DynamicApprovalStepConfig, error) {
|
|
|
|
// Retrieve dynamic configurations for the flow
|
|
|
|
flowByID, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
configs := make([]*DynamicApprovalStepConfig, 0, len(flowByID.Steps))
|
|
|
|
for _, step := range flowByID.Steps {
|
|
|
|
configs = append(configs, step.DynamicConfig)
|
|
|
|
}
|
|
|
|
return configs, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) UpdateDynamicStepConfig(ctx context.Context, flowID int64, stepID int64, config *DynamicApprovalStepConfig) error {
|
|
|
|
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
|
|
|
|
dynamicConfig := step.DynamicConfig
|
|
|
|
// Update the fields of the existing dynamicConfig
|
|
|
|
dynamicConfig.Name = config.Name
|
|
|
|
dynamicConfig.Action = config.Action
|
|
|
|
dynamicConfig.Priority = config.Priority
|
|
|
|
dynamicConfig.ConditionExpression = config.ConditionExpression
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) DeleteDynamicStepConfig(ctx context.Context, flowID int64, stepID int64) error {
|
|
|
|
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
|
|
|
|
step.DynamicConfig.Delete()
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) AddPathConfig(ctx context.Context, flowID int64, stepID int64, config *ApprovalPathConfig) error {
|
|
|
|
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
|
|
|
|
return step.AddPathConfig(config)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) GetPathConfigs(ctx context.Context, flowID int64) ([]*ApprovalPathConfig, error) {
|
|
|
|
// Retrieve dynamic configurations for the flow
|
|
|
|
flowByID, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
// Extract PathConfigs from each step in the flow
|
|
|
|
var configs []*ApprovalPathConfig
|
|
|
|
for _, step := range flowByID.Steps {
|
|
|
|
configs = append(configs, step.PathConfigs...)
|
|
|
|
}
|
|
|
|
return configs, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) UpdatePathConfig(ctx context.Context, flowID int64, stepID int64, config *ApprovalPathConfig) error {
|
|
|
|
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
|
|
|
|
pathById, err := step.GetPathById(config.ID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-11-15 16:53:35 +08:00
|
|
|
pathById.ToNodeKey = config.ToNodeKey
|
2024-11-14 17:02:41 +08:00
|
|
|
pathById.IsParallel = config.IsParallel
|
|
|
|
pathById.ConditionExpression = config.ConditionExpression
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) DeletePathConfig(ctx context.Context, flowID int64, stepID int64, pathID int64) error {
|
|
|
|
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
|
|
|
|
pathById, err := step.GetPathById(pathID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
pathById.Delete()
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) handlerStep(
|
|
|
|
ctx context.Context,
|
|
|
|
flowID int64,
|
|
|
|
stepID int64,
|
|
|
|
handler func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error,
|
|
|
|
) error {
|
|
|
|
flowById, step, err := f.findStepByStepId(ctx, flowID, stepID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if step == nil {
|
|
|
|
return fmt.Errorf("step with ID %d not found in flow %d", stepID, flowID)
|
|
|
|
}
|
|
|
|
err = handler(ctx, flowById, step)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return f.GetFlowRepository().SaveFlow(ctx, flowById)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) handlerFlow(ctx context.Context,
|
|
|
|
flowID int64,
|
|
|
|
handler func(ctx context.Context, flow *ApprovalFlow) error,
|
|
|
|
) error {
|
|
|
|
flowById, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = handler(ctx, flowById)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return f.GetFlowRepository().SaveFlow(ctx, flowById)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) findStepByStepId(ctx context.Context, flowID int64, stepID int64) (*ApprovalFlow, *ApprovalStep, error) {
|
|
|
|
// Retrieve the flow to confirm it exists
|
|
|
|
flowByID, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
var step *ApprovalStep
|
|
|
|
for _, s := range flowByID.Steps {
|
|
|
|
if s.ID == stepID {
|
|
|
|
step = s
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if step == nil {
|
|
|
|
return nil, nil, errors.New("step not found")
|
|
|
|
}
|
|
|
|
return flowByID, step, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewFlowDefinitionService(params ...interface{}) (interface{}, error) {
|
|
|
|
container := params[0].(framework.Container)
|
|
|
|
return &FlowDefinitionService{container: container}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FlowDefinitionService) GetFlowRepository() FlowRepository {
|
|
|
|
infrastructureService := f.container.MustMake(contract.InfrastructureKey).(contract.InfrastructureService)
|
|
|
|
return infrastructureService.GetModuleOrmRepository(FlowRepositoryKey).(FlowRepository)
|
|
|
|
}
|