ai动态报表
This commit is contained in:
@@ -1,65 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.osv import expression
|
||||
import pypinyin
|
||||
import re
|
||||
|
||||
|
||||
class IrUiMenu(models.Model):
|
||||
_inherit = 'ir.ui.menu'
|
||||
|
||||
name_pinyin = fields.Char(
|
||||
string='菜单名拼音',
|
||||
compute='_compute_name_pinyin',
|
||||
store=True,
|
||||
index=True,
|
||||
)
|
||||
|
||||
@api.depends('name')
|
||||
def _compute_name_pinyin(self):
|
||||
for menu in self:
|
||||
if menu.name:
|
||||
# 全拼:如 "通知公告" → "tongzhigonggao"
|
||||
full_pinyin = ''.join(pypinyin.lazy_pinyin(menu.name)).lower()
|
||||
# 首字母:如 "通知公告" → "tzgg"
|
||||
first_letters = ''.join([
|
||||
p[0] for p in pypinyin.pinyin(menu.name)
|
||||
]).lower()
|
||||
menu.name_pinyin = f"{full_pinyin} {first_letters}"
|
||||
else:
|
||||
menu.name_pinyin = False
|
||||
|
||||
def name_search(self, name='', args=None, operator='ilike', limit=100):
|
||||
"""
|
||||
重写 name_search 支持全拼/首字母模糊搜索菜单
|
||||
"""
|
||||
"""支持全拼/首字母模糊搜索菜单(Ctrl+K)"""
|
||||
if args is None:
|
||||
args = []
|
||||
if name and operator in ('ilike', 'like', '=', '=like'):
|
||||
# 清理输入:去掉空格、转小写
|
||||
search_term = name.strip().lower().replace(' ', '')
|
||||
if not search_term:
|
||||
return super().name_search(name=name, args=args, operator=operator, limit=limit)
|
||||
if not name or operator not in ('ilike', 'like', '=', '=like'):
|
||||
return super().name_search(name=name, args=args, operator=operator, limit=limit)
|
||||
|
||||
# 生成搜索词的拼音和首字母
|
||||
search_pinyin = ''.join(pypinyin.lazy_pinyin(search_term)).lower()
|
||||
search_first = ''.join([p[0] for p in pypinyin.pinyin(search_term)]).lower()
|
||||
search_term = name.strip().lower().replace(' ', '')
|
||||
if not search_term:
|
||||
return super().name_search(name=name, args=args, operator=operator, limit=limit)
|
||||
|
||||
# 构建拼音搜索域:匹配 name_pinyin 字段
|
||||
pinyin_domain = [
|
||||
'|',
|
||||
('name_pinyin', 'ilike', search_term), # 直接搜索词
|
||||
('name_pinyin', 'ilike', search_pinyin), # 全拼搜索
|
||||
]
|
||||
# 如果首字母不同,也加上
|
||||
if search_first != search_pinyin:
|
||||
pinyin_domain = ['|'] + pinyin_domain + [('name_pinyin', 'ilike', search_first)]
|
||||
# 生成搜索词的拼音和首字母
|
||||
search_pinyin = ''.join(pypinyin.lazy_pinyin(search_term)).lower()
|
||||
search_first = ''.join([p[0] for p in pypinyin.pinyin(search_term)]).lower()
|
||||
|
||||
# 组合:原名搜索 OR 拼音搜索
|
||||
full_domain = ['|'] + expression.AND([args, [('name', operator, name)]]) + expression.AND([args, pinyin_domain])
|
||||
# 原名搜索
|
||||
name_domain = expression.AND([args, [('name', operator, name)]])
|
||||
name_ids = self.search(name_domain, limit=limit).ids
|
||||
|
||||
# 去重:用 browse 把结果合并(优先按原名匹配排序)
|
||||
name_results = self.search(expression.AND([args, [('name', operator, name)]]), limit=limit)
|
||||
pinyin_results = self.search(expression.AND([args, pinyin_domain]), limit=limit)
|
||||
all_ids = list(dict.fromkeys(name_results.ids + pinyin_results.ids))[:limit]
|
||||
return self.browse(all_ids).name_get()
|
||||
return super().name_search(name=name, args=args, operator=operator, limit=limit)
|
||||
# 拼音搜索:拿到所有菜单,在 Python 层过滤
|
||||
all_menus = self.search(args, limit=limit * 3)
|
||||
pinyin_ids = []
|
||||
for menu in all_menus:
|
||||
if not menu.name:
|
||||
continue
|
||||
menu_pinyin = ''.join(pypinyin.lazy_pinyin(menu.name)).lower()
|
||||
menu_first = ''.join([p[0] for p in pypinyin.pinyin(menu.name)]).lower()
|
||||
search_key = f"{menu_pinyin} {menu_first}"
|
||||
if search_term in search_key or search_pinyin in search_key or search_first in search_key:
|
||||
pinyin_ids.append(menu.id)
|
||||
|
||||
# 合并,原名匹配优先
|
||||
all_ids = list(dict.fromkeys(name_ids + pinyin_ids))[:limit]
|
||||
return self.browse(all_ids).name_get()
|
||||
|
||||
Reference in New Issue
Block a user