66 lines
2.7 KiB
Python
66 lines
2.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
from odoo import api, fields, models, _
|
|
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 支持全拼/首字母模糊搜索菜单
|
|
"""
|
|
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)
|
|
|
|
# 生成搜索词的拼音和首字母
|
|
search_pinyin = ''.join(pypinyin.lazy_pinyin(search_term)).lower()
|
|
search_first = ''.join([p[0] for p in pypinyin.pinyin(search_term)]).lower()
|
|
|
|
# 构建拼音搜索域:匹配 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)]
|
|
|
|
# 组合:原名搜索 OR 拼音搜索
|
|
full_domain = ['|'] + expression.AND([args, [('name', operator, name)]]) + expression.AND([args, pinyin_domain])
|
|
|
|
# 去重:用 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)
|