初步可用后台

This commit is contained in:
j4587698 2020-02-16 22:11:24 +08:00
parent 104cfb2463
commit c448afdd1d
37 changed files with 2278 additions and 310 deletions

View File

@ -1,18 +0,0 @@
using JXCMS.CMS.Attribute;
using Microsoft.AspNetCore.Mvc;
namespace JXCMS.CMS.Admin.Controllers
{
[Area("Admin")]
[AdminAuthentication]
public class ArticleController : Controller
{
// GET
public IActionResult Index()
{
ViewBag.title = "所有文章";
return View();
}
}
}

View File

@ -0,0 +1,73 @@
using System.Linq;
using FreeSql;
using JXCMS.CMS.Attribute;
using JXCMS.CMS.Entity;
using JXCMS.CMS.Movie.Entity;
using JXCMS.CMS.Movie.Spider;
using JXCMS.CMS.Movie.Utils;
using Microsoft.AspNetCore.Mvc;
namespace JXCMS.CMS.Movie.Admin.Controllers
{
[Area("Admin")]
[AdminAuthentication]
public class ClassifyController : Controller
{
public IActionResult Index(int pageNumber = 1, int pageSize = 20)
{
var list = ClassifyEntity.Select.Include(x => x.Parent).Count(out long count).Page(pageNumber, pageSize).ToList(
x => new ClassifyEntity{Id = x.Id, Name = x.Name, Alias = x.Alias, ParentId = x.ParentId, Parent = x.Parent, UpdateTime = x.UpdateTime,
Count = MovieEntity.Select.Where(y => y.ClassifyId == x.Id).Count()});
ViewBag.count = count;
ViewBag.pageNumber = pageNumber;
ViewBag.totlePage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
return View(list);
}
public IActionResult ClassifyDialog(int id)
{
ClassifyEntity classifyEntity = null;
if (id == 0)
{
classifyEntity = new ClassifyEntity();
ViewBag.title = "添加新分类";
ViewBag.classifyEntities = ClassifyEntity.Select.ToList();
}
else
{
classifyEntity = ClassifyEntity.Find(id);
ViewBag.title = "修改分类" + classifyEntity.Name;
ViewBag.classifyEntities = Classify.FindAllNotChildren(ClassifyEntity.Select.ToList(), id);
}
return View(classifyEntity);
}
public IActionResult DeleteClassify(int id)
{
if (MovieEntity.Select.Any(x => x.ClassifyId == id))
{
return Redirect(Url.Action("Index"));
}
if (ClassifyEntity.Select.Any(x => x.ParentId == id))
{
ClassifyEntity.Where(x => x.ParentId == id).ToUpdate().Set(x => x.ParentId, 0).ExecuteAffrows();
}
ClassifyEntity.Find(id).Delete();
return Redirect(Url.Action("Index"));
}
public IActionResult ModifyClassify(ClassifyEntity classifyEntity)
{
if (classifyEntity.Id != 0 &&
Classify.FindAllChildren(ClassifyEntity.Select.ToList(), classifyEntity.Id).Any(x => x.Id == classifyEntity.ParentId))
{
return Redirect(Url.Action("Index"));
}
classifyEntity.Save();
return Redirect(Url.Action("Index"));
}
}
}

View File

@ -1,8 +1,12 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
using FreeSql;
using JXCMS.CMS.Attribute;
using JXCMS.CMS.Movie.Entity;
using JXCMS.CMS.Movie.Jobs;
using JXCMS.CMS.Movie.Spider;
using JXCMS.CMS.Movie.Utils;
using JXCMS.Core.TimingTask;
using Microsoft.AspNetCore.Mvc;
using Quartz;
@ -16,7 +20,11 @@ namespace JXCMS.CMS.Movie.Admin.Controllers
public IActionResult Index(int pageNumber = 1, int pageSize = 20)
{
ViewBag.title = "采集地址";
var website = WebSiteEntity.Select.Count(out long count).Page(pageNumber, pageSize).ToList();
var website = WebSiteEntity.Select.Count(out long count).Page(pageNumber, pageSize).ToList().Select(x =>
{
x.NextRunTime = x.IsEnable ? QuartzTask.GetCronSchedule(x.Cron, 1, DateTimeOffset.Now) : "已禁用";
return x;
}).ToList();
ViewBag.website = website;
ViewBag.count = count;
ViewBag.pageNumber = pageNumber;
@ -27,6 +35,10 @@ namespace JXCMS.CMS.Movie.Admin.Controllers
[HttpPost]
public IActionResult AddWebSite(WebSiteEntity webSiteEntity)
{
if (!CronExpression.IsValidExpression(webSiteEntity.Cron))
{
return Redirect(Url.Action("Index"));
}
webSiteEntity.Save();
if (webSiteEntity.IsEnable)
{
@ -87,7 +99,26 @@ namespace JXCMS.CMS.Movie.Admin.Controllers
}
return View(webSiteEntity);
}
public IActionResult BindingClassifyDialog(int id)
{
var classifyEntities = Classify.Structured(ClassifyEntity.Select.ToList());
var webSiteClassifyEntities = WebSiteClassifyEntity.Where(x => x.WebSiteId == id).ToList();
var webSiteEntity = WebSiteEntity.Find(id);
classifyEntities.Insert(0, new ClassifyEntity(){Id = 0, Name = "未绑定"});
ViewBag.classifyEntities = classifyEntities;
ClassifySpider.GetAllClassifyFromUrl(id, webSiteEntity.ApiUrl, webSiteClassifyEntities);
ViewBag.title = "修改" + webSiteEntity.WebSiteName + "的类型绑定";
return View(webSiteClassifyEntities);
}
public IActionResult UpdateBindingClassify(WebSiteClassifyEntity[] webSiteClassifyEntities)
{
foreach (var webSiteClassifyEntity in webSiteClassifyEntities)
{
webSiteClassifyEntity.Save();
}
return Redirect(Url.Action("Index"));
}
}
}

