一、项目需求
大多数的网站都会开启评论功能区域,主要可以提升用户与网站之间的互动,增加用户粘性和提高网站的活跃度。
我的B站视频教程
评论-3评论时间处理
二、基础实现
1、搭建SQL Server数据库环境
1)使用NetDB.sql导入数据库,包含User表和Product表。
2)新建Comment表
id int (主键,自增)
message text //评论内容
userId int //外键,指向User表
productId int //外键,指向Product表
isValid bit //管理员审核
createDate datetime //创建
isDelete bit //逻辑删除
2、新建Web应用程序
Visual Studio 2019→创建新项目→ASP.NET Web应用程序(.NET Framework)→MVC
3、DataBaseFirst模式创建EF
右键“添加”→“新建项”→“ADO.NET实体数据模型”→“来自数据库的EF设计器”→连接数据库→勾选数据库中的两个表→勾选“确定所声称对象名称的单复数形式”
三、Product模块
1、添加数据注解
public partial class Product
{
public int id { get; set; }
[DisplayName("产品名称")]
[Required]
public string name { get; set; }
[DisplayName("生产日期")]
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public System.DateTime pDate { get; set; }
[DisplayName("生成人")]
[Required]
public string pWork { get; set; }
[DisplayName("价格")]
[Required]
[DataType(DataType.Currency)]
public decimal price { get; set; }
}
2、列表页
1)Product Controller 数据库上下文
//获取数据库上下文
private NetDBEntities dbContext = new NetDBEntities();
2)List Action
public ActionResult List()
{
List<Product> products = dbContent.Products.Select(p => p).ToList();
return View(products);
}
3)生成List cshtml
3、详情页
1)Details Action
public ActionResult Details(int? id)
{
Product product = dbContent.Products.Where(p => p.id == id).FirstOrDefault();
return View(product);
}
2)生成Details cshtml
四、Comment模块
1、 用户数据准备
1)发表评论需要用户id和产品id,产品id可以使用传参方式获取,用户id本应从session中读取,本项目没有做用户登录,使用随机数获取用户id
2)导入测试用户数据
public ActionResult Index()
{
string nameStr = "叶静宜、江淑玲、 邓仪绍、林兰瑄、陈俊铭、陈盈昆、谈亭美、张芳坚、" +
"丁俊毅、白山贵、陈胜火、杨秋雯、蔡登木、张钧幸、林怡桦、郭法美、王雅云、黄台育、" +
"王嘉琪、 胡钰雯、汤筠霞、洪思贤、骆文馨、刘培宁、林俊贤、邓淳筠、李汉霖、敖秀娟、" +
"陈家弘、 苏承松、王怡祯、叶胜群、叶志鸿、黄郁翔、柯意孝、杨莉倩、 吕孟儒、蔡佩圣、" +
"阮伦淑、童启光、王淑惠、张淑智、林正平";
string[] nameArr = nameStr.Split('、');
List<User> userList = new List<User>();
foreach (var name in nameArr)
{
userList.Add(new User {
username = name,
password = "e10adc3949ba59abbe56e057f20f883e",
role = 0,
email = "test@qq.com",
age = 22,
phone = "15866668888",
create_time = DateTime.Now,
update_time = DateTime.Now
});
}
dbContext.Users.AddRange(userList);
dbContext.SaveChanges();
return Content("批量添加测试用户数据成功");
}
2、 发表评论
1)Create Action
public ActionResult Create(Comment comment)
{
if (String.IsNullOrEmpty(comment.message) || comment.message.Trim().Length == 0)
{
return RedirectToAction("AjaxPage", new { productId = comment.productId });
}
comment.userId = (new Random()).Next(3, 45);
comment.createDate = DateTime.Now;
comment.isValid = true;
comment.isDelete = false;
dbContext.Comments.Add(comment);
dbContext.SaveChanges();
return RedirectToAction("AjaxPage", new { productId = comment.productId });
}
2)Product详情页添加发表评论表单 Details cshtml
@if (Model != null)
{
<div style="background-color:cadetblue;padding-left:8px;color:white;height:36px;line-height:36px;font-size:20px">
<span>顾客评论</span>
</div>
<div id="commentList">
</div>
using (Ajax.BeginForm("Create", "Comment", new AjaxOptions
{
UpdateTargetId = "commentList",
InsertionMode = InsertionMode.Replace,
OnSuccess = "CommentSuccess"
}))
{
<input type="hidden" name="productId" value="@Model.id" />
<textarea name="message" id="message" class="form-control" rows="5" , placeholder="评论"></textarea>
<div style="display: flex; justify-content:right;margin-top:5px;margin-right:20px">
<input type="submit" value="提交" class="btn btn-default" onclick="return commentFormSubmit()" />
</div>
}
}
@section scripts{
<script>
function commentFormSubmit() {
if ($("#message").val().trim().length == 0)
return false;
return true
}
function CommentSuccess() {
$("#message").val("")
}
</script>
}
3、 异步分页显示评论
1)安装Webdiyer.MvcPager
2)安装并引入 jquery.unobtrusive-ajax.js
3)AjaxPage Action
为了保障用户隐私,用户名只显示第一个汉字,其余用*代替
public ActionResult AjaxPage(int? productId, int pageIndex = 1, int pageSize = 3)
{
IQueryable<Comment> commentQueryable =
dbContext.Comments.Where(c => c.productId == productId).Select(c => c);
commentQueryable = commentQueryable.OrderByDescending(c => c.createDate);
PagedList<Comment> commentPagedList = commentQueryable.ToPagedList(pageIndex, pageSize);
foreach (var item in commentPagedList)
{
item.User.username = item.User.username.Trim().Substring(0, 1) + new string('*', item.User.username.Trim().Length - 1);
}
commentPagedList.TotalItemCount = commentQueryable.Count();
return PartialView("_AjaxPage", commentPagedList);
}
4)_AjaxPage cshtml
@using Webdiyer.WebControls.Mvc
@model PagedList<CommentProject.Models.Comment>
@Html.Partial("_List",Model)
<div style="margin-right:40px">
@Ajax.Pager(Model,
new PagerOptions
{
PageIndexParameterName = "pageIndex",
HorizontalAlign = "right",
PagerItemTemplate = " {0}",
PageNumberFormatString = "[{0}]"
}).AjaxOptions(a => a.SetUpdateTargetId("commentList"))
</div>
5)_List cshtml
@using Webdiyer.WebControls.Mvc
@using CommentProject.Utils
@model PagedList<CommentProject.Models.Comment>
@foreach (var item in Model)
{
<div class="row" style="height:24px;line-height:24px;padding-left:24px">
<span style="margin-right:18px">@TimeUtil.getTimeSpanStr(DateTime.Now - item.createDate)</span>
<span style="margin-right:18px">@item.User.username</span>
<span>@item.message</span>
</div>
}
6)产品详情页导入 _AjaxPage
<div id="commentList">
@Html.Action("AjaxPage", "Comment", new { productId = Model.id })
</div>
@section scripts{
@{Html.RegisterMvcPagerScriptResource();}
}
4、评论时间处理
1)TimeUtil 时间处理工具类
public class TimeUtil
{
public static string getTimeSpanStr(TimeSpan ts) {
if (ts.TotalDays>365)
{
return Math.Floor(ts.TotalDays / 365) + "年前";
}
else if (ts.TotalDays > 30)
{
return Math.Floor(ts.TotalDays / 30) + "月前";
}
else if (ts.TotalHours>24)
{
return Math.Floor(ts.TotalHours / 24) + "天前";
}
else if (ts.TotalHours > 1)
{
return Math.Floor(ts.TotalHours) + "小时前";
}
else if (ts.TotalMinutes > 1)
{
return Math.Floor(ts.TotalMinutes) + "分钟前";
}
else
return "刚刚";
}
}
2)修改页面 _List
@using CommentProject.Utils
<span style="margin-right:18px">@TimeUtil.getTimeSpanStr(DateTime.Now - item.createDate)</span>