前言:踏入十二月,人生也即将进入下一个阶段。
最近忙于其他,代码也是偶尔更新。目前算是0.9的版本,就是基本上可以完成一个简单的企业站/博客的功能。
主要特点:前台完整演示:文章、产品、留言。界面响应式:响应PC和手机
预计:1.0版本的话,带有app端(预计只有安卓版本,苹果版本没有证书-_-')演示,也算是可以应用于app、小程序(微信小程序、支付宝、百度小程序)。当然只是预告而已ORZ
github地址:https://github.com/hogenwang/comcms_core
讨论Q群:1600800
本次最重要的是,加上前台的完整前端。一方面,让整个小cms系统更加完整。另外一方面,也是演示了,如何搭配前端view进行开发。还有就是XCode如是使用。
之前有人提到,希望有多一点的二次开发文档。这个我尽量抽时间写写,其实主要还是XCode的用法。
话不多说,先看整体的效果吧:
以下就简单说一下,前台的一些特点和二次开发注意的内容:
1、前台控制器继承:HomeBaseController 主要是:
提供了后台配置,和前后端交互的json基础类JsonTip
所有需要展示网站完整页面的需要加入:
ViewBag.cfg = cfg;
2、ServerController 为数据交互提交方法,可以将所有需要交互的数据,方法都写在本控制器,当然,你也可以写在其他的。
而一般,提交的方法,都使用POST外加:AutoValidateAntiforgeryToken 保证数据提交的安全,最后,统一都返回一个json:
复制代码
    /// 
    /// 系统JSON提示实体类
    /// 
    [Serializable]
    public class JsonTip
    {
        public JsonTip() { }
        /// 
        /// 成功状态
        /// 
        public static readonly string SUCCESS = "success";
        /// 
        /// 失败状态
        /// 
        public static readonly string ERROR = "error";
        /// 
        /// 请求返回状态 默认 error(错误);成功:success 
        /// 
        public string Status { get; set; } = ERROR;
        /// 
        /// 提示信息
        /// 
        public string Message { get; set; }
        /// 
        /// 其他信息
        /// 
        public string Other { get; set; }
        /// 
        /// Id 可选
        /// 
        public int Id { get; set; } = 0;
        /// 
        /// 返回URL
        /// 
        public string ReturnUrl { get; set; }
        /// 
        /// 获取JSON字符串
        /// 
        /// 
JsonTip实体类
        /// 
        public static string GetJsonString(JsonTip json)
        {
            if (json != null)
                return JsonConvert.SerializeObject(json);
            else
                return string.Empty;
        }
    }
复制代码
如演示里面的提交留言:
复制代码
#region 提交前台底部留言
        [HttpPost]
        [AutoValidateAntiforgeryToken]
        public IActionResult DoPostMessage(string name,string phone,string content)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                tip.Message = "请填写您的姓名!";
                return Json(tip);
            }
            if (!Utils.IsTel(phone))
            {
                tip.Message = "请填写正确的手机号码!";
                return Json(tip);
            }
            if (string.IsNullOrWhiteSpace(content))
            {
                tip.Message = "请填写您的留言内容!";
                return Json(tip);
            }
            Guestbook entity = new Guestbook()
            {
                AddTime = DateTime.Now,
                IP = Utils.GetIP(),
                KId = 1,
                Nickname = name,
                Content = Utils.NoHTML(content),
                Tel = phone
            };
            entity.Insert();
            tip.Message = "留言成功,感谢您的留言!";
            tip.Status = JsonTip.SUCCESS;
            return Json(tip);
        }
        #endregion
