From 990833e029422f77e89fb8d4f9f682966285b1ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Tue, 15 Sep 2026 18:17:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- soong_workflow/models/soong_workflow_mixin.py | 7 +++++++ soong_workflow/models/soong_workflow_node.py | 1 + yuthon_hr_attendance/models/yuthon_vacation_reports.py | 9 ++++++--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py index 60e69dd56..ac4f0ea13 100644 --- a/soong_workflow/models/soong_workflow_mixin.py +++ b/soong_workflow/models/soong_workflow_mixin.py @@ -867,6 +867,13 @@ class SoongWorkflowMixin(models.AbstractModel): prev_approvers = self._get_approvers_for_link(prev_link, self) if len(prev_approvers) == 1 and prev_approvers[0] == current_approver: invalid_links |= prev_link + # 此节点之后的所有相同审批人节点跳过 + if node_id.same_user_skip_type == 'after': + for j in range(idx + 1, len(sorted_all_links)): + after_link = sorted_all_links[j] + after_approvers = self._get_approvers_for_link(after_link, self) + if len(after_approvers) == 1 and after_approvers[0] == current_approver: + invalid_links |= after_link allowed_link_ids = [lid for lid in trans_link_ids if lid not in invalid_links.ids] default_trans_link_id = allowed_link_ids[0] if allowed_link_ids else trans_link_id diff --git a/soong_workflow/models/soong_workflow_node.py b/soong_workflow/models/soong_workflow_node.py index 1a7560b9d..080117282 100644 --- a/soong_workflow/models/soong_workflow_node.py +++ b/soong_workflow/models/soong_workflow_node.py @@ -106,6 +106,7 @@ class SoongWorkflowNode(models.Model): ('none', '不跳过'), ('next', '跳过下一个相同人员节点'), ('prev', '跳过上一个相同人员节点'), + ('after', '跳过此节点之后的所有相同人员节点'), ], string='相同人员节点处理', default='none') is_mandatory_node = fields.Boolean(string="必经节点", default=False) diff --git a/yuthon_hr_attendance/models/yuthon_vacation_reports.py b/yuthon_hr_attendance/models/yuthon_vacation_reports.py index 10950b806..370155dcd 100644 --- a/yuthon_hr_attendance/models/yuthon_vacation_reports.py +++ b/yuthon_hr_attendance/models/yuthon_vacation_reports.py @@ -1568,8 +1568,8 @@ class YuthonVacationReports(models.Model): processed_employees = set() send_count = 0 for report in report_objs: - # 已确认的记录不需要再发 - if report.vacation_state == 'confirmed': + # 已发送(pending)/已确认(confirmed)的记录不再重复发送,避免同一人被多个入口反复推送 + if report.vacation_state in ('pending', 'confirmed'): continue if report.employee_id.id in processed_employees: # 同员工已发送过通知,多余记录只改状态不重复发 @@ -1647,7 +1647,8 @@ class YuthonVacationReports(models.Model): month = self.vacation_date.month data = f"你{year}年{month}月的考勤确认单已经生成,请确认" self.sudo().env["wecom.apps"].sync_send_message_textcard(category='att_ok', user_id=we_id, title="考勤确认单", description=data, url=url, btntxt="详细信息") - + # 记录发送时间,供提醒 cron 的去重闸判断,避免重复推送 + self.last_reminder_date = fields.Date.today() self.write({'vacation_state': 'pending'}) return { 'type': 'ir.actions.client', @@ -1795,6 +1796,8 @@ class YuthonVacationReports(models.Model): data = f"你{year}年{month}月的考勤确认单已经生成,请确认" self.sudo().env["wecom.apps"].sync_send_message_textcard(category='att_ok', user_id=we_id, title="考勤确认单", description=data, url=url, btntxt="详细信息") send_count += 1 + # 记录发送时间,供提醒 cron 去重闸判断,避免重复推送 + rec.last_reminder_date = fields.Date.today() rec.write({'vacation_state': 'pending'}) # 给管理员发统计消息 if send_count > 0: