@@ -136,50 +136,68 @@ def _validate_scope_changes(self, scope_value):
136
136
return
137
137
138
138
scope_set = set (scope_value )
139
-
140
- invalid_projects = []
141
- invalid_common_templates = []
139
+ conflict_projects = set ()
140
+ conflicts_project_templates = set ()
141
+ conflicts_common_templates = []
142
142
for item in references :
143
143
if item .get ("template_type" ) != COMMON :
144
144
project_id = str (item ["project_id" ])
145
145
if project_id not in scope_value :
146
- invalid_projects . append ( project_id )
146
+ conflicts_project_templates . add ( item [ "project_name" ] )
147
147
else :
148
148
if not set (item .get ("project_scope" , [])).issubset (scope_set ):
149
- invalid_common_templates .append (str (item ["name" ]))
150
-
151
- if invalid_common_templates :
152
- invalid_common_templates = "," .join (invalid_common_templates )
153
- raise serializers .ValidationError (f"流程在公共流程 { invalid_common_templates } 中被引用,使用范围存在冲突,请检查配置" )
154
-
155
- if invalid_projects :
156
- invalid_projects = "," .join (invalid_projects )
157
- raise serializers .ValidationError (f"流程在项目 { invalid_projects } 中被引用,请检查使用范围配置" )
158
-
159
- def _validate_child_scope (self , project_scope ):
160
- pipeline_tree = self .instance .pipeline_tree
149
+ conflicting_projects = sorted (set (item .get ("project_scope" )) - scope_set )
150
+ project_names = Project .objects .filter (id__in = conflicting_projects ).values_list ("name" , flat = True )
151
+ conflicts_common_templates .append (item ["name" ])
152
+ conflict_projects .update (project_names )
153
+
154
+ if conflicts_common_templates :
155
+ err_message = (
156
+ f"当前流程与父流程 { ', ' .join (conflicts_common_templates )} 的可见范围存在冲突,"
157
+ f"请遵循父流程的可见范围不能超出子流程的规则,至少包含项目 { ', ' .join (sorted (conflict_projects ))} "
158
+ )
159
+ raise serializers .ValidationError (err_message )
160
+
161
+ if conflicts_project_templates :
162
+ err_message = f"当前流程在项目 { ', ' .join (conflicts_project_templates )} 中被引用,请遵循流程可见范围限制"
163
+ raise serializers .ValidationError (err_message )
164
+
165
+ def _validate_child_scope (self , pipeline_tree , project_scope ):
161
166
project_scope_set = set (project_scope )
167
+ conflict_details = set ()
168
+ subprocess = []
162
169
for activity in pipeline_tree .get ("activities" , {}).values ():
163
170
if activity .get ("type" ) != "SubProcess" or activity .get ("template_source" ) != "common" :
164
171
continue
165
- common_template_id = activity .get ("template_id" )
166
- result = CommonTemplate .objects .get (id = common_template_id )
167
- common_project_scope = result .extra_info .get ("project_scope" )
168
- if common_project_scope == ["*" ]:
172
+ common_template = CommonTemplate .objects .get (id = activity ["template_id" ])
173
+ common_scope = set (common_template .extra_info .get ("project_scope" , []))
174
+ if common_scope == ["*" ]:
169
175
continue
170
- if not project_scope_set .issubset (set (common_project_scope )):
171
- raise serializers .ValidationError (f"保存流程失败,子流程 { result .pipeline_template .name } 的可见范围与当前流程的可见范围存在冲突" )
176
+ if not project_scope_set .issubset (common_scope ):
177
+ conflicting_projects = sorted (common_scope - project_scope_set )
178
+ project_names = Project .objects .filter (id__in = conflicting_projects ).values_list ("name" , flat = True )
179
+ subprocess .append (common_template .pipeline_template .name )
180
+ conflict_details .update (project_names )
181
+
182
+ if subprocess :
183
+ error_messages = (
184
+ f"当前流程与子流程 { ', ' .join (subprocess )} 的可见范围存在冲突,"
185
+ f"请遵循父流程的可见范围不能超出子流程的规则,至少包含项目 { ', ' .join (set (conflict_details ))} "
186
+ )
187
+ raise serializers .ValidationError (error_messages )
172
188
return pipeline_tree
173
189
174
- def validate_project_scope (self , value ):
190
+ def validate (self , attrs ):
191
+ project_scope = attrs .get ("extra_info" ).get ("project_scope" )
175
192
request = self .context .get ("request" )
193
+ # 检测其引用的子流程
194
+ self ._validate_child_scope (json .loads (attrs ["pipeline_tree" ]), project_scope )
176
195
177
196
if request .method in ("PUT" , "PATCH" ):
178
197
# 检测其被作为子流程引用的父流程
179
- self ._validate_scope_changes (value )
180
- # 检测其引用的子流程
181
- self ._validate_child_scope (value )
182
- return value
198
+ self ._validate_scope_changes (project_scope )
199
+
200
+ return attrs
183
201
184
202
class Meta :
185
203
model = CommonTemplate
@@ -213,5 +231,5 @@ class Meta:
213
231
214
232
def validate_project_scope (self , value ):
215
233
self ._validate_scope_changes (value )
216
- self ._validate_child_scope (value )
234
+ self ._validate_child_scope (self . instance . pipeline_tree , value )
217
235
return value
0 commit comments