08
2017
03

.Net Core MVC 网站开发(Ninesky) 2.5、修改和删除栏目

这段时间懒了一下,算下时间两个多月没写博客了,过完年之后一直状态没调整过来。上班时间不好写,下了班要陪孩子写作业,时间真的很少。这几天总算熬夜写了一篇。

这篇的工作是完成栏目的修改和删除,删除比较简单,主要是修改栏目涉及的较逻辑教多。

写之前也画了一个流程图。

修改栏目.png

修改栏目流程图

删除的流程图。

实际写代码的时候并没有完全按照流程图的写,但思路还是按这个来的。下面写下主要的做法,详细的还是看代码吧。


 

一、修改栏目


1、方法操作结果(OperationResult)

OperationResult类有Succeed、Code、Message、Data四个属性,分别表示操作是否成功,操作结果的代码,结果的消息提示和返回的数据。常用的就Succeed和Message,Data做好少用,因为是dynamic类型,使用起来肯定影响性能。

在 Ninesky.Models项目中右键添加类OperationResult,代码如下:

using System.Collections.Generic; namespace Ninesky.Models {     /// <summary>     /// 方法操作结果     /// </summary>     public class OperationResult     {         /// <summary>         /// 操作是否成功         /// </summary>         public bool Succeed { get; set; }         /// <summary>         /// 操作结果详细代码【必要时】         /// </summary>         public int Code { get; set; }         /// <summary>         /// 操作结果消息         /// </summary>         public string Message { get; set; }         /// <summary>         /// 操作产生的数据【必要时,慎用-会降低性能】         /// </summary>         public dynamic Data { get; set; }         public OperationResult()         {             Succeed = false;             Message = "未知错误";         }     } }

2、重写更新方法

因为接口基类nterfaceBaseService中定义了更新栏目代码,只需要在实现类中重写该方法。

打开打开Ninesky.Base\CategoryService.cs。重写更新栏目的方法实现。

        /// <summary>
        /// 更新栏目
        /// </summary>
        /// <param name="entity">栏目实体</param>
        /// <param name="isSave">立即保存</param>
        /// <returns></returns>
        public override async Task<OperationResult> UpdateAsync(Category category, bool isSave = true)
        {
            var oResult = new OperationResult() { Succeed = true, Message = "更新成功栏目" };
            var originalCategory = await FindAsync(category.CategoryId);
            //修改的栏目是否存在
            if (originalCategory == null)
            {
                oResult.Succeed = false;
                oResult.Message = "栏目不存在,请确认栏目【" + category.Name + "】是否已被删除?";
            }
            else
            {
                //父栏目是否更改
                if (category.ParentId != originalCategory.ParentId)
                {
                    var parentCategory = await FindAsync(category.ParentId);
                    if(parentCategory ==null)
                    {
                        oResult.Succeed = false;
                        oResult.Message = "父栏目不存在";
                    }
                    var canParentResult = CanParent(parentCategory, originalCategory);
                    if (canParentResult.Succeed)
                    {
                        if (category.ParentId == 0)
                        {
                            originalCategory.ParentId = category.ParentId;
                            originalCategory.ParentPath = "0";
                        }
                        else
                        {
                            originalCategory.ParentId = category.ParentId;
                            originalCategory.ParentPath = parentCategory.ParentPath + "," + parentCategory.CategoryId;
                        }
                    }
                    else
                    {
                        oResult.Succeed = false;
                        oResult.Message = canParentResult.Message;
                    }
                }
                //栏目类型是否更改
                if (oResult.Succeed && category.Type != originalCategory.Type)
                {
                    originalCategory.Type = category.Type;
                    //原栏目类型是否常规栏目
                    if (originalCategory.Type == CategoryType.General)
                    {
                        //栏目是否设置了内容
                        if (originalCategory.General.ModuleId > 0)
                        {
                            ModuleService moduleService = new ModuleService(this._dbContext);
                            var moduleId = (await FindAsync((int)originalCategory.General.ModuleId)).General.ModuleId;
                            var controller = (await moduleService.FindAsync((int)moduleId)).Controller;
                            switch (controller)
                            {
                                case "Article":
                                    //此栏目是否有内容
                                   break;
                            }
                            //***此处位置是否恰当
                            await moduleService.RemoveAsync(new Module { ModuleId = (int)originalCategory.General.ModuleId }, false);
                        }
                    }
                }
                switch (category.Type)
                {
                    case CategoryType.General:
                        if (category.General == null)
                        {
                            oResult.Succeed = false;
                            oResult.Message = "请填写常规栏目内容。";
                        }
                        else
                        {
                            if (category.General.ModuleId > 0)
                            {
                                if (string.IsNullOrEmpty(category.General.ContentView))
                                {
                                    oResult.Succeed = false;
                                    oResult.Message = "请填写栏目视图。";
                                }
                                else if (category.General.ContentOrder == null)
                                {
                                    oResult.Succeed = false;
                                    oResult.Message = "请选择内容排序方式";
                                }
                            }
                            else
                            {
                                if (originalCategory.General == null) originalCategory.General = category.General;
                                else
                                {
                                    originalCategory.General.ContentOrder = category.General.ContentOrder;
                                    originalCategory.General.ContentView = category.General.ContentView;
                                    originalCategory.General.CategoryId = originalCategory.CategoryId;
                                    originalCategory.General.ModuleId = category.General.ModuleId;
                                }
                                if (originalCategory.Page != null) originalCategory.Page = null;
                                if (originalCategory.Link != null) originalCategory.Link = null;
                            }
                        }
                        break;
                    case CategoryType.Page:

                        //检查
                        if (category.Page == null)
                        {
                            oResult.Succeed = false;
                            oResult.Message = "请填写单页栏目内容";
                        }
                        else
                        {
                            if (string.IsNullOrEmpty(category.Page.Content))
                            {
                                oResult.Succeed = false;
                                oResult.Message = "请输入单页栏目内容";
                            }
                            else
                            {
                                if (originalCategory.Page == null) originalCategory.Page = category.Page;
                                else
                                {
                                    originalCategory.Page.Content = category.Page.Content;  
                                }
                                if (originalCategory.General != null) originalCategory.General = null;
                               if (originalCategory.Link != null) originalCategory.Link = null;
                            }
                        }
                        break;
                    case CategoryType.Link:
                        //检查
                        if (category.Link == null)
                        {
                            oResult.Succeed = false;
                            oResult.Message = "请填写连接栏目内容";
                        }
                        else
                        {
                            if (string.IsNullOrEmpty(category.Link.Url))
                            {
                                oResult.Succeed = false;
                               oResult.Message = "请选择输入链接地址";
                            }
                            else
                            {
                                if (originalCategory.Link == null) originalCategory.Link = category.Link;
                                else
                                {
                                    originalCategory.Link.Url = category.Link.Url;
                                }
                                if (category.General != null) category.General = null;
                                if (category.General != null) category.General = null;
                            }
                        }
                        break;
                }
            }
            if (oResult.Succeed)
            {
                originalCategory.Name = category.Name;
                originalCategory.Order = category.Order;
                originalCategory.Target = category.Target;
                originalCategory.View = category.View;
                originalCategory.Description = category.Description;
                oResult = await base.UpdateAsync(originalCategory);
            }
            return oResult;

        }

 3、控制器

打开Ninesky.Web\Areas\System\Controllers\CategoryController.cs。添加栏目详细信息的action。

        public async Task<IActionResult> Details([FromServices]InterfaceModuleService moduleService, int id)
        {
            var modules = await moduleService.FindListAsync(true);
            var modeleArry = modules.Select(m => new SelectListItem { Text = m.Name, Value = m.ModuleId.ToString() }).ToList();
            modeleArry.Insert(0, new SelectListItem() { Text = "无", Value = "0", Selected = true });
            ViewData["Modules"] = modeleArry;
            return View(await _categoryService.FindAsync(id));
        }

4、添加视图

这个视图和添加栏目非常类似,直接参考改动一下就可以。

@model Ninesky.Models.Category
@{
    ViewData["Title"] = Model.Name;
}
<ol class="breadcrumb">
    <li><span class="fa fa-home"></span>  <a asp-controller="Home" asp-action="Index">首页</a></li>
    <li><a asp-controller="Category" asp-action="Index">栏目管理</a></li>
    <li class="active">@Model.Name</li>
</ol>
<div class="panel panel-default">
    <div class="panel-body">
        <form asp-action="Details">
            <div class="form-horizontal">
                <div asp-validation-summary="All" class="text-danger"></div>
                <ul class="nav nav-tabs" role="tablist">
                    <li role="presentation" class="active"><a href="#base" role="tab" data-toggle="tab">基本信息</a></li>
                    <li role="presentation"><a href="#general" role="tab" data-toggle="tab">常规栏目</a></li>
                    <li role="presentation"><a href="#page" role="tab" data-toggle="tab">单页栏目</a></li>
                    <li role="presentation"><a href="#link" role="tab" data-toggle="tab">链接栏目</a></li>
                </ul>
                <input asp-for="CategoryId" type="hidden" />
                <!-- Tab panes -->
                <div class="tab-content">
                    <div role="tabpanel" class="tab-pane active" id="base">
                        <div class="form-group">
                            <label asp-for="ParentId" class="col-md-2 control-label"></label>
                            <div class="col-md-10">
                                <div class="input-group" style="width:280px;">
                                    <input id="ParentId-text" type="text" class="form-control" readonly value="无" />
                                    <ul id="ParentId-dropdown" class="dropdown-menu dropdown-menu-left ztree"></ul>
                                    <div class="input-group-btn">
                                        <button id="ParentId-btn" type="button" class="btn btn-default"><span class="caret"></span></button>
                                    </div>
                                    <input asp-for="ParentId" class="form-control" style="width:0; visibility:hidden; position:absolute;padding:0" data-url="@Url.Action("ParentTree", "Category")" />
                                </div>
                                <span asp-validation-for="ParentId" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label asp-for="Type" class="col-md-2 control-label"></label>
                            <div class="col-md-10">
                                <select asp-for="Type" asp-items="Html.GetEnumSelectList<Ninesky.Models.CategoryType>()" class="selectpicker form-control" data-style="btn-dropdown"></select>
                                <span asp-validation-for="Type" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label asp-for="Name" class="col-md-2 control-label"></label>
                            <div class="col-md-10">
                                <input asp-for="Name" class="form-control" />
                                <span asp-validation-for="Name" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label asp-for="View" class="col-md-2 control-label"></label>
                            <div class="col-md-10">
                                <input asp-for="View" class="form-control" />
                                <span asp-validation-for="View" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label asp-for="Order" class="col-md-2 control-label"></label>
                            <div class="col-md-10">
                                <input asp-for="Order" class="form-control" />
                                <span asp-validation-for="Order" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label asp-for="Target" class="col-md-2 control-label"></label>
                            <div class="col-md-10">
                                <select asp-for="Target" asp-items="Html.GetEnumSelectList<Ninesky.Models.LinkTarget>()" class="selectpicker form-control" data-style="btn-dropdown"></select>
                                <span asp-validation-for="Target" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label asp-for="Description" class="col-md-2 control-label"></label>
                            <div class="col-md-10">
                                <textarea asp-for="Description" class="form-control"></textarea>
                                <span asp-validation-for="Description" class="text-danger"></span>
                            </div>
                        </div>
                    </div>
                    <div role="tabpanel" class="tab-pane" id="general">
                        <div class="form-group">
                            <label asp-for="General.ModuleId" class="col-md-2 control-label"></label>
                            <div class="col-md-10">
                                <select asp-for="General.ModuleId" asp-items="@ViewData["Modules"] as List<SelectListItem>" class="selectpicker form-control" data-style="btn-dropdown"></select>
                                <span asp-validation-for="General.ModuleId" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label asp-for="General.ContentView" class="col-md-2 control-label"></label>
                            <div class="col-md-10">
                                <input asp-for="General.ContentView" class="form-control" />
                                <span asp-validation-for="General.ContentView" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label asp-for="General.ContentOrder" class="col-md-2 control-label"></label>
                            <div class="col-md-10">
                                <select asp-for="General.ContentOrder" class="form-control" data-url="@Url.Action("OrderList","Module")"></select>
                                <span asp-validation-for="General.ContentOrder" class="text-danger"></span>
                            </div>
                        </div>
                    </div>
                    <div role="tabpanel" class="tab-pane" id="page">
                        <div class="form-group">
                            <label asp-for="Page.Content" class="control-label"></label>
                            
                                <textarea asp-for="Page.Content" ></textarea>
                                <span asp-validation-for="Page.Content" class="text-danger"></span>
                            
                        </div>
                    </div>
                    <div role="tabpanel" class="tab-pane" id="link">
                        <div class="form-group">
                            <label asp-for="Link.Url" class="col-md-2 control-label"></label>
                            <div class="col-md-10">
                                <input asp-for="Link.Url" class="form-control" />
                                <span asp-validation-for="Link.Url" class="text-danger"></span>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-md-offset-2 col-md-10">
                        <input type="submit" value="修改" class="btn btn-default" />
                        <input id="btn_del" data-value="@Model.CategoryId" data-action="@Url.Action("Delete","Category")" type="button" value="删除" class="btn btn-danger" />
                    </div>
                </div>
            </div>
        </form>
    </div>
</div>
@section aside{
    @Html.Partial("Aside")
}
@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    <script src="~/lib/ueditor/ueditor.config.js"></script>
    <script src="~/lib/ueditor/ueditor.all.min.js"></script>
    <script src="~/Areas/System/Category/Details.js"></script>
}

