Train.php 98 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286
  1. <?php
  2. namespace app\sys\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. class Train
  25. {
  26. /**
  27. * 课件列表页面展示
  28. */
  29. public function course_index()
  30. {
  31. $condition = [
  32. 'root_id' => request()->employee->root_id,
  33. 'from_type' => 0
  34. ];
  35. $type = TrainType::where($condition)->select()->toArray();
  36. View::assign('type', $type);
  37. return View::fetch();
  38. }
  39. /**
  40. * 课件列表
  41. */
  42. public function trainCourseList()
  43. {
  44. $param = request()->param();
  45. $condition[] = ['root_id', '=', request()->employee->root_id];
  46. if (isset($param['type_id']) && !empty($param['type_id'])) $condition[] = ['type_id', '=', $param['type_id']];
  47. if (isset($param['keyword']) && !empty($param['keyword'])) $condition[] = ['title', 'like', '%' . $param['keyword'] . '%'];
  48. if (isset($param['type']) && !empty($param['type'])) $condition[] = ['type', '=', $param['type']];
  49. if (isset($param['date']) && !empty($param['date'])) $condition[] = ['date', 'like', '%' . $param['date'] . '%'];
  50. $data = TrainCourse::withCount(['trainCourseView'=>function($query){
  51. $query->where([['type', '=', 'traincourse']]);
  52. }])->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 course_add()
  60. {
  61. $condition = [
  62. 'root_id' => request()->employee->root_id,
  63. 'from_type' => 0
  64. ];
  65. $type = TrainType::where($condition)->select()->toArray();
  66. View::assign('type', $type);
  67. return View::fetch();
  68. }
  69. /*
  70. * 课件保存
  71. */
  72. public function courseAddSave()
  73. {
  74. $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']);
  75. if ($data['time_check'] == 0 && $data['word_check'] == 0) return json(['code' => 1, 'msg' => '完成条件最少选择一项']);
  76. $ask = input('content');
  77. $ask = str_replace('&nbsp;', '', $ask);
  78. if (trim($ask) == '' && $data['type'] != 'pdf') {
  79. return json(['code' => 1, 'msg' => '课件内容不能为空']);
  80. }
  81. $newData = [
  82. 'root_id' => request()->employee->root_id,
  83. 'title' => $data['title'],
  84. 'type_id' => $data['type_id'],
  85. 'content' => $data['content'],
  86. 'type' => $data['type'],
  87. 'study_time' => $data['time_check'] == 0 ? 0 : $data['study_time'],
  88. 'comment_word_num' => $data['word_check'] == 0 ? 0 : $data['comment_word_num']
  89. ];
  90. if ($data['type'] == 'video') {
  91. if (empty($data['file_video'])) return json(['code' => 1, 'msg' => '请选择视频']);
  92. $arr = explode(',', $data['file_video']);
  93. $newData['file'] = end($arr);
  94. $newData['video_img'] = !empty($data['video_img']) ? $data['video_img'] : null;
  95. } elseif ($data['type'] == 'image') {
  96. if (empty($data['file_image'])) return json(['code' => 1, 'msg' => '请选择图片']);
  97. $newData['file'] = $data['file_image'];
  98. } elseif ($data['type'] == 'pdf') {
  99. if (empty($data['file_pdf'])) return json(['code' => 1, 'msg' => '请选择pdf课程文件']);
  100. $arr = explode(',', $data['file_pdf']);
  101. $newData['file'] = end($arr);
  102. } else {
  103. if (empty($data['file_audio'])) return json(['code' => 1, 'msg' => '请选择音频']);
  104. $arr = explode(',', $data['file_audio']);
  105. $newData['file'] = end($arr);
  106. }
  107. if (TrainCourse::insert($newData)) {
  108. return json(['code' => 0, 'msg' => '添加成功']);
  109. } else {
  110. return json(['code' => 1, 'msg' => '添加失败']);
  111. }
  112. }
  113. /**
  114. * 课件富文本文件上传
  115. */
  116. public function fileupload()
  117. {
  118. $ali_oss_bindurl = config('app.ali_oss_bindurl');
  119. $url = 'https://' . $ali_oss_bindurl . '/' . Request::param('file');
  120. return json(['code' => 0, 'data' => ['src' => $url]]);
  121. }
  122. /**
  123. * 课件活动编辑页面
  124. */
  125. public function course_edit()
  126. {
  127. $id = Request::param('id');
  128. $data = (new TrainCourse())->where(['id' => $id, 'root_id' => request()->employee->root_id])->find();
  129. View::assign('type_id', $data->getData('type_id'));
  130. View::assign('data', $data);
  131. View::assign('old_file', $data->getData('file'));
  132. View::assign('old_video_img', $data->getData('video_img'));
  133. //$type = TrainType::where(['root_id' => request()->employee->root_id, 'id' => $data->getData('type_id')])->field('id,type')->find();
  134. $condition = [
  135. 'root_id' => request()->employee->root_id,
  136. 'from_type' => 0
  137. ];
  138. $type = TrainType::where($condition)->select()->toArray();
  139. View::assign('type', $type);
  140. return View::fetch();
  141. }
  142. /**
  143. * 课件活动编辑保存
  144. */
  145. public function courseEditSave()
  146. {
  147. $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']);
  148. if ($data['time_check'] == 0 && $data['word_check'] == 0) return json(['code' => 1, 'msg' => '完成条件最少选择一项']);
  149. $ask = input('content');
  150. $ask = str_replace('&nbsp;', '', $ask);
  151. if (trim($ask) == '' && $data['type'] != 'pdf') {
  152. return json(['code' => 1, 'msg' => '课件内容不能为空']);
  153. }
  154. $newData = [
  155. 'root_id' => request()->employee->root_id,
  156. 'title' => $data['title'],
  157. 'type_id' => $data['type_id'],
  158. 'content' => $data['content'],
  159. 'type' => $data['type'],
  160. 'study_time' => $data['time_check'] == 0 ? 0 : $data['study_time'],
  161. 'comment_word_num' => $data['word_check'] == 0 ? 0 : $data['comment_word_num']
  162. ];
  163. // 添加判断
  164. $course = TrainCourse::where(['root_id' => request()->employee->root_id, 'id' => $data['id']])->find();
  165. if (empty($course)) return json(['code' => 1, 'msg' => '课件不存在']);
  166. // 判断是否更换类型,如果更换类型,则内容需要重新上传
  167. if ($course->type != $data['type'] && empty($data['file_' . $data['type']])) {
  168. $msgType = [
  169. 'video' => '视频',
  170. 'audio' => '音频',
  171. 'pdf' => 'pdf课程文件',
  172. 'image' => '图片',
  173. ];
  174. return json(['code' => 1, 'msg' => '请选择' . $msgType[$data['type']]]);
  175. }
  176. if (!empty($data['file_' . $data['type']])) {
  177. if ($data['type'] == 'image') {
  178. $newData['file'] = $data['file_image'];
  179. } else {
  180. $arr = explode(',', $data['file_' . $data['type']]);
  181. $newData['file'] = end($arr);
  182. if ('video' == $data['type'])
  183. $newData['video_img'] = !empty($data['video_img']) ? $data['video_img'] : null;
  184. }
  185. }
  186. $course->save($newData);
  187. // if ($data['type'] == 'video') {
  188. // if (empty($data['file_video'])) return json(['code' => 1, 'msg' => '请选择视频']);
  189. // $arr = explode(',', $data['file_video']);
  190. // $newData['file'] = end($arr);
  191. // $newData['video_img'] = !empty($data['video_img']) ? $data['video_img'] : null;
  192. // } elseif ($data['type'] == 'audio') {
  193. // if (empty($data['file_audio'])) return json(['code' => 1, 'msg' => '请选择音频']);
  194. // $arr = explode(',', $data['file_audio']);
  195. // $newData['file'] = end($arr);
  196. // } elseif ($data['type'] == 'pdf') {
  197. // if (empty($data['file_pdf'])) return json(['code' => 1, 'msg' => '请选择pdf课程文件']);
  198. // $arr = explode(',', $data['file_pdf']);
  199. // $newData['file'] = end($arr);
  200. // } else {
  201. // if (empty($data['file_image'])) return json(['code' => 1, 'msg' => '请选择图片']);
  202. // $newData['file'] = $data['file_image'];
  203. // }
  204. // TrainCourse::where(['root_id' => request()->employee->root_id, 'id' => $data['id']])->update($newData);
  205. return json(['code' => 0, 'msg' => '修改成功']);
  206. }
  207. /**
  208. * 课件删除
  209. */
  210. public function del_course_train()
  211. {
  212. $id = Request::param('id');
  213. $course = TrainCourse::where(['id' => $id, 'root_id' => request()->employee->root_id])->find();
  214. if (!$course) return json(['code' => 1, 'msg' => '删除失败,课件不存在']);
  215. Db::startTrans();
  216. try {
  217. //查询课程中使用该课件的数据
  218. $data = TrainClass::field('id,course_id,publish')->whereRaw("FIND_IN_SET(" . $id . " , course_id)")->where([['root_id', '=', request()->employee->root_id], ['del', '=', 0]])->select()->toArray();
  219. $column_cid = array_column($data, 'id');
  220. $course->delete_time = time();
  221. $course->save();
  222. foreach ($data as $item) {
  223. //删除绑定该课件的课程,如果该课程全部删除课件则下架课程
  224. $newArr = array_diff(explode(',', $item['course_id']), explode(',', $id));
  225. $newArrs = implode(',', $newArr);
  226. $update = [
  227. 'course_id' => $newArrs,
  228. 'publish' => empty($newArrs) ? 0 : $item['publish']
  229. ];
  230. TrainClass::where('id', $item['id'])->update($update);
  231. //查询完成数据中有存在删除的课件
  232. $log = TrainDoneLog::where([['from', '=', 0], ['class_id', '=', $item['id']], ['root_id', '=', request()->employee->root_id]])->whereRaw("FIND_IN_SET(" . $id . " , course_id)")->field('id,course_id,done_percent')->select();
  233. foreach ($log as $val) {
  234. $newsArr = array_diff(explode(',', $val['course_id']), explode(',', $id));
  235. $newLogArr = implode(',', $newsArr);
  236. $GDP = $this->GDP(count($newsArr), count($newArr));
  237. TrainDoneLog::where('id', $val['id'])->update(['course_id' => $newLogArr, 'done_percent' => $GDP]);
  238. }
  239. }
  240. Db::commit();
  241. return json(['code' => 0, 'msg' => '删除成功']);
  242. } catch (\Exception $e) {
  243. Db::rollback();
  244. return json(['code' => 1, 'msg' => '删除失败']);
  245. }
  246. }
  247. /*
  248. * 课件场景列表
  249. */
  250. public function type_index()
  251. {
  252. if (!Request::isAjax()) {
  253. return View::fetch();
  254. }
  255. $param = request()->param();
  256. $condition = [
  257. 'root_id' => request()->employee->root_id,
  258. 'from_type' => 0
  259. ];
  260. $data = TrainType::where($condition)->page($param['page'], $param['limit'])
  261. // ->order('train_course_count desc,id desc')
  262. ->order(['show'=>'asc','id'=>'desc'])
  263. ->select();
  264. $count = TrainType::where($condition)->count();
  265. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  266. }
  267. /*
  268. * 课件场景添加
  269. */
  270. public function add_train_type()
  271. {
  272. $type = Request::param('type');
  273. if (empty($type)) return json(['code' => 1, 'msg' => '请输入场景名称']);
  274. $isAdd = TrainType::where(['type' => $type, 'root_id' => request()->employee->root_id])->count();
  275. if ($isAdd > 0) return json(['code' => 1, 'msg' => '场景已存在']);
  276. $objId = TrainType::insertGetId(['type' => $type, 'root_id' => request()->employee->root_id]);
  277. return json(['code' => 0, 'msg' => '添加成功', 'data' => ['id' => $objId, 'type' => $type]]);
  278. }
  279. /*
  280. * 课件场景修改
  281. */
  282. public function edit_train_type()
  283. {
  284. $id = Request::param('id');
  285. $type = Request::param('type');
  286. if (empty($type)) return json(['code' => 1, 'msg' => '请输入场景名称']);
  287. if (TrainType::where(['id' => $id, 'root_id' => request()->employee->root_id])->update(['type' => $type])) {
  288. return json(['code' => 0, 'msg' => '修改成功']);
  289. } else {
  290. return json(['code' => 1, 'msg' => '修改失败']);
  291. }
  292. }
  293. /*
  294. * 场景删除
  295. */
  296. public function del_train_type()
  297. {
  298. $id = Request::param('id');
  299. $data = TrainType::where(['id' => $id, 'root_id' => request()->employee->root_id])->find();
  300. if (!$data) return json(['code' => 1, 'msg' => '删除失败']);
  301. $other_id = TrainType::where(['root_id'=>request()->employee->root_id , 'show'=>1])->value('id');
  302. if(empty($other_id)) $other_id = TrainType::insertGetId(['type'=>'其它','root_id'=>request()->employee->root_id,'show'=>1]);
  303. TrainCourse::where(['root_id'=>request()->employee->root_id , 'type_id'=>$id])->update(['type_id'=>$other_id]);
  304. $data->delete();
  305. return json(['code' => 0, 'msg' => '删除成功']);
  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', '=', request()->employee->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', '=', request()->employee->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','=',request()->employee->root_id],['state','=','在职'],['uid','>',0]])->count();
  335. //课程总结
  336. $trainSummary = TrainSumup::where([['root_id', '=', request()->employee->root_id], ['course_id', '=', 0]])->group('class_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]])->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 qrcode($id)
  384. {
  385. $class = TrainClass::where(['id' => $id, 'root_id' => request()->employee->root_id])->field('qrcode')->find();
  386. if (empty($class)) return json(['code' => 1, 'msg' => '课程信息不存在']);
  387. $qrcode = $class['qrcode'];
  388. if (empty($class['qrcode'])) {
  389. // 生成二维码
  390. $mini = Miniprogram::where([['root_id', '=', request()->employee->root_id]])->find();
  391. $qrObj = new Qrcode;
  392. $param = [
  393. 'scene' => 'cli=' . $mini['notify'] . '&id=' . $class['id'] . '&t=tl',
  394. 'page' => 'pages/index/index',
  395. 'width' => '280px',
  396. ];
  397. $qr = $qrObj->getUnlimited($mini->accesstoken, $param);
  398. $rs = json_decode($qr, true);
  399. if (!is_null($rs)) {
  400. return json(['code' => 1, 'msg' => '课程二维码生成失败']);
  401. }
  402. $path = 'trainClassQrcode/' . uniqid() . '.jpeg';
  403. ossContentUpload($path, $qr);
  404. $class->qrcode = $path;
  405. $class->save();
  406. $qrcode = 'https://' . config('app.ali_oss_bindurl') . '/' . $path;
  407. }
  408. return json(['code' => 0, 'msg' => '获取成功', 'qrcode' => $qrcode]);
  409. }
  410. /*
  411. * 完成画像列表
  412. * 新逻辑 区分指派前和指派后 以train_class表的train_employee字段区分,为空则为指派前阶段,有值为指派后阶段
  413. * 指派前阶段为自由学习阶段,所有人都可以看到课程并学习,指派后则为指派的人能学习
  414. * 量化考核中也要区分,指派前和指派后互相数据不关联
  415. *
  416. * 指派前未完成列表要把公司所有人都列出来
  417. * 指派后只查询指派范围内的未学习和未完成人员
  418. */
  419. public function doneLog($page = 1, $limit = 10, $type, $class_id, $keyword = null)
  420. {
  421. if (!Request::isAjax()) {
  422. View::assign('type', $type);
  423. View::assign('class_id', $class_id);
  424. return View::fetch();
  425. }
  426. //没有指派就把公司所有没学完的人
  427. $train = TrainClass::where('id',$class_id)->field('id,train_employee')->findOrEmpty();
  428. if($train->isEmpty()) return json(['code' => 1, 'data' => [], 'count' => 0]);
  429. //未指派
  430. if (!$train->train_employee) {
  431. $condition = [
  432. ['root_id', '=', request()->employee->root_id],
  433. ['class_id', '=', $class_id],
  434. ['from','=',0]
  435. ];
  436. $finish = TrainDoneLog::where(array_merge([['done_percent', '=', 100]],$condition))->column('done_percent','employee_id');
  437. $nofinish = TrainDoneLog::where(array_merge([['done_percent', 'between', [1,99]]],$condition))->column('done_percent','employee_id');
  438. if ($type == 'complete') {
  439. //已完成
  440. $where[] = ['id','in',array_keys($finish)];
  441. } else {
  442. //未完成
  443. $employee_id = Employee::where([['root_id','=',request()->employee->root_id],['state','=','在职'],['uid','>',0]])->column('id');
  444. $employee = array_diff($employee_id,array_keys($finish));
  445. $where[] = ['id','in',$employee];
  446. }
  447. }else{
  448. $employee_id = explode(',',$train->train_employee);
  449. //已指派
  450. $condition = [
  451. ['root_id', '=', request()->employee->root_id],
  452. ['class_id', '=', $class_id],
  453. ['from','=',0],
  454. ['employee_id','in',$employee_id]
  455. ];
  456. $finish = TrainDoneLog::where(array_merge([['done_percent', '=', 100]],$condition))->column('done_percent','employee_id');
  457. $nofinish = TrainDoneLog::where(array_merge([['done_percent', 'between', [1,99]]],$condition))->column('done_percent','employee_id');
  458. if ($type == 'complete') {
  459. //已完成
  460. $where[] = ['id','in',array_keys($finish)];
  461. } else {
  462. //未完成
  463. $employee = array_diff($employee_id,array_keys($finish));
  464. $where[] = ['id','in',$employee];
  465. }
  466. }
  467. if ($keyword) {
  468. $where[] = ['name','like','%'.$keyword.'%'];
  469. }
  470. $data = Employee::with(['user'])->where($where)->field('id,name,uid')->page($page, $limit)->select()->toArray();
  471. $column_uid = array_column($data, 'uid');
  472. $user = User::where('id', 'in', $column_uid)->column('headimgurl', 'id');
  473. foreach ($data as &$val) {
  474. //头像
  475. $val['headimgurl'] = isset($user[$val['uid']]) ? $user[$val['uid']] : '';
  476. //进度
  477. $val['done_percent'] = isset($finish[$val['id']]) ? $finish[$val['id']] : (isset($nofinish[$val['id']]) ? $nofinish[$val['id']] : '未学习');
  478. }
  479. $count = Employee::where($where)->count();
  480. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  481. // $condition = [
  482. // ['root_id', '=', request()->employee->root_id],
  483. // ['class_id', '=', $class_id]
  484. // ];
  485. // if ($type == 'complete') {
  486. // $condition[] = [['done_percent', '=', 100]];
  487. // } else {
  488. // $condition[] = [['done_percent', 'BETWEEN', [1, 99]]];
  489. // }
  490. // if (!empty($keyword)) {
  491. // $employee_id = Employee::where([['root_id', '=', request()->employee->root_id], ['name', 'like', '%' . $keyword . '%']])->column('id');
  492. // $condition[] = [['employee_id', 'in', $employee_id]];
  493. // }
  494. // $condition[] = ['from', '=', 0];
  495. // $data = TrainDoneLog::with(['employee'])->field('id,employee_id,done_percent')->where($condition)->page($page, $limit)->order('done_percent desc')->select()->toArray();
  496. // $column_uid = array_column($data, 'uid');
  497. // $user = User::where('id', 'in', $column_uid)->column('headimgurl', 'id');
  498. // foreach ($data as &$val) {
  499. // $val['headimgurl'] = isset($user[$val['uid']]) ? $user[$val['uid']] : '';
  500. // }
  501. // $count = TrainDoneLog::where($condition)->count();
  502. // return json(['code' => 0, 'data' => $data, 'count' => $count]);
  503. }
  504. /*
  505. * 课程培训添加页
  506. */
  507. public function class_add()
  508. {
  509. $w = [
  510. ['root_id', '=', request()->employee->root_id],
  511. ['pid', '=', 0]
  512. ];
  513. $type = TrainClassCate::where($w)->field('id,name')->select();
  514. View::assign('type', $type);
  515. return View::fetch();
  516. }
  517. /*
  518. * 获取分类标签
  519. */
  520. public function get_label()
  521. {
  522. $param = Request::only(['id' => 0, 'name' => '']);
  523. if ($param['id']) {
  524. $w[] = ['pid', '=', $param['id']];
  525. } else if ($param['name']) {
  526. $w1 = [
  527. ['root_id', '=', request()->employee->root_id],
  528. ['name', '=', $param['name']]
  529. ];
  530. $pid = TrainClassCate::where($w1)->value('id');
  531. $w[] = ['pid', '=', $pid];
  532. } else {
  533. return json(['code' => 0, 'data' => []]);
  534. }
  535. $w[] = ['root_id', '=', request()->employee->root_id];
  536. $list = TrainClassCate::where($w)->field('id,name')->order('id desc')->select();
  537. return json(['code' => 0, 'data' => $list]);
  538. }
  539. /*
  540. * 课程培训添加页面所需课件展示
  541. */
  542. public function class_choice_course()
  543. {
  544. $param = Request::only(['page'=>1,'limit'=>10,'keyword'=>'']);
  545. $type = TrainType::where(['root_id' => request()->employee->root_id, 'from_type' => 0])->field('id,type,from_type')->select()->toArray();
  546. if (!Request::isAjax()) {
  547. $checkValId = request()->param('course_id');
  548. View::assign('type', $type);
  549. View::assign('course_id', isset($checkValId) ? $checkValId : '');
  550. return View::fetch();
  551. }
  552. $type_id = request()->param('type_id');
  553. $course_id = request()->param('course_id');
  554. $condition[] = ['root_id', '=', request()->employee->root_id];
  555. if (isset($type_id) && !empty($type_id)) $condition[] = ['type_id', '=', $type_id];
  556. if (!empty($course_id)) {
  557. $arrId = explode(',', $course_id);
  558. $condition[] = ['id', 'not in', $arrId];
  559. }
  560. if($param['keyword']) $condition[] = ['title','like','%'.$param['keyword'].'%'];
  561. $data = TrainCourse::where($condition)->order('id desc')->page($param['page'],$param['limit'])->select();
  562. $count = TrainCourse::where($condition)->count();
  563. return json(['code' => 0, 'data' => $data,'count'=>$count]);
  564. }
  565. /*
  566. * 课程培训修改页
  567. */
  568. public function class_edit()
  569. {
  570. //分类
  571. $w = [
  572. ['root_id', '=', request()->employee->root_id],
  573. ['pid', '=', 0]
  574. ];
  575. $type = TrainClassCate::where($w)->field('id,name')->select();
  576. View::assign('type', $type);
  577. $class_id = request()->param('class_id');
  578. $class = TrainClass::where(['id' => $class_id, 'root_id' => request()->employee->root_id])->find();
  579. $class['sumup_keyword'] = empty($class['sumup_keyword']) ? '' : implode('|', json_decode($class['sumup_keyword'], true));
  580. $class['sumup_score'] = json_decode($class['sumup_score'], true);
  581. View::assign('class', $class);
  582. View::assign('cover', $class->getData('cover'));
  583. $course = TrainCourse::where('id', 'in', $class['course_id'])->select();
  584. View::assign('course', $course);
  585. //标签
  586. $w[] = ['name', '=', $class->cate];
  587. $pid = TrainClassCate::where($w)->value('id');
  588. $labels = TrainClassCate::where('pid', $pid)->select();
  589. View::assign('labels', $labels);
  590. return View::fetch();
  591. }
  592. /**
  593. * 课件活动编辑保存
  594. */
  595. public function classEditSave()
  596. {
  597. $data = Request::only(['title', 'cate', 'label', 'des'=>'', 'type', 'category', 'cover', 'course_id', 'id', 'sumup_num', 'sumup_keyword', 'score_one', 'score_two', 'score_three','credit']);
  598. $data['cate'] = str_replace(' ', '', $data['cate']);
  599. $data['label'] = str_replace(' ', '', $data['label']);
  600. $data['sumup_num'] = $data['sumup_num'] ? $data['sumup_num'] : 0;
  601. $newData = [
  602. 'title' => $data['title'],
  603. 'type' => $data['type'],
  604. 'category' => $data['category'],
  605. 'course_id' => $data['course_id'],
  606. 'des' => $data['des'],
  607. 'cover' => $data['cover'],
  608. 'sumup_num' => $data['sumup_num'],
  609. 'sumup_keyword' => empty(array_filter(explode('|', trim($data['sumup_keyword'], '|')))) ? null : json_encode(array_values(array_filter(explode('|', trim($data['sumup_keyword'], '|'))))),
  610. 'sumup_score' => json_encode(['score_one' => $data['score_one'], 'score_two' => $data['score_two'], 'score_three' => $data['score_three']]),
  611. 'cate' => $data['cate'],
  612. 'label' => $data['label'],
  613. 'credit' => $data['credit']
  614. ];
  615. if (empty($newData['cover'])) return json(['code' => 1, 'msg' => '请选择封面']);
  616. $class = TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $data['id']])->find();
  617. $newData['publish'] = empty($data['course_id']) ? 0 : $class['publish'];
  618. if (empty($class['qrcode'])) {
  619. // 生成二维码
  620. $rootOrgId = request()->employee->root_id;
  621. $mini = Miniprogram::where([['root_id', '=', $rootOrgId]])->find();
  622. $qrObj = new Qrcode;
  623. $param = [
  624. 'scene' => 'cli=' . $mini['notify'] . '&id=' . $data['id'] . '&t=tl',
  625. 'page' => 'pages/index/index',
  626. 'width' => '280px',
  627. ];
  628. $qr = $qrObj->getUnlimited($mini->accesstoken, $param);
  629. $rs = json_decode($qr, true);
  630. if (!is_null($rs)) {
  631. trace('课程二维码生成失败' . ';error:' . $qr, 'error');
  632. }
  633. $path = 'trainClassQrcode/' . uniqid() . '.jpeg';
  634. ossContentUpload($path, $qr);
  635. $newData['qrcode'] = $path;
  636. }
  637. $stringA = explode(',', $class['course_id']);
  638. $stringB = explode(',', $newData['course_id']);
  639. if (array_diff($stringA, $stringB) || array_diff($stringB, $stringA)) {
  640. //修改课程课件时同步更新员工完成的完成情况
  641. $log = TrainDoneLog::where(['root_id' => request()->employee->root_id, 'class_id' => $data['id'], 'from' => 0])->select();
  642. foreach ($log as $item) {
  643. //员工之前完成的课件 , 修改后的课件
  644. $contrast = array_intersect(explode(',', $newData['course_id']), explode(',', $item['course_id']));
  645. $contrastImplode = implode(',', $contrast);
  646. $fload = $this->GDP(count($contrast), count(explode(',', $data['course_id'])));
  647. TrainDoneLog::where('id', $item['id'])->update(['course_id' => $contrastImplode, 'done_percent' => $fload]);
  648. }
  649. }
  650. if (TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $data['id']])->update($newData)) {
  651. return json(['code' => 0, 'msg' => '修改成功']);
  652. } else {
  653. return json(['code' => 1, 'msg' => '修改失败']);
  654. }
  655. }
  656. /**
  657. * 课件活动添加保存
  658. */
  659. public function classAddSave()
  660. {
  661. $data = Request::only(['title','label', 'cate', 'des'=>'', 'type', 'category', 'cover', 'course_id', 'sumup_num', 'sumup_keyword', 'score_one', 'score_two', 'score_three', 'train_employee','credit']);
  662. $data['sumup_num'] = $data['sumup_num'] ? $data['sumup_num'] : 0;
  663. $data['cate'] = str_replace(' ','',$data['cate']);
  664. $data['label'] = str_replace(' ','',$data['label']);
  665. $newData = [
  666. 'root_id' => request()->employee->root_id,
  667. 'title' => $data['title'],
  668. 'type' => $data['type'],
  669. 'category' => $data['category'],
  670. 'course_id' => $data['course_id'],
  671. 'des' => $data['des'],
  672. 'sumup_num' => $data['sumup_num'],
  673. 'sumup_keyword' => empty(array_filter(explode('|', trim($data['sumup_keyword'], '|')))) ? null : json_encode(array_values(array_filter(explode('|', trim($data['sumup_keyword'], '|'))))),
  674. 'sumup_score' => json_encode(['score_one' => $data['score_one'], 'score_two' => $data['score_two'], 'score_three' => $data['score_three']]),
  675. 'qrcode' => '',
  676. 'train_employee' => '',
  677. 'cate' => $data['cate'],
  678. 'label' => $data['label'],
  679. 'credit' => $data['credit']
  680. ];
  681. if (!isset($data['cover']) && empty($data['cover'])) return json(['code' => 1, 'msg' => '请选择封面']);
  682. $newData['cover'] = $data['cover'];
  683. $id = TrainClass::insertGetid($newData);
  684. if ($id) {
  685. // 生成二维码
  686. $rootOrgId = request()->employee->root_id;
  687. $mini = Miniprogram::where([['root_id', '=', $rootOrgId]])->find();
  688. $qrObj = new Qrcode;
  689. $param = [
  690. 'scene' => 'cli=' . $mini['notify'] . '&id=' . $id . '&t=tl',
  691. 'page' => 'pages/index/index',
  692. 'width' => '280px',
  693. ];
  694. $qr = $qrObj->getUnlimited($mini->accesstoken, $param);
  695. $rs = json_decode($qr, true);
  696. if (!is_null($rs)) {
  697. trace('课程二维码生成失败' . ';error:' . $qr, 'error');
  698. }
  699. $path = 'trainClassQrcode/' . uniqid() . '.jpeg';
  700. ossContentUpload($path, $qr);
  701. (new TrainClass())->update(['id' => $id, 'qrcode' => $path]);
  702. dataStatistics(request()->employee->root_id,'course_count',1,'inc');//manage应用首页统计数据
  703. return json(['code' => 0, 'msg' => '添加成功']);
  704. } else {
  705. return json(['code' => 1, 'msg' => '添加失败']);
  706. }
  707. }
  708. /*
  709. * 培训课程删除
  710. */
  711. public function classDel($id)
  712. {
  713. $obj = TrainClass::where(['id' => $id, 'root_id' => request()->employee->root_id])->find();
  714. if (empty($obj)) return json(['code' => 1, 'msg' => '删除失败,数据不存在']);
  715. $obj->del = 1;
  716. $obj->save();
  717. dataStatistics(request()->employee->root_id,'course_count',1,'dec');//manage应用首页统计数据
  718. return json(['code' => 0, 'msg' => '删除成功']);
  719. }
  720. /*
  721. * 培训课程上下架
  722. */
  723. public function classPublish($id)
  724. {
  725. $obj = TrainClass::where(['id' => $id, 'root_id' => request()->employee->root_id])->find();
  726. if (empty($obj)) return json(['code' => 1, 'msg' => '操作失败,数据不存在']);
  727. if (empty($obj['course_id']) && $obj->publish == 0) return json(['code' => 1, 'msg' => '请先绑定课件']);
  728. $obj->publish = $obj->publish == 1 ? 0 : 1;
  729. $obj->save();
  730. return json(['code' => 0, 'msg' => '操作成功']);
  731. }
  732. /*
  733. * 课程指派展示
  734. */
  735. public function class_assign()
  736. {
  737. if (!Request::isAjax()) {
  738. $id = Request::param('id');
  739. View::assign('id', $id);
  740. return View::fetch();
  741. }
  742. $id = Request::param('id');
  743. $org = TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $id])->value('org_id');
  744. $datastr = OrgLogic::struc(request()->employee['root_id']);
  745. $datastr = json_decode($datastr, true);
  746. return json(['code' => 0, 'data' => $datastr, 'checkOrg' => $org]);
  747. }
  748. /*
  749. * 课程指派展示
  750. */
  751. public function class_assigns()
  752. {
  753. if (!Request::isAjax()) {
  754. $id = Request::param('id');
  755. View::assign('id', $id);
  756. $info = TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $id])->value('train_employee');
  757. $count = $info ? count(explode(',', $info)) : 0;
  758. view::assign('count', $count);
  759. return View::fetch();
  760. }
  761. $id = Request::param('id'); //课程id
  762. $pid = Request::param('pid'); //多选框选中id
  763. $type = Request::param('type'); //选中类型,人/部门
  764. $res = Request::param('res'); //选择结果 1选中,0取消
  765. $data = [];
  766. $info = TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $id])->find();
  767. $a = 0;
  768. if ($type == 'per' && $pid) {
  769. $data[] = 'per_' . $pid;
  770. $pid = [$pid];
  771. $a = 1;
  772. } elseif ($type == 'org' && $pid) {
  773. $data[] = 'org_' . $pid;
  774. $org = Org::where([['id', '=', $pid]])->value('path');
  775. $orgs = Org::where([['path', 'like', $org . '%']])->column('id');
  776. $pid = Employee::where([['root_id', '=', request()->employee->root_id], ['org_id', 'in', $orgs], ['state', '=', '在职'], ['uid', '>', 0]])->order('is_manager desc,id desc')->column('id');
  777. $a = 1;
  778. foreach ($pid as $v) {
  779. $data[] = 'per_' . $v;
  780. }
  781. foreach ($orgs as $v2) {
  782. $data[] = 'org_' . $v2;
  783. }
  784. }
  785. $train_employee = explode(',', $info['train_employee']);
  786. if ($a) {
  787. $arr = array_filter(array_diff($train_employee, $pid));
  788. $arr = $res ? array_merge($pid, $arr) : $arr;
  789. $arr = array_unique($arr);
  790. //过滤运营人员,旧bug导致选择根部门时,运营人员也会在内
  791. $arr = Employee::where([['id', 'in', $arr], ['uid', '>', 0], ['state', '=', '在职']])->column('id');
  792. //查询指派人的组织
  793. $employee_org = Employee::where('id', 'in', $arr)->group('org_id')->column('org_id');
  794. $employee_org = implode(',', $employee_org);
  795. TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $id])->update(['org_id' => $employee_org, 'train_employee' => implode(',', $arr)]);
  796. // 指派记录调整
  797. $assign = TrainClassAssign::where([['root_id', '=', request()->employee->root_id], ['class_id', '=', $id]])->select();
  798. foreach ($assign as $k => $v) {
  799. if (!in_array($v['id'], $arr)) {
  800. $v->delete();
  801. }
  802. }
  803. $old_assign = array_column($assign->toArray(), 'employee_id');
  804. $new_assign_emp = array_diff($arr, $old_assign);
  805. $new_assign = [];
  806. foreach ($new_assign_emp as $e) {
  807. $new_assign[] = [
  808. 'class_id' => $id,
  809. 'employee_id' => $e,
  810. 'root_id' => request()->employee->root_id
  811. ];
  812. if ($info['publish'] == 1){
  813. event(new Msg($e, '你有新的课程被指派,请前往学习', 'trainClass', $id));
  814. }
  815. }
  816. (new TrainClassAssign)->saveAll($new_assign);
  817. }
  818. return json(['code' => 0, 'data' => $data]);
  819. }
  820. /*
  821. * 课程指派展示列表
  822. */
  823. public function class_assigns_list()
  824. {
  825. $id = Request::param('id');
  826. $page = Request::param('page') ?: 1;
  827. $limit = Request::param('limit') ?: 10;
  828. $keyword = Request::param('keyword') ?: '';
  829. if ($keyword) {
  830. $w[] = ['name', 'like', '%' . $keyword . '%'];
  831. }
  832. $arr = TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $id])->value('train_employee');
  833. $arr = $arr ? explode(',', $arr) : [];
  834. $w[] = ['id', 'in', $arr];
  835. $w[] = ['state', '=', '在职'];
  836. $w[] = ['uid', '>', 0];
  837. $data = Employee::with('orgName')->where($w)->visible(['name', 'org_name', 'id', 'is_manager'])->select()->toArray();
  838. $count = count($data);
  839. $arr = array_flip($arr);
  840. foreach ($data as $k => $v) {
  841. $data[$k]['order'] = $arr[$v['id']];
  842. }
  843. array_multisort(array_column($data, 'order'), SORT_ASC, $data);
  844. foreach ($data as $k => $v) {
  845. $data[$k]['xh'] = $k + 1;
  846. }
  847. $data = array_slice($data, ($page - 1) * $limit, $limit);
  848. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  849. }
  850. /*
  851. * 课程指派展示列表
  852. */
  853. public function del_assign()
  854. {
  855. $id = Request::param('id');
  856. $eid = Request::param('eid');
  857. if ($id && $eid) {
  858. if ($eid == -1) {
  859. TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $id])->update(['train_employee' => '']);
  860. } else {
  861. $arr = TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $id])->value('train_employee');
  862. $arr = array_filter(array_diff(explode(',', $arr), [$eid]));
  863. TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $id])->update(['train_employee' => implode(',', $arr)]);
  864. }
  865. }
  866. return json(['code' => 0, 'data' => '取消成功', 'msg' => '取消成功']);
  867. }
  868. /*
  869. * 课程指派入库
  870. */
  871. public function class_assign_edit()
  872. {
  873. $param = Request::param(['id', 'org']);
  874. $before = TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $param['id']])->field('org_id,title')->find()->toArray();
  875. if (TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $param['id']])->update(['org_id' => $param['org']])) {
  876. $title = $before['title'];
  877. $before = $before['org_id'];
  878. //发送消息通知
  879. $arr1 = $before ? explode(',', $before) : [];
  880. $arr2 = explode(',', $param['org']);
  881. $add = array_diff($arr1, $arr2);
  882. $reduce = array_diff($arr2, $arr1);
  883. if ($add) {
  884. $eids = Employee::where([['org_id', 'in', $add], ['state', '=', '在职']])->column('id');
  885. foreach ($eids as $v1) {
  886. event(new Msg($v1, '您的培训“' . $title . '”已取消。', 'cancelTraining'));
  887. }
  888. }
  889. if ($reduce) {
  890. $eids = Employee::where([['org_id', 'in', $reduce], ['state', '=', '在职']])->column('id');
  891. foreach ($eids as $v2) {
  892. event(new Msg($v2, '您有新的培训“' . $title . '”请及时参加。', 'courseTraining', $param['id']));
  893. }
  894. }
  895. return json(['code' => 0, 'msg' => '保存成功']);
  896. } else {
  897. return json(['code' => 1, 'msg' => '保存失败,无修改']);
  898. }
  899. }
  900. /*
  901. * 课程观看感悟
  902. */
  903. public function class_comment()
  904. {
  905. if (!Request::isAjax()) {
  906. $class_id = Request::param('class_id');
  907. View::assign('class_id', $class_id);
  908. return View::fetch();
  909. }
  910. $param = Request::param();
  911. $condition[] = [
  912. ['root_id', '=', request()->employee->root_id],
  913. ['class_id', '=', $param['class_id']],
  914. ['course_id', '=', 0]
  915. ];
  916. if (isset($param['keyword']) && !empty($param['keyword'])) $condition[] = ['content', 'like', '%' . $param['keyword'] . '%'];
  917. $data = TrainSumup::with(['employee'])->where($condition)->page($param['page'], $param['limit'])->order('addtime desc')->select();
  918. $count = TrainSumup::where($condition)->count();
  919. $class = TrainClass::where('id', $param['class_id'])->field('sumup_keyword,sumup_score')->find();
  920. foreach ($data as &$item) {
  921. $item['score'] = TrainSumup::sumup_score_num($class['sumup_keyword'], $class['sumup_score'], $item['content']);
  922. }
  923. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  924. }
  925. /*
  926. * 量化考核
  927. * 新逻辑 区分指派前和指派后 以train_class表的train_employee字段区分,为空则为指派前阶段,有值为指派后阶段
  928. * 指派前阶段为自由学习阶段,所有人都可以看到课程并学习,指派后则为指派的人能学习
  929. * 量化考核中也要区分,指派前和指派后互相数据不关联
  930. *
  931. * 调整部门逻辑, 部门调整后学习和感悟跟着走,人在那个部门内数据就属于那个部门
  932. *
  933. */
  934. public function class_org_data()
  935. {
  936. $class_id = request()->param('class_id');
  937. $root_id = request()->employee->root_id;
  938. $info = TrainClass::where(['root_id' => $root_id, 'id' => $class_id])->find();
  939. // $org_id = TrainClass::where(['root_id' => $root_id, 'id' => $class_id])->value('org_id');
  940. // //指派前所有部门,指派后指派的部门
  941. // $org_id = $org_id ? explode(',', $org_id) : Org::where([['path', 'like', request()->employee->root_id . '-%']])->column('id');
  942. //有切换部门情况
  943. $org_id = $info->train_employee ? Employee::where([['id','in',explode(',',$info->train_employee)]])->group('org_id')->column('org_id') : Org::where([['path', 'like', request()->employee->root_id . '-%']])->column('id');
  944. if (!Request::isAjax()) {
  945. //trainNumber 培训人数,指派部门的所有人数,completeCount 完成进度为100 的人数,summaryCount课程感悟人次
  946. $data = request()->param(['trainNumber', 'completeCount', 'summaryCount']);
  947. // $data['trainNumber'] = count(array_filter(explode(',',$info->train_employee)));
  948. $data['studyGDP'] = $this->GDP($data['completeCount'], $data['trainNumber']);
  949. $data['summaryGDP'] = $this->GDP($data['summaryCount'], $data['completeCount']);
  950. $data['earnestGDP'] = $this->GDP($data['summaryCount'], $data['trainNumber']);
  951. $org = Org::where('id', 'in', $org_id)->field('id,name')->select()->toArray();
  952. $orgNum = Employee::where([['root_id', '=', $root_id],['uid','>',0], ['state', '=', '在职'], ['org_id', '>', 0]])->group('org_id')->column('count(org_id)', 'org_id');
  953. //
  954. // $sumup = TrainSumup::where([['root_id', '=', $root_id], ['class_id', '=', $class_id]])->group(['org_id', 'employee_id'])->column('count(org_id)', 'org_id');
  955. $sumup = TrainSumup::where([['root_id', '=', $root_id], ['class_id', '=', $class_id]])->group('employee_id')->column('employee_id');
  956. $sumup = Employee::where([['id','in',$sumup]])->group('org_id')->column('count(org_id)', 'org_id');
  957. foreach ($org as &$item) {
  958. $employeeNum = isset($orgNum[$item['id']]) ? $orgNum[$item['id']] : 0;
  959. $writeSummary = isset($sumup[$item['id']]) ? $sumup[$item['id']] : 0;
  960. $item['summaryDGP'] = $this->GDP($writeSummary, $employeeNum);
  961. }
  962. $last_data = array_column($org, 'summaryDGP');
  963. array_multisort($last_data, SORT_DESC, $org);
  964. $data['max_org'] = empty($org) || $org[0]['summaryDGP'] == 0 ? '暂无数据' : $org[0]['name'];
  965. array_multisort($last_data, SORT_ASC, $org);
  966. $data['min_org'] = empty($org) || $org[0]['summaryDGP'] == 0 ? '暂无数据' : $org[0]['name'];
  967. View::assign('data', $data);
  968. View::assign('org', $org);
  969. View::assign('class_id', $class_id);
  970. return View::fetch();
  971. }
  972. $info = TrainClass::where(['root_id' => $root_id, 'id' => $class_id])->find();
  973. // $train_employee = []; //指派的员工
  974. // if (!empty($info->train_employee)){
  975. // $train_employee = explode(',', $info->train_employee);
  976. // }
  977. // 已学习的员工。 如果没指派员工则需要用已学习的员工去统计,合并数组是因为可能存在先是未指派,后面又指派的情况
  978. // $learned_employee = TrainDoneLog::where([['root_id', '=', $root_id], ['class_id', '=', $class_id]])->column('employee_id');
  979. // $all_employee = array_values(array_filter(array_unique(array_merge($train_employee, $learned_employee))));
  980. $param = Request::param(['org_id'=>0, 'study_state', 'view_state']);
  981. $where = $query = [];
  982. if($info->train_employee) $where[] = $query[] = ['id','in',explode(',',$info->train_employee)];
  983. if($param['org_id']) $where[] = ['org_id','=',$param['org_id']];
  984. $org_id = Employee::where([['state','=','在职'],['uid','>',0],['root_id','=',$root_id]])->where($where)->group('org_id')->column('org_id');
  985. $orgCondition[] = ['id', 'in', $org_id];
  986. // if (!empty($param['org_id'])) {
  987. // $orgCondition[] = ['id', '=', $param['org_id']];
  988. // }
  989. $org = Org::where($orgCondition)->field('id,name')->select();
  990. $orgCount = Employee::where([['root_id', '=', $root_id], ['state', 'like', '%在职%'], ['org_id', '>', 0], ['uid', '>', 0]])->where($query)->group('org_id')->column('count(id)', 'org_id');
  991. //已学完
  992. //$class_success = TrainDoneLog::where(['from' => 0, 'root_id' => $root_id, 'class_id' => $class_id, 'done_percent' => 100])->group('org_id')->column('count(employee_id)', 'org_id');
  993. $class_success_employee = TrainDoneLog::where(['from' => 0, 'root_id' => $root_id, 'class_id' => $class_id, 'done_percent' => 100])->column('employee_id');
  994. $class_success = Employee::where('id', 'in', $class_success_employee)->group('org_id')->column('count(id)', 'org_id');
  995. //未学完
  996. //$class_no_success = TrainDoneLog::where([['from', '=', 0], ['root_id', '=', $root_id], ['class_id', '=', $class_id], ['done_percent', '<', 100]])->group('org_id')->column('count(employee_id)', 'org_id');
  997. $class_no_success_employee = TrainDoneLog::where([['from', '=', 0], ['root_id', '=', $root_id], ['class_id', '=', $class_id], ['done_percent', '<', 100]])->column('employee_id');
  998. $class_no_success = Employee::where('id', 'in', $class_no_success_employee)->group('org_id')->column('count(id)', 'org_id');
  999. //感悟
  1000. $sumup_org_employee = TrainSumup::where([['root_id', '=', $root_id], ['class_id', '=', $class_id], ['course_id', '=', 0]])->group('employee_id')->column('employee_id');
  1001. $sumup_org = Employee::where('id', 'in', $sumup_org_employee)->field('id,org_id')->select();
  1002. $sumup_org_id = [];
  1003. foreach ($sumup_org as $k => $v){
  1004. $sumup_org_id[$v['org_id']][] = $v['id'];
  1005. }
  1006. $sumup = [];
  1007. foreach ($sumup_org_id as $k => $v) {
  1008. $sumup[$k] = TrainSumup::where([['employee_id', 'in', $v], ['class_id', '=', $class_id], ['course_id', '=', 0]])->group('employee_id')->count();
  1009. }
  1010. foreach ($org as &$item) {
  1011. //学习人数
  1012. $item['trainNumber'] = isset($orgCount[$item['id']]) ? $orgCount[$item['id']] : 0;
  1013. //已学完
  1014. $item['completeCount'] = isset($class_success[$item['id']]) ? $class_success[$item['id']] : 0;
  1015. //未学完
  1016. $item['noFinishCount'] = isset($class_no_success[$item['id']]) ? $class_no_success[$item['id']] : 0;
  1017. //写观后感
  1018. $item['summaryCount'] = isset($sumup[$item['id']]) ? $sumup[$item['id']] : 0;
  1019. //学习完成率
  1020. $item['studyDGP'] = $this->GDP($item['completeCount'], $item['trainNumber']);
  1021. //观看感完成率
  1022. $item['summaryCountDGP'] = $this->GDP($item['summaryCount'], $item['completeCount']);
  1023. //认真完成率
  1024. $item['earnestDGP'] = $this->GDP($item['summaryCount'], $item['trainNumber']);
  1025. }
  1026. $data = $org;
  1027. $count = $org->count();
  1028. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1029. }
  1030. /*
  1031. * 计算率;根据两个数计算
  1032. */
  1033. private function GDP($data1, $data2)
  1034. {
  1035. if (empty($data1) || empty($data2)) {
  1036. return 0;
  1037. } else {
  1038. return floor(($data1 / $data2) * 100) > 100 ? 100 : floor(($data1 / $data2) * 100);
  1039. }
  1040. }
  1041. /**
  1042. * 量化考核员工学习情况
  1043. */
  1044. public function class_employee_data()
  1045. {
  1046. $param = Request::param(['org_id']);
  1047. $class_id = request()->param('class_id');
  1048. $dataurl = request()->param(['trainNumber', 'completeCount', 'summaryCount']);
  1049. $from = input('from', '', 'trim');
  1050. if ($from) {
  1051. $where1[] = ['from_content_id', '=', $class_id];
  1052. $where1[] = ['root_id', '=', orgRootId($param['org_id'])];
  1053. $class_id = TrainClass::where($where1)->value('id');
  1054. }
  1055. $info = TrainClass::where('id',$class_id)->find();
  1056. $employee_id = $info->train_employee ? explode(',',$info->train_employee) : [];
  1057. if ($employee_id) $where[] = ['id','in',$employee_id];
  1058. $where[] = ['org_id', '=', $param['org_id']];
  1059. $where[] = ['state', '=', '在职'];
  1060. $where[] = ['uid', '>', 0];
  1061. $employee = Employee::where($where)->select();
  1062. if (!Request::isAjax()) {
  1063. $data['employeeCount'] = $employee->count();
  1064. $data['completeCount'] = TrainDoneLog::where(['from' => 0, 'class_id' => $class_id, 'done_percent' => 100])->where([['employee_id','in',array_column($employee->toArray(),'id')]])->count();
  1065. $data['summaryCount'] = TrainSumup::where([['class_id', '=', $class_id], ['course_id', '=', 0], ['employee_id', 'in', array_column($employee->toArray(),'id')]])->group('employee_id')->count();
  1066. View::assign('class_id', $class_id);
  1067. View::assign('org_id', $param['org_id']);
  1068. View::assign('data', $data);
  1069. View::assign('dataurl', $dataurl);
  1070. return View::fetch();
  1071. }
  1072. $org_name = Org::where('id', '=', $param['org_id'])->value('name');
  1073. foreach ($employee as $k => $v) {
  1074. $employee[$k]['org_name'] = $org_name;
  1075. $employee[$k]['done_percent'] = TrainDoneLog::where(['from' => 0, 'class_id' => $class_id, 'employee_id' => $v['id']])->value('done_percent');
  1076. $employee[$k]['summary'] = TrainSumup::where([['class_id', '=', $class_id], ['course_id', '=', 0], ['employee_id', '=', $v['id']]])->value('content');
  1077. }
  1078. $count = $employee->count();
  1079. return json(['code' => 0, 'data' => $employee->toArray(), 'count' => $count]);
  1080. }
  1081. //部门人员树
  1082. public function tree($data, $pid = 0, $persons)
  1083. {
  1084. $new_arr = [];
  1085. foreach ($data as $k => $v) {
  1086. if ($v['pid'] == $pid) {
  1087. $persions = isset($persons[$v['id']]) ? $persons[$v['id']] : [];
  1088. $children = $this->tree($data, $v['id'], $persons);
  1089. $v['children'] = array_merge_recursive($children, $persions);
  1090. if (empty($v['children'])) $v['disabled'] = true;
  1091. $new_arr[] = $v;
  1092. }
  1093. }
  1094. return $new_arr;
  1095. }
  1096. /*
  1097. * 培训人员
  1098. */
  1099. public function get_person($id)
  1100. {
  1101. $ids = input('id', '');
  1102. $root_id = request()->employee->root_id;
  1103. $keyword = input('keyword', '');
  1104. //所有员工
  1105. $w1[] = ['root_id', '=', $root_id];
  1106. $w1[] = ['state', '=', '在职'];
  1107. $w1[] = ['org_id', '>', 0];
  1108. $w1[] = ['uid', '>', 0];
  1109. if ($keyword) {
  1110. $w1[] = ['name', 'like', '%' . $keyword . '%'];
  1111. }
  1112. $employee = Employee::where($w1)->field('id,name title,org_id,is_manager')->order('is_manager desc,id desc')->select()->toArray();
  1113. if ($ids) {
  1114. $ids = explode(',', $ids);
  1115. foreach ($employee as $k => &$v) {
  1116. $v['selected'] = in_array($v['id'], $ids);
  1117. $v['children'] = [];
  1118. $v['title'] = $v['is_manager'] ? $v['title'] . '(负责人)' : $v['title'];
  1119. $v['org_class'] = 'org_' . $v['org_id'];
  1120. $v['per_class'] = 'per_' . $v['id'];
  1121. $v['type'] = 'per';
  1122. }
  1123. } else {
  1124. foreach ($employee as $k => &$v) {
  1125. $v['selected'] = false;
  1126. $v['children'] = [];
  1127. $v['all_count'] = 0;
  1128. $v['title'] = $v['is_manager'] ? $v['title'] . '(负责人)' : $v['title'];
  1129. $v['org_class'] = 'org_' . $v['org_id'];
  1130. $v['per_class'] = 'per_' . $v['id'];
  1131. $v['type'] = 'per';
  1132. }
  1133. }
  1134. $persons = [];
  1135. foreach ($employee as $k => $v1) {
  1136. $persons[$v1['org_id']][] = $v1;
  1137. }
  1138. $where = [
  1139. ['path', 'like', $root_id . '-%'],
  1140. ['status', '=', 1]
  1141. ];
  1142. $count = Employee::where([['root_id', '=', $root_id], ['state', '=', '在职'], ['uid', '>', 0]])->group('org_id')->column('count(*) count', 'org_id');
  1143. $allnodes = Org::where($where)->field('id,pid,name title,level,org_type,info,path')->order('level asc, id asc')->select()->toArray();
  1144. foreach ($allnodes as $k => $v) {
  1145. $allnodes[$k]['count'] = isset($count[$v['id']]) ? $count[$v['id']] : 0; //本部门人数
  1146. $allnodes[$k]['all_count'] = 0; //包含子部门总数
  1147. $allnodes[$k]['org_class'] = 'org_' . $v['id'];
  1148. $allnodes[$k]['per_class'] = 'per_org_' . $v['id'];
  1149. $allnodes[$k]['type'] = 'org';
  1150. foreach ($allnodes as $k2 => $v2) {
  1151. if (strpos($v2['path'], $v['path']) !== false) {
  1152. $allnodes[$k]['all_count'] = isset($count[$v2['id']]) ? $count[$v2['id']] + $allnodes[$k]['all_count'] : $allnodes[$k]['all_count'];
  1153. }
  1154. }
  1155. $allnodes[$k]['title'] = $allnodes[$k]['title'] . ' (' . $allnodes[$k]['all_count'] . ')';
  1156. }
  1157. $tree = $this->tree($allnodes, 0, $persons);
  1158. $info = TrainClass::where(['root_id' => request()->employee->root_id, 'id' => $id])->value('train_employee');
  1159. return json(['code' => 0, 'data' => $tree, 'checkOrg' => $info]);
  1160. }
  1161. /***************** 集团课程板块列表 *****************/
  1162. /*
  1163. * 集团后台课程自建
  1164. */
  1165. public function groupClassList()
  1166. {
  1167. $param = request()->param();
  1168. if (!Request::isAjax()) {
  1169. View::assign('from', isset($param['from']) ? 'share' : 'add');
  1170. View::assign('root_id', isset($param['root_id']) ? $param['root_id'] : '');
  1171. View::assign('company_group', isset($param['company_group']) ? $param['company_group'] : '');
  1172. return View::fetch();
  1173. }
  1174. $condition = [
  1175. ['del', '=', 0],
  1176. ['from_type', '=', 0],
  1177. ['root_id', '=', request()->employee->root_id]
  1178. ];
  1179. if (isset($param['keyword'])) $condition[] = ['title', 'like', '%' . $param['keyword'] . '%'];
  1180. $data = TrainClass::where($condition)->field('id,title,course_id,addtime')->page($param['page'], $param['limit'])->order('addtime desc')->select()->toArray();
  1181. $class_id = array_column($data, 'id');
  1182. $shareCompany = TrainClass::where([['from_content_id', 'in', $class_id], ['from_type', '=', 1]])->group('from_content_id')->column('count(id)', 'from_content_id');
  1183. foreach ($data as &$v) {
  1184. //培训人数
  1185. $from_content_id = TrainClass::where('from_content_id', $v['id'])->column('root_id');
  1186. $v['trainNumber'] = Employee::where([['root_id', 'in', $from_content_id], ['state', 'like', '%在职%'], ['uid', '>', 0]])->count();
  1187. //已完成人数
  1188. $from_class_id = TrainClass::where('from_content_id', $v['id'])->column('id');
  1189. $v['completeCount'] = TrainDoneLog::where([['from', '=', 0], ['root_id', 'in', $from_content_id], ['class_id', 'in', $from_class_id], ['done_percent', '=', 100]])->count();
  1190. //未完成人数
  1191. $v['noFinishCount'] = TrainDoneLog::where([['from', '=', 0], ['root_id', 'in', $from_content_id], ['class_id', 'in', $from_class_id], ['done_percent', '<', 100], ['done_percent', '>', 0]])->count();
  1192. //章节数
  1193. $v['courseCount'] = empty($v['course_id']) ? 0 : count(explode(',', $v['course_id']));
  1194. //完成观看感
  1195. $v['summaryCount'] = TrainSumup::where([['root_id', 'in', $from_content_id], ['class_id', 'in', $from_class_id], ['course_id', '=', 0]])->count();
  1196. //未开始人数
  1197. $v['noStartCount'] = $v['trainNumber'] - ($v['completeCount'] + $v['noFinishCount']);
  1198. $v['noStartCount'] = $v['noStartCount'] >= 0 ? $v['noStartCount'] : 0;
  1199. $v['shareCompany'] = isset($shareCompany[$v['id']]) ? $shareCompany[$v['id']] : 0;
  1200. }
  1201. $count = TrainClass::where($condition)->count();
  1202. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1203. }
  1204. /*
  1205. * 集团指派完成画像列表
  1206. */
  1207. public function groupDoneLog($page = 1, $limit = 10, $type, $class_id, $keyword = null, $company_name_id = 0)
  1208. {
  1209. if (!Request::isAjax()) {
  1210. View::assign('type', $type);
  1211. View::assign('class_id', $class_id);
  1212. $data = TrainClass::with(['company'])->where('from_content_id', $class_id)->select();
  1213. View::assign('data', $data);
  1214. return View::fetch();
  1215. }
  1216. $classid = TrainClass::with(['company'])->where('from_content_id', $class_id)->column('id');
  1217. $condition = [
  1218. ['class_id', 'in', $classid],
  1219. ];
  1220. if (empty($company_name_id)) {
  1221. $company = TrainClass::with(['company'])->where('from_content_id', $class_id)->column('root_id');
  1222. $condition[] = ['root_id', 'in', $company];
  1223. } else {
  1224. $condition[] = ['root_id', '=', $company_name_id];
  1225. }
  1226. if ($type == 'complete') {
  1227. $condition[] = ['done_percent', '=', 100];
  1228. } else {
  1229. $condition[] = ['done_percent', 'BETWEEN', [1, 99]];
  1230. }
  1231. if (!empty($keyword)) {
  1232. $where = [['name', 'like', '%' . $keyword . '%']];
  1233. if (empty($company_name_id)) {
  1234. $where[] = ['root_id', 'in', $company];
  1235. } else {
  1236. $where[] = ['root_id', '=', $company_name_id];
  1237. }
  1238. $employee_id = Employee::where($where)->column('id');
  1239. $condition[] = ['employee_id', 'in', $employee_id];
  1240. }
  1241. $condition[] = ['from', '=', 0];
  1242. $data = TrainDoneLog::with(['employee'])->field('id,employee_id,done_percent')->where($condition)->page($page, $limit)->order('done_percent desc')->select()->toArray();
  1243. $column_uid = array_column($data, 'uid');
  1244. $user = User::where('id', 'in', $column_uid)->column('headimgurl', 'id');
  1245. foreach ($data as &$val) {
  1246. $val['headimgurl'] = isset($user[$val['uid']]) ? $user[$val['uid']] : '';
  1247. }
  1248. $count = TrainDoneLog::where($condition)->count();
  1249. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1250. }
  1251. /*
  1252. * 集团后台课程自建
  1253. */
  1254. public function groupCompanyClassList()
  1255. {
  1256. $param = request()->param();
  1257. if (!Request::isAjax()) {
  1258. View::assign('from', isset($param['from']) ? 'share' : 'add');
  1259. View::assign('root_id', isset($param['root_id']) ? $param['root_id'] : '');
  1260. View::assign('company_group', isset($param['company_group']) ? $param['company_group'] : '');
  1261. return View::fetch();
  1262. }
  1263. $condition = [
  1264. ['del', '=', 0],
  1265. ['from_type', '=', 0]
  1266. ];
  1267. if ($param['from'] == 'share') {
  1268. $fromRootId = Company::where('id', $param['company_group'])->value('root_id');
  1269. if ($fromRootId !== request()->employee->root_id) return json(['code' => 0, 'msg' => '未找到店面信息']);
  1270. $condition[] = ['root_id', '=', $param['root_id']];
  1271. } else {
  1272. $condition[] = ['root_id', '=', request()->employee->root_id];
  1273. }
  1274. if (isset($param['keyword'])) $condition[] = ['title', 'like', '%' . $param['keyword'] . '%'];
  1275. $data = TrainClass::where($condition)->field('id,title,course_id,addtime,org_id')->page($param['page'], $param['limit'])->order('addtime desc')->select()->toArray();
  1276. //获取课程id
  1277. $class_id = array_column($data, 'id');
  1278. $shareCompany = TrainClass::where([['from_content_id', 'in', $class_id], ['from_type', 'in', [1, 2]]])->group('from_content_id')->column('count(id)', 'from_content_id');
  1279. foreach ($data as &$v) {
  1280. //章节数
  1281. $v['courseCount'] = empty($v['course_id']) ? 0 : count(explode(',', $v['course_id']));
  1282. $v['shareCompany'] = isset($shareCompany[$v['id']]) ? $shareCompany[$v['id']] : 0;
  1283. }
  1284. $count = TrainClass::where($condition)->count();
  1285. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1286. }
  1287. /*
  1288. * 集团课件场景列表
  1289. */
  1290. public function groupType()
  1291. {
  1292. if (!Request::isAjax()) {
  1293. return View::fetch();
  1294. }
  1295. $param = request()->param();
  1296. $condition[] = ['root_id', '=', request()->employee->root_id];
  1297. $data = TrainType::withCount(['trainCourse' => function ($query) {
  1298. $query->where(['root_id' => request()->employee->root_id, 'delete_time' => 0]);
  1299. }])->withMax(['trainCourse' => function ($query) {
  1300. $query->where(['root_id' => request()->employee->root_id, 'delete_time' => 0]);
  1301. }], 'addtime')->where($condition)->page($param['page'], $param['limit'])->order('train_course_count desc')->select();
  1302. $count = TrainType::where($condition)->count();
  1303. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1304. }
  1305. /*
  1306. * 共享的店面
  1307. */
  1308. public function groupShareCompany()
  1309. {
  1310. if (!Request::isAjax()) {
  1311. $id = request()->param('id');
  1312. $form = request()->param('form');
  1313. view::assign('id', $id);
  1314. view::assign('form', $form);
  1315. return View::fetch();
  1316. }
  1317. $id = request()->param('id');
  1318. $page = input('page', 1);
  1319. $limit = input('limit', 10);
  1320. $data = TrainClass::with(['company'])->where('from_content_id', $id)->page($page, $limit)->select();
  1321. $count = TrainClass::with(['company'])->where('from_content_id', $id)->count();
  1322. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1323. }
  1324. /*
  1325. * 集团后台课程店面共享
  1326. */
  1327. public function groupCompanyClass()
  1328. {
  1329. if (!Request::isAjax()) {
  1330. return View::fetch();
  1331. }
  1332. $param = Request::param();
  1333. //查询店面
  1334. $companyId = Company::where('root_id', request()->employee->root_id)->value('id');
  1335. $data = Company::where('company_group', $companyId)->field('root_id,company_name,company_group')->page($param['page'], $param['limit'])->select()->toArray();
  1336. $count = Company::where('company_group', $companyId)->count();
  1337. //内容
  1338. $root_id = array_column($data, 'root_id');
  1339. $train = TrainClass::where([['root_id', 'in', $root_id], ['del', '=', 0], ['from_type', '=', 0]])->group('root_id')->column('count(id)', 'root_id');
  1340. foreach ($data as &$v) {
  1341. $v['count'] = isset($train[$v['root_id']]) ? $train[$v['root_id']] : 0;
  1342. }
  1343. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1344. }
  1345. /*
  1346. * 指派
  1347. */
  1348. public function group_assign()
  1349. {
  1350. $param = request()->param();
  1351. if (!Request::isAjax()) {
  1352. View::assign('id', $param['id']);
  1353. View::assign('from', $param['from']);
  1354. View::assign('root_id', $param['root_id']);
  1355. return View::fetch();
  1356. }
  1357. //查询店面
  1358. $page = input('page', 1);
  1359. $limit = input('limit', 10);
  1360. $id = input('id', 0); //课程id
  1361. $from = input('from'); //add指派, share共享
  1362. $class = TrainClass::where('id', $id)->find();
  1363. $companyId = Company::where('root_id', request()->employee->root_id)->value('id');
  1364. $tw = [['company_group', '=', $companyId]];
  1365. if ($from == 'share') { //排除自己共享给自己的课程
  1366. $tw[] = ['root_id', '<>', $class->root_id];
  1367. }
  1368. $data = Company::where($tw)->field('root_id,company_name')->page($page, $limit)->select();
  1369. $count = Company::where($tw)->count();
  1370. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1371. }
  1372. /*
  1373. * 批量指派共享
  1374. */
  1375. public function all_train_assign()
  1376. {
  1377. $root_id = request()->employee->root_id;
  1378. $root_ids = input('ids', ''); //指派/贡献店面id
  1379. $id = input('id', 0); //课程id
  1380. $from = input('from', '');
  1381. //指派
  1382. $eq = ($from == 'add') ? '=' : '<>';
  1383. $w[] = ['root_id', $eq, $root_id];
  1384. $w[] = ['id', '=', $id];
  1385. $w[] = ['from_type', '=', 0]; //来源类型,0自建/1集团/2其它店面
  1386. $w[] = ['from_root_id', '=', 0]; //0为自建/其它店面
  1387. $w[] = ['from_content_id', '=', 0]; //0为自建/内容id
  1388. $class = TrainClass::where($w)->find();
  1389. if (!$class) return json(['code' => 1, 'msg' => '课程不存在']);
  1390. $root_ids = explode(',', $root_ids);
  1391. if ($from == 'share') $root_ids = array_diff($root_ids, [$class->root_id]); //排除自己的课程指派给自己
  1392. //排除重复指派共享
  1393. foreach ($root_ids as $k => $v) {
  1394. $w = [];
  1395. $w[] = ['root_id', '=', $v];
  1396. $w[] = ['from_content_id', '=', $id];
  1397. $check = TrainClass::where($w)->find();
  1398. if ($check) unset($root_ids[$k]);
  1399. }
  1400. if (empty($root_ids)) return json(['code' => 1, 'msg' => '重复操作']);
  1401. $course = TrainCourse::where('id', 'in', explode(',', $class['course_id']))->column('*');
  1402. //指派
  1403. Db::startTrans();
  1404. try {
  1405. $trainNewCourseId = [];
  1406. $from = $from == 'add' ? 1 : 2;
  1407. //课件数据
  1408. foreach ($course as $val) {
  1409. $type = TrainType::where('id', $val['type_id'])->find();
  1410. $save_courses = $save_type = [];
  1411. foreach ($root_ids as $v) {
  1412. //场景
  1413. $save = [];
  1414. $save['from_type'] = $from;
  1415. $save['from_root_id'] = $type['root_id'];
  1416. $save['type'] = $type['type'];
  1417. $save['root_id'] = $v;
  1418. $check = TrainType::where($save)->find();
  1419. if ($check) {
  1420. $newTypeId = $check->id;
  1421. } else {
  1422. $newTypeId = TrainType::insertGetId($save);
  1423. }
  1424. //课件
  1425. $save = [];
  1426. $save['root_id'] = $v;
  1427. $save['title'] = $val['title'];
  1428. $save['type'] = $val['type'];
  1429. $save['content'] = $val['content'];
  1430. $save['type_id'] = $newTypeId;
  1431. $save['file'] = $val['file'];
  1432. $save['study_time'] = $val['study_time'];
  1433. $save['comment_word_num'] = $val['comment_word_num'];
  1434. $trainNewCourseId[$v][] = TrainCourse::insertGetId($save);
  1435. }
  1436. }
  1437. foreach ($root_ids as $v2) {
  1438. //课程数据
  1439. $classNewData = [];
  1440. $classNewData = [
  1441. 'root_id' => $v2,
  1442. 'title' => $class['title'],
  1443. 'des' => $class['des'],
  1444. 'cover' => $class->getData('cover'),
  1445. 'publish' => 1,
  1446. 'type' => $class['type'],
  1447. 'course_id' => implode(',', $trainNewCourseId[$v2]),
  1448. 'org_id' => '',
  1449. 'sumup_num' => $class['sumup_num'],
  1450. 'sumup_keyword' => $class['sumup_keyword'],
  1451. 'sumup_score' => $class['sumup_score'],
  1452. 'qrcode' => '',
  1453. 'category' => $class['category'],
  1454. 'train_employee' => '',
  1455. 'from_type' => $from,
  1456. 'from_root_id' => $class['root_id'],
  1457. 'from_content_id' => $class['id']
  1458. ];
  1459. TrainClass::insertGetId($classNewData);
  1460. }
  1461. Db::commit();
  1462. $msg = $from == 1 ? '指派' : '共享';
  1463. return json(['code' => 0, 'msg' => $msg . '成功']);
  1464. } catch (\Exception $e) {
  1465. Db::rollback();
  1466. return json(['code' => 1, 'msg' => $msg . '失败']);
  1467. }
  1468. }
  1469. /*
  1470. * 课程观看感悟
  1471. */
  1472. public function groupComment()
  1473. {
  1474. if (!Request::isAjax()) {
  1475. $class_id = Request::param('class_id');
  1476. View::assign('class_id', $class_id);
  1477. $data = TrainClass::with(['company'])->where('from_content_id', $class_id)->select();
  1478. View::assign('data', $data);
  1479. return View::fetch();
  1480. }
  1481. $param = Request::param();
  1482. $class_id = TrainClass::where(['from_type' => 1, 'from_content_id' => $param['class_id'], 'from_root_id' => request()->employee->root_id])->column('id');
  1483. $condition[] = [
  1484. ['class_id', 'in', $class_id],
  1485. ['course_id', '=', 0]
  1486. ];
  1487. if (isset($param['company_name_id']) && !empty($param['company_name_id'])) $condition[] = ['root_id', '=', $param['company_name_id']];
  1488. if (isset($param['keyword']) && !empty($param['keyword'])) $condition[] = ['content', 'like', '%' . $param['keyword'] . '%'];
  1489. $data = TrainSumup::with(['employee'])->where($condition)->page($param['page'], $param['limit'])->order('addtime desc')->select();
  1490. $count = TrainSumup::where($condition)->count();
  1491. $class = TrainClass::where(['id' => $param['class_id'], 'root_id' => request()->employee->root_id])->field('sumup_keyword,sumup_score')->find();
  1492. foreach ($data as &$item) {
  1493. $item['score'] = TrainSumup::sumup_score_num($class['sumup_keyword'], $class['sumup_score'], $item['content']);
  1494. }
  1495. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1496. }
  1497. /*
  1498. * 集团量化考核
  1499. */
  1500. public function groupOrgData()
  1501. {
  1502. $class_id = request()->param('class_id');
  1503. if (!Request::isAjax()) {
  1504. $data = TrainClass::with(['company'])->where('from_content_id', $class_id)->order('id desc')->select();
  1505. View::assign('data', $data);
  1506. View::assign('class_id', $class_id);
  1507. return View::fetch();
  1508. }
  1509. $param = request()->param();
  1510. //培训人
  1511. $where1 = [['from_content_id', '=', $param['class_id']]];
  1512. if (!empty($param['org_id'])) {
  1513. $where1[] = ['root_id', '=', $param['org_id']];
  1514. }
  1515. $employee_root = TrainClass::with(['company'])->where($where1)->column('root_id');
  1516. $trainNumber = Employee::where([['root_id', 'in', $employee_root], ['state', 'like', '%在职%'], ['uid', '>', 0]])->count();
  1517. //培训完
  1518. $complete_class_id = TrainClass::with(['company'])->where($where1)->column('id');
  1519. $completeCount = TrainDoneLog::where([['class_id', 'in', $complete_class_id], ['done_percent', '=', 100], ['from', '=', 0], ['root_id', 'in', $employee_root]])->count();
  1520. //写观后感人
  1521. $summaryCount = TrainSumup::where([['class_id', 'in', $complete_class_id], ['course_id', '=', 0], ['root_id', 'in', $employee_root]])->group('employee_id')->count();
  1522. //学习完成率
  1523. $studyGDP = $this->GDP($completeCount, $trainNumber);
  1524. //写观后感率
  1525. $summaryGDP = $this->GDP($summaryCount, $completeCount);
  1526. //认真完成率
  1527. $earnestGDP = $this->GDP($summaryCount, $trainNumber);
  1528. //查询有哪些部门
  1529. $orgArray = [];
  1530. foreach ($employee_root as $items) {
  1531. $org = Org::where('path', 'like', '%' . $items . '-%')->select()->toArray();
  1532. foreach ($org as $res) {
  1533. $array = ['id' => $res['id'], 'name' => $res['name']];
  1534. $orgArray[] = $array;
  1535. }
  1536. }
  1537. $orgCount = Employee::where([['root_id', 'in', $employee_root], ['state', 'like', '%在职%'], ['uid', '>', 0]])->group('org_id')->column('count(org_id)', 'org_id');
  1538. $class_success = TrainDoneLog::where([['from', '=', 0], ['root_id', 'in', $employee_root], ['class_id', 'in', $complete_class_id], ['done_percent', '=', 100]])->group('org_id')->column('count(org_id)', 'org_id');
  1539. $class_no_success = TrainDoneLog::where([['from', '=', 0], ['root_id', 'in', $employee_root], ['class_id', 'in', $complete_class_id], ['done_percent', '<', 100]])->group('org_id')->column('count(org_id)', 'org_id');
  1540. $sumup_org_id = TrainSumup::where([['root_id', 'in', $employee_root], ['class_id', 'in', $complete_class_id], ['course_id', '=', 0]])->group('org_id')->column('org_id');
  1541. $sumup = [];
  1542. foreach ($sumup_org_id as $k => $v) {
  1543. $sumup[$v] = TrainSumup::where([['org_id', '=', $v], ['class_id', 'in', $complete_class_id], ['course_id', '=', 0]])->group('employee_id')->count();
  1544. }
  1545. foreach ($orgArray as &$item) {
  1546. //学习人数
  1547. $item['trainNumber'] = isset($orgCount[$item['id']]) ? $orgCount[$item['id']] : 0;
  1548. //已学完
  1549. $item['completeCount'] = isset($class_success[$item['id']]) ? $class_success[$item['id']] : 0;
  1550. //未学完
  1551. $item['noFinishCount'] = isset($class_no_success[$item['id']]) ? $class_no_success[$item['id']] : 0;
  1552. //写观后感
  1553. $item['summaryCount'] = isset($sumup[$item['id']]) ? $sumup[$item['id']] : 0;
  1554. //学习完成率
  1555. $item['studyDGP'] = $this->GDP($item['completeCount'], $item['trainNumber']);
  1556. //观看感完成率
  1557. $item['summaryCountDGP'] = $this->GDP($item['summaryCount'], $item['completeCount']);
  1558. //认真完成率
  1559. $item['earnestDGP'] = $this->GDP($item['summaryCount'], $item['trainNumber']);
  1560. }
  1561. //查询认真率最高和最低部门
  1562. $last_data = array_column($orgArray, 'earnestDGP');
  1563. array_multisort($last_data, SORT_DESC, $orgArray);
  1564. $max_org = empty($orgArray) || $orgArray[0]['earnestDGP'] == 0 ? '暂无数据' : $orgArray[0]['name'];
  1565. array_multisort($last_data, SORT_ASC, $orgArray);
  1566. $min_org = empty($orgArray) || $orgArray[0]['earnestDGP'] == 0 ? '暂无数据' : $orgArray[0]['name'];
  1567. return json([
  1568. 'code' => 0,
  1569. 'data' => $orgArray,
  1570. 'count' => count($orgArray),
  1571. 'trainNumber' => $trainNumber,
  1572. 'completeCount' => $completeCount,
  1573. 'summaryCount' => $summaryCount,
  1574. 'studyGDP' => $studyGDP,
  1575. 'summaryGDP' => $summaryGDP,
  1576. 'earnestGDP' => $earnestGDP,
  1577. 'max_org' => $max_org,
  1578. 'min_org' => $min_org,
  1579. ]);
  1580. }
  1581. /**
  1582. * 课件浏览记录
  1583. */
  1584. public function courese_view_list()
  1585. {
  1586. $param = Request::only(['course_id' => 0, 'org_id' => 0, 'page' => 1, 'limit' => 10]);
  1587. $course_id = $param['course_id'];
  1588. $org_id = $param['org_id'];
  1589. $root_id = request()->employee->root_id;
  1590. if ($org_id) {
  1591. $eids = Employee::where([['org_id', '=', $org_id], ['root_id', '=', $root_id]])->column('id');
  1592. $w[] = ['employee_id', 'in', $eids];
  1593. }
  1594. $w[] = ['root_id', '=', $root_id];
  1595. $w[] = ['con_id', '=', $course_id];
  1596. $w[] = ['type', '=', 'traincourse'];
  1597. $list = TrainCourseView::with(['employee' => function ($query) {
  1598. $query->visible(['name', 'id'])->bind(['name']);
  1599. }])->where($w)->page($param['page'], $param['limit'])->select();
  1600. foreach ($list as $k => $v) {
  1601. $v->org_name = $v->employee->org->name ?? '';
  1602. }
  1603. $count = TrainCourseView::where($w)->count();
  1604. return json(['code' => 0, 'data' => $list, 'count' => $count]);
  1605. }
  1606. /**
  1607. * 课件浏览记录
  1608. */
  1609. public function courese_view($course_id = 0)
  1610. {
  1611. $root_id = request()->employee->root_id;
  1612. $org = Org::where([['path', 'like', $root_id . '-%']])->field('name,id')->select()->toArray();
  1613. View::assign('org', $org);
  1614. View::assign('course_id', $course_id);
  1615. return View::fetch();
  1616. }
  1617. /**
  1618. * 课程浏览记录
  1619. */
  1620. public function class_view_list()
  1621. {
  1622. $param = Request::only(['class_id' => 0, 'org_id' => 0, 'page' => 1, 'limit' => 10]);
  1623. $class_id = $param['class_id'];
  1624. $org_id = $param['org_id'];
  1625. $root_id = request()->employee->root_id;
  1626. if ($org_id) {
  1627. $eids = Employee::where([['org_id', '=', $org_id], ['root_id', '=', $root_id]])->column('id');
  1628. $w[] = ['employee_id', 'in', $eids];
  1629. }
  1630. $w[] = ['root_id', '=', $root_id];
  1631. $w[] = ['class_id', '=', $class_id];
  1632. $w[] = ['type', '=', 'traincourse'];
  1633. $list = TrainClassView::with(['employee' => function ($query) {
  1634. $query->visible(['name', 'id'])->bind(['name']);
  1635. }])->where($w)->page($param['page'], $param['limit'])->select();
  1636. foreach ($list as $k => $v) {
  1637. $v->org_name = $v->employee->org->name;
  1638. }
  1639. $count = TrainClassView::where($w)->count();
  1640. return json(['code' => 0, 'data' => $list, 'count' => $count]);
  1641. }
  1642. /**
  1643. * 课程浏览记录
  1644. */
  1645. public function class_view($class_id = 0)
  1646. {
  1647. $root_id = request()->employee->root_id;
  1648. $org = Org::where([['path', 'like', $root_id . '-%']])->field('name,id')->select()->toArray();
  1649. View::assign('org', $org);
  1650. View::assign('class_id', $class_id);
  1651. return View::fetch();
  1652. }
  1653. /**
  1654. * 分类管理
  1655. */
  1656. public function class_cate()
  1657. {
  1658. return View::fetch();
  1659. }
  1660. /**
  1661. * 分类管理列表
  1662. */
  1663. public function class_cate_list()
  1664. {
  1665. $root_id = request()->employee->root_id;
  1666. $param = Request::only(['page' => 1, 'limit' => 10]);
  1667. $w[] = ['root_id', '=', $root_id];
  1668. $w[] = ['pid', '=', 0];
  1669. $list = TrainClassCate::where($w)->page($param['page'], $param['limit'])->order(['show' => 'asc','order' => 'asc'])->select();
  1670. $count = TrainClassCate::where($w)->count();
  1671. return json(['code' => 0, 'data' => $list, 'count' => $count]);
  1672. }
  1673. /**
  1674. * 分类管理编辑
  1675. */
  1676. public function class_cate_edit()
  1677. {
  1678. $root_id = request()->employee->root_id;
  1679. $param = Request::only(['id' => 0, 'name' => '']);
  1680. $w[] = ['root_id', '=', $root_id];
  1681. $w[] = ['id', '<>', $param['id']];
  1682. $w[] = ['name', '=', $param['name']];
  1683. $w[] = ['pid', '=', 0];
  1684. $find = TrainClassCate::where($w)->findOrEmpty();
  1685. if (!$find->isEmpty()) return json(['code' => 1, 'data' => '分类已存在', 'msg' => '分类已存在']);
  1686. $name = TrainClassCate::where('id', $param['id'])->value('name');
  1687. TrainClassCate::where('id', $param['id'])->update(['name' => $param['name']]);
  1688. $w1[] = ['cate', '=', $name];
  1689. $w1[] = ['root_id', '=', $root_id];
  1690. TrainClass::where($w1)->update(['cate' => $param['name']]);
  1691. return json(['code' => 0, 'data' => '修改成功', 'msg' => '修改成功']);
  1692. }
  1693. /**
  1694. * 分类管理添加
  1695. */
  1696. public function class_cate_add()
  1697. {
  1698. $root_id = request()->employee->root_id;
  1699. $param = Request::only(['name' => '']);
  1700. $param['name'] = str_replace(' ', '', $param['name']);
  1701. $w[] = ['root_id', '=', $root_id];
  1702. $w[] = ['name', '=', $param['name']];
  1703. $find = TrainClassCate::where($w)->findOrEmpty();
  1704. if (!$find->isEmpty()) return json(['code' => 1, 'data' => '分类已存在', 'msg' => '分类已存在']);
  1705. $id = TrainClassCate::insertGetId(['root_id' => $root_id, 'name' => $param['name']]);
  1706. return json(['code' => 0, 'data' => '添加成功', 'msg' => '添加成功', 'id' => $id]);
  1707. }
  1708. /*
  1709. * 删除标签或分类前,查询关联的内容数量
  1710. */
  1711. public function with_type_count()
  1712. {
  1713. $param = Request::param();
  1714. if($param['type'] == 'cate')
  1715. {
  1716. $field = 'cate';
  1717. }else{
  1718. $field = 'label';
  1719. }
  1720. $where = [
  1721. ['root_id','=',request()->employee->root_id],
  1722. ['del','=',0],
  1723. [$field,'=',$param[$field]]
  1724. ];
  1725. $count = TrainClass::where($where)->count();
  1726. if($count > 0)
  1727. {
  1728. $type = $field == 'cate' ? '分类' : '标签' ;
  1729. $msg = '该'.$type.'关联'.$count.'个'.'课程,删除后该内容将归为其它分类。';
  1730. }else{
  1731. $msg = '确定删除该分类吗?';
  1732. }
  1733. return $msg;
  1734. }
  1735. /*
  1736. * 分类、标签删除
  1737. */
  1738. public function class_cate_or_label_del()
  1739. {
  1740. $param = Request::param();
  1741. $trainCate = TrainClassCate::where(['root_id'=>request()->employee->root_id,'id'=>$param['id']])->find();
  1742. if(empty($trainCate)) return json(['code' => 1, 'msg' => '数据不存在']);
  1743. Db::startTrans();
  1744. try {
  1745. if($param['type'] == 'cate')
  1746. {
  1747. //查询是否存在其它分类
  1748. $type_id = TrainClassCate::where(['root_id'=>request()->employee->root_id,'pid'=>0,'show'=>1])->value('id');
  1749. if(empty($type_id)) $type_id = TrainClassCate::insertGetId(['pid'=>0,'name'=>'其它','root_id'=>request()->employee->root_id,'show'=>1]);
  1750. //更新关联内容
  1751. TrainClass::where(['root_id'=>request()->employee->root_id,'cate'=>$trainCate['name']])->update(['cate'=>'其它']);
  1752. TrainClassCate::where(['root_id'=>request()->employee->root_id,'pid'=>$trainCate['id']])->update(['pid'=>$type_id]);
  1753. //去重
  1754. $groupId = TrainClassCate::where(['root_id'=>request()->employee->root_id,'pid'=>$type_id,'show'=>1])->min('id');
  1755. TrainClassCate::where([['root_id','=',request()->employee->root_id],['pid','=',$type_id],['show','=',1],['id','<>',$groupId]])->delete();
  1756. //删除分类
  1757. $trainCate->delete();
  1758. }else{
  1759. $label_id = TrainClassCate::where(['root_id'=>request()->employee->root_id,'pid'=>$trainCate['pid'],'show'=>1])->value('id');
  1760. if(empty($label_id)) $label_id = TrainClassCate::insertGetId(['pid'=>$trainCate['pid'],'name'=>'其它','root_id'=>request()->employee->root_id,'show'=>1]);
  1761. //更新关联内容
  1762. TrainClass::where(['root_id'=>request()->employee->root_id,'label'=>$trainCate['name']])->update(['label'=>'其它']);
  1763. //删除分类
  1764. $trainCate->delete();
  1765. }
  1766. Db::commit();
  1767. return json(['code' => 0, 'msg' => '删除成功']);
  1768. } catch (\Exception $e) {
  1769. Db::rollback();
  1770. return json(['code' => 1, 'msg' => '删除失败']);
  1771. }
  1772. }
  1773. /**
  1774. * 课程培训标签管理
  1775. */
  1776. public function class_label()
  1777. {
  1778. return View::fetch();
  1779. }
  1780. /**
  1781. * 标签管理列表
  1782. */
  1783. public function class_label_list()
  1784. {
  1785. $root_id = request()->employee->root_id;
  1786. $param = Request::only(['page' => 1, 'limit' => 10]);
  1787. $w[] = ['root_id', '=', $root_id];
  1788. $w[] = ['pid', '>', 0];
  1789. $list = TrainClassCate::where($w)->page($param['page'], $param['limit'])->order(['show'=>'asc','id'=>'desc'])->select();
  1790. if (!$list->isEmpty()) {
  1791. $w1[] = ['root_id', '=', $root_id];
  1792. $w1[] = ['pid', '=', 0];
  1793. $cates = TrainClassCate::where($w1)->column('name', 'id');
  1794. foreach ($list as $k => $v) {
  1795. $v->pname = isset($cates[$v->pid]) ? $cates[$v->pid] : '';
  1796. }
  1797. }
  1798. $count = TrainClassCate::where($w)->count();
  1799. return json(['code' => 0, 'data' => $list, 'count' => $count]);
  1800. }
  1801. /**
  1802. * 标签管理编辑
  1803. */
  1804. public function class_label_edit()
  1805. {
  1806. $root_id = request()->employee->root_id;
  1807. $param = Request::only(['id' => 0, 'name' => '', 'pid' => 0]);
  1808. $param['name'] = str_replace(' ', '', $param['name']);
  1809. $w[] = ['root_id', '=', $root_id];
  1810. $w[] = ['id', '<>', $param['id']];
  1811. $w[] = ['name', '=', $param['name']];
  1812. $w[] = ['pid', '>', 0];
  1813. $find = TrainClassCate::where($w)->findOrEmpty();
  1814. if (!$find->isEmpty()) return json(['code' => 1, 'data' => '分类已存在', 'msg' => '分类已存在']);
  1815. $name = TrainClassCate::where('id', $param['id'])->value('name');
  1816. TrainClassCate::where('id', $param['id'])->update(['name' => $param['name']]);
  1817. $w1[] = ['label', '=', $name];
  1818. $w1[] = ['root_id', '=', $root_id];
  1819. TrainClass::where($w1)->update(['label' => $param['name']]);
  1820. return json(['code' => 0, 'data' => '修改成功', 'msg' => '修改成功']);
  1821. }
  1822. /**
  1823. * 分类管理添加页面
  1824. */
  1825. public function class_label_add()
  1826. {
  1827. $root_id = request()->employee->root_id;
  1828. $w[] = ['root_id', '=', $root_id];
  1829. $w[] = ['pid', '=', 0];
  1830. $cate = TrainClassCate::where($w)->order('id desc')->select();
  1831. View::assign('cate', $cate);
  1832. return View::fetch();
  1833. }
  1834. /**
  1835. * 标签管理添加
  1836. */
  1837. public function class_label_add_ajax()
  1838. {
  1839. $root_id = request()->employee->root_id;
  1840. $param = Request::only(['name' => '', 'pid' => 0]);
  1841. $param['name'] = str_replace(' ', '', $param['name']);
  1842. $w[] = ['root_id', '=', $root_id];
  1843. $w[] = ['name', '=', $param['name']];
  1844. $w[] = ['pid', '=', $param['pid']];
  1845. $find = TrainClassCate::where($w)->findOrEmpty();
  1846. if (!$find->isEmpty()) return json(['code' => 1, 'data' => '标签已存在', 'msg' => '标签已存在']);
  1847. $id = TrainClassCate::insertGetId(['root_id' => $root_id, 'name' => $param['name'], 'pid' => $param['pid']]);
  1848. return json(['code' => 0, 'data' => '添加成功', 'msg' => '添加成功', 'id' => $id]);
  1849. }
  1850. //学分设置
  1851. public function credit_setting()
  1852. {
  1853. $request = request();
  1854. $type=$request->param('type');
  1855. $where[] = ['code', '=', 'studytime_credit'];
  1856. $where[] = ['root_id', '=', $request->employee->root_id];
  1857. $time_study=CreditsSetting::where($where)->field('status,value')->find();
  1858. $data['studytime_credit'] = !empty($time_study['value']) ? json_decode($time_study['value'], true) : ['numtime' => 0, 'time_credit' => 0];
  1859. $data['studytime_status']=!empty($time_study)?$time_study['status']:1;
  1860. $where3[] = ['code', '=', 'studyday_maxcredit'];
  1861. $where3[] = ['root_id', '=', $request->employee->root_id];
  1862. $maxcredit = CreditsSetting::where($where3)->field('status,value')->find();
  1863. $data['studyday_maxcredit'] = !empty($maxcredit['value'])?$maxcredit['value']:0;
  1864. $data['studyday_status'] = !empty($maxcredit)?$maxcredit['status']:1;
  1865. $where4[] = ['code', '=', 'studyfeeling_credit'];
  1866. $where4[] = ['root_id', '=', $request->employee->root_id];
  1867. $person2 = CreditsSetting::where($where4)->field('status,value')->find();
  1868. $data['studyfeeling_credit'] = !empty($person2['value'])?$person2['value']:0;
  1869. $data['studyfeeling_status'] = !empty($person2)?$person2['status']:1;
  1870. View::assign('data', $data);
  1871. return View::fetch();
  1872. }
  1873. //设置学分
  1874. public function reward_credit_save()
  1875. {
  1876. $request = request();
  1877. $param = Request::only(['numtime','time_credit','max_credit','howday','feeling_credit','studytime_status','studyday_status','studyfeeling_status']);
  1878. // var_dump($param);
  1879. // exit;
  1880. if($param['studytime_status']==2 && ($param['numtime']==0 || $param['time_credit']==0)){
  1881. return json(['code' => 1, 'msg' => '设置学习时长不能有0值']);
  1882. }if($param['studyday_status']==2 && $param['max_credit']==0){
  1883. return json(['code' => 1, 'msg' => '设置一天可得学分不能为0']);
  1884. }if($param['studyfeeling_status']==2 && $param['feeling_credit']==0){
  1885. return json(['code' => 1, 'msg' => '设置感悟学分不能为0']);
  1886. }
  1887. if ($param['studytime_status']==2 && isset($param['numtime']) && isset($param['time_credit'])) {
  1888. $json = json_encode(['numtime' => $param['numtime'], 'time_credit' => $param['time_credit']]);
  1889. credits($request->employee->root_id, $json, 'studytime_credit', 0); //贡献值
  1890. }
  1891. if ($param['studyday_status']==2 && isset($param['max_credit'])) {
  1892. credits($request->employee->root_id, $param['max_credit'], 'studyday_maxcredit', 0); //积分
  1893. }
  1894. if ($param['studyfeeling_status']==2 && isset($param['feeling_credit'])) {
  1895. credits($request->employee->root_id, $param['feeling_credit'], 'studyfeeling_credit', 0); //积分
  1896. }
  1897. return json(['code' => 0, 'msg' => '保存成功']);
  1898. }
  1899. //修改学分开启关闭
  1900. public function up_credit_status()
  1901. {
  1902. $request = request();
  1903. $param = Request::only(['code']);
  1904. $arr=['studyfeeling_credit','studyday_maxcredit','studycourse_credit','studytime_credit'];
  1905. if(!in_array($param['code'],$arr)) return json(['code' => 1, 'msg' => '参数错误']);
  1906. $ms=CreditsSetting::where([['root_id', '=', $request->employee->root_id],['code', '=', $param['code']]])->find();
  1907. $tips=1;
  1908. if(!empty($ms)){
  1909. $tips=$ms['status'];
  1910. $ms->status=!empty($ms['status'])?0:1;
  1911. $ms->save();
  1912. }
  1913. if($tips==1){
  1914. return json(['code' => 0, 'msg' => '开启成功']);
  1915. }else{
  1916. return json(['code' => 0, 'msg' => '关闭成功']);
  1917. }
  1918. }
  1919. /**
  1920. * root_id 被复制的店面id
  1921. *
  1922. * new_root_id 新添加数据的店面
  1923. */
  1924. public function addData($root_id=0,$new_root_id=0)
  1925. {
  1926. //train_class train_class_cate fl_train_type fl_train_course
  1927. if (!$root_id || !$new_root_id) {
  1928. return false;
  1929. }
  1930. // TrainClassCate
  1931. // TrainType
  1932. // TrainCourse
  1933. // TrainClass
  1934. $where[] = ['root_id','=',$root_id];
  1935. $query[] = ['root_id','=',$new_root_id];
  1936. // $train_type = TrainType::where($where)->field('type,'.' '.$new_root_id.' as root_id')->select()->toArray();
  1937. $train_type = TrainType::where($where)->column('type');
  1938. //去重
  1939. $j_type = TrainType::where($query)->column('type');
  1940. $new_type = array_diff($train_type,$j_type);
  1941. $type = [];
  1942. foreach ($new_type as $v) {
  1943. $type[] = [
  1944. 'root_id'=>$new_root_id,
  1945. 'type' => $v
  1946. ];
  1947. }
  1948. TrainType::InsertAll($type);
  1949. //TrainClassCate
  1950. $train_class_cate = TrainClassCate::where($where)->column('id,pid,name');
  1951. $cate = [];
  1952. foreach ($train_class_cate as $v1) {
  1953. if ($v1['pid']==0) {
  1954. $cate[$v1['name']] = [];
  1955. foreach ($train_class_cate as $v2) {
  1956. if($v1['id']==$v2['pid']) $cate[$v1['name']][] = $v2['name'];
  1957. }
  1958. }
  1959. }
  1960. foreach ($cate as $k3 => $v3) {
  1961. $where_cate = [];
  1962. $where_cate[] = ['root_id','=',$new_root_id];
  1963. $where_cate[] = ['name','=',$k3];
  1964. $where_cate[] = ['pid','=',0];
  1965. $check = TrainClassCate::where($where_cate)->findOrEmpty();
  1966. unset($where_cate);
  1967. if ($check->isEmpty()) {
  1968. $pid = TrainClassCate::InsertGetId([
  1969. 'root_id' => $new_root_id,
  1970. 'name' => $k3,
  1971. 'pid' => 0
  1972. ]);
  1973. }else{
  1974. $pid = $check->id;
  1975. }
  1976. //二级分类
  1977. foreach ($v3 as $k4 => $v4) {
  1978. $where_cate2 = [];
  1979. $where_cate2[] = ['pid','=',$pid];
  1980. $where_cate2[] = ['name','=',$v4];
  1981. $where_cate2[] = ['root_id','=',$new_root_id];
  1982. $check2 = TrainClassCate::where($where_cate2)->findOrEmpty();
  1983. unset($where_cate2);
  1984. if ($check2->isEmpty()) {
  1985. TrainClassCate::Insert([
  1986. 'root_id' => $new_root_id,
  1987. 'name' => $v4,
  1988. 'pid' => $pid
  1989. ]);
  1990. }
  1991. }
  1992. }
  1993. //TrainClass
  1994. $train_class = TrainClass::where($where)->column('*');
  1995. foreach ($train_class as $k6 => $v6) {
  1996. unset($train_class[$k6]['id']);
  1997. $train_class[$k6]['addtime'] = date('Y-m-d H:i:s');
  1998. $train_class[$k6]['root_id'] = $new_root_id;
  1999. $train_class[$k6]['course_id'] = '';
  2000. if ($v6['course_id']) {
  2001. $train_class[$k6]['course_id'] = $this->course($v6['course_id'],$new_root_id);
  2002. }
  2003. $train_class[$k6]['qrcode'] = '';
  2004. $train_class[$k6]['org_id'] = '';
  2005. $train_class[$k6]['train_employee'] = '';
  2006. }
  2007. TrainClass::insertAll($train_class);
  2008. return 1;
  2009. }
  2010. public function course($ids,$new_root_id){
  2011. $ids = explode(',',$ids);
  2012. // TrainCourse
  2013. $where[] = ['id','in',$ids];
  2014. $train_course = TrainCourse::where($where)->column('*');
  2015. foreach ($train_course as $k5 => $v5) {
  2016. unset($train_course[$k5]['id']);
  2017. //type_id
  2018. $name = TrainType::where('id',$v5['type_id'])->value('type');
  2019. $train_course_where = [];
  2020. $train_course_where[] = ['type','=',$name];
  2021. $train_course_where[] = ['root_id','=',$new_root_id];
  2022. $train_course[$k5]['type_id'] = TrainType::where($train_course_where)->value('id');
  2023. unset($train_course_where);
  2024. $train_course[$k5]['root_id'] = $new_root_id;
  2025. $train_course[$k5]['addtime'] = date('Y-m-d H:i:s');
  2026. }
  2027. $id = [];
  2028. foreach ($train_course as $v) {
  2029. $id[] = TrainCourse::insertGetId($v);
  2030. }
  2031. return implode(',',$id);
  2032. }
  2033. }