51 lines
1.9 KiB
Python
51 lines
1.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
from odoo import api, fields, models, _
|
|
from odoo.osv import expression
|
|
import pypinyin
|
|
|
|
|
|
class IrUiMenu(models.Model):
|
|
_inherit = 'ir.ui.menu'
|
|
|
|
def _get_menu_pinyin(self, name):
|
|
"""计算菜单名的全拼+首字母"""
|
|
if not name:
|
|
return ''
|
|
full_pinyin = ''.join(pypinyin.lazy_pinyin(name)).lower()
|
|
first_letters = ''.join([p[0] for p in pypinyin.pinyin(name)]).lower()
|
|
return f"{full_pinyin} {first_letters}"
|
|
|
|
def name_search(self, name='', args=None, operator='ilike', limit=100):
|
|
"""支持全拼/首字母搜索菜单"""
|
|
if args is None:
|
|
args = []
|
|
if not name or operator not in ('ilike', 'like', '=', '=like'):
|
|
return super().name_search(name=name, args=args, operator=operator, limit=limit)
|
|
|
|
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_domain = expression.AND([args, [('name', operator, name)]])
|
|
name_ids = self.search(name_domain, limit=limit).ids
|
|
|
|
# Python 层拼音匹配
|
|
all_menus = self.search(args, limit=limit * 3)
|
|
pinyin_ids = []
|
|
for menu in all_menus:
|
|
if menu.id in name_ids:
|
|
continue
|
|
if not menu.name:
|
|
continue
|
|
pinyin = self._get_menu_pinyin(menu.name)
|
|
if search_term in pinyin or search_pinyin in pinyin or search_first in pinyin:
|
|
pinyin_ids.append(menu.id)
|
|
|
|
all_ids = list(dict.fromkeys(name_ids + pinyin_ids))[:limit]
|
|
return self.browse(all_ids).name_get()
|