Todo.php 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057
  1. <?php
  2. namespace app\common\model;
  3. use app\common\util\AppMsg;
  4. use app\hander\HelpHander;
  5. use think\Db;
  6. use think\Exception;
  7. class Todo extends Base
  8. {
  9. public $table = 'todo';
  10. public function formatTodo($v){
  11. $v['order_type'] = '';
  12. $v['order_type_matter'] = '';
  13. $v['address_title'] = '';
  14. $v['repair_priority'] = '';
  15. if($v['work_type_mode']==1){
  16. $typeInfo = (new \app\common\model\OrderType())
  17. ->getTypeByOrderId($v['order_id']);
  18. $v['order_type'] = isset($typeInfo['title'])?$typeInfo['title']:'';
  19. $v['order_type_matter'] = isset($typeInfo['child_title'])?$typeInfo['child_title']:'';
  20. $v['address_title'] = isset($typeInfo['address_title'])?$typeInfo['address_title']:'';
  21. $v['repair_priority'] = isset($typeInfo['repair_priority'])?$typeInfo['repair_priority']:'';
  22. $v['bx_sign'] = Db::name('todo')->where('id',$v['id'])->value('sign');
  23. }
  24. $v['work_type_mode_text'] = $this->getTableField('work_type_mode', ['id'=>$v['work_type_mode']], 'name');
  25. $v['real_name'] = $this->getTableField('user',['id'=>$v['create_user_id']],'real_name');
  26. $v['pause_cost'] = '';
  27. if(!empty($v['pause_time']) && !empty($v['pause_end']) && $v['todo_mode']==3){
  28. if(!empty($v['confirm_time'])){
  29. $v['time_cost'] = $this->getM1($v['done_time'],$v['confirm_time'],$v['pause_end'],$v['pause_time']);
  30. }else{
  31. $v['time_cost'] = '';
  32. }
  33. $v['pause_cost'] = $this->getM($v['pause_time'],$v['pause_end']);
  34. }else{
  35. $v['time_cost'] = $v['todo_mode']==3 && !empty($v['confirm_time'])?$this->getM($v['done_time'],$v['confirm_time']):'';
  36. }
  37. $pDep = '';
  38. $depInfo = Db::name('dep')
  39. ->where('id',$v['dep_id'])
  40. ->find();
  41. if($depInfo){
  42. $pDep = Db::name('dep_cate')
  43. ->where('id',$depInfo['cate_id'])
  44. ->value('title');
  45. }
  46. $v['dep_cate_name'] = $pDep;
  47. $v['source_type_text'] =$v['from']>0? isset(model('Orders')->source_type[$v['from']])?model('Orders')->source_type[$v['from']]:'':$this->getTableField('work_type_mode', ['id' => $v['work_type_mode']], 'name');
  48. $v['dispatch_time'] = $this->getM($v['to_create_time'],$v['create_time']);
  49. $v['jiedan_time'] = !empty($v['confirm_time'])?$this->getM($v['confirm_time'],$v['to_create_time']):'';
  50. $orderInfo = Db::name('orders')
  51. ->where('id',$v['order_id'])
  52. ->find();
  53. $v['dep'] = $this->getTableField('dep', ['id'=>$orderInfo['dep_id']], 'title');
  54. $v['order_info'] = model('orders')->formatOrder($orderInfo,1);
  55. if($v['work_type_mode']==3){
  56. $oc = Db::name('order_convey')
  57. ->where('order_id',$v['order_id'])
  58. ->find();
  59. $oc['type_name']=$v['type_name'] = isset($oc['type'])?$this->getTableField('convey_cate',['id'=>$oc['type']],'title'):"";
  60. $oc['start_name']=$v['start_name'] = isset($oc['start'])?$this->getTableField('address',['id'=>$oc['start']],'title'):"";
  61. $oc['end_name'] =$v['end_name'] =isset($oc['end'])?$this->getTableField('address',['id'=>$oc['end']],'title'):'';
  62. $oc['device_name']= $v['device_name'] = isset($oc['device_id'])?$this->getTableField('convey_device',['id'=>$oc['device_id']],'title'):'';
  63. $v['xq_time'] = isset($oc['xq_time'])?$oc['xq_time']:'';
  64. $v['ywc_time'] = isset($oc['ywc_time'])?$oc['ywc_time']:"";
  65. $v['oc'] = $oc;
  66. $v['ocp'] = [];
  67. $cate = isset($oc['type'])?$this->getTableField('convey_cate',['id'=>$oc['type']],'cate'):'';
  68. if($cate==1){
  69. $ocp = Db::name('order_convey_patient')
  70. ->where('order_id',$v['order_id'])
  71. ->find();
  72. $v['ocp'] = $ocp;
  73. }
  74. }
  75. $pauseList = [];
  76. if($v['todo_mode']==2 && $v['pause']==1){
  77. $ll = Db::name('todo_puase')
  78. ->where('todo_id',$v['id'])
  79. ->select();
  80. foreach ($ll as $pp=>$dd) {
  81. $pauseList[$pp]['content'] = $dd['reason'];
  82. $pauseList[$pp]['timestamp'] = $dd['create_time'];
  83. $pauseList[$pp]['color'] ='#0bbd87';
  84. }
  85. }
  86. $v['pauseList'] = $pauseList;
  87. return $v;
  88. }
  89. public function newFormatTodo($v){
  90. $v['order_type'] = '';
  91. $v['order_type_matter'] = '';
  92. $v['address_title'] = '';
  93. $v['repair_priority'] = '';
  94. if($v['work_type_mode']==1){
  95. $typeInfo = (new \app\common\model\OrderType())
  96. ->getTypeByOrderId($v['order_id']);
  97. $v['order_type'] = isset($typeInfo['title'])?$typeInfo['title']:'';
  98. $v['order_type_matter'] = isset($typeInfo['child_title'])?$typeInfo['child_title']:'';
  99. $v['address_title'] = isset($typeInfo['address_title'])?$typeInfo['address_title']:'';
  100. $v['repair_priority'] = isset($typeInfo['repair_priority'])?$typeInfo['repair_priority']:'';
  101. $v['bx_sign'] = Db::name('todo')->where('id',$v['id'])->value('sign');
  102. }
  103. $v['work_type_mode_text'] = $this->getTableField('work_type_mode', ['id'=>$v['work_type_mode']], 'name');
  104. $v['real_name'] = $this->getTableField('user',['id'=>$v['create_user_id']],'real_name');
  105. $v['pause_cost'] = '';
  106. if(!empty($v['pause_time']) && !empty($v['pause_end']) && $v['todo_mode']==3){
  107. if(!empty($v['confirm_time'])){
  108. $v['time_cost'] = $this->getM1($v['done_time'],$v['confirm_time'],$v['pause_end'],$v['pause_time']);
  109. }else{
  110. $v['time_cost'] = '';
  111. }
  112. $v['pause_cost'] = $this->getM($v['pause_time'],$v['pause_end']);
  113. }else{
  114. $v['time_cost'] = $v['todo_mode']==3 && !empty($v['confirm_time'])?$this->getM($v['done_time'],$v['confirm_time']):'';
  115. }
  116. $pDep = '';
  117. $depInfo = Db::name('dep')
  118. ->where('id',$v['dep_id'])
  119. ->find();
  120. if($depInfo){
  121. $pDep = Db::name('dep_cate')
  122. ->where('id',$depInfo['cate_id'])
  123. ->value('title');
  124. }
  125. $v['dep_cate_name'] = $pDep;
  126. $v['source_type_text'] =$v['from']>0? isset(model('Orders')->source_type[$v['from']])?model('Orders')->source_type[$v['from']]:'':$this->getTableField('work_type_mode', ['id' => $v['work_type_mode']], 'name');
  127. $v['dispatch_time'] = $this->getM($v['to_create_time'],$v['create_time']);
  128. $v['jiedan_time'] = !empty($v['confirm_time'])?$this->getM($v['confirm_time'],$v['to_create_time']):'';
  129. $orderInfo = Db::name('orders')
  130. ->where('id',$v['order_id'])
  131. ->find();
  132. $v['dep'] = $this->getTableField('dep', ['id'=>$orderInfo['dep_id']], 'title');
  133. if($v['work_type_mode']==3){
  134. $oc = Db::name('order_convey')
  135. ->where('order_id',$v['order_id'])
  136. ->find();
  137. $oc['type_name']=$v['type_name'] = isset($oc['type'])?$this->getTableField('convey_cate',['id'=>$oc['type']],'title'):"";
  138. $oc['start_name']=$v['start_name'] = isset($oc['start'])?$this->getTableField('address',['id'=>$oc['start']],'title'):"";
  139. $oc['end_name'] =$v['end_name'] =isset($oc['end'])?$this->getTableField('address',['id'=>$oc['end']],'title'):'';
  140. $oc['device_name']= $v['device_name'] = isset($oc['device_id'])?$this->getTableField('convey_device',['id'=>$oc['device_id']],'title'):'';
  141. $v['xq_time'] = isset($oc['xq_time'])?$oc['xq_time']:'';
  142. $v['ywc_time'] = isset($oc['ywc_time'])?$oc['ywc_time']:"";
  143. $v['oc'] = $oc;
  144. $v['ocp'] = [];
  145. $cate = isset($oc['type'])?$this->getTableField('convey_cate',['id'=>$oc['type']],'cate'):'';
  146. if($cate==1){
  147. $ocp = Db::name('order_convey_patient')
  148. ->where('order_id',$v['order_id'])
  149. ->find();
  150. $v['ocp'] = $ocp;
  151. }
  152. }
  153. // $pauseList = [];
  154. // if($v['todo_mode']==2 && $v['pause']==1){
  155. // $ll = Db::name('todo_puase')
  156. // ->where('todo_id',$v['id'])
  157. // ->select();
  158. // foreach ($ll as $pp=>$dd) {
  159. // $pauseList[$pp]['content'] = $dd['reason'];
  160. // $pauseList[$pp]['timestamp'] = $dd['create_time'];
  161. // $pauseList[$pp]['color'] ='#0bbd87';
  162. // }
  163. // }
  164. // $v['pauseList'] = $pauseList;
  165. return $v;
  166. }
  167. public function apiFormatTodo($v){
  168. $v['work_type_mode_text'] = $this->getTableField('work_type_mode', ['id'=>$v['work_type_mode']], 'name');
  169. $v['todo_mode_text'] = $this->getTableField('todo_mode', ['id'=>$v['todo_mode']], 'out_content');
  170. $v['real_name'] = $this->getTableField('user',['id'=>$v['to_user_id']],'real_name');
  171. $v['time_cost'] = $v['todo_mode']==3 && !empty($v['confirm_time'])?$this->getM($v['done_time'],$v['confirm_time']):'';
  172. $v['confirm_time'] = $v['confirm_time']?$v['confirm_time']:"";
  173. $v['done_time'] = $v['done_time']?$v['done_time']:"";
  174. $orderInfo = Db::name('orders')
  175. ->where('id',$v['order_id'])
  176. ->find();
  177. $v['dep'] = $this->getTableField('dep', ['id'=>$orderInfo['dep_id']], 'title');
  178. return $v;
  179. }
  180. public function getM($do,$cof){
  181. $diff = strtotime($do) - strtotime($cof);
  182. $days = floor(($diff )/ (60*60*24));
  183. $hours = floor(($diff - $days*60*60*24) / (60*60));
  184. $minutes = floor(($diff - $days*60*60*24 - $hours*60*60)/ 60);
  185. $seconds = floor(($diff - $days*60*60*24 - $hours*60*60 - $minutes*60));
  186. if ($diff < 60) {
  187. $time_cost = $seconds."秒";
  188. } else if ($diff >= 60 && $diff < 60*60) {
  189. $time_cost = $minutes."分钟".$seconds."秒";
  190. } else if ($diff >= 60*60 && $diff < 60*60*24) {
  191. $time_cost = $hours."小时".$minutes."分钟".$seconds."秒";
  192. } else {
  193. $time_cost = $days."天".$hours."小时".$minutes."分钟".$seconds."秒";
  194. }
  195. return $time_cost;
  196. }
  197. public function getM1($do,$cof,$e,$a){
  198. $diff = strtotime($do) - strtotime($cof);
  199. $aa = strtotime($e) - strtotime($a);
  200. $diff = $diff-$aa;
  201. $days = floor(($diff )/ (60*60*24));
  202. $hours = floor(($diff - $days*60*60*24) / (60*60));
  203. $minutes = floor(($diff - $days*60*60*24 - $hours*60*60)/ 60);
  204. $seconds = floor(($diff - $days*60*60*24 - $hours*60*60 - $minutes*60));
  205. if ($diff < 60) {
  206. $time_cost = $seconds."秒";
  207. } else if ($diff >= 60 && $diff < 60*60) {
  208. $time_cost = $minutes."分钟".$seconds."秒";
  209. } else if ($diff >= 60*60 && $diff < 60*60*24) {
  210. $time_cost = $hours."小时".$minutes."分钟".$seconds."秒";
  211. } else {
  212. $time_cost = $days."天".$hours."小时".$minutes."分钟".$seconds."秒";
  213. }
  214. return $time_cost;
  215. }
  216. // 检查工单状态变化后续的操作
  217. public function checkToDo($orderId,$todoId,$todoMode){
  218. $list = Db::name('todo')
  219. ->where('todo_mode','in',array(1,2,4))
  220. ->where('order_id',$orderId)
  221. ->where('id','<>',$todoId)
  222. ->where('del',0)
  223. ->field('todo_mode')
  224. ->select();
  225. $todoInfo = Db::name('todo')
  226. ->where('id',$todoId)
  227. ->find();
  228. Db::name('task')
  229. ->where('bus_id', $todoId)
  230. ->where('user_id', $todoInfo['to_user_id'])
  231. ->where('type', 1)
  232. ->delete();
  233. if($list){
  234. return true; //不需要修改
  235. }
  236. if($todoMode == 3){ // 完成
  237. $res = Db::name('orders')
  238. ->where('id',$orderId)->update([
  239. 'order_mode' => 5,
  240. 'finish_time' => date('Y-m-d H:i:s')
  241. ]);
  242. if(!$res){
  243. return false;
  244. }
  245. $this->finishTodoPush($orderId,$todoId);
  246. return true;
  247. }else if ($todoMode==5){//无法完成
  248. $check = Db::name('todo')
  249. ->where('todo_mode',3)
  250. ->where('order_id',$orderId)
  251. ->where('id','<>',$todoId)
  252. ->field('todo_mode')
  253. ->find();
  254. if($check){
  255. $res = Db::name('orders')
  256. ->where('id',$orderId)->update([
  257. 'order_mode' => 5,
  258. 'finish_time' => date('Y-m-d H:i:s')
  259. ]);
  260. if($res){
  261. $this->finishTodoPush($orderId,$todoId);
  262. return true;
  263. }
  264. return false;
  265. }else{
  266. $res = Db::name('orders')
  267. ->where('id',$orderId)
  268. ->update(['order_mode'=>7,'update_time'=>getTime()]);
  269. if($res){
  270. return true;
  271. }
  272. return false;
  273. }
  274. } else { //取消
  275. $res = Db::name('orders')
  276. ->where('id',$orderId)->update([
  277. 'order_mode' =>3,
  278. ]);
  279. return $res?true:false;
  280. }
  281. }
  282. public function finishTodoPush($orderId,$todoId){
  283. $todoInfo = Db::name('todo')
  284. ->where('id',$todoId)
  285. ->find();
  286. // 投诉完成推送
  287. model('Complain')->pushCreateUser($orderId,0);
  288. // 是病人运送订单且需要收费时需要生成,缴费单
  289. // 检查运送收费开发是否开启
  290. $ysoff = model('Config')->getConfig('org_ys_switch',$todoInfo['org_id']);
  291. $money1 = model('Config')->getConfig('org_ys_init_money',$todoInfo['org_id']);
  292. $money2 = model('Config')->getConfig('org_ys_lj_money',$todoInfo['org_id']);
  293. $money1 = $money1?$money1:0;
  294. $money2 = $money2?$money2:0;
  295. if($ysoff){
  296. // 检查订单是不是病人运送
  297. $convey = Db::name('order_convey')
  298. ->alias('a')
  299. ->join('convey_cate b','a.type = b.id')
  300. ->where('a.order_id',$orderId)
  301. ->where('b.cate',1)
  302. ->field('a.*')
  303. ->find();
  304. if($convey){
  305. $count = Db::name('order_convey_end')->where('order_convey_id',$convey['id'])->count();
  306. $money = round($money1 + $count*$money2,2);
  307. if($money > 0){
  308. $ret = Db::name('order_convey_pay')->insert([
  309. 'sn' => get_unique_id('YS'),
  310. 'org_id' => $todoInfo['org_id'],
  311. 'order_id' => $convey['order_id'],
  312. 'order_convey_id' => $convey['id'],
  313. 'money' => $money,
  314. 'status' => 0,
  315. 'create_time' => date('Y-m-d H:i:s'),
  316. 'type' => 0
  317. ]);
  318. if(!$ret){
  319. return false;
  320. }
  321. }
  322. }
  323. }
  324. }
  325. public function cancel($id,$reason){
  326. $info = $this->where('id',$id)->find();
  327. if (!$info) {
  328. $this->error='工单不存在';
  329. return false;
  330. }
  331. if (!in_array($info['todo_mode'], array(1, 2, 4))) {
  332. $this->error='此状态不能取消工单';
  333. return false;
  334. }
  335. $this->startTrans();
  336. try {
  337. if ($info['todo_mode'] == 1 || $info['todo_mode'] == 2) {
  338. $mode = 6;
  339. } else {
  340. $mode = 7;
  341. }
  342. $ret = $this->where('id', $id)->update(['todo_mode'=>$mode,'cancel_reason'=>$reason]);
  343. if (!$ret) {
  344. exception('工单状态修改失败');
  345. }
  346. $ret = $this->checktodo($info['order_id'],$id,6);
  347. if(!$ret){
  348. exception('订单修改失败');
  349. }
  350. $this->commit();
  351. return true;
  352. } catch (Exception $e) {
  353. $this->rollback();
  354. $this->error=$e->getMessage();
  355. return false;
  356. }
  357. }
  358. public function finish($id){
  359. $info = $this->where('id',$id)->find();
  360. if (!$info) {
  361. $this->error='工单不存在';
  362. return false;
  363. }
  364. if (!in_array($info['todo_mode'], array(1, 2))) {
  365. $this->error='此状态不能完成工单';
  366. return false;
  367. }
  368. $this->startTrans();
  369. try {
  370. $curTime = date('Y-m-d H:i:s');
  371. $cfTime = $info['confirm_time'];
  372. $sData = array(
  373. 'todo_mode' => 3,
  374. 'done_time' => $curTime,
  375. );
  376. if($info['todo_mode'] == 1){
  377. $cfTime = $sData['confirm_time'] = $info['create_time'];
  378. }
  379. $wc_time = time() - strtotime($cfTime);
  380. $sData['wc_time'] = $cfTime?$wc_time:0;
  381. $ret = $this->where('id',$id)->update($sData);
  382. if(!$ret){
  383. exception('操作失败');
  384. }
  385. $ret = $this->checktodo($info['order_id'],$info['id'],3);
  386. if(!$ret){
  387. exception('订单修改失败');
  388. }
  389. $this->commit();
  390. return true;
  391. } catch (Exception $e) {
  392. $this->rollback();
  393. $this->error=$e->getMessage();
  394. return false;
  395. }
  396. }
  397. //后台重新分配
  398. public function send($id,$userId,$data){
  399. $info = Db::name('todo_view')->where('id',$id)->find();
  400. if(!$info||$info['org_id']!=$data['org_id']){
  401. $this->error='订单不存在';
  402. return false;
  403. }
  404. if(!in_array($info['todo_mode'],array(4))){
  405. $this->error='此状态不能重新下发任务';
  406. return false;
  407. }
  408. if($info['order_mode'] != 4){
  409. $this->error='订单已完成不能重新下发任务';
  410. return false;
  411. }
  412. if(!isset($data['to_user_id'])||empty($data['to_user_id'])){
  413. $this->error='请选择执行人';
  414. return false;
  415. }
  416. $send_user_num = (new Orders())->sendUserNum($info['work_type_mode'],$data['org_id']);
  417. $users = explode(',', $data['to_user_id']);
  418. if($send_user_num==1 && count($users) >1){
  419. $this->error = '执行人只能选择单人';
  420. return false;
  421. }
  422. $to_user_id = array_unique($users);
  423. $todo = array();
  424. $this->startTrans();
  425. try{
  426. //todo::订单状态暂时不做修改
  427. //取消驳回的订单
  428. $res = $this
  429. ->where('id',$id)->update(['todo_mode'=>7]);
  430. if(!$res){
  431. exception('订单状态更改失败');
  432. }
  433. $todoData = [
  434. 'order_id' => $info['order_id'],
  435. 'todo_content' => $data['todo_content'],
  436. 'create_user_id' => $userId,
  437. 'org_id' => $data['org_id'],
  438. 'create_time' => getTime(),
  439. 'todo_mode' => 1,
  440. 'work_type_mode' => $info['work_type_mode'],
  441. 'create_yyyy' => date('Y'),
  442. 'create_yyyymm' => date('Ym'),
  443. 'create_yyyymmdd' => date('Ymd'),
  444. ];
  445. $taskData=[
  446. 'org_id'=>$data['org_id'],
  447. 'type'=>1,
  448. 'start_time'=>getTime(),
  449. 'create_time'=>getTime(),
  450. ];
  451. $pusharr =[];
  452. $sns = [];
  453. foreach ($to_user_id as $k => $v) {
  454. if(empty($v)){
  455. continue;
  456. }
  457. $todoData['to_user_id'] = $v;
  458. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  459. while (true){
  460. if(in_array($todoData['sn'],$sns)){
  461. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  462. }else{
  463. $sns[] = $todoData['sn'];
  464. break;
  465. }
  466. }
  467. $res = Db::name('todo')
  468. ->insertGetId($todoData);
  469. if (!$res){
  470. \exception('执行人:'.$v.'派单失败');
  471. }
  472. $taskData['user_id'] = $v;
  473. $taskData['bus_id'] = $res;
  474. $res = Db::name('task')
  475. ->insert($taskData);
  476. if (!$res){
  477. \exception('执行人:'.$v.'任务保存失败');
  478. }
  479. $pusharr[] = [
  480. 'user_id'=>$v,
  481. 'todo_id'=>$res
  482. ];
  483. }
  484. $res = Db::name('orders')->where('id',$info['order_id'])
  485. ->update(['order_mode'=>4,'send_time'=>getTime()]);
  486. if (!$res){
  487. \exception('订单更新失败');
  488. }
  489. if($info['work_type_mode']==1){//报修订单
  490. $rData = [];
  491. if(isset($data['type_id']) && !empty($data['type_id'])){
  492. $rData['type_id'] = $data['type_id'];
  493. }
  494. if(isset($data['address_id']) && !empty($data['address_id'])){
  495. $rData['address_id'] = $data['address_id'];
  496. }
  497. if(!empty($rData)){
  498. $rData['order_id'] = $info['order_id'];
  499. Db::name('order_repair')
  500. ->where('order_id',$info['order_id'])->delete();
  501. $res = Db::name('order_repair')
  502. ->insert($rData);
  503. if(!$res){
  504. \exception('保存维修扩展失败');
  505. }
  506. }
  507. }
  508. $this->commit();
  509. if($pusharr){
  510. foreach ($pusharr as $k=>$v){
  511. // 极光推送
  512. send_jpush([$v['user_id']],AppMsg::PUSH_WORKER_ORDER_SEND,'',['id'=>$v['todo_id']]);
  513. }
  514. }
  515. return true;
  516. }catch (Exception $e){
  517. $this->rollback();
  518. $this->error=$e->getMessage();
  519. return false;
  520. }
  521. }
  522. //api 工单列表
  523. public function lists($page,$size,$userId,$orgId,$type){
  524. $offset = ($page-1)*$size;
  525. if($type==1){//已完成
  526. $map[] = ['org_id','=',$orgId];
  527. $map[] = ['del','=',0];
  528. $map[] = ['to_user_id','=',$userId];
  529. $map[] = ['todo_mode','=',3];
  530. $list = $this->where($map)
  531. ->limit($offset,$size)
  532. ->order('id','desc')
  533. ->select();
  534. $list = $list?$list->toArray():[];
  535. }else if ($type==2){//已评价
  536. $list = Db::name('todo')
  537. ->alias('a')
  538. ->join('orders b','b.id=a.order_id','left')
  539. ->where('a.to_user_id',$userId)
  540. ->where('a.del',0)
  541. ->where('b.del',0)
  542. ->where('a.org_id',$orgId)
  543. ->where('b.order_mode',6)
  544. ->field('a.*')
  545. ->order('a.id','desc')
  546. ->limit($offset,$size)
  547. ->select();
  548. }else if ($type==0){//所有
  549. $list = Db::name('todo')
  550. ->alias('a')
  551. ->join('orders b','b.id=a.order_id','left')
  552. ->where('a.to_user_id',$userId)
  553. ->where('a.del',0)
  554. ->where('b.del',0)
  555. ->where('a.org_id',$orgId)
  556. ->where(function ($query){
  557. $query->where('a.todo_mode', 3)->whereor('b.order_mode', 6);
  558. })
  559. ->field('a.*')
  560. ->order('a.id','desc')
  561. ->limit($offset,$size)
  562. ->select();
  563. }
  564. $n = [];
  565. foreach ($list as $k=>$v){
  566. $a= $this->apiFormatTodo($v);
  567. $n[] = formatArray(
  568. [
  569. 'id',
  570. 'confirm_time',
  571. 'done_time',
  572. 'work_type_mode',
  573. 'sn'
  574. ]
  575. , $a);
  576. }
  577. return $n;
  578. }
  579. //api工单详情
  580. public function apiDetail($todoId){
  581. $info = Db::name('todo_view')->where('id',$todoId)
  582. ->find();
  583. if(empty($info)){
  584. HelpHander::error('工单信息不存在');
  585. }
  586. $order = Db::name('orders')
  587. ->where('id',$info['order_id'])
  588. ->find();
  589. $orderInfo = (new Orders())->apiFormatOrder($order,1,$todoId);
  590. if($order['work_type_mode'] == 3){
  591. // 地点路径
  592. $conveyends = Db::name('order_convey_end')
  593. ->alias('a')
  594. ->join('address b','b.id = a.addr')
  595. ->where('a.order_id',$order['id'])
  596. ->order('a.id asc')
  597. ->field('a.id,a.addr,b.title,a.scan,a.create_time,a.update_time')
  598. ->select();
  599. $orderInfo['ends'] = $conveyends?$conveyends:[];
  600. $payinfo = [
  601. 'is_pay' => 0,
  602. 'id' => 0,
  603. 'url' => '',
  604. 'money' => 0,
  605. 'remark' => '',
  606. 'type' => 1,
  607. 'pay_time' => '',
  608. ];
  609. // 是否需要支付
  610. $pay = Db::name('order_convey_pay')->where('order_id',$order['id'])->find();
  611. if($pay){
  612. $payinfo['is_pay'] = $pay['status'] == 0?0:1;
  613. $payinfo['url'] = url('h5/Index/pay',['id'=>$pay['id']],false,true);
  614. $payinfo['money'] = round($pay['money'],2);
  615. $payinfo['remark'] = $pay['remark'];
  616. $payinfo['pay_time'] = $pay['pay_time']?$pay['pay_time']:'';
  617. $payinfo['id'] = $pay['id'];
  618. }
  619. $orderInfo['pay'] = $payinfo;
  620. }
  621. return $orderInfo;
  622. }
  623. //处理驳回订单
  624. public function createNtbo($todoId,$toUserIdArray,$todoContent,$userId,$typeId,$addressId){
  625. $todo=$this
  626. ->where('id',$todoId)->find();
  627. if(!$todo || $todo['del'] == 1){
  628. $this->error = '工单不存在';
  629. return false;
  630. }
  631. if($todo['todo_mode'] != 4){
  632. $this->error = '无权限分配订单';
  633. return false;
  634. }
  635. if(!isset($toUserIdArray)||empty($toUserIdArray)){
  636. $this->error='请选择执行人';
  637. return false;
  638. }
  639. $send_user_num = (new Orders())->sendUserNum($todo['work_type_mode'],$todo['org_id']);
  640. $users = explode(',', $toUserIdArray);
  641. if($send_user_num==1 && count($users) >1){
  642. $this->error = '执行人只能选择单人';
  643. return false;
  644. }
  645. $to_user_id = array_unique($users);
  646. $this->startTrans();
  647. try{
  648. $res = $this
  649. ->where('id',$todoId)->update(['todo_mode'=>7]);
  650. if(!$res){
  651. \exception('订单状态更改失败');
  652. }
  653. if($todo['work_type_mode']==1){//报修订单
  654. $rData = [];
  655. if(!empty($typeId) && $typeId>0 ){
  656. $rData['type_id'] =$typeId;
  657. }
  658. if(!empty($addressId) && $addressId>0){
  659. $rData['address_id'] = $addressId;
  660. }
  661. if(!empty($rData)){
  662. $rData['order_id'] = $todo['order_id'];
  663. Db::name('order_repair')
  664. ->where('order_id',$todo['order_id'])->delete();
  665. $res = Db::name('order_repair')
  666. ->insert($rData);
  667. if(!$res){
  668. \exception('保存维修扩展失败');
  669. }
  670. }
  671. }
  672. $todoData = [
  673. 'order_id' => $todo['order_id'],
  674. 'todo_content' => $todoContent,
  675. 'create_user_id' => $userId,
  676. 'org_id' => $todo['org_id'],
  677. 'create_time' => getTime(),
  678. 'todo_mode' => 1,
  679. 'work_type_mode' => $todo['work_type_mode'],
  680. 'create_yyyy' => date('Y'),
  681. 'create_yyyymm' => date('Ym'),
  682. 'create_yyyymmdd' => date('Ymd'),
  683. ];
  684. $taskData=[
  685. 'org_id'=>$todo['org_id'],
  686. 'type'=>1,
  687. 'start_time'=>getTime(),
  688. 'create_time'=>getTime(),
  689. ];
  690. $sns = [];
  691. foreach ($to_user_id as $k => $v) {
  692. if(empty($v)){
  693. continue;
  694. }
  695. $todoData['to_user_id'] = $v;
  696. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  697. while (true){
  698. if(in_array($todoData['sn'],$sns)){
  699. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  700. }else{
  701. $sns[] = $todoData['sn'];
  702. break;
  703. }
  704. }
  705. $res = Db::name('todo')
  706. ->insertGetId($todoData);
  707. if (!$res){
  708. \exception('执行人:'.$v.'派单失败');
  709. }
  710. $taskData['user_id'] = $v;
  711. $taskData['bus_id'] = $res;
  712. $res = Db::name('task')
  713. ->insert($taskData);
  714. if (!$res){
  715. \exception('执行人:'.$v.'任务保存失败');
  716. }
  717. // 极光推送
  718. send_jpush([$v],AppMsg::PUSH_WORKER_ORDER_SEND,'',['id'=>$res]);
  719. }
  720. $this->commit();
  721. return true;
  722. }catch (Exception $e){
  723. $this->rollback();
  724. return false;
  725. }
  726. }
  727. //修改工单状态 4 驳回 5客观原因
  728. public function updateState($todoId,$todoMode,$nodoReason,$userId,$rejectVoice){
  729. $todo = $this
  730. ->where('id',$todoId)
  731. ->where('del',0)
  732. ->find();
  733. if(!$todo){
  734. $this->error = '工单不存在';
  735. return false;
  736. }
  737. if($todoMode == 4){ // 驳回
  738. if($todo['todo_mode']!==1){
  739. $this->error = '当前状态不能驳回';
  740. return false;
  741. }
  742. $this->startTrans();
  743. try{
  744. $ret = $this
  745. ->where('id',$todoId)
  746. ->update(['todo_mode'=>$todoMode,
  747. 'nodo_reason'=>$nodoReason,
  748. 'reject_voice'=>$rejectVoice,
  749. 'reject_time' => date('Y-m-d H:i:s')]);
  750. if(!$ret){
  751. \exception('操作失败');
  752. }
  753. Db::name('task')
  754. ->where('org_id',$todo['org_id'])
  755. ->where('user_id',$userId)
  756. ->where('type',1)
  757. ->where('bus_id',$todoId)
  758. ->delete();
  759. $this->commit();
  760. }catch (Exception $e){
  761. $this->rollback();
  762. $this->error = $e->getMessage();
  763. return false;
  764. }
  765. }else if($todoMode == 2){
  766. if($todo['todo_mode']!==1){
  767. $this->error = '当前状态不能领取';
  768. return false;
  769. }
  770. $XY_TIME = time() - strtotime($todo['create_time']);
  771. $ret = $this->where('id',$todoId)->update([
  772. 'todo_mode'=>$todoMode,
  773. 'confirm_time' => date('Y-m-d H:i:s'),
  774. 'xy_time' => $XY_TIME
  775. ]);
  776. // $todoIds = Db::name('todo')
  777. // ->where('id','<>',$todoId)
  778. // ->where('order_id','=',$todo['order_id'])
  779. // ->column('id');
  780. // if(!empty($todoIds)){
  781. // $r = Db::name('todo')
  782. // ->where('id','in',$todoIds)
  783. // ->delete();
  784. // Db::name('task')
  785. // ->where('bus_id', 'in', $todoIds)
  786. // ->where('type', 1)
  787. // ->delete();
  788. // if(!$r){
  789. // $this->error = '操作失败';
  790. // return false;
  791. // }
  792. // }
  793. if(!$ret){
  794. $this->error = '操作失败';
  795. return false;
  796. }
  797. }else if($todoMode == 6){ // 取消驳回工单
  798. $this->startTrans();
  799. try{
  800. $ret = $this
  801. ->where('id',$todoId)
  802. ->update(['todo_mode'=>$todoMode,
  803. 'cancel_reason' => $nodoReason]);
  804. if(!$ret){
  805. \exception('订单错误失败');
  806. }
  807. $ret = $this->checkToDo($todo['order_id'],$todoId,$todoMode);
  808. if(!$ret){
  809. \exception('订单修改失败');
  810. }
  811. Db::name('task')
  812. ->where('org_id',$todo['org_id'])
  813. ->where('user_id',$userId)
  814. ->where('type',1)
  815. ->where('bus_id',$todoId)
  816. ->delete();
  817. $this->commit();
  818. }catch (Exception $e){
  819. $this->rollback();
  820. $this->error = $e->getMessage();
  821. return false;
  822. }
  823. }
  824. return true;
  825. }
  826. // 工人完成提交任务/无法完成
  827. public function finishTodo($todoId,$todoMode,$content,$userId,$images,$consItems,$sign){
  828. $todo = $this
  829. ->where('id',$todoId)
  830. ->where('del',0)->find();
  831. if(!$todo){
  832. $this->error = '工单不存在';
  833. return false;
  834. }
  835. if($todo['to_user_id'] != $userId || $todo['todo_mode'] != 2){
  836. $this->error = '无权限操作';
  837. return false;
  838. }
  839. if($todo['work_type_mode']== 1 && $todo['todo_mode'] == 2 && $todo['pause'] == 1){
  840. $this->error = '工单正在挂起,无法完成';
  841. return false;
  842. }
  843. if($todo['work_type_mode']==1 && $todoMode==3){
  844. $off =(new Config())->getConfig('org_sign',$todo['org_id']);
  845. if($off==1 && empty($sign)){
  846. $this->error = '请上传签名';
  847. return false;
  848. }
  849. }
  850. $this->startTrans();
  851. try{
  852. if($todo['pause'] == 2){
  853. $ct = strtotime($todo['confirm_time']);
  854. $pst = strtotime($todo['pause_time']);
  855. $pet = strtotime($todo['pause_end']);
  856. $WC_TIME = ($pst - $ct) + time()-$pet;
  857. }else{
  858. $WC_TIME = time() - strtotime($todo['confirm_time']);
  859. }
  860. $curTime = date('Y-m-d H:i:s');
  861. $ret = $this
  862. ->where('id',$todoId)->update([
  863. 'nodo_reason' => $content,
  864. 'images' => $images,
  865. 'todo_mode' => $todoMode,
  866. 'done_time' => $curTime,
  867. 'wc_time' => $WC_TIME,
  868. 'sign' => $sign
  869. ]);
  870. if(!$ret){
  871. \exception('工单修改失败');
  872. }
  873. if($todoMode == 3 && $consItems){ // 工单完成且有耗材
  874. $consItems = json_decode($consItems,true);
  875. $mate = [
  876. 'todo_id'=>$todoId,
  877. 'order_id'=>$todo['order_id'],
  878. 'org_id'=>$todo['org_id'],
  879. 'user_id'=>$userId,
  880. 'create_time'=>getTime()
  881. ];
  882. $todo_mate_id = Db::name('todo_mate')
  883. ->insertGetId($mate);
  884. if(!$todo_mate_id){
  885. \exception('订单使用物品记录失败');
  886. }
  887. $items = [];
  888. foreach ($consItems as $k=>$v){
  889. $itemInfo = Db::name('mate_goods')
  890. ->where('id',$v['itemsId'])
  891. ->find();
  892. if($itemInfo['nums'] < $v['total']){
  893. \exception($itemInfo['title'].' 库存不足');
  894. }
  895. $items[] = [
  896. 'todo_mate_id'=>$todo_mate_id,
  897. 'items_id'=>$v['itemsId'],
  898. 'total'=>$v['total'],
  899. 'create_time'=>getTime(),
  900. 'user_id'=>$userId,
  901. 'money'=>$itemInfo['price'],
  902. 'total_money'=>$itemInfo['price']*$v['total'],
  903. ];
  904. $res = Db::name('mate_goods')
  905. ->where('id',$v['itemsId'])
  906. ->setDec('nums',$v['total']);
  907. if(!$res){
  908. \exception($itemInfo['title'].' 数量修改失败');
  909. }
  910. }
  911. $res = Db::name('todo_mate_item')
  912. ->insertAll($items);
  913. if(!$res){
  914. \exception('物品使用记录失败');
  915. }
  916. }
  917. $ret = $this->checkToDo($todo['order_id'],$todoId,$todoMode);
  918. Db::name('task')
  919. ->where('bus_id', '=', $todoId)
  920. ->where('type', 1)
  921. ->delete();
  922. if(!$ret){
  923. \exception('订单修改失败');
  924. }
  925. $this->commit();
  926. }catch (Exception $e){
  927. $this->error = $e->getMessage();
  928. $this->rollback();
  929. return false;
  930. }
  931. return true;
  932. }
  933. //获取物品列表
  934. public function getMateGoods($orgId,$userId,$title,$page,$size){
  935. $map[] = ['org_id','=',$orgId];
  936. $map[] = ['enable','=',1];
  937. $map[] = ['del','=',0];
  938. if($title){
  939. $map[] = ['title','like','%'.$title.'%'];
  940. }
  941. $offset = ($page-1)*$size;
  942. $list = (new MateGoods())->getList($offset,$size,$map,'id desc');
  943. $a = [];
  944. foreach ($list as $k=>$v){
  945. $user_cons = Db::name('user_cons')
  946. ->where('user_id',$userId)
  947. ->where('goods_id',$v['id'])
  948. ->find();
  949. $v['is_fav'] = $user_cons?1:0;
  950. $a[] = formatArray([
  951. 'id','price','nums','title','spec','is_fav'
  952. ],$v);
  953. }
  954. return $a;
  955. }
  956. //收藏/取消收藏
  957. public function favGoods($userId,$type,$goodsId){
  958. if($type==0){
  959. $res = Db::name('user_cons')
  960. ->where('goods_id',$goodsId)
  961. ->where('user_id',$userId)
  962. ->delete();
  963. }else{
  964. if(Db::name('user_cons')
  965. ->where('goods_id',$goodsId)
  966. ->where('user_id',$userId)->find()){
  967. HelpHander::error('该物品已收藏');
  968. }
  969. $res = Db::name('user_cons')
  970. ->insertGetId([
  971. 'goods_id'=>$goodsId,
  972. 'user_id'=>$userId,
  973. ]);
  974. }
  975. return $res;
  976. }
  977. //收藏物品列表
  978. public function favList($userId,$title){
  979. if($title){
  980. $map[] = ['b.title','like','%'.$title.'%'];
  981. }
  982. $map[] = ['a.user_id','=',$userId];
  983. $map[] = ['b.enable','=',1];
  984. $map[] = ['b.del','=',0];
  985. $list = Db::name('user_cons')
  986. ->alias('a')
  987. ->join('mate_goods b','a.goods_id = b.id')
  988. ->where($map)
  989. ->order('a.id desc')
  990. ->field('b.*')
  991. ->select();
  992. $a = [];
  993. foreach ($list as $k=>$v){
  994. $a[] = formatArray([
  995. 'id','price','nums','title','spec',
  996. ],$v);
  997. }
  998. return $a;
  999. }
  1000. }