1
0

Train.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. <?php
  2. namespace app\api\controller;
  3. use app\model\TrainChapterCourse;
  4. use app\model\TrainClass;
  5. use app\model\TrainClassChapter;
  6. use app\model\TrainClassView;
  7. use app\model\TrainCourse;
  8. use app\model\TrainDoneLog;
  9. use app\model\TrainSumup;
  10. use app\model\TrainThumbLog;
  11. use app\model\Employee;
  12. use think\facade\Db;
  13. use app\model\Org;
  14. use app\model\Company;
  15. use app\model\User;
  16. use think\facade\Console;
  17. use app\model\TrainCourseView;
  18. use app\model\TrainClassCate;
  19. use app\model\TrainCouresStudytime;
  20. use app\model\CreditsSetting;
  21. use app\model\TrainCredits;
  22. use app\model\TrainStudylog;
  23. use app\model\CustomerVisitLog;
  24. use app\model\PreformanceTasks;
  25. use app\model\PreformanceTasksOrg;
  26. class Train extends Base
  27. {
  28. /**
  29. * 新课程推荐
  30. */
  31. public function new()
  32. {
  33. $condition = [
  34. 'root_id' => $this->request->token['root_org'],
  35. 'del' => 0,
  36. 'publish' => 1,
  37. 'from_type' => 0
  38. ];
  39. $cate = input('cate', '');
  40. if ($cate) $condition['cate'] = $cate;
  41. $eid = $this->request->token['employee_id'];
  42. $data = TrainClass::field('id,title,cover,view')->whereRaw("FIND_IN_SET(" . $eid . " , train_employee)")->where($condition)->order('view desc')->limit(4)->select()->toArray();
  43. return json(['code' => 0, 'data' => $data]);
  44. }
  45. /**
  46. * 培训课程列表from_type=3查询0,2
  47. * from_type:0自建,1集团指派,2店面共享
  48. */
  49. public function trainClassList($page, $from_type = 0)
  50. {
  51. $condition = [
  52. ['root_id', '=', $this->request->token['root_org']],
  53. ['del', '=', 0],
  54. ['publish', '=', 1]
  55. ];
  56. $condition[] = $from_type == 3 ? ['from_type', 'in', [0, 2]] : ['from_type', '=', $from_type];
  57. $cate = input('cate', '');
  58. if ($cate) $condition[] = ['cate', '=', $cate];
  59. $label = input('label', '');
  60. if ($label) $condition[] = ['label', '=', $label];
  61. $keyword = input('keyword', '');
  62. if ($keyword) $condition[] = ['title', 'like', '%' . trim($keyword) . '%'];
  63. $eid = $this->request->token['employee_id'];
  64. $sql = TrainClass::field('id,title,cover,course_id,category,view,train_employee,addtime,type');
  65. //集团指派课程全员展示
  66. if ($from_type != 1) {
  67. $sql->where(function ($query) use ($eid) {
  68. $query->whereRaw("FIND_IN_SET(" . $eid . " , train_employee)")
  69. ->whereOr('train_employee', '=', '');
  70. });
  71. }
  72. $data = $sql->where($condition)->page($page, 10)->order('addtime desc')->select()->toArray();
  73. $column_class_id = array_column($data, 'id');
  74. $doneLog = TrainDoneLog::where([['from', '=', 0], ['class_id', 'in', $column_class_id], ['root_id', '=', $this->request->token['root_org']], ['done_percent', '>', 0]])->group('class_id')->column('count(class_id)', 'class_id');
  75. //查询最近完成人的头像取6个
  76. $res = TrainDoneLog::with(['employee'])->where([['from', '=', 0], ['class_id', 'in', $column_class_id], ['root_id', '=', $this->request->token['root_org']], ['done_percent', '=', 100]])->order('addtime desc')->select()->toArray();
  77. $uid = array_column($res, 'uid');
  78. $user = User::where('id', 'in', $uid)->column('headimgurl', 'id');
  79. $headimgurl = [];
  80. foreach ($res as &$r) {
  81. $headimgurl[$r['class_id']][] = isset($user[$r['uid']]) ? $user[$r['uid']] : '';
  82. }
  83. // 查询课程多少人参与,课程章节数
  84. foreach ($data as &$item) {
  85. $item['train_employee_count'] = count(explode(',', $item['train_employee']));
  86. $item['course_num'] = empty($item['course_id']) ? 0 : count(explode(',', $item['course_id']));
  87. $item['done_log_num'] = isset($doneLog[$item['id']]) ? $doneLog[$item['id']] : 0;
  88. $item['done_log_num'] = $item['view'] >= $item['train_employee_count'] ? $item['train_employee_count'] : $item['view']; //学习人数太少先用浏览量展示
  89. $item['headimgurl'] = isset($headimgurl[$item['id']]) ? $headimgurl[$item['id']] : [];
  90. }
  91. return json(['code' => 0, 'data' => $data]);
  92. }
  93. /**
  94. * 课程内容详情
  95. */
  96. public function classDetail($class_id)
  97. {
  98. $token = $this->request->token;
  99. $from = input('from', 0) ? 1 : 0;
  100. $data = TrainClass::where([['id', '=', $class_id], ['root_id', '=', $token['root_org']], ['del', '=', 0], ['publish', '=', 1]])->field('id,title,cover,des,course_id,type,category,train_employee,addtime,from_type,from_root_id')->find();
  101. if (empty($data)) return json(['code' => 0, 'data' => []]);
  102. $data['course_num'] = empty($data['course_id']) ? 0 : count(explode(',', $data['course_id']));
  103. $data['done_log_num'] = TrainDoneLog::where([['from', '=', $from], ['class_id', '=', $data['id']], ['root_id', '=', $token['root_org']], ['done_percent', '>', 0]])->count();
  104. //课程是否完成
  105. $myDoneLog = TrainDoneLog::where([['from', '=', $from], ['employee_id', '=', $token['employee_id']], ['class_id', '=', $data['id']], ['root_id', '=', $token['root_org']]])->find();
  106. if ($myDoneLog) {
  107. $data['is_success_class'] = $myDoneLog->done_percent == 100 ? true : false; //是否全部完成
  108. $data['is_course_num'] = $myDoneLog->course_id ? count(explode(',', $myDoneLog->course_id)) : 0; //完成课件数量
  109. } else {
  110. $data['is_success_class'] = false; //是否全部完成
  111. $data['is_course_num'] = 0; //完成课件数量
  112. }
  113. // $data['is_success_class'] = empty($myDoneLog) ? false : true;
  114. $data['train_employee_num'] = $data->from_type = 1 ? '全员' : ($data->train_employee ? count(explode(',', $data->train_employee)) : 0); //学习总人数
  115. //全部完成人员信息
  116. $myDoneLog = TrainDoneLog::where([['from', '=', $from], ['class_id', '=', $data['id']], ['root_id', '=', $token['root_org']], ['done_percent', '=', 100]])->column('employee_id');
  117. $tw[] = ['id', 'in', $myDoneLog];
  118. $data['train_employee_info'] = Employee::with('userImg')->where($tw)->visible(['name', 'img'])->select()->toArray(); //
  119. $data['train_employee_info_count'] = count($data['train_employee_info']);
  120. //课程来源
  121. if ($data['from_type'] == 0) {
  122. $data['from'] = '店面发布';
  123. } elseif ($data['from_type'] == 1) {
  124. $data['from'] = '集团指派';
  125. } else {
  126. $company = Company::where('root_id', $data['from_root_id'])->value('company_name');
  127. $data['from'] = '集团从' . $company . '共享';
  128. }
  129. //浏览量+1
  130. // $rand = mt_rand(1,10);
  131. $view = input('view', '', 'trim');
  132. if ($view) {
  133. TrainClass::where('id', $class_id)->inc('view', 1)->update();
  134. }
  135. return json(['code' => 0, 'data' => $data]);
  136. }
  137. /**
  138. * 课程课件列表
  139. */
  140. public function trainCourseList($page, $class_id)
  141. {
  142. $from = input('from', 0) ? 1 : 0;
  143. $class = TrainClass::where(['id' => $class_id, 'root_id' => $this->request->token['root_org'], 'publish' => 1, 'del' => 0])->field('course_id,type')->find();
  144. if (empty($class)) return json(['code' => 0, 'data' => []]);
  145. $data = TrainCourse::field('id,title,type')->where([['id', 'in', $class['course_id']], ['root_id', '=', $this->request->token['root_org']]])->page($page, 20)->select()->toArray();
  146. $employee_id = $this->request->token['employee_id'];
  147. $doneLog = TrainDoneLog::where(['employee_id' => $employee_id, 'from' => $from, 'class_id' => $class_id, 'root_id' => $this->request->token['root_org']])->value('course_id');
  148. // 查询课件完成情况
  149. foreach ($data as &$item) {
  150. $doneLogArr = explode(',', $doneLog);
  151. $item['done_state'] = empty($doneLog) ? false : (in_array($item['id'], $doneLogArr) ? true : false);
  152. }
  153. return json(['code' => 0, 'data' => $data]);
  154. }
  155. /*
  156. * 课程观看感、课件读后感
  157. */
  158. public function watch_feel($page, $class_id, $course_id)
  159. {
  160. $course_id = empty($course_id) ? 0 : $course_id;
  161. $sumup = TrainSumup::with(['employee', 'user'])->where([['course_id', '=', $course_id], ['class_id', '=', $class_id], ['root_id', '=', $this->request->token['root_org']]])->page($page, 10)->order('addtime des')->select()->toArray();
  162. $column_sumup_id = array_column($sumup, 'id');
  163. $employee_id = $this->request->token['employee_id'];
  164. $log = TrainThumbLog::where([['sumup_id', 'in', $column_sumup_id], ['employee_id', '=', $employee_id], ['root_id', '=', $this->request->token['root_org']]])->column('id', 'sumup_id');
  165. $class = TrainClass::where('id', $class_id)->field('sumup_keyword,sumup_score')->find();
  166. foreach ($sumup as &$item) {
  167. $item['score'] = TrainSumup::sumup_score_num($class['sumup_keyword'], $class['sumup_score'], $item['content']);
  168. $item['thumblog'] = isset($log[$item['id']]) ? true : false;
  169. $item['addtime'] = $this->date_switch($item['addtime']);
  170. }
  171. $count = TrainSumup::where([['course_id', '=', $course_id], ['class_id', '=', $class_id], ['root_id', '=', $this->request->token['root_org']]])->count();
  172. return json(['code' => 0, 'data' => $sumup, 'count' => $count]);
  173. }
  174. /*
  175. * 根据时间计算距离现在多久
  176. */
  177. private function date_switch($time)
  178. {
  179. $now = time();
  180. $old = strtotime(date($time));
  181. $dur = $now - $old;
  182. if ($dur <= 0) {
  183. return $time;
  184. } elseif ($dur < 60) {
  185. return $dur . '秒前';
  186. } elseif ($dur < 3600) {
  187. return floor($dur / 60) . '分钟前';
  188. } elseif ($dur < 86400) {
  189. return floor($dur / 3600) . '小时前';
  190. } elseif ($dur < 2678400) {
  191. return floor($dur / 86400) . '天前';
  192. } elseif ($dur < 2678400 * 12) {
  193. return floor($dur / 2678400) . '月前';
  194. } else {
  195. return floor($dur / 2678400 / 12) . '年前';
  196. }
  197. }
  198. /**
  199. * 课件内容详情
  200. */
  201. public function courseDetail($course_id)
  202. {
  203. $token = $this->request->token;
  204. $class_id = input('class_id', 0); //所属课程id
  205. $data = TrainCourse::where(['id' => $course_id, 'root_id' => $token['root_org']])->find()->toArray();
  206. //评论内容
  207. $data['comment'] = 0;
  208. $w[] = ['class_id', '=', $class_id];
  209. $w[] = ['course_id', '=', $course_id];
  210. $w[] = ['root_id', '=', $token['root_org']];
  211. $data['comment_count'] = TrainSumup::with('employee')->where($w)->count();
  212. //学习总人数
  213. $tw[] = ['root_id', '=', $token['root_org']];
  214. $tw[] = ['id', '=', $class_id];
  215. //如果是集团指派的课程查询全部人员
  216. $class = TrainClass::where($tw)->whereRaw("FIND_IN_SET(" . $course_id . " , course_id)")->field('train_employee,from_type')->find();
  217. if (empty($class['train_employee'])) {
  218. $data['train_count'] = Employee::where([['root_id', '=', $token['root_org']], ['uid', '>', 0], ['state', '=', '在职']])->count();
  219. } else {
  220. $data['train_count'] = count(array_filter(array_unique(explode(',', $class['train_employee']))));
  221. }
  222. //学习完成人数
  223. $dw = [['from', '=', 0], ['root_id', '=', $token['root_org']], ['class_id', '=', $class_id]];
  224. $data['complete_count'] = TrainDoneLog::where($dw)->whereRaw("FIND_IN_SET(" . $course_id . " , course_id)")->group('employee_id')->count();
  225. //未学习人数
  226. $data['no_count'] = $data['train_count'] - $data['complete_count'] > 0 ? $data['train_count'] - $data['complete_count'] : 0;
  227. $data['page_num'] = 0;
  228. //pdf 页数
  229. if ($data['type'] == 'pdf') {
  230. $data['page_num'] = $data['file'] ? $this->getPageTotal($data['file']) : 0;
  231. }
  232. return json(['code' => 0, 'data' => $data]);
  233. }
  234. /**
  235. * 获取PDF的页数
  236. */
  237. public function getPageTotal($path)
  238. {
  239. // 打开文件
  240. if (!$fp = @fopen($path, "r")) {
  241. $error = "打开文件{$path}失败";
  242. return 0;
  243. } else {
  244. $max = 0;
  245. while (!feof($fp)) {
  246. $line = fgets($fp, 255);
  247. if (preg_match('/\/Count [0-9]+/', $line, $matches)) {
  248. preg_match('/[0-9]+/', $matches[0], $matches2);
  249. if ($max < $matches2[0]) $max = $matches2[0];
  250. }
  251. }
  252. fclose($fp);
  253. // 返回页数
  254. return $max;
  255. }
  256. }
  257. /**
  258. * 课件浏览详情+1
  259. */
  260. public function coureseView($course_id, $time = 0)
  261. {
  262. $token = $this->request->token;
  263. $save['con_id'] = $course_id;
  264. $save['time'] = $time;
  265. $save['root_id'] = $token['root_org'];
  266. $save['employee_id'] = $token['employee_id'];
  267. $save['uid'] = $token['uid'];
  268. $save['org_id'] = $token['org_id'];
  269. $save['type'] = 'traincourse';
  270. TrainCourseView::insertGetId($save);
  271. TrainCourse::where(['id' => $course_id, 'root_id' => $token['root_org']])->inc('view')->update();
  272. return json(['code' => 0, 'data' => '成功浏览']);
  273. }
  274. /**
  275. * 课程浏览 +1
  276. */
  277. public function classView()
  278. {
  279. $class_id = input('class_id', '', 'intval');
  280. $course_id = input('course_id', '', 'intval');
  281. $time = input('time', 0, 'intval');
  282. $token = $this->request->token;
  283. $save['course_id'] = $course_id;
  284. $save['class_id'] = $class_id;
  285. $save['time'] = $time;
  286. $save['root_id'] = $token['root_org'];
  287. $save['employee_id'] = $token['employee_id'];
  288. $save['uid'] = $token['uid'];
  289. $save['org_id'] = $token['org_id'];
  290. $save['type'] = 'traincourse';
  291. TrainClassView::insertGetId($save);
  292. TrainCourse::where(['id' => $course_id, 'root_id' => $token['root_org']])->inc('view')->update();
  293. return json(['code' => 0, 'data' => '成功浏览']);
  294. }
  295. //全部完成课程人员列表
  296. public function all_complete()
  297. {
  298. $token = $this->request->token;
  299. $class_id = input('class_id', 0); //所属课程id
  300. $keyword = input('keyword', 0);
  301. $org_id = input('org_id', 0);
  302. $page = input('page', 1);
  303. $limit = input('limit', 10);
  304. $start = input('start_date', '');
  305. $end = input('end_date', '');
  306. $w = [];
  307. if ($keyword) {
  308. $w[] = ['employee.name', 'like', '%' . $keyword . '%'];
  309. }
  310. if ($org_id) {
  311. $org_id = explode(',', $org_id);
  312. $w[] = ['employee.org_id', 'in', $org_id];
  313. }
  314. if ($start) {
  315. $w[] = ['train_done_log.addtime', '>=', $start . ' 00:00:00'];
  316. }
  317. if ($end) {
  318. $w[] = ['train_done_log.addtime', '<=', $end . ' 23:59:59'];
  319. }
  320. $w[] = ['class_id', '=', $class_id];
  321. $w[] = ['train_done_log.root_id', '=', $token['root_org']];
  322. $w[] = ['done_percent', '=', 100];
  323. $w[] = ['from', '=', 0];
  324. $myDoneLog = TrainDoneLog::withJoin('employee')->where($w)->visible(['employee_id', 'addtime'])->order('id desc')->page($page, $limit)->select()->toArray();
  325. $eids = $myDoneLog ? array_column($myDoneLog, 'employee_id') : [];
  326. $ew[] = ['id', 'in', $eids];
  327. $employee = Employee::with(['userImg', 'orgName'])->where($ew)->visible(['name', 'img', 'id', 'org_name', 'org_id'])->select()->toArray();
  328. foreach ($myDoneLog as $k => $v) {
  329. $myDoneLog[$k]['addtime'] = $v['addtime'] = $this->date_switch($v['addtime']);
  330. foreach ($employee as $k2 => $v2) {
  331. if ($v['employee_id'] == $v2['id']) {
  332. $myDoneLog[$k] = array_merge($v, $v2);
  333. unset($myDoneLog[$k]['employee']);
  334. break;
  335. }
  336. }
  337. if (isset($myDoneLog[$k]['employee'])) {
  338. $myDoneLog[$k]['name'] = $myDoneLog[$k]['img'] = $myDoneLog[$k]['org_name'] = '';
  339. $myDoneLog[$k]['id'] = $myDoneLog[$k]['org_id'] = 0;
  340. }
  341. }
  342. return json(['code' => 0, 'data' => $myDoneLog]);
  343. }
  344. //部门列表
  345. public function all_org()
  346. {
  347. $token = $this->request->token;
  348. $res = Org::where([['path', 'like', $token['root_org'] . '-%'], ['status', '=', 1]])->field('id,name,pid')->select()->toArray();
  349. $res = $this->tree($res, 0, []);
  350. return json(['code' => 0, 'data' => $res]);
  351. }
  352. //部门人员树
  353. public function tree($data, $pid = 0, $persons)
  354. {
  355. $new_arr = [];
  356. foreach ($data as $k => $v) {
  357. if ($v['pid'] == $pid) {
  358. $persions = isset($persons[$v['id']]) ? $persons[$v['id']] : [];
  359. $children = $this->tree($data, $v['id'], $persons);
  360. $v['children'] = array_merge_recursive($children, $persions);
  361. if (empty($v['children'])) $v['disabled'] = true;
  362. $new_arr[] = $v;
  363. }
  364. }
  365. return $new_arr;
  366. }
  367. /*
  368. * 员工完成课件
  369. */
  370. public function doneLogging()
  371. {
  372. $token = $this->request->token;
  373. $param = request()->param(['course_id', 'class_id', 'study_time']);
  374. $employee_id = $this->request->token['employee_id'];
  375. $root_id = $this->request->token['root_org'];
  376. $from = input('from', 0);
  377. //查询课件是否存在
  378. $class = TrainClass::where(['root_id' => $root_id, 'del' => 0, 'publish' => 1, 'id' => $param['class_id']])->find();
  379. $c = explode(',', $class['course_id']);
  380. if (empty($class) || !in_array($param['course_id'], $c)) {
  381. return json(['code' => 1, 'msg' => '课件内容不存在']);
  382. }
  383. //判断是否已完成该课件
  384. $doneLog = TrainDoneLog::where(['employee_id' => $employee_id, 'from' => $from, 'root_id' => $root_id, 'class_id' => $param['class_id']])->find();
  385. $log_course_id = !empty($doneLog['course_id']) ? explode(',', $doneLog['course_id']) : [];
  386. if (!empty($doneLog) && !empty($doneLog['done_percent']) && in_array($param['course_id'], $log_course_id)) {
  387. return json(['code' => 1, 'msg' => '该课件已完成,无需重复操作']);
  388. }
  389. //判断是否设置课件评论字数
  390. $comment_word_num = TrainCourse::where(['root_id' => $root_id, 'id' => $param['course_id']])->value('comment_word_num');
  391. if ($comment_word_num > 0) {
  392. $where[] = ['employee_id', '=', $employee_id];
  393. $where[] = ['course_id', '=', $param['course_id']];
  394. $where[] = ['class_id', '=', $param['class_id']];
  395. $where[] = ['', 'EXP', Db::raw('char_length(content) >= ' . $comment_word_num . '')];
  396. $sumupcount = TrainSumup::where($where)->count();
  397. if ($sumupcount == 0) return json(['code' => 1, 'msg' => '课件评论字数不达标']);
  398. }
  399. $course_id = explode(',', $class['course_id']);
  400. if (!empty($doneLog)) {
  401. $have = explode(',', $doneLog['course_id']);
  402. $checkCourse = [$param['course_id']];
  403. $newCourseArr = array_filter(array_merge($have, $checkCourse));
  404. $GDP = floor((count($newCourseArr) / count($course_id)) * 100);
  405. $doneLog->done_percent = $GDP;
  406. $doneLog->course_id = implode(',', $newCourseArr);
  407. if ($doneLog->save()) {
  408. if ($GDP == 100) { //累计勋章
  409. Console::call('medal', ['class', (string)$employee_id, (string)$root_id]);
  410. //增加课程完成赠送学分
  411. $this->add_studylog($employee_id, $class, $root_id);
  412. }
  413. //完成单个课件增加学习时长
  414. if (!empty($param['study_time'])) {
  415. $this->add_studytime($employee_id, $param['class_id'], $param['course_id'], $param['study_time'], $root_id);
  416. }
  417. return json(['code' => 0, 'msg' => '完成本节学习']);
  418. } else {
  419. return json(['code' => 1, 'msg' => '未能完成本节学习']);
  420. }
  421. } else {
  422. $GDP = floor((1 / count($course_id)) * 100);
  423. if (TrainDoneLog::insert([
  424. 'employee_id' => $employee_id,
  425. 'root_id' => $root_id,
  426. 'org_id' => $token['org_id'],
  427. 'class_id' => $param['class_id'],
  428. 'done_percent' => $GDP,
  429. 'course_id' => $param['course_id'],
  430. 'from' => $from
  431. ])) {
  432. if ($GDP == 100) { //累计勋章
  433. Console::call('medal', ['class', (string)$employee_id, (string)$root_id]);
  434. //增加课程完成赠送学分
  435. $this->add_studylog($employee_id, $class, $root_id);
  436. }
  437. //完成单个课件增加学习时长
  438. if (!empty($param['study_time'])) {
  439. $this->add_studytime($employee_id, $param['class_id'], $param['course_id'], $param['study_time'], $root_id);
  440. }
  441. return json(['code' => 0, 'msg' => '完成本节学习']);
  442. } else {
  443. return json(['code' => 1, 'msg' => '未能完成本节学习']);
  444. }
  445. }
  446. }
  447. //增加课程的学习完成记录
  448. public function add_studylog($employee_id, $class, $root_id)
  449. {
  450. if (empty($class['credit'])) return; //如果没有设置学分直接返回
  451. $maxcredit = $this->sumday_credit($root_id, $employee_id);
  452. $you = TrainCredits::where([['employee_id', '=', $employee_id], ['root_id', '=', $root_id]])->order('id desc')->find();
  453. if (empty($maxcredit) || $maxcredit['status'] == 1 || ($maxcredit['status'] == 0 && $maxcredit['yes_course'] > $class['credit'])) {
  454. $add = ['employee_id' => $employee_id, 'root_id' => $root_id, 'type' => 2, 'credits' => $class['credit'], 'now_credits' => $class['credit']];
  455. if (!empty($you)) {
  456. $add['now_credits'] = $you['now_credits'] + $class['credit'];
  457. }
  458. }
  459. if (!empty($maxcredit) && $maxcredit['status'] != 1 && $maxcredit['yes_course'] != 0 && $maxcredit['yes_course'] < $class['credit']) {
  460. $add = ['employee_id' => $employee_id, 'root_id' => $root_id, 'type' => 2, 'credits' => $maxcredit['yes_course'], 'now_credits' => $maxcredit['yes_course'] + (!empty($you['now_credits']) ? $you['now_credits'] : 0)];
  461. }
  462. if (!empty($add)) {
  463. $this->add_credit($add);
  464. }
  465. }
  466. //增加课程的学习时间
  467. public function add_studytime($employee_id, $class_id, $course_id, $study_time, $root_id)
  468. {
  469. $where[] = ['code', '=', 'studytime_credit'];
  470. $where[] = ['root_id', '=', $root_id];
  471. $time_study = CreditsSetting::where($where)->field('status,value')->find();
  472. if (empty($time_study)) return; //如果没有设置学习时长直接返回;
  473. if ($time_study['status'] == 0) {
  474. $add = ['empid' => $employee_id, 'classid' => $class_id, 'course_id' => $course_id, 'study_time' => $study_time, 'all_time' => $study_time, 'type' => 1];
  475. $you = TrainCouresStudytime::where([['empid', '=', $employee_id]])->order('id desc')->find();
  476. if (!empty($you)) {
  477. $add['all_time'] = $you['all_time'] + $study_time;
  478. }
  479. TrainCouresStudytime::insert($add);
  480. $this->call_studytime($employee_id); //增加完学习时长直接开始计算是否送学分
  481. }
  482. }
  483. //统计当天获得的总学分
  484. public function sumday_credit($root_id, $employee_id)
  485. {
  486. $where3[] = ['code', '=', 'studyday_maxcredit'];
  487. $where3[] = ['root_id', '=', $root_id];
  488. $maxcredit = CreditsSetting::where($where3)->field('status,value')->find(); //->findOrEmpty();
  489. if (!empty($maxcredit) && $maxcredit['status'] == 0) {
  490. $day_course = TrainCredits::where([['employee_id', '=', $employee_id], ['root_id', '=', $root_id], ['addtime', '>=', date('Y-m-d') . ' 00:00:00'], ['addtime', '<=', date('Y-m-d') . ' 23:59:59']])->sum('credits');
  491. $yes_course = $maxcredit['value'] - $day_course;
  492. $maxcredit['yes_course'] = $yes_course;
  493. }
  494. return $maxcredit;
  495. }
  496. //计算学习时长送学分
  497. public function call_studytime($employee_id)
  498. {
  499. $token = $this->request->token;
  500. $maxcredit = $this->sumday_credit($token['root_org'], $token['employee_id']);
  501. $all_time = TrainCouresStudytime::where('empid', $employee_id)->order('id desc')->value('all_time');
  502. $where[] = ['code', '=', 'studytime_credit'];
  503. $where[] = ['root_id', '=', $token['root_org']];
  504. $time_study = CreditsSetting::where($where)->field('status,value')->find();
  505. if (empty($time_study)) return; //如果没有设置学习时长直接返回
  506. $time_study['value'] = !empty($time_study['value']) ? json_decode($time_study['value'], true) : ['numtime' => 0, 'time_credit' => 0];
  507. if ($time_study['status'] == 0 && $time_study['value']['numtime'] > 0 && $all_time >= $time_study['value']['numtime'] * 60) {
  508. $b = floor($all_time / ($time_study['value']['numtime'] * 60));
  509. $credits = $b * $time_study['value']['time_credit'];
  510. $reduce_time = $b * ($time_study['value']['numtime'] * 60);
  511. $you = TrainCredits::where([['employee_id', '=', $token['employee_id']], ['root_id', '=', $token['root_org']]])->order('id desc')->find();
  512. //正常情况所得学分不大于当天可获得最高学分
  513. if (empty($maxcredit) || $maxcredit['status'] == 1 || ($maxcredit['status'] == 0 && $maxcredit['yes_course'] > $credits)) {
  514. $add = ['employee_id' => $token['employee_id'], 'root_id' => $token['root_org'], 'type' => 1, 'credits' => $credits, 'now_credits' => $credits];
  515. if (!empty($you)) {
  516. $add['now_credits'] = $you['now_credits'] + $credits;
  517. }
  518. $this->add_credit($add);
  519. $newadd = ['empid' => $token['employee_id'], 'study_time' => $reduce_time, 'all_time' => $all_time - $reduce_time, 'type' => 2];
  520. $newadd['all_time'] = $newadd['all_time'] > 0 ? $newadd['all_time'] : 0;
  521. TrainCouresStudytime::insert($newadd);
  522. }
  523. //所得学分大于当天剩余可得学分时取差值补满当天最高学分
  524. if (!empty($maxcredit) && $maxcredit['status'] == 0 && $maxcredit['yes_course'] != 0 && $maxcredit['yes_course'] < $credits) {
  525. $add = ['employee_id' => $token['employee_id'], 'root_id' => $token['root_org'], 'type' => 1, 'credits' => $maxcredit['yes_course'], 'now_credits' => $maxcredit['yes_course'] + (!empty($you['now_credits']) ? $you['now_credits'] : 0)];
  526. $this->add_credit($add);
  527. $newadd = ['empid' => $token['employee_id'], 'study_time' => $reduce_time, 'all_time' => 0, 'type' => 2];
  528. TrainCouresStudytime::insert($newadd);
  529. }
  530. // if($maxcredit['status']!=1 && $maxcredit['yes_course'] < $credits){
  531. // $newadd=['empid'=>$token['employee_id'],'study_time'=>$reduce_time,'all_time'=>0,'type'=>2];
  532. // TrainCouresStudytime::insert($newadd);
  533. // }
  534. }
  535. }
  536. //计算提交感悟送学分
  537. public function feeling_credits($root_id, $employee_id)
  538. {
  539. $maxcredit = $this->sumday_credit($root_id, $employee_id);
  540. $where[] = ['code', '=', 'studyfeeling_credit'];
  541. $where[] = ['root_id', '=', $root_id];
  542. $studyfeeling = CreditsSetting::where($where)->field('status,value')->find();
  543. if (empty($studyfeeling)) return; //如果没有设置感悟送学分直接返回
  544. $you = TrainCredits::where([['employee_id', '=', $employee_id], ['root_id', '=', $root_id]])->order('id desc')->find();
  545. if ($studyfeeling['status'] == 0 && $studyfeeling['value'] > 0) {
  546. if (empty($maxcredit) || $maxcredit['status'] == 1 || ($maxcredit['status'] != 1 && $maxcredit['yes_course'] > $studyfeeling['value'])) {
  547. $add = ['employee_id' => $employee_id, 'root_id' => $root_id, 'type' => 3, 'credits' => $studyfeeling['value'], 'now_credits' => $studyfeeling['value']];
  548. if (!empty($you)) {
  549. $add['now_credits'] = $you['now_credits'] + $studyfeeling['value'];
  550. }
  551. $this->add_credit($add);
  552. }
  553. if (!empty($maxcredit) && $maxcredit['status'] == 0 && $maxcredit['yes_course'] != 0 && $maxcredit['yes_course'] < $studyfeeling['value']) {
  554. $add = ['employee_id' => $employee_id, 'root_id' => $root_id, 'type' => 3, 'credits' => $maxcredit['yes_course'], 'now_credits' => $maxcredit['yes_course'] + (!empty($you['now_credits']) ? $you['now_credits'] : 0)];
  555. $this->add_credit($add);
  556. }
  557. }
  558. }
  559. //赠送学分统一方法方便计划任务处理
  560. public function add_credit($add)
  561. {
  562. $id = TrainCredits::insertGetId($add);
  563. $this->preformance_tasks($add['credits'], $id);
  564. }
  565. /**
  566. * 计算业绩任务
  567. */
  568. public function preformance_tasks($credit = 0, $vislog_id)
  569. {
  570. $token = $this->request->token;
  571. //防止后台切换部门
  572. $token['org_id'] = Employee::where('id', $token['employee_id'])->value('org_id');
  573. $time = date('Y-m-d H:i:s');
  574. //查询进行中的指派到所属部门的所有进度
  575. // $w[] = ['org_id','=',$token['org_id']];
  576. $w[] = ['root_id', '=', $token['root_org']];
  577. $w[] = ['start_date', '<=', $time];
  578. $w[] = ['end_date', '>=', $time];
  579. $w[] = ['is_credit', '=', 1];
  580. $preformance_tasks = PreformanceTasks::where($w)->column('id');
  581. $w1[] = ['root_id', '=', $token['root_org']];
  582. $w1[] = ['org_id', '=', $token['org_id']];
  583. $w1[] = ['performance_tasks_id', 'in', $preformance_tasks];
  584. $w1[] = ['is_credit', '=', 1];
  585. //指派到自己部门
  586. $pid = PreformanceTasksOrg::where($w1)->group('performance_tasks_id')->column('*');
  587. $w4[] = ['id', 'in', array_column($pid, 'performance_tasks_id')];
  588. $model = PreformanceTasks::where($w4)->column('*');
  589. foreach ($model as $k => $v) {
  590. $u = [];
  591. $u['ok_credit'] = $v['ok_credit'] + $credit;
  592. $u['customer_visit_log_id'] = $v['customer_visit_log_id'] ? $v['customer_visit_log_id'] . ',' . $vislog_id : $vislog_id;
  593. PreformanceTasks::where('id', $v['id'])->update($u);
  594. unset($u);
  595. }
  596. PreformanceTasksOrg::where($w1)->inc('ok_credit', (int)$credit)->update();
  597. return 1;
  598. }
  599. /*
  600. * 课件完成操作
  601. */
  602. private function course_finish($trainClassCourseId, $doneLog, $paramCourseId, $paramClassId, $from = 0, $study_time = 0)
  603. {
  604. //课程绑定的课件
  605. $course_id = explode(',', $trainClassCourseId);
  606. $class = TrainClass::find($paramClassId);
  607. if (!empty($doneLog)) {
  608. $have = explode(',', $doneLog['course_id']);
  609. $checkCourse = [$paramCourseId];
  610. $newCourseArr = array_merge($have, $checkCourse);
  611. $GDP = floor((count($newCourseArr) / count($course_id)) * 100);
  612. $update = [
  613. 'done_percent' => $GDP,
  614. 'course_id' => implode(',', $newCourseArr)
  615. ];
  616. $res = TrainDoneLog::where([
  617. 'from' => $from, 'employee_id' => $this->request->token['employee_id'],
  618. 'root_id' => $this->request->token['root_org'],
  619. 'class_id' => $paramClassId
  620. ])->update($update);
  621. if ($res) {
  622. if ($GDP == 100) { //累计勋章
  623. $employee_id = $this->request->token['employee_id'];
  624. $root_id = $this->request->token['root_org'];
  625. Console::call('medal', ['class', (string)$employee_id, (string)$root_id]);
  626. //完成课程增加学分
  627. $this->add_studylog($employee_id, $class, $root_id);
  628. }
  629. //完成单个课件增加学习时长
  630. $this->add_studytime($this->request->token['employee_id'], $paramClassId, $paramCourseId, $study_time, $this->request->token['root_org']);
  631. return true;
  632. } else {
  633. return false;
  634. }
  635. } else {
  636. $GDP = floor((1 / count($course_id)) * 100);
  637. //第一次完成课件直接添加
  638. if (TrainDoneLog::insert([
  639. 'employee_id' => $this->request->token['employee_id'],
  640. 'root_id' => $this->request->token['root_org'],
  641. 'org_id' => $this->request->token['org_id'],
  642. 'class_id' => $paramClassId,
  643. 'done_percent' => $GDP,
  644. 'course_id' => $paramCourseId,
  645. 'from' => $from
  646. ])) {
  647. if ($GDP == 100) { //累计勋章
  648. $employee_id = $this->request->token['employee_id'];
  649. $root_id = $this->request->token['root_org'];
  650. Console::call('medal', ['class', (string)$employee_id, (string)$root_id]);
  651. //完成课程增加学分
  652. $this->add_studylog($employee_id, $class, $root_id);
  653. }
  654. //完成单个课件增加学习时长
  655. $this->add_studytime($this->request->token['employee_id'], $paramClassId, $paramCourseId, $study_time, $this->request->token['root_org']);
  656. return true;
  657. } else {
  658. return false;
  659. }
  660. }
  661. }
  662. /*
  663. * 评论
  664. */
  665. public function commentAdd()
  666. {
  667. $param = request()->param(['class_id', 'course_id', 'content', 'read_status', 'from' => 0, 'study_time' => 0]);
  668. $data = [
  669. 'user_id' => $this->request->token['uid'],
  670. 'root_id' => $this->request->token['root_org'],
  671. 'employee_id' => $this->request->token['employee_id'],
  672. 'org_id' => $this->request->token['org_id'],
  673. 'class_id' => $param['class_id'],
  674. 'course_id' => empty($param['course_id']) ? 0 : $param['course_id'],
  675. 'content' => $param['content']
  676. ];
  677. $TrainClass = TrainClass::where('id', $param['class_id'])->field('sumup_num,course_id')->find();
  678. if (empty($param['course_id'])) {
  679. //课程评论验证字数是否达标
  680. if (mb_strlen($param['content']) < $TrainClass['sumup_num']) return json(['code' => 1, 'msg' => '课程感悟不低于' . $TrainClass['sumup_num'] . '字数']);
  681. }
  682. if (!empty($param['course_id'])) {
  683. //查询课件评论字数限制
  684. $comment_word_num = TrainCourse::where(['root_id' => $this->request->token['root_org'], 'id' => $param['course_id']])->value('comment_word_num');
  685. if ($comment_word_num && mb_strlen($data['content']) < $comment_word_num) return json(['code' => 1, 'msg' => '课件评论不低于' . $comment_word_num . '字数']);
  686. //课件评论验证完成情况
  687. if (isset($param['read_status']) && $param['read_status'] == true) {
  688. $doneLog = TrainDoneLog::where(['from' => $param['from'], 'employee_id' => $this->request->token['employee_id'], 'root_id' => $this->request->token['root_org'], 'class_id' => $param['class_id']])->find();
  689. $log_course_id = !$doneLog ? [] : explode(',', $doneLog['course_id']);
  690. if (!in_array($param['course_id'], $log_course_id)) {
  691. //完成课件操作
  692. $this->course_finish($TrainClass['course_id'], $doneLog, $param['course_id'], $param['class_id'], $param['from'], $param['study_time']);
  693. }
  694. }
  695. }
  696. if (TrainSumup::insert($data)) {
  697. //增加提交感悟送学分
  698. if ($param['course_id'] == 0) {
  699. $this->feeling_credits($this->request->token['root_org'], $this->request->token['employee_id']);
  700. }
  701. return json(['code' => 0, 'msg' => '提交成功']);
  702. } else {
  703. return json(['code' => 1, 'msg' => '提交失败']);
  704. }
  705. }
  706. /**
  707. * 点赞
  708. */
  709. public function thumbing($sumup_id)
  710. {
  711. if (isset($sumup_id)) {
  712. $root_id = $this->request->token['root_org'];
  713. $employee_id = $this->request->token['employee_id'];
  714. $sumup = TrainSumup::where(['root_id' => $root_id, 'id' => $sumup_id])->find();
  715. if (empty($sumup)) return json(['code' => 1, 'msg' => '内容不存在']);
  716. $log = TrainThumbLog::where([
  717. ['sumup_id', '=', $sumup_id],
  718. ['employee_id', '=', $employee_id],
  719. ['root_id', '=', $root_id]
  720. ])->find();
  721. if ($log) {
  722. TrainThumbLog::where(['sumup_id' => $sumup_id, 'employee_id' => $employee_id, 'root_id' => $root_id])->delete();
  723. TrainSumup::where(['root_id' => $root_id, 'id' => $sumup_id])->dec('thumb')->update();
  724. return json(['code' => 0, 'msg' => '取消点赞']);
  725. } else {
  726. TrainThumbLog::insert(['sumup_id' => $sumup_id, 'employee_id' => $employee_id, 'root_id' => $root_id]);
  727. TrainSumup::where(['root_id' => $root_id, 'id' => $sumup_id])->inc('thumb')->update();
  728. return json(['code' => 0, 'msg' => '成功点赞']);
  729. }
  730. } else {
  731. return json(['code' => 1, 'msg' => '点赞失败']);
  732. }
  733. }
  734. /**
  735. * 获取课程培训分类
  736. */
  737. public function get_train_class_cate()
  738. {
  739. $token = $this->request->token;
  740. $w[] = ['root_id', '=', $token['root_org']];
  741. $w[] = ['pid', '=', 0];
  742. $list = TrainClassCate::where($w)->field('id,name')->order(['order' => 'asc', 'id' => 'desc'])->select();
  743. return json(['code' => 0, 'data' => $list]);
  744. }
  745. /**
  746. * 获取课程培训标签
  747. */
  748. public function get_train_class_label()
  749. {
  750. $token = $this->request->token;
  751. $pid = input('pid', 0);
  752. $w[] = ['root_id', '=', $token['root_org']];
  753. $w[] = ['pid', '=', $pid];
  754. $list = TrainClassCate::where($w)->field('id,name')->order('id asc')->select();
  755. return json(['code' => 0, 'data' => $list]);
  756. }
  757. /*
  758. * 贡献值积分详情
  759. */
  760. public function credits_info()
  761. {
  762. $param = $this->request->only(['page', 'limit']);
  763. $token = $this->request->token;
  764. $where[] = ['root_id', '=', $token['root_org']];
  765. $where[] = ['employee_id', '=', $token['employee_id']];
  766. //当前学分
  767. $val = TrainCredits::where($where)
  768. ->order('id desc')->value('now_credits');
  769. $res['my_value'] = $val ? $val : 0;
  770. //贡献值排名
  771. $ranking = TrainCredits::where([['root_id', '=', $token['root_org']]])
  772. ->group('employee_id')->order('sum desc,id desc')->column('sum(credits) sum', 'employee_id');
  773. if ($ranking) {
  774. $found_arr = array_keys($ranking);
  775. $key = array_search($token['employee_id'], $found_arr);
  776. $res['my_ranking'] = $key === false ? 0 : $key + 1;
  777. } else {
  778. $res['my_ranking'] = 0;
  779. }
  780. //详情0积分,1贡献值
  781. $credits = TrainCredits::where($where)->order('id desc')->page($param['page'], $param['limit'])->select()->toArray();
  782. foreach ($credits as $k => $v) {
  783. $val = [];
  784. if ($v['type'] == 1) {
  785. $credits[$k]['remark'] = '您学习到时规定时长,学分+' . $v['credits'] . '学分,当前学分总数:' . $v['now_credits'];
  786. } elseif ($v['type'] == 2) {
  787. $credits[$k]['remark'] = '课程学习完成+' . $v['credits'] . '学分,当前学分总数:' . $v['now_credits'];
  788. } elseif ($v['type'] == 3) {
  789. $credits[$k]['remark'] = '你评论一个感悟+' . $v['credits'] . '学分,当前学分总数:' . $v['now_credits'];
  790. }
  791. }
  792. $res['info'] = $credits;
  793. $res['info_count'] = TrainCredits::where($where)->count();
  794. return json(['code' => 0, 'msg' => '获取成功', 'data' => $res]);
  795. }
  796. }