ASP.NET MVC4+BootStrap 实战(十三)

最近公司来了一个陕北的实习妹子,据说家里是开矿的,人长得一般,但很有气质。开矿的,当然钱很多了。以前在大学有个同学,家里是开油田的,有节毛概课,老师说西安的房价都是陕北人轰起来的,西安人都怨陕北人。我这个同学听了不开心了,周末直接在东西南北各买一套。牛逼啊,让你老师多嘴。这几天周围的同事心思都在这个姑娘身上,装作喝咖啡过去瞄一眼,或者站起来瞅瞅背影。IT爷们真的是空虚,IT界无美女啊,还是吉日嘎啦说的好,公司有美女,可以提升爷们的战斗力。

OK,今天我们来看一下新闻审核界面,本来这节是要说ueditor上传图片到mongoDB,但是最近实在精力有限,先放放,稍后再上博客。我们先看一下界面,提提神。

这个界面上面部分是查询,采用响应式布局方式。当在手机或者pad的浏览器上的时候,依然能够正常显示并使用。

OK,我们今天主要看的不是界面,还是看功能的实现。

首先先看一下查询功能,查询有个新闻类别的下拉列表,后台Action代码如下

[HttpGet]
public JsonResult GetNewsTypeList()
{
    List<NewsTypesEntity> newsTypeEntityList = NewsMngBiz.GetInstance().GetNewsTypes();
    newsTypeEntityList.Insert(0, new NewsTypesEntity() { TransactionNumber = null, NewsTypeName = CommonResouce.DefaultSelectText });
    return Json(newsTypeEntityList, JsonRequestBehavior.AllowGet);
}

OK,接下来我们就要看界面了

