|
|
<?php
|
|
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
|
|
use App\Exports\CommonExport;
|
|
|
use App\Helpers\ResponseCode;
|
|
|
use App\Models\Course;
|
|
|
use App\Models\CourseContent;
|
|
|
use App\Models\Teacher;
|
|
|
use Illuminate\Support\Carbon;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
use Illuminate\Support\Facades\Validator;
|
|
|
use Maatwebsite\Excel\Facades\Excel;
|
|
|
use Rap2hpoutre\FastExcel\FastExcel;
|
|
|
|
|
|
class CourseContentController extends BaseController
|
|
|
{
|
|
|
|
|
|
/**
|
|
|
* 构造函数
|
|
|
*/
|
|
|
public function __construct()
|
|
|
{
|
|
|
parent::__construct(new CourseContent());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/api/admin/course-contents/index",
|
|
|
* tags={"排课"},
|
|
|
* summary="列表",
|
|
|
* description="",
|
|
|
* @OA\Parameter(name="is_export", in="query", @OA\Schema(type="string"), required=false, description="是否导出0否1是"),
|
|
|
* @OA\Parameter(name="export_fields", in="query", @OA\Schema(type="string"), required=false, description="需要导出的字段数组"),
|
|
|
* @OA\Parameter(name="file_name", in="query", @OA\Schema(type="string"), required=false, description="导出文件名"),
|
|
|
* @OA\Parameter(name="filter", in="query", @OA\Schema(type="string"), required=false, description="查询条件。数组"),
|
|
|
* @OA\Parameter(name="show_relation", in="query", @OA\Schema(type="string"), required=false, description="需要输出的关联关系数组,不填输出全部,填写输出指定数据"),
|
|
|
* @OA\Parameter(name="page_size", in="query", @OA\Schema(type="string"), required=false, description="每页显示的条数"),
|
|
|
* @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"),
|
|
|
* @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"),
|
|
|
* @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="暂无"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function index()
|
|
|
{
|
|
|
$all = request()->all();
|
|
|
$list = $this->model->with($all['show_relation'] ?? [])
|
|
|
->withCount('courseKeeps')
|
|
|
->withCount(['courseKeeps as user_sign_total' => function ($query) {
|
|
|
$query->where('status', 1);
|
|
|
}])->withCount(['courseKeeps as user_lack_sign_total' => function ($query) {
|
|
|
$query->where('status', 0);
|
|
|
}])->where(function ($query) use ($all) {
|
|
|
if (isset($all['filter']) && !empty($all['filter'])) {
|
|
|
foreach ($all['filter'] as $condition) {
|
|
|
$key = $condition['key'] ?? null;
|
|
|
$op = $condition['op'] ?? null;
|
|
|
$value = $condition['value'] ?? null;
|
|
|
if (!isset($key) || !isset($op) || !isset($value)) {
|
|
|
continue;
|
|
|
}
|
|
|
// 等于
|
|
|
if ($op == 'eq') {
|
|
|
$query->where($key, $value);
|
|
|
}
|
|
|
// 不等于
|
|
|
if ($op == 'neq') {
|
|
|
$query->where($key, '!=', $value);
|
|
|
}
|
|
|
// 模糊搜索
|
|
|
if ($op == 'like') {
|
|
|
$query->where($key, 'like', '%' . $value . '%');
|
|
|
}
|
|
|
// 否定模糊搜索
|
|
|
if ($op == 'notlike') {
|
|
|
$query->where($key, 'not like', '%' . $value . '%');
|
|
|
}
|
|
|
// null搜索
|
|
|
if ($op == 'null') {
|
|
|
$query->whereNull($key)->orWhere('json_length(' . $key . ') =', 0);
|
|
|
}
|
|
|
// notnull搜索
|
|
|
if ($op == 'notnull') {
|
|
|
// 不是null并且不是空json,这个是一个json字段
|
|
|
$query->whereNotNull($key)->where('json_length(' . $key . ') >', 0);
|
|
|
}
|
|
|
// 范围搜索
|
|
|
if ($op == 'range') {
|
|
|
list($from, $to) = explode(',', $value);
|
|
|
if (empty($from) || empty($to)) {
|
|
|
continue;
|
|
|
}
|
|
|
$query->whereBetween($key, [$from, $to]);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
})->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc');
|
|
|
if (isset($all['is_export']) && !empty($all['is_export'])) {
|
|
|
// 导出文件名字
|
|
|
$list = $list->limit(5000)->get()->toArray();
|
|
|
return Excel::download(new CommonExport($list, $all['export_fields'] ?? ''), $all['file_name'] ?? '' . date('YmdHis') . '.xlsx');
|
|
|
} else {
|
|
|
// 输出
|
|
|
$list = $list->paginate($all['page_size'] ?? 20);
|
|
|
}
|
|
|
return $this->success($list);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/api/admin/course-contents/show",
|
|
|
* tags={"排课"},
|
|
|
* summary="详情",
|
|
|
* description="",
|
|
|
* @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"),
|
|
|
* @OA\Parameter(name="show_relation", in="query", @OA\Schema(type="string"), required=false, description="需要输出的关联关系数组,填写输出指定数据"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="暂无"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function show()
|
|
|
{
|
|
|
$all = \request()->all();
|
|
|
$messages = [
|
|
|
'id.required' => 'Id必填',
|
|
|
];
|
|
|
$validator = Validator::make($all, [
|
|
|
'id' => 'required'
|
|
|
], $messages);
|
|
|
if ($validator->fails()) {
|
|
|
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
|
|
|
}
|
|
|
$detail = $this->model->with('courseContentEvaluation.courseContentEvaluationAsks')->find($all['id']);
|
|
|
return $this->success($detail);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Post(
|
|
|
* path="/api/admin/course-contents/save",
|
|
|
* tags={"排课"},
|
|
|
* summary="更新或新增",
|
|
|
* @OA\Parameter(name="id", in="query", @OA\Schema(type="integer"), required=true, description="课程ID(存在则更新,不存在则新增)"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="验证token"),
|
|
|
* @OA\Parameter(name="course_id", in="query", @OA\Schema(type="integer"), description="课程ID"),
|
|
|
* @OA\Parameter(name="start_time", in="query", @OA\Schema(type="string"), description="开始时间"),
|
|
|
* @OA\Parameter(name="end_time", in="query", @OA\Schema(type="string"), description="结束时间"),
|
|
|
* @OA\Parameter(name="date", in="query", @OA\Schema(type="string", format="date"), description="日期"),
|
|
|
* @OA\Parameter(name="teacher_id", in="query", @OA\Schema(type="integer"), description="老师ID"),
|
|
|
* @OA\Parameter(name="address", in="query", @OA\Schema(type="string"), description="地址"),
|
|
|
* @OA\Parameter(name="theme", in="query", @OA\Schema(type="string"), description="主题"),
|
|
|
* @OA\Parameter(name="longitude", in="query", @OA\Schema(type="string"), description="经度"),
|
|
|
* @OA\Parameter(name="latitude", in="query", @OA\Schema(type="string"), description="纬度"),
|
|
|
* @OA\Parameter(name="address_detail", in="query", @OA\Schema(type="string"), description="详细地址"),
|
|
|
* @OA\Parameter(name="file_ids", in="query", @OA\Schema(type="string"), description="文件id数组"),
|
|
|
* @OA\Response(
|
|
|
* response=200,
|
|
|
* description="操作成功"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function save()
|
|
|
{
|
|
|
return parent::save();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/api/admin/course-contents/destroy",
|
|
|
* tags={"排课"},
|
|
|
* summary="删除",
|
|
|
* description="",
|
|
|
* @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="暂无"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function destroy()
|
|
|
{
|
|
|
return parent::destroy();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Post(
|
|
|
* path="/api/admin/course-contents/excel-show",
|
|
|
* tags={"排课"},
|
|
|
* summary="导入预览",
|
|
|
* description="",
|
|
|
* @OA\Parameter(name="course_id", in="query", @OA\Schema(type="string"), required=true, description="课程ID"),
|
|
|
* @OA\Parameter(name="file", in="query", @OA\Schema(type="string"), required=true, description="文件"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="暂无"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function excelShow()
|
|
|
{
|
|
|
$file = \request()->file('file');
|
|
|
$course_id = request('course_id');
|
|
|
if (empty($course_id)) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '课程不存在']);
|
|
|
}
|
|
|
//判断文件是否有效
|
|
|
if (!(\request()->hasFile('file') && $file->isValid())) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '文件不存在或无效']);
|
|
|
}
|
|
|
//获取文件大小
|
|
|
$img_size = floor($file->getSize() / 1024);
|
|
|
if ($img_size >= 50 * 1024) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '文件必须小于50M']);
|
|
|
}
|
|
|
//过滤文件后缀
|
|
|
$ext = $file->getClientOriginalExtension();
|
|
|
if (!in_array($ext, ['xls', 'xlsx', 'csv'])) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '仅支持xls/xlsx/csv格式']);
|
|
|
}
|
|
|
$tempFile = $file->getRealPath();
|
|
|
$dataArray = (new FastExcel)->import($tempFile)->toArray();
|
|
|
// 获取所有key
|
|
|
$keyList = array_keys($dataArray[0]);
|
|
|
if (!in_array('日期', $keyList)) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '日期字段不存在']);
|
|
|
}
|
|
|
if (!in_array('时间', $keyList)) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '时间字段不存在']);
|
|
|
}
|
|
|
if (!in_array('授课老师', $keyList)) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '授课老师字段不存在']);
|
|
|
}
|
|
|
if (!in_array('老师简介', $keyList)) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '老师简介字段不存在']);
|
|
|
}
|
|
|
if (!in_array('课程主题', $keyList)) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '课程主题字段不存在']);
|
|
|
}
|
|
|
if (!in_array('上课地点', $keyList)) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '上课地点字段不存在']);
|
|
|
}
|
|
|
if (!in_array('联系方式', $keyList)) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '联系方式字段不存在']);
|
|
|
}
|
|
|
if (!in_array('性别', $keyList)) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '性别字段不存在']);
|
|
|
}
|
|
|
$list = [];
|
|
|
foreach ($dataArray as $value) {
|
|
|
if (empty($value['授课老师']) && empty($value['联系方式'])) {
|
|
|
continue;
|
|
|
}
|
|
|
if ($value['授课老师']) {
|
|
|
$teacher_id = Teacher::where('name', $value['授课老师'])->value('id');
|
|
|
}
|
|
|
if ($value['联系方式']) {
|
|
|
$teacher_id = Teacher::where('mobile', $value['联系方式'])->value('id');
|
|
|
}
|
|
|
$list[] = [
|
|
|
'course_id' => $course_id,
|
|
|
'date' => Carbon::parse($value['日期'])->toDateString(),
|
|
|
'period' => $value['时间'] ?? '',
|
|
|
'teacher_name' => $value['授课老师'] ?? '',
|
|
|
'teacher_introduce' => $value['老师简介'] ?? '',
|
|
|
'teacher_id' => $teacher_id ?? null,
|
|
|
'address' => $value['上课地点'] ?? '',
|
|
|
'theme' => $value['课程主题'] ?? '',
|
|
|
'sex' => $value['性别'] ?? '',
|
|
|
'mobile' => $value['联系方式'] ?? ''
|
|
|
];
|
|
|
}
|
|
|
return $this->success($list);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Post(
|
|
|
* path="/api/admin/course-contents/import",
|
|
|
* tags={"排课"},
|
|
|
* summary="导入",
|
|
|
* description="",
|
|
|
* @OA\Parameter(name="data", in="query", @OA\Schema(type="string"), required=true, description="导入分析获取到的二维数组"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="暂无"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function import()
|
|
|
{
|
|
|
$all = \request()->all();
|
|
|
$messages = [
|
|
|
'data.required' => '数据必填',
|
|
|
];
|
|
|
$validator = Validator::make($all, [
|
|
|
'data' => 'required',
|
|
|
], $messages);
|
|
|
if ($validator->fails()) {
|
|
|
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
|
|
|
}
|
|
|
$records = $all['data'];
|
|
|
if (!isset($records[0]['course_id'])) {
|
|
|
return $this->fail([ResponseCode::ERROR_PARAMETER, '数据不存在']);
|
|
|
}
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
// CourseContent::where('course_id', $records[0]['course_id'])->delete();
|
|
|
Course::where('id', $records[0]['course_id'])->update(['course_content_status' => 0]);
|
|
|
// 分段导入
|
|
|
foreach ($records as $item) {
|
|
|
if (!isset($item['teacher_id']) || empty($item['teacher_id'])) {
|
|
|
// 写入老师表
|
|
|
if ($item['mobile']) {
|
|
|
$where = ['mobile' => $item['mobile']];
|
|
|
}
|
|
|
if ($item['teacher_name']) {
|
|
|
$where = ['name' => $item['teacher_name']];
|
|
|
}
|
|
|
$data = [
|
|
|
'mobile' => $item['mobile'],
|
|
|
'name' => $item['teacher_name'],
|
|
|
'introduce' => $item['teacher_introduce'],
|
|
|
'sex' => $item['sex'],
|
|
|
];
|
|
|
$teacher = Teacher::updateOrCreate($where, $data);
|
|
|
$item['teacher_id'] = $teacher->id;
|
|
|
} else {
|
|
|
$teacher = Teacher::find($item['teacher_id']);
|
|
|
$teacher->name = $item['teacher_name'];
|
|
|
$teacher->mobile = $item['mobile'];
|
|
|
$teacher->introduce = $item['teacher_introduce'];
|
|
|
$teacher->sex = $item['sex'];
|
|
|
$teacher->save();
|
|
|
}
|
|
|
CourseContent::create($item);
|
|
|
}
|
|
|
DB::commit();
|
|
|
return $this->success(['total' => count($records), 'filter_total' => count($records)]);
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return $this->fail([$exception->getCode(), $exception->getMessage()]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/api/admin/course-contents/qrcode",
|
|
|
* tags={"排课"},
|
|
|
* summary="签到二维码",
|
|
|
* description="",
|
|
|
* @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="暂无"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function qrcode()
|
|
|
{
|
|
|
$all = \request()->all();
|
|
|
$messages = [
|
|
|
'id.required' => 'Id必填',
|
|
|
];
|
|
|
$validator = Validator::make($all, [
|
|
|
'id' => 'required'
|
|
|
], $messages);
|
|
|
if ($validator->fails()) {
|
|
|
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
|
|
|
}
|
|
|
$url = (new CourseContent())->getCourseContentCheckQrcode($all['id']);
|
|
|
return $this->success($url);
|
|
|
}
|
|
|
|
|
|
}
|