5、修改的接收处理action

[HttpPost]

        public async Task<IActionResult> Details([FromServices]InterfaceModuleService moduleService, Category category)

        {

            //模型验证是否通过

            if (ModelState.IsValid)

            {

                var oResult = await _categoryService.UpdateAsync(category);

                if (oResult.Succeed) return View("UpdateSucceed", category);

                else ModelState.AddModelError("", oResult.Message);

            }

            var modules = await moduleService.FindListAsync(true);

            var modeleArry = modules.Select(m => new SelectListItem { Text = m.Name, Value = m.ModuleId.ToString() }).ToList();

            modeleArry.Insert(0, new SelectListItem() { Text = "无", Value = "0", Selected = true });

            ViewData["Modules"] = modeleArry;

            return View(category);

        }

6、修改成功的视图(UpdateSucceed)

在区域的views\category\下添加UpdateSucceed视图

@model Ninesky.Models.Category
@{
    ViewData["Title"] = "修改栏目";
}
<ol class="breadcrumb">
    <li><span class="fa fa-home"></span>  <a asp-controller="Home" asp-action="Index">首页</a></li>
    <li><a asp-controller="Category" asp-action="Index">栏目管理</a></li>
    <li class="active">修改栏目</li>
</ol>
<div class="alert alert-success fade in" role="alert">
    <h4><i class="fa fa-check"></i> 修改成功 </h4>
    <p>[email protected]</p>
    <p>
        <a href="@Url.Action("Add")" class="btn btn-default">添加栏目</a>
        <a href="@Url.Action("Details","Category",new {id=Model.CategoryId })" class="btn btn-default">修改栏目</a>
    </p>
