From 0654f1feef6dce13c025ae048a069c4f494652ba 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: Wed, 10 Jun 2026 17:33:52 +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 --- .../views/soong_workflow_record.xml | 2 +- .../wizard/soong_workflow_comment_wizard.py | 52 ++++++++++++++++++- .../soong_workflow_comment_wizard_view.xml | 6 +++ yuthon_issue/models/issue_library.py | 21 ++++++++ yuthon_issue/views/issue_library_views.xml | 10 ++++ 5 files changed, 89 insertions(+), 2 deletions(-) diff --git a/soong_workflow/views/soong_workflow_record.xml b/soong_workflow/views/soong_workflow_record.xml index 70a0bdf82..9a4283683 100644 --- a/soong_workflow/views/soong_workflow_record.xml +++ b/soong_workflow/views/soong_workflow_record.xml @@ -459,7 +459,7 @@ ir.actions.act_window soong.workflow.record tree,kanban,search - [('reclaim_state', '=', False), ('is_company', '=', True),('approve_state','!=','start'),('approvals_group_id.name', 'not in', ['考勤', '人事'])] + [('reclaim_state', '=', False), ('approve_state','!=','start'),('approvals_group_id.name', 'not in', ['考勤', '人事']), '|', ('users_ids', 'in', [uid]), ('member_of_department', '=', True)] {'search_default_my_department_shifts': True, 'default_order': 'display_end_time desc'} diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index 89c28c297..398237a2f 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -19,6 +19,7 @@ class SoongWorkflowCommentWizard(models.TransientModel): res_model = fields.Char() res_id = fields.Integer() code = fields.Char() + log_ids = fields.Many2many(comodel_name="soong.workflow.log") node_btn_id = fields.Many2one(comodel_name="soong.workflow.node.button") node_btn_name = fields.Char(string="动作名称", related='node_btn_id.name') @@ -35,6 +36,51 @@ class SoongWorkflowCommentWizard(models.TransientModel): workflow_record_id = fields.Many2one('soong.workflow.record', string="流程") is_selection = fields.Boolean(string="是否自动选择") trans_link_id = fields.Many2one('trans.link', string='转交节点', ondelete='set null') + is_avoid = fields.Boolean(string='是否回避') + allowed_issue_ids = fields.Many2many('issue.library', 'soong_comment_wizard_allowed_issue_rel', + 'wizard_id', 'issue_id', string='可选议题') + avoid_issue_ids = fields.Many2many('issue.library', 'soong_comment_wizard_avoid_issue_rel', + 'wizard_id', 'issue_id', string='回避议题') + avoid_comment = fields.Char(string='回避意见') + + @api.model + def default_get(self, fields_list): + res = super().default_get(fields_list) + ctx = self.env.context + res_model = ctx.get('default_res_model') or res.get('res_model') + res_id = ctx.get('default_res_id') or res.get('res_id') + if res_model and res_id: + source = self.env[res_model].browse(res_id) + if hasattr(source, 'line_ids'): + res['allowed_issue_ids'] = [(6, 0, source.line_ids.mapped('issue_id').ids)] + return res + + @api.onchange('avoid_issue_ids') + def _onchange_avoid_issue_ids(self): + if self.avoid_issue_ids and self.allowed_issue_ids: + invalid = self.avoid_issue_ids - self.allowed_issue_ids + if invalid: + self.avoid_issue_ids = [(6, 0, (self.avoid_issue_ids - invalid).ids)] + return { + 'warning': { + 'title': '无效议题', + 'message': f'以下议题不在当前申报范围内,已自动移除:{", ".join(invalid.mapped("name"))}', + } + } + + @api.onchange('is_avoid') + def _onchange_is_avoid(self): + if not self.is_avoid: + self.avoid_issue_ids = [(5, 0, 0)] + self.avoid_comment = False + + def _handle_avoidance(self): + """回避处理:勾选回避且选了议题时,在对应议题中记录回避""" + if not self.is_avoid or not self.avoid_issue_ids: + return + for issue in self.avoid_issue_ids: + issue.log_avoidance(self.env.user, self.avoid_comment or '') + document_ids = fields.Many2many('ir.attachment', string="附件") return_link_id = fields.Many2one('trans.link', string='退回节点', ondelete='set null') invalid_link_ids = fields.Many2many( @@ -130,7 +176,7 @@ class SoongWorkflowCommentWizard(models.TransientModel): ]) self.employee_ids2 = self.env['hr.employee'].search(domain) - @api.depends('comment_note_id', 'comment_note') + @api.depends('comment_note_id', 'comment_note', 'avoid_comment') def _compute_comment(self): for record in self: comment_parts = [] @@ -138,6 +184,8 @@ class SoongWorkflowCommentWizard(models.TransientModel): comment_parts.append(record.comment_note_id.name) if record.comment_note: comment_parts.append(record.comment_note) + if record.avoid_comment: + comment_parts.append(f'【回避意见】{record.avoid_comment}') record.comment = " ".join(comment_parts) if comment_parts else "" @api.depends('user_id.employee_ids.user_role_ids', 'user_id.employee_ids.user_role_id') @@ -564,6 +612,7 @@ class SoongWorkflowCommentWizard(models.TransientModel): title=record_id._description + '传阅/抄送,测试提醒', description=description, url=url, btntxt="查看详情") + self._handle_avoidance() if self.node_btn_name == '退回': if not self.return_link_id: raise UserError('请选择退回节点') @@ -970,6 +1019,7 @@ class SoongWorkflowCommentWizard(models.TransientModel): title=title, description=f"标题为{record_id.name}的{title}已结束,请归档", url=url, btntxt="查看详情") + self._handle_avoidance() if self.node_btn_name == "分发": record_id.is_send = True menu_id = self.env['ir.ui.menu'].search([('name', '=', '行政收文')], limit=1) diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml b/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml index ba475968e..8cf556148 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml +++ b/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml @@ -12,6 +12,7 @@ + @@ -136,6 +137,11 @@ + + + +
退回节点
diff --git a/yuthon_issue/models/issue_library.py b/yuthon_issue/models/issue_library.py index 3b3e1c4b0..7eea5915a 100644 --- a/yuthon_issue/models/issue_library.py +++ b/yuthon_issue/models/issue_library.py @@ -71,6 +71,7 @@ class IssueLibrary(models.Model): issue_approval_id = fields.Many2one('issue.approval', string="关联议题审批") issue_library_line_ids = fields.One2many('issue.library.line', 'issue_library_id', string="决策明细") issue_library_approval_line_ids = fields.One2many('issue.library.approval.line', 'issue_library_id', string='流程记录') + avoid_line_ids = fields.One2many('issue.library.avoid.line', 'issue_library_id', string='回避记录') approval_decision_sequence = fields.Char(string="决策清单事项") is_booking = fields.Boolean(string="是否上会") issues_result = fields.Html(string="会议结果") @@ -113,6 +114,15 @@ class IssueLibrary(models.Model): is_push_depart = fields.Boolean(string="部门推送") is_meeting = fields.Boolean(string="已过会", compute='_compute_meeting', store=True) + def log_avoidance(self, avoid_user, avoid_comment=''): + """记录回避信息""" + self.env['issue.library.avoid.line'].create({ + 'issue_library_id': self.id, + 'avoid_user_id': avoid_user.id, + 'avoid_date': fields.Datetime.now() + timedelta(hours=8), + 'avoid_comment': avoid_comment, + }) + def correction_confirm(self): for rec in self: rec.is_confirm = False @@ -1006,3 +1016,14 @@ class IssueLibraryRoomLine(models.Model): 'target': 'current', } + +class IssueLibraryAvoidLine(models.Model): + _name = 'issue.library.avoid.line' + _description = '回避记录' + _order = 'avoid_date desc' + + issue_library_id = fields.Many2one('issue.library', string='关联议题') + avoid_user_id = fields.Many2one('res.users', string='回避人', default=lambda self: self.env.user) + avoid_date = fields.Datetime(string='回避时间', default=fields.Datetime.now) + avoid_comment = fields.Text(string='回避意见') + diff --git a/yuthon_issue/views/issue_library_views.xml b/yuthon_issue/views/issue_library_views.xml index 763698f3c..da8fca6f3 100644 --- a/yuthon_issue/views/issue_library_views.xml +++ b/yuthon_issue/views/issue_library_views.xml @@ -328,6 +328,16 @@
+ + + + + + + + + +