View File

@ -1,17 +1,15 @@
using System.Security.Claims;
using System.Threading.Tasks;
using JXCMS.CMS.Attribute;
using JXCMS.CMS.Entity;
using JXCMS.CMS.Movie.Entity;
using JXCMS.CMS.Utils;
using JXCMS.Core.Auth;
using JXCMS.Core.Encrypt;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace JXCMS.CMS.Admin.Controllers
namespace JXCMS.CMS.Movie.Admin.Controllers
{
[Area("Admin")]
[AdminAuthentication]

View File

@ -73,6 +73,180 @@ namespace JXCMS.CMS.Admin.Controllers
Type = "Settings"
});
BaseEntity.Orm.Insert(settings).ExecuteInserted();
var classify = new ClassifyEntity()
{
Name = "电影",
Alias = "dianying",
ParentId = 0
};
classify.Save();
List<ClassifyEntity> classifyEntities = new List<ClassifyEntity>();
classifyEntities.Add(new ClassifyEntity()
{
Name = "动作片",
Alias = "dongzuo",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "喜剧片",
Alias = "xiju",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "爱情片",
Alias = "aiqing",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "科幻片",
Alias = "kehuan",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "恐怖片",
Alias = "kongbu",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "剧情片",
Alias = "juqing",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "战争片",
Alias = "zhanzheng",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "纪录片",
Alias = "jilupian",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "微电影",
Alias = "weidianying",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "伦理片",
Alias = "lunli",
ParentId = classify.Id
});
BaseEntity.Orm.Insert(classifyEntities).ExecuteAffrows();
classify = new ClassifyEntity()
{
Name = "电视剧",
Alias = "tv",
ParentId = 0
};
classify.Save();
classifyEntities.Clear();
classifyEntities.Add(new ClassifyEntity()
{
Name = "国产剧",
Alias = "guochanju",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "香港剧",
Alias = "xianggangju",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "韩国剧",
Alias = "hanguoju",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "欧美剧",
Alias = "oumeiju",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "台湾剧",
Alias = "taiwanju",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "日本剧",
Alias = "ribenju",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "海外剧",
Alias = "haiwaiju",
ParentId = classify.Id
});
BaseEntity.Orm.Insert(classifyEntities).ExecuteAffrows();
classify = new ClassifyEntity()
{
Name = "综艺片",
Alias = "zongyi",
ParentId = 0
};
classify.Save();
classifyEntities.Clear();
classifyEntities.Add(new ClassifyEntity()
{
Name = "内地综艺",
Alias = "neidizongyi",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "日韩综艺",
Alias = "rihanzongyi",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "欧美综艺",
Alias = "oumeizongyi",
ParentId = classify.Id
});
BaseEntity.Orm.Insert(classifyEntities).ExecuteAffrows();
classify = new ClassifyEntity()
{
Name = "动漫片",
Alias = "dongman",
ParentId = 0
};
classify.Save();
classifyEntities.Clear();
classifyEntities.Add(new ClassifyEntity()
{
Name = "国产动漫",
Alias = "guochandongman",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "日韩动漫",
Alias = "rihandongman",
ParentId = classify.Id
});
classifyEntities.Add(new ClassifyEntity()
{
Name = "欧美动漫",
Alias = "oumeidongman",
ParentId = classify.Id
});
BaseEntity.Orm.Insert(classifyEntities).ExecuteAffrows();
System.IO.File.Create("install.lock");
return View();
}

View File

@ -0,0 +1,21 @@
using JXCMS.CMS.Attribute;
using JXCMS.CMS.Movie.Entity;
using Microsoft.AspNetCore.Mvc;
namespace JXCMS.CMS.Movie.Admin.Controllers
{
[Area("Admin")]
[AdminAuthentication]
public class MovieController : Controller
{
public IActionResult Index(int pageNumber = 1, int pageSize = 20)
{
var model = MovieEntity.Select.Count(out long count).Page(pageNumber, pageSize)
.Include(x => x.DirectorEntity).Include(x => x.ClassifyEntity).ToList();
ViewBag.count = count;
ViewBag.pageNumber = pageNumber;
ViewBag.totlePage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
return View(model);
}
}
}

