• CMS内容管理


    CMS内容管理中,类别是很重要的一部,特别是多级分类的,理论上是可以建立无限级别的,当然实际使用中最多到3-4级也就很多了。本文主要从数据库的角度介绍类别的管理的核心算法,SQL有了,对SQL的执行还难吗?

    先看演示   http://portal.dotnetcms.org/ep/portal/admin/Addeditcategory.aspx (如果需要登录,用户名是admin, 密码是123456)

    (全站演示:http://portal.dotnetcms.org 登陆后即可看到管理中心)

    要构建无限级别菜单,需要有两个核心ID,一个是本分类的ID,一个该ID的父ID--parentID,除此以外,可以增加类别的额外信息,例如名称,显示顺序等

    为此,在Dotnetcms里建立了portal_category表(说明:这里分类参考了博客园里一个博主的文章,找了半天也没有找到是谁写的)

    代码


    CREATE TABLE [dbo].[portal_category](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [catname] [nvarchar](50) NULL,
    [parentid] [int] NULL,
    [orderid] [int] NULL,
    [depth] [int] NULL,
    [fullpathname] [nvarchar](300) NULL,
    [fullids] [nvarchar](150) NULL,
    [url] [nvarchar](200) NULL,
    [haschild] [int] NULL,
    [path] [nvarchar](1000) NULL,
    [target] [nvarchar](50) NULL,
    CONSTRAINT [PK_portal_category] PRIMARY KEY CLUSTERED
    (
    [id] ASC
    )
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    )
    ON [PRIMARY]

    GO


     接下来就可以对类别进行增删读写,不在话下。

    然而,类别的管理并不仅仅如此简单,

    首先,介绍类别的移动(这里的移动是手动选择类别的子类别,不支持鼠标拖动),DEMO体验: http://portal.dotnetcms.org/ep/portal/admin/Mgrcategory.aspx

    在实际使用中,当用户把一个类别移动到另外一个类别时,需要考虑如何更新子类别,因为一个类别可能还有子类别,移动后,除了新类别增加了子类,还需要删除旧类别的子类

    为此,我们在photoes_category里增加了数据库的冗余字段path,这有两个好处,利用path字段存储类别的等级,Path存储类别的值类似A,AB,ABC;   B,BC,BCD等类似这样的信息,所以如果你需要获得某个类别下的字类别,只要使用 

    ALTER Proc [dbo].[sp_portal_GetSubCategory](
    @path nvarchar(20)
    )
    as
    Begin
    select * from Catalog where path like @path+'%'
    End


    即可,另外一个好处,会提高访问系统性能,毕竟执行一下上一个SQL语句,比循环递归计算一个节点的的子节点快

    接下来就可以写SQL语句,来更新类别了


    /****** Object: StoredProcedure [dbo].[sp_portal_movecategory] Script Date: 05/08/2010 09:36:17 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO

    ALTER PROCEDURE [dbo].[sp_portal_movecategory]
    (
    @ParentID int,--新父节点
    @CataID int,--要移动的节点编号
    @CataPath varchar(20) output,--新移动后的节点路径
    @orderid int,
    @catname nvarchar(200),
    @url nvarchar(500)

    )
    AS

    if not exists(select 1 from portal_category where ID = @ParentID)
    begin
    update portal_category set orderid=@orderid , catname=@catname, url=@url where id=@cataid
    set @CataPath = '' -- 如果新父节点不存在,

    end
    else
    begin

    declare @oldParentID int -- 原来的父节点
    select @oldParentID = ParentID from portal_category where ID = @CataID
    if @oldParentID = @ParentID -- 没有移动
    begin
    update portal_category set orderid=@orderid , catname=@catname, url=@url where id=@cataid
    select @CataPath = path from portal_category where ID = @CataID

    end
    else
    begin

    declare @pathLength int
    declare @path varchar(20)
    select @path = max(Path) from portal_category where parentID =@parentId --order by Path desc
    select @pathLength = len(@path)
    print @pathLength
    declare @newpath varchar(20)-- 计算移动到新分类后的节点路径
    if @pathLength > 0 -- 已经存在该父类
    select @newpath = substring(@path,1,@pathLength -1)+CHAR(ASCII(REVERSE(@path))+1)
    else
    select @newpath = path + 'A' from portal_category where ID = @parentID

    if len(@newpath) > 0
    begin
    declare @oldPath varchar(20)-- 记录原来的节点路径
    select @oldPath = Path from portal_category where ID = @CataID
    set @CataPath = @newpath;
    update portal_category set orderid=@orderid, catname=@catname, url=@url, ParentID = @ParentID,Path = @newpath where ID = @CataID
    -- 替换子类的Path
    update portal_category set Path = stuff(path,1,len(@oldPath),@CataPath) where Path like @oldPath+'%'
    end
    else
    set @CataPath = ''
    end
    end






    有了类别的添加,更新(包括类别的移动),接下来就要显示类别了,对于无限分级的列表,唯一合适的控件,应该就是Treeview了

    TreeView空间使用起来比较简单,首先需要获取数据源,因此我们建立一个递归方法


    public static void CreateTreeViewRecursive(TreeNodeCollection nodes, DataTable dataSource, int parentid)
    {
    string filter;
    filter
    = string.Format("parentid={0}", parentid); //从0开始,可以自设
    DataRow[] drarr = dataSource.Select(filter);
    TreeNode node;
    foreach (DataRow dr in drarr)
    {
    node
    = new TreeNode();

    node.Text
    = (string)dr["catname"];
    node.Value
    = dr["id"].ToString();
    node.NavigateUrl
    = "addeditcategory.aspx?id="+dr["id"].ToString();
    node.Target
    = "_blank";
    nodes.Add(node);
    CreateTreeViewRecursive(node.ChildNodes, dataSource,
    int.Parse(node.Value));
    }

    }

    来从数据库里读取类别信息

    接下来在PageLoad里绑定数据源即可


    if (!Page.IsPostBack)
    {

    DataSet ds
    = 执行 select * from portal_category order by orderid 语句返回DataSet

    CreateTreeViewRecursive(TreeView1.Nodes, ds.Tables[
    0], 0);

    }

    页面前台很简单,一句话就 OK

       

    <asp:TreeView runat="server"
    ShowLines
    ="true"
    ID
    ="TreeView1"></asp:TreeView>

    这样,一个无限级类别的分类管理就完成了

    ----------------------------------------------------------------------------------------------------------------------------

     

    Dotnetcms Portal集CMS与部分OA于一体,致力于企业内网建立,Dotnetcms Portal由一些列插件组成,Demo演示  http://portal.dotnetcms.org 

    会议室预定系统插件:demo演示 http://demo.dotnetcms.org/dotnetcms 可以预定会议室

    Survey调查插件: demo演示: http://demo.dotnetcms.org/survery/admin/step0.aspx  可以当不懂技术的员工制作问卷调查

    ...更多插件,您可以访问 http://www.dotnetcms.org/bbs/ 了解更多

    http://www.cnblogs.com/mqingqing123/archive/2010/05/08/1730309.html

  • 相关阅读:
    Dbzoj#3188. [Coci 2011]Upit
    P1903 [国家集训队]数颜色 带修改莫队板子
    P2045 方格取数加强版
    P1402 酒店之王
    P4151 [WC2011]最大XOR和路径
    Orz YYB!
    Atcoder2167 Blackout
    P2939 [USACO09FEB]改造路Revamping Trails
    博弈论简单入门sb总结
    P3592 [POI2015]MYJ
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1747380.html
Copyright © 2020-2023  润新知