@{
    Layout = null;
}
<div ng-app="newsAuditModule" ng-controller="newsAuditController" id="div_newsAudit" class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">
            <img class="img-panel-title" src="~/Images/Base/audit.png" />
            <b>新闻审核</b>
        </h3>
    </div>
    <div class="panel-body">
        <div class="row" style="line-height:30px">
            <label for="newsTitle" class="col-sm-2 control-label">新闻标题</label>
            <div class="col-sm-10">
                <input type="text" maxlength="100" class="form-control" id="newsTitle" ng-model="newsTitle"
                       placeholder="请输入新闻标题查询">
            </div>
        </div>
        <div class="row" style="margin-top: 5px; margin-bottom: 5px; line-height: 30px">
            <label for="newsTitle" class="col-sm-2 control-label">新闻类别</label>
            <div class="col-sm-10">
                <select id="newsTitle" class="form-control" ng-model="newsType">
                    @*<option value="">---请选择---</option>*@
                    <option ng-repeat="type in NewsTypeList" value="{{type.TransactionNumber}}">{{type.NewsTypeName}}</option>
                </select>
            </div>
        </div>
        <div class="row" style="line-height:30px">
            <label for="newsTitle" class="col-sm-2 control-label">审核状态</label>
            <div class="col-sm-10">
                <select id="newsTitle" class="form-control" ng-model="newsState">
                    <option value="">---请选择---</option>
                    <option value="-1">未审核</option>
                    <option value="0">未通过</option>
                    <option value="1">通过</option>
                </select>
            </div>
        </div>
        <div class="row" style="margin-top:10px">
            <div class="col-sm-3">
                <button type="button" class="btn btn-primary btn-form-width" ng-click="getDataList()">查询</button>
            </div>
        </div>
        <div class="pre-scroll" style="margin-top:10px">
            <table class="table table-bordered table-striped table-hover" ng-init="load()">
                <tr style="background-color: #428bca; color: white">
                    <th><input type="checkbox" ng-model="isCheckAll" ng-change="setCheckState()"></th>
                    <th>新闻标题</th>
                    <th>新闻类别</th>
                    <th>创建日期</th>
                    <th>审核状态</th>
                    <th>审核人</th>
                    <th>审核日期</th>
                    <th>操作</th>
                </tr>
                <tr ng-repeat="newsEntity in NewsList">
                    <td><input id="chk_{{newsEntity.TransactionNumber}}" type="checkbox" ng-model="newsEntity.IsChecked" /></td>
                    <td title="{{newsEntity.Title}}">{{newsEntity.SubTitle}}</td>
                    <td>{{newsEntity.InforType}}</td>
                    <td>{{newsEntity.InDate.slice(6,-2)|date:‘yyyy-MM-dd‘}}</td>
                    <td style="color:{{ newsEntity.Color }}">{{newsEntity.AuditStatus}}</td>
                    <td>{{newsEntity.AuditUserName}}</td>
                    <td>{{newsEntity.AuditDate.slice(6,-2)|date:‘yyyy-MM-dd‘}}</td>
                    <td>
                        <span style="cursor:pointer;">
                            <a href="#"><img title="浏览"  src="~/Images/Base/preview.png" class="img-table-column" /></a>
                            <a href="#"><img title="审核" ng-click="auditModalShow(newsEntity)"  src="~/Images/Base/key.png" class="img-table-column" /></a>
                        </span>
                    </td>
                </tr>
            </table>
        </div>
        <div class="btn-group dropup">
            <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
                批量操作<span class="caret"></span>
            </button>
            <ul class="dropdown-menu" role="menu">
                <li><a href="#" ng-click="batchOperation(‘A‘)">批量通过</a></li>
                <li class="divider"></li>
                <li><a href="#" ng-click="batchOperation(‘D‘)">批量删除</a></li>
            </ul>
        </div>
    </div>

    <div class="modal fade" id="newAuditModal" tabindex="-1" role="dialog"
         aria-labelledby="auditModalTitle" aria-hidden="true" data-backdrop="static">
        <div class="modal-dialog">
            <div class="modal-content" style="width:550px">
                <div class="modal-header" style="background-color: #009966;height:45px;line-height:45px">
                    <button type="button" class="close"
                            data-dismiss="modal" aria-hidden="true">
                        &times;
                    </button>
                    <h5 class="modal-title" id="auditModalTitle" style="color:white">
                        新闻审核
                    </h5>
                </div>
                <div class="modal-body">
                    <div class="form-horizontal">
                        <div class="form-group">
                            <label class="col-md-3" for="labTitle">新闻标题:</label>
                            <div class="col-md-9">
                                <label id="labTitle"></label>
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-md-3">审核结果:</label>
                            <div class="col-md-9">
                                <input type="radio" name="radAuditResult" ng-change="setAuditResaonEditable()" value="1" checked ng-model="AuditResult"> 通过
                                <input type="radio" name="radAuditResult" ng-change="setAuditResaonEditable()" value="0" ng-model="AuditResult" style="margin-left:10px"> 不通过
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-md-3" for="div_reason">未通过原因:</label>
                            <div class="col-md-9">
                                <div id="div_reason" style="border: 1px solid #003366; height: 90px; word-break: break-all;max-height:90px;overflow-y:scroll"
                                     contenteditable="true"></div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" ng-click="auditNews()" class="btn btn-primary btn-form-width">
                        提交
                    </button>
                    <button type="button" class="btn btn-danger btn-form-width"
                            data-dismiss="modal">
                        关闭
                    </button>
                </div>
            </div><!-- /.modal-content -->
        </div><!-- /.modal -->
    </div>
</div>

查询条件下拉列表的初始化很简单。

$scope.getNewsTypeList = function () {
    $http.get("/NewsManage/GetNewsTypeList").success(function (data) {
        $scope.NewsTypeList = data;
    });
};

接下来我们看一下查询功能,点击查询按钮,调用getDataList方法

$scope.getDataList = function () {
    $scope.isCheckAll = false;
    var param = {
        requestJson: JSON.stringify({
            Title: $.trim($scope.newsTitle),
            InforType: $scope.newsType,
            AuditStatus: $scope.newsState
        })
    };

    $http({
        method: "post",
        url: "/NewsManage/GetNewsNativeList",
        headers: { ‘Content-Type‘: ‘application/x-www-form-urlencoded‘ },
        data: $.param(param)
    }).success(function (data, status, headers, config) {
        $scope.NewsList = data;
        angular.forEach($scope.NewsList, function (value, key) {
            if ($.trim(value.AuditState) == "") {
                value.Color = "#003366;"
            }
            else if (value.AuditState == "0") {
                value.Color = "#FF0033;"
            }
            else {
                value.Color = "#009966";
            }
        });
    });
}

传入查询条件,并且在返回结果后,对颜色进行设置,未审核是蓝色,审核通过是绿色,不通过是红色。<td style="color:{{ newsEntity.Color }}">{{newsEntity.AuditStatus}}</td>这段就是设置审核状态颜色的,颜色是根据Color属性显示的。

