Order.php 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. <?php
  2. namespace app\api\model\service;
  3. use think\App;
  4. use think\Model;
  5. use traits\model\SoftDelete;
  6. use think\Exception;
  7. use fast\Random;
  8. class Order extends Model
  9. {
  10. use SoftDelete;
  11. // 表名
  12. protected $name = 'service_order';
  13. // 自动写入时间戳字段
  14. protected $autoWriteTimestamp = 'int';
  15. // 定义时间戳字段名
  16. protected $createTime = 'createtime';
  17. protected $updateTime = 'updatetime';
  18. protected $deleteTime = 'deletetime';
  19. /**
  20. * 项目结算
  21. * @param $param
  22. * @return array
  23. * @throws Exception
  24. * @throws \think\db\exception\DataNotFoundException
  25. * @throws \think\db\exception\ModelNotFoundException
  26. * @throws \think\exception\DbException
  27. */
  28. public static function settle($params)
  29. {
  30. $goods = Goods::where(['id' => $params['goods_id'], 'status' => 'normal'])->field('id,image,response_hour,start_hour,end_hour,shop_id,name,type,price,cost_seconds,to_shop,is_travel,choose_skill_type')->find();
  31. if (!$goods) {
  32. throw new Exception('项目信息异常,无法下单');
  33. }
  34. $data['goods'] = $goods;
  35. $data['sumprice'] = bcmul($goods['price'], $params['num'], 2);
  36. $data['shop'] = $goods['type'] == 1 ? Shop::getShop($goods['shop_id']) : '';
  37. if ($params['goods_sku_id']) {
  38. $goodsSku = GoodsSku::where(['id' => $params['goods_sku_id'], 'goods_id' => $goods['id'], 'status' => 'normal'])->field('id,name,price,cost_seconds')->find();
  39. if (!$goodsSku['id']) {
  40. throw new Exception('规格信息异常');
  41. }
  42. $data['goodsSku'] = $goodsSku;
  43. $goods['price'] = $goodsSku['price'];
  44. $data['sumprice'] = sprintf("%.2f", $data['goodsSku']['price'] * $params['num']);
  45. }
  46. return $data;
  47. }
  48. public static function createPackageOrder($params)
  49. {
  50. $userInfo = UserInfo::where(['user_id' => $params['user_id']])->field('discount,is_plus,leader_id,rec_leader_id')->find();
  51. $packageOrderDetail = PackageOrderDetail::where(['id'=>$params['package_order_detail_id'],'user_id'=>$params['user_id']])->find();
  52. $totalPrice = bcmul($params['num'],$packageOrderDetail['act_price'],2);
  53. $totalCostSeconds = bcmul($params['num'],$packageOrderDetail['cost_seconds']);
  54. $packageOrder = PackageOrder::where('id',$packageOrderDetail['package_order_id'])->field('id,status,endtime,package_card_id,discount,paytype,orderId,trade_no,total_nums,use_nums')->find();
  55. if(!$packageOrderDetail || !$packageOrder)
  56. {
  57. throw new Exception('套餐信息异常,请联系管理员');
  58. }
  59. if($packageOrderDetail['usenums']+$params['num'] > $packageOrderDetail['nums'])
  60. {
  61. throw new Exception('套餐当前项目已使用完毕');
  62. }
  63. if($packageOrder['status'] != 1)
  64. {
  65. throw new Exception('套餐卡已无法使用,请联系管理员');
  66. }
  67. $goods = Goods::where(['id'=>$packageOrderDetail['goods_id']])->find();
  68. $endtime = $totalCostSeconds*60+$params['starttime'];
  69. $data = ['user_id' => $params['user_id'],'goods_id'=>$packageOrderDetail['goods_id'],'is_pool'=>1,'package_order_id'=>$packageOrder['id'],'ordertype'=>1,'city'=>$params['city'], 'price'=>$totalPrice,'sumprice'=>$totalPrice,'goods_total_price'=>$totalPrice,'payprice'=>$totalPrice, 'choose_skill_type' => 0,'traveltype'=>0, 'paytype' => $packageOrder['paytype'],'orderId'=>$packageOrder['orderId'],'trade_no'=>$packageOrder['trade_no'],'total_cost_seconds'=>$totalCostSeconds, 'to_shop' => $goods['to_shop'],'starttime'=>$params['starttime'],'endtime'=>$endtime,'actendtime'=>$endtime+1799,'paytime'=>time(),'memo' => $params['memo'],'status'=>1];
  70. $order = new Order($data);
  71. $order->allowField(true)->save();
  72. OrderLog::create(['order_id' => $order->id, 'user_id' => $params['user_id'], 'content' => '用户创建订单成功']);
  73. $address = Address::where(['id' => $params['address_id']])->field('name,sex,mobile,province,city,district,address,lng,lat,area')->find()->toArray();
  74. $address['user_id'] = $params['user_id'];
  75. $address['order_id'] = $order->id;
  76. OrderAddress::create($address);
  77. $detailData = ['user_id' => $params['user_id'], 'order_id' => $order->id, 'goods_id' => $packageOrderDetail['goods_id'], 'goods_sku_id' => $packageOrderDetail['goods_sku_id'], 'name' => $packageOrderDetail['goodsname'], 'image' => $goods['image'], 'num' => $params['num'], 'sku_name' => $packageOrderDetail['name'], 'price' => $packageOrderDetail['act_price'], 'sumprice' => $totalPrice];
  78. $orderDetail = new OrderDetail($detailData);
  79. $orderDetail->allowField(true)->save();
  80. PackageOrderDetail::where('id',$params['package_order_detail_id'])->setInc('usenums',$params['num']);
  81. PackageOrder::where('id',$packageOrder['id'])->setInc('use_nums');
  82. if($packageOrder['use_nums']+1 >= $packageOrder['total_nums'])
  83. {
  84. PackageOrder::where('id',$packageOrder['id'])->update(['status'=>2]);
  85. }
  86. return true;
  87. }
  88. /**
  89. * 创建订单
  90. * @param $params
  91. * @return array
  92. * @throws Exception
  93. * @throws \think\db\exception\DataNotFoundException
  94. * @throws \think\db\exception\ModelNotFoundException
  95. * @throws \think\exception\DbException
  96. */
  97. public static function createOrder($params)
  98. {
  99. $goods = self::settle($params);
  100. $userInfo = UserInfo::where(['user_id' => $params['user_id']])->field('discount,is_plus,leader_id,rec_leader_id')->find();
  101. $data = ['user_id' => $params['user_id'],'leader_id'=>$userInfo['leader_id'],'rec_leader_id'=>$userInfo['rec_leader_id'],'goods_id'=>$goods['goods']['id'],'discount'=>$userInfo['discount'],'city'=>$params['city'],'traveltype' => $params['traveltype'], 'travel_price' => $params['travel_price'],'distance'=>$params['distance'], 'choose_skill_type' => $params['choose_skill_type'], 'paytype' => $params['paytype'], 'to_shop' => $params['to_shop'], 'orderId' => 'GoodsOrd' . Random::alnum(4) . '-' . $params['user_id'] . '-' . time(), 'memo' => $params['memo']];
  102. if($params['shop_id'])
  103. {
  104. $data['shop_id'] = $params['shop_id'];
  105. }elseif($goods['goods']['shop_id']){
  106. $data['shop_id'] = $goods['goods']['shop_id'];
  107. }
  108. $data['total_cost_seconds'] = isset($goods['goodsSku']) ? intval($goods['goodsSku']['cost_seconds'] * $params['num']) : intval($goods['goods']['cost_seconds'] * $params['num']);
  109. $price = isset($goods['goodsSku']) ? $goods['goodsSku']['price'] : $goods['goods']['price'];
  110. $data['price'] = bcmul($price, $params['num'], 2);
  111. $data['sumprice'] = bcadd($data['price'], $params['travel_price'], 2);
  112. $data['goods_total_price'] = $userInfo['discount'] < 100 ?round(bcmul($data['price'], $userInfo['discount']/100, 3),2) : $data['price'];
  113. $data['payprice'] = $userInfo['discount'] < 100?bcadd($data['goods_total_price'],$params['travel_price'],3):$data['sumprice'];
  114. if (!strstr($goods['goods']['to_shop'], $params['to_shop'])) {
  115. throw new Exception('当前服务并无所选出行方式');
  116. }
  117. $needtime = $data['total_cost_seconds'] * 60;
  118. if($params['to_shop'] == 'shop' && $params['skill_id'])
  119. {
  120. $params['skill_id'] = '';
  121. }
  122. if ($params['skill_id']) {
  123. $skill = Skill::skillInfo($params['skill_id']);
  124. if($skill['is_rest'] == 1)
  125. {
  126. throw new Exception('服务者休息中,无法预约');
  127. }
  128. $data['skill_id'] = $skill['id'];
  129. $data['shop_id'] = $skill['shop_id'];
  130. $data['choose_skill_type'] = 1;
  131. $timeInfo = SkillTime::where(['skill_id' => $params['skill_id'], 'id' => $params['time_id'], 'state' => 0])->field('id,starttime')->find();
  132. if (!$timeInfo) {
  133. throw new Exception('当前时间已占用,无法预约');
  134. }
  135. $data['starttime'] = $timeInfo['starttime'];
  136. $data['endtime'] = $timeInfo['starttime'] + $needtime;
  137. $data['actendtime'] = $data['endtime'] + 1799;
  138. $timeExist = SkillTime::where(['state' => ['>', 0], 'skill_id' => $params['skill_id'], 'starttime' => ['between', [$data['starttime'], $data['actendtime']]]])->value('id');
  139. if ($timeExist) {
  140. throw new Exception('当前时间区间有被预约,请更换其他时间区间');
  141. }
  142. } elseif ($params['starttime']) {
  143. if ($params['starttime'] < time()) {
  144. throw new Exception('选择时间不可小于当前时间');
  145. }
  146. $data['starttime'] = $params['starttime'];
  147. $data['endtime'] = $params['starttime'] + $needtime;
  148. $data['actendtime'] = $data['endtime'] + 1799;
  149. }
  150. if ($params['coupon_id']) {
  151. $coupon = UserCoupon::checkCoupon($params['coupon_id'], $goods);
  152. if (!$coupon) {
  153. throw new Exception('优惠券无法使用');
  154. }
  155. $data['coupon_id'] = $params['coupon_id'];
  156. $data['coupon_price'] = sprintf("%.2f", $coupon['reduce']);
  157. $data['payprice'] = bcsub($data['payprice'], $data['coupon_price'],2);
  158. }
  159. if(empty($data['shop_id']) && empty($params['skill_id']))
  160. {
  161. $data['is_pool'] = 1;
  162. }
  163. $userMoney = User::getMoney($params['user_id']);
  164. if ($params['paytype'] == 4 && $userMoney < $data['payprice']) {
  165. throw new Exception('余额不足,请及时充值');
  166. }
  167. $order = new Order($data);
  168. $order->allowField(true)->save();
  169. OrderLog::create(['order_id' => $order->id, 'user_id' => $params['user_id'], 'content' => '用户创建订单成功']);
  170. if ($params['to_shop'] == 'door' && $params['address_id']) {
  171. $address = Address::where(['id' => $params['address_id']])->field('name,sex,mobile,province,city,district,address,lng,lat,area')->find()->toArray();
  172. if($params['skill_id'])
  173. {
  174. $skillCity = Skill::where('id',$params['skill_id'])->value('city');
  175. if($skillCity != $address['city'])
  176. {
  177. throw new Exception('上门地址请选择服务者所在城市');
  178. }
  179. }
  180. $address['user_id'] = $params['user_id'];
  181. $address['order_id'] = $order->id;
  182. OrderAddress::create($address);
  183. }
  184. $sku_name = isset($goods['goodsSku']) ? $goods['goodsSku']['name'] : '';
  185. $detailData = ['user_id' => $params['user_id'], 'order_id' => $order->id, 'goods_id' => $params['goods_id'], 'goods_sku_id' => $params['goods_sku_id'], 'skill_id' => $params['skill_id'], 'name' => $goods['goods']['name'], 'image' => $goods['goods']['image'], 'num' => $params['num'], 'sku_name' => $sku_name, 'price' => $price, 'sumprice' => $data['sumprice']];
  186. $orderDetail = new OrderDetail($detailData);
  187. $orderDetail->allowField(true)->save();
  188. $re = [];
  189. if (in_array($params['paytype'], [0, 1, 2, 3])) {
  190. $re['pay'] = \addons\service\library\Pay::payOrder(['amount' => $data['payprice'], 'orderid' => $data['orderId'], 'title' => '支付项目费用'], $params['paytype'], $params['user_id'], 0);
  191. } elseif ($params['paytype'] == 4) {
  192. User::money(-$data['payprice'], $data['user_id'], '支付' . $goods['goods']['name'] . '项目费用');
  193. $order->save(['status' => 1, 'paytime' => time()], ['id' => $order->id]);
  194. $re['pay'] = '';
  195. self::finishPay($order->id);
  196. }
  197. return $re;
  198. }
  199. public static function pay($params)
  200. {
  201. $order = self::where(['id'=>$params['id'],'status'=>0,'user_id'=>$params['user_id']])->field('id,skill_id,shop_id,goods_id,payprice,user_id,to_shop,starttime,actendtime,coupon_id')->find();
  202. if(!$order)
  203. {
  204. throw new Exception('订单已超时,无法支付');
  205. }
  206. $orderDetail = OrderDetail::where(['order_id'=>$order['id']])->field('goods_id,goods_sku_id,price,name')->find();
  207. $price = $orderDetail['goods_sku_id'] ?GoodsSku::where(['id'=>$orderDetail['goods_sku_id'],'status'=>'normal'])->value('price'):Goods::where(['id'=>$order['goods_id'],'status'=>'normal'])->value('price');
  208. if(!$price || $price!=$orderDetail['price'])
  209. {
  210. throw new Exception('订单项目信息发生变化,请重新下单');
  211. }
  212. if ($order['coupon_id']) {
  213. $couponState = UserCoupon::where(['id'=>$order['coupon_id'],'user_id'=>$order['user_id']])->value('state');
  214. if ($couponState!=0) {
  215. throw new Exception('优惠券无法使用,请重新下单');
  216. }
  217. }
  218. if($order['starttime']<time())
  219. {
  220. throw new Exception('预约时间已超出,请重新下单');
  221. }
  222. if($order['skill_id'])
  223. {
  224. $skill = Skill::where(['id'=>$order['skill_id'],'state'=>1])->value('id');
  225. if(!$skill)
  226. {
  227. throw new Exception('当前服务者暂时无法接单,请重新下单');
  228. }
  229. $timeExist = SkillTime::where(['state' => ['>', 0], 'skill_id' => $order['skill_id'], 'starttime' => ['between', [$order['starttime'], $order['actendtime']]]])->value('id');
  230. if ($timeExist) {
  231. throw new Exception('当前服务者时间区间有被预约,请重新下单');
  232. }
  233. }
  234. $userMoney = User::getMoney($order['user_id']);
  235. if ($params['paytype'] == 4 && $userMoney < $order['payprice']) {
  236. throw new Exception('余额不足,请及时充值');
  237. }
  238. $orderId = 'GoodsOrd' . Random::alnum(4) . '-' . $params['user_id'] . '-' . time();
  239. self::where(['id'=>$order['id']])->update(['orderId'=>$orderId,'paytype'=>$params['paytype']]);
  240. $re = [];
  241. if (in_array($params['paytype'], [0, 1, 2, 3])) {
  242. $re['pay'] = \addons\service\library\Pay::payOrder(['amount' => $order['payprice'], 'orderid' => $orderId, 'title' => '支付项目费用'], $params['paytype'], $params['user_id'], 0);
  243. } elseif ($params['paytype'] == 4) {
  244. User::money(-$order['payprice'], $params['user_id'], '支付' .$orderDetail['name']. '项目费用');
  245. $order->save(['status' => 1, 'paytime' => time()], ['id' => $order['id']]);
  246. $re['pay'] = '';
  247. self::finishPay($order['id']);
  248. }
  249. return $re;
  250. }
  251. public static function allocationOrder($params)
  252. {
  253. $order = self::where(['id'=>$params['id'],'shop_id'=>$params['shop_id'],'status'=>1,'is_service'=>['in',[0,-1]]])->field('id,user_id,to_shop,starttime,actendtime,is_service,status')->find();
  254. if($order['to_shop'] != 'door' || !$order)
  255. {
  256. throw new Exception('当前订单无法分配服务者');
  257. }
  258. $skillId = Skill::where(['id'=>$params['skill_id'],'state'=>1])->value('id');
  259. if(!$skillId)
  260. {
  261. throw new Exception('当前服务者无法接单');
  262. }
  263. $exist = SkillTime::where(['skill_id'=>$skillId,'state'=>['in',[1,2]],'starttime'=>['between',[$order['starttime'],$order['actendtime']]]])->value('id');
  264. if($exist)
  265. {
  266. throw new Exception('当前服务者时间有被预约');
  267. }
  268. \app\api\model\service\SkillTime::updateSkillTime(['skill_id'=>$params['skill_id'],'starttime'=>$order['starttime'],'actendtime'=>$order['actendtime']],1);
  269. OrderLog::create(['order_id'=>$order['id'],'type'=>14,'content'=>'订单已分配','user_id'=>$order['user_id']]);
  270. self::where(['id'=>$order['id']])->update(['skill_id'=>$skillId]);
  271. $skillOpenid = UserInfo::getOpenid($params['skill_id'],1);
  272. self::createOrderTemplateParams(['id'=>$order['id'],'user_id'=>$order['user_id'],'to_shop'=>$order['to_shop'],'type'=>1,'templateAttr'=>'skill_order_template','openid'=>$skillOpenid]);
  273. return true;
  274. }
  275. public static function finishPay($id)
  276. {
  277. $order = self::where(['id'=>$id,'status'=>1])->find();
  278. if(!$order)
  279. {
  280. return false;
  281. }
  282. if($order['skill_id'])
  283. {
  284. SkillTime::updateSkillTime($order,1);
  285. }
  286. if($order['coupon_id']){
  287. UserCoupon::where('id',$order['coupon_id'])->update(['state'=>1,'updatetime'=>time()]);
  288. }
  289. if($order['to_shop'] == 'shop')
  290. {
  291. $update['status'] = 2;
  292. $update['check_name'] = time().$order['id'];
  293. $update['qrcode_image'] = \addons\service\library\Common::createQrcode($update['check_name']);
  294. }
  295. $update['act_travel_price'] = sprintf("%.2f",$order['travel_price']);
  296. self::where(['id'=>$id])->update($update);
  297. OrderLog::create(['order_id'=>$id,'user_id'=>$order['user_id'],'type'=>1,'content'=>'用户订单已支付']);
  298. Goods::where('id',$order['goods_id'])->setInc('salenums');
  299. if($order['skill_id'])
  300. {
  301. $skillOpenid = UserInfo::getOpenid($order['skill_id'],1);
  302. self::createOrderTemplateParams(['id'=>$order['id'],'user_id'=>$order['user_id'],'to_shop'=>$order['to_shop'],'type'=>1,'templateAttr'=>'skill_order_template','openid'=>$skillOpenid]);
  303. }
  304. if($order['shop_id'])
  305. {
  306. $shopOpenid = UserInfo::getOpenid($order['shop_id'],2);
  307. self::createOrderTemplateParams(['id'=>$order['id'],'user_id'=>$order['user_id'],'to_shop'=>$order['to_shop'],'type'=>2,'templateAttr'=>'shop_order_template','openid'=>$shopOpenid]);
  308. }
  309. return true;
  310. }
  311. public static function getTotalAccept($params)
  312. {
  313. extract($params);
  314. $where['status'] = ['>',1];
  315. if(isset($skill_id) && $skill_id != '')
  316. {
  317. $where['skill_id'] = $skill_id;
  318. }
  319. if(isset($shop_id) && $shop_id != '')
  320. {
  321. $where['shop_id'] = $shop_id;
  322. }
  323. $starttime = strtotime(date("Y-m-d",$starttime));
  324. $where['starttime'] = ['>=',$starttime];
  325. return self::where($where)->count();
  326. }
  327. /**
  328. * 查询订单列表s
  329. * @param $params
  330. * @return bool|\PDOStatement|string|\think\Collection
  331. * @throws \think\db\exception\DataNotFoundException
  332. * @throws \think\db\exception\ModelNotFoundException
  333. * @throws \think\exception\DbException
  334. */
  335. public static function getOrderList($params)
  336. {
  337. extract($params);
  338. $order = 'createtime desc';
  339. $where['is_service'] = ['<',1];
  340. if (isset($status) && $status != '') {
  341. $where['status'] = $status;
  342. }
  343. if (isset($city) && $city != '') {
  344. $where['city'] = $city;
  345. }
  346. if (isset($is_pool) && $is_pool != '') {
  347. $where['is_pool'] = $is_pool;
  348. $where['status'] = ['>',0];
  349. }
  350. if (isset($finish) && $finish == 1) {
  351. $where['status'] = ['in',[6,7]];
  352. }
  353. if (isset($not_in_finish) && $not_in_finish == 1) {
  354. $where['status'] = ['in',[1,2,3,4]];
  355. }
  356. if (isset($not_accept) && $not_accept == 1) {
  357. $where['status'] = 1;
  358. $where['skill_id'] = ['neq',''];
  359. }
  360. if (isset($not_allocation) && $not_allocation == 1) {
  361. $where['status'] = 1;
  362. $where['skill_id'] = ['null',''];
  363. }
  364. if (isset($not_finish) && $not_finish == 1) {
  365. $where['status'] = ['in',[2,3,4,5]];
  366. }
  367. if (isset($finish) && $finish == 1) {
  368. $where['status'] = ['in',[6,7]];
  369. }
  370. if (isset($in_service) && $in_service == 1) {
  371. $where['is_service'] = ['in',[1,2,-1]];
  372. }
  373. if (isset($user_id) && $user_id != '') {
  374. $where['user_id'] = $user_id;
  375. }
  376. if(isset($is_all) && $is_all != '')
  377. {
  378. $where['is_service'] = ['in',[1,2,0,-1]];
  379. }
  380. if(isset($goods_ids) && $goods_ids != '')
  381. {
  382. $where['goods_id'] = ['in',$goods_ids];
  383. }
  384. if(isset($shop_id) && $shop_id != '')
  385. {
  386. $where['shop_id'] = $shop_id;
  387. }
  388. if(isset($skill_id) && $skill_id != '')
  389. {
  390. $where['skill_id'] = $skill_id;
  391. }
  392. if(isset($is_service) && $is_service != '')
  393. {
  394. $where['is_service'] = $is_service;
  395. }
  396. $list = self::where($where)->field('id,user_id,skill_id,shop_id,payprice,status,refund_price,is_service,starttime,price,total_cost_seconds,to_shop,memo,is_settle')->order($order)->page($page)->limit(10)->select();
  397. foreach ($list as &$value)
  398. {
  399. $value['user'] = User::where(['id'=>$value['user_id']])->field('id,nickname,avatar')->find();
  400. $value['address'] = OrderAddress::where(['order_id'=>$value['id']])->find();
  401. $value['orderDetail'] = OrderDetail::where(['order_id'=>$value['id']])->field('goods_id,name,image,sku_name,num,price')->find();
  402. $value['shopName'] = $value['shop_id']?Shop::where('id',$value['shop_id'])->field('name,logo_image,trade_hour')->find():'';
  403. $value['skillInfo'] = $value['skill_id']?Skill::getOrderSkill($value['skill_id']):'';
  404. $value['refundInfo'] = $value['is_service'] != 0?RefundOrder::where(['order_id'=>$value['id']])->field('refund_reason,refund_price,content,note')->order('id desc')->find():'';
  405. }
  406. return $list;
  407. }
  408. public static function searchSettleOrder($params)
  409. {
  410. extract($params);
  411. $order = 'finishtime desc';
  412. $where['is_settle'] = ['>',0];
  413. $rebateWhere = ['user_id'=>$user_id,'type'=>$type,'rebatetype'=>['<>',2]];
  414. if(isset($shop_id))
  415. {
  416. $where['shop_id'] = $shop_id;
  417. }
  418. if(isset($skill_id) && $skill_id != '')
  419. {
  420. $where['skill_id'] = $skill_id;
  421. }
  422. if(isset($types))
  423. {
  424. $where['shop_id'] = $types == 0?['null','']:['not null',''];
  425. }
  426. if(isset($is_settle) && $is_settle != '')
  427. {
  428. $where['is_settle'] = $is_settle;
  429. }
  430. if(isset($starttime) && isset($endtime))
  431. {
  432. $where['finishtime'] = ['between',[$starttime,$endtime]];
  433. $rebateWhere['createtime'] = ['between',[$starttime,$endtime]];
  434. }
  435. $list = self::where($where)->field('id,user_id,skill_id,shop_id,payprice,status,is_settle,is_service,starttime,sumprice,coupon_price,premium_price,add_price,act_travel_price,refund_price,settle_price,total_cost_seconds,memo,orderId,createtime,finishtime')->order($order)->page($page)->limit(10)->select();
  436. foreach ($list as $key=>$value)
  437. {
  438. $list[$key]['orderDetail'] = OrderDetail::where(['order_id'=>$value['id']])->field('goods_id,name,image,sku_name,num,price')->find();
  439. $list[$key]['rebatePrice'] = Rebate::where(['order_id'=>$value['id'],'type'=>$type,'rebatetype'=>['<>',2]])->value('num');
  440. $list[$key]['skill'] = $value['skill_id']?Skill::where('id',$value->skill_id)->field('name,image')->find():'';
  441. }
  442. $orderIds = self::where($where)->column('id');
  443. $rebateWhere['order_id'] = ['in',$orderIds];
  444. $sumPrice = sprintf("%.2f",Rebate::where($rebateWhere)->sum('num'));
  445. return ['sumPrice'=>$sumPrice,'list'=>$list];
  446. }
  447. public static function getShopSkillOrder($params)
  448. {
  449. extract($params);
  450. $order = 'createtime desc';
  451. if(isset($shop_id) && $shop_id != '')
  452. {
  453. $where['shop_id'] = $shop_id;
  454. }
  455. if(isset($id) && $id != '')
  456. {
  457. $where['skill_id'] = $id;
  458. }
  459. if((isset($starttime) && $starttime != '') && (isset($endtime) && $endtime != ''))
  460. {
  461. $where['createtime'] = ['between',[$starttime,$endtime]];
  462. }
  463. $list = self::where($where)->field('id,user_id,skill_id,shop_id,payprice,status,is_settle,is_service,starttime,sumprice,coupon_price,premium_price,add_price,act_travel_price,refund_price,settle_price,total_cost_seconds,memo,orderId,createtime,finishtime')->order($order)->page($page)->limit(10)->select();
  464. foreach ($list as $key=>$value)
  465. {
  466. $list[$key]['address'] = OrderAddress::where(['order_id'=>$value['id']])->field('name,sex,mobile,province,city,district,address,area,lng,lat')->find();
  467. $list[$key]['orderDetail'] = OrderDetail::where(['order_id'=>$value['id']])->field('goods_id,name,image,sku_name,num,price')->find();
  468. }
  469. return $list;
  470. }
  471. public static function getOrderCount($params)
  472. {
  473. return self::where($params)->count();
  474. }
  475. public static function getOrderPrice($params,$attr)
  476. {
  477. return self::where($params)->sum($attr);
  478. }
  479. public static function getOrder($params)
  480. {
  481. return self::where($params)->field('id,payprice,starttime,status')->with('detail')->order('id desc')->select();
  482. }
  483. public static function getSkillOrderCount($params)
  484. {
  485. $start= strtotime(date("Y-m-d",time()));
  486. $endTime = $start+86399;
  487. for($a = 0;$a <= 2; $a++){
  488. $params['starttime'] = ['between',[86400*$a+$start,86400*$a+$endTime]];
  489. $week['date'] = date("Y-m-d",86400*$a+$start);
  490. $week['count'] = self::where($params)->count();
  491. $list[] = $week;
  492. }
  493. return $list;
  494. }
  495. public static function getTotalOrder()
  496. {
  497. $daytime = strtotime(date("Y-m-d",time()));
  498. $start= $daytime-86400*6;
  499. $end = $daytime;
  500. $day = [];
  501. $orderTotal = [];
  502. $total = ceil(($end-$start)/86400);;
  503. for($a = 0;$a <=$total; $a++){
  504. $where['finishtime'] = ['between',[86400*$a+$start,86400*$a+86399+$start]];
  505. $where['status'] = ['>',5];
  506. $day[] = date("m-d",86400*$a+$start);
  507. $orderTotal[] = self::where($where)->count();
  508. }
  509. return ['day'=>$day,'total'=>$orderTotal];
  510. }
  511. public static function getForm($params)
  512. {
  513. $daytime = strtotime(date("Y-m-d",time()));
  514. extract($params);
  515. $start= isset($starttime)?$starttime:$daytime-86400*6;
  516. $end = isset($endtime)?$endtime:$daytime;
  517. $total = ceil(($end-$start)/86400);
  518. if(isset($shop_id) && $shop_id != '')
  519. {
  520. $where['shop_id'] = $shop_id;
  521. }
  522. if(isset($skill_id) && $skill_id == 1)
  523. {
  524. $where['skill_id'] = $skill_id;
  525. }
  526. $where['status'] = ['>',5];
  527. $list = [];
  528. for($a = 0;$a <=$total; $a++){
  529. $where['finishtime'] = ['between',[86400*$a+$start,86400*$a+$start+86399]];
  530. $week['date'] = date("Y-m-d",86400*$a+$start);
  531. $week['price'] = sprintf("%.2f",self::where($where)->sum('price'));
  532. $week['count'] = self::where($where)->count();
  533. $list[] = $week;
  534. }
  535. return $list;
  536. }
  537. /**
  538. * 获取近3天订单数量
  539. * @param $params
  540. * @return array
  541. * @throws Exception
  542. */
  543. public static function getDayServiceList($params)
  544. {
  545. $daytime = strtotime(date("Y-m-d",time()));
  546. $list = [];
  547. for ($a = 0; $a < 3; $a++)
  548. {
  549. $starttime = $a>0 ?$a*86400+$daytime:$daytime;
  550. $endtime = $starttime+86399;
  551. $params['starttime'] = ['between',[$starttime,$endtime]];
  552. $day['time'] = $starttime;
  553. $day['orderCount'] = self::where($params)->count();
  554. $list[] = $day;
  555. }
  556. return $list;
  557. }
  558. public static function getCount($params)
  559. {
  560. $where['user_id'] = $params['user_id'];
  561. $where['is_service'] = ['in',[0,-1]];
  562. $where['status'] = 0;
  563. $data['unpayCount'] = self::where($where)->count();
  564. $where['status'] = ['in',[1,2,3,4]];
  565. $data['unServiceCount'] = self::where($where)->count();
  566. $where['status'] = 5;
  567. $data['serviceCount'] = self::where($where)->count();
  568. $where['status'] = 6;
  569. $data['notCommentCount'] = self::where($where)->count();
  570. unset($where['status']);
  571. $where['is_service'] = 1;
  572. $data['refundCount'] = self::where($where)->count();
  573. return $data;
  574. }
  575. public static function getOrderInfo($id)
  576. {
  577. $where = [
  578. 'id' => $id,
  579. ];
  580. $order = self::where($where)->field('id,user_id,skill_id,shop_id,traveltype,check_name,refund_price,choose_skill_type,paytype,to_shop,orderId,discount,is_settle,price,travel_price,distance,sumprice,coupon_price,premium_price,add_price,payprice,total_cost_seconds,starttime,endtime,memo,qrcode_image,is_service,status,createtime,paytime')
  581. ->order('id desc')->find();
  582. $order['adddetail'] = AddOrder::getOrderDetailList($id);
  583. $order['detail'] = OrderDetail::where(['order_id'=>$order['id']])->find();
  584. $order['orderAddress'] = $order['to_shop'] == 'door'?OrderAddress::where(['order_id'=>$id])->find():'';
  585. $order['orderLog'] = OrderLog::where(['order_id'=>$id])->field('id,type,createtime,content')->order('id desc')->select();
  586. $order['shopInfo'] = $order['shop_id']?Shop::getShop($order['shop_id']):'';
  587. $order['skillInfo'] = $order['skill_id']?Skill::getOrderSkill($order['skill_id']):'';
  588. return $order;
  589. }
  590. public static function getTemplateOrderInfo($id)
  591. {
  592. $order = db('service_order')->where('id',$id)->field('skill_id,to_shop,orderId,memo as note,status,starttime as time,payprice as price')->find();
  593. $order['cate'] = OrderDetail::where('order_id',$id)->value('name');
  594. $order['address'] = $order['to_shop'] == 'door'?implode('',db('service_order_address')->where(['order_id'=>$id])->field('district,address')->find()):'到店服务';
  595. $order['status'] = self::getStatus($order['status']);
  596. $order['name'] = $order['skill_id']?Skill::where('id',$order['skill_id'])->value('name'):'';
  597. return $order;
  598. }
  599. public static function getStatus($status)
  600. {
  601. $statusAttr = ['待支付','待接单','待出发','已出发','已到达','开始服务','已完成','已评价'];
  602. return $status == -1?'已取消':$statusAttr[$status];
  603. }
  604. public static function shopAccept($order)
  605. {
  606. if(!$order)
  607. {
  608. throw new Exception('当前订单无法选取接单,请联系管理员');
  609. }
  610. OrderLog::create(['order_id'=>$order['id'],'user_id'=>$order['user_id'],'type'=>15,'content'=>'订单已被商户接取']);
  611. $update['status'] = 1;
  612. $update['is_pool'] = 0;
  613. $update['shop_id'] = $order['shop_id'];
  614. self::where(['id'=>$order['id']])->update($update);
  615. Shop::where('id',$order['shop_id'])->setInc('salenums');
  616. return true;
  617. }
  618. public static function createComplaintTemplateParams($params)
  619. {
  620. $params['status'] = $params['state'] == 1?'已处理':'已拒绝';
  621. $templateParams = array_merge($params,['type'=>$params['type'],'templateAttr'=>$params['templateAttr'],'openid'=>$params['openid']]);
  622. (new \addons\service\library\MiniSms())->sendMessage($templateParams);
  623. return true;
  624. }
  625. public static function createRefundTemplateParams($params)
  626. {
  627. $templateOrder = self::refundOrderTemplate($params);
  628. $templateParams = array_merge($templateOrder,['id'=>$params['id'],'type'=>$params['type'],'templateAttr'=>$params['templateAttr'],'openid'=>$params['openid'],'note'=>$params['note']]);
  629. (new \addons\service\library\MiniSms())->sendMessage($templateParams);
  630. return true;
  631. }
  632. public static function refundOrderTemplate($params)
  633. {
  634. $refundOrder =RefundOrder::where('order_id',$params['id'])->field('id,state')->find();
  635. $params['cate'] = OrderDetail::where('order_id',$params['id'])->value('name');
  636. $params['status'] = $refundOrder?$refundOrder['state'] == 1?'审核通过':'审核拒绝':'审核通过';
  637. $params['time'] = time();
  638. return $params;
  639. }
  640. public static function accept($params)
  641. {
  642. $order = self::where(['status'=>1,'id'=>$params['id']])->field('id,user_id,skill_id,is_pool,starttime,actendtime,to_shop')->find();
  643. if(!$order)
  644. {
  645. throw new Exception('当前订单无法选取接单,请联系管理员');
  646. }
  647. OrderLog::create(['order_id'=>$order['id'],'user_id'=>$order['user_id'],'type'=>2,'content'=>'订单已被服务者接取']);
  648. $update['accepttime']= time();
  649. $update['status'] = 2;
  650. if($order['is_pool'] == 1)
  651. {
  652. $update['is_pool'] = 0;
  653. $update['skill_id'] = $params['skill_id'];
  654. $update['shop_id'] = $params['shop_id'];
  655. $exist = SkillTime::where(['skill_id'=>$params['skill_id'],'state'=>['in',[1,2]],'starttime'=>['between',[$order['starttime'],$order['actendtime']]]])->value('id');
  656. if($exist)
  657. {
  658. throw new Exception('当前项目时间区间有被预约');
  659. }
  660. SkillTime::updateSkillTime(['skill_id'=>$params['skill_id'],'starttime'=>$order['starttime'],'actendtime'=>$order['actendtime']],1);
  661. Skill::where('id',$params['skill_id'])->inc('salenums')->update();
  662. }
  663. self::where(['id'=>$order['id']])->update($update);
  664. $userOpenid = UserInfo::getOpenid($order['user_id'],0);
  665. self::createOrderTemplateParams(['id'=>$order['id'],'user_id'=>$order['user_id'],'to_shop'=>$order['to_shop'],'type'=>0,'note'=>'有问题请联系客服','templateAttr'=>'user_notice_template','openid'=>$userOpenid]);
  666. return true;
  667. }
  668. public static function createOrderTemplateParams($order)
  669. {
  670. $templateOrder = self::getTemplateOrderInfo($order['id']);
  671. $templateParams = array_merge($templateOrder,['id'=>$order['id'],'type'=>$order['type'],'templateAttr'=>$order['templateAttr'],'openid'=>$order['openid']]);
  672. (new \addons\service\library\MiniSms())->sendMessage($templateParams);
  673. return true;
  674. }
  675. public static function go($params)
  676. {
  677. $order = self::where(['status'=>2,'id'=>$params['id']])->field('id,user_id,to_shop,skill_id')->find();
  678. if(!$order)
  679. {
  680. throw new Exception('当前订单状态异常');
  681. }
  682. OrderLog::create(['order_id'=>$params['id'],'user_id'=>$order['user_id'],'type'=>3,'content'=>'服务人员已出发']);
  683. self::where(['id'=>$params['id']])->update(['reachtime'=>time(),'status'=>3]);
  684. return true;
  685. }
  686. public static function reach($params)
  687. {
  688. $order = self::where(['status'=>3,'id'=>$params['id']])->field('id,user_id,to_shop')->find();
  689. if(!$order)
  690. {
  691. throw new Exception('当前订单状态异常');
  692. }
  693. OrderLog::create(['order_id'=>$params['id'],'user_id'=>$order['user_id'],'type'=>4,'content'=>'服务人员已到达']);
  694. self::where(['id'=>$params['id']])->update(['reachtime'=>time(),'status'=>4,'reach_images'=> $params['reach_images'] ?? '']);
  695. return true;
  696. }
  697. public static function skillStart($params)
  698. {
  699. $order = self::where(['status'=>4,'id'=>$params['id']])->field('id,user_id,to_shop,skill_id')->find();
  700. if(!$order)
  701. {
  702. throw new Exception('当前订单状态异常');
  703. }
  704. OrderLog::create(['order_id'=>$params['id'],'user_id'=>$order['user_id'],'type'=>5,'content'=>'服务人员已开始服务']);
  705. self::where(['id'=>$params['id']])->update(['servicetime'=>time(),'status'=>5]);
  706. $userOpenid = UserInfo::getOpenid($order['user_id'],0);
  707. Order::createOrderTemplateParams(['id'=>$order['id'],'user_id'=>$order['user_id'],'to_shop'=>$order['to_shop'],'note'=>'有问题请联系客服','type'=>0,'templateAttr'=>'user_order_template','openid'=>$userOpenid]);
  708. return true;
  709. }
  710. public static function skillFinish($params)
  711. {
  712. $order = self::where(['status'=>['in',[2,5]],'id'=>$params['id']])->field('id,to_shop,leader_id,rec_leader_id,user_id,skill_id,status,shop_id,goods_total_price,shop_id,payprice,travel_price,price,sumprice,premium_price,coupon_price,add_price')->find();
  713. if(!$order)
  714. {
  715. throw new Exception('当前订单状态异常,无法确认完成');
  716. }
  717. //更新订单,进行订单待结算
  718. self::where(['id'=>$params['id']])->update(['status'=>6,'finish_images'=>isset($params['finish_images'])?$params['finish_images']:'','finishtime'=>time()]);
  719. self::orderFinish($order);
  720. $userOpenid = UserInfo::getOpenid($order['user_id'],0);
  721. self::createOrderTemplateParams(['id'=>$order['id'],'user_id'=>$order['user_id'],'to_shop'=>$order['to_shop'],'type'=>0,'note'=>'有问题请联系客服','templateAttr'=>'order_finish_template','openid'=>$userOpenid]);
  722. if($order['shop_id'])
  723. {
  724. $shopOpenid = UserInfo::getOpenid($order['shop_id'],2);
  725. self::createOrderTemplateParams(['id'=>$order['id'],'user_id'=>$order['user_id'],'to_shop'=>$order['to_shop'],'type'=>2,'templateAttr'=>'shop_finish_template','openid'=>$shopOpenid]);
  726. }
  727. return true;
  728. }
  729. public static function orderFinish($order)
  730. {
  731. OrderLog::create(['order_id'=>$order['id'],'user_id'=>$order['user_id'],'type'=>6,'content'=>'服务人员已完成服务']);
  732. $settleDay = $order['shop_id']?Shop::getSettleDay($order['shop_id']):ProjectConfig::getProjectConfig('settle_day');
  733. $settletime = $settleDay*86400+time();
  734. $totalPrice = bcadd(($order['goods_total_price']+$order['premium_price']),$order['add_price'],2);
  735. $settlePrice =$order['coupon_price'] > 0 ?bcsub($totalPrice,$order['coupon_price'],2): $totalPrice;
  736. $update = ['is_settle'=>1,'settletime'=>$settletime,'settle_price'=>$settlePrice];
  737. //走这先确定结算方式和结算金额,等到结算日期直接放入账户即可
  738. if($order['skill_id'])
  739. {
  740. $update['skill_percent'] = Skill::where('id',$order['skill_id'])->value('percent');
  741. }
  742. if($order['shop_id'])
  743. {
  744. $update['shop_percent'] = Shop::where('id',$order['shop_id'])->value('percent');
  745. }
  746. self::where(['id'=>$order['id']])->update($update);
  747. Rebate::orderRebate($order);
  748. UserInfo::where('user_id',$order['user_id'])->setInc('total_price',$order['payprice']);
  749. $userInfo = UserInfo::where('user_id',$order['user_id'])->field('total_price,user_id')->find();
  750. return true;
  751. }
  752. public static function checkOrder($order)
  753. {
  754. if(!$order)
  755. {
  756. throw new Exception('订单信息异常,无法核销');
  757. }
  758. self::where(['id'=>$order['id']])->update(['status'=>6,'finishtime'=>time()]);
  759. self::orderFinish($order);
  760. $shopOpenid = UserInfo::getOpenid($order['shop_id'],2);
  761. self::createOrderTemplateParams(['id'=>$order['id'],'user_id'=>$order['id'],'to_shop'=>$order['to_shop'],'type'=>2,'templateAttr'=>'shop_order_template','openid'=>$shopOpenid]);
  762. return true;
  763. }
  764. public function adddetail()
  765. {
  766. return $this->hasMany('AddOrderDetail','order_id');
  767. }
  768. public function detail()
  769. {
  770. return $this->hasMany('OrderDetail','order_id');
  771. }
  772. }