View File

@ -1,265 +0,0 @@
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-toolbar clearfix">
<form class="pull-right search-bar" method="get" action="#!" role="form">
<div class="input-group">
<div class="input-group-btn">
<input type="hidden" name="search_field" id="search-field" value="title">
<button class="btn btn-default dropdown-toggle" id="search-btn" data-toggle="dropdown" type="button" aria-haspopup="true" aria-expanded="false">
标题 <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li> <a tabindex="-1" href="javascript:void(0)" data-field="title">标题</a> </li>
<li> <a tabindex="-1" href="javascript:void(0)" data-field="cat_name">栏目</a> </li>
</ul>
</div>
<input type="text" class="form-control" value="" name="keyword" placeholder="请输入名称">
</div>
</form>
<div class="toolbar-btn-action">
<a class="btn btn-primary m-r-5" href="#!"><i class="mdi mdi-plus"></i> 新增</a>
<a class="btn btn-success m-r-5" href="#!"><i class="mdi mdi-check"></i> 启用</a>
<a class="btn btn-warning m-r-5" href="#!"><i class="mdi mdi-block-helper"></i> 禁用</a>
<a class="btn btn-danger" href="#!"><i class="mdi mdi-window-close"></i> 删除</a>
</div>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" id="check-all"><span></span>
</label>
</th>
<th>编号</th>
<th>标题</th>
<th>书籍</th>
<th>作者</th>
<th>阅读量</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" name="ids[]" value="1"><span></span>
</label>
</td>
<td>1</td>
<td>第01章 天涯思君不可忘</td>
<td>《倚天屠龙记》</td>
<td>金庸</td>
<td>36</td>
<td><font class="text-success">正常</font></td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" href="#!" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>
<a class="btn btn-xs btn-default" href="#!" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>
</div>
</td>
</tr>
<tr>
<td>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" name="ids[]" value="2"><span></span>
</label>
</td>
<td>2</td>
<td>第01章 古道腾驹惊白发,危峦快剑识青翎</td>
<td>《书剑恩仇录》</td>
<td>金庸</td>
<td>44</td>
<td><font class="text-success">正常</font></td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" href="#!" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>
<a class="btn btn-xs btn-default" href="#!" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>
</div>
</td>
</tr>
<tr>
<td>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" name="ids[]" value="3"><span></span>
</label>
</td>
<td>3</td>
<td>一个戴水獭皮帽子的朋友</td>
<td>《湘行散记》</td>
<td>沈从文</td>
<td>39</td>
<td><font class="text-success">正常</font></td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" href="#!" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>
<a class="btn btn-xs btn-default" href="#!" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>
</div>
</td>
</tr>
<tr>
<td>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" name="ids[]" value="4"><span></span>
</label>
</td>
<td>4</td>
<td>你是要灼灼容颜,还是要宜其室家</td>
<td>《诗三百:思无邪》</td>
<td>安意如</td>
<td>36</td>
<td><font class="text-success">正常</font></td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" href="#!" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>
<a class="btn btn-xs btn-default" href="#!" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>
</div>
</td>
</tr>
<tr>
<td>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" name="ids[]" value="5"><span></span>
</label>
</td>
<td>5</td>
<td>海上的消息</td>
<td>《打开心内的窗》</td>
<td>林清玄</td>
<td>32</td>
<td><font class="text-success">正常</font></td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" href="#!" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>
<a class="btn btn-xs btn-default" href="#!" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>
</div>
</td>
</tr>
<tr>
<td>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" name="ids[]" value="6"><span></span>
</label>
</td>
<td>6</td>
<td>楔子 一阕词来 南国清秋魂梦绕 十年人散 绣房红烛剑光寒</td>
<td>《七剑下天山》</td>
<td>梁羽生</td>
<td>42</td>
<td><font class="text-success">正常</font></td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" href="#!" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>
<a class="btn btn-xs btn-default" href="#!" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>
</div>
</td>
</tr>
<tr>
<td>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" name="ids[]" value="7"><span></span>
</label>
</td>
<td>7</td>
<td>祝福</td>
<td>《彷徨》</td>
<td>鲁迅</td>
<td>40</td>
<td><font class="text-success">正常</font></td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" href="#!" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>
<a class="btn btn-xs btn-default" href="#!" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>
</div>
</td>
</tr>
<tr>
<td>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" name="ids[]" value="8"><span></span>
</label>
</td>
<td>8</td>
<td>一个女长年的故事</td>
<td>《莫泊桑短篇小说集》</td>
<td>莫泊桑</td>
<td>36</td>
<td><font class="text-success">正常</font></td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" href="#!" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>
<a class="btn btn-xs btn-default" href="#!" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>
</div>
</td>
</tr>
<tr>
<td>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" name="ids[]" value="9"><span></span>
</label>
</td>
<td>9</td>
<td>第一回 赈民饥包公奉旨 图谋害庞相施计</td>
<td>《五虎征西》</td>
<td>李雨堂</td>
<td>35</td>
<td><font class="text-success">正常</font></td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" href="#!" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>
<a class="btn btn-xs btn-default" href="#!" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>
</div>
</td>
</tr>
<tr>
<td>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" name="ids[]" value="10"><span></span>
</label>
</td>
<td>10</td>
<td>第一回 于按察山东赴任 邹其仁赴路登程</td>
<td>《于公案》</td>
<td>佚名</td>
<td>37</td>
<td><font class="text-success">正常</font></td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" href="#!" title="编辑" data-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>
<a class="btn btn-xs btn-default" href="#!" title="删除" data-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<ul class="pagination">
<li class="disabled"><span>«</span></li>
<li class="active"><span>1</span></li>
<li><a href="#1">2</a></li>
<li><a href="#1">3</a></li>
<li><a href="#1">4</a></li>
<li><a href="#1">5</a></li>
<li><a href="#1">6</a></li>
<li><a href="#1">7</a></li>
<li><a href="#1">8</a></li>
<li class="disabled"><span>...</span></li>
<li><a href="#!">14452</a></li>
<li><a href="#!">14453</a></li>
<li><a href="#!">»</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,42 @@
@using JXCMS.CMS.Movie.Entity
@model JXCMS.CMS.Movie.Entity.ClassifyEntity
@{
Layout = "_DialogLayout";
}
<form id="modify_classify" action="@Url.Action("ModifyClassify")" method="post">
<input type="hidden" id="id" name="id" value="@Model.Id"/>
<div class="form-group">
<label for="name" class="control-label">分类名称:</label>
<input type="text" class="form-control" id="name" name="name" value="@Model.Name">
</div>
<div class="form-group">
<label for="alias" class="control-label">别名:</label>
<input type="text" class="form-control" id="alias" name="alias" value="@Model.Alias">
</div>
<div class="form-group">
<label for="parentId" class="control-label">父级分类:</label>
<select class="form-control" id="parentId" name="parentId">
<option value="0">无</option>
@foreach (ClassifyEntity classify in ViewBag.classifyEntities)
{
@:<option value="@classify.Id" @(Model.ParentId == classify.Id ? "selected" : "")>@classify.Name</option>
}
</select>
</div>
</form>
@section dialogScript
{
<script type="text/javascript">
$('#commit').click(function() {
var name = $("#name").val();
if (name === ""){
lightyear.notify('分类名称不能为空', 'danger', 100);
return;
}
$('#modify_classify').submit();
})
</script>
}