OK,查询完了之后,我们看一下最底下的批量操作按钮。

点击批量操作按钮,其实是弹出一个菜单,有批量通过和批量删除两个选项,这正是BootStrap中的按钮菜单。点击批量通过,其实是要将上面选中的新闻全部审核通过,删除也雷同。我们看一下,点击批量通过调用的js方法batchOperation(‘A‘)。

$scope.batchOperation = function (operationType) {
    var selectedIDs = [];
    angular.forEach($scope.NewsList, function (value, key) {
        if (value.IsChecked) {
            selectedIDs.push(value.TransactionNumber);
        }
    });

    if (selectedIDs.length == 0) {
        alert(‘请选择要批量操作的数据!‘);
        return;
    }

    var param = {
        requestJson: JSON.stringify({
            newsIDs: selectedIDs
        })
    };

    var postAction = operationType == "A" ? "BatchPassNewsAudit" : "BatchNativeNewsDelete";

    $http({
        method: "post",
        url: "/NewsManage/" + postAction,
        headers: { ‘Content-Type‘: ‘application/x-www-form-urlencoded‘ },
        data: $.param(param)
    }).success(function (data, status, headers, config) {
        if (data.suc == "1") {
            $scope.getDataList();
        }
        alert(data.msg);
    });
}

首先会check有没有选中的数据,然将选中的主键传到后台action进行处理。

[HttpPost]
public JsonResult BatchPassNewsAudit()
{
    string requestJson = Request["requestJson"];
    string[] userIDArray = JsonBuilder.BuildStringArray(requestJson, "newsIDs");
    int suc = NewsMngBiz.GetInstance().BatchAuditPass(string.Join(",", userIDArray), this.UserID);
    if (suc > 0)
    {
        return GetJsonMessage("NM_001", JsonMsgType.SUCCESS);
    }

    return GetJsonMessage("NM_002");
}

ok,我们再看一下批量删除,批量删除和批量通过走的是一个js方法并且action也雷同,所以在这里我们只看一下删除的sql脚本。

DECLARE @NewsIDTable TABLE
(
    ID INT IDENTITY(1,1),
    TransactionNumber INT NOT NULL
)

INSERT INTO @NewsIDTable
(
    TransactionNumber
)
SELECT short_str
FROM ChinaInformation.dbo.F_SQLSERVER_SPLIT(@NewsIDs,‘,‘)

DELETE FROM ChinaInformation.dbo.InformationNative
OUTPUT
	DELETED.NewsContent,
	DELETED.InfoTypeID,
	DELETED.AuditState,
	DELETED.InDate,
	DELETED.InUser,
	DELETED.LastEditDate,
	DELETED.LastEditUser,
	DELETED.AuditUser,
	DELETED.AuditDate,
	DELETED.Title,
  GETDATE(),
  @UserID
INTO ChinaInformation.dbo.InformationNativeDeleteLog
WHERE TransactionNumber IN(
  SELECT TransactionNumber
  FROM @NewsIDTable
)

删除的时候要将删除记录插入log表。

接下来我们再看一下单个审核功能

当点击审核图标的时候,弹出modal页面。