</div>
@section aside{
    @Html.Partial("Aside")
}

二、删除栏目

因为删除栏目使用的jquery的post提交,为了返回的时候不能能知道是否成功,还希望返回操作结果的提示,需要添加一个返回类型。另外在删除栏目的时候如果栏目类型为常规栏目首先要检测一下栏目是否有子栏目,还要加一个判断是否有子栏目的方法。


1、接口

打开Ninesky.InterfaceBase\InterfaceCategoryService.cs。

  • 添加判断是否有子栏目的方法

/// <summary>        /// 是否存在子栏目        /// </summary>        /// <param name="id">栏目ID</param>        /// <returns></returns>        Task<bool> HasChildren(int id);

  • 添加删除栏目方法

/// <summary>        /// 删除栏目        /// </summary>        /// <param name="id">栏目Id</param>        /// <returns></returns>        Task<OperationResult> RemoveAsync(int id);

2、实现

打开Ninesky.Base\CategoryService.cs

  • 添加判断是否有子栏目方法的实现

/// <summary>        /// 是否存在子栏目        /// </summary>        /// <param name="id">栏目ID</param>        /// <returns></returns>        public async Task<bool> HasChildren(int id)        {            return await ExistsAsync(c => c.ParentId == id);        }

  • 添加删除栏目方法的实现

/// <summary>         /// 删除子栏目         /// </summary>         /// <param name="id">栏目ID</param>         /// <returns></returns>         public async Task<OperationResult> RemoveAsync(int id)         {             OperationResult opResult = new OperationResult();             Category category = await FindAsync(id);             switch (category.Type)             {                 case CategoryType.General:                     if (await HasChildren(id))                     {                         opResult.Succeed = false;                         opResult.Message = "请先删除子栏目";                         return opResult;                     }                     if (category.General != null)                     {                         if (category.General.ModuleId != null && category.General.ModuleId > 0)                         {                             ModuleService moduleService = new ModuleService(this._dbContext);                             await moduleService.RemoveAsync(new Module() { ModuleId = (int)category.General.ModuleId }, false);                         }                         CategoryGeneralService gengralService = new CategoryGeneralService(this._dbContext);                         await gengralService.RemoveAsync(category.General, false);                     }                     break;                 case CategoryType.Page:                     if (category.Page != null)                     {                         CategoryPageService pageService = new CategoryPageService(this._dbContext);                         await pageService.RemoveAsync(category.Page, false);                     }                     break;                 case CategoryType.Link:                     if (category.Link != null)                     {                         CategoryLinkService linkService = new CategoryLinkService(this._dbContext);                         await linkService.RemoveAsync(category.Link, false);                     }                     break;             }             opResult.Succeed = await RemoveAsync(category);             if (opResult.Succeed) opResult.Message = "删除栏目成功";             return opResult;         }

 3、视图

