From 37446da00f4b932b03befe87281ce391b72d1fef 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: Fri, 20 Mar 2026 17:02:24 +0800 Subject: [PATCH 1/4] =?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 --- .../models/soong_workflow_record.py | 279 +++++------------- 1 file changed, 80 insertions(+), 199 deletions(-) diff --git a/soong_workflow/models/soong_workflow_record.py b/soong_workflow/models/soong_workflow_record.py index 713a7428f..6ca409b45 100644 --- a/soong_workflow/models/soong_workflow_record.py +++ b/soong_workflow/models/soong_workflow_record.py @@ -169,155 +169,113 @@ class SoongWorkflowRecord(models.Model): _logger.warning(f"Failed to get urgency_level from {record.res_model}: {e}") record.urgency_level = 'normal' - @api.depends('employee_ids', 'res_model', 'res_id', 'soong_state', 'reclaim_state', 'approve_state') + @api.depends('employee_ids', 'res_model', 'res_id', 'soong_state', 'reclaim_state', 'approve_state', 'users_ids') def _compute_is_to_do(self): - """保留原有计算逻辑(已优化批量查询,参考之前的版本)""" current_uid = self.env.user.id - current_employees = self.env['hr.employee'].search([('user_id', '=', current_uid)]) - active_employee_ids = current_employees.ids if current_employees else [] - if not active_employee_ids: - self.is_to_do = False - return - # 批量优化:预加载员工映射(仅查1次) - all_employees = self.env['hr.employee'].search([('user_state', '=', 'in')]) - emp_to_user = {emp.id: emp.user_id.id for emp in all_employees if emp.user_id} - - # 第一步:批量处理条件1(approve_state=start) - condition1_records = self.filtered( - lambda r: not r.reclaim_state and r.approve_state == 'start' and - set(active_employee_ids) & set(r.employee_ids.ids + r.employee2_ids.ids) + for rec in self: + rec.is_to_do = False + valid_records = self.filtered( + lambda r: current_uid in r.users_ids.ids ) - condition1_records.is_to_do = True - - # 第二步:批量处理条件2(log_ids/log_ids2) - remaining_records = self - condition1_records - remaining_records.is_to_do = False - - # 按res_model分组批量查询log(核心优化) - model_res_ids = defaultdict(list) - rec_model_res_map = {} - for rec in remaining_records.filtered(lambda r: not r.reclaim_state and r.res_model and r.res_id): - model_res_ids[rec.res_model].append(rec.res_id) - rec_model_res_map[rec.id] = (rec.res_model, rec.res_id) - - # 批量查log满足条件的记录ID - valid_rec_ids = [] - for model_name, res_ids in model_res_ids.items(): - if not res_ids: - continue - TargetModel = self.env[model_name].sudo() + if not valid_records: + return + start_records = valid_records.filtered(lambda r: r.approve_state == 'start') + start_records.is_to_do = True + remaining_records = valid_records - start_records + if not remaining_records: + return + for rec in remaining_records: log_domain = [ - ('res_id', 'in', res_ids), - ('done_by', 'in', list(emp_to_user.values())), + ("model", "=", rec.res_model ), + ("res_id", "=", rec.res_id), + ('done_by', '=', current_uid), ('approval_state', 'in', ['0', '1']) ] - # 批量查log_ids - log1_valid_res_ids = TargetModel.log_ids.search(log_domain).mapped('res_id') - # 批量查log_ids2 - log2_valid_res_ids = TargetModel.log_ids2.search(log_domain).mapped('res_id') - - valid_res_ids = set(log1_valid_res_ids + log2_valid_res_ids) - for rec_id, (model, res_id) in rec_model_res_map.items(): - if model == model_name and res_id in valid_res_ids: - valid_rec_ids.append(rec_id) - self.browse(valid_rec_ids).is_to_do = True + has_valid_log1 = self.env['soong.workflow.log'].search_count(log_domain) > 0 + has_valid_log2 = self.env['soong.workflow.log2'].search_count(log_domain) > 0 + if has_valid_log1 or has_valid_log2: + rec.is_to_do = True def _search_is_to_do(self, operator, value): - """搜索待办状态:仅打印总耗时""" - current_uid = self.env.user.id - current_employees = self.env['hr.employee'].sudo().search([('user_id', '=', current_uid)]) - active_employee_ids = current_employees.ids if current_employees else [] - if not active_employee_ids: + # 第一步:基础过滤 - 只处理包含当前用户的记录 + base_domain = [('users_ids', 'in', [current_uid])] + candidate_records = self.search(base_domain) + + if not candidate_records: return [('id', '=', False)] - base_domain = [ - ('reclaim_state', '=', False), - '|', - ('employee_ids', 'in', active_employee_ids), - ('employee2_ids', 'in', active_employee_ids) - ] - + # 处理 "is_to_do = True" 或 "is_to_do != False" 的情况 if (operator == '=' and value) or (operator == '!=' and not value): - candidate_records = self.search(base_domain) - if not candidate_records: - return [('id', '=', False)] - + # 条件1:approve_state为start的记录ID condition1_ids = candidate_records.filtered( - lambda r: r.approve_state == 'start' and not r.reclaim_state + lambda r: r.approve_state == 'start' ).ids - model_res_ids = defaultdict(list) - rec_model_res_map = {} - for rec in candidate_records - self.browse(condition1_ids): - if rec.res_model and rec.res_id: - model_res_ids[rec.res_model].append(rec.res_id) - rec_model_res_map[rec.id] = (rec.res_model, rec.res_id) + # 条件2:非start状态,且日志符合条件的记录ID + remaining_records = candidate_records - self.browse(condition1_ids) + # 仅筛选有res_model/res_id且非草稿/非start的记录 + target_records = remaining_records.filtered( + lambda r: r.res_model and r.res_id and r.approve_state not in ['draft', 'start'] + ) condition2_rec_ids = [] - for model_name, res_ids in model_res_ids.items(): - if not res_ids: - continue - TargetModel = self.env[model_name].sudo() - log1_domain = [ - ('res_id', 'in', res_ids), - ('done_by', '=', current_uid), - ('approval_state', 'in', ['0', '1']) - ] - log1_valid_res_ids = TargetModel.log_ids.search(log1_domain).mapped('res_id') - log2_domain = [ - ('res_id', 'in', res_ids), - ('done_by', '=', current_uid), - ('approval_state', 'in', ['0', '1']) - ] - log2_valid_res_ids = TargetModel.log_ids2.search(log2_domain).mapped('res_id') + if target_records: + # 逐条检查日志(完全对齐compute逻辑,移除try-except) + for rec in target_records: + # 日志筛选条件(和compute逻辑完全一致) + log_domain = [ + ("model", "=", rec.res_model), + ("res_id", "=", rec.res_id), + ('done_by', '=', current_uid), + ('approval_state', 'in', ['0', '1']) + ] + # 直接查询soong.workflow.log和log2模型 + has_valid_log1 = self.env['soong.workflow.log'].search_count(log_domain) > 0 + has_valid_log2 = self.env['soong.workflow.log2'].search_count(log_domain) > 0 - valid_res_ids = set(log1_valid_res_ids + log2_valid_res_ids) - for rec_id, (model, res_id) in rec_model_res_map.items(): - if model == model_name and res_id in valid_res_ids: - condition2_rec_ids.append(rec_id) + if has_valid_log1 or has_valid_log2: + condition2_rec_ids.append(rec.id) + # 合并符合条件的记录ID valid_ids = list(set(condition1_ids + condition2_rec_ids)) - domain = [('id', 'in', valid_ids)] + domain = [('id', 'in', valid_ids)] if valid_ids else [('id', '=', False)] elif (operator == '=' and not value) or (operator == '!=' and value): - candidate_records = self.search(base_domain) - if not candidate_records: - return [('id', '=', False)] - - condition1_invalid_ids = candidate_records.filtered( - lambda r: r.approve_state == 'start' and not r.reclaim_state + todo_ids = [] + # 条件1:approve_state为start的待办ID + condition1_todo_ids = candidate_records.filtered( + lambda r: r.approve_state == 'start' ).ids - model_res_ids = defaultdict(list) - rec_model_res_map = {} - for rec in candidate_records - self.browse(condition1_invalid_ids): - if rec.res_model and rec.res_id: - model_res_ids[rec.res_model].append(rec.res_id) - rec_model_res_map[rec.id] = (rec.res_model, rec.res_id) + # 条件2:日志符合条件的待办ID + remaining_records = candidate_records - self.browse(condition1_todo_ids) + target_records = remaining_records.filtered( + lambda r: r.res_model and r.res_id and r.approve_state not in ['draft', 'start'] + ) - condition2_invalid_ids = [] - for model_name, res_ids in model_res_ids.items(): - if not res_ids: - continue - TargetModel = self.env[model_name].sudo() - log1_domain = [ - ('res_id', 'in', res_ids), - ('done_by', '=', current_uid), - ('approval_state', 'in', ['0', '1']) - ] - log1_valid_res_ids = TargetModel.log_ids.search(log1_domain).mapped('res_id') - log2_domain = log1_domain.copy() - log2_valid_res_ids = TargetModel.log_ids2.search(log2_domain).mapped('res_id') + condition2_todo_ids = [] + if target_records: + for rec in target_records: + log_domain = [ + ("model", "=", rec.res_model), + ("res_id", "=", rec.res_id), + ('done_by', '=', current_uid), + ('approval_state', 'in', ['0', '1']) + ] + has_valid_log1 = self.env['soong.workflow.log'].search_count(log_domain) > 0 + has_valid_log2 = self.env['soong.workflow.log2'].search_count(log_domain) > 0 - valid_res_ids = set(log1_valid_res_ids + log2_valid_res_ids) - for rec_id, (model, res_id) in rec_model_res_map.items(): - if model == model_name and res_id in valid_res_ids: - condition2_invalid_ids.append(rec_id) + if has_valid_log1 or has_valid_log2: + condition2_todo_ids.append(rec.id) - invalid_ids = list(set(condition1_invalid_ids + condition2_invalid_ids)) - domain = [('id', 'not in', invalid_ids)] + todo_ids = list(set(condition1_todo_ids + condition2_todo_ids)) + # 非待办 = 基础候选记录 - 待办记录 + all_candidate_ids = candidate_records.ids + non_todo_ids = [rec_id for rec_id in all_candidate_ids if rec_id not in todo_ids] + domain = [('id', 'in', non_todo_ids)] if non_todo_ids else [('id', '=', False)] else: + # 不支持的操作符 domain = [('id', '=', False)] return domain @@ -669,90 +627,13 @@ class SoongWorkflowRecord(models.Model): @api.model def get_view(self, view_id=None, view_type='form', **options): - """优化后:批量查询+批量写入,消除嵌套循环""" - # ========== 第一步:批量查询所有目标记录(仅1次搜索) ========== current_user_id = self.env.user.id all_records = self.search([ ('users_ids', 'in', current_user_id), - ('soong_state', '!=', 'active'), + ('reclaim_state', '=', False) ]) if not all_records: return super().get_view(view_id, view_type, **options) - - model_res_ids = defaultdict(list) - rec_model_res_map = {rec.id: (rec.res_model, rec.res_id) for rec in all_records if rec.res_model and rec.res_id} - for rec_id, (model, res_id) in rec_model_res_map.items(): - model_res_ids[model].append(res_id) - - log_data = defaultdict(dict) - for model_name, res_ids in model_res_ids.items(): - if not res_ids: - continue - try: - TargetModel = self.env[model_name].sudo() - has_log1 = 'log_ids' in TargetModel._fields - has_log2 = 'log_ids2' in TargetModel._fields - - # 批量查log_ids(当前用户,仅当字段存在时) - if has_log1: - log1_domain = [('res_id', 'in', res_ids), ('done_by', '=', current_user_id)] - log1_records = TargetModel.log_ids.search(log1_domain) - for log in log1_records: - if log.res_id not in log_data[model_name]: - log_data[model_name][log.res_id] = {'log1_states': [], 'log2_states': [], - 'has_archive_log': False} - log_data[model_name][log.res_id]['log1_states'].append(log.approval_state) - if log.name == '归档': - log_data[model_name][log.res_id]['has_archive_log'] = True - log_data[model_name][log.res_id]['archive_state'] = log.approval_state - - # 批量查log_ids2(当前用户,仅当字段存在时) - if has_log2: - log2_domain = [('res_id', 'in', res_ids), ('done_by.name', '=', self.env.user.name)] - log2_records = TargetModel.log_ids2.search(log2_domain) - for log2 in log2_records: - if log2.res_id not in log_data[model_name]: - log_data[model_name][log2.res_id] = {'log1_states': [], 'log2_states': [], - 'has_archive_log': False} - log_data[model_name][log2.res_id]['log2_states'].append(log2.approval_state) - except Exception: - continue - - to_write = defaultdict(list) # {状态: [记录ID]} - for rec in all_records: - if rec.id not in rec_model_res_map: - continue - model, res_id = rec_model_res_map[rec.id] - if model not in log_data or res_id not in log_data[model]: - continue - - log_info = log_data[model][res_id] - # 处理归档日志优先级最高 - if log_info['has_archive_log']: - if log_info['archive_state'] in ['0', '1']: - to_write['to_active'].append(rec.id) - elif log_info['archive_state'] == '2': - to_write['active'].append(rec.id) - continue - - # 处理普通log_ids - log1_states = log_info['log1_states'] - if any(s in ['0', '1'] for s in log1_states): - to_write['to_do'].append(rec.id) - elif all(s == '2' for s in log1_states if s): - to_write['done'].append(rec.id) - - # 处理log_ids2 - log2_states = log_info['log2_states'] - if log2_states: - if any(s in ['0', '1'] for s in log2_states): - to_write['to_do'].append(rec.id) - elif all(s == '2' for s in log2_states): - to_write['done'].append(rec.id) - - for state, rec_ids in to_write.items(): - if rec_ids: - self.browse(rec_ids).write({'soong_state': state}) all_records._compute_is_done() all_records._compute_is_to_do() return super().get_view(view_id, view_type, **options) From 43a66272c3cf05f6dbef47a6837308c16b671d56 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: Fri, 20 Mar 2026 17:33:33 +0800 Subject: [PATCH 2/4] =?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_record.py | 2 -- soong_workflow/wizard/soong_workflow_comment_wizard.py | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/soong_workflow/models/soong_workflow_record.py b/soong_workflow/models/soong_workflow_record.py index 6ca409b45..c096933b0 100644 --- a/soong_workflow/models/soong_workflow_record.py +++ b/soong_workflow/models/soong_workflow_record.py @@ -201,10 +201,8 @@ class SoongWorkflowRecord(models.Model): # 第一步:基础过滤 - 只处理包含当前用户的记录 base_domain = [('users_ids', 'in', [current_uid])] candidate_records = self.search(base_domain) - if not candidate_records: return [('id', '=', False)] - # 处理 "is_to_do = True" 或 "is_to_do != False" 的情况 if (operator == '=' and value) or (operator == '!=' and not value): # 条件1:approve_state为start的记录ID diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index d9d074812..15841563e 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -386,8 +386,10 @@ class SoongWorkflowCommentWizard(models.TransientModel): return self.env['hr.employee'].sudo().search(domain) elif link_users_group_ids: - role_domain = ['|', ('user_role_id', 'in', link_users_group_ids.user_role_ids.ids), - ('user_role_ids', 'in', link_users_group_ids.user_role_ids.ids)] + role_domain = ['|', '|', ('user_role_id', 'in', link_users_group_ids.user_role_ids.ids), + ('user_role_ids', 'in', link_users_group_ids.user_role_ids.ids), + ('role_group_ids', 'in', link_users_group_ids.ids) + ] if user_role_domain: role_domain = ['|'] + role_domain + user_role_domain domain = role_domain + company_domain + department_domain From ee48f814fc2d1caf7413c7dd7950dd9541ff9dea 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: Fri, 20 Mar 2026 18:05:12 +0800 Subject: [PATCH 3/4] =?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 --- .../models/soong_workflow_record.py | 199 +++++++++++------- 1 file changed, 121 insertions(+), 78 deletions(-) diff --git a/soong_workflow/models/soong_workflow_record.py b/soong_workflow/models/soong_workflow_record.py index c096933b0..7f0e22190 100644 --- a/soong_workflow/models/soong_workflow_record.py +++ b/soong_workflow/models/soong_workflow_record.py @@ -169,111 +169,154 @@ class SoongWorkflowRecord(models.Model): _logger.warning(f"Failed to get urgency_level from {record.res_model}: {e}") record.urgency_level = 'normal' - @api.depends('employee_ids', 'res_model', 'res_id', 'soong_state', 'reclaim_state', 'approve_state', 'users_ids') + @api.depends('employee_ids', 'res_model', 'res_id', 'soong_state', 'reclaim_state', 'approve_state') def _compute_is_to_do(self): + """保留原有计算逻辑(已优化批量查询,参考之前的版本)""" current_uid = self.env.user.id - for rec in self: - rec.is_to_do = False - valid_records = self.filtered( - lambda r: current_uid in r.users_ids.ids + current_employees = self.env['hr.employee'].search([('user_id', '=', current_uid)]) + active_employee_ids = current_employees.ids if current_employees else [] + if not active_employee_ids: + self.is_to_do = False + return + all_employees = self.env['hr.employee'].search([('user_state', '=', 'in')]) + emp_to_user = {emp.id: emp.user_id.id for emp in all_employees if emp.user_id} + + # 第一步:批量处理条件1(approve_state=start) + condition1_records = self.filtered( + lambda r: not r.reclaim_state and r.approve_state == 'start' and + set(active_employee_ids) & set(r.employee_ids.ids + r.employee2_ids.ids) ) - if not valid_records: - return - start_records = valid_records.filtered(lambda r: r.approve_state == 'start') - start_records.is_to_do = True - remaining_records = valid_records - start_records - if not remaining_records: - return - for rec in remaining_records: + condition1_records.is_to_do = True + + # 第二步:批量处理条件2(log_ids/log_ids2) + remaining_records = self - condition1_records + remaining_records.is_to_do = False + + # 按res_model分组批量查询log(核心优化) + model_res_ids = defaultdict(list) + rec_model_res_map = {} + for rec in remaining_records.filtered(lambda r: not r.reclaim_state and r.res_model and r.res_id): + model_res_ids[rec.res_model].append(rec.res_id) + rec_model_res_map[rec.id] = (rec.res_model, rec.res_id) + + # 批量查log满足条件的记录ID + valid_rec_ids = [] + for model_name, res_ids in model_res_ids.items(): + if not res_ids: + continue + TargetModel = self.env[model_name].sudo() log_domain = [ - ("model", "=", rec.res_model ), - ("res_id", "=", rec.res_id), - ('done_by', '=', current_uid), + ('res_id', 'in', res_ids), + ('done_by', 'in', list(emp_to_user.values())), ('approval_state', 'in', ['0', '1']) ] - has_valid_log1 = self.env['soong.workflow.log'].search_count(log_domain) > 0 - has_valid_log2 = self.env['soong.workflow.log2'].search_count(log_domain) > 0 - if has_valid_log1 or has_valid_log2: - rec.is_to_do = True + # 批量查log_ids + log1_valid_res_ids = TargetModel.log_ids.search(log_domain).mapped('res_id') + # 批量查log_ids2 + log2_valid_res_ids = TargetModel.log_ids2.search(log_domain).mapped('res_id') + + valid_res_ids = set(log1_valid_res_ids + log2_valid_res_ids) + for rec_id, (model, res_id) in rec_model_res_map.items(): + if model == model_name and res_id in valid_res_ids: + valid_rec_ids.append(rec_id) + self.browse(valid_rec_ids).is_to_do = True def _search_is_to_do(self, operator, value): + """搜索待办状态:仅打印总耗时""" + current_uid = self.env.user.id - # 第一步:基础过滤 - 只处理包含当前用户的记录 - base_domain = [('users_ids', 'in', [current_uid])] - candidate_records = self.search(base_domain) - if not candidate_records: + current_employees = self.env['hr.employee'].sudo().search([('user_id', '=', current_uid)]) + active_employee_ids = current_employees.ids if current_employees else [] + if not active_employee_ids: return [('id', '=', False)] - # 处理 "is_to_do = True" 或 "is_to_do != False" 的情况 + + base_domain = [ + ('reclaim_state', '=', False), + '|', + ('employee_ids', 'in', active_employee_ids), + ('employee2_ids', 'in', active_employee_ids) + ] + if (operator == '=' and value) or (operator == '!=' and not value): - # 条件1:approve_state为start的记录ID + candidate_records = self.search(base_domain) + if not candidate_records: + return [('id', '=', False)] + condition1_ids = candidate_records.filtered( - lambda r: r.approve_state == 'start' + lambda r: r.approve_state == 'start' and not r.reclaim_state ).ids - # 条件2:非start状态,且日志符合条件的记录ID - remaining_records = candidate_records - self.browse(condition1_ids) - # 仅筛选有res_model/res_id且非草稿/非start的记录 - target_records = remaining_records.filtered( - lambda r: r.res_model and r.res_id and r.approve_state not in ['draft', 'start'] - ) + model_res_ids = defaultdict(list) + rec_model_res_map = {} + for rec in candidate_records - self.browse(condition1_ids): + if rec.res_model and rec.res_id: + model_res_ids[rec.res_model].append(rec.res_id) + rec_model_res_map[rec.id] = (rec.res_model, rec.res_id) condition2_rec_ids = [] - if target_records: - # 逐条检查日志(完全对齐compute逻辑,移除try-except) - for rec in target_records: - # 日志筛选条件(和compute逻辑完全一致) - log_domain = [ - ("model", "=", rec.res_model), - ("res_id", "=", rec.res_id), - ('done_by', '=', current_uid), - ('approval_state', 'in', ['0', '1']) - ] - # 直接查询soong.workflow.log和log2模型 - has_valid_log1 = self.env['soong.workflow.log'].search_count(log_domain) > 0 - has_valid_log2 = self.env['soong.workflow.log2'].search_count(log_domain) > 0 + for model_name, res_ids in model_res_ids.items(): + if not res_ids: + continue + TargetModel = self.env[model_name].sudo() + log1_domain = [ + ('res_id', 'in', res_ids), + ('done_by', '=', current_uid), + ('approval_state', 'in', ['0', '1']) + ] + log1_valid_res_ids = TargetModel.log_ids.search(log1_domain).mapped('res_id') + log2_domain = [ + ('res_id', 'in', res_ids), + ('done_by', '=', current_uid), + ('approval_state', 'in', ['0', '1']) + ] + log2_valid_res_ids = TargetModel.log_ids2.search(log2_domain).mapped('res_id') - if has_valid_log1 or has_valid_log2: - condition2_rec_ids.append(rec.id) + valid_res_ids = set(log1_valid_res_ids + log2_valid_res_ids) + for rec_id, (model, res_id) in rec_model_res_map.items(): + if model == model_name and res_id in valid_res_ids: + condition2_rec_ids.append(rec_id) - # 合并符合条件的记录ID valid_ids = list(set(condition1_ids + condition2_rec_ids)) - domain = [('id', 'in', valid_ids)] if valid_ids else [('id', '=', False)] + domain = [('id', 'in', valid_ids)] elif (operator == '=' and not value) or (operator == '!=' and value): - todo_ids = [] - # 条件1:approve_state为start的待办ID - condition1_todo_ids = candidate_records.filtered( - lambda r: r.approve_state == 'start' + candidate_records = self.search(base_domain) + if not candidate_records: + return [('id', '=', False)] + + condition1_invalid_ids = candidate_records.filtered( + lambda r: r.approve_state == 'start' and not r.reclaim_state ).ids - # 条件2:日志符合条件的待办ID - remaining_records = candidate_records - self.browse(condition1_todo_ids) - target_records = remaining_records.filtered( - lambda r: r.res_model and r.res_id and r.approve_state not in ['draft', 'start'] - ) + model_res_ids = defaultdict(list) + rec_model_res_map = {} + for rec in candidate_records - self.browse(condition1_invalid_ids): + if rec.res_model and rec.res_id: + model_res_ids[rec.res_model].append(rec.res_id) + rec_model_res_map[rec.id] = (rec.res_model, rec.res_id) - condition2_todo_ids = [] - if target_records: - for rec in target_records: - log_domain = [ - ("model", "=", rec.res_model), - ("res_id", "=", rec.res_id), - ('done_by', '=', current_uid), - ('approval_state', 'in', ['0', '1']) - ] - has_valid_log1 = self.env['soong.workflow.log'].search_count(log_domain) > 0 - has_valid_log2 = self.env['soong.workflow.log2'].search_count(log_domain) > 0 + condition2_invalid_ids = [] + for model_name, res_ids in model_res_ids.items(): + if not res_ids: + continue + TargetModel = self.env[model_name].sudo() + log1_domain = [ + ('res_id', 'in', res_ids), + ('done_by', '=', current_uid), + ('approval_state', 'in', ['0', '1']) + ] + log1_valid_res_ids = TargetModel.log_ids.search(log1_domain).mapped('res_id') + log2_domain = log1_domain.copy() + log2_valid_res_ids = TargetModel.log_ids2.search(log2_domain).mapped('res_id') - if has_valid_log1 or has_valid_log2: - condition2_todo_ids.append(rec.id) + valid_res_ids = set(log1_valid_res_ids + log2_valid_res_ids) + for rec_id, (model, res_id) in rec_model_res_map.items(): + if model == model_name and res_id in valid_res_ids: + condition2_invalid_ids.append(rec_id) - todo_ids = list(set(condition1_todo_ids + condition2_todo_ids)) - # 非待办 = 基础候选记录 - 待办记录 - all_candidate_ids = candidate_records.ids - non_todo_ids = [rec_id for rec_id in all_candidate_ids if rec_id not in todo_ids] - domain = [('id', 'in', non_todo_ids)] if non_todo_ids else [('id', '=', False)] + invalid_ids = list(set(condition1_invalid_ids + condition2_invalid_ids)) + domain = [('id', 'not in', invalid_ids)] else: - # 不支持的操作符 domain = [('id', '=', False)] return domain From 61caa779c18c6dac0777e21d0e88b9533cfbd76a 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: Fri, 20 Mar 2026 18:05:52 +0800 Subject: [PATCH 4/4] =?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_record.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soong_workflow/models/soong_workflow_record.py b/soong_workflow/models/soong_workflow_record.py index 7f0e22190..56afd43b6 100644 --- a/soong_workflow/models/soong_workflow_record.py +++ b/soong_workflow/models/soong_workflow_record.py @@ -671,7 +671,7 @@ class SoongWorkflowRecord(models.Model): current_user_id = self.env.user.id all_records = self.search([ ('users_ids', 'in', current_user_id), - ('reclaim_state', '=', False) + ('soong_state', '!=', 'active'), ]) if not all_records: return super().get_view(view_id, view_type, **options)