| | |
| | | using NewPdaSqlServer.DB; |
| | | using NewPdaSqlServer.DB; // 你的Repository基类所在的命名空间 |
| | | using NewPdaSqlServer.Dto.Simple; |
| | | using NewPdaSqlServer.entity; |
| | | using NewPdaSqlServer.entity; // 引用实体 |
| | | using SqlSugar; |
| | | |
| | | namespace NewPdaSqlServer.service.Simple; |
| | | |
| | | /// <summary> |
| | | /// 看板菜单业务管理器 |
| | | /// 实现与Java版本MesSimpleServiceImpl完全一致的业务逻辑 |
| | | /// </summary> |
| | | public class SimpleManager : Repository<MesSimple> |
| | | { |
| | | /// <summary> |
| | | /// 获取树形菜单 |
| | | /// 对应Java: getTree() |
| | | /// </summary> |
| | | /// <returns>树形菜单数据</returns> |
| | | public ResultDto<List<TreeViewDto>> GetTree() |
| | | { |
| | | try |
| | | { |
| | | var tree = ToTree(); |
| | | var allNodes = Db.Queryable<MesSimple>() |
| | | .Where(m => m.IsEnabled && !m.IsDeleted) |
| | | .OrderBy(m => m.SortOrder) |
| | | .ToList(); |
| | | |
| | | var tree = BuildTree(allNodes, null); |
| | | return ResultDto<List<TreeViewDto>>.Ok(tree, tree.Count); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return ResultDto<List<TreeViewDto>>.Error(ex.Message); |
| | | return ResultDto<List<TreeViewDto>>.Error("获取树形菜单失败: " + ex.Message); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 转换为树形结构 |
| | | /// 对应Java: toTree() |
| | | /// </summary> |
| | | /// <returns>树形视图列表</returns> |
| | | public List<TreeViewDto> ToTree() |
| | | private List<TreeViewDto> BuildTree(List<MesSimple> allNodes, long? parentId) |
| | | { |
| | | return ConvertToTreeViewList(GetTopList()); |
| | | return allNodes |
| | | .Where(x => x.ParentId == parentId) |
| | | .Select(x => new TreeViewDto |
| | | { |
| | | Id = x.Id, |
| | | Title = x.Title, |
| | | Field = x.Code, |
| | | Spread = x.IsExpanded, |
| | | Href = x.Url, |
| | | NodeType = x.NodeType, |
| | | Children = BuildTree(allNodes, x.Id) |
| | | }) |
| | | .ToList(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取菜单列表 |
| | | /// 对应Java: getMenuList() |
| | | /// 查询条件: disabled=0 且 isTop>0 (排除根节点) |
| | | /// </summary> |
| | | /// <returns>菜单列表</returns> |
| | | public ResultDto<List<MesSimpleDto>> GetMenuList() |
| | | { |
| | | try |
| | | { |
| | | var list = Db.Queryable<MesSimple>() |
| | | .Where(m => m.Disabled == 0 && m.IsTop > 0) |
| | | .Where(m => m.IsEnabled && !m.IsDeleted) |
| | | .OrderBy(m => m.SortOrder) |
| | | .Select(m => new MesSimpleDto |
| | | { |
| | | Id = m.Id, |
| | | IsTop = m.IsTop, |
| | | Fid = m.Fid, |
| | | ParentId = m.ParentId, |
| | | NodeType = m.NodeType, |
| | | NodeLevel = m.NodeLevel, |
| | | Code = m.Code, |
| | | Title = m.Title, |
| | | Field = m.Field, |
| | | Href = m.Href, |
| | | Spread = m.Spread, |
| | | Disabled = m.Disabled, |
| | | Lbtime = m.Lbtime |
| | | Url = m.Url, |
| | | CarouselDuration = m.CarouselDuration, |
| | | IsExpanded = m.IsExpanded, |
| | | IsEnabled = m.IsEnabled, |
| | | SortOrder = m.SortOrder |
| | | }) |
| | | .ToList(); |
| | | |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据菜单ID获取BI视图列表 |
| | | /// 对应Java: getBiViewsByMenuId() |
| | | /// 根据ID获取视图列表 |
| | | /// 逻辑升级: |
| | | /// 1. 先找子节点 (轮播模式) |
| | | /// 2. 如果没子节点,但自己有URL (单页模式),则返回自己 |
| | | /// </summary> |
| | | /// <param name="menuId">菜单ID</param> |
| | | /// <returns>BI视图列表</returns> |
| | | public ResultDto<List<BiViewDto>> GetBiViewsByMenuId(int menuId) |
| | | public ResultDto<List<BiViewDto>> GetBiViewsByMenuId(long menuId) |
| | | { |
| | | try |
| | | { |
| | | // 查询指定菜单下的所有BI视图 |
| | | var list = Db.Queryable<MesSimpleCcb>() |
| | | .Where(b => b.Pid == menuId && b.Href != null) |
| | | .Select(b => new BiViewDto |
| | | // 1. 首先查询点击的这个节点本身 (必须是启用且未删除) |
| | | var selfNode = Db.Queryable<MesSimple>() |
| | | .First(m => m.Id == menuId && m.IsEnabled && !m.IsDeleted); |
| | | |
| | | if (selfNode == null) return ResultDto<List<BiViewDto>>.Error("该节点不存在或已禁用"); |
| | | |
| | | // 安全检查:如果前端传了 NodeType=0 的 ID 进来,这里拦截 |
| | | if (selfNode.NodeType == 0) return ResultDto<List<BiViewDto>>.Error("目录节点不可直接预览"); |
| | | |
| | | // 2. 判断自己是否有 URL |
| | | // 排除空值和占位符 "轮播" |
| | | if (!string.IsNullOrEmpty(selfNode.Url) && selfNode.Url != "轮播") |
| | | { |
| | | Id = b.Id, |
| | | Pid = b.Pid, |
| | | Name = b.Name, |
| | | Href = b.Href, |
| | | Lbtime = b.Lbtime |
| | | }) |
| | | var selfView = new BiViewDto |
| | | { |
| | | Id = selfNode.Id, |
| | | ParentId = selfNode.ParentId, |
| | | Title = selfNode.Title, |
| | | Url = selfNode.Url, |
| | | Duration = (selfNode.CarouselDuration == null || selfNode.CarouselDuration <= 0) ? 10 : selfNode.CarouselDuration |
| | | }; |
| | | return ResultDto<List<BiViewDto>>.Ok(new List<BiViewDto> { selfView |
| | | }, 1); |
| | | } |
| | | |
| | | // 3. 自己没有 URL,查找子目录/子项 |
| | | // 查询 ParentId = menuId 且类型为 2 的子项 |
| | | var childNodes = Db.Queryable<MesSimple>() |
| | | .Where(b => b.ParentId == menuId && b.NodeType == 2 && b.IsEnabled && !b.IsDeleted) |
| | | .OrderBy(b => b.SortOrder) |
| | | .ToList(); |
| | | |
| | | // 如果有数据,获取父菜单的轮播时间配置并赋值给所有BI视图 |
| | | if (list.Count > 0) |
| | | if (childNodes.Count > 0) |
| | | { |
| | | var simple = Db.Queryable<MesSimple>() |
| | | .Where(m => m.Id == menuId) |
| | | .First(); |
| | | var resultList = childNodes.Select(b => new BiViewDto |
| | | { |
| | | Id = b.Id, |
| | | ParentId = b.ParentId, |
| | | Title = b.Title, |
| | | Url = b.Url, |
| | | // 子项如果没时间,继承当前 menuId 节点的时间配置 |
| | | Duration = (b.CarouselDuration == null || b.CarouselDuration <= 0) |
| | | ? (selfNode.CarouselDuration ?? 10) |
| | | : b.CarouselDuration |
| | | }).ToList(); |
| | | |
| | | if (simple != null) |
| | | { |
| | | // 将父菜单的lbtime赋值给所有BI视图 |
| | | list.ForEach(biView => biView.Lbtime = simple.Lbtime); |
| | | } |
| | | return ResultDto<List<BiViewDto>>.Ok(resultList, resultList.Count); |
| | | } |
| | | |
| | | return ResultDto<List<BiViewDto>>.Ok(list, list.Count); |
| | | // 4. 自己没 URL 且 子项也没 URL |
| | | // 返回空列表,前端 bi_view.html 收到后会弹出“当前菜单下没有可轮播的内容” |
| | | return ResultDto<List<BiViewDto>>.Ok(new List<BiViewDto>(), 0); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return ResultDto<List<BiViewDto>>.Error(ex.Message); |
| | | return ResultDto<List<BiViewDto>>.Error("数据查询失败: " + ex.Message); |
| | | } |
| | | } |
| | | |
| | | #region 私有方法 |
| | | |
| | | /// <summary> |
| | | /// 获取根节点列表 |
| | | /// 查询条件: isTop=0 且 disabled=0 |
| | | /// </summary> |
| | | /// <returns>根节点列表</returns> |
| | | private List<MesSimple> GetTopList() |
| | | { |
| | | return Db.Queryable<MesSimple>() |
| | | .Where(m => m.IsTop == 0 && m.Disabled == 0) |
| | | .ToList(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 转换为树形视图列表 |
| | | /// 对应Java: convertToTreeViewList() |
| | | /// 使用并行处理提升性能 |
| | | /// </summary> |
| | | /// <param name="mesSimpleList">根节点列表</param> |
| | | /// <returns>树形视图列表</returns> |
| | | private List<TreeViewDto> ConvertToTreeViewList(List<MesSimple> mesSimpleList) |
| | | { |
| | | // 使用Parallel.ForEach实现并行处理,类似Java的CompletableFuture |
| | | var treeViews = new List<TreeViewDto>(); |
| | | var lockObj = new object(); |
| | | |
| | | Parallel.ForEach(mesSimpleList, mesSimple => |
| | | { |
| | | var treeView = ConvertToTreeView(mesSimple); |
| | | lock (lockObj) |
| | | { |
| | | treeViews.Add(treeView); |
| | | } |
| | | }); |
| | | |
| | | return treeViews; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 转换单个菜单项为树形视图 |
| | | /// 对应Java: convertToTreeView() |
| | | /// </summary> |
| | | /// <param name="mesSimple">菜单实体</param> |
| | | /// <returns>树形视图</returns> |
| | | private TreeViewDto ConvertToTreeView(MesSimple mesSimple) |
| | | { |
| | | var treeView = new TreeViewDto |
| | | { |
| | | Id = mesSimple.Id, |
| | | Title = mesSimple.Title, |
| | | Field = mesSimple.Field, |
| | | Spread = mesSimple.Spread == 1 |
| | | }; |
| | | |
| | | // 查询子节点 |
| | | var childList = Db.Queryable<MesSimple>() |
| | | .Where(m => m.Disabled == 0 && m.Fid == mesSimple.Id) |
| | | .ToList(); |
| | | |
| | | // 转换子节点 |
| | | var childrenList = new List<ChildrenDto>(); |
| | | foreach (var child in childList) |
| | | { |
| | | var children = new ChildrenDto |
| | | { |
| | | Id = child.Id, |
| | | Title = child.Title, |
| | | Field = child.Field |
| | | }; |
| | | |
| | | // 处理href字段 |
| | | // 如果href值为"轮播",则自动生成轮播页面链接 |
| | | if ("轮播".Equals(child.Href)) |
| | | { |
| | | children.Href = $"bi_view.html?menuId={child.Id}&lbsj={child.Lbtime}"; |
| | | } |
| | | else |
| | | { |
| | | children.Href = child.Href; |
| | | } |
| | | |
| | | childrenList.Add(children); |
| | | } |
| | | |
| | | treeView.Children = childrenList; |
| | | |
| | | return treeView; |
| | | } |
| | | |
| | | #endregion |
| | | } |