Details_Admin.cshtml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. @using System.Web
  2. @using Masuit.MyBlogs.Core.Common
  3. @using Masuit.MyBlogs.Core.Models.DTO
  4. @using Masuit.MyBlogs.Core.Models.Enum
  5. @using Masuit.MyBlogs.Core.Models.ViewModel
  6. @using Masuit.Tools.Core.Net
  7. @using Masuit.Tools.Systems
  8. @model Masuit.MyBlogs.Core.Models.Entity.Post
  9. @{
  10. ViewBag.Title = Model.Title;
  11. Layout = "~/Views/Shared/_Layout.cshtml";
  12. UserInfoDto user = Context.Session.Get<UserInfoDto>(SessionKey.UserInfo);
  13. AdvertisementDto ad = ViewBag.Ads;
  14. }
  15. <script src="~/UEditorPlus/ueditor.config.front.js"></script>
  16. <script charset="utf-8" src="~/UEditorPlus/ueditor.all.js" type="text/javascript"></script>
  17. <script src="https://cdn.jsdelivr.net/npm/dayjs/dayjs.min.js"></script>
  18. <script>
  19. window.defaultUser=function(){
  20. return {
  21. NickName: `@user.NickName`,
  22. Email: `@user.Email`,
  23. Agree:true,
  24. IsAdmin:true,
  25. voteDownCount:@Model.VoteDownCount,
  26. voteUpCount:@Model.VoteUpCount
  27. };
  28. }
  29. </script>
  30. <div class="container" id="postApp">
  31. <ol class="breadcrumb">
  32. <li>
  33. <a asp-action="Index" asp-controller="Home">首页</a>
  34. </li>
  35. <li>
  36. <a asp-action="Post" asp-controller="Home">文章列表</a>
  37. </li>
  38. @if (Model.Category.ParentId > 0) {
  39. if (Model.Category.Parent.ParentId > 0) {
  40. <li>
  41. <a asp-action="Category" asp-controller="Home" asp-route-id="@Model.Category.Parent.ParentId">@Model.Category.Parent.Parent.Name</a>
  42. </li>
  43. }
  44. <li>
  45. <a asp-action="Category" asp-controller="Home" asp-route-id="@Model.Category.ParentId">@Model.Category.Parent.Name</a>
  46. </li>
  47. }
  48. <li>
  49. <a asp-action="Category" asp-controller="Home" asp-route-id="@Model.CategoryId">@Model.Category.Name</a>
  50. </li>
  51. <li class="current">
  52. <em>@ViewBag.Title</em>
  53. </li>
  54. </ol>
  55. <div class="main-container">
  56. <!-- 头部信息 -->
  57. <section class="article-header">
  58. <div class="article-title-row">
  59. <h2 class="article-title">@Html.Raw(Model.Title)</h2>
  60. <span class="article-status">@Model.Status.GetDisplay()</span>
  61. </div>
  62. <div class="article-meta-row">
  63. <div>
  64. <span class="author">
  65. <a asp-action="Author" asp-controller="Home" asp-route-author="@Model.Author">@Model.Author</a>
  66. </span>
  67. <span>
  68. 发布于
  69. <a asp-action="Archieve" asp-controller="Home" asp-route-dd="@Model.PostDate.Day" asp-route-mm="@Model.PostDate.Month" asp-route-mode="@nameof(Model.PostDate)" asp-route-yyyy="@Model.PostDate.Year">
  70. <time class="text-info">@Model.PostDate.ToString("yyyy-MM-dd HH:mm:ss")</time>
  71. </a>
  72. </span>
  73. </div>
  74. <div>
  75. <span class="modifier">
  76. <a asp-action="Author" asp-controller="Home" asp-route-author="@Model.Modifier">@Model.Modifier</a>
  77. </span>
  78. <span>
  79. 修改于
  80. <a asp-action="Archieve" asp-controller="Home" asp-route-dd="@Model.ModifyDate.Day" asp-route-mm="@Model.ModifyDate.Month" asp-route-mode="@nameof(Model.ModifyDate)" asp-route-yyyy="@Model.ModifyDate.Year">
  81. <time class="text-success">@Model.ModifyDate.ToString("yyyy-MM-dd HH:mm")</time>
  82. </a>
  83. </span>
  84. </div>
  85. <span>评论数:@ViewBag.CommentsCount</span>
  86. <span>访问量:@Model.TotalViewCount</span>
  87. <span>
  88. 正在浏览:
  89. <span @@click="showViewer(true)" class="text-red">{{online}}人</span>
  90. </span>
  91. </div>
  92. <div class="article-meta-row">
  93. <div class="article-tags-row">
  94. <span style="font-weight:600;color:#1566b6;font-size:1.06rem;">
  95. <i class="icon-map-pin"></i>分类:
  96. <span class="article-tag">
  97. @{
  98. await Html.RenderPartialAsync("CategoryPath", Model.Category);
  99. }
  100. </span>
  101. </span>
  102. </div>
  103. @if (Model.Seminar.Any()) {
  104. <div class="article-tags-row">
  105. <span style="font-weight:600;color:#1566b6;font-size:1.06rem;">所属专题:</span>
  106. @{
  107. var seminars = Model.Seminar;
  108. foreach (var s in seminars) {
  109. <span class="article-tag">
  110. <a asp-action="Index" asp-controller="Seminar" asp-route-id="@s.Id">@s.Title</a>
  111. </span>
  112. }
  113. }
  114. </div>
  115. }
  116. @{
  117. if (!string.IsNullOrEmpty(Model.Label)) {
  118. <div class="article-tags-row">
  119. <span style="font-weight:600;color:#1566b6;font-size:1.06rem;">标签:</span>
  120. @foreach (string s in Model.Label.Split([',', ','], StringSplitOptions.RemoveEmptyEntries)) {
  121. <span class="article-tag">
  122. <a asp-action="Tag" asp-controller="Home" asp-route-tag="@s">
  123. @s
  124. </a>
  125. </span>
  126. }
  127. </div>
  128. }
  129. }
  130. </div>
  131. <div class="article-meta-row">
  132. @if (Model.LimitMode != null) {
  133. <span class="limit-tip">访问限制: @Model.LimitMode?.GetDescription(Model.Regions, Model.ExceptRegions)</span>
  134. }
  135. <div class="article-ops-row">
  136. <a asp-action="Refresh" asp-controller="Post" asp-route-id="@Model.Id">
  137. <button class="article-op-btn">刷新</button>
  138. </a>
  139. @if (Model.IsFixedTop) {
  140. <button @@click="fixtop" class="article-op-btn">取消置顶</button>
  141. } else {
  142. <button @@click="fixtop" class="article-op-btn">置顶</button>
  143. }
  144. @if (Model.Status == Status.Pending) {
  145. <button @@click="postPass" class="article-op-btn">通过</button>
  146. }
  147. <a href="/dashboard/posts/[email protected]" target="_blank">
  148. <button class="article-op-btn">修改</button>
  149. </a>
  150. <a href="/dashboard/posts/[email protected]" target="_blank">
  151. <button class="article-op-btn">复制</button>
  152. </a>
  153. <button @@click="takedown" class="article-op-btn">下架</button>
  154. <a asp-action="PostVisitRecordInsight" asp-controller="Post" asp-route-id="@Model.Id" class="article-op-btn" target="_blank">洞察</a>
  155. </div>
  156. </div>
  157. </section>
  158. <!-- 内容区 -->
  159. <section class="article-content-card">
  160. <div class="article-content">
  161. @if (DateTime.Now - Model.ModifyDate > TimeSpan.FromDays(365)) {
  162. <div class="old-card">
  163. 该文章已经超过1年未更新,可能无法为您提供及时准确的资讯,请根据当下实际情况,酌情参考本文内容。
  164. </div>
  165. }
  166. @Html.Raw(Model.Content)
  167. @Html.Raw(Model.ProtectContent)
  168. </div>
  169. @if (ad != null) {
  170. await Html.RenderPartialAsync("_ArticleListAdvertisement", ad);
  171. }
  172. <div class="article-footer-row">
  173. <div class="like-btn-group">
  174. <button :disabled="disableVoteUp" @@click="voteUp" class="like-btn"> 👍赞 </button>
  175. <span class="like-count">{{voteUpCount}}</span>
  176. <button :disabled="disableVoteDown" @@click="voteDown" class="dislike-btn"> 👎踩 </button>
  177. <span class="dislike-count">{{voteDownCount}}</span>
  178. </div>
  179. @if (Model.Rss) {
  180. <a asp-action="PostRss" asp-controller="Subscribe" asp-route-id="@Model.Id" target="_blank">
  181. <button class="subscribe-btn" type="button">
  182. &#128233; 订阅本文章更新
  183. </button>
  184. </a>
  185. }
  186. @if (ViewBag.HistoryCount > 0) {
  187. <a asp-action="History" asp-controller="Post" asp-route-id="@Model.Id" class="history-link">
  188. 文章历史版本
  189. <span style="background:#eaf6ff;color:#1566b6;border-radius:6px;padding:2px 10px;font-size:.98rem;margin-left:4px;">修改 @ViewBag.HistoryCount 次</span>
  190. </a>
  191. }
  192. </div>
  193. <div class="nav-links">
  194. @{
  195. PostModelBase prev = ViewBag.Prev;
  196. if (prev != null) {
  197. <a asp-action="Details" asp-controller="Post" asp-route-id="@prev.Id" class="nav-link">上一篇:@prev.Title</a>
  198. }
  199. PostModelBase next = ViewBag.Next;
  200. if (next != null) {
  201. <a asp-action="Details" asp-controller="Post" asp-route-id="@next.Id" class="nav-link">下一篇:@next.Title</a>
  202. }
  203. }
  204. </div>
  205. @{
  206. var posts = (IDictionary<int, string>) ViewBag.Related;
  207. if (posts.Count > 1) {
  208. <div class="recommend-card">
  209. <h2 class="recommend-title" id="recommend">相关推荐</h2>
  210. <ul class="recommend-list">
  211. @foreach (var item in posts) {
  212. <li class="recommend-item">
  213. <a asp-action="Details" asp-controller="Post" asp-route-id="@item.Key">@item.Value</a>
  214. </li>
  215. }
  216. </ul>
  217. </div>
  218. }
  219. }
  220. <div class="copyright-card">
  221. <h2 class="recommend-title" id="copyright">版权声明</h2>
  222. @if (Model.DisableCopy) {
  223. <text>🈲⚠本文为作者原创,仅用于本站访客学习、研究和交流目的,未经授权禁止转载。️⚠🈲</text>
  224. } else {
  225. <text>
  226. 本文仅用于学习、研究和交流目的,欢迎非商业性质转载。本文链接:
  227. <a asp-action="Details" asp-controller="Post" asp-route-id="@Model.Id">@HttpUtility.UrlDecode(Context.Request.Scheme + "://" + Context.Request.Host + Context.Request.Path)</a>。
  228. </text>
  229. @Html.Raw(CommonHelper.SystemSettings["Disclaimer"])
  230. }
  231. </div>
  232. </section>
  233. <section class="comment-section">
  234. <div class="comment-form">
  235. <h2 class="comment-list-title" id="comment">评论区</h2>
  236. @Html.AntiForgeryToken()
  237. <div class="comment-form-row" style="width:100%;margin-top:12px;">
  238. <div class="ueditor" id="editor"></div>
  239. </div>
  240. <div class="comment-form-row" style="display:flex;align-items:center;justify-content:space-between;margin-top:12px;gap:18px;">
  241. <button :disabled="!msg.Content" @@click="submit(msg)" class="comment-form-btn">提交评论</button>
  242. </div>
  243. </div>
  244. <parent-messages :data="list" :is-admin="true" @@getmsgs="getcomments" @@reply-msg="replyMsg"></parent-messages>
  245. <n-pagination :page-count="Math.ceil(pageConfig.total / pageConfig.size)" :page-sizes="[10, 20, 30, 50]" show-size-picker v-if="pageConfig.total > 0" v-model:page="pageConfig.page" v-model:page-size="pageConfig.size"/>
  246. <h4 v-if="pageConfig.total === 0">还没有评论哦,赶紧来写评论吧</h4>
  247. </section>
  248. </div>
  249. <n-modal :mask-closable="false" :title="`回复:${reply.for?.NickName}`" @@positive-click="submit(reply)" negative-text="取消回复" positive-text="回复评论" preset="dialog" style="width:70vw;min-width:400px" v-model:show="showPopup">
  250. <div class="comment-item">
  251. <div class="comment-meta-row">
  252. <div>
  253. <span class="comment-author">{{reply.for?.NickName}}</span>
  254. <span class="comment-time">{{ reply.for?.CommentDate }}</span>
  255. </div>
  256. </div>
  257. <div class="comment-content" v-html="reply.for?.Content"></div>
  258. </div>
  259. @Html.AntiForgeryToken()
  260. <div class="ueditor" id="editor2"></div>
  261. </n-modal>
  262. </div>
  263. <environment names="Development">
  264. <link href="~/UEditorPlus/third-party/SyntaxHighlighter/shCoreDefault.css" rel="stylesheet"/>
  265. <script src="/UEditorPlus/third-party/SyntaxHighlighter/shCore.js"></script>
  266. <link href="~/Assets/auto-toc/auto-toc.css" rel="stylesheet"/>
  267. <script src="/Assets/auto-toc/auto-toc.js"></script>
  268. <script src="/Scripts/global/article.js"></script>
  269. </environment>
  270. <environment names="Stage,Production">
  271. @await Styles.RenderAsync("/bundles/article.css")
  272. @await Scripts.RenderAsync("/bundles/article.js")
  273. </environment>