View File

@ -0,0 +1,160 @@
@using JXCMS.CMS.Movie.Entity
@using JXCMS.Core.Extensions
@model List<JXCMS.CMS.Movie.Entity.ClassifyEntity>
@{
ViewBag.Title = "分类目录";
Layout = "_Layout";
}
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-toolbar clearfix">
<div class="toolbar-btn-action">
<a data-src="@Url.Action("ClassifyDialog", "Classify", new {id = 0})" class="btn btn-primary m-r-5" id="new" data-toggle="modal" data-target="#exampleModal"><i class="mdi mdi-plus"></i> 新增</a>
</div>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>名称</th>
<th>别名</th>
<th>上级分类</th>
<th>视频数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@if (Model.Count == 0)
{
<tr>
<td colspan="5" style="text-align: center">无数据</td>
</tr>
}
@foreach (var classifyEntity in Model)
{
<tr>
<td>@classifyEntity.Name</td>
<td>@(classifyEntity.Alias.IsNullOrEmpty() ? "-" : classifyEntity.Alias)</td>
<td>@(classifyEntity.Parent == null ? "无" : classifyEntity.Parent.Name)</td>
<td>@classifyEntity.Count</td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" data-src="@Url.Action("ClassifyDialog", "Classify", new {id = classifyEntity.Id})" title="编辑" data-toggle="modal" data-target="#exampleModal">
<i class="mdi mdi-pencil"></i>
</a>
<a class="btn btn-xs btn-default" title="删除" data-toggle="tooltip" onclick="delClassify(@classifyEntity.Id, '@classifyEntity.Name')"
@if (classifyEntity.Count > 0)
{
@:disabled
}>
<i class="mdi mdi-window-close"></i>
</a>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
<ul class="pagination">
@if (ViewBag.pageNumber != 1)
{
<li>
<a href="@Url.Action("Index", "Classify")">&lt;&lt;</a>
</li>
}
@for (int i = ViewBag.pageNumber - 3; i < ViewBag.pageNumber + 3; i++)
{
if (i < 1 || i > ViewBag.totlePage)
{
continue;
}
if (i == ViewBag.pageNumber)
{
<li class="active">
<span>@i</span>
</li>
}
else
{
<li>
<a href="@Url.Action("Index", "Classify", new {pageNumber = i})">@i</a>
</li>
}
}
@if (ViewBag.pageNumber < ViewBag.totlePage)
{
<li>
<a href="@Url.Action("Index", "Classify", new {pageNumber = ViewBag.totlePage})">&gt;&gt;</a>
</li>
}
</ul>
</div>
</div>
</div>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
正在加载,请稍后...
</div>
</div>
</div>
</div>
<form id="delForm" action="@Url.Action("DeleteClassify")" method="post">
<input type="hidden" name="id" id="delId"/>
</form>
</div>
@section style
{
<link rel="stylesheet" href="@Url.ContentAdmin("js/jconfirm/jquery-confirm.min.css")">
}
@section script
{
<script src="@Url.ContentAdmin("js/bootstrap-notify.min.js")"></script>
<script type="text/javascript" src="@Url.ContentAdmin("js/lightyear.js")"></script>
<script src="@Url.ContentAdmin("js/jconfirm/jquery-confirm.min.js")"></script>
<script type="text/javascript">
$('#exampleModal').on('show.bs.modal', function(event) {
var button = $(event.relatedTarget); // Button that triggered the modal
var recipient = button.data('src'); // Extract info from data-* attributes
var content = $(this).find(".modal-content");
content.html("正在加载,请稍后...");
$.get(recipient, function(data, status) {
if (status === "success") {
content.html(data)
} else{
content.html("发生错误,请重试")
}
})
});
function delClassify(id, name) {
$.alert({
title: '删除分类地址' + name,
content: '是否删除' + name + '?(如果该分类下有子分类,子分类将变为顶级分类)<br />该操作不可恢复',
buttons: {
confirm: {
text: '是',
btnClass: 'btn-primary',
action: function(){
$('#delId').val(id);
$('#delForm').submit();
}
},
cancel: {
text: '否'
}
}
});
}
</script>
}

View File

@ -0,0 +1,35 @@
@{
Layout = "_DialogLayout";
}
@using JXCMS.CMS.Movie.Entity
@model List<JXCMS.CMS.Movie.Entity.WebSiteClassifyEntity>
@{
var classifyEntities = (List<ClassifyEntity>) ViewBag.classifyEntities;
}
<form id="modify_website" action="@Url.Action("UpdateBindingClassify")" method="post">
@for (int i = 0; i < Model.Count; i++)
{
@Html.HiddenFor(x => x[i].Id)
@Html.HiddenFor(x => x[i].WebSiteId)
@Html.HiddenFor(x => x[i].TypeName)
@Html.HiddenFor(x => x[i].TypeId)
<div class="input-daterange input-group" style="margin-bottom: 10px">
<span class="form-control">@Model[i].TypeName</span>
<span class="input-group-addon">
<i class="mdi mdi-link-variant"></i>
</span>
@Html.DropDownListFor(x => x[i].ClassifyId, new SelectList(classifyEntities, "Id", "Name", Model[i].ClassifyId),
new {@class = "form-control"})
</div>
}
</form>
@section dialogScript
{
<script type="text/javascript">
$('#commit').click(function() {
$('#modify_website').submit();
})
</script>
}

View File

@ -47,10 +47,17 @@
<th>网站url</th>
<th>采集cron</th>
<th>状态</th>
<th>下次执行时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@if (ViewBag.website.Count == 0)
{
<tr>
<td colspan="7" style="text-align: center">无数据</td>
</tr>
}
@foreach (WebSiteEntity webSiteEntity in ViewBag.website)
{
<tr>
@ -65,12 +72,13 @@
<td>
<span class="text-success">@(webSiteEntity.IsEnable ? "正常" : "已禁用")</span>
</td>
<td>@webSiteEntity.NextRunTime</td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" data-src="@Url.Action("WebSiteDialog", "Collection", new {id = webSiteEntity.Id})" title="编辑" data-toggle="modal" data-target="#exampleModal">
<i class="mdi mdi-pencil"></i>
</a>
<a class="btn btn-xs btn-default" href="#" title="绑定分类" onclick="delWebsite(@webSiteEntity.Id, '@webSiteEntity.WebSiteName')">
<a class="btn btn-xs btn-default" data-src="@Url.Action("BindingClassifyDialog", "Collection", new {id = webSiteEntity.Id})" data-toggle="modal" data-target="#exampleModal">
<i class="mdi mdi-link-variant"></i>
</a>
<a class="btn btn-xs btn-default" href="#" title="删除" onclick="delWebsite(@webSiteEntity.Id, '@webSiteEntity.WebSiteName')">

View File

@ -34,11 +34,10 @@
<ul class="nav nav-drawer">
<li class="nav-item active"> <a class="multitabs" href="@Url.Action("Home")"><i class="mdi mdi-home"></i> <span>后台首页</span></a> </li>
<li class="nav-item nav-item-has-subnav">
<a href="javascript:void(0)"><i class="mdi mdi-format-align-justify"></i> <span>文章</span></a>
<a href="javascript:void(0)"><i class="mdi mdi-format-align-justify"></i> <span>影视</span></a>
<ul class="nav nav-subnav">
<li> <a class="multitabs" href="@Url.Action("Index", "Article")">所有文章</a> </li>
<li> <a class="multitabs" href="lyear_forms_radio.html">写文章</a> </li>
<li> <a class="multitabs" href="lyear_forms_checkbox.html">分类目录</a> </li>
<li> <a class="multitabs" href="@Url.Action("Index", "Movie")">所有影视</a> </li>
<li> <a class="multitabs" href="@Url.Action("Index", "Classify")">分类目录</a> </li>
<li> <a class="multitabs" href="lyear_forms_switch.html">标签</a> </li>
</ul>
</li>

View File

@ -0,0 +1,131 @@
@model List<JXCMS.CMS.Movie.Entity.MovieEntity>
@{
Layout = "_Layout";
}
<div class="container-fluid p-t-15">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-toolbar clearfix">
<form class="pull-right search-bar" method="get" action="#!" role="form">
<div class="input-group">
<div class="input-group-btn">
<input type="hidden" name="search_field" id="search-field" value="title">
<button class="btn btn-default dropdown-toggle" id="search-btn" data-toggle="dropdown" type="button" aria-haspopup="true" aria-expanded="false">
标题 <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<a tabindex="-1" href="javascript:void(0)" data-field="title">标题</a>
</li>
<li>
<a tabindex="-1" href="javascript:void(0)" data-field="cat_name">栏目</a>
</li>
</ul>
</div>
<input type="text" class="form-control" value="" name="keyword" placeholder="请输入名称">
</div>
</form>
<div class="toolbar-btn-action">
<a class="btn btn-primary m-r-5" href="#!"><i class="mdi mdi-plus"></i> 新增</a>
<a class="btn btn-success m-r-5" href="#!"><i class="mdi mdi-check"></i> 显示</a>
<a class="btn btn-warning m-r-5" href="#!"><i class="mdi mdi-block-helper"></i> 隐藏</a>
<a class="btn btn-danger" href="#!"><i class="mdi mdi-window-close"></i> 删除</a>
</div>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" id="check-all"><span></span>
</label>
</th>
<th>名称</th>
<th>导演</th>
<th>年份</th>
<th>语种</th>
<th>分类</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach (var movieEntity in Model)
{
<tr>
<td>
<label class="lyear-checkbox checkbox-primary">
<input type="checkbox" name="ids[]" value="1"><span></span>
</label>
</td>
<td>@movieEntity.Name</td>
<td>@movieEntity.DirectorEntity.DirectorName</td>
<td>@movieEntity.Year</td>
<td>@movieEntity.Lang</td>
<td>@movieEntity.ClassifyEntity.Name</td>
<td>
<font class="text-success">@(movieEntity.IsEnable ? "正常" : "已隐藏")</font>
</td>
<td>
<div class="btn-group">
<a class="btn btn-xs btn-default" href="#!" title="编辑" data-toggle="tooltip">
<i class="mdi mdi-pencil"></i>
</a>
<a class="btn btn-xs btn-default" href="#!" title="删除" data-toggle="tooltip">
<i class="mdi mdi-window-close"></i>
</a>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
<ul class="pagination">
@if (ViewBag.pageNumber != 1)
{
<li>
<a href="@Url.Action("Index", "Collection")">&lt;&lt;</a>
</li>
}
@for (int i = ViewBag.pageNumber - 3; i < ViewBag.pageNumber + 3; i++)
{
if (i < 1 || i > ViewBag.totlePage)
{
continue;
}
if (i == ViewBag.pageNumber)
{
<li class="active">
<span>@i</span>
</li>
}
else
{
<li>
<a href="@Url.Action("Index", "Collection", new {pageNumber = i})">@i</a>
</li>
}
}
@if (ViewBag.pageNumber < ViewBag.totlePage)
{
<li>
<a href="@Url.Action("Index", "Collection", new {pageNumber = ViewBag.totlePage})">&gt;&gt;</a>
</li>
}
</ul>
</div>
</div>
</div>
</div>
</div>

View File

@ -6,6 +6,8 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using JXCMS.CMS.Models;
using JXCMS.CMS.Movie.Entity;
using JXCMS.CMS.Movie.Spider;
using JXCMS.Core.Themes;
namespace JXCMS.CMS.Controllers
@ -35,5 +37,10 @@ namespace JXCMS.CMS.Controllers
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
public IActionResult Test()
{
return View();
}
}
}

View File

@ -0,0 +1,14 @@
using System.Collections.Generic;
using FreeSql;
using FreeSql.DataAnnotations;
namespace JXCMS.CMS.Movie.Entity
{
public class ActorEntity : BaseEntity<ActorEntity, int>
{
public string ActorName { get; set; }
[Navigate(ManyToMany = typeof(MovieActorEntity))]
public List<MovieEntity> MovieEntities { get; set; }
}
}

View File

@ -1,4 +1,7 @@
using System.Collections.Generic;
using FreeSql;
using FreeSql.DataAnnotations;
using Renci.SshNet.Messages.Transport;
namespace JXCMS.CMS.Movie.Entity
{
@ -6,6 +9,17 @@ namespace JXCMS.CMS.Movie.Entity
{
public string Name { get; set; }
public string Alias { get; set; }
public int ParentId { get; set; }
[Navigate("ParentId")]
public ClassifyEntity Parent { get; set; }
public ICollection<ClassifyEntity> Childs { get; set; }
[Column(IsIgnore = true)]
public long Count { get; set; }
}
}

View File

@ -0,0 +1,9 @@
using FreeSql;
namespace JXCMS.CMS.Movie.Entity
{
public class DirectorEntity : BaseEntity<DirectorEntity, int>
{
public string DirectorName { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using FreeSql;
using FreeSql.DataAnnotations;
namespace JXCMS.CMS.Movie.Entity
{
public class MovieActorEntity : BaseEntity<MovieActorEntity, int>
{
public int ActorId { get; set; }
[Navigate("ActorId")]
public ActorEntity ActorEntity { get; set; }
public int MovieId { get; set; }
[Navigate("MovieId")]
public MovieEntity MovieEntity { get; set; }
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using FreeSql;
using FreeSql.DataAnnotations;
namespace JXCMS.CMS.Movie.Entity
{
public class MovieEntity : BaseEntity<MovieEntity, int>
{
public string Name { get; set; }
public string Pic { get; set; }
public int ClassifyId { get; set; }
public string Lang { get; set; }
public string Area { get; set; }
public string Year { get; set; }
public int DirectorId { get; set; }
public DateTime LastUpdate { get; set; }
public bool IsEnable { get; set; } = true;
[StringLength(-1)]
public string Des { get; set; }
[Navigate("DirectorId")]
public virtual DirectorEntity DirectorEntity { get; set; }
[Navigate("ClassifyId")]
public virtual ClassifyEntity ClassifyEntity { get; set; }
[Navigate(ManyToMany = typeof(MovieActorEntity))]
public virtual List<ActorEntity> ActorEntities { get; set; }
[Navigate("Id")]
public virtual List<MovieListEntity> MovieListEntities { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using FreeSql;
using FreeSql.DataAnnotations;
namespace JXCMS.CMS.Movie.Entity
{
public class MovieListEntity : BaseEntity<MovieListEntity, int>
{
public string Name { get; set; }
public string PlayUrl { get; set; }
public string Type { get; set; }
public int MovieId { get; set; }
public int WebSiteId { get; set; }
[Navigate("MovieId")]
public virtual MovieEntity MovieEntity { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using FreeSql;
using FreeSql.DataAnnotations;
namespace JXCMS.CMS.Movie.Entity
{
public class WebSiteClassifyEntity : BaseEntity<WebSiteClassifyEntity, int>
{
public int WebSiteId { get; set; }
public int TypeId { get; set; }
public string TypeName { get; set; }
public int ClassifyId { get; set; }
[Navigate("WebSiteId")]
public virtual WebSiteEntity WebSiteEntity { get; set; }
}
}

View File

@ -1,4 +1,7 @@
using System;
using System.Collections.Generic;
using FreeSql;
using FreeSql.DataAnnotations;
namespace JXCMS.CMS.Movie.Entity
{
@ -11,5 +14,15 @@ namespace JXCMS.CMS.Movie.Entity
public string Cron { get; set; } = "0 0 * * * ?";
public bool IsEnable { get; set; } = true;
public string LatestMovieNote { get; set; }
public DateTime LatestMoveTime { get; set; }
[Navigate("Id")]
public List<ClassifyEntity> WebSiteClassifyEntities { get; set; }
[Column(IsIgnore = true)]
public string NextRunTime { get; set; }
}
}

View File

@ -21,6 +21,7 @@
<ItemGroup>
<Folder Include="Admin\Content" />
<Folder Include="Logs" />
<Folder Include="Views\Default" />
</ItemGroup>

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using JXCMS.CMS.Movie.Entity;
namespace JXCMS.CMS.Movie.Models
{
public class MovieListInfoModel
{
public string RecordCount { get; set; }
public string PageSize { get; set; }
public string CurrentPage { get; set; }
public string PageCount { get; set; }
public List<MovieInfoModel> MovieInfoModels { get; set; } = new List<MovieInfoModel>();
}
public class MovieInfoModel
{
public string Id { get; set; }
public string TypeId { get; set; }
public DateTime LastUpdateTime { get; set; }
public string Name { get; set; }
public string TypeName { get; set; }
}
}

View File

@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
namespace JXCMS.CMS
{
@ -22,6 +23,6 @@ namespace JXCMS.CMS
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}).UseSerilog();
}
}

View File

@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Xml;
using JXCMS.CMS.Movie.Entity;
using SufeiUtil;
namespace JXCMS.CMS.Movie.Spider
{
public class ClassifySpider
{
public static void GetAllClassifyFromUrl(int websiteId, string url, List<WebSiteClassifyEntity> webSiteClassifyEntities)
{
var helper = new HttpHelper();
var item = new HttpItem();
item.URL = url;
var result = helper.GetHtml(item);
if (result.StatusCode == HttpStatusCode.OK)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(result.Html);
var classNode = doc.SelectSingleNode("/rss/class");
foreach (XmlNode childNode in classNode.ChildNodes)
{
if (webSiteClassifyEntities.All(x => x.TypeId.ToString() != childNode.Attributes["id"].Value))
{
WebSiteClassifyEntity webSiteClassifyEntity = new WebSiteClassifyEntity();
webSiteClassifyEntity.TypeId = int.Parse(childNode.Attributes["id"].Value);
webSiteClassifyEntity.TypeName = childNode.InnerText;
webSiteClassifyEntity.WebSiteId = websiteId;
webSiteClassifyEntities.Add(webSiteClassifyEntity);
}
}
}
}
}
}

View File

@ -0,0 +1,265 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Xml;
using FreeSql;
using JXCMS.CMS.Movie.Entity;
using JXCMS.CMS.Movie.Models;
using JXCMS.Core.Extensions;
using JXCMS.Core.Log;
using SufeiUtil;
using Log = Serilog.Log;
namespace JXCMS.CMS.Movie.Spider
{
public class MovieSpider
{
private readonly List<WebSiteClassifyEntity> _webSiteClassifyEntities;
private readonly List<ActorEntity> _actorEntities;
private readonly List<DirectorEntity> _directorEntities;
private static MovieSpider _instance;
public static MovieSpider Instance => _instance ??= new MovieSpider();
private MovieSpider()
{
_webSiteClassifyEntities = WebSiteClassifyEntity.Select.ToList();
_actorEntities = ActorEntity.Select.ToList();
_directorEntities = DirectorEntity.Select.ToList();
}
public MovieListInfoModel GetMovieList(WebSiteEntity webSiteEntity, int number)
{
HttpItem item = new HttpItem();
item.URL = $"{webSiteEntity.ApiUrl}?pg={number}";
HttpHelper helper = new HttpHelper();
var result = helper.GetHtml(item);
if (result.StatusCode == HttpStatusCode.OK)
{
Log.Logger.Information($"{{@name}} 成功获取地址:{item.URL}", webSiteEntity.WebSiteName);
XmlDocument doc = new XmlDocument();
doc.LoadXml(result.Html);
var listNode = doc.SelectSingleNode("/rss/list");
MovieListInfoModel movieListInfoModel = new MovieListInfoModel();;
movieListInfoModel.CurrentPage = listNode.Attributes["page"].Value;
movieListInfoModel.PageCount = listNode.Attributes["pagecount"].Value;
movieListInfoModel.PageSize = listNode.Attributes["pagesize"].Value;
movieListInfoModel.RecordCount = listNode.Attributes["recordcount"].Value;
var videos = listNode.SelectNodes("//video");
foreach (XmlNode video in videos)
{
MovieInfoModel model = new MovieInfoModel
{
LastUpdateTime = DateTime.Parse(video.SelectSingleNode("last").InnerText),
Name = video.SelectSingleNode("name").InnerText,
TypeId = video.SelectSingleNode("tid").InnerText,
Id = video.SelectSingleNode("id").InnerText,
TypeName = video.SelectSingleNode("type").InnerText
};
movieListInfoModel.MovieInfoModels.Add(model);
}
return movieListInfoModel;
}
Log.Warning($"{{@name}} 获取api失败错误码{result.StatusCode}", webSiteEntity.WebSiteName);
return null;
}
public DateTime GetMovieInfos(WebSiteEntity webSiteEntity, List<(string id, string name, string typeId)> idNameTypes)
{
HttpItem item = new HttpItem();
item.URL = $"{webSiteEntity.ApiUrl}?ac=videolist&ids={string.Join(",", idNameTypes.Select(x => x.id))}";
HttpHelper helper = new HttpHelper();
var result = helper.GetHtml(item);
if (result.StatusCode == HttpStatusCode.OK)
{
DateTime dt = DateTime.MinValue;
Log.Logger.Information($"{{@name}} 成功获取地址:{item.URL}", webSiteEntity.WebSiteName);
XmlDocument doc = new XmlDocument();
doc.LoadXml(result.Html);
var videoNode = doc.SelectNodes("/rss/list/video");
foreach (XmlNode video in videoNode)
{
var name = video.SelectSingleNode("name").InnerText;
var director = video.SelectSingleNode("director").InnerText;
if (director.IsNullOrEmpty())
{
director = "未知";
}
var movieEntity = MovieEntity.Select.Include(x => x.DirectorEntity)
.Where(x => x.Name == name && x.DirectorEntity.DirectorName == director).First();
if (movieEntity == null)