229 lines
8.9 KiB
Plaintext
229 lines
8.9 KiB
Plaintext
async def home_page_product_menu_search(ns={}):
|
||
"""
|
||
查找菜单,支持按层级和父级ID筛选
|
||
规则:
|
||
1. 无参数时,返回所有数据并有嵌套层级
|
||
2. 有参数时,menu_level和title必传,返回当前层级以及向下的嵌套层级数据
|
||
:param ns:
|
||
:return:
|
||
"""
|
||
db = DBPools()
|
||
async with db.sqlorContext('kboss') as sor:
|
||
try:
|
||
# 无参数时,返回所有数据
|
||
if not ns:
|
||
conditions = {"del_flg": "0"}
|
||
result = await sor.R('home_page_product_menu', conditions)
|
||
menu_tree = await build_menu_tree(result)
|
||
return {
|
||
'status': True,
|
||
'msg': 'search all menu success',
|
||
'data': menu_tree
|
||
}
|
||
|
||
# 有参数时,验证必填参数
|
||
# if not ns.get('menu_level') or not ns.get('title'):
|
||
# return {
|
||
# 'status': False,
|
||
# 'msg': 'menu_level and title are required when parameters are provided'
|
||
# }
|
||
|
||
# 获取指定层级及向下层级的数据
|
||
menu_level = int(ns.get('menu_level'))
|
||
title = ns.get('title')
|
||
|
||
# 构建查询条件,获取当前层级及向下层级的数据
|
||
conditions = {"del_flg": "0"}
|
||
|
||
# 根据层级获取相应的数据
|
||
if menu_level == 1:
|
||
# 获取所有层级的数据,用于构建完整的树形结构
|
||
all_conditions = {"del_flg": "0"}
|
||
if title:
|
||
# 如果指定了标题,获取所有层级中标题匹配的数据
|
||
all_result = await sor.R('home_page_product_menu', all_conditions)
|
||
filtered_result = [item for item in all_result if title in item.get('title', '')]
|
||
|
||
# 获取匹配项的所有子级数据
|
||
result = []
|
||
parent_ids = set()
|
||
|
||
# 收集一级菜单的ID
|
||
for item in filtered_result:
|
||
if item['menu_level'] == 1:
|
||
parent_ids.add(item['id'])
|
||
result.append(item)
|
||
|
||
# 获取所有子级数据
|
||
if parent_ids:
|
||
all_data = await sor.R('home_page_product_menu', {"del_flg": "0"})
|
||
for item in all_data:
|
||
if item['parent_id'] in parent_ids:
|
||
result.append(item)
|
||
|
||
menu_tree = await build_menu_tree(result)
|
||
else:
|
||
# 获取所有数据
|
||
result = await sor.R('home_page_product_menu', all_conditions)
|
||
menu_tree = await build_menu_tree(result)
|
||
|
||
elif menu_level == 2:
|
||
# 获取二级菜单及其子级(三级)
|
||
all_conditions = {"del_flg": "0"}
|
||
all_result = await sor.R('home_page_product_menu', all_conditions)
|
||
|
||
# 筛选匹配的二级菜单
|
||
level2_items = [item for item in all_result if item['menu_level'] == 2 and title in item.get('title', '')]
|
||
|
||
if level2_items:
|
||
parent_ids = set(item['id'] for item in level2_items)
|
||
|
||
# 获取对应的一级菜单
|
||
result = []
|
||
for item in all_result:
|
||
if item['menu_level'] == 1 and any(level2['parent_id'] == item['id'] for level2 in level2_items):
|
||
result.append(item)
|
||
|
||
# 添加匹配的二级菜单
|
||
result.extend(level2_items)
|
||
|
||
# 获取三级子菜单
|
||
for item in all_result:
|
||
if item['menu_level'] == 3 and item['parent_id'] in parent_ids:
|
||
result.append(item)
|
||
|
||
menu_tree = await build_menu_tree(result)
|
||
else:
|
||
menu_tree = []
|
||
|
||
elif menu_level == 3:
|
||
# 获取三级菜单
|
||
all_conditions = {"del_flg": "0"}
|
||
all_result = await sor.R('home_page_product_menu', all_conditions)
|
||
|
||
# 筛选匹配的三级菜单
|
||
level3_items = [item for item in all_result if item['menu_level'] == 3 and title in item.get('title', '')]
|
||
|
||
if level3_items:
|
||
result = []
|
||
|
||
# 获取对应的二级和一级菜单
|
||
level2_ids = set()
|
||
level1_ids = set()
|
||
|
||
for item in level3_items:
|
||
level2_ids.add(item['parent_id'])
|
||
|
||
for item in all_result:
|
||
if item['menu_level'] == 2 and item['id'] in level2_ids:
|
||
result.append(item)
|
||
level1_ids.add(item['parent_id'])
|
||
|
||
for item in all_result:
|
||
if item['menu_level'] == 1 and item['id'] in level1_ids:
|
||
result.append(item)
|
||
|
||
# 添加匹配的三级菜单
|
||
result.extend(level3_items)
|
||
|
||
menu_tree = await build_menu_tree(result)
|
||
else:
|
||
menu_tree = []
|
||
else:
|
||
return {
|
||
'status': False,
|
||
'msg': 'Invalid menu_level, must be 1, 2, or 3'
|
||
}
|
||
|
||
return {
|
||
'status': True,
|
||
'msg': 'search menu success',
|
||
'data': menu_tree
|
||
}
|
||
|
||
except Exception as e:
|
||
return {
|
||
'status': False,
|
||
'msg': 'search menu failed, %s' % str(e)
|
||
}
|
||
|
||
async def get_home_page_product(ns={}):
|
||
db = DBPools()
|
||
async with db.sqlorContext('kboss') as sor:
|
||
find_sql = """select * from home_page_product_info where menu_id = '%s' and del_flg = '0' order by sort_order asc;""" % ns.get("menu_id")
|
||
result = await sor.sqlExe(find_sql, {})
|
||
return result
|
||
|
||
# 构建菜单树形结构
|
||
async def build_menu_tree(menu_list, target_level=None, target_title=None):
|
||
"""
|
||
将扁平的菜单列表转换为树形结构
|
||
:param menu_list: 菜单列表
|
||
:param target_level: 目标层级(可选)
|
||
:param target_title: 目标标题(可选)
|
||
:return: 树形结构的菜单
|
||
"""
|
||
|
||
# 通过sort_order对菜单进行排序
|
||
menu_list.sort(key=lambda x: int(x['sort_order']), reverse=False)
|
||
|
||
menu_dict = {}
|
||
result = []
|
||
|
||
# 先创建所有菜单的字典
|
||
for menu in menu_list:
|
||
# 创建菜单节点的基本结构
|
||
menu_node = {
|
||
'id': menu['id'],
|
||
'title': menu['title'],
|
||
'menu_level': menu['menu_level'],
|
||
'parent_id': menu['parent_id'],
|
||
'children': [] # 动态子菜单数组
|
||
}
|
||
menu_dict[menu['id']] = menu_node
|
||
|
||
# 构建父子关系
|
||
for menu in menu_list:
|
||
menu_node = menu_dict[menu['id']]
|
||
parent_id = menu['parent_id']
|
||
|
||
# 如果有父级且父级存在
|
||
if parent_id and parent_id in menu_dict:
|
||
parent_node = menu_dict[parent_id]
|
||
parent_node['children'].append(menu_node)
|
||
else:
|
||
# 没有父级的菜单(根节点)
|
||
result.append(menu_node)
|
||
|
||
# 递归构建层级结构
|
||
async def build_hierarchy(node, level=1):
|
||
"""递归构建层级结构"""
|
||
if level == 1:
|
||
return {
|
||
'id': node['id'],
|
||
'firTitle': node['title'],
|
||
'secMenu': [await build_hierarchy(child, 2) for child in node['children']]
|
||
}
|
||
elif level == 2:
|
||
return {
|
||
'id': node['id'],
|
||
'secTitle': node['title'],
|
||
'thrMenu': [await build_hierarchy(child, 3) for child in node['children']]
|
||
}
|
||
else:
|
||
# 三级及以上
|
||
return {
|
||
'id': node['id'],
|
||
'thrTitle': node['title'],
|
||
'value': await get_home_page_product({'menu_id': node['id']}) # 三级菜单没有子菜单,value为空列表
|
||
}
|
||
|
||
# 构建最终的树形结构
|
||
final_result = []
|
||
for root_node in result:
|
||
final_result.append(await build_hierarchy(root_node))
|
||
|
||
return final_result
|
||
|
||
ret = await home_page_product_menu_search(params_kw)
|
||
return ret |