Merge pull request !9891 from 李鹏宇/dev
This commit is contained in:
李鹏宇
2026-03-18 11:27:41 +00:00
committed by Gitee
+7 -86
View File
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
import time
from odoo import models, fields, api, _
from odoo import models, exceptions
from odoo.exceptions import ValidationError, UserError
import logging
from datetime import datetime, date, time, timedelta
from datetime import datetime, date, timedelta
import re
from collections import defaultdict
_logger = logging.getLogger(__name__)
@@ -75,7 +75,6 @@ class SoongWorkflowRecord(models.Model):
is_unlink = fields.Boolean(string="是否可删", compute='_compute_is_unlink')
is_to_do = fields.Boolean(
string="是否是待办流程",
compute='_compute_is_to_do',
search='_search_is_to_do',
)
@@ -169,74 +168,16 @@ 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')
def _compute_is_to_do(self):
"""计算待办状态:
1. approve_state为start 且 employee_ids包含当前用户关联员工 → 待办
2. 原有逻辑:log_ids/log_ids2满足条件 → 待办
"""
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:
for record in self:
record.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}
for record in self.filtered(lambda r: not r.reclaim_state):
record.is_to_do = False
all_record_emp_ids = record.employee_ids.ids + record.employee2_ids.ids
if record.approve_state == 'start' and set(active_employee_ids) & set(all_record_emp_ids) and not record.reclaim_state:
record.is_to_do = True
continue
# 原有逻辑:仅当新增条件不满足时,才执行原有log_ids/log_ids2判断
record_emp_ids = [emp.id for emp in record.employee_ids if emp.id in active_employee_ids]
if not record_emp_ids:
continue
record_user_ids = [emp_to_user[emp_id] for emp_id in record_emp_ids if emp_id in emp_to_user]
if not record_user_ids:
continue
target_record = None
if record.res_model and record.res_id:
try:
target_record = self.env[record.res_model].browse(record.res_id).exists()
except (exceptions.MissingError, exceptions.AccessError):
continue
if not target_record:
continue
is_todo = False
# 检查log_ids
target_logs = target_record.log_ids.filtered(
lambda l: l.done_by.id in record_user_ids and l.approval_state in ['0', '1']
)
if target_logs:
is_todo = True
# 检查log_ids2
if not is_todo:
target_log2 = target_record.log_ids2.filtered(
lambda l: l.done_by.id in record_user_ids and l.approval_state in ['0', '1']
)
if target_log2:
is_todo = True
# 设置最终待办状态
record.is_to_do = is_todo
def _search_is_to_do(self, operator, value):
"""优化版:批量查询+预加载,3000条记录耗时1-3秒"""
"""搜索待办状态:仅打印总耗时"""
current_uid = self.env.user.id
# 1. 批量获取当前用户关联的员工ID(仅查1次)
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)]
# 2. 基础域(批量筛选,仅查1次)
base_domain = [
('reclaim_state', '=', False),
'|',
@@ -244,43 +185,33 @@ class SoongWorkflowRecord(models.Model):
('employee2_ids', 'in', active_employee_ids)
]
# 3. 核心逻辑:分场景处理,批量查询代替逐行循环
if (operator == '=' and value) or (operator == '!=' and not value):
# 场景1:搜索is_to_do=True的记录
candidate_records = self.search(base_domain)
if not candidate_records:
return [('id', '=', False)]
# 3.1 批量筛选条件1:approve_state=start(无需查数据库)
condition1_ids = candidate_records.filtered(
lambda r: r.approve_state == 'start' and not r.reclaim_state
).ids
# 3.2 批量处理条件2:log_ids/log_ids2满足条件(核心优化)
# 步骤1:按res_model分组,收集所有res_id
model_res_ids = defaultdict(list)
rec_model_res_map = {} # 记录ID -> (model, res_id) 映射
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:批量查询所有目标模型的log记录(1次查询代替3000次)
condition2_rec_ids = []
for model_name, res_ids in model_res_ids.items():
if not res_ids:
continue
TargetModel = self.env[model_name].sudo() # sudo减少权限校验
# 批量查log_ids满足条件的res_id
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')
# 批量查log_ids2满足条件的res_id
log2_domain = [
('res_id', 'in', res_ids),
('done_by', '=', current_uid),
@@ -288,28 +219,23 @@ class SoongWorkflowRecord(models.Model):
]
log2_valid_res_ids = TargetModel.log_ids2.search(log2_domain).mapped('res_id')
# 合并有效res_id,映射回当前记录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)
# 3.3 合并条件1和条件2的ID
valid_ids = list(set(condition1_ids + condition2_rec_ids))
domain = [('id', 'in', valid_ids)]
elif (operator == '=' and not value) or (operator == '!=' and value):
# 场景2:搜索is_to_do=False的记录
candidate_records = self.search(base_domain)
if not candidate_records:
return [('id', '=', False)]
# 3.1 批量筛选条件1的无效ID
condition1_invalid_ids = candidate_records.filtered(
lambda r: r.approve_state == 'start' and not r.reclaim_state
).ids
# 3.2 批量查询条件2的无效ID
model_res_ids = defaultdict(list)
rec_model_res_map = {}
for rec in candidate_records - self.browse(condition1_invalid_ids):
@@ -322,14 +248,12 @@ class SoongWorkflowRecord(models.Model):
if not res_ids:
continue
TargetModel = self.env[model_name].sudo()
# 批量查log_ids
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')
# 批量查log_ids2
log2_domain = log1_domain.copy()
log2_valid_res_ids = TargetModel.log_ids2.search(log2_domain).mapped('res_id')
@@ -338,13 +262,10 @@ class SoongWorkflowRecord(models.Model):
if model == model_name and res_id in valid_res_ids:
condition2_invalid_ids.append(rec_id)
# 3.3 合并无效ID,返回反向域
invalid_ids = list(set(condition1_invalid_ids + condition2_invalid_ids))
domain = [('id', 'not in', invalid_ids)]
else:
domain = [('id', '=', False)]
return domain
@api.depends('employee_ids', 'soong_state', 'reclaim_state')