Todo.php 40 KB

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