Commit b2df69b1 authored by wangtao's avatar wangtao

增加课程列表,上传接口

parent abf68cfb
...@@ -153,4 +153,11 @@ abstract class AdminBase extends BaseController ...@@ -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 @@ ...@@ -11,7 +11,7 @@
namespace app\admin\controller\course; namespace app\admin\controller\course;
use app\admin\controller\AdminBase; use app\admin\controller\AdminBase;
use app\model\ShCourse AS ShCourseModel; use app\model\ShCourse as ShCourseModel;
use think\App; use think\App;
use think\facade\Db; use think\facade\Db;
use app\model\CourseCategory as CourseCategoryModel; use app\model\CourseCategory as CourseCategoryModel;
...@@ -20,7 +20,7 @@ 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; protected $course;
...@@ -49,7 +49,8 @@ class course extends AdminBase ...@@ -49,7 +49,8 @@ class course extends AdminBase
if (isset($post['cate_id']) && !empty($post['cate_id'])) { if (isset($post['cate_id']) && !empty($post['cate_id'])) {
$map[] = ['cate_id', '=', $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); return $this->returnMsg($list);
} }
$category = CourseCategoryModel::field('*,pid as parentid')->where('is_del', 0)->order('sort desc')->select()->toArray(); $category = CourseCategoryModel::field('*,pid as parentid')->where('is_del', 0)->order('sort desc')->select()->toArray();
...@@ -68,7 +69,6 @@ class course extends AdminBase ...@@ -68,7 +69,6 @@ class course extends AdminBase
} }
public function del() public function del()
{ {
$post = input(); $post = input();
...@@ -81,4 +81,40 @@ class course extends AdminBase ...@@ -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 ...@@ -25,6 +25,7 @@ class Filemanage extends AdminBase
*/ */
public function index(string $do = '') public function index(string $do = '')
{ {
if($do=='json'){ if($do=='json'){
$d = $this->only(['kw','fields','sotime','groupid','isdel','limit'=>'10/d'],'get'); $d = $this->only(['kw','fields','sotime','groupid','isdel','limit'=>'10/d'],'get');
$kw = $d['kw']; $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 @@ ...@@ -63,14 +63,26 @@
<script type="text/html" id="toolDemo"> <script type="text/html" id="toolDemo">
<div class="layui-clear-space"> <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="detail">详情</a>
<a class="layui-btn layui-btn-xs" lay-event="edit1">审核</a> <a class="layui-btn layui-btn-xs" lay-event="shenhei">审核</a>
<a class="layui-btn layui-btn-xs" lay-event="more"> <a class="layui-btn layui-btn-xs" lay-event="more">
更多 更多
<i class="layui-icon layui-icon-down"></i> <i class="layui-icon layui-icon-down"></i>
</a> </a>
</div> </div>
</script> </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部分--> <!--JS部分-->
<script> <script>
...@@ -112,18 +124,18 @@ ...@@ -112,18 +124,18 @@
limit:{$limit}, limit:{$limit},
height: 'full-341', height: 'full-341',
url: app_root+"index?&do=json", url: app_root+"index?&do=json",
// css: 'td .layui-table-cell{height:80px;line-height:80px;padding:0 5px;}',
cols: [[ cols: [[
{type:'checkbox',fixed:'left'}, {type:'checkbox',fixed:'left'},
{field:'id',width:50,unresize:true,align:'center',title:'ID',sort:!0}, {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:'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: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:'cate_name',width:120,align:'center',title:'类别'},
{field:'price',width:120,align:'center',title:'价格'},
{field:'createtime',width:120,align:'center',title:'发布时间'}, {field:'createtime',width:120,align:'center',title:'发布时间'},
{field:"status_text",width:80,align:'center',title:"状态",templet:'#status-demo'},
{field:"is_sell_text",width:80,align:'center',title:"上架状态"},
{field:"status_text",width:80,align:'center',title:"上架状态"},
{field:"status_text",width:80,align:'center',title:"状态"},
{field:"teacher_name",width:100,align:'center',title:"讲师"}, {field:"teacher_name",width:100,align:'center',title:"讲师"},
{field:'tag_title',width:100,align:'center',title:'标签'}, {field:'tag_title',width:100,align:'center',title:'标签'},
...@@ -145,10 +157,32 @@ ...@@ -145,10 +157,32 @@
table.on('tool(course)', function(obj){ table.on('tool(course)', function(obj){
var data = obj.data; var data = obj.data;
var id = data.id; var id = data.id;
if(obj.event === 'edit'){ if(obj.event === 'detail'){
courseOpen(data.id); courseOpen(data.id);
}else if(obj.event === 'del'){ }else if(obj.event === 'del'){
del(id); 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'){ }else if(obj.event === 'course-event-image'){
var src = $(this).attr('src'), alt = $(this).attr('alt'); 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']}); layer.photos({photos:{data:[{alt:alt,src:src}],start:'0'},anim:5,shade:[0.4,'#000']});
...@@ -171,8 +205,13 @@ ...@@ -171,8 +205,13 @@
id: 'del' id: 'del'
}], }],
click: function(menudata){ click: function(menudata){
if(menudata.id === 'detail'){ if(menudata.id === 'keshi'){
layer.msg('查看操作,当前行 ID:'+ data.id);
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'){ } else if(menudata.id === 'del'){
del(id); del(id);
} }
...@@ -184,9 +223,28 @@ ...@@ -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){ function del(ids){
layer.confirm('确定要删除所选课程吗?', function(){ layer.confirm('确定要删除所选课程吗?', function(){
...@@ -206,42 +264,39 @@ ...@@ -206,42 +264,39 @@
console.log(ids); console.log(ids);
del(ids); del(ids);
});/**/ });/**/
$('#course-add').on('click',function(){courseOpen();});/**/
/*弹出窗*/ /*弹出窗*/
function courseOpen(id='',type=''){ function courseOpen(id='',type=''){
var title = "添加文章";
if(id > 0){
title = '编辑文章';
}
layer.open({ layer.open({
type: 2, type: 2,
area: ['900px', '900px'], area: ['1000px', '900px'],
title: title, title: "课程详情",
btn: ['确定', '关闭'], btn: ['确定', '关闭'],
fixed: false, //不固定 fixed: false, //不固定
content: '/admin/course/edit?id='+id+'&type='+type, content: '/admin/course.course/detail?id='+id,
yes: function(index, layero){ yes: function(index, layero){
var data = window["layui-layer-iframe" + index].callbackdata(); // var data = window["layui-layer-iframe" + index].callbackdata();
$.ajax({ // $.ajax({
method: "post", // method: "post",
url: layui.cache.maps+'/course/edit', // url: layui.cache.maps+'/course/edit',
data: data, // data: data,
dataType: "json", // dataType: "json",
success: function (res){ // success: function (res){
if(res.code===1) { // if(res.code===1) {
layer.msg(res.msg,{icon:1,shade:[0.4,'#000'],time:1500},function (){ // layer.msg(res.msg,{icon:1,shade:[0.4,'#000'],time:1500},function (){
layer.close(index); // layer.close(index);
table.reloadData('course'); // table.reloadData('course');
}); // });
}else{ // }else{
layer.msg(res.msg,{icon:2,shade:[0.4,'#000'],time:1500},function (){ // layer.msg(res.msg,{icon:2,shade:[0.4,'#000'],time:1500},function (){
//
}); // });
} // }
// layer.closeAll(); // // 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
...@@ -31,147 +31,170 @@ define('ADDON_PATH', ROOT_PATH . 'addons' . VT_DS); ...@@ -31,147 +31,170 @@ define('ADDON_PATH', ROOT_PATH . 'addons' . VT_DS);
// 临时目录 // 临时目录
define('RUNTIME_PATH', ROOT_PATH . 'runtime' . VT_DS); define('RUNTIME_PATH', ROOT_PATH . 'runtime' . VT_DS);
use app\model\system\SystemUploadFile;
//获取图片地址 //获取图片地址
function get_upload_file($fileid='') function get_upload_file($fileid = '', $datatype = '')
{ {
if ($datatype == 'list') {
//多附件读取列表
$map[] = ['fileid', 'in', $fileid];
return SystemUploadFile::where($map)->select();
} elseif ($datatype == 'info') {
$map[] = ['fileid', '=', $fileid];
return SystemUploadFile::where($map)->find();
} else {
$fileinfo = (new SystemUploadFile)->where('fileid', $fileid)->find();
return $fileinfo['fileurl'];
}
return \think\facade\Db::name('system_upload_file')->where('fileid',$fileid)->value('fileurl');
} }
/** /**
* md5判断 * md5判断
* @param string $w 字符 * @param string $w 字符
* @return bool * @return bool
*/ */
function is_md5($w){ function is_md5($w)
{
return preg_match("/^[a-f0-9]{32}$/", $w); return preg_match("/^[a-f0-9]{32}$/", $w);
} }
/** /**
* 判断字符是否合乎规则 * 判断字符是否合乎规则
* @param string $s 目标字符串 * @param string $s 目标字符串
* @param string $f 正则类型 ip,mobile,email 或者 允许有的位数范围,如:{1,3} * @param string $f 正则类型 ip,mobile,email 或者 允许有的位数范围,如:{1,3}
* @param array $t 合法的字符集0:字母数字汉字下划线 1:数字 2:小写字母 3:大写字母 4:汉字 5:任何非空白字符 * @param array $t 合法的字符集0:字母数字汉字下划线 1:数字 2:小写字母 3:大写字母 4:汉字 5:任何非空白字符
* @param string $o 允许有字符 * @param string $o 允许有字符
* @return bool * @return bool
*/ */
function is_preg($s,$f='',$t=[0],$o=''){ function is_preg($s, $f = '', $t = [0], $o = '')
if($s=='' || is_array($s)) return false; {
$s = str_replace([chr(10),chr(13),"\t"],['','',''],$s); if ($s == '' || is_array($s)) return false;
$s = str_replace([chr(10), chr(13), "\t"], ['', '', ''], $s);
$p = [ $p = [
'ip' => "/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", 'ip' => "/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/",
'mobile'=> "/^1[3|4|5|6|7|8|9]{1}[0-9]{9}$/", 'mobile' => "/^1[3|4|5|6|7|8|9]{1}[0-9]{9}$/",
'email' => "/^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/", 'email' => "/^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/",
'class' => "/^[A-Z]{1}[a-zA-Z0-9]{1,15}$/", 'class' => "/^[A-Z]{1}[a-zA-Z0-9]{1,15}$/",
'idcard'=> "/^([1-6][1-9]|50)\d{4}(19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/" 'idcard' => "/^([1-6][1-9]|50)\d{4}(19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/"
]; ];
if(isset($p[$f])) return preg_match($p[$f],$s); if (isset($p[$f])) return preg_match($p[$f], $s);
$m = '/^['; $m = '/^[';
$p = ['\w',"0-9",'a-z','A-Z','\x{4e00}-\x{9fa5}','\S']; $p = ['\w', "0-9", 'a-z', 'A-Z', '\x{4e00}-\x{9fa5}', '\S'];
foreach($t as $v){ foreach ($t as $v) {
$m .= $p[$v] ?? ''; $m .= $p[$v] ?? '';
} }
$m .= $o ? $o.']'.$f.'+$/u' : ']'.$f.'+$/u'; $m .= $o ? $o . ']' . $f . '+$/u' : ']' . $f . '+$/u';
return preg_match($m,$s); return preg_match($m, $s);
} }
/** /**
* 返回字符串长度 * 返回字符串长度
* @param string $s 目标源 * @param string $s 目标源
* @return int * @return int
*/ */
function word_count($s){ function word_count($s)
{
return function_exists('mb_strlen') ? mb_strlen($s, 'utf8') : strlen($s); return function_exists('mb_strlen') ? mb_strlen($s, 'utf8') : strlen($s);
} }
/** /**
* 生成指定长度的随机字符 * 生成指定长度的随机字符
* @param int $l 指定长度 * @param int $l 指定长度
* @param string $c 源字符集 * @param string $c 源字符集
* @return string * @return string
*/ */
function random($l,$c = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz'){ function random($l, $c = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz')
{
$h = ''; $h = '';
$m = strlen($c) - 1; $m = strlen($c) - 1;
for($i = 0; $i < $l; $i++){$h .= $c[mt_rand(0, $m)];} for ($i = 0; $i < $l; $i++) {
$h .= $c[mt_rand(0, $m)];
}
return $h; return $h;
} }
/** /**
* 生成密码 * 生成密码
* @param string $p 密码 * @param string $p 密码
* @param string $s 密钥 * @param string $s 密钥
* @return string * @return string
*/ */
function set_password($p,$s){ function set_password($p, $s)
return md5((is_md5($p) ? md5($p) : md5(md5($p))).$s); {
return md5((is_md5($p) ? md5($p) : md5(md5($p))) . $s);
} }
/** /**
* 设置订单号 * 设置订单号
* @retrun string * @retrun string
*/ */
function set_order_id(){ function set_order_id()
return date('YmdHis',time()).substr(microtime(),2,6).sprintf('%03d',rand(0,999)); {
return date('YmdHis', time()) . substr(microtime(), 2, 6) . sprintf('%03d', rand(0, 999));
} }
/** /**
* 字符串中间替换为星号 * 字符串中间替换为星号
* @param string $s 字符串 * @param string $s 字符串
* @param string $n 星号数 0:按字符算 * @param string $n 星号数 0:按字符算
* @return string * @return string
*/ */
function half_replace($s,$n=0){ function half_replace($s, $n = 0)
{
$l = mb_strlen($s, 'UTF-8'); $l = mb_strlen($s, 'UTF-8');
if($l<=2) return $s; if ($l <= 2) return $s;
$l = $n>0 ? $n : $l-2; $l = $n > 0 ? $n : $l - 2;
return mb_substr($s, 0, 1, 'UTF-8') . str_repeat('*',$l) . mb_substr($s, -1, 1, 'UTF-8'); return mb_substr($s, 0, 1, 'UTF-8') . str_repeat('*', $l) . mb_substr($s, -1, 1, 'UTF-8');
} }
/** /**
* 回车、换行、空格字符过滤 * 回车、换行、空格字符过滤
* @param string $s 目标字符 * @param string $s 目标字符
* @return string * @return string
*/ */
function vtrim($s){ function vtrim($s)
return str_replace([chr(10),chr(13),"\t",' '],['','','',''],$s); {
return str_replace([chr(10), chr(13), "\t", ' '], ['', '', '', ''], $s);
} }
/** /**
* 字符过滤 【空值或中间未出现空格均不过滤】 * 字符过滤 【空值或中间未出现空格均不过滤】
* @param string|array $s 目标字符 * @param string|array $s 目标字符
* @param int $t 过滤类型 默认1 1转码 0解码 * @param int $t 过滤类型 默认1 1转码 0解码
* @return string|array * @return string|array
*/ */
function strip_sql($s,$t=1){ function strip_sql($s, $t = 1)
if(is_array($s)){ {
if (is_array($s)) {
return array_map('strip_sql', $s); return array_map('strip_sql', $s);
}else{ } else {
if(empty($s)) return $s; if (empty($s)) return $s;
$s = trim($s); $s = trim($s);
if($t){ if ($t) {
global $_VFILTER; global $_VFILTER;
if($_VFILTER) $s = str_ireplace($_VFILTER,'',$s); if ($_VFILTER) $s = str_ireplace($_VFILTER, '', $s);
if(strripos($s,' ') == 0) return $s; if (strripos($s, ' ') == 0) return $s;
$p = 'vt_'; $p = 'vt_';
$s = preg_replace("/\/\*([\s\S]*?)\*\//", "", $s); $s = preg_replace("/\/\*([\s\S]*?)\*\//", "", $s);
$s = preg_replace("/0x([a-f0-9]{2,})/i", '0&#120;\\1', $s); $s = preg_replace("/0x([a-f0-9]{2,})/i", '0&#120;\\1', $s);
$s = preg_replace_callback("/(select|update|replace|delete|drop)([\s\S]*?)(".$p."|from)/i", 'strip_wd', $s); $s = preg_replace_callback("/(select|update|replace|delete|drop)([\s\S]*?)(" . $p . "|from)/i", 'strip_wd', $s);
$s = preg_replace_callback("/(load_file|substring|substr|reverse|trim|space|left|right|mid|lpad|concat|concat_ws|make_set|ascii|bin|oct|hex|ord|char|conv)([^a-z]?)\(/i", 'strip_wd', $s); $s = preg_replace_callback("/(load_file|substring|substr|reverse|trim|space|left|right|mid|lpad|concat|concat_ws|make_set|ascii|bin|oct|hex|ord|char|conv)([^a-z]?)\(/i", 'strip_wd', $s);
$s = preg_replace_callback("/(union|where|having|outfile|dumpfile|".$p.")/i", 'strip_wd', $s); $s = preg_replace_callback("/(union|where|having|outfile|dumpfile|" . $p . ")/i", 'strip_wd', $s);
return $s; return $s;
}else{ } else {
return str_replace(['&#95;','&#100;','&#101;','&#103;','&#105;','&#109;','&#110;','&#112;','&#114;','&#115;','&#116;','&#118;','&#120;'], ['_','d','e','g','i','m','n','p','r','s','t','v','x'], $s); return str_replace(['&#95;', '&#100;', '&#101;', '&#103;', '&#105;', '&#109;', '&#110;', '&#112;', '&#114;', '&#115;', '&#116;', '&#118;', '&#120;'], ['_', 'd', 'e', 'g', 'i', 'm', 'n', 'p', 'r', 's', 't', 'v', 'x'], $s);
} }
} }
} }
/** /**
* 过滤扩展初始化,需要扩展过滤时前置于方法strip_sql调用该方法 * 过滤扩展初始化,需要扩展过滤时前置于方法strip_sql调用该方法
* @param string $filter 自定义过滤的字符串多个逗号,隔开,默认按系统配置 sys_filter 设置进行过滤 * @param string $filter 自定义过滤的字符串多个逗号,隔开,默认按系统配置 sys_filter 设置进行过滤
* @global array $_VFILTER * @global array $_VFILTER
*/ */
function strip_sql_extend($filter = ''){ function strip_sql_extend($filter = '')
{
global $_VFILTER; global $_VFILTER;
$filter = $filter ?: vconfig('sys_filter'); $filter = $filter ?: vconfig('sys_filter');
$_VFILTER = $_VFILTER ?: ($filter ? explode(',', $filter) : []); $_VFILTER = $_VFILTER ?: ($filter ? explode(',', $filter) : []);
...@@ -179,14 +202,15 @@ function strip_sql_extend($filter = ''){ ...@@ -179,14 +202,15 @@ function strip_sql_extend($filter = ''){
/** /**
* 转ASCII码 (以上方法 strip_sql 中用于转换ASCII码仿SQL注入) * 转ASCII码 (以上方法 strip_sql 中用于转换ASCII码仿SQL注入)
* @param array $m 对象 * @param array $m 对象
* @return string * @return string
*/ */
function strip_wd($m){ function strip_wd($m)
if(is_array($m) && isset($m[1])){ {
$wd = substr($m[1], 0, -1).'&#'.ord(strtolower(substr($m[1], -1))).';'; if (is_array($m) && isset($m[1])) {
if(isset($m[3])) return $wd.$m[2].$m[3]; $wd = substr($m[1], 0, -1) . '&#' . ord(strtolower(substr($m[1], -1))) . ';';
if(isset($m[2])) return $wd.$m[2].'('; if (isset($m[3])) return $wd . $m[2] . $m[3];
if (isset($m[2])) return $wd . $m[2] . '(';
return $wd; return $wd;
} }
return ''; return '';
...@@ -194,26 +218,27 @@ function strip_wd($m){ ...@@ -194,26 +218,27 @@ function strip_wd($m){
/** /**
* HTML过滤 * HTML过滤
* @param string|array $str 目标 * @param string|array $str 目标
* @param int $low 级别 默认1全过滤,0简单标签过滤 * @param int $low 级别 默认1全过滤,0简单标签过滤
* @return string|array * @return string|array
*/ */
function strip_html($str,$low = 1){ function strip_html($str, $low = 1)
if(is_array($str)){ {
return array_map('strip_html', $str, ['low'=>$low]); if (is_array($str)) {
}elseif(!empty($str)){ return array_map('strip_html', $str, ['low' => $low]);
} elseif (!empty($str)) {
$str = htmlspecialchars_decode(trim($str)); $str = htmlspecialchars_decode(trim($str));
$str = strip_tags($str); $str = strip_tags($str);
if($low){ if ($low) {
$str = str_replace(['"',"\\","'","/","..","../","./","//"],'',$str); $str = str_replace(['"', "\\", "'", "/", "..", "../", "./", "//"], '', $str);
$no = '/<!--.*-->/'; $no = '/<!--.*-->/';
$str = preg_replace("$no",'',$str); $str = preg_replace("$no", '', $str);
$no = '/%0[0-8bcef]/'; $no = '/%0[0-8bcef]/';
$str = preg_replace($no,'',$str); $str = preg_replace($no, '', $str);
$no = '/%1[0-9a-f]/'; $no = '/%1[0-9a-f]/';
$str = preg_replace($no,'',$str); $str = preg_replace($no, '', $str);
$no = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; $no = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';
$str = preg_replace($no,'',$str); $str = preg_replace($no, '', $str);
} }
} }
return $str; return $str;
...@@ -221,13 +246,14 @@ function strip_html($str,$low = 1){ ...@@ -221,13 +246,14 @@ function strip_html($str,$low = 1){
/** /**
* 转换HTML实体(双引号、单引号均转换) * 转换HTML实体(双引号、单引号均转换)
* @param string $s 目标字符 * @param string $s 目标字符
* @return string * @return string
*/ */
function vhtmlspecialchars($s){ function vhtmlspecialchars($s)
if(is_array($s)){ {
if (is_array($s)) {
return array_map('vhtmlspecialchars', $s); return array_map('vhtmlspecialchars', $s);
}else{ } else {
$s = htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); $s = htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
return str_replace('&amp;', '&', $s); return str_replace('&amp;', '&', $s);
} }
...@@ -235,152 +261,160 @@ function vhtmlspecialchars($s){ ...@@ -235,152 +261,160 @@ function vhtmlspecialchars($s){
/** /**
* 数字格式转换 * 数字格式转换
* @param float $v 数值 * @param float $v 数值
* @param int $p 小数点后位数 * @param int $p 小数点后位数
* @param bool $s 是否格式化为字符串 * @param bool $s 是否格式化为字符串
* @return float|string * @return float|string
*/ */
function dround($v, $p=2, $s=false){ function dround($v, $p = 2, $s = false)
{
$v = round(floatval($v), $p); $v = round(floatval($v), $p);
if($s) $v = sprintf('%.'.$p.'f', $v); if ($s) $v = sprintf('%.' . $p . 'f', $v);
return $v; return $v;
} }
/** /**
* 获取扩展名 * 获取扩展名
* @param string $f 文件路径串 * @param string $f 文件路径串
* @return string * @return string
*/ */
function file_ext($f){ function file_ext($f)
if(strpos($f, '.') === false) return ''; {
if (strpos($f, '.') === false) return '';
$ext = strtolower(trim(substr(strrchr($f, '.'), 1))); $ext = strtolower(trim(substr(strrchr($f, '.'), 1)));
return preg_match("/^[a-z0-9]{1,10}$/", $ext) ? $ext : ''; return preg_match("/^[a-z0-9]{1,10}$/", $ext) ? $ext : '';
} }
/** /**
* 删除文件夹 * 删除文件夹
* @param string $dirname 目录 * @param string $dirname 目录
* @param bool $self 是否删除自身 * @param bool $self 是否删除自身
* @return bool * @return bool
*/ */
function rmdirs($dirname, $self = true){ function rmdirs($dirname, $self = true)
if(!is_dir($dirname)){ {
return false; if (!is_dir($dirname)) {
} return false;
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS),RecursiveIteratorIterator::CHILD_FIRST); }
foreach($files as $fileinfo){ $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST);
$todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink'); foreach ($files as $fileinfo) {
$todo($fileinfo->getRealPath()); $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
} $todo($fileinfo->getRealPath());
if($self){ }
@rmdir($dirname); if ($self) {
} @rmdir($dirname);
return true; }
return true;
} }
/** /**
* 复制文件夹 * 复制文件夹
* @param string $source 源文件夹 * @param string $source 源文件夹
* @param string $dest 目标文件夹 * @param string $dest 目标文件夹
*/ */
function copydirs($source, $dest){ function copydirs($source, $dest)
if(!is_dir($dest)){ {
mkdir($dest, 0755, true); if (!is_dir($dest)) {
} mkdir($dest, 0755, true);
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),RecursiveIteratorIterator::SELF_FIRST); }
foreach($iterator as $item){ $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
if($item->isDir()){ foreach ($iterator as $item) {
$sontDir = $dest . VT_DS . $iterator->getSubPathName(); if ($item->isDir()) {
if(!is_dir($sontDir)){ $sontDir = $dest . VT_DS . $iterator->getSubPathName();
mkdir($sontDir, 0755, true); if (!is_dir($sontDir)) {
} mkdir($sontDir, 0755, true);
}else{ }
copy($item, $dest . VT_DS . $iterator->getSubPathName()); } else {
} copy($item, $dest . VT_DS . $iterator->getSubPathName());
} }
}
} }
/** /**
* 移除空目录 * 移除空目录
* @param string $dir 目录 * @param string $dir 目录
* @return * @return
*/ */
function remove_empty_folder($dir){ function remove_empty_folder($dir)
try{ {
try {
$isDirEmpty = !(new \FilesystemIterator($dir))->valid(); $isDirEmpty = !(new \FilesystemIterator($dir))->valid();
if($isDirEmpty){ if ($isDirEmpty) {
@rmdir($dir); @rmdir($dir);
remove_empty_folder(dirname($dir)); remove_empty_folder(dirname($dir));
} }
}catch(\UnexpectedValueException $e){ } catch (\UnexpectedValueException $e) {
}catch(\Exception $e){ } catch (\Exception $e) {
} }
} }
/** /**
* 键串转换键值串 * 键串转换键值串
* @param string $ids 键串 * @param string $ids 键串
* @param array $arr 数组 * @param array $arr 数组
* @return string * @return string
*/ */
function idstoname($ids,$arr){ function idstoname($ids, $arr)
{
$str = ''; $str = '';
$a = explode(',', $ids); $a = explode(',', $ids);
foreach($a as $i){ foreach ($a as $i) {
$t = $arr[$i] ?? ''; $t = $arr[$i] ?? '';
if($t) $str .= $str ? ','.$t : $t; if ($t) $str .= $str ? ',' . $t : $t;
} }
return $str; return $str;
} }
/** /**
* 获取站点配置 * 获取站点配置
* @param string $name 配置键【支持:域1.域2,插件配置获取:@插件名.键名】 * @param string $name 配置键【支持:域1.域2,插件配置获取:@插件名.键名】
* @param string $default 缺省值 * @param string $default 缺省值
* @return array|string * @return array|string
*/ */
function vconfig($name='',$default=''){ function vconfig($name = '', $default = '')
{
static $_VCF = []; static $_VCF = [];
$_VCF = $_VCF ?: \app\model\system\SystemSetting::cache(); $_VCF = $_VCF ?: \app\model\system\SystemSetting::cache();
if($name){ if ($name) {
if(isset($_VCF[$name])){ if (isset($_VCF[$name])) {
$rs = $_VCF[$name]; $rs = $_VCF[$name];
}else{ } else {
$dt = explode('.', $name); $dt = explode('.', $name);
if(isset($_VCF[$dt[0]])){ if (isset($_VCF[$dt[0]])) {
$rs = $_VCF[$dt[0]]; $rs = $_VCF[$dt[0]];
if(isset($dt[1])){ if (isset($dt[1])) {
$rs = $rs[$dt[1]] ?? $default; $rs = $rs[$dt[1]] ?? $default;
$_VCF[$dt[0].'.'.$dt[1]] = $rs; $_VCF[$dt[0] . '.' . $dt[1]] = $rs;
} }
}else{ } else {
$rs = $default; $rs = $default;
$_VCF[$dt[0]] = $rs; $_VCF[$dt[0]] = $rs;
} }
} }
return $rs || $rs == '0' || $rs === 0 ? $rs : $default; return $rs || $rs == '0' || $rs === 0 ? $rs : $default;
}else{ } else {
return $_VCF; return $_VCF;
} }
} }
/** /**
* 时间格式 * 时间格式
* @param int $time 时间戳 * @param int $time 时间戳
* @return string * @return string
*/ */
function show_time($time){ function show_time($time)
{
$rtime = date("Y-m-d H:i", $time); $rtime = date("Y-m-d H:i", $time);
$time = time() - $time; $time = time() - $time;
if($time < 60){ if ($time < 60) {
$str = '刚刚'; $str = '刚刚';
}elseif($time < 3600){ } elseif ($time < 3600) {
$str = floor($time / 60) . '分钟前'; $str = floor($time / 60) . '分钟前';
}elseif($time < 86400){ } elseif ($time < 86400) {
$str = floor($time / 3600) . '小时前'; $str = floor($time / 3600) . '小时前';
}elseif($time < 259200){ } elseif ($time < 259200) {
$str = floor($time / 86400) == 1 ? '昨天' : '前天'; $str = floor($time / 86400) == 1 ? '昨天' : '前天';
}else{ } else {
$str = $rtime; $str = $rtime;
} }
return $str; return $str;
...@@ -388,39 +422,41 @@ function show_time($time){ ...@@ -388,39 +422,41 @@ function show_time($time){
/** /**
* 配置项解析 Setting 后台设置模块中用到 * 配置项解析 Setting 后台设置模块中用到
* @param string $value 配置值 * @param string $value 配置值
* @return array|string * @return array|string
*/ */
function parse_attr($value = ''){ function parse_attr($value = '')
$array = preg_split('/[,;\r\n]+/', trim($value, ",;\r\n")); {
if(strpos($value, ':')){ $array = preg_split('/[,;\r\n]+/', trim($value, ",;\r\n"));
$value = []; if (strpos($value, ':')) {
foreach($array as $val){ $value = [];
list($k, $v) = explode(':', $val); foreach ($array as $val) {
$value[$k] = $v; list($k, $v) = explode(':', $val);
} $value[$k] = $v;
}else{ }
$value = $array; } else {
} $value = $array;
return $value; }
return $value;
} }
/** /**
* 获取所有子类ID * 获取所有子类ID
* @param int $pid 上级ID * @param int $pid 上级ID
* @param array $box 数据源 * @param array $box 数据源
* @param string $ikey ID键 * @param string $ikey ID键
* @param string $pkey 上级键 * @param string $pkey 上级键
* @return string ID串 * @return string ID串
*/ */
function get_subclass($pid,$box,$ikey='id',$pkey='pid'){ function get_subclass($pid, $box, $ikey = 'id', $pkey = 'pid')
{
$str = ''; $str = '';
foreach($box as $item){ foreach ($box as $item) {
if($item[$pkey]==$pid){ if ($item[$pkey] == $pid) {
$str .= $str ? ','.$item[$ikey] : $item[$ikey]; $str .= $str ? ',' . $item[$ikey] : $item[$ikey];
$get = get_subclass($item[$ikey],$box,$ikey,$pkey); $get = get_subclass($item[$ikey], $box, $ikey, $pkey);
if($get){ if ($get) {
$str .= ','.$get; $str .= ',' . $get;
} }
} }
} }
...@@ -429,71 +465,73 @@ function get_subclass($pid,$box,$ikey='id',$pkey='pid'){ ...@@ -429,71 +465,73 @@ function get_subclass($pid,$box,$ikey='id',$pkey='pid'){
/** /**
* 小地区往上查询 * 小地区往上查询
* @param int $areaid 地区ID * @param int $areaid 地区ID
* @param string $str 分隔符 * @param string $str 分隔符
* @param int $deep 查找深度 * @param int $deep 查找深度
* @param int $start 查找开始 * @param int $start 查找开始
* @return bool * @return bool
*/ */
function area_pos($areaid, $str = ' &raquo; ', $deep = 0, $start = 0){ function area_pos($areaid, $str = ' &raquo; ', $deep = 0, $start = 0)
{
$areaid = intval($areaid); $areaid = intval($areaid);
$area = \app\model\system\SystemArea::cache(); $area = \app\model\system\SystemArea::cache();
if(!$areaid || !$area) return ''; if (!$areaid || !$area) return '';
$arrparentid = $area[$areaid]['arrparentid'] ? explode(',', $area[$areaid]['arrparentid']) : []; $arrparentid = $area[$areaid]['arrparentid'] ? explode(',', $area[$areaid]['arrparentid']) : [];
$arrparentid[] = $areaid; $arrparentid[] = $areaid;
$pos = ''; $pos = '';
if($deep) $i = 1; if ($deep) $i = 1;
$j = 0; $j = 0;
foreach($arrparentid as $areaid){ foreach ($arrparentid as $areaid) {
if(!$areaid || !isset($area[$areaid])) continue; if (!$areaid || !isset($area[$areaid])) continue;
if($j++ < $start) continue; if ($j++ < $start) continue;
if($deep){ if ($deep) {
if($i > $deep) continue; if ($i > $deep) continue;
$i++; $i++;
} }
$pos .= $area[$areaid]['areaname'].$str; $pos .= $area[$areaid]['areaname'] . $str;
} }
$_len = strlen($str); $_len = strlen($str);
if($str && substr($pos, -$_len, $_len) === $str) $pos = substr($pos, 0, strlen($pos)-$_len); if ($str && substr($pos, -$_len, $_len) === $str) $pos = substr($pos, 0, strlen($pos) - $_len);
return $pos; return $pos;
} }
/** /**
* 多级列表构造(有递归) * 多级列表构造(有递归)
* @param array $rs 所有菜单数组集 * @param array $rs 所有菜单数组集
* @param int $pid 开始的父级ID * @param int $pid 开始的父级ID
* @param array $key 3要素 ['id','parentid','title'] 顺序不能变 * @param array $key 3要素 ['id','parentid','title'] 顺序不能变
* @param int $t 填充符 * @param int $t 填充符
* @param int $j 层级数 * @param int $j 层级数
* @param string $s 缩进符 * @param string $s 缩进符
* @param array $ids 某id键的子类个数集 * @param array $ids 某id键的子类个数集
* @param array $arr 返回的父子重构顺序集 相对 $rs 多了 new_title 键 * @param array $arr 返回的父子重构顺序集 相对 $rs 多了 new_title 键
* @return array * @return array
*/ */
function list_tree($rs=[],$pid=0,$key=['id','parentid','title'],$t=1,$j=0,$s='',$ids=[],$arr=[]){ function list_tree($rs = [], $pid = 0, $key = ['id', 'parentid', 'title'], $t = 1, $j = 0, $s = '', $ids = [], $arr = [])
if(empty($rs)) return $arr; {
$ids = empty($ids) ? array_count_values(array_column($rs,$key[1])) : $ids; if (empty($rs)) return $arr;
$ids = empty($ids) ? array_count_values(array_column($rs, $key[1])) : $ids;
$i = 1; $i = 1;
$k = $j; $k = $j;
$a = $s; $a = $s;
if($t==1){ if ($t == 1) {
$c = ["&nbsp;&nbsp;&nbsp;│ ",'&nbsp;&nbsp;&nbsp;├─ ','&nbsp;&nbsp;&nbsp;└─ ','&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;']; $c = ["&nbsp;&nbsp;&nbsp;│ ", '&nbsp;&nbsp;&nbsp;├─ ', '&nbsp;&nbsp;&nbsp;└─ ', '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'];
}else{ } else {
$c = [" - "," - "," - "," - "]; $c = [" - ", " - ", " - ", " - "];
} }
foreach($rs as $v){ foreach ($rs as $v) {
if($pid == $v[$key[1]]){ if ($pid == $v[$key[1]]) {
$n = ''; $n = '';
if($k>0){ if ($k > 0) {
$n = ($ids[$pid]==$i) ? $a.$c[2] : $a.$c[1]; $n = ($ids[$pid] == $i) ? $a . $c[2] : $a . $c[1];
$s = ($ids[$pid]==$i) ? $a.$c[3] : $a.$c[0]; $s = ($ids[$pid] == $i) ? $a . $c[3] : $a . $c[0];
} }
$v['new_title'] = $n.$v[$key[2]]; $v['new_title'] = $n . $v[$key[2]];
$arr[] = $v; $arr[] = $v;
$id = $v[$key[0]]; $id = $v[$key[0]];
if(isset($ids[$id])){ if (isset($ids[$id])) {
$j = $k+1; $j = $k + 1;
$arr = list_tree($rs,$id,$key,$t,$j,$s,$ids,$arr); $arr = list_tree($rs, $id, $key, $t, $j, $s, $ids, $arr);
} }
$i++; $i++;
} }
...@@ -503,20 +541,20 @@ function list_tree($rs=[],$pid=0,$key=['id','parentid','title'],$t=1,$j=0,$s='', ...@@ -503,20 +541,20 @@ function list_tree($rs=[],$pid=0,$key=['id','parentid','title'],$t=1,$j=0,$s='',
/** /**
* 生成单据号 * 生成单据号
* @param string $code 单据标识 * @param string $code 单据标识
* @param string $spr 拼接范式 * @param string $spr 拼接范式
* @param string $start 起始范式 * @param string $start 起始范式
* @return string * @return string
*/ */
function build_bill_no(string $code, string $spr = "-%03d", string $start = "-001") function build_bill_no(string $code, string $spr = "-%03d", string $start = "-001")
{ {
$day = strtotime(date('Y-m-d')); $day = strtotime(date('Y-m-d'));
$rs = \think\facade\Db::name('system_sequence')->where('code',$code)->find(); $rs = \think\facade\Db::name('system_sequence')->where('code', $code)->find();
if($rs){ if ($rs) {
$str = $rs['prefix'] . date("Ymd", $day); $str = $rs['prefix'] . date("Ymd", $day);
if ($rs['day'] == $day) { if ($rs['day'] == $day) {
$str .= sprintf($spr, $rs['seq']); $str .= sprintf($spr, $rs['seq']);
$rs['seq'] ++; $rs['seq']++;
} else { } else {
$str .= $start; $str .= $start;
$rs['seq'] = 2; $rs['seq'] = 2;
...@@ -524,7 +562,7 @@ function build_bill_no(string $code, string $spr = "-%03d", string $start = "-00 ...@@ -524,7 +562,7 @@ function build_bill_no(string $code, string $spr = "-%03d", string $start = "-00
} }
\think\facade\Db::name('system_sequence')->save($rs); \think\facade\Db::name('system_sequence')->save($rs);
return $str; return $str;
}else{ } else {
return '??' . date("Ymd", $day) . '001'; return '??' . date("Ymd", $day) . '001';
} }
} }
\ No newline at end of file
...@@ -16,7 +16,7 @@ use think\facade\Db; ...@@ -16,7 +16,7 @@ use think\facade\Db;
use think\Model; use think\Model;
/** /**
* 模型公用类 * 课程模型
*/ */
class ShCourse extends Model class ShCourse extends Model
{ {
...@@ -24,8 +24,9 @@ class ShCourse extends Model ...@@ -24,8 +24,9 @@ class ShCourse extends Model
public function getCreatetimeAttr($value) 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) public function getThumbpathAttr($value, $data)
{ {
return get_upload_file($data['thumb']); return get_upload_file($data['thumb']);
...@@ -46,10 +47,12 @@ class ShCourse extends Model ...@@ -46,10 +47,12 @@ class ShCourse extends Model
{ {
return CourseTeacher::where('id', $data['teacher_id'])->value('nickname'); return CourseTeacher::where('id', $data['teacher_id'])->value('nickname');
} }
public function getTagTitleAttr($value, $data) 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) public function getStatusTextAttr($value, $data)
{ {
switch ($data['status']) { switch ($data['status']) {
...@@ -74,4 +77,21 @@ class ShCourse extends Model ...@@ -74,4 +77,21 @@ class ShCourse extends Model
return User::where('id', $data['user_id'])->field('id,username,mobile')->find(); 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 @@ ...@@ -7,6 +7,7 @@
* Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行 * Licensed: 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
* --------------------------------------------------------------------------- * ---------------------------------------------------------------------------
*/ */
namespace app\model\system; namespace app\model\system;
use app\model\Base; use app\model\Base;
...@@ -18,22 +19,28 @@ class SystemUploadFile extends Base ...@@ -18,22 +19,28 @@ class SystemUploadFile extends Base
{ {
/** /**
* 定义主键 * 定义主键
* @var string * @var string
*/ */
protected $pk = 'fileid'; protected $pk = 'fileid';
/** /**
* 获取上传文件记录(分页) * 获取上传文件记录(分页)
* @param string/array $where 条件 * @param string/array $where 条件
* @param string/array $order 排序 * @param string/array $order 排序
* @param string $field 字段 * @param string $field 字段
* @return obj * @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(); $d = request()->param();
$limit = isset($d['limit']) ? intval($d['limit']) : (isset($d['size']) ? intval($d['size']) : 10); // 兼容百度编辑器附件列表 $limit = isset($d['limit']) ? intval($d['limit']) : (isset($d['size']) ? intval($d['size']) : 10); // 兼容百度编辑器附件列表
return $this->where($where)->order($order)->field($field)->paginate($limit); 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 [ ...@@ -32,4 +32,5 @@ return [
'error_message' => '页面错误!请稍后再试~', 'error_message' => '页面错误!请稍后再试~',
// 显示错误信息 // 显示错误信息
'show_error_msg' => false, 'show_error_msg' => false,
'file_http_url' => 'http://192.168.4.26:8082',
]; ];
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
return [ return [
//API接口地址 末尾不要加 / //API接口地址 末尾不要加 /
'api_url' => 'https://www.veitool.com', 'api_url' => '',
//插件强行卸载、覆盖 false 则会检查冲突文件 //插件强行卸载、覆盖 false 则会检查冲突文件
'force' => true, 'force' => true,
//插件是否备份有冲突的全局文件 //插件是否备份有冲突的全局文件
......
...@@ -114,10 +114,6 @@ layui.define(['tagsInput','fileLibrary','cascader'], function(e){ ...@@ -114,10 +114,6 @@ layui.define(['tagsInput','fileLibrary','cascader'], function(e){
var b = { var b = {
on: function(o,m,t){ 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