删除的操作方式是在修改页面有个删除按钮,点击对话框弹出确认框,确认后使用jquery的post方法向后台提交。删除没有单独的页面,功能通过一串js代码实现

 //删除事件

        $("#btn_del").click(function () {

            BootstrapDialog.confirm({

                title: '提示',

                message: '确认删除栏目',

                type: BootstrapDialog.TYPE_DANGER, 

                closable: true,

                draggable: true,

                btnOKLabel: '确定',

                btnCancelLabel: '取消',

                btnOKClass: 'btn-danger',

                callback: function (result) {

                    if (result) {

                        $.post($("#btn_del").attr("data-action"), { id: $("#btn_del").attr("data-value") }, function (data) {

                            if (data != undefined) {

                                if (data.succeed == true) {

                                    BootstrapDialog.alert({ title: "成功", message: data.message, callback: function () { location.href = "/System/Category"; } });

                                }

                                else BootstrapDialog.alert({ title: "失败", message: data.message });

                            }

                            else BootstrapDialog.alert({ title: "消息", message: "请求失败" });

                        }, 'json');

                    }

                }

            });

            

        });

四、其他

 

代码托管地址:https://git.oschina.net/ninesky/Ninesky

文章发布地址:http://www.ninesky.cn

                 http://mzwhj.cnblogs.com/

代码包下载:Ninesky2.5.rar

返回目录

« 上一篇下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。