Train.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. <?php
  2. namespace app\adminall\controller;
  3. use app\model\Miniprogram;
  4. use app\model\TrainClassAssign;
  5. use app\model\TrainClassView;
  6. use think\facade\Request;
  7. use think\facade\View;
  8. use think\facade\Db;
  9. use app\model\TrainClass;
  10. use app\model\TrainCourse;
  11. use app\model\TrainType;
  12. use app\model\TrainDoneLog;
  13. use app\model\TrainSumup;
  14. use app\model\Org;
  15. use app\logics\OrgLogic;
  16. use app\model\Employee;
  17. use app\event\Msg;
  18. use wx\miniprogram\Qrcode;
  19. use app\model\User;
  20. use app\model\Company;
  21. use app\model\TrainCourseView;
  22. use app\model\TrainClassCate;
  23. use app\model\CreditsSetting;
  24. use app\model\Lecturer;
  25. class Train
  26. {
  27. private $root_id = 0;//总后台店面id默认0
  28. /**
  29. * 课件列表页面展示
  30. */
  31. public function course_index()
  32. {
  33. $condition = [
  34. 'root_id' => $this->root_id,
  35. 'from_type' => 0
  36. ];
  37. $type = TrainType::where($condition)->select()->toArray();
  38. View::assign('type', $type);
  39. return View::fetch();
  40. }
  41. /**
  42. * 课件列表
  43. */
  44. public function trainCourseList()
  45. {
  46. $param = request()->param();
  47. $condition[] = ['root_id', '=', $this->root_id];
  48. if (isset($param['type_id']) && !empty($param['type_id'])) $condition[] = ['type_id', '=', $param['type_id']];
  49. if (isset($param['keyword']) && !empty($param['keyword'])) $condition[] = ['title', 'like', '%' . $param['keyword'] . '%'];
  50. if (isset($param['type']) && !empty($param['type'])) $condition[] = ['type', '=', $param['type']];
  51. if (isset($param['date']) && !empty($param['date'])) $condition[] = ['date', 'like', '%' . $param['date'] . '%'];
  52. $data = TrainCourse::where($condition)->page($param['page'], $param['limit'])->order('id desc')->select();
  53. $count = TrainCourse::where($condition)->count();
  54. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  55. }
  56. /*
  57. * 课件场景列表
  58. */
  59. public function type_index()
  60. {
  61. if (!Request::isAjax()) {
  62. return View::fetch();
  63. }
  64. $param = request()->param();
  65. $condition = [
  66. 'root_id' => $this->root_id,
  67. 'from_type' => 0
  68. ];
  69. $data = TrainType::where($condition)->page($param['page'], $param['limit'])
  70. // ->order('train_course_count desc,id desc')
  71. ->order(['show'=>'asc','id'=>'desc'])
  72. ->select();
  73. $count = TrainType::where($condition)->count();
  74. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  75. }
  76. /*
  77. * 课件场景添加
  78. */
  79. public function add_train_type()
  80. {
  81. $type = Request::param('type');
  82. if (empty($type)) return json(['code' => 1, 'msg' => '请输入场景名称']);
  83. $isAdd = TrainType::where(['type' => $type, 'root_id' => $this->root_id])->count();
  84. if ($isAdd > 0) return json(['code' => 1, 'msg' => '场景已存在']);
  85. $objId = TrainType::insertGetId(['type' => $type, 'root_id' => $this->root_id]);
  86. return json(['code' => 0, 'msg' => '添加成功', 'data' => ['id' => $objId, 'type' => $type]]);
  87. }
  88. /*
  89. * 场景删除
  90. */
  91. public function del_train_type()
  92. {
  93. $id = Request::param('id');
  94. $data = TrainType::where(['id' => $id, 'root_id' => $this->root_id])->find();
  95. if (!$data) return json(['code' => 1, 'msg' => '删除失败']);
  96. $other_id = TrainType::where(['root_id'=>$this->root_id , 'show'=>1])->value('id');
  97. if(empty($other_id)) $other_id = TrainType::insertGetId(['type'=>'其它','root_id'=>$this->root_id,'show'=>1]);
  98. TrainCourse::where(['root_id'=>$this->root_id , 'type_id'=>$id])->update(['type_id'=>$other_id]);
  99. $data->delete();
  100. return json(['code' => 0, 'msg' => '删除成功']);
  101. }
  102. /*
  103. * 课件场景修改
  104. */
  105. public function edit_train_type()
  106. {
  107. $id = Request::param('id');
  108. $type = Request::param('type');
  109. if (empty($type)) return json(['code' => 1, 'msg' => '请输入场景名称']);
  110. if (TrainType::where(['id' => $id, 'root_id' => $this->root_id])->update(['type' => $type])) {
  111. return json(['code' => 0, 'msg' => '修改成功']);
  112. } else {
  113. return json(['code' => 1, 'msg' => '修改失败']);
  114. }
  115. }
  116. /**
  117. * 课件添加页面
  118. */
  119. public function course_add()
  120. {
  121. $condition = [
  122. 'root_id' => $this->root_id,
  123. 'from_type' => 0
  124. ];
  125. $type = TrainType::where($condition)->select()->toArray();
  126. View::assign('type', $type);
  127. return View::fetch();
  128. }
  129. /*
  130. * 课件保存
  131. */
  132. public function courseAddSave()
  133. {
  134. $data = Request::only(['title', 'type_id', 'type', 'content', 'video_img', 'file_image', 'file_video', 'file_audio', 'file_pdf', 'time_check', 'word_check', 'study_time', 'comment_word_num']);
  135. if ($data['time_check'] == 0 && $data['word_check'] == 0) return json(['code' => 1, 'msg' => '完成条件最少选择一项']);
  136. $ask = input('content');
  137. $ask = str_replace('&nbsp;', '', $ask);
  138. if (trim($ask) == '' && $data['type'] != 'pdf') {
  139. return json(['code' => 1, 'msg' => '课件内容不能为空']);
  140. }
  141. $newData = [
  142. 'root_id' => $this->root_id,
  143. 'title' => $data['title'],
  144. 'type_id' => $data['type_id'],
  145. 'content' => $data['content'],
  146. 'type' => $data['type'],
  147. 'study_time' => $data['time_check'] == 0 ? 0 : $data['study_time'],
  148. 'comment_word_num' => $data['word_check'] == 0 ? 0 : $data['comment_word_num']
  149. ];
  150. if ($data['type'] == 'video') {
  151. if (empty($data['file_video'])) return json(['code' => 1, 'msg' => '请选择视频']);
  152. $arr = explode(',', $data['file_video']);
  153. $newData['file'] = end($arr);
  154. $newData['video_img'] = !empty($data['video_img']) ? $data['video_img'] : null;
  155. } elseif ($data['type'] == 'image') {
  156. if (empty($data['file_image'])) return json(['code' => 1, 'msg' => '请选择图片']);
  157. $newData['file'] = $data['file_image'];
  158. } elseif ($data['type'] == 'pdf') {
  159. if (empty($data['file_pdf'])) return json(['code' => 1, 'msg' => '请选择pdf课程文件']);
  160. $arr = explode(',', $data['file_pdf']);
  161. $newData['file'] = end($arr);
  162. } else {
  163. if (empty($data['file_audio'])) return json(['code' => 1, 'msg' => '请选择音频']);
  164. $arr = explode(',', $data['file_audio']);
  165. $newData['file'] = end($arr);
  166. }
  167. if (TrainCourse::insert($newData)) {
  168. return json(['code' => 0, 'msg' => '添加成功']);
  169. } else {
  170. return json(['code' => 1, 'msg' => '添加失败']);
  171. }
  172. }
  173. /**
  174. * 课件富文本文件上传
  175. */
  176. public function fileupload()
  177. {
  178. $ali_oss_bindurl = config('app.ali_oss_bindurl');
  179. $url = 'https://' . $ali_oss_bindurl . '/' . Request::param('file');
  180. return json(['code' => 0, 'data' => ['src' => $url]]);
  181. }
  182. /**
  183. * 课件活动编辑页面
  184. */
  185. public function course_edit()
  186. {
  187. $id = Request::param('id');
  188. $data = (new TrainCourse())->where(['id' => $id, 'root_id' => $this->root_id])->find();
  189. View::assign('type_id', $data->getData('type_id'));
  190. View::assign('data', $data);
  191. View::assign('old_file', $data->getData('file'));
  192. View::assign('old_video_img', $data->getData('video_img'));
  193. //$type = TrainType::where(['root_id' => $this->root_id, 'id' => $data->getData('type_id')])->field('id,type')->find();
  194. $condition = [
  195. 'root_id' => $this->root_id,
  196. 'from_type' => 0
  197. ];
  198. $type = TrainType::where($condition)->select()->toArray();
  199. View::assign('type', $type);
  200. return View::fetch();
  201. }
  202. /**
  203. * 课件活动编辑保存
  204. */
  205. public function courseEditSave()
  206. {
  207. $data = Request::only(['title', 'type_id', 'type', 'content', 'video_img', 'file_image', 'file_audio', 'file_video', 'file_pdf', 'id', 'time_check', 'word_check', 'study_time', 'comment_word_num']);
  208. if ($data['time_check'] == 0 && $data['word_check'] == 0) return json(['code' => 1, 'msg' => '完成条件最少选择一项']);
  209. $ask = input('content');
  210. $ask = str_replace('&nbsp;', '', $ask);
  211. if (trim($ask) == '' && $data['type'] != 'pdf') {
  212. return json(['code' => 1, 'msg' => '课件内容不能为空']);
  213. }
  214. $newData = [
  215. 'root_id' => $this->root_id,
  216. 'title' => $data['title'],
  217. 'type_id' => $data['type_id'],
  218. 'content' => $data['content'],
  219. 'type' => $data['type'],
  220. 'study_time' => $data['time_check'] == 0 ? 0 : $data['study_time'],
  221. 'comment_word_num' => $data['word_check'] == 0 ? 0 : $data['comment_word_num']
  222. ];
  223. // 添加判断
  224. $course = TrainCourse::where(['root_id' => $this->root_id, 'id' => $data['id']])->find();
  225. if (empty($course)) return json(['code' => 1, 'msg' => '课件不存在']);
  226. // 判断是否更换类型,如果更换类型,则内容需要重新上传
  227. if ($course->type != $data['type'] && empty($data['file_' . $data['type']])) {
  228. $msgType = [
  229. 'video' => '视频',
  230. 'audio' => '音频',
  231. 'pdf' => 'pdf课程文件',
  232. 'image' => '图片',
  233. ];
  234. return json(['code' => 1, 'msg' => '请选择' . $msgType[$data['type']]]);
  235. }
  236. if (!empty($data['file_' . $data['type']])) {
  237. if ($data['type'] == 'image') {
  238. $newData['file'] = $data['file_image'];
  239. } else {
  240. $arr = explode(',', $data['file_' . $data['type']]);
  241. $newData['file'] = end($arr);
  242. if ('video' == $data['type'])
  243. $newData['video_img'] = !empty($data['video_img']) ? $data['video_img'] : null;
  244. }
  245. }
  246. $course->save($newData);
  247. // if ($data['type'] == 'video') {
  248. // if (empty($data['file_video'])) return json(['code' => 1, 'msg' => '请选择视频']);
  249. // $arr = explode(',', $data['file_video']);
  250. // $newData['file'] = end($arr);
  251. // $newData['video_img'] = !empty($data['video_img']) ? $data['video_img'] : null;
  252. // } elseif ($data['type'] == 'audio') {
  253. // if (empty($data['file_audio'])) return json(['code' => 1, 'msg' => '请选择音频']);
  254. // $arr = explode(',', $data['file_audio']);
  255. // $newData['file'] = end($arr);
  256. // } elseif ($data['type'] == 'pdf') {
  257. // if (empty($data['file_pdf'])) return json(['code' => 1, 'msg' => '请选择pdf课程文件']);
  258. // $arr = explode(',', $data['file_pdf']);
  259. // $newData['file'] = end($arr);
  260. // } else {
  261. // if (empty($data['file_image'])) return json(['code' => 1, 'msg' => '请选择图片']);
  262. // $newData['file'] = $data['file_image'];
  263. // }
  264. // TrainCourse::where(['root_id' => $this->root_id, 'id' => $data['id']])->update($newData);
  265. return json(['code' => 0, 'msg' => '修改成功']);
  266. }
  267. /**
  268. * 课件删除
  269. */
  270. public function del_course_train()
  271. {
  272. $id = Request::param('id');
  273. $course = TrainCourse::where(['id' => $id, 'root_id' => $this->root_id])->find();
  274. if (!$course) return json(['code' => 1, 'msg' => '删除失败,课件不存在']);
  275. Db::startTrans();
  276. try {
  277. //查询课程中使用该课件的数据
  278. $data = TrainClass::field('id,course_id,publish')->whereRaw("FIND_IN_SET(" . $id . " , course_id)")->where([['root_id', '=', $this->root_id], ['del', '=', 0]])->select()->toArray();
  279. $column_cid = array_column($data, 'id');
  280. $course->delete_time = time();
  281. $course->save();
  282. foreach ($data as $item) {
  283. //删除绑定该课件的课程,如果该课程全部删除课件则下架课程
  284. $newArr = array_diff(explode(',', $item['course_id']), explode(',', $id));
  285. $newArrs = implode(',', $newArr);
  286. $update = [
  287. 'course_id' => $newArrs,
  288. 'publish' => empty($newArrs) ? 0 : $item['publish']
  289. ];
  290. TrainClass::where('id', $item['id'])->update($update);
  291. //查询完成数据中有存在删除的课件
  292. $log = TrainDoneLog::where([['from', '=', 0], ['class_id', '=', $item['id']], ['root_id', '=', $this->root_id]])->whereRaw("FIND_IN_SET(" . $id . " , course_id)")->field('id,course_id,done_percent')->select();
  293. foreach ($log as $val) {
  294. $newsArr = array_diff(explode(',', $val['course_id']), explode(',', $id));
  295. $newLogArr = implode(',', $newsArr);
  296. $GDP = $this->GDP(count($newsArr), count($newArr));
  297. TrainDoneLog::where('id', $val['id'])->update(['course_id' => $newLogArr, 'done_percent' => $GDP]);
  298. }
  299. }
  300. Db::commit();
  301. return json(['code' => 0, 'msg' => '删除成功']);
  302. } catch (\Exception $e) {
  303. Db::rollback();
  304. return json(['code' => 1, 'msg' => '删除失败']);
  305. }
  306. }
  307. /*
  308. * 课程培训
  309. * 新逻辑 区分指派前和指派后 以train_class表的train_employee字段区分,为空则为指派前阶段,有值为指派后阶段
  310. * 指派前阶段为自由学习阶段,所有人都可以看到课程并学习,指派后则为指派的人能学习
  311. * 量化考核中也要区分,指派前和指派后互相数据不关联
  312. */
  313. public function class_index()
  314. {
  315. if (!Request::isAjax()) {
  316. return View::fetch();
  317. }
  318. $param = request()->param();
  319. $condition[] = ['del', '=', 0];
  320. $condition[] = ['root_id', '=', $this->root_id];
  321. $condition[] = ['from_type', 'in', [0, 2]];
  322. if (isset($param['keyword'])) $condition[] = ['title', 'like', '%' . $param['keyword'] . '%'];
  323. if (isset($param['date'])) $condition[] = ['addtime', 'like', '%' . $param['date'] . '%'];
  324. $data = TrainClass::withCount(['doneLog' => function ($query, &$alias) {
  325. $query->where('done_percent', 100);
  326. $alias = 'completeCount';
  327. }])->withCount(['doneLog' => function ($query, &$alias) {
  328. $query->where([['done_percent', '<', 100], ['done_percent', '>', 0]]);
  329. $alias = 'noFinishCount';
  330. }])->where($condition)->page($param['page'], $param['limit'])->order('addtime desc')
  331. ->field('id,title,course_id,addtime,org_id,train_employee')->select()->toArray();
  332. $orgCount = Employee::where([['root_id', '=', $this->root_id], ['state', 'like', '%在职%'], ['org_id', '>', 0], ['uid', '>', 0]])->group('org_id')->column('count(org_id)', 'org_id');
  333. //总人数
  334. $total = Employee::where([['root_id','=',$this->root_id],['state','=','在职'],['uid','>',0]])->count();
  335. //课程总结
  336. $trainSummary = TrainSumup::where([['root_id', '=', $this->root_id], ['course_id', '=', 0]])->group('class_id,employee_id')->column('count(id),class_id');
  337. foreach ($data as &$v) {
  338. //培训人数
  339. $v['trainNumber'] = 0;
  340. if (!empty($orgCount) && !empty($v['org_id'])) {
  341. $trainArr = explode(',', $v['org_id']);
  342. foreach ($trainArr as $c) {
  343. isset($orgCount[$c]) ? $v['trainNumber'] += $orgCount[$c] : 0;
  344. }
  345. }
  346. //章节数
  347. $v['courseCount'] = empty($v['course_id']) ? 0 : count(explode(',', $v['course_id']));
  348. //指派人员
  349. $employee_id = explode(',', $v['train_employee']);
  350. $v['train_employee'] = count(array_filter(explode(',', $v['train_employee'])));
  351. //未开始人数
  352. $v['noStartCount'] = $v['train_employee'] - ($v['completeCount'] + $v['noFinishCount']);
  353. $v['noStartCount'] = $v['noStartCount'] >= 0 ? $v['noStartCount'] : 0;
  354. //完成观后感
  355. $v['summaryCount'] = isset($trainSummary[$v['id']]) ? $trainSummary[$v['id']] : 0;
  356. //新逻辑 区分指派前和指派后 ,这段删除就是之前的逻辑
  357. if ($v['train_employee']) {
  358. $v['trainNumber'] = $v['train_employee'];
  359. //指派后,完成人数
  360. $v['completeCount'] = TrainDoneLog::where([['class_id','=',$v['id']],['employee_id','in',$employee_id],['done_percent','=',100]])->count();
  361. $nofinish = TrainDoneLog::where([['class_id','=',$v['id']],['employee_id','in',$employee_id],['done_percent','in',[1,99]]])->count();
  362. //未完成人数
  363. $v['noFinishCount'] = count($employee_id) - $v['completeCount'];
  364. //未开始
  365. $v['noStartCount'] = count($employee_id) - $v['completeCount'] - $nofinish;
  366. //感悟数量
  367. $v['summaryCount'] = TrainSumup::where([['employee_id','in',$employee_id],['class_id','=', $v['id']], ['course_id', '=', 0]])->group('employee_id')->count();
  368. }else{
  369. //指派前,培训人数和学习人数都是所有人
  370. $v['trainNumber'] = $v['train_employee'] = $total;
  371. //未开始人数
  372. $v['noStartCount'] = $total - ($v['completeCount'] + $v['noFinishCount']);
  373. //未完成
  374. $v['noFinishCount'] = $total - $v['completeCount'];
  375. }
  376. }
  377. $count = TrainClass::where($condition)->count();
  378. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  379. }
  380. /**
  381. * 分类管理
  382. */
  383. public function class_cate()
  384. {
  385. return View::fetch();
  386. }
  387. /**
  388. * 分类管理添加
  389. */
  390. public function class_cate_add()
  391. {
  392. $root_id = $this->root_id;
  393. $param = Request::only(['name' => '']);
  394. $param['name'] = str_replace(' ', '', $param['name']);
  395. $w[] = ['root_id', '=', $root_id];
  396. $w[] = ['name', '=', $param['name']];
  397. $find = TrainClassCate::where($w)->findOrEmpty();
  398. if (!$find->isEmpty()) return json(['code' => 1, 'data' => '分类已存在', 'msg' => '分类已存在']);
  399. $id = TrainClassCate::insertGetId(['root_id' => $root_id, 'name' => $param['name']]);
  400. return json(['code' => 0, 'data' => '添加成功', 'msg' => '添加成功', 'id' => $id]);
  401. }
  402. /**
  403. * 分类管理列表
  404. */
  405. public function class_cate_list()
  406. {
  407. $root_id = $this->root_id;
  408. $param = Request::only(['page' => 1, 'limit' => 10]);
  409. $w[] = ['root_id', '=', $root_id];
  410. $w[] = ['pid', '=', 0];
  411. $list = TrainClassCate::where($w)->page($param['page'], $param['limit'])->order(['show' => 'asc','order' => 'asc'])->select();
  412. $count = TrainClassCate::where($w)->count();
  413. return json(['code' => 0, 'data' => $list, 'count' => $count]);
  414. }
  415. /**
  416. * 分类管理编辑
  417. */
  418. public function class_cate_edit()
  419. {
  420. $root_id = $this->root_id;
  421. $param = Request::only(['id' => 0, 'name' => '']);
  422. $w[] = ['root_id', '=', $root_id];
  423. $w[] = ['id', '<>', $param['id']];
  424. $w[] = ['name', '=', $param['name']];
  425. $w[] = ['pid', '=', 0];
  426. $find = TrainClassCate::where($w)->findOrEmpty();
  427. if (!$find->isEmpty()) return json(['code' => 1, 'data' => '分类已存在', 'msg' => '分类已存在']);
  428. $name = TrainClassCate::where('id', $param['id'])->value('name');
  429. TrainClassCate::where('id', $param['id'])->update(['name' => $param['name']]);
  430. $w1[] = ['cate', '=', $name];
  431. $w1[] = ['root_id', '=', $root_id];
  432. TrainClass::where($w1)->update(['cate' => $param['name']]);
  433. return json(['code' => 0, 'data' => '修改成功', 'msg' => '修改成功']);
  434. }
  435. /*
  436. * 删除标签或分类前,查询关联的内容数量
  437. */
  438. public function with_type_count()
  439. {
  440. $param = Request::param();
  441. if($param['type'] == 'cate')
  442. {
  443. $field = 'cate';
  444. }else{
  445. $field = 'label';
  446. }
  447. $where = [
  448. ['root_id','=',$this->root_id],
  449. ['del','=',0],
  450. [$field,'=',$param[$field]]
  451. ];
  452. $count = TrainClass::where($where)->count();
  453. if($count > 0)
  454. {
  455. $type = $field == 'cate' ? '分类' : '标签' ;
  456. $msg = '该'.$type.'关联'.$count.'个'.'课程,删除后该内容将归为其它分类。';
  457. }else{
  458. $msg = '确定删除该分类吗?';
  459. }
  460. return $msg;
  461. }
  462. /*
  463. * 分类、标签删除
  464. */
  465. public function class_cate_or_label_del()
  466. {
  467. $param = Request::param();
  468. $trainCate = TrainClassCate::where(['root_id'=>$this->root_id,'id'=>$param['id']])->find();
  469. if(empty($trainCate)) return json(['code' => 1, 'msg' => '数据不存在']);
  470. Db::startTrans();
  471. try {
  472. if($param['type'] == 'cate')
  473. {
  474. //查询是否存在其它分类
  475. $type_id = TrainClassCate::where(['root_id'=>$this->root_id,'pid'=>0,'show'=>1])->value('id');
  476. if(empty($type_id)) $type_id = TrainClassCate::insertGetId(['pid'=>0,'name'=>'其它','root_id'=>$this->root_id,'show'=>1]);
  477. //更新关联内容
  478. TrainClass::where(['root_id'=>$this->root_id,'cate'=>$trainCate['name']])->update(['cate'=>'其它']);
  479. TrainClassCate::where(['root_id'=>$this->root_id,'pid'=>$trainCate['id']])->update(['pid'=>$type_id]);
  480. //去重
  481. $groupId = TrainClassCate::where(['root_id'=>$this->root_id,'pid'=>$type_id,'show'=>1])->min('id');
  482. TrainClassCate::where([['root_id','=',$this->root_id],['pid','=',$type_id],['show','=',1],['id','<>',$groupId]])->delete();
  483. //删除分类
  484. $trainCate->delete();
  485. }else{
  486. $label_id = TrainClassCate::where(['root_id'=>$this->root_id,'pid'=>$trainCate['pid'],'show'=>1])->value('id');
  487. if(empty($label_id)) $label_id = TrainClassCate::insertGetId(['pid'=>$trainCate['pid'],'name'=>'其它','root_id'=>$this->root_id,'show'=>1]);
  488. //更新关联内容
  489. TrainClass::where(['root_id'=>$this->root_id,'label'=>$trainCate['name']])->update(['label'=>'其它']);
  490. //删除分类
  491. $trainCate->delete();
  492. }
  493. Db::commit();
  494. return json(['code' => 0, 'msg' => '删除成功']);
  495. } catch (\Exception $e) {
  496. Db::rollback();
  497. return json(['code' => 1, 'msg' => '删除失败']);
  498. }
  499. }
  500. /*
  501. * 课程培训添加页
  502. */
  503. public function class_add()
  504. {
  505. $w = [
  506. ['root_id', '=', $this->root_id],
  507. ['pid', '=', 0]
  508. ];
  509. $type = TrainClassCate::where($w)->field('id,name')->select();
  510. View::assign('type', $type);
  511. $lecturer = Lecturer::where([['root_id', '=', $this->root_id]])->column('id,name');
  512. View::assign('lecturer', $lecturer);
  513. return View::fetch();
  514. }
  515. /**
  516. * 课件活动添加保存
  517. */
  518. public function classAddSave()
  519. {
  520. $data = Request::only(['title','label'=>0, 'cate', 'des'=>'', 'type', 'category', 'cover', 'course_id', 'sumup_num', 'sumup_keyword', 'score_one', 'score_two', 'score_three', 'train_employee','credit'=>0,'lecturer_id'=>0]);
  521. $data['sumup_num'] = $data['sumup_num'] ? $data['sumup_num'] : 0;
  522. $data['cate'] = str_replace(' ','',$data['cate']);
  523. $data['label'] = str_replace(' ','',$data['label']);
  524. $newData = [
  525. 'root_id' => $this->root_id,
  526. 'title' => $data['title'],
  527. 'type' => $data['type'],
  528. 'category' => $data['category'],
  529. 'course_id' => $data['course_id'],
  530. 'des' => $data['des'],
  531. 'sumup_num' => $data['sumup_num'],
  532. 'sumup_keyword' => empty(array_filter(explode('|', trim($data['sumup_keyword'], '|')))) ? null : json_encode(array_values(array_filter(explode('|', trim($data['sumup_keyword'], '|'))))),
  533. 'sumup_score' => json_encode(['score_one' => $data['score_one'], 'score_two' => $data['score_two'], 'score_three' => $data['score_three']]),
  534. 'qrcode' => '',
  535. 'train_employee' => '',
  536. 'cate' => $data['cate'],
  537. 'label' => $data['label'],
  538. 'credit' => $data['credit'],
  539. 'lecturer_id' => $data['lecturer_id']
  540. ];
  541. if (!isset($data['cover']) && empty($data['cover'])) return json(['code' => 1, 'msg' => '请选择封面']);
  542. $newData['cover'] = $data['cover'];
  543. $id = TrainClass::insertGetid($newData);
  544. if ($id) {
  545. return json(['code' => 0, 'msg' => '添加成功']);
  546. } else {
  547. return json(['code' => 1, 'msg' => '添加失败']);
  548. }
  549. }
  550. /*
  551. * 课程培训添加页面所需课件展示
  552. */
  553. public function class_choice_course()
  554. {
  555. $param = Request::only(['page'=>1,'limit'=>10,'keyword'=>'']);
  556. $type = TrainType::where(['root_id' => $this->root_id, 'from_type' => 0])->field('id,type,from_type')->select()->toArray();
  557. if (!Request::isAjax()) {
  558. $checkValId = request()->param('course_id');
  559. View::assign('type', $type);
  560. View::assign('course_id', isset($checkValId) ? $checkValId : '');
  561. return View::fetch();
  562. }
  563. $type_id = request()->param('type_id');
  564. $course_id = request()->param('course_id');
  565. $condition[] = ['root_id', '=', $this->root_id];
  566. if (isset($type_id) && !empty($type_id)) $condition[] = ['type_id', '=', $type_id];
  567. if (!empty($course_id)) {
  568. $arrId = explode(',', $course_id);
  569. $condition[] = ['id', 'not in', $arrId];
  570. }
  571. if($param['keyword']) $condition[] = ['title','like','%'.$param['keyword'].'%'];
  572. $data = TrainCourse::where($condition)->order('id desc')->page($param['page'],$param['limit'])->select();
  573. $count = TrainCourse::where($condition)->count();
  574. return json(['code' => 0, 'data' => $data,'count'=>$count]);
  575. }
  576. /*
  577. * 培训课程上下架
  578. */
  579. public function classPublish($id)
  580. {
  581. $obj = TrainClass::where(['id' => $id, 'root_id' => $this->root_id])->find();
  582. if (empty($obj)) return json(['code' => 1, 'msg' => '操作失败,数据不存在']);
  583. if (empty($obj['course_id']) && $obj->publish == 0) return json(['code' => 1, 'msg' => '请先绑定课件']);
  584. $obj->publish = $obj->publish == 1 ? 0 : 1;
  585. $obj->save();
  586. return json(['code' => 0, 'msg' => '操作成功']);
  587. }
  588. /*
  589. * 培训课程删除
  590. */
  591. public function classDel($id)
  592. {
  593. $obj = TrainClass::where(['id' => $id, 'root_id' => $this->root_id])->find();
  594. if (empty($obj)) return json(['code' => 1, 'msg' => '删除失败,数据不存在']);
  595. $obj->del = 1;
  596. $obj->save();
  597. return json(['code' => 0, 'msg' => '删除成功']);
  598. }
  599. /*
  600. * 课程观看感悟
  601. */
  602. public function class_comment()
  603. {
  604. if (!Request::isAjax()) {
  605. $class_id = Request::param('class_id');
  606. View::assign('class_id', $class_id);
  607. return View::fetch();
  608. }
  609. $param = Request::param();
  610. $condition[] = [
  611. ['root_id', '=', $this->root_id],
  612. ['class_id', '=', $param['class_id']],
  613. ['course_id', '=', 0]
  614. ];
  615. if (isset($param['keyword']) && !empty($param['keyword'])) $condition[] = ['content', 'like', '%' . $param['keyword'] . '%'];
  616. $data = TrainSumup::with(['employee'])->where($condition)->page($param['page'], $param['limit'])->order('addtime desc')->select();
  617. $count = TrainSumup::where($condition)->count();
  618. $class = TrainClass::where('id', $param['class_id'])->field('sumup_keyword,sumup_score')->find();
  619. foreach ($data as &$item) {
  620. $item['score'] = TrainSumup::sumup_score_num($class['sumup_keyword'], $class['sumup_score'], $item['content']);
  621. }
  622. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  623. }
  624. /*
  625. * 课程培训修改页
  626. */
  627. public function class_edit()
  628. {
  629. //分类
  630. $w = [
  631. ['root_id', '=', $this->root_id],
  632. ['pid', '=', 0]
  633. ];
  634. $type = TrainClassCate::where($w)->field('id,name')->select();
  635. View::assign('type', $type);
  636. $lecturer = Lecturer::where([['root_id', '=', $this->root_id]])->column('id,name');
  637. View::assign('lecturer', $lecturer);
  638. $class_id = request()->param('class_id');
  639. $class = TrainClass::where(['id' => $class_id, 'root_id' => $this->root_id])->find();
  640. $class['sumup_keyword'] = empty($class['sumup_keyword']) ? '' : implode('|', json_decode($class['sumup_keyword'], true));
  641. $class['sumup_score'] = json_decode($class['sumup_score'], true);
  642. View::assign('class', $class);
  643. View::assign('cover', $class->getData('cover'));
  644. $course = TrainCourse::where('id', 'in', $class['course_id'])->select();
  645. View::assign('course', $course);
  646. //标签
  647. $w[] = ['name', '=', $class->cate];
  648. $pid = TrainClassCate::where($w)->value('id');
  649. $labels = TrainClassCate::where('pid', $pid)->select();
  650. View::assign('labels', $labels);
  651. return View::fetch();
  652. }
  653. /**
  654. * 课件活动编辑保存
  655. */
  656. public function classEditSave()
  657. {
  658. $data = Request::only(['title', 'cate', 'label'=>0, 'des'=>'', 'type', 'category', 'cover', 'course_id', 'id', 'sumup_num', 'sumup_keyword', 'score_one', 'score_two', 'score_three','credit'=>0,'lecturer_id'=>0]);
  659. $data['cate'] = str_replace(' ', '', $data['cate']);
  660. $data['label'] = str_replace(' ', '', $data['label']);
  661. $data['sumup_num'] = $data['sumup_num'] ? $data['sumup_num'] : 0;
  662. $newData = [
  663. 'title' => $data['title'],
  664. 'type' => $data['type'],
  665. 'category' => $data['category'],
  666. 'course_id' => $data['course_id'],
  667. 'des' => $data['des'],
  668. 'cover' => $data['cover'],
  669. 'sumup_num' => $data['sumup_num'],
  670. 'sumup_keyword' => empty(array_filter(explode('|', trim($data['sumup_keyword'], '|')))) ? null : json_encode(array_values(array_filter(explode('|', trim($data['sumup_keyword'], '|'))))),
  671. 'sumup_score' => json_encode(['score_one' => $data['score_one'], 'score_two' => $data['score_two'], 'score_three' => $data['score_three']]),
  672. 'cate' => $data['cate'],
  673. 'label' => $data['label'],
  674. 'credit' => $data['credit'],
  675. 'lecturer_id' => $data['lecturer_id']
  676. ];
  677. if (empty($newData['cover'])) return json(['code' => 1, 'msg' => '请选择封面']);
  678. $class = TrainClass::where(['root_id' => $this->root_id, 'id' => $data['id']])->find();
  679. $newData['publish'] = empty($data['course_id']) ? 0 : $class['publish'];
  680. $stringA = explode(',', $class['course_id']);
  681. $stringB = explode(',', $newData['course_id']);
  682. if (array_diff($stringA, $stringB) || array_diff($stringB, $stringA)) {
  683. //修改课程课件时同步更新员工完成的完成情况
  684. $log = TrainDoneLog::where(['root_id' => $this->root_id, 'class_id' => $data['id'], 'from' => 0])->select();
  685. foreach ($log as $item) {
  686. //员工之前完成的课件 , 修改后的课件
  687. $contrast = array_intersect(explode(',', $newData['course_id']), explode(',', $item['course_id']));
  688. $contrastImplode = implode(',', $contrast);
  689. $fload = $this->GDP(count($contrast), count(explode(',', $data['course_id'])));
  690. TrainDoneLog::where('id', $item['id'])->update(['course_id' => $contrastImplode, 'done_percent' => $fload]);
  691. }
  692. }
  693. if (TrainClass::where(['root_id' => $this->root_id, 'id' => $data['id']])->update($newData)) {
  694. return json(['code' => 0, 'msg' => '修改成功']);
  695. } else {
  696. return json(['code' => 1, 'msg' => '修改失败']);
  697. }
  698. }
  699. /**
  700. * 课件浏览记录
  701. */
  702. public function courese_view_list()
  703. {
  704. $param = Request::only(['course_id' => 0, 'org_id' => 0, 'page' => 1, 'limit' => 10]);
  705. $course_id = $param['course_id'];
  706. $org_id = $param['org_id'];
  707. // $root_id = request()->employee->root_id;
  708. if ($org_id) {
  709. $eids = Employee::where([['org_id', '=', $org_id]])->column('id');
  710. $w[] = ['employee_id', 'in', $eids];
  711. }
  712. // $w[] = ['root_id', '=', $root_id];
  713. $w[] = ['con_id', '=', $course_id];
  714. $w[] = ['type', '=', 'traincourse'];
  715. $list = TrainCourseView::with(['employee' => function ($query) {
  716. $query->visible(['name', 'id'])->bind(['name']);
  717. }])->where($w)->page($param['page'], $param['limit'])->select();
  718. foreach ($list as $k => $v) {
  719. $v->org_name = $v->employee->org->name;
  720. }
  721. $count = TrainCourseView::where($w)->count();
  722. return json(['code' => 0, 'data' => $list, 'count' => $count]);
  723. }
  724. /**
  725. * 课件浏览记录
  726. */
  727. public function courese_view($course_id = 0)
  728. {
  729. // $root_id = request()->employee->root_id;
  730. // $org = Org::where([['path', 'like', $root_id . '-%']])->field('name,id')->select()->toArray();
  731. $org = [];
  732. View::assign('org', $org);
  733. View::assign('course_id', $course_id);
  734. return View::fetch();
  735. }
  736. }