<a href="#"><img title="审核" ng-click="auditModalShow(newsEntity)"  src="~/Images/Base/key.png" class="img-table-column" /></a>
$scope.auditModalShow = function (newsEntity) {
    angular.element("#labTitle").text(newsEntity.SubTitle);
    angular.element("#labTitle").attr("title", newsEntity.Title);
    $scope.SelectID = newsEntity.TransactionNumber;
    angular.AuditResult = "1";

    if (typeof (Storage) !== "undefined"
        && sessionStorage.auditReason != undefined
        && sessionStorage.auditReason != ""
        && $scope.AuditResult == "0") {
        document.getElementById("div_reason").innerHTML = sessionStorage.auditReason;
    }

    angular.element(‘#newAuditModal‘).modal(‘show‘);
}

在这里我们把标题什么的,都附上。标题因为有的可能太长,所以我就设置需要显示的为SubTitle,title为原有没有截断的新闻标题,这样用户鼠标放上去就可以看到完整的标题。

默认值设置完了之后,我们判断如果本地session存储sessionStorage中存储的auditReason有值,我们就把它赋给div。注意这里的div,它的contenteditable为true的话是可以编辑的。另外,想让它换行,又不至于高度一直扩展,我们加了滚动条。

<div id="div_reason" style="border: 1px solid #003366; height: 90px; word-break: break-all;max-height:90px;overflow-y:scroll"
                                     contenteditable="true"></div>

OK,最后我们看一下通过和不通过的change事件。

$scope.setAuditResaonEditable = function () {
    var div_auditReason = document.getElementById("div_reason");
    if ($scope.AuditResult == "1") {
        div_auditReason.contentEditable = "false";
        div_auditReason.style.backgroundColor = "#999999";

        if (typeof (Storage) !== "undefined") {
            sessionStorage.auditReason = document.getElementById("div_reason").innerHTML;
        }

        div_auditReason.innerHTML = "";
    }
    else {
        div_auditReason.contentEditable = "true";
        div_auditReason.style.backgroundColor = "#FFFFFF";
    }
}

当radio的值有变化的时候,调用上面js方法。如果审核通过被选中,那么我们需要把不通过原因存储在本地session中,注意本地session的作用域是浏览器,浏览器关了就没有了。另外还要特别注意的是这里的div_auditReason.contentEditable = "true";一定得是"true",双引号括起来的true。contentEditable 这个单词的E一定要大写,不然就不会有任何效果。下面这两张图就是radio change效果。

OK,最后我们再看一下后台的处理

$scope.auditNews = function () {
    var unPassReason = document.getElementById("div_reason").innerHTML;

    if ($scope.AuditResult == "0" && (unPassReason == "" || unPassReason.length < 10)) {
        alert("不通过原因不能少于10个字!");
        return;
    }

    var param = {
        requestJson: JSON.stringify({
            TransactionNumber: $scope.SelectID,
            AuditStatus: $scope.AuditResult,
            UnPassReason: $scope.AuditResult == "1" ? "" : unPassReason
        })
    };

    $http({
        method: "post",
        url: "/NewsManage/NewsAuditSingle",
        headers: { ‘Content-Type‘: ‘application/x-www-form-urlencoded‘ },
        data: $.param(param)
    }).success(function (data, status, headers, config) {
        if (data.suc == "1") {
            $scope.getDataList();
        }
        alert(data.msg);
    });
};

后台代码如下

[HttpPost]
public JsonResult NewsAuditSingle(FormCollection fc)
{
    string requestJson = fc["requestJson"];
    string auditState = JsonBuilder.BuildValueByType<string>(requestJson, "AuditStatus");
    int transactionNumber = JsonBuilder.BuildValueByType<int>(requestJson, "TransactionNumber");
    string unPassReason = JsonBuilder.BuildValueByType<string>(requestJson, "UnPassReason");

    int suc = NewsMngBiz.GetInstance().NewsNativeAuditSingle(transactionNumber, auditState, unPassReason, this.UserID);
    if (suc > 0)
    {
        return GetJsonMessage("NM_005", JsonMsgType.SUCCESS);
    }

    return GetJsonMessage("NM_006");
}

OK,今天就到这里,这个界面还剩余一个新闻预览功能,和审核不通过原因查看。

时间: 2024-10-24 09:27:30

ASP.NET MVC4+BootStrap 实战(十三)的相关文章

ASP.NET MVC4+BootStrap 实战(二)

上一篇文章我们讲述了页面初始加载数据的一些东西,本篇我们来讲一下查询按钮和分页按钮.在很久以前我写过一篇ASP.NET MVC4切近实战的文章,有关于分页的代码,本篇我们不采用微软的AJAX框架. 先看一下查询效果,在点击Get按钮之后,会进行AJAX请求. js代码如下 jQuery(document).ready(function () {     setRowBackColor();     $("#btnsearch").click(function () {         

ASP.NET MVC4+BootStrap 实战(七)

连续三年年会中奖,第一年二等奖,价值2600元的魔音耳机,到现在才用了10几次.第二年中了个价值260元的飞利浦烧水壶,到现在还没用.今年中了个飞利浦挂烫机,也没查是多少钱,反正觉得奖项一年不如一年.在此我就给大家上一张年会热图. 男人的肚皮舞,嗨爆全场.好了,废话不多说,我们进入正题吧. 今天我们要说的就是主页面以及用户注册界面,功能做的都比较简单,我们先看一下Index界面. <div id="div_navigation" style="margin-top:10

ASP.NET MVC4+BootStrap 实战(六)

最近面试了一个西安电子科技大学刚毕业的,不是计算机系毕业,却喜欢编程.除了书本上的知识以外,其他一窍不通,笔试题答得不错.经验欠佳,编程也只懂书本上的一些例子.本来不打算录用,但是后来聊到高等数学和物理是她学的最好的两门,那必须收下.人家都说了能考上西电,就能证明她的学习能力,我和项目经理也就相信人家了.毕竟当年面试的时候我面试的是南京擎天科技,有个西电的面试的是南京联创,人家和我聊了两句,得知我是二本院校的,人家说了句他同学面试的都是腾讯,阿里,百度,新浪,说完直接放弃面试,我去南京擎天还害怕

ASP.NET MVC4+BootStrap 实战(三)

上节我们剩余Compare和Fix按钮没有讲,本节我们就来讲一下Compare按钮的功能,年底了,要开年会了,一个个积极的跟邱少云似得,给员工涨工资的时候能不能也积极点.不说了,说多了都是泪. 还记得我之前写的大数据实战之环境搭建,我们今天主要是拿DB的数据和solr的数据作比较,得出比较结果.首先,先启动centOS,启动tomcat,这样我们才能利用SolrNet调用solr公开的API.关于solr的启动再次我就不再赘述. OK,我们将solr实例启动起来后,用firefox浏览管理界面,

[转]ASP.NET MVC4+BootStrap 实战(一)

本文转自:http://leelei.blog.51cto.com/856755/1587301 好久没有写关于web开发的文章了,进到这个公司一直就是winform和Silverlight,实在是没有实战web项目的机会.大D也辞职了,去搞web app了.自己也该闲暇时间多学习学习,每天进步一点点. OK,不多说了,看一下Solution的截图 基本上一看就明白了,控制器调用Biz层,Biz层调用DAL层,DAL层进行数据的CURD.Utility是一些公用的类库.ok,为什么程序集的命名都

ASP.NET MVC4+BootStrap 实战(十)

年过完了,也该收心了.想想过年这几天都是每天睡到12:00,实在是腐化.大家都沉浸在抢红包的喜悦之中. 不说了,今天我们主要看一下新闻链接管理界面.先上图,无图无真相. 上半部分主要是对已经添加的外链接进行修改删除,设置优先级,下半部分是新增外链接网站. 首先我们先看一下上半部分. <div id="div_newsManage" class="panel panel-primary" ng-app="newsLinkManageModule&quo

ASP.NET MVC4+BootStrap 实战(八)

今天西安下雪了,贼冷,我去.今年的年终奖还没发,都快揭不开锅了. 今天的话我们来看一下用户删除和修改,天太冷,先调一下胃口,上图,无图无真相. 看到了吧,新增了选择列,操作列,以及页面最下面的全选,反选,新增,删除按钮. 我们先来看一下全选反选吧,经过修改之后,我们的Table变成如下的代码 <table class="table table-bordered table-striped table-hover" ng-init="load()">   

ASP.NET MVC4+BootStrap 实战(九)

哄孩子睡觉哄到现在,要两个孩子真的是不容易.孩子不睡觉,我没办法写博客.孩子睡着了,我一写就要写到半夜2点.6点起床,6:30骑自行车去上班,呼吸着雾霾,头皮冻得僵硬.到了软件园楼底下,还要排队买胡辣汤,排队上电梯.唉,生活不易. 今天,我们要说的当然是用户信息修改,请看下图. 看到一龙了么,重庆功夫盛典和日本变装拳手战成平手,打裂了日本拳手的眉骨.OK,我们点击铅笔,弹出用户信息修改界面.那么,我们在弹出用户信息修改界面之前,先要给弹出界面的form赋值.那么这一步要怎么做,当然了,是使用an

ASP.NET MVC4+BootStrap 实战(十一)

最近一天真的都不知道自己在忙什么,当了回Scrum Master.给自己的感觉就是像大学时期,饭堂经理看员工给学生打饭太慢,自己抡起大勺子给学生打菜,偶尔有些学生有情绪还要忍着.说到饭堂,最近都不知道该吃啥.黄焖鸡,biangbiang面,镇川碗托,麻辣香锅,自助餐都吃的没啥可吃了.偶尔咥一碗麦利鸡汤刀削面或者米线凉皮沙县.不说了,这会也确实有些饿,洗个苹果吃一下. 上面这一碗就是我经常吃的biangbiang面. 今天我们主要是来看一下新闻链接的修改和新增,先上图,无图无真相. 看到了吧,这个