@@ -213,12 +213,45 @@ def _dingtalk_pending_input_defs(form_data: dict) -> list[dict]:
213213
214214
215215def _dingtalk_clean_form_content (form_data : dict ) -> str :
216- content = form_data .get ('raw_form_content' ) or form_data .get ('form_content' ) or ''
217- field_names = {
218- str (field .get ('output_variable_name' ) or '' ).strip ()
219- for field in _dingtalk_form_input_defs (form_data )
220- if str (field .get ('output_variable_name' ) or '' ).strip ()
221- }
216+ is_field_step = bool (form_data .get ('_current_input_field' )) and not form_data .get ('_action_select_only' )
217+ raw_content = str (form_data .get ('raw_form_content' ) or '' )
218+ content = raw_content or form_data .get ('form_content' ) or ''
219+ input_defs = _dingtalk_form_input_defs (form_data )
220+ field_names = {_dingtalk_field_name (field ) for field in input_defs if _dingtalk_field_name (field )}
221+
222+ if is_field_step and raw_content :
223+ current_field = str (form_data .get ('_current_input_field' ) or '' ).strip ()
224+ current_placeholder = next (
225+ (
226+ match
227+ for match in re .finditer (r'\{\{#\$output\.([^#{}]+)#\}\}' , raw_content )
228+ if match .group (1 ).strip () == current_field
229+ ),
230+ None ,
231+ )
232+ content = (
233+ raw_content [: current_placeholder .end ()] if current_placeholder else form_data .get ('form_content' ) or ''
234+ )
235+
236+ if form_data .get ('_action_select_only' ) or is_field_step :
237+ fields = {_dingtalk_field_name (field ): field for field in input_defs if _dingtalk_field_name (field )}
238+ inputs = form_data .get ('inputs' ) or {}
239+
240+ def replace_placeholder (match : re .Match [str ]) -> str :
241+ field_name = match .group (1 ).strip ()
242+ field = fields .get (field_name )
243+ if not field or inputs .get (field_name ) in (None , '' , []):
244+ return ''
245+ lines = _dingtalk_completed_input_lines (
246+ {
247+ 'input_defs' : [field ],
248+ 'inputs' : {field_name : inputs [field_name ]},
249+ }
250+ )
251+ return lines [0 ] if lines else ''
252+
253+ content = re .sub (r'\{\{#\$output\.([^#{}]+)#\}\}' , replace_placeholder , str (content ))
254+
222255 kept_lines : list [str ] = []
223256 for line in str (content ).splitlines ():
224257 placeholder = re .fullmatch (r'\s*\{\{#\$output\.([^#{}]+)#\}\}\s*' , line )
@@ -228,6 +261,11 @@ def _dingtalk_clean_form_content(form_data: dict) -> str:
228261 return re .sub (r'\n{3,}' , '\n \n ' , '\n ' .join (kept_lines ).strip ())
229262
230263
264+ def _dingtalk_card_markdown (content : str ) -> str :
265+ """Preserve line breaks inside DingTalk card-template markdown slots."""
266+ return '<br>' .join (str (content or '' ).splitlines ())
267+
268+
231269def _dingtalk_form_input_defs (form_data : dict ) -> list [dict ]:
232270 return list (form_data .get ('all_input_defs' ) or form_data .get ('input_defs' ) or [])
233271
@@ -261,11 +299,11 @@ def _dingtalk_completed_input_lines(form_data: dict) -> list[str]:
261299 field_type = _dingtalk_field_type (field )
262300 display_value = _dingtalk_display_input_value (field , value )
263301 if field_type == 'select' :
264- lines .append (f'✅ 已选择 { field_name } :** { display_value } ** ' )
302+ lines .append (f'✅ 已选择 { field_name } :{ display_value } ' )
265303 elif field_type in {'file' , 'file-list' }:
266- lines .append (f'✅ 已上传 { field_name } :** { display_value } ** ' )
304+ lines .append (f'✅ 已上传 { field_name } :{ display_value } ' )
267305 else :
268- lines .append (f'✅ 已填写 { field_name } :** { display_value } ** ' )
306+ lines .append (f'✅ 已填写 { field_name } :{ display_value } ' )
269307 return lines
270308
271309
@@ -915,9 +953,9 @@ async def _paint_form_on_card(
915953 if node_title :
916954 parts .append (f'**{ node_title } **' )
917955 if form_content :
918- parts .append (form_content )
956+ parts .append (_dingtalk_card_markdown ( form_content ) )
919957 completed_lines = _dingtalk_completed_input_lines (form_data )
920- if completed_lines :
958+ if completed_lines and not all ( line in form_content for line in completed_lines ) :
921959 parts .append ('<hr>' + '<br>' .join (completed_lines ))
922960 input_hint_lines = [] if native_field else _dingtalk_input_hint_lines (form_data )
923961 if input_hint_lines :
@@ -1017,9 +1055,9 @@ async def _send_form_card(
10171055 if node_title :
10181056 parts .append (f'**{ node_title } **' )
10191057 if form_content :
1020- parts .append (form_content )
1058+ parts .append (_dingtalk_card_markdown ( form_content ) )
10211059 completed_lines = _dingtalk_completed_input_lines (form_data )
1022- if completed_lines :
1060+ if completed_lines and not all ( line in form_content for line in completed_lines ) :
10231061 parts .append ('<hr>' + '<br>' .join (completed_lines ))
10241062 input_hint_lines = [] if native_field else _dingtalk_input_hint_lines (form_data )
10251063 if input_hint_lines :
@@ -1457,14 +1495,14 @@ async def _mark_card_resolved(
14571495 if node_title :
14581496 parts .append (f'**{ node_title } **' )
14591497 if form_content :
1460- parts .append (form_content )
1498+ parts .append (_dingtalk_card_markdown ( form_content ) )
14611499 completed_lines = _dingtalk_completed_input_lines (
14621500 {
14631501 'input_defs' : input_defs or [],
14641502 'inputs' : inputs or {},
14651503 }
14661504 )
1467- if completed_lines :
1505+ if completed_lines and not all ( line in form_content for line in completed_lines ) :
14681506 parts .append ('<hr>' + '<br>' .join (completed_lines ))
14691507 parts .append (f'<hr>✅ 已选择:**{ action_title } **' )
14701508 content = '<br><br>' .join (parts )
0 commit comments