复制代码
可以看到,涉及到XCode的用法也是非常简单的,new一个对象后,最后调用Insert();就可以插入数据了。值得一提的是,如果插入这个数据后,想获取主键Id的值:entity.Id就可以了。不要用Insert() 返回值。
3、为了方便演示,我大部分获取数据都写在views里面,建议还是写在Controller里面。如首页模板
复制代码
    IList
 listLinks = Link.FindAll(Link._.KId == 1, Link._.Sequence.Asc(), null, 0, 0);
    //处理bannr广告
    var bannerPC = Ads.GetSlideAds(1);
    var bannerMobile = Ads.GetSlideAds(2);
复制代码
4、后台文章,可以配置相应的模板,可以根据不同情况配置不同模板。如演示,关于我们、联系我们和新闻中心模板就不一样。
因为编译了模板,所以选择模板使用反射实现:
复制代码
            //获取模板 模板规则,以Index_开头的,为栏目列表,以Detial_开头的为文章详情
            List
 listTpls = new List();
            var asms = AppDomain.CurrentDomain.GetAssemblies();
            foreach (var asmItem in asms)
            {
                var types = asmItem.GetTypes().Where(e => e.Name.StartsWith("Views_Article")).ToList();
                if (types.Count == 0) continue;
                foreach (var type in types)
                {
                    string viewName = type.Name.Replace("Views_Article_", "") + ".cshtml";
                    listTpls.Add(viewName);
                }
            }
            ViewBag.ListTpl = listTpls;
复制代码
注意看注释部分内容哦。
5、列表分页的,这里我使用了手动计算分页的形式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
IList list = new List();
int numPerPage, currentPage, startRowIndex;
numPerPage = model.PageSize;
if (page > 0)
    currentPage = page;
else
    currentPage = 1;
 
startRowIndex = (currentPage - 1) * numPerPage;
 
var ex = Article._.IsHide != 1 & Article._.IsDel != 1;
 
//如果显示下级栏目文章
if (model.IsShowSubDetail == 1)
{
    //获取下级所有栏目
    List allsubkids = new List();
    allsubkids.Add(model.Id);
 
    IList allkind = ArticleCategory.FindAllSubKinds(model.Id);
    if (allkind != null && allkind.Count > 0)
    {
        foreach (var s in allkind)
        {
            allsubkids.Add(s.Id);
        }
    }
    ex &= Article._.KId.In(allsubkids);
}
else
    ex &= Article._.KId == model.Id;
long totalCount = Article.FindCount(ex, Article._.Sequence.Asc().And(Article._.Id.Desc()), null, startRowIndex, numPerPage);
int pageCount = (int)totalCount / numPerPage;//总页数
if (totalCount % numPerPage > 0)
{
    pageCount += 1;
}
list = Article.FindAll(ex, Article._.Sequence.Asc().And(Article._.Id.Desc()), null, startRowIndex, numPerPage);
ViewBag.list = list;//列表
//分页信息
ViewBag.totalCount = totalCount;
ViewBag.pageCount = pageCount;
ViewBag.page = page;
ViewBag.pagesize = numPerPage;
  而views里面调用分页代码:
@Html.Raw(Pages.GetPageStr(ViewBag.pagesize, (int)ViewBag.totalCount, ViewBag.page, $"/Article/Index/{Model.Id}" + "?page={0}", 99, 10, ""))
6、后台权限使用方法
由于上面提到统一执行post返回一个标准的json。所以后台权限,目前设计验证两种,一种是普通的验证,错误返回提示页面,另外一种是提交验证,错误返回一个json。也就是POST提交的时候。
用法也是很简单,给方法名加上:
[MyAuthorize( "viewlist",  "articlecategory")]
[MyAuthorize( "add",  "articlecategory", "JSON")]
其中第一个参数为事件权限,在后台:后台权限》事件权限管理管理
第二个参数为页面的key。这个在后台栏目权限管理中设置:
 
这样,在二次开发中,就可以很快速的添加功能和权限控制了。
 
其他方面暂不一一列出。如果有什么不明白的,可以给我留言。
也欢迎大家点个star。
最后再次提醒,讨论Q群:1600800https://www.cnblogs.com/m5v8/p/10055427.html