Commit b2df69b1 authored by wangtao's avatar wangtao

增加课程列表,上传接口

parent abf68cfb
......@@ -153,4 +153,11 @@ abstract class AdminBase extends BaseController
}
}
public function downloadfile($fileid)
{
$fileinfo = get_upload_file($fileid,'info');
return download('.'.$fileinfo['fileurl'], $fileinfo['filename'],true);
}
}
\ No newline at end of file
......@@ -11,7 +11,7 @@
namespace app\admin\controller\course;
use app\admin\controller\AdminBase;
use app\model\ShCourse AS ShCourseModel;
use app\model\ShCourse as ShCourseModel;
use think\App;
use think\facade\Db;
use app\model\CourseCategory as CourseCategoryModel;
......@@ -20,7 +20,7 @@ use app\model\CourseCategory as CourseCategoryModel;
/**
* 后台主控制器
*/
class course extends AdminBase
class Course extends AdminBase
{
protected $course;
......@@ -49,7 +49,8 @@ class course extends AdminBase
if (isset($post['cate_id']) && !empty($post['cate_id'])) {
$map[] = ['cate_id', '=', $post['cate_id']];
}
$list = $this->course->where($map)->append(['thumbpath','cate_name','teacher_name','status_text','tag_title','user_info'])->order('createtime desc')->paginate($post['limit']);
$list = $this->course->where($map)->append(['thumbpath', 'cate_name', 'teacher_name', 'status_text', 'tag_title', 'user_info', 'is_sell_text'])->order('createtime desc')->paginate($post['limit']);
return $this->returnMsg($list);
}
$category = CourseCategoryModel::field('*,pid as parentid')->where('is_del', 0)->order('sort desc')->select()->toArray();
......@@ -68,7 +69,6 @@ class course extends AdminBase
}
public function del()
{
$post = input();
......@@ -81,4 +81,40 @@ class course extends AdminBase
}
//审核课程
public function shenhecourse()
{
$post = input();
$errordesc = '';
$shstatus = 3;
if ($post['shstatus'] == 2) {
if (empty($post['errordesc'])) {
return $this->returnMsg("请输入失败原因");
}
$errordesc = $post['errordesc'];
$shstatus = 2;
}
$updatedata['status'] = $shstatus;
$updatedata['sh_time'] = time();
$updatedata['sh_error_desc'] = $errordesc;
$result = $this->course->where('id', $post['id'])->update($updatedata);
if ($result) {
return $this->returnMsg("操作成功",1);
}else{
return $this->returnMsg("操作失败");
}
}
//课程详情
public function detail()
{
$post = input();
$info = $this->course->where('id', $post['id'])->find();
$this->assign('info', $info);
return $this->fetch('', '', false);
}
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\admin\controller\course;
use app\admin\controller\AdminBase;
use app\model\ShCourse;
use app\model\ShCourseClass AS ShCourseClassModel;
use app\model\ShCourseClassCategory;
use think\App;
/**
* 后台主控制器
*/
class CourseClass extends AdminBase
{
protected $courseclass;
public function __construct(App $app)
{
parent::__construct($app);
$this->courseclass = new ShCourseClassModel();
}
// 课程列表
public function index(string $do = '')
{
$limit = 10;
if ($do == 'json') {
$post = input();
$post['limit'] = isset($post['limit']) ? $post['limit'] : $limit;
$map[] = ['is_del', '=', 0];
if (isset($post['kw']) && !empty($post['kw'])) {
$map[] = ['title', 'like', '%' . $post['kw'] . '%'];
}
if (isset($post['kc']) && !empty($post['kc'])) {
$kcmap[] = ['title', 'like', '%' . $post['kc'] . '%'];
$kcid_arr = ShCourse::where($kcmap)->column('id');
if($kcid_arr){
$map[] = ['course_id', 'in', $kcid_arr];
}else{
$map[] = ['course_id', 'in', 99999];
}
}
if (isset($post['zj']) && !empty($post['zj'])) {
$zjmap[] = ['title', 'like', '%' . $post['zj'] . '%'];
$zjid_arr = ShCourseClassCategory::where($zjmap)->column('id');
if($zjid_arr){
$map[] = ['cate_id', 'in', $zjid_arr];
}else{
$map[] = ['cate_id', 'in', 99999];
}
}
if (isset($post['course_id']) && !empty($post['course_id'])) {
$map[] = ['course_id', '=', $post['course_id']];
}
$list = $this->courseclass->where($map)->append(['course_title','user_info','course_class_cate','issktext','tvfilepath'])->order('createtime desc')->paginate($post['limit']);
return $this->returnMsg($list);
}
$this->assign('limit', $limit);
return $this->fetch('', '', false);
}
//快速编辑
public function editup()
{
$post = input();
$this->courseclass->update([$post['af'] => $post['av']], [['id', '=', $post['id']]]);
return $this->returnMsg('修改成功');
}
public function del()
{
$post = input();
$ids = is_array($post['id']) ? implode(',', $post['id']) : $post['id'];
if ($this->courseclass->where("id IN(" . $ids . ")")->update(['is_del' => 1])) {
return $this->returnMsg("删除成功", 1);
} else {
return $this->returnMsg("删除失败");
}
}
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\admin\controller\course;
use app\admin\controller\AdminBase;
use app\model\ShCourse;
use app\model\ShCourseClassCategory AS ShCourseClassCategoryModel;
use think\App;
/**
* 后台主控制器
*/
class CourseClassCategory extends AdminBase
{
protected $courseclasscategory;
public function __construct(App $app)
{
parent::__construct($app);
$this->courseclasscategory = new ShCourseClassCategoryModel();
}
// 课程列表
public function index(string $do = '')
{
$limit = 10;
if ($do == 'json') {
$post = input();
$post['limit'] = isset($post['limit']) ? $post['limit'] : $limit;
$map[] = ['is_del', '=', 0];
if (isset($post['kw']) && !empty($post['kw'])) {
$map[] = ['title', 'like', '%' . $post['kw'] . '%'];
}
if (isset($post['kc']) && !empty($post['kc'])) {
$kcmap[] = ['title', 'like', '%' . $post['kc'] . '%'];
$kcid_arr = ShCourse::where($kcmap)->column('id');
if($kcid_arr){
$map[] = ['course_id', 'in', $kcid_arr];
}else{
$map[] = ['course_id', 'in', 99999];
}
}
if (isset($post['course_id']) && !empty($post['course_id'])) {
$map[] = ['course_id', '=', $post['course_id']];
}
$list = $this->courseclasscategory->where($map)->append(['course_title','user_info'])->order('createtime desc')->paginate($post['limit']);
return $this->returnMsg($list);
}
$this->assign('limit', $limit);
return $this->fetch('', '', false);
}
//快速编辑
public function editup()
{
$post = input();
$this->courseclasscategory->update([$post['af'] => $post['av']], [['id', '=', $post['id']]]);
return $this->returnMsg('修改成功');
}
public function del()
{
$post = input();
$ids = is_array($post['id']) ? implode(',', $post['id']) : $post['id'];
if ($this->courseclasscategory->where("id IN(" . $ids . ")")->update(['is_del' => 1])) {
return $this->returnMsg("删除成功", 1);
} else {
return $this->returnMsg("删除失败");
}
}
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\admin\controller\course;
use app\admin\controller\AdminBase;
use app\model\ShCourse;
use app\model\ShCourseWork AS ShCourseWorkModel;
use think\App;
use function Symfony\Component\Translation\t;
/**
* 后台主控制器
*/
class CourseWork extends AdminBase
{
protected $coursework;
public function __construct(App $app)
{
parent::__construct($app);
$this->coursework = new ShCourseWorkModel();
}
// 课程列表
public function index(string $do = '')
{
$limit = 10;
if ($do == 'json') {
$post = input();
$post['limit'] = isset($post['limit']) ? $post['limit'] : $limit;
$map[] = ['is_del', '=', 0];
if (isset($post['kw']) && !empty($post['kw'])) {
$map[] = ['title', 'like', '%' . $post['kw'] . '%'];
}
if (isset($post['kc']) && !empty($post['kc'])) {
$kcmap[] = ['title', 'like', '%' . $post['kc'] . '%'];
$kcid_arr = ShCourse::where($kcmap)->column('id');
if($kcid_arr){
$map[] = ['course_id', 'in', $kcid_arr];
}else{
$map[] = ['course_id', 'in', 99999];
}
}
if (isset($post['course_id']) && !empty($post['course_id'])) {
$map[] = ['course_id', '=', $post['course_id']];
}
$list = $this->coursework->where($map)->append(['course_title','user_info'])->order('createtime desc')->paginate($post['limit']);
return $this->returnMsg($list);
}
$this->assign('limit', $limit);
return $this->fetch('', '', false);
}
//快速编辑
public function editup()
{
$post = input();
$this->coursework->update([$post['af'] => $post['av']], [['id', '=', $post['id']]]);
return $this->returnMsg('修改成功');
}
//作业详情
public function detail()
{
$post = input();
$info = $this->coursework->where('id', $post['id'])->find();
$this->assign('info', $info);
return $this->fetch('', '', false);
}
public function del()
{
$post = input();
$ids = is_array($post['id']) ? implode(',', $post['id']) : $post['id'];
if ($this->coursework->where("id IN(" . $ids . ")")->update(['is_del' => 1])) {
return $this->returnMsg("删除成功", 1);
} else {
return $this->returnMsg("删除失败");
}
}
}
\ No newline at end of file
......@@ -25,6 +25,7 @@ class Filemanage extends AdminBase
*/
public function index(string $do = '')
{
if($do=='json'){
$d = $this->only(['kw','fields','sotime','groupid','isdel','limit'=>'10/d'],'get');
$kw = $d['kw'];
......
{extend name="base/header" /}
{block name="body"}
<style>
.layui-table .widthtd{ width: 120px;}
</style>
<div style="margin: 0px 10px">
<table class="layui-table">
<tbody>
<tr>
<td class="widthtd"><strong>课程名称</strong></td>
<td>{$info.title}</td>
<td class="widthtd"><strong>课程分类</strong></td>
<td>{$info.cate_name}</td>
</tr>
<tr>
<td class="widthtd"><strong>发布者</strong></td>
<td>{$info.user_info.username}</td>
<td class="widthtd"><strong>发布时间</strong></td>
<td>{$info.createtime}</td>
</tr>
<tr>
<td class="widthtd"><strong>价格</strong></td>
<td>{$info.price}</td>
<td class="widthtd"><strong>讲师</strong></td>
<td>{$info.teacher_name}</td>
</tr>
<tr>
<td class="widthtd"><strong>标签</strong></td>
<td>{$info.tag_title}</td>
<td class="widthtd"><strong>上架状态</strong></td>
<td>{$info.is_sell_text}</td>
</tr>
<tr>
<td class="widthtd"><strong>浏览量</strong></td>
<td>{$info.click}</td>
<td class="widthtd"><strong>播放量</strong></td>
<td>{$info.tvclick}</td>
</tr>
<tr>
<td class="widthtd"><strong>封面图</strong></td>
<td><img width="50" height="50" src="{$info.thumbpath}" class="imgclick" /></td>
<td class="widthtd"><strong>详情图</strong></td>
<td><img width="50" height="50" src="{$info.thumbpath}" class="imgclick"/></td>
</tr>
<tr>
<td class="widthtd"><strong>审核状态</strong></td>
<td colspan="4">
{if $info.status == 2}
{$info.status_text} - {$info.sh_error_desc}
{else /}
{$info.status_text}
{/if}
</td>
</tr>
</tbody>
</table>
<div class="layui-tab layui-tab-card" lay-filter="demotest">
<ul class="layui-tab-title">
<li class="layui-this">课程内容</li>
<li>课时列表</li>
<li>章节列表</li>
<li>作业列表</li>
</ul>
<div class="layui-tab-content" >
<div class="layui-tab-item layui-show">
<div style="width: 95%; margin: 10px auto;">
{$info.content}
</div>
</div>
<div class="layui-tab-item">
<div class="layui-card-body" style=" padding: 0px 10px !important; ">
<div class="layui-card-box" >
<table lay-filter="courseclasstwo" id="courseclasstwo"></table>
</div>
</div>
</div>
<div class="layui-tab-item">
<div class="layui-card-body" style=" padding: 0px 10px !important; ">
<div class="layui-card-box" style="width: 950px;">
<table lay-filter="courseclasscategory" id="courseclasscategory"></table>
</div>
</div>
</div>
<div class="layui-tab-item">
<div class="layui-card-body" style=" padding: 0px 10px !important; ">
<div class="layui-card-box" style="width: 950px;">
<table lay-filter="coursework" id="coursework"></table>
</div>
</div>
</div>
</div>
</div>
</div>
{/block}
{block name="script"}
<script type="text/javascript">
var course_id = "{$info.id}";
layui.use(['buildItems', 'form', 'laydate', 'util','vinfo','element'], function () {
var layer = layui.layer,table=layui.table,form=layui.form,admin=layui.admin;
var element = layui.element;
/*解析顶部分组选项*/
var map_root = layui.cache.maps;
//章节列表
table.render({
elem: '#courseclasscategory',
page: true,
limit:20,
height: 'full-341',
url: map_root+"/course.course_class_category/index?&do=json",
where:{course_id:course_id},
cols: [[
{field:'id',width:50,align:'center',title:'ID',sort:!0},
{field:'title',align:'center',title:'章节名称'},
{field:'username',width:120,align:'center',title:'发布者',templet:'<div>{{d.user_info.username}}</div>'},
{field:'createtime',width:160,align:'center',title:'创建时间'},
]],
});
table.render({
elem: '#courseclasstwo',
page: true,
limit:20,
height: 'full-341',
url: map_root+"course.course_class/index?&do=json",
where:{course_id:course_id},
cols: [[
{field:'id',width:50,align:'center',title:'ID',sort:!0},
{field:'title',width:200,align:'center',title:'课时名称'},
{field:'course_class_cate',width:200,align:'center',title:'所属章节'},
{field:'course_title', width:200, align:'center',title:'所属课程'},
{field:'username',width:120,align:'center',title:'发布者',templet:'<div>{{d.user_info.username}}</div>'},
{field:'createtime',width:120,align:'center',title:'创建时间'},
{field:'issktext',width:120,align:'center',title:'是否试看'},
{fixed:'right',width:130,align:'center',toolbar:'<div><a class="layui-btn layui-btn-xs" lay-event="clicktv">查看视频</a></div>',title:'操作'}
]],
done: function(){
admin.vShow($('[lay-table-id="courseclasstwo"]'));
}
});
table.render({
elem: '#coursework',
page: true,
limit:20,
height: 'full-341',
url: map_root+"course.course_work/index?&do=json",
where:{course_id:course_id},
cols: [[
{field:'id',width:50,unresize:true,align:'center',title:'ID',sort:!0},
{field:'title',align:'center',title:'作业标题'},
{field:'course_title',align:'center',title:'所属课程'},
{field:'username',width:120,align:'center',title:'发布者',templet:'<div>{{d.user_info.username}}</div>'},
{field:'createtime',width:160,align:'center',title:'创建时间'},
{fixed:'right',width:130,align:'center',toolbar:'<div><a class="layui-btn layui-btn-xs" lay-event="workdetail">详情</a></div>',title:'操作'}
]],
done: function(){ admin.vShow($('[lay-table-id="coursework"]'));
}
});
//一些事件
element.on('tab(demotest)', function(data){
console.log(data);
if(data.index === 1){
table.reloadData('courseclasstwo');
}
});
/*工具条监听*/
table.on('tool(courseclasstwo)', function(obj){
var data = obj.data;
if(obj.event === 'clicktv'){
// 在此处输入 layer 的任意代码
layer.open({
type: 1, // page 层类型
area: ['500px', '450px'],
title: data.title,
shade: 0.6, // 遮罩透明度
shadeClose: true, // 点击遮罩区域,关闭弹层
maxmin: true, // 允许全屏最小化
anim: 0, // 0-6 的动画形式,-1 不开启
content: '<div style="text-align: center;"><video width="480" controls autoplay>\n' +
' <source src="'+data.tvfilepath+'" type="video/mp4">\n' +
'</video></div>'
});
}else if(obj.event === 'workdetail'){
alert(32);
courseOpen(data.id);
}
});/**/
/*工具条监听*/
table.on('tool(coursework)', function(obj){
var data = obj.data;
if(obj.event === 'workdetail'){
courseOpen(data.id);
}
});/**/
});
$(".imgclick").click(function (){
var src = $(this).attr('src'), alt = $(this).attr('alt');
layer.photos({photos:{data:[{alt:alt,src:src}],start:'0'},anim:5,shade:[0.4,'#000']});
});
/*弹出窗*/
function courseOpen(id='',type=''){
layer.open({
type: 2,
area: ['800px', '600px'],
title: "作业详情",
btn: ['确定', '关闭'],
fixed: false, //不固定
content: '/admin/course.course_work/detail?id='+id,
yes: function(index, layero){
layer.close(index); // 关闭弹窗
},
});
}/**/
var callbackdata = function () {
};
</script>
{/block}
\ No newline at end of file
......@@ -63,14 +63,26 @@
<script type="text/html" id="toolDemo">
<div class="layui-clear-space">
<a class="layui-btn layui-btn-xs" lay-event="edit">详情</a>
<a class="layui-btn layui-btn-xs" lay-event="edit1">审核</a>
<a class="layui-btn layui-btn-xs" lay-event="detail">详情</a>
<a class="layui-btn layui-btn-xs" lay-event="shenhei">审核</a>
<a class="layui-btn layui-btn-xs" lay-event="more">
更多
<i class="layui-icon layui-icon-down"></i>
</a>
</div>
</script>
<script type="text/html" id="status-demo">
{{# if (d.status === 3) { }}
<a class="layui-btn layui-btn-xs layui-btn-normal" >{{=d.status_text}}</a>
{{# } else { }}
{{# if(d.status === 2) { }}
<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="statuserror">{{=d.status_text}}</a>
{{# } else { }}
<a class="layui-btn layui-btn-xs">{{=d.status_text}}</a>
{{# } }}
{{# } }}
</script>
<!--JS部分-->
<script>
......@@ -112,18 +124,18 @@
limit:{$limit},
height: 'full-341',
url: app_root+"index?&do=json",
// css: 'td .layui-table-cell{height:80px;line-height:80px;padding:0 5px;}',
cols: [[
{type:'checkbox',fixed:'left'},
{field:'id',width:50,unresize:true,align:'center',title:'ID',sort:!0},
{field:'thumb',width:80,height:80,align:'center',title:'课程图片',templet:'<div class="files_itemw"><img src="{{d.thumbpath}}" lay-event="course-event-image" /></div>'},
{field:'title',width:300,align:'center',title:'课程名称'},
{field:'title',width:150,align:'center',title:'发布者',templet:'<div>{{d.user_info.username}}</div>'},
{field:'username',width:150,align:'center',title:'发布者',templet:'<div>{{d.user_info.username}}</div>'},
{field:'cate_name',width:120,align:'center',title:'类别'},
{field:'price',width:120,align:'center',title:'价格'},
{field:'createtime',width:120,align:'center',title:'发布时间'},
{field:"status_text",width:80,align:'center',title:"上架状态"},
{field:"status_text",width:80,align:'center',title:"状态"},
{field:"status_text",width:80,align:'center',title:"状态",templet:'#status-demo'},
{field:"is_sell_text",width:80,align:'center',title:"上架状态"},
{field:"teacher_name",width:100,align:'center',title:"讲师"},
{field:'tag_title',width:100,align:'center',title:'标签'},
......@@ -145,10 +157,32 @@
table.on('tool(course)', function(obj){
var data = obj.data;
var id = data.id;
if(obj.event === 'edit'){
if(obj.event === 'detail'){
courseOpen(data.id);
}else if(obj.event === 'del'){
del(id);
}else if(obj.event === 'statuserror'){
layer.alert(data.sh_error_desc);
}else if(obj.event === 'shenhei'){
layer.confirm('选择审核状态?', {
btn: ['审核通过', '审核不通过'],
btn1: function(index, layero, that){
shajax(data.id,1);
},
btn2: function(index, layero, that){
layer.prompt({
formType: 2,
value: '',
title: '请输入失败原因',
}, function(value, index, elem){
shajax(data.id,2,value);
});
},
});
}else if(obj.event === 'course-event-image'){
var src = $(this).attr('src'), alt = $(this).attr('alt');
layer.photos({photos:{data:[{alt:alt,src:src}],start:'0'},anim:5,shade:[0.4,'#000']});
......@@ -171,8 +205,13 @@
id: 'del'
}],
click: function(menudata){
if(menudata.id === 'detail'){
layer.msg('查看操作,当前行 ID:'+ data.id);
if(menudata.id === 'keshi'){
window.location.href="#/course.course_class/index/kc="+ encodeURIComponent(data.title);
}else if(menudata.id === 'zhangjie'){
window.location.href="#/course.course_class_category/index/kc="+ encodeURIComponent(data.title);
}else if(menudata.id === 'zuoye'){
window.location.href="#/course.course_work/index/kc="+ encodeURIComponent(data.title);
} else if(menudata.id === 'del'){
del(id);
}
......@@ -184,9 +223,28 @@
}
});/**/
function shajax(id,shstatus,errordesc=''){
$.ajax({
method: "post",
url: layui.cache.maps+'/course.course/shenhecourse',
data: {id:id,shstatus:shstatus,errordesc:errordesc},
dataType: "json",
success: function (res){
if(res.code===1) {
layer.msg(res.msg,{icon:1,shade:[0.4,'#000'],time:1500},function (){
layer.closeAll();
table.reloadData('course');
});
}else{
layer.msg(res.msg,{icon:2,shade:[0.4,'#000'],time:1500},function (){
});
}
}
});
}
/*删除*/
function del(ids){
layer.confirm('确定要删除所选课程吗?', function(){
......@@ -206,42 +264,39 @@
console.log(ids);
del(ids);
});/**/
$('#course-add').on('click',function(){courseOpen();});/**/
/*弹出窗*/
function courseOpen(id='',type=''){
var title = "添加文章";
if(id > 0){
title = '编辑文章';
}
layer.open({
type: 2,
area: ['900px', '900px'],
title: title,
area: ['1000px', '900px'],
title: "课程详情",
btn: ['确定', '关闭'],
fixed: false, //不固定
content: '/admin/course/edit?id='+id+'&type='+type,
content: '/admin/course.course/detail?id='+id,
yes: function(index, layero){
var data = window["layui-layer-iframe" + index].callbackdata();
$.ajax({
method: "post",
url: layui.cache.maps+'/course/edit',
data: data,
dataType: "json",
success: function (res){
if(res.code===1) {
layer.msg(res.msg,{icon:1,shade:[0.4,'#000'],time:1500},function (){
layer.close(index);
table.reloadData('course');
});
}else{
layer.msg(res.msg,{icon:2,shade:[0.4,'#000'],time:1500},function (){
});
}
// layer.closeAll();
}
});
// var data = window["layui-layer-iframe" + index].callbackdata();
// $.ajax({
// method: "post",
// url: layui.cache.maps+'/course/edit',
// data: data,
// dataType: "json",
// success: function (res){
// if(res.code===1) {
// layer.msg(res.msg,{icon:1,shade:[0.4,'#000'],time:1500},function (){
// layer.close(index);
// table.reloadData('course');
// });
// }else{
// layer.msg(res.msg,{icon:2,shade:[0.4,'#000'],time:1500},function (){
//
// });
// }
// // layer.closeAll();
//
// }
// });
},
});
}/**/
......
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
<form class="layui-form render">
<input type="hidden" name="groupid" id="courseclass-groupid" value=""/>
<div class="layui-form-item">
<div class="layui-inline" style="width:250px;"><input type="text" name="kw" placeholder="课时名称关键词" value="{php}echo urldecode(input('kw') ? input('kw'): '');{/php}" autocomplete="off" class="layui-input" lay-affix="clear"/></div>
<div class="layui-inline" style="width:250px;"><input type="text" name="kc" placeholder="课程名称关键词" value="{php}echo urldecode(input('kc') ? input('kc'): '');{/php}" autocomplete="off" class="layui-input" lay-affix="clear"/></div>
<div class="layui-inline" style="width:250px;"><input type="text" name="zj" placeholder="章节关键词" value="{php}echo urldecode(input('zj') ? input('zj'): '');{/php}" autocomplete="off" class="layui-input" lay-affix="clear"/></div>
<div class="layui-inline">
<div class="layui-btn-group">
<button class="layui-btn" lay-submit lay-filter="search-courseclass"><i class="layui-icon layui-icon-search"></i> 搜索</button>
<a class="layui-btn" lay-submit lay-filter="search-courseclass-all" onclick="$('#courseclass-groupid').val('')"><i class="layui-icon layui-icon-light"></i>全部</a>
<a class="layui-btn" id="courseclass-del"><i class="layui-icon layui-icon-delete"></i> 删除</a>
</div>
</div>
</div>
</form>
</div>
<div class="layui-card-body">
<div class="layui-card-box">
<table lay-filter="courseclass" id="courseclass"></table>
</div>
</div>
</div>
</div>
<!--JS部分-->
<script>
layui.use(['vinfo', 'buildItems'], function(){
var map_root = layui.cache.maps;
var app_root = map_root + 'course.course_class/';
var layer = layui.layer,table=layui.table,form=layui.form,admin=layui.admin;
/*初始渲染*/
/*==============左树结构END==============*/
var kw = $('input[name=kw]').val();
var kc = $('input[name=kc]').val();
var zj = $('input[name=zj]').val();
/*渲染数据*/
table.render({
elem: '#courseclass',
page: true,
limit:{$limit},
height: 'full-341',
url: app_root+"index?&do=json",
where:{kw:kw,kc:kc,zj:zj},
cols: [[
{type:'checkbox',fixed:'left'},
{field:'id',width:50,unresize:true,align:'center',title:'ID',sort:!0},
{field:'title',align:'center',title:'课时名称'},
{field:'course_class_cate',align:'center',title:'所属章节'},
{field:'course_title',align:'center',title:'所属课程'},
{field:'username',width:120,align:'center',title:'发布者',templet:'<div>{{d.user_info.username}}</div>'},
{field:'createtime',width:120,align:'center',title:'创建时间'},
{field:'issktext',width:120,align:'center',title:'是否试看'},
{field:'sort',width:50,align:'center',title:'排序',edit:'text'},
{fixed:'right',width:130,align:'center',toolbar:'<div><a class="layui-btn layui-btn-xs" lay-event="clicktv">查看视频</a><a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a></div>',title:'操作'}
]],
done: function(){ admin.vShow($('[lay-table-id="courseclass"]'));
}
});
/*快编监听*/
table.on('edit(courseclass)',function(obj){
admin.req(app_root+"editup",{id:obj.data.id,av:obj.value,af:obj.field},function(res){
layer.msg(res.msg,{shade:[0.4,'#000'],time:500});
},'post',{headersToken:true});
});/**/
/*工具条监听*/
table.on('tool(courseclass)', function(obj){
var data = obj.data;
var id = data.id;
if(obj.event === 'clicktv'){
// 在此处输入 layer 的任意代码
layer.open({
type: 1, // page 层类型
area: ['500px', '450px'],
title: data.title,
shade: 0.6, // 遮罩透明度
shadeClose: true, // 点击遮罩区域,关闭弹层
maxmin: true, // 允许全屏最小化
anim: 0, // 0-6 的动画形式,-1 不开启
content: '<div style="text-align: center;"><video width="480" controls autoplay>\n' +
' <source src="'+data.tvfilepath+'" type="video/mp4">\n' +
'</video></div>'
});
}else if(obj.event === 'del'){
del(id);
}else if(obj.event === 'courseclass-event-image'){
var src = $(this).attr('src'), alt = $(this).attr('alt');
layer.photos({photos:{data:[{alt:alt,src:src}],start:'0'},anim:5,shade:[0.4,'#000']});
}
});/**/
/*删除*/
function del(ids){
layer.confirm('确定要删除所选记录吗?', function(){
admin.req(app_root+"del",{id:ids},function(res){
layer.msg(res.msg,{shade:[0.4,'#000'],time:1500},function(){
if(res.code==1) table.reloadData('courseclass');
});
},'post',{headersToken:true});
});
}/**/
/*顶部删除按钮*/
$('#courseclass-del').on('click', function(){
var checkRows = table.checkStatus('courseclass').data;
if(checkRows.length === 0){return layer.msg('请选择需删除的文章');}
var ids = checkRows.map(function(d){return d.id;});
console.log(ids);
del(ids);
});/**/
$('#courseclass-add').on('click',function(){courseclassOpen();});/**/
});
</script>
\ No newline at end of file
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
<form class="layui-form render">
<input type="hidden" name="groupid" id="courseclasscategory-groupid" value=""/>
<div class="layui-form-item">
<div class="layui-inline" style="width:250px;"><input type="text" name="kw" placeholder="章节名称关键词" autocomplete="off" class="layui-input" lay-affix="clear"/></div>
<div class="layui-inline" style="width:250px;"><input type="text" name="kc" placeholder="课程名称关键词" value="{php}echo urldecode(input('kc') ? input('kc'): '');{/php}" autocomplete="off" class="layui-input" lay-affix="clear"/></div>
<div class="layui-inline">
<div class="layui-btn-group">
<button class="layui-btn" lay-submit lay-filter="search-courseclasscategory"><i class="layui-icon layui-icon-search"></i> 搜索</button>
<a class="layui-btn" lay-submit lay-filter="search-courseclasscategory-all" onclick="$('#courseclasscategory-groupid').val('')"><i class="layui-icon layui-icon-light"></i>全部</a>
<a class="layui-btn" id="courseclasscategory-del"><i class="layui-icon layui-icon-delete"></i> 删除</a>
</div>
</div>
</div>
</form>
</div>
<div class="layui-card-body">
<div class="layui-card-box">
<table lay-filter="courseclasscategory" id="courseclasscategory"></table>
</div>
</div>
</div>
</div>
<!--JS部分-->
<script>
layui.use(['vinfo', 'buildItems'], function(){
var map_root = layui.cache.maps;
var app_root = map_root + 'course.course_class_category/';
var layer = layui.layer,table=layui.table,form=layui.form,admin=layui.admin;
/*初始渲染*/
/*==============左树结构END==============*/
/*渲染数据*/
var kc = $('input[name=kc]').val();
table.render({
elem: '#courseclasscategory',
page: true,
limit:{$limit},
height: 'full-341',
url: app_root+"index?&do=json",
where:{kc:kc},
cols: [[
{type:'checkbox',fixed:'left'},
{field:'id',width:50,unresize:true,align:'center',title:'ID',sort:!0},
{field:'title',align:'center',title:'章节名称'},
{field:'course_title',align:'center',title:'所属课程'},
{field:'username',width:120,align:'center',title:'发布者',templet:'<div>{{d.user_info.username}}</div>'},
{field:'createtime',width:120,align:'center',title:'创建时间'},
{field:'sort',width:50,align:'center',title:'排序',edit:'text'},
{fixed:'right',width:130,align:'center',toolbar:'<div><a href="#/course.course_class/index/zj={{d.title}}" class="layui-btn layui-btn-xs">查看课时</a><a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a></div>',title:'操作'}
]],
done: function(){ admin.vShow($('[lay-table-id="courseclasscategory"]'));
}
});
/*快编监听*/
table.on('edit(courseclasscategory)',function(obj){
admin.req(app_root+"editup",{id:obj.data.id,av:obj.value,af:obj.field},function(res){
layer.msg(res.msg,{shade:[0.4,'#000'],time:500});
},'post',{headersToken:true});
});/**/
/*工具条监听*/
table.on('tool(courseclasscategory)', function(obj){
var data = obj.data;
var id = data.id;
if(obj.event === 'clicktv'){
// 在此处输入 layer 的任意代码
layer.open({
type: 1, // page 层类型
area: ['500px', '450px'],
title: data.title,
shade: 0.6, // 遮罩透明度
shadeClose: true, // 点击遮罩区域,关闭弹层
maxmin: true, // 允许全屏最小化
anim: 0, // 0-6 的动画形式,-1 不开启
content: '<div style="text-align: center;"><video width="480" controls autoplay>\n' +
' <source src="'+data.tvfilepath+'" type="video/mp4">\n' +
'</video></div>'
});
}else if(obj.event === 'del'){
del(id);
}else if(obj.event === 'courseclasscategory-event-image'){
var src = $(this).attr('src'), alt = $(this).attr('alt');
layer.photos({photos:{data:[{alt:alt,src:src}],start:'0'},anim:5,shade:[0.4,'#000']});
}
});/**/
/*删除*/
function del(ids){
layer.confirm('确定要删除所选记录吗?', function(){
admin.req(app_root+"del",{id:ids},function(res){
layer.msg(res.msg,{shade:[0.4,'#000'],time:1500},function(){
if(res.code==1) table.reloadData('courseclasscategory');
});
},'post',{headersToken:true});
});
}/**/
/*顶部删除按钮*/
$('#courseclasscategory-del').on('click', function(){
var checkRows = table.checkStatus('courseclasscategory').data;
if(checkRows.length === 0){return layer.msg('请选择需删除的文章');}
var ids = checkRows.map(function(d){return d.id;});
console.log(ids);
del(ids);
});/**/
$('#courseclasscategory-add').on('click',function(){courseclasscategoryOpen();});/**/
});
</script>
\ No newline at end of file
{extend name="base/header" /}
{block name="body"}
<style>
.layui-table .widthtd{ width: 120px;}
</style>
<div style="margin: 0px 10px">
<table class="layui-table">
<tbody>
<tr>
<td class="widthtd"><strong>作业标题</strong></td>
<td>{$info.title}</td>
<td class="widthtd"><strong>所属课程</strong></td>
<td>{$info.course_title}</td>
</tr>
<tr>
<td class="widthtd"><strong>发布者</strong></td>
<td>{$info.user_info.username}</td>
<td class="widthtd"><strong>发布时间</strong></td>
<td>{$info.createtime}</td>
</tr>
<tr>
<td class="widthtd"><strong>附件下载</strong></td>
<td colspan="3">
<table class="layui-table">
<thead>
<tr>
<th>文件名称</th>
<th>大小</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{volist name="info.filelist" id="data"}
<tr>
<td>{$data.filename}</td>
<td>{$data.filesize}KB</td>
<td ><a class="layui-btn layui-btn-xs" href="/admin/course.course_work/downloadfile?fileid={$data.fileid}" target="_blank">下载</a></td>
</tr>
{/volist}
</tbody>
</table>
</td>
</tr>
<tr>
<td class="widthtd"><strong>作业内容</strong></td>
<td colspan="3">{$info.content}</td>
</tr>
</tbody>
</table>
</div>
{/block}
{block name="script"}
<script type="text/javascript">
var course_id = "{$info.id}";
layui.use(['buildItems', 'form', 'laydate', 'util','vinfo','element'], function () {
var layer = layui.layer,table=layui.table,form=layui.form,admin=layui.admin;
});
$(".imgclick").click(function (){
var src = $(this).attr('src'), alt = $(this).attr('alt');
layer.photos({photos:{data:[{alt:alt,src:src}],start:'0'},anim:5,shade:[0.4,'#000']});
});
var callbackdata = function () {
};
</script>
{/block}
\ No newline at end of file
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
<form class="layui-form render">
<input type="hidden" name="groupid" id="coursework-groupid" value=""/>
<div class="layui-form-item">
<div class="layui-inline" style="width:250px;"><input type="text" name="kw" placeholder="作业标题关键词" autocomplete="off" class="layui-input" lay-affix="clear"/></div>
<div class="layui-inline" style="width:250px;"><input type="text" name="kc" placeholder="课程名称关键词" value="{php}echo urldecode(input('kc') ? input('kc'): '');{/php}" autocomplete="off" class="layui-input" lay-affix="clear"/></div>
<div class="layui-inline">
<div class="layui-btn-group">
<button class="layui-btn" lay-submit lay-filter="search-coursework"><i class="layui-icon layui-icon-search"></i> 搜索</button>
<a class="layui-btn" lay-submit lay-filter="search-coursework-all" onclick="$('#coursework-groupid').val('')"><i class="layui-icon layui-icon-light"></i>全部</a>
<a class="layui-btn" id="coursework-del"><i class="layui-icon layui-icon-delete"></i> 删除</a>
</div>
</div>
</div>
</form>
</div>
<div class="layui-card-body">
<div class="layui-card-box">
<table lay-filter="coursework" id="coursework"></table>
</div>
</div>
</div>
</div>
<!--JS部分-->
<script>
layui.use(['vinfo', 'buildItems'], function(){
var map_root = layui.cache.maps;
var app_root = map_root + 'course.course_work/';
var layer = layui.layer,table=layui.table,form=layui.form,admin=layui.admin;
/*初始渲染*/
/*==============左树结构END==============*/
/*渲染数据*/
var kc = $('input[name=kc]').val();
table.render({
elem: '#coursework',
page: true,
limit:{$limit},
height: 'full-341',
url: app_root+"index?&do=json",
where:{kc:kc},
cols: [[
{type:'checkbox',fixed:'left'},
{field:'id',width:50,unresize:true,align:'center',title:'ID',sort:!0},
{field:'title',align:'center',title:'作业标题'},
{field:'course_title',align:'center',title:'所属课程'},
{field:'username',width:120,align:'center',title:'发布者',templet:'<div>{{d.user_info.username}}</div>'},
{field:'createtime',width:160,align:'center',title:'创建时间'},
{fixed:'right',width:130,align:'center',toolbar:'<div><a class="layui-btn layui-btn-xs" lay-event="detail">详情</a><a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a></div>',title:'操作'}
]],
done: function(){ admin.vShow($('[lay-table-id="coursework"]'));
}
});
/*快编监听*/
table.on('edit(coursework)',function(obj){
admin.req(app_root+"editup",{id:obj.data.id,av:obj.value,af:obj.field},function(res){
layer.msg(res.msg,{shade:[0.4,'#000'],time:500});
},'post',{headersToken:true});
});/**/
/*工具条监听*/
table.on('tool(coursework)', function(obj){
var data = obj.data;
var id = data.id;
if(obj.event === 'detail'){
courseOpen(data.id);
}else if(obj.event === 'del'){
del(id);
}else if(obj.event === 'coursework-event-image'){
var src = $(this).attr('src'), alt = $(this).attr('alt');
layer.photos({photos:{data:[{alt:alt,src:src}],start:'0'},anim:5,shade:[0.4,'#000']});
}
});/**/
/*删除*/
function del(ids){
layer.confirm('确定要删除所选记录吗?', function(){
admin.req(app_root+"del",{id:ids},function(res){
layer.msg(res.msg,{shade:[0.4,'#000'],time:1500},function(){
if(res.code==1) table.reloadData('coursework');
});
},'post',{headersToken:true});
});
}/**/
/*顶部删除按钮*/
$('#coursework-del').on('click', function(){
var checkRows = table.checkStatus('coursework').data;
if(checkRows.length === 0){return layer.msg('请选择需删除的文章');}
var ids = checkRows.map(function(d){return d.id;});
console.log(ids);
del(ids);
});/**/
$('#coursework-add').on('click',function(){courseworkOpen();});/**/
/*弹出窗*/
function courseOpen(id='',type=''){
layer.open({
type: 2,
area: ['1000px', '900px'],
title: "作业详情",
btn: ['确定', '关闭'],
fixed: false, //不固定
content: '/admin/course.course_work/detail?id='+id,
yes: function(index, layero){
layer.close(index); // 关闭弹窗
},
});
}/**/
});
</script>
\ No newline at end of file
This diff is collapsed.
......@@ -16,7 +16,7 @@ use think\facade\Db;
use think\Model;
/**
* 模型公用类
* 课程模型
*/
class ShCourse extends Model
{
......@@ -24,8 +24,9 @@ class ShCourse extends Model
public function getCreatetimeAttr($value)
{
return date('Y-m-d H:i:s',$value);
return date('Y-m-d H:i:s', $value);
}
public function getThumbpathAttr($value, $data)
{
return get_upload_file($data['thumb']);
......@@ -46,10 +47,12 @@ class ShCourse extends Model
{
return CourseTeacher::where('id', $data['teacher_id'])->value('nickname');
}
public function getTagTitleAttr($value, $data)
{
return implode(',',CourseTag::where('id', $data['tag_ids'])->column('title'));
return implode(',', CourseTag::where('id', $data['tag_ids'])->column('title'));
}
public function getStatusTextAttr($value, $data)
{
switch ($data['status']) {
......@@ -74,4 +77,21 @@ class ShCourse extends Model
return User::where('id', $data['user_id'])->field('id,username,mobile')->find();
}
//上架状态
public function getIsSellTextAttr($value, $data)
{
switch ($data['is_sell']) {
case 1:
$selltext = '已上架';
break;
default:
$selltext = '已下架';
break;
}
return $selltext;
}
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\model;
use app\model\project\User;
use think\facade\Db;
use think\Model;
/**
* 课时模型
*/
class ShCourseClass extends Model
{
public function getCreatetimeAttr($value)
{
return date('Y-m-d H:i:s', $value);
}
//课程名称
public function getCourseTitleAttr($value, $data)
{
return ShCourse::where('id', $data['course_id'])->value('title');
}
public function getUserInfoAttr($value, $data)
{
return User::where('id', $data['user_id'])->field('id,username,mobile')->find();
}
//章节名称
public function getCourseClassCateAttr($value, $data)
{
$title = ShCourseClassCategory::where('id', $data['cate_id'])->value('title');
return $title ? $title : '无';
}
//试看
public function getIssktextAttr($value, $data){
return $data['is_sk'] == 1 ? '是' : '否';
}
//视频地址
public function getTvfilepathAttr($value, $data)
{
return get_upload_file($data['tv_file']);
}
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\model;
use app\model\project\User;
use think\facade\Db;
use think\Model;
/**
* 章节模型
*/
class ShCourseClassCategory extends Model
{
public function getCreatetimeAttr($value)
{
return date('Y-m-d H:i:s', $value);
}
public function getUserInfoAttr($value, $data)
{
return User::where('id', $data['user_id'])->field('id,username,mobile')->find();
}
//课程名称
public function getCourseTitleAttr($value, $data)
{
return ShCourse::where('id', $data['course_id'])->value('title');
}
}
\ No newline at end of file
<?php
/**
* ===========================================================================
* Veitool 快捷开发框架系统
* Author: Niaho 26843818@qq.com
* Copyright (c)2019-2025 www.veitool.com All rights reserved.
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\model;
use app\model\project\User;
use think\facade\Db;
use think\Model;
/**
* 章节模型
*/
class ShCourseWork extends Model
{
public function getCreatetimeAttr($value)
{
return date('Y-m-d H:i:s', $value);
}
public function getUserInfoAttr($value, $data)
{
return User::where('id', $data['user_id'])->field('id,username,mobile')->find();
}
//课程名称
public function getCourseTitleAttr($value, $data)
{
return ShCourse::where('id', $data['course_id'])->value('title');
}
//获取下载列表
public function getFilelistAttr($value,$data)
{
return get_upload_file($data['file_id_str'],'list');
}
}
\ No newline at end of file
......@@ -7,6 +7,7 @@
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* ---------------------------------------------------------------------------
*/
namespace app\model\system;
use app\model\Base;
......@@ -18,22 +19,28 @@ class SystemUploadFile extends Base
{
/**
* 定义主键
* @var string
* @var string
*/
protected $pk = 'fileid';
/**
* 获取上传文件记录(分页)
* @param string/array $where 条件
* @param string/array $order 排序
* @param string $field 字段
* @param string/array $where 条件
* @param string/array $order 排序
* @param string $field 字段
* @return obj
*/
public function listQuery(string|array $where = '', string|array $order = ['fileid'=>'desc'], string $field = '*')
public function listQuery(string|array $where = '', string|array $order = ['fileid' => 'desc'], string $field = '*')
{
$d = request()->param();
$limit = isset($d['limit']) ? intval($d['limit']) : (isset($d['size']) ? intval($d['size']) : 10); // 兼容百度编辑器附件列表
return $this->where($where)->order($order)->field($field)->paginate($limit);
}
public function getFileurlAttr($value, $data)
{
return config('app.file_http_url').$value;
}
}
\ No newline at end of file
......@@ -32,4 +32,5 @@ return [
'error_message' => '页面错误!请稍后再试~',
// 显示错误信息
'show_error_msg' => false,
'file_http_url' => 'http://192.168.4.26:8082',
];
\ No newline at end of file
......@@ -2,7 +2,7 @@
return [
//API接口地址 末尾不要加 /
'api_url' => 'https://www.veitool.com',
'api_url' => '',
//插件强行卸载、覆盖 false 则会检查冲突文件
'force' => true,
//插件是否备份有冲突的全局文件
......
......@@ -114,10 +114,6 @@ layui.define(['tagsInput','fileLibrary','cascader'], function(e){
var b = {
on: function(o,m,t){
// 记录关联项,用于渲染完成后显示选中的关联项
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment