kboss/b/product/home_page_product_menu_search.dspy
2025-11-27 18:00:11 +08:00

229 lines
8.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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