Todo.php 35 KB

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