前言:踏入十二月,人生也即將進入下一個階段。
最近忙於其他,代碼也是偶爾更新。目前算是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:
/// <summary> /// 系統JSON提示實體類 /// </summary> [Serializable] public class JsonTip { public JsonTip() { } /// <summary> /// 成功狀態 /// </summary> public static readonly string SUCCESS = "success"; /// <summary> /// 失敗狀態 /// </summary> public static readonly string ERROR = "error"; /// <summary> /// 請求返回狀態 默認 error(錯誤);成功:success /// </summary> public string Status { get; set; } = ERROR; /// <summary> /// 提示信息 /// </summary> public string Message { get; set; } /// <summary> /// 其他信息 /// </summary> public string Other { get; set; } /// <summary> /// Id 可選 /// </summary> public int Id { get; set; } = 0; /// <summary> /// 返回URL /// </summary> public string ReturnUrl { get; set; } /// <summary> /// 獲取JSON字符串 /// </summary> /// <param name="json">JsonTip實體類</param> /// <returns></returns> 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<Link> 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<string> listTpls = new List<string>(); 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、列表分頁的,這里我使用了手動計算分頁的形式:
IList<Article> list = new List<Article>(); 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<int> allsubkids = new List<int>(); allsubkids.Add(model.Id); IList<ArticleCategory> 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群:1600800