ServiceOrderLogic.php 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. <?php
  2. namespace app\api\logic;
  3. use app\adminapi\service\DistributeLeafletsService;
  4. use app\common\enum\GoodsEnum;
  5. use app\common\enum\PayEnum;
  6. use app\common\enum\WorkEnum;
  7. use app\common\logic\BaseLogic;
  8. use app\common\logic\PaymentLogic;
  9. use app\common\model\coupon\UserCoupon;
  10. use app\common\model\dict\DictData;
  11. use app\common\model\goods\Goods;
  12. use app\common\model\master_worker\MasterWorker;
  13. use app\common\model\master_worker\MasterWorkerRule;
  14. use app\common\model\orders\RechargeOrder;
  15. use app\common\model\recharge\OrderGoods;
  16. use app\common\model\refund\RefundRecord;
  17. use app\common\model\spare_part\SparePart;
  18. use app\common\model\works\ServiceWork;
  19. use app\common\model\works\ServiceWorkAppointmentLog;
  20. use app\common\model\works\ServiceWorkSpare;
  21. use app\workerapi\logic\ServiceWorkLogLogic;
  22. use think\Exception;
  23. use think\facade\Db;
  24. /**
  25. * 订单逻辑层
  26. * Class ServiceOrderLogic
  27. * @package app\api\logic
  28. */
  29. class ServiceOrderLogic extends BaseLogic
  30. {
  31. /**
  32. * 判断是否在某服务区
  33. * @param $params
  34. * @return bool
  35. */
  36. public static function isService($params)
  37. {
  38. // 查询服务区所有的地点
  39. $rules = MasterWorkerRule::where('scene_id',MasterWorkerRule::SCENE_SERVICE)->column('description','id');
  40. //$masters = [];
  41. foreach ($rules as $key=>$value){
  42. $rule = explode(',',$value);
  43. //$masters[] = ['id'=>$key,'lon'=>$rule[0],'lat'=>$rule[1],'radius'=>$rule[2]];
  44. $distance = round(DistributeLeafletsService::haversineDistance($params['lat'], $params['lon'], $rule[1], $rule[0]), 2);
  45. if($distance <= (float)$rule[2]){
  46. return true;
  47. }
  48. }
  49. self::setError('已超出服务区域!');
  50. return false;
  51. }
  52. /**
  53. * 提交订单
  54. * @param array $params
  55. * @return array|false
  56. */
  57. public static function submitOrder($params)
  58. {
  59. Db::startTrans();
  60. try {
  61. // 订单位置是否在服务区内
  62. if(!self::isService($params)){
  63. throw new Exception('已超出服务区域!');
  64. }
  65. $goods = Goods::findOrEmpty($params['goods_id']);
  66. if($goods->isEmpty()){
  67. throw new Exception('产品不存在!');
  68. }
  69. if(empty($params['user_info']['mobile'])){
  70. throw new Exception('请先补充您的联系方式后在提交订单');
  71. }
  72. //根据服务工单计算当前订单应支付金额
  73. if($goods['goods_payment_type'] == GoodsEnum::ISGOODS_PAYMENT_TYPE){
  74. //一口价订单
  75. $order_total = $goods['service_fee'];
  76. $order_amount = $goods['service_fee'];
  77. }else if ($goods['goods_payment_type'] == GoodsEnum::DEP_GOODS_PAYMENT_TYPE){
  78. $order_total = $goods['service_fee'];
  79. $order_amount = $goods['service_fee'];
  80. }
  81. else{
  82. $order_total = $goods['base_service_fee'];
  83. $order_amount = $goods['service_fee'];
  84. }
  85. //优惠券验证
  86. if(!empty($params['coupon_id'])){
  87. $user_coupon = UserCoupon::where(['id'=>$params['coupon_id'],'user_id'=>$params['user_id'],'voucher_status'=>0])
  88. ->where('voucher_count','>',0)
  89. ->where('expire_time','>=',time())
  90. ->where('begin_use','<',time())
  91. ->findOrEmpty();
  92. if($user_coupon->isEmpty()){
  93. throw new Exception('该优惠券无法使用');
  94. }
  95. if($goods['goods_payment_type'] == GoodsEnum::ISGOODS_PAYMENT_TYPE and $order_amount<$user_coupon['amount_require']){
  96. throw new Exception('该优惠劵不满足满减使用条件');
  97. }
  98. if($goods['goods_payment_type'] != GoodsEnum::ISGOODS_PAYMENT_TYPE){
  99. throw new Exception('请在支付尾款的时候使用该优惠券');
  100. }
  101. //优惠券折扣
  102. if($user_coupon['mold_type'] == 1){
  103. //按比例折扣
  104. if($user_coupon['discount_ratio']>=1){
  105. throw new Exception('优惠券有误,请联系客服');
  106. }
  107. $order_coupon_amount = $order_amount*(1-$user_coupon['discount_ratio']);
  108. }else{
  109. $order_coupon_amount = $user_coupon['amount'];
  110. }
  111. if(!empty($user_coupon['max_deductible_price'])){
  112. $order_amount = ($order_coupon_amount>$user_coupon['max_deductible_price'])?($order_amount-$user_coupon['max_deductible_price']):($order_amount-$order_coupon_amount);
  113. }else{
  114. $order_amount = $order_amount-$order_coupon_amount;
  115. }
  116. $user_coupon->voucher_status = 1;
  117. $user_coupon->voucher_count = $user_coupon->voucher_count-1;
  118. $user_coupon->save();
  119. }
  120. //生成服务工单
  121. $work_data = [
  122. 'work_sn' => generate_sn(ServiceWork::class, 'work_sn'),
  123. 'real_name' => $params['contact_people'],
  124. 'mobile' => $params['contact_number'],
  125. 'address' => $params['address'],
  126. 'title' => $goods->goods_name . '*' . $goods->goods_number.$goods->good_unit,
  127. 'category_type' => $goods['category_type'],
  128. 'goods_category_ids' => $goods['goods_category_ids'],
  129. 'goods_category_id' => $goods['goods_category_id'],
  130. 'base_service_fee' => $goods['base_service_fee'],
  131. 'service_fee' => $goods['service_fee'],
  132. 'work_pay_status'=>WorkEnum::UN_PAY_STATUS,
  133. 'appointment_time' => strtotime($params['appointment_time']),
  134. 'user_id'=>$params['user_id'],
  135. 'lon'=>!empty($params['lon'])?$params['lon']:0,
  136. 'lat'=>!empty($params['lat'])?$params['lat']:0,
  137. ];
  138. //判断是否是加单
  139. if(!empty($params['worker'])){
  140. $worker_id = MasterWorker::where('worker_number',$params['worker'])->value('id');
  141. $work_data['master_worker_id'] = $worker_id;
  142. $work_data['work_status'] = 1;
  143. $work_data['dispatch_time'] = time();
  144. $work_data['work_type'] = 2;
  145. }
  146. $service_work = ServiceWork::create($work_data);
  147. //生成服务订单
  148. $data = [
  149. 'work_id'=> $service_work['id'],
  150. 'sn' => generate_sn(RechargeOrder::class, 'sn'),
  151. 'order_type'=>0,//服务订单
  152. 'order_terminal' => $params['terminal'],
  153. 'payment_type'=>$goods['goods_payment_type']==GoodsEnum::ISGOODS_PAYMENT_TYPE?0:1,
  154. 'user_id' => $params['user_id'],
  155. 'pay_status' => PayEnum::UNPAID,
  156. 'coupon_id'=>!empty($params['coupon_id'])?$params['coupon_id']:0,
  157. 'coupon_price'=>!empty($order_coupon_amount)?$order_coupon_amount:0,
  158. 'pay_way' => $params['pay_way'],
  159. 'order_total' => $order_total,
  160. 'order_amount' => $order_amount,
  161. ];
  162. $order = RechargeOrder::create($data);
  163. //生成订单服务详情
  164. OrderGoods::create([
  165. 'sn' => $order['sn'],
  166. 'goods_id' => $params['goods_id'],
  167. 'category_type' => $goods['category_type'],
  168. 'goods_category_ids' => $goods['goods_category_ids'],
  169. 'goods_category_id' => $goods['goods_category_id'],
  170. 'goods_name' => $goods['goods_name'],
  171. 'goods_image' => $goods['goods_image'],
  172. 'goods_video' => $goods['goods_video'],
  173. 'goods_number' => $goods['goods_number'],
  174. 'good_unit' => $goods['good_unit'],
  175. 'goods_size' => $goods['goods_size'],
  176. 'goods_type' => $goods['goods_type'],
  177. 'goods_brand' => $goods['goods_brand'],
  178. 'install_guide' => $goods['install_guide'],
  179. 'goods_payment_type'=>$goods['goods_payment_type'],
  180. 'base_service_fee' => $goods['base_service_fee'],
  181. 'service_total' => $goods['service_total'],
  182. 'service_fee' => $goods['service_fee'],
  183. 'service_image' => $goods['service_image'],
  184. 'warranty_period'=>$goods['warranty_period'],
  185. 'fee_schedule' => $goods['fee_schedule'],
  186. 'goods_status' => $goods['goods_status'],
  187. ]);
  188. Db::commit();
  189. } catch (\Exception $e) {
  190. self::setError($e->getMessage());
  191. return false;
  192. }
  193. return [
  194. 'order_id' => (int)$order['id'],
  195. 'work_id' => (int)$order['work_id'],
  196. ];
  197. }
  198. /**
  199. * 提交尾款订单
  200. * @param array $params
  201. * @return array|false
  202. */
  203. public static function submitFinalOrder($params)
  204. {
  205. Db::startTrans();
  206. try {
  207. $order = \app\common\model\recharge\RechargeOrder::where('sn',$params['sn'])->findOrEmpty();
  208. if ($order->isEmpty()) {
  209. throw new Exception('订单不存在');
  210. }
  211. //判断订单类型.服务订单尾款处理
  212. if($order['order_type'] == 0 and $order['pay_status'] == PayEnum::ISPAID)//服务工单
  213. {
  214. $order = RechargeOrder::where(['work_id'=>$order['work_id'],'pay_status'=>0])->findOrEmpty();
  215. if($order->isEmpty()){
  216. throw new Exception('订单已支付');
  217. }
  218. }
  219. if ($order['pay_status'] == PayEnum::ISPAID) {
  220. throw new Exception('订单已支付');
  221. }
  222. $order_goods = OrderGoods::where('sn',$params['sn'])->findOrEmpty();
  223. $goods = Goods::findOrEmpty($order_goods['goods_id']);
  224. //判断是否存在优惠券
  225. //优惠券验证
  226. if(!empty($order['coupon_id'])){
  227. $order->coupon_id = 0;
  228. $order->coupon_price = 0;
  229. $order->order_amount = $order->order_total;
  230. $order->save();
  231. $user_coupon_ed = UserCoupon::findOrEmpty($order['coupon_id']);
  232. $user_coupon_ed->voucher_count = $user_coupon_ed->voucher_count+1;
  233. $user_coupon_ed->voucher_status = 0;
  234. $user_coupon_ed->save();
  235. $order = \app\common\model\recharge\RechargeOrder::where('sn',$order['sn'])->findOrEmpty();
  236. }
  237. if(!empty($params['coupon_id']) && empty($order['coupon_id'])){
  238. $user_coupon = UserCoupon::where(['id'=>$params['coupon_id'],'user_id'=>$params['user_id'],'voucher_status'=>0])
  239. ->where('voucher_count','>',0)
  240. ->where('expire_time','>=',time())
  241. ->where('begin_use','<',time())
  242. ->findOrEmpty();
  243. if($user_coupon->isEmpty()){
  244. throw new Exception('该优惠券无法使用');
  245. }
  246. if($goods['goods_payment_type'] == GoodsEnum::ISGOODS_PAYMENT_TYPE and $order['order_amount']<$user_coupon['amount_require']){
  247. throw new Exception('该优惠劵不满足满减使用条件');
  248. }
  249. //优惠券折扣
  250. if($user_coupon['mold_type'] == 1){
  251. //按比例折扣
  252. if($user_coupon['discount_ratio']>=1){
  253. throw new Exception('优惠券有误,请联系客服');
  254. }
  255. $order_coupon_amount = $order['order_amount']*(1-$user_coupon['discount_ratio']);
  256. }else{
  257. $order_coupon_amount = $user_coupon['amount'];
  258. }
  259. if(!empty($user_coupon['max_deductible_price'])){
  260. $order_amount = ($order_coupon_amount>$user_coupon['max_deductible_price'])?($order['order_amount']-$user_coupon['max_deductible_price']):($order['order_amount']-$order_coupon_amount);
  261. }else{
  262. $order_amount = $order['order_amount']-$order_coupon_amount;
  263. }
  264. $user_coupon->voucher_status = 1;
  265. $user_coupon->voucher_count = $user_coupon->voucher_count-1;
  266. $user_coupon->save();
  267. }
  268. $order->coupon_id = !empty($params['coupon_id'])?$params['coupon_id']:0;
  269. $order->coupon_price = !empty($order_coupon_amount)?$order_coupon_amount:0;
  270. $order->order_amount = !empty($order_amount)?$order_amount:$order->order_amount;
  271. $order->save();
  272. Db::commit();
  273. } catch (\Exception $e) {
  274. self::setError($e->getMessage());
  275. return false;
  276. }
  277. return [
  278. 'order_id' => (int)$order['id'],
  279. 'work_id' => (int)$order['work_id'],
  280. ];
  281. }
  282. /**
  283. * 重置订单优惠券
  284. * * @param $params
  285. * * * @return array|false
  286. */
  287. public static function cancelOrderCoupon($params)
  288. {
  289. Db::startTrans();
  290. try {
  291. $order = \app\common\model\recharge\RechargeOrder::where('sn',$params['sn'])->findOrEmpty();
  292. if ($order->isEmpty()) {
  293. throw new Exception('订单不存在');
  294. }
  295. //判断订单类型.服务订单尾款处理
  296. if($order['order_type'] == 0 and $order['pay_status'] == PayEnum::ISPAID)//服务工单
  297. {
  298. $order = RechargeOrder::where(['work_id'=>$order['work_id'],'pay_status'=>0])->findOrEmpty();
  299. if($order->isEmpty()){
  300. throw new Exception('订单已支付');
  301. }
  302. }
  303. if ($order['pay_status'] == PayEnum::ISPAID) {
  304. throw new Exception('订单已支付');
  305. }
  306. if(!empty($order['coupon_id'])){
  307. $user_coupon_ed = UserCoupon::findOrEmpty($order['coupon_id']);
  308. if(!$user_coupon_ed->isEmpty()){
  309. $user_coupon_ed->voucher_count = $user_coupon_ed->voucher_count+1;
  310. $user_coupon_ed->voucher_status = 0;
  311. $user_coupon_ed->save();
  312. $order->order_amount = $order->order_amount+$order->coupon_price;
  313. $order->coupon_id = 0;
  314. $order->coupon_price = 0;
  315. $order->save();
  316. }
  317. }
  318. Db::commit();
  319. } catch (\Exception $e) {
  320. self::setError($e->getMessage());
  321. return false;
  322. }
  323. }
  324. /**
  325. * 获取订单工程师信息
  326. * * @param $params
  327. * * @return array|false
  328. */
  329. public static function getMasterWorker($params)
  330. {
  331. try {
  332. $order_info = \app\common\model\recharge\RechargeOrder::with(['order_goods'=>function ($query) {
  333. $query->visible(['goods_name','goods_image','goods_number','good_unit']);
  334. },'service_work'=>function ($query) {
  335. $query->visible(['real_name','mobile','address','service_status','appointment_time','master_worker_id','work_images','finished_images','finished_time'])->append(['service_status_text','user_service_status','user_service_status_text']);
  336. }])
  337. ->visible(['id','sn','payment_type','order_total','order_amount','pay_status','create_time','title','work_id'])
  338. ->where([
  339. 'order_type' => 0,
  340. 'user_id' => $params['user_id'],
  341. 'sn'=>$params['sn']
  342. ])->findOrEmpty()->toArray();
  343. $data = [];
  344. //获取工程师参数
  345. if(!empty($order_info['service_work']['master_worker_id'])){
  346. $worker = MasterWorker::find($order_info['service_work']['master_worker_id']);
  347. $data['avatar'] = $worker['avatar'];
  348. $data['real_name'] = $worker['real_name'];
  349. $data['worker_number'] = $worker['worker_number'];
  350. $data['mobile'] = $worker['mobile'];
  351. $maintain_exp_type = !empty($worker->worker_register->maintain_exp_type)?$worker->worker_register->maintain_exp_type:'';
  352. $data['worker_exp'] = DictData::where(['type_value'=>'worker_exp_type','value'=>$maintain_exp_type])->value('name');
  353. $data['appointment_time'] = $order_info['service_work']['appointment_time'];
  354. }
  355. return $data;
  356. }
  357. catch (\Exception $e) {
  358. self::setError($e->getMessage());
  359. return false;
  360. }
  361. }
  362. /**
  363. * 获取订单详情
  364. * @param $params
  365. * @return array|false
  366. */
  367. public static function detail($params)
  368. {
  369. try {
  370. $order_info = \app\common\model\recharge\RechargeOrder::with(['order_goods'=>function ($query) {
  371. $query->visible(['goods_name','goods_image','goods_number','good_unit']);
  372. },'service_work'=>function ($query) {
  373. $query->visible(['work_sn','real_name','mobile','address','service_status','appointment_time','master_worker_id','work_images','finished_images','finished_time','spare_total','service_work_spare_id'])->append(['service_status_text','user_service_status','user_service_status_text']);
  374. }])
  375. ->visible(['id','sn','payment_type','order_total','order_amount','paid_amount','pay_status','create_time','title','work_id'])
  376. ->where([
  377. 'order_type' => 0,
  378. 'user_id' => $params['user_id'],
  379. 'sn'=>$params['sn']
  380. ])->findOrEmpty()->toArray();
  381. if(empty($order_info)){
  382. throw new Exception('订单不存在');
  383. }
  384. $order_info['master_worker'] = [
  385. 'avatar' => '',
  386. 'real_name'=>'',
  387. 'worker_number'=>'',
  388. 'mobile'=>'',
  389. 'worker_exp'=>''
  390. ];
  391. //查询总价
  392. $order_info['order_amount'] = \app\common\model\recharge\RechargeOrder::where(['order_type'=>0,'user_id'=>$params['user_id'],'work_id'=>$order_info['work_id']])->sum('order_amount');
  393. $order_info['paid_amount'] = \app\common\model\recharge\RechargeOrder::where(['order_type'=>0,'user_id'=>$params['user_id'],'work_id'=>$order_info['work_id']])->sum('paid_amount');
  394. //退款金额
  395. $order_refund_amount = 0;
  396. //获取工程师参数
  397. if(!empty($order_info['service_work']['master_worker_id'])){
  398. $worker = MasterWorker::find($order_info['service_work']['master_worker_id']);
  399. $order_info['master_worker']['avatar'] = !empty($worker)?$worker['avatar']:'';
  400. $order_info['master_worker']['real_name'] = !empty($worker)?$worker['real_name']:'';
  401. $order_info['master_worker']['worker_number'] = !empty($worker)?$worker['worker_number']:'';
  402. $order_info['master_worker']['mobile'] = !empty($worker)?$worker['mobile']:'';
  403. $maintain_exp_type = !empty($worker->worker_register->maintain_exp_type)?$worker->worker_register->maintain_exp_type:'';
  404. $order_info['master_worker']['worker_exp'] = DictData::where(['type_value'=>'worker_exp_type','value'=>$maintain_exp_type])->value('name');
  405. }
  406. //搜索当前工单下的所有订单记录
  407. $order_info['pay_orders'] = \app\common\model\recharge\RechargeOrder::where(['work_id'=>$order_info['work_id']])->field('id as order_id, pay_status ,refund_status,payment_type,pay_way,pay_time,order_total,order_amount,coupon_price')->order('id asc')->select()->toArray();
  408. $pay_status_data = DictData::where('type_value','pay_status')->column('name','value');
  409. $payment_type_data = DictData::where('type_value','payment_type')->column('name','value');
  410. $pay_way_data = DictData::where('type_value','pay_way')->column('name','value');
  411. $coupon_price = 0;
  412. foreach ($order_info['pay_orders'] as $k=>&$v){
  413. $v['pay_status_name'] = $pay_status_data[$v['pay_status']];
  414. $v['payment_type_name'] = $payment_type_data[$v['payment_type']];
  415. $v['pay_way_name'] = $pay_way_data[$v['pay_way']];
  416. if($v['refund_status']==1){
  417. $order_refund_amount += $v['order_amount'];
  418. $refund_status = RefundRecord::where('order_id',$v['order_id'])->value('refund_status');
  419. }
  420. if($v['payment_type']!=1 and !empty($order_info['service_work']['spare_total'])){
  421. $v['order_amount_total'] = $v['order_amount'];
  422. $v['order_amount'] = $v['order_amount'] - $order_info['service_work']['spare_total'];
  423. }
  424. $coupon_price += $v['coupon_price'];
  425. }
  426. //汇总优惠卷额度
  427. $order_info['coupon_price'] = $coupon_price;
  428. //退款汇总
  429. $order_info['refund_amount'] = $order_refund_amount;
  430. if(isset($refund_status)){
  431. switch ($refund_status){
  432. case 0:
  433. $order_info['refund_status'] = '退款中';
  434. break;
  435. case 1:
  436. $order_info['refund_status'] = '退款成功';
  437. break;
  438. case 2:
  439. $order_info['refund_status'] = '退款失败';
  440. break;
  441. }
  442. }else{
  443. $order_info['refund_status'] = '未退款';
  444. }
  445. // 所有配件
  446. $order_info['spare_total'] = $order_info['service_work']['spare_total']??0;
  447. $order_info['spare_parts'] = [];
  448. if($order_info['service_work']['service_work_spare_id']){
  449. $work_spare_parts = json_decode(ServiceWorkSpare::where('id',$order_info['service_work']['service_work_spare_id'])->value('spare_parts'),true);
  450. $spare_parts = SparePart::where('id','in',array_column($work_spare_parts,'id'))
  451. ->field(['id', 'goods_category_id', 'spare_name', 'spare_image', 'spare_number', 'spare_unit','spare_status'])
  452. ->select()
  453. ->toArray();
  454. $spare_parts = array_column($spare_parts,null,'id');
  455. foreach (array_column($work_spare_parts,null,'id') as $k=>&$v){
  456. $spare_parts[$k] = array_merge($spare_parts[$k],$v);
  457. }
  458. $order_info['spare_parts'] = array_values($spare_parts)??[];
  459. }
  460. return $order_info;
  461. }
  462. catch (\Exception $e) {
  463. self::setError($e->getMessage());
  464. return false;
  465. }
  466. }
  467. /**
  468. * 获取订单支付详情
  469. * @param $params
  470. * @return array|false
  471. */
  472. public static function orderPayInfo($params)
  473. {
  474. try {
  475. $order_info = \app\common\model\recharge\RechargeOrder::with(['order_goods'=>function ($query) {
  476. $query->visible(['goods_payment_type','goods_category_id']);
  477. },'service_work'=>function ($query) {
  478. $query->visible(['service_fee','spare_total','service_work_spare_id']);
  479. }])
  480. ->visible(['id','sn','work_id'])
  481. ->where([
  482. 'order_type' => 0,
  483. 'user_id' => $params['user_id'],
  484. 'sn'=>$params['sn']
  485. ])->findOrEmpty()->toArray();
  486. if(empty($order_info)){
  487. throw new Exception('订单不存在');
  488. }
  489. //查询总价
  490. $order_info['order_amount'] = \app\common\model\recharge\RechargeOrder::where(['order_type'=>0,'user_id'=>$params['user_id'],'work_id'=>$order_info['work_id']])->sum('order_amount');
  491. $order_info['paid_amount'] = \app\common\model\recharge\RechargeOrder::where(['order_type'=>0,'user_id'=>$params['user_id'],'work_id'=>$order_info['work_id']])->sum('paid_amount');
  492. //搜索当前工单下的所有订单记录
  493. $order_info['pay_orders'] = \app\common\model\recharge\RechargeOrder::where(['work_id'=>$order_info['work_id']])->field('id as order_id, pay_status,refund_status,payment_type,pay_way,pay_time,order_total,order_amount,coupon_price')->order('id asc')->select()->toArray();
  494. $pay_status_data = DictData::where('type_value','pay_status')->column('name','value');
  495. $payment_type_data = DictData::where('type_value','payment_type')->column('name','value');
  496. $pay_way_data = DictData::where('type_value','pay_way')->column('name','value');
  497. $coupon_price = 0;
  498. //退款金额
  499. $order_refund_amount = 0;
  500. $payment_type = 0;
  501. foreach ($order_info['pay_orders'] as $k=>&$v){
  502. $v['pay_status_name'] = $pay_status_data[$v['pay_status']];
  503. $v['payment_type_name'] = $payment_type_data[$v['payment_type']];
  504. $v['pay_way_name'] = $pay_way_data[$v['pay_way']];
  505. if($v['refund_status']==1){
  506. $order_refund_amount += $v['order_amount'];
  507. $refund_status = RefundRecord::where('order_id',$v['order_id'])->value('refund_status');
  508. }
  509. if($v['payment_type']!=1 and !empty($order_info['service_work']['spare_total'])){
  510. $v['order_total'] = $v['order_total'] - $order_info['service_work']['spare_total'];
  511. $v['order_amount'] = $v['order_amount'] - $order_info['service_work']['spare_total'] + $v['coupon_price'];
  512. }
  513. $coupon_price += $v['coupon_price'];
  514. $payment_type = $v['payment_type'];
  515. }
  516. $order_info['payment_type'] = $payment_type;
  517. //汇总优惠卷额度
  518. $order_info['coupon_price'] = $coupon_price;
  519. //退款汇总
  520. $order_info['refund_amount'] = $order_refund_amount;
  521. if(isset($refund_status)){
  522. switch ($refund_status){
  523. case 0:
  524. $order_info['refund_status'] = '退款中';
  525. break;
  526. case 1:
  527. $order_info['refund_status'] = '退款成功';
  528. break;
  529. case 2:
  530. $order_info['refund_status'] = '退款失败';
  531. break;
  532. }
  533. }else{
  534. $order_info['refund_status'] = '未退款';
  535. }
  536. // 所有配件
  537. $order_info['spare_total'] = $order_info['service_work']['spare_total']??0;
  538. $order_info['spare_parts'] = [];
  539. if($order_info['service_work']['service_work_spare_id']){
  540. $work_spare_parts = json_decode(ServiceWorkSpare::where('id',$order_info['service_work']['service_work_spare_id'])->value('spare_parts'),true);
  541. $spare_parts = SparePart::where('id','in',array_column($work_spare_parts,'id'))
  542. ->field(['id', 'goods_category_id', 'spare_name', 'spare_image', 'spare_number', 'spare_unit','spare_status'])
  543. ->select()
  544. ->toArray();
  545. $spare_parts = array_column($spare_parts,null,'id');
  546. foreach (array_column($work_spare_parts,null,'id') as $k=>&$v){
  547. $spare_parts[$k] = array_merge($spare_parts[$k],$v);
  548. }
  549. $order_info['spare_parts'] = array_values($spare_parts)??[];
  550. }
  551. return $order_info;
  552. }
  553. catch (\Exception $e) {
  554. self::setError($e->getMessage());
  555. return false;
  556. }
  557. }
  558. /**
  559. * 取消订单
  560. * @param $params
  561. * @return false|void
  562. */
  563. public static function cancelOrder($params)
  564. {
  565. Db::startTrans();
  566. try {
  567. $work_id = \app\common\model\recharge\RechargeOrder::where([
  568. 'order_type' => 0,
  569. 'user_id' => $params['user_id'],
  570. 'sn'=>$params['sn']
  571. ])->value('work_id');
  572. if(empty($work_id)){
  573. throw new Exception('订单不存在');
  574. }
  575. $payed_order = \app\common\model\recharge\RechargeOrder::where(['user_id'=>$params['user_id'],'work_id'=>$work_id,'pay_status'=>1])->findOrEmpty();
  576. if(!$payed_order->isEmpty()){
  577. throw new Exception('存在已支付订单,不允许取消订单,请联系客服');
  578. }
  579. //软删除订单
  580. $cancel_order = \app\common\model\recharge\RechargeOrder::where(['user_id'=>$params['user_id'],'work_id'=>$work_id])->findOrEmpty();
  581. $cancel_order->pay_status = 2;
  582. $cancel_order->save();
  583. //更新工单状态为已取消
  584. $service_work = ServiceWork::find($work_id);
  585. $service_work->service_status = 4;
  586. $service_work->save();
  587. //判断如果存在优惠券,返还优惠券
  588. if(!empty($payed_order->coupon_id)){
  589. $user_coupon = UserCoupon::where(['user_id'=>$payed_order->user_id,'id'=>$payed_order->coupon_id])->findOrEmpty();
  590. $user_coupon->voucher_status = 0;
  591. $user_coupon->voucher_count = $user_coupon->voucher_count+1;
  592. $user_coupon->save();
  593. }
  594. Db::commit();
  595. }
  596. catch (\Exception $e) {
  597. self::setError($e->getMessage());
  598. return false;
  599. }
  600. }
  601. /**
  602. * 用户确认尾款报价单
  603. * @param $params
  604. * @return false|void
  605. */
  606. public static function confirmOrder($params)
  607. {
  608. Db::startTrans();
  609. try {
  610. $work_id = \app\common\model\recharge\RechargeOrder::where([
  611. 'order_type' => 0,
  612. 'user_id' => $params['user_id'],
  613. 'sn'=>$params['sn']
  614. ])->value('work_id');
  615. if(empty($work_id)){
  616. throw new Exception('订单不存在');
  617. }
  618. //更新工单状态为已取消
  619. $service_work = ServiceWork::find($work_id);
  620. if($service_work->user_confirm_status==2){
  621. throw new Exception('请勿重复操作');
  622. }
  623. $service_work->work_status = 5;
  624. $service_work->user_confirm_status = 2;
  625. $service_work->save();
  626. $work_log = [
  627. 'work_id'=>$work_id,
  628. 'master_worker_id'=>$service_work->master_worker_id,
  629. 'opera_log'=>'用户'.$params['user_info']['real_name'].'于'.date('y-m-d H:i:s',time()).'于'.date('Y-m-d H:i:s',time()).'确认了报价单',
  630. ];
  631. ServiceWorkLogLogic::add($work_log);
  632. Db::commit();
  633. }
  634. catch (\Exception $e) {
  635. self::setError($e->getMessage());
  636. return false;
  637. }
  638. }
  639. /**
  640. * 用户确认服务完成
  641. * @param $params
  642. * @return false|void
  643. */
  644. public static function confirmServiceFinish($params)
  645. {
  646. Db::startTrans();
  647. try {
  648. $work_id = \app\common\model\recharge\RechargeOrder::where([
  649. 'order_type' => 0,
  650. 'user_id' => $params['user_id'],
  651. 'sn'=>$params['sn']
  652. ])->value('work_id');
  653. if(empty($work_id)){
  654. throw new Exception('订单不存在');
  655. }
  656. $service_work = ServiceWork::find($work_id);
  657. if($service_work->user_confirm_status!=3){
  658. throw new Exception('请勿重复操作');
  659. }
  660. $orders = RechargeOrder::where(['work_id'=>$work_id,'user_id'=>$params['user_id']])->select()->toArray();
  661. //确认所有订单总金额和结算金额
  662. //若订单是全款已支付订单
  663. if(count($orders)==1 and $orders[0]['payment_type']==0 and $orders[0]['pay_status']==1){
  664. $service_work->work_status = 7;
  665. $service_work->user_confirm_status = 5;
  666. $service_work->service_status = 3;
  667. $service_work->work_pay_status = 1;
  668. }else{
  669. $service_work->work_status = 6;
  670. $service_work->user_confirm_status = 4;
  671. }
  672. $service_work->finished_time = time();
  673. $service_work->save();
  674. //更新工程师的进行工单数量
  675. MasterWorker::setWorktotal('dec',$service_work->master_worker_id);
  676. $work_log = [
  677. 'work_id'=>$work_id,
  678. 'master_worker_id'=>$service_work->master_worker_id,
  679. 'opera_log'=>'用户'.$params['user_info']['real_name'].'于'.date('y-m-d H:i:s',time()).'于'.date('Y-m-d H:i:s',time()).'确认服务完成',
  680. ];
  681. ServiceWorkLogLogic::add($work_log);
  682. Db::commit();
  683. }
  684. catch (\Exception $e) {
  685. self::setError($e->getMessage());
  686. return false;
  687. }
  688. }
  689. public static function approvalChangePrice($params)
  690. {
  691. Db::startTrans();
  692. try {
  693. $order = RechargeOrder::where('sn',$params['sn'])->findOrEmpty();
  694. if($order->isEmpty()){
  695. throw new Exception('订单不存在');
  696. }
  697. $work = ServiceWork::findOrEmpty($order->work_id);
  698. if($work->isEmpty()){
  699. throw new Exception('工单不存在');
  700. }
  701. $work->price_approval = 1;
  702. $work->save();
  703. Db::commit();
  704. }
  705. catch (\Exception $e) {
  706. self::setError($e->getMessage());
  707. return false;
  708. }
  709. }
  710. public static function approvalChangeAppointment($params)
  711. {
  712. Db::startTrans();
  713. try {
  714. $order = RechargeOrder::where('sn',$params['sn'])->findOrEmpty();
  715. if($order->isEmpty()){
  716. throw new Exception('订单不存在');
  717. }
  718. $work = ServiceWork::findOrEmpty($order->work_id);
  719. if($work->isEmpty()){
  720. throw new Exception('工单不存在');
  721. }
  722. $work->appointment_time = strtotime($params['appointment_time']);
  723. //更新工单未确认上门的状态
  724. $work->work_status = 3;
  725. $work->user_confirm_status = 0;
  726. ServiceWorkAppointmentLog::create([
  727. 'work_id'=>$work->id,
  728. 'last_appointment_time'=>$work->appointment_time,
  729. 'this_appointment_time'=>strtotime($params['appointment_time']),
  730. ]);
  731. $work->save();
  732. Db::commit();
  733. }
  734. catch (\Exception $e) {
  735. self::setError($e->getMessage());
  736. return false;
  737. }
  738. }
  739. }