diff --git a/yuthon_issue/models/issue_library.py b/yuthon_issue/models/issue_library.py index 903a7ec93..85b87c97f 100644 --- a/yuthon_issue/models/issue_library.py +++ b/yuthon_issue/models/issue_library.py @@ -170,6 +170,78 @@ class IssueLibrary(models.Model): for record in issue_active_ids: record._compute_meeting() + def remove_duplicate_lines(self): + """删除关联流程和关联会议中的重复明细行,重复的只保留一条(保留创建日期最早的)""" + total_removed = 0 + detail_msg = [] + + for rec in self: + # ========== 1. 去重:关联流程明细 (issue.library.approval.line) ========== + # 重复判断依据:同一议题下,code 相同视为重复 + approval_lines = rec.issue_library_approval_line_ids + if approval_lines: + # 按 code 分组,找出每组中需要删除的多余记录 + seen_codes = {} # {code: [line_ids]} + for line in approval_lines: + key = line.code or '' + if key not in seen_codes: + seen_codes[key] = [] + seen_codes[key].append(line.id) + + approval_to_remove = [] + for code_val, line_ids in seen_codes.items(): + if len(line_ids) > 1: + # 按创建时间排序,保留第一条(最早),其余删除 + sorted_lines = self.env['issue.library.approval.line'].browse(line_ids).sorted(key=lambda l: l.create_date or '') + approval_to_remove.extend(sorted_lines[1:].ids) + + if approval_to_remove: + self.env['issue.library.approval.line'].browse(approval_to_remove).unlink() + removed_count = len(approval_to_remove) + total_removed += removed_count + detail_msg.append(f'议题【{rec.name or rec.code}】关联流程去重删除 {removed_count} 条') + + # ========== 2. 去重:关联会议明细 (issue.library.room.line) ========== + # 重复判断依据:同一议题下,room_booking_id 相同视为重复 + room_lines = rec.issue_library_room_line_ids + if room_lines: + seen_bookings = {} # {room_booking_id: [line_ids]} + for line in room_lines: + key = line.room_booking_id.id or 0 + if key not in seen_bookings: + seen_bookings[key] = [] + seen_bookings[key].append(line.id) + + room_to_remove = [] + for booking_id, line_ids in seen_bookings.items(): + if len(line_ids) > 1: + # 按 id 排序,保留第一条(id 最小的),其余删除 + sorted_lines = self.env['issue.library.room.line'].browse(line_ids).sorted(key=lambda l: l.id) + room_to_remove.extend(sorted_lines[1:].ids) + + if room_to_remove: + self.env['issue.library.room.line'].browse(room_to_remove).unlink() + removed_count = len(room_to_remove) + total_removed += removed_count + detail_msg.append(f'议题【{rec.name or rec.code}】关联会议去重删除 {removed_count} 条') + + # 返回结果通知 + msg = f'共清理 {total_removed} 条重复数据' + if detail_msg: + msg += '\n' + '\n'.join(detail_msg[:10]) # 最多显示前10条详情 + if len(detail_msg) > 10: + msg += f'\n...等共 {len(detail_msg)} 个议题' + + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': '去重完成', + 'message': msg, + 'sticky': True, + } + } + def batch_add_ci_char(self): import re active_ids = self._context.get('active_ids', []) diff --git a/yuthon_issue/views/issue_library_views.xml b/yuthon_issue/views/issue_library_views.xml index 24330f758..547a35f8d 100644 --- a/yuthon_issue/views/issue_library_views.xml +++ b/yuthon_issue/views/issue_library_views.xml @@ -8,6 +8,10 @@ decoration-info="issue_state == 'will'" decoration-success="issue_state == 'done'" decoration-muted="issue_state == 'cancel'"> +
+
@@ -60,6 +64,8 @@
@@ -114,6 +120,8 @@ decoration-muted="issue_state == 'cancel'">
@@ -458,6 +466,8 @@
@@ -505,6 +515,8 @@