StoreOrder.php 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\wap\model\store;
  12. use app\wap\model\special\Special;
  13. use app\wap\model\special\SpecialBuy;
  14. use app\wap\model\user\User;
  15. use app\wap\model\user\UserAddress;
  16. use app\wap\model\user\UserBill;
  17. use app\wap\model\user\WechatUser;
  18. use basic\ModelBasic;
  19. use behavior\wap\StoreProductBehavior;
  20. use behavior\wechat\PaymentBehavior;
  21. use service\AlipayTradeWapService;
  22. use service\HookService;
  23. use service\SystemConfigService;
  24. use service\WechatService;
  25. use service\WechatTemplateService;
  26. use think\Cache;
  27. use think\Url;
  28. use traits\ModelTrait;
  29. use app\wap\model\user\MemberShip;
  30. use service\GroupDataService;
  31. use app\wap\model\routine\RoutineTemplate;
  32. use app\wap\model\wap\SmsTemplate;
  33. use app\wap\model\topic\TestPaperObtain;
  34. use app\wap\model\material\DataDownloadBuy;
  35. use app\wap\model\merchant\MerchantFlowingWater;
  36. use app\admin\model\study\Plan;
  37. use app\admin\model\study\PlanBuy;
  38. /**订单表
  39. * Class StoreOrder
  40. * @package app\wap\model\store
  41. */
  42. class StoreOrder extends ModelBasic
  43. {
  44. use ModelTrait;
  45. protected $insert = ['add_time'];
  46. protected static $payType = ['weixin' => '微信支付', 'yue' => '余额支付', 'offline' => '线下支付', 'zhifubao' => '支付宝'];
  47. protected static $deliveryType = ['send' => '商家配送', 'express' => '快递配送'];
  48. protected function setAddTimeAttr()
  49. {
  50. return time();
  51. }
  52. protected function setCartIdAttr($value)
  53. {
  54. return is_array($value) ? json_encode($value) : $value;
  55. }
  56. protected function getCartIdAttr($value)
  57. {
  58. return json_decode($value, true);
  59. }
  60. /**购物车价格计算
  61. * @param $cartInfo
  62. * @return array
  63. */
  64. public static function getOrderPriceGroup($cartInfo)
  65. {
  66. $storePostage = 0;
  67. $totalPrice = self::getOrderTotalPrice($cartInfo);
  68. $costPrice = self::getOrderCostPrice($cartInfo);
  69. foreach ($cartInfo as $cart) {
  70. if (!$cart['productInfo']['is_postage']) {
  71. $storePostage = bcadd($storePostage, $cart['productInfo']['postage'], 2);
  72. if (bcsub($cart['productInfo']['free_shipping'], $cart['cart_num'], 0) <= 0 && $cart['productInfo']['free_shipping'] > 0) {
  73. $storePostage = 0;
  74. }
  75. }
  76. }
  77. return compact('storePostage', 'totalPrice', 'costPrice');
  78. }
  79. /**计算总价
  80. * @param $cartInfo
  81. * @return int|string
  82. */
  83. public static function getOrderTotalPrice($cartInfo)
  84. {
  85. $totalPrice = 0;
  86. foreach ($cartInfo as $cart) {
  87. $totalPrice = bcadd($totalPrice, bcmul($cart['cart_num'], $cart['truePrice'], 2), 2);
  88. }
  89. return $totalPrice;
  90. }
  91. /**计算成本价
  92. * @param $cartInfo
  93. * @return int|string
  94. */
  95. public static function getOrderCostPrice($cartInfo)
  96. {
  97. $costPrice = 0;
  98. foreach ($cartInfo as $cart) {
  99. $costPrice = bcadd($costPrice, bcmul($cart['cart_num'], $cart['costPrice'], 2), 2);
  100. }
  101. return $costPrice;
  102. }
  103. public static function getPinkOrderId($id)
  104. {
  105. return self::where('id', $id)->value('order_id');
  106. }
  107. public static function cacheOrderInfo($uid, $cartInfo, $priceGroup, $cacheTime = 600)
  108. {
  109. $subjectUrl = getUrlToDomain();
  110. $key = md5(time());
  111. Cache::store("redis")->set($subjectUrl . 'user_order_' . $uid . $key, compact('cartInfo', 'priceGroup'), $cacheTime);
  112. return $key;
  113. }
  114. public static function getCacheOrderInfo($uid, $key)
  115. {
  116. $subjectUrl = getUrlToDomain();
  117. $cacheName = $subjectUrl . 'user_order_' . $uid . $key;
  118. if (!Cache::store("redis")->has($cacheName)) return null;
  119. return Cache::store("redis")->get($cacheName);
  120. }
  121. public static function clearCacheOrderInfo($uid, $key)
  122. {
  123. $subjectUrl = getUrlToDomain();
  124. Cache::store("redis")->clear($subjectUrl . 'user_order_' . $uid . $key);
  125. }
  126. public static function getSpecialIds($uid)
  127. {
  128. return self::where(['is_del' => 0, 'paid' => 1, 'uid' => $uid, 'is_gift' => 0])->column('cart_id');
  129. }
  130. /**
  131. * 获取专题订单列表
  132. * @param $type
  133. * @param $page
  134. * @param $limit
  135. * @param $uid
  136. * @return array
  137. * @throws \think\Exception
  138. * @throws \think\db\exception\DataNotFoundException
  139. * @throws \think\db\exception\ModelNotFoundException
  140. * @throws \think\exception\DbException
  141. */
  142. public static function getSpecialOrderList($type, $page, $limit, $uid)
  143. {
  144. $model = self::where(['a.is_del' => 0, 's.is_del' => 0, 'a.uid' => $uid, 'a.paid' => 1])->order('a.add_time desc')->alias('a')->join('__SPECIAL__ s', 'a.cart_id=s.id');
  145. switch ($type) {
  146. case 1:
  147. $model = $model->where(['a.is_gift' => 1, 'a.combination_id' => 0, 'a.pink_id' => 0, 'a.type' => 0]);
  148. break;
  149. case 2:
  150. $model = $model->where(['a.is_gift' => 0, 'a.combination_id' => 0, 'a.pink_id' => 0, 'a.type' => 0]);
  151. break;
  152. case 3:
  153. $model = $model->where('a.is_gift', 0)->where('a.type', 0)->where('a.combination_id', 'NEQ', 0)->where('a.pink_id', 'NEQ', 0);
  154. break;
  155. }
  156. $list = $model->field(['a.*', 's.title', 's.image', 's.money', 's.pink_number', 's.is_light'])->page($page, $limit)->select();
  157. $list = count($list) ? $list->toArray() : [];
  158. foreach ($list as &$item) {
  159. $item['image'] = get_oss_process($item['image'], 4);
  160. $item['pink'] = [];
  161. $item['stop_time'] = 0;
  162. $item['is_draw'] = false;
  163. if ($type === 3 && $item['pink_id'] != 0) {
  164. if ($pink = StorePink::where('order_id', $item['order_id'])->find()) {
  165. $pink = $pink->toArray();
  166. $item['pink_status'] = $pink['is_refund'] ? 4 : $pink['status'];
  167. $item['stop_time'] = date('Y-m-d H:i:s', $pink['stop_time']);
  168. $item['pink_id'] = $pink['id'];
  169. StorePink::setPinkIng($pink, $item['uid']);
  170. } else {
  171. $item['pink_status'] = 5;
  172. }
  173. } else if ($type === 1) {
  174. if ($uid = self::where(['gift_order_id' => $item['order_id']])->value('uid')) {
  175. $item['is_draw'] = true;
  176. $userAvatar = User::where('uid', $uid)->field(['nickname', 'avatar'])->find();
  177. if ($userAvatar) {
  178. $item['gift_user'] = $userAvatar->toArray();
  179. } else {
  180. $item['gift_user'] = ['nickname' => '', 'avatar' => ''];
  181. }
  182. }
  183. }
  184. }
  185. $page++;
  186. return compact('list', 'page');
  187. }
  188. /**
  189. * 获取礼物领取记录
  190. * @param $order_id 订单号
  191. * @return array|bool
  192. * @throws \think\db\exception\DataNotFoundException
  193. * @throws \think\db\exception\ModelNotFoundException
  194. * @throws \think\exception\DbException
  195. */
  196. public static function getOrderIdGiftReceive($order_id)
  197. {
  198. $is_gift = false;
  199. $user = [];
  200. $order = self::where(['is_del' => 0, 'order_id' => $order_id])->find();
  201. if (!$order) return self::setErrorInfo('订单不存在');
  202. if (!$order->cart_id) return self::setErrorInfo('订单专题不存在!');
  203. $add_time = date('m-d H:i', $order->add_time);
  204. $data = Special::PreWhere()->where(['id' => $order->cart_id])->field('image,title')->find();
  205. $image = $data['image'];
  206. $title = $data['title'];
  207. $uid = self::where(['is_del' => 0, 'gift_order_id' => $order->order_id])->value('uid');
  208. if ($uid) {
  209. $is_gift = true;
  210. $user = User::where('uid', $uid)->field(['avatar', 'nickname'])->find();
  211. }
  212. return compact('user', 'is_gift', 'image', 'add_time', 'title');
  213. }
  214. /**
  215. * 获取订单的专题详情信息
  216. * @param $order_id 订单号
  217. * @return bool
  218. * @throws \think\db\exception\DataNotFoundException
  219. * @throws \think\db\exception\ModelNotFoundException
  220. * @throws \think\exception\DbException
  221. */
  222. public static function getOrderIdToSpecial($order_id, $uid)
  223. {
  224. $order = self::where(['is_del' => 0, 'order_id' => $order_id, 'uid' => $uid])->find();
  225. if (!$order) return self::setErrorInfo('订单不存在或给订单不是您的!');
  226. if (!$order->cart_id) return self::setErrorInfo('订单专题不存在!');
  227. $special = Special::PreWhere()->where(['id' => $order->cart_id])->find();
  228. if (!$special) return self::setErrorInfo('赠送的专题已下架,或已被删除!');
  229. $special->abstract = self::HtmlToMbStr($special->abstract);
  230. return $special->toArray();
  231. }
  232. /**
  233. * 创建领取礼物订单
  234. * @param $orderId 订单号
  235. * @param $uid
  236. * @return bool
  237. * @throws \think\db\exception\DataNotFoundException
  238. * @throws \think\db\exception\ModelNotFoundException
  239. * @throws \think\exception\DbException
  240. */
  241. public static function createReceiveGift($orderId, $uid)
  242. {
  243. $order = self::where(['is_del' => 0, 'order_id' => $orderId, 'paid' => 1])->find();
  244. if (!$order) return self::setErrorInfo('赠送的礼物订单不存在');
  245. if ($order->total_num == $order->gift_count) return self::setErrorInfo('礼物已被领取完');
  246. if (SpecialBuy::be(['special_id' => $order['cart_id'], 'uid' => $uid])) return self::setErrorInfo('您已拥有此专题无法,进行领取');
  247. $data = [
  248. 'uid' => $uid,
  249. 'order_id' => self::getNewOrderId(),
  250. 'cart_id' => $order->cart_id,
  251. 'total_num' => 1,
  252. 'total_price' => $order->total_price,
  253. 'gift_count' => 1,
  254. 'pay_price' => 0,
  255. 'paid' => 1,
  256. 'pay_time' => time(),
  257. 'is_receive_gift' => 1,
  258. 'mark' => '礼物领取订单',
  259. 'unique' => md5(time() . '' . $uid . $order->cart_id),
  260. 'cost' => $order->total_price,
  261. 'pay_type' => $order->pay_type,
  262. 'gift_order_id' => $orderId
  263. ];
  264. $order->gift_count += 1;
  265. if ($order->save() && ($order = self::set($data))) {
  266. SpecialBuy::setAllBuySpecial($order['order_id'], $order['uid'], $order['cart_id'], 2);
  267. StoreOrderStatus::status($order['id'], 'cache_key_create_order', '订单生成');
  268. TestPaperObtain::setTestPaper($order['order_id'], $order['uid'], $order['cart_id'], 2);
  269. DataDownloadBuy::setDataDownload($order['order_id'], $order['uid'], $order['cart_id'], 0);
  270. return true;
  271. } else
  272. return self::setErrorInfo('领取礼物订单生成失败');
  273. }
  274. /**
  275. * 创建订单专题订单
  276. * @param $special
  277. * @param $pinkId
  278. * @param $pay_type
  279. * @param $uid
  280. * @param $payType
  281. * @param int $link_pay_uid
  282. * @param int $total_num
  283. * @return bool|object
  284. */
  285. public static function createSpecialOrder($special, $pinkId, $pay_type, $uid, $payType, $link_pay_uid = 0, $total_num = 1)
  286. {
  287. if (!array_key_exists($payType, self::$payType)) return self::setErrorInfo('选择支付方式有误!');
  288. $userInfo = User::getUserData($uid);
  289. if (!$userInfo) return self::setErrorInfo('用户不存在!');
  290. $total_price = 0;
  291. $combination_id = 0;
  292. switch ((int)$pay_type) {
  293. case 1:
  294. //送朋友
  295. $total_price = $special->money;
  296. if (isset($userInfo['level']) && $userInfo['level'] > 0 && $special->member_pay_type == 1 && $special->member_money > 0) {
  297. $total_price = $special->member_money;
  298. }
  299. break;
  300. case 2:
  301. //自己买
  302. $total_price = $special->money;
  303. if (isset($userInfo['level']) && $userInfo['level'] > 0 && $special->member_pay_type == 1 && $special->member_money > 0) {
  304. $total_price = $special->member_money;
  305. }
  306. $res = SpecialBuy::PaySpecial($special->id, $uid);
  307. if ($res) return self::setErrorInfo('您已获得专题,无需再次购买!');
  308. break;
  309. case 3:
  310. //参与拼团
  311. if (!$special->is_pink && $special->pink_end_time < date('Y-m-d H:i:s', time())) return self::setErrorInfo('拼团已结束或暂没有开团');
  312. $total_price = $special->pink_money;
  313. $combination_id = $special->id;
  314. $res = SpecialBuy::PaySpecial($special->id, $uid);
  315. if ($res) return self::setErrorInfo('您已获得专题,不能参与拼团!');
  316. $order = self::where(['uid' => $uid, 'cart_id' => $special->id, 'paid' => 1, 'combination_id' => $combination_id, 'pink_id' => $pinkId, 'is_gift' => 0, 'type' => 0, 'status' => 0, 'refund_status' => 0, 'is_del' => 0])->find();
  317. if ($order) return self::setErrorInfo('您已参与拼团,不能参与拼团!');
  318. break;
  319. }
  320. $orderInfo = [
  321. 'uid' => $uid,
  322. 'mer_id' => $special->mer_id,
  323. 'order_id' => self::getNewOrderId(),
  324. 'cart_id' => $special->id,
  325. 'total_num' => $total_num,
  326. 'total_price' => $total_price,
  327. 'pay_price' => $total_price,
  328. 'pay_type' => $payType,
  329. 'combination_id' => $combination_id,
  330. 'is_gift' => $pay_type == 1 ? 1 : 0,
  331. 'pink_time' => $pay_type == 3 ? $special->pink_time : 0,
  332. 'paid' => 0,
  333. 'pink_id' => $pinkId,
  334. 'unique' => md5(time() . '' . $uid . $special->id),
  335. 'cost' => $total_price,
  336. 'link_pay_uid' => $userInfo['spread_uid'] ? 0 : $link_pay_uid,
  337. 'spread_uid' => $userInfo['spread_uid'] ? $userInfo['spread_uid'] : 0,
  338. 'is_del' => 0,
  339. ];
  340. $order = self::set($orderInfo);
  341. if (!$order) return self::setErrorInfo('订单生成失败!');
  342. StoreOrderStatus::status($order['id'], 'cache_key_create_order', '订单生成');
  343. return $order;
  344. }
  345. /**
  346. * 创建商品订单
  347. * @param $uid
  348. * @param $key
  349. * @param $addressId
  350. * @param $payType
  351. * @param string $mark
  352. * @return bool|object
  353. * @throws \think\db\exception\DataNotFoundException
  354. * @throws \think\db\exception\ModelNotFoundException
  355. * @throws \think\exception\DbException
  356. */
  357. public static function cacheKeyCreateOrder($uid, $key, $addressId, $payType, $useGold, $mark = '')
  358. {
  359. if (!array_key_exists($payType, self::$payType)) return self::setErrorInfo('选择支付方式有误!');
  360. if (self::be(['unique' => $key, 'uid' => $uid])) return self::setErrorInfo('请勿重复提交订单');
  361. $userInfo = User::getUserData($uid);
  362. if (!$userInfo) return self::setErrorInfo('用户不存在!');
  363. $cartGroup = self::getCacheOrderInfo($uid, $key);
  364. if (!$cartGroup) return self::setErrorInfo('订单已过期,请刷新当前页面!');
  365. $cartInfo = $cartGroup['cartInfo'];
  366. $priceGroup = $cartGroup['priceGroup'];
  367. $payPrice = $priceGroup['totalPrice'];
  368. $payPostage = $priceGroup['storePostage'];
  369. if (!$addressId) return self::setErrorInfo('请选择收货地址!');
  370. if (!UserAddress::be(['uid' => $uid, 'id' => $addressId, 'is_del' => 0]) || !($addressInfo = UserAddress::find($addressId)))
  371. return self::setErrorInfo('地址选择有误!');
  372. $payPrice = bcadd($payPrice, $payPostage, 2);
  373. $cartIds = [];
  374. $totalNum = 0;
  375. $giveGoldNum = 0;
  376. $mer_id = 0;
  377. foreach ($cartInfo as $cart) {
  378. $cartIds[] = $cart['id'];
  379. $totalNum += $cart['cart_num'];
  380. $giveGoldNum = bcadd($giveGoldNum, $cart['productInfo']['give_gold_num'], 2);
  381. $mer_id = $cart['productInfo']['mer_id'];
  382. }
  383. //虚拟币抵扣
  384. $res2 = true;
  385. $gold_name = SystemConfigService::get('gold_name');
  386. if ($useGold && $userInfo['gold_num'] > 0 && $payPrice > 0) {
  387. $ratio = SystemConfigService::get('deduction_proportion_ratio');
  388. $ratio = bcdiv($ratio, 100, 2);
  389. $deductionPrice = bcmul($userInfo['gold_num'], $ratio, 2);
  390. if ($deductionPrice < $payPrice) {
  391. $payPrice = bcsub($payPrice, $deductionPrice, 2);
  392. $usedGold = $userInfo['gold_num'];
  393. $res2 = false !== User::edit(['gold_num' => 0], $userInfo['uid'], 'uid');
  394. } else {
  395. $deductionPrice = $payPrice;
  396. $usedGold = bcdiv($payPrice, $ratio, 2);
  397. $res2 = false !== User::bcDec($userInfo['uid'], 'gold_num', $usedGold, 'uid');
  398. $payPrice = 0;
  399. }
  400. $res2 = $res2 && false != UserBill::expend($gold_name . '抵扣', $uid, 'gold_num', 'deduction', $usedGold, $key, $userInfo['gold_num'], '购买商品使用' . floatval($usedGold) . $gold_name . '抵扣' . floatval($deductionPrice) . '元');
  401. } else {
  402. $deductionPrice = 0;
  403. $usedGold = 0;
  404. }
  405. if (!$res2) return self::setErrorInfo($gold_name . '抵扣失败!');
  406. $orderInfo = [
  407. 'uid' => $uid,
  408. 'order_id' => self::getNewOrderId(),
  409. 'mer_id' => $mer_id,
  410. 'type' => 2,
  411. 'real_name' => $addressInfo['real_name'],
  412. 'user_phone' => $addressInfo['phone'],
  413. 'user_address' => $addressInfo['province'] . ' ' . $addressInfo['city'] . ' ' . $addressInfo['district'] . ' ' . $addressInfo['detail'],
  414. 'cart_id' => $cartIds,
  415. 'total_num' => $totalNum,
  416. 'total_price' => $priceGroup['totalPrice'],
  417. 'total_postage' => $priceGroup['storePostage'],
  418. 'pay_price' => $payPrice,
  419. 'pay_postage' => $payPostage,
  420. 'paid' => 0,
  421. 'pay_type' => $payType,
  422. 'gain_gold_num' => $giveGoldNum,
  423. 'use_gold' => $usedGold,
  424. 'deduction_price' => $deductionPrice,
  425. 'mark' => htmlspecialchars($mark),
  426. 'cost' => $priceGroup['costPrice'],
  427. 'unique' => $key
  428. ];
  429. $order = self::set($orderInfo);
  430. if (!$order) return self::setErrorInfo('订单生成失败!');
  431. $res5 = true;
  432. foreach ($cartInfo as $cart) {
  433. //减库存加销量
  434. $res5 = $res5 && StoreProduct::decProductStock($cart['cart_num'], $cart['productInfo']['id'], isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique'] : '');
  435. }
  436. //保存购物车商品信息
  437. $res4 = false !== StoreOrderCartInfo::setCartInfo($order['id'], $cartInfo);
  438. //购物车状态修改
  439. $res6 = false !== StoreCart::where('id', 'IN', $cartIds)->update(['is_pay' => 1]);
  440. if (!$res4 || !$res5 || !$res6) return self::setErrorInfo('订单生成失败!');
  441. try {
  442. HookService::listen('store_product_order_create', $order, compact('cartInfo', 'addressId'), false, StoreProductBehavior::class);
  443. } catch (\Exception $e) {
  444. return self::setErrorInfo($e->getMessage());
  445. }
  446. self::clearCacheOrderInfo($uid, $key);
  447. self::commitTrans();
  448. StoreOrderStatus::status($order['id'], 'cache_key_create_order', '订单生成');
  449. return $order;
  450. }
  451. /**创建会员订单
  452. * @param $uid
  453. * @param $kid
  454. * @return bool|object
  455. * @throws \think\db\exception\DataNotFoundException
  456. * @throws \think\db\exception\ModelNotFoundException
  457. * @throws \think\exception\DbException
  458. */
  459. public static function cacheMemberCreateOrder($uid, $id, $payType)
  460. {
  461. if (!array_key_exists($payType, self::$payType)) return self::setErrorInfo('选择支付方式有误!');
  462. $userInfo = User::getUserData($uid);
  463. if (!$userInfo) return self::setErrorInfo('用户不存在!');
  464. if ($userInfo['level'] && $userInfo['is_permanent']) return self::setErrorInfo('您是永久会员,无需续费!');
  465. $member = MemberShip::where('id', $id)->where('is_publish', 1)->where('is_del', 0)->where('type', 1)->find();
  466. if ($member['is_free']) {
  467. if (self::be(['uid' => $uid, 'member_id' => $id, 'is_del' => 0])) return self::setErrorInfo('免费会员不能重复领取!');
  468. }
  469. $orderInfo = [
  470. 'uid' => $uid,
  471. 'order_id' => self::getNewOrderId(),
  472. 'type' => 1,
  473. 'member_id' => $id,
  474. 'total_num' => 1,
  475. 'total_price' => $member['original_price'],
  476. 'pay_price' => $member['price'],
  477. 'pay_type' => $payType,
  478. 'combination_id' => 0,
  479. 'is_gift' => 0,
  480. 'pink_time' => 0,
  481. 'paid' => 0,
  482. 'pink_id' => 0,
  483. 'unique' => md5(time() . '' . $uid . $id),
  484. 'cost' => $member['original_price'],
  485. 'link_pay_uid' => 0,
  486. 'spread_uid' => $userInfo['spread_uid'] ? $userInfo['spread_uid'] : 0,
  487. 'is_del' => 0,
  488. ];
  489. $order = self::set($orderInfo);
  490. if (!$order) return self::setErrorInfo('订单生成失败!');
  491. StoreOrderStatus::status($order['id'], 'cache_key_create_order', '订单生成');
  492. return $order;
  493. }
  494. public static function getNewOrderId()
  495. {
  496. $count = (int)self::where('add_time', ['>=', strtotime(date("Y-m-d"))], ['<', strtotime(date("Y-m-d", strtotime('+1 day')))])->count();
  497. return 'wx' . date('YmdHis', time()) . (10000 + $count + 1);
  498. }
  499. public static function changeOrderId($orderId)
  500. {
  501. $ymd = substr($orderId, 2, 8);
  502. $key = substr($orderId, 16);
  503. return 'wx' . $ymd . date('His') . $key;
  504. }
  505. /**
  506. * 微信支付 为 0元时 商品
  507. * @param $order_id
  508. * @param $uid
  509. * @return bool
  510. */
  511. public static function jsPayGoodsPrice($order_id, $uid)
  512. {
  513. $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->where('type', 2)->where('is_del', 0)->find();
  514. if (!$orderInfo) return self::setErrorInfo('订单不存在!');
  515. if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
  516. $userInfo = User::getUserData($uid);
  517. self::beginTrans();
  518. $res1 = UserBill::expend('购买商品', $uid, 'now_money', 'pay_goods', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '支付' . floatval($orderInfo['pay_price']) . '元购买商品');
  519. $res2 = self::payGoodsSuccess($order_id);
  520. $res = $res1 && $res2;
  521. self::checkTrans($res);
  522. return $res;
  523. }
  524. /**商品微信
  525. * @param $orderId
  526. * @param string $field
  527. * @return array|string
  528. * @throws \think\db\exception\DataNotFoundException
  529. * @throws \think\db\exception\ModelNotFoundException
  530. * @throws \think\exception\DbException
  531. */
  532. public static function jsPay($orderId, $field = 'order_id')
  533. {
  534. if (is_string($orderId))
  535. $orderInfo = self::where($field, $orderId)->where('type', 2)->find();
  536. else
  537. $orderInfo = $orderId;
  538. if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  539. if ($orderInfo['paid']) exception('支付已支付!');
  540. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  541. $openid = WechatUser::uidToOpenid($orderInfo['uid']);
  542. return WechatService::jsPay($openid, $orderInfo['order_id'], $orderInfo['pay_price'], 'goods', SystemConfigService::get('site_name'));
  543. }
  544. /**
  545. * 微信h5支付
  546. * @param $orderId
  547. * @param string $field
  548. * @return array|string
  549. * @throws \think\db\exception\DataNotFoundException
  550. * @throws \think\db\exception\ModelNotFoundException
  551. * @throws \think\exception\DbException
  552. */
  553. public static function h5Pay($orderId, $field = 'order_id')
  554. {
  555. if (is_string($orderId))
  556. $orderInfo = self::where($field, $orderId)->find();
  557. else
  558. $orderInfo = $orderId;
  559. if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  560. if ($orderInfo['paid']) exception('支付已支付!');
  561. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  562. $site_name = SystemConfigService::get('site_name');
  563. if (!$site_name) exception('支付参数缺少:请前往后台设置->系统设置-> 填写 网站名称');
  564. return WechatService::paymentPrepare(null, $orderInfo['order_id'], $orderInfo['pay_price'], 'goods', self::getSubstrUTf8($site_name . '-商品购买', 30), '', 'MWEB');
  565. }
  566. /**商品余额支付
  567. * @param $order_id
  568. * @param $uid
  569. * @return bool
  570. * @throws \think\db\exception\DataNotFoundException
  571. * @throws \think\db\exception\ModelNotFoundException
  572. * @throws \think\exception\DbException
  573. */
  574. public static function yueGoodsPay($order_id, $uid)
  575. {
  576. $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->where('type', 2)->where('is_del', 0)->find();
  577. if (!$orderInfo) return self::setErrorInfo('订单不存在!');
  578. if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
  579. if ($orderInfo['pay_type'] != 'yue') return self::setErrorInfo('该订单不能使用余额支付!');
  580. $userInfo = User::getUserData($uid);
  581. if ($userInfo['now_money'] < $orderInfo['pay_price']) return self::setErrorInfo('余额不足' . floatval($orderInfo['pay_price']));
  582. self::beginTrans();
  583. $res1 = false !== User::bcDec($uid, 'now_money', $orderInfo['pay_price'], 'uid');
  584. $res2 = UserBill::expend('购买商品', $uid, 'now_money', 'pay_goods', $orderInfo['pay_price'], $orderInfo['id'], bcsub($userInfo['now_money'], $orderInfo['pay_price'], 2), '余额支付' . floatval($orderInfo['pay_price']) . '元购买商品');
  585. $res3 = self::payGoodsSuccess($order_id);
  586. try {
  587. HookService::listen('yue_pay_product', $userInfo, $orderInfo, false, PaymentBehavior::class);
  588. } catch (\Exception $e) {
  589. self::rollbackTrans();
  590. return self::setErrorInfo($e->getMessage());
  591. }
  592. $res = $res1 && $res2 && $res3;
  593. self::checkTrans($res);
  594. return $res;
  595. }
  596. /**专题微信支付
  597. * @param $orderId
  598. * @param string $field
  599. * @return array|string
  600. * @throws \think\db\exception\DataNotFoundException
  601. * @throws \think\db\exception\ModelNotFoundException
  602. * @throws \think\exception\DbException
  603. */
  604. public static function jsSpecialPay($orderId, $field = 'order_id')
  605. {
  606. if (is_string($orderId))
  607. $orderInfo = self::where($field, $orderId)->find();
  608. else
  609. $orderInfo = $orderId;
  610. if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  611. if ($orderInfo['paid']) exception('支付已支付!');
  612. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  613. $site_name = SystemConfigService::get('site_name');
  614. $openid = WechatUser::uidToOpenid($orderInfo['uid']);
  615. return WechatService::jsPay($openid, $orderInfo['order_id'], $orderInfo['pay_price'], 'special', self::getSubstrUTf8($site_name, 30));
  616. }
  617. /**
  618. * 微信h5支付
  619. * @param $orderId
  620. * @param string $field
  621. * @return array|string
  622. * @throws \think\db\exception\DataNotFoundException
  623. * @throws \think\db\exception\ModelNotFoundException
  624. * @throws \think\exception\DbException
  625. */
  626. public static function h5SpecialPay($orderId, $field = 'order_id')
  627. {
  628. if (is_string($orderId))
  629. $orderInfo = self::where($field, $orderId)->find();
  630. else
  631. $orderInfo = $orderId;
  632. if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  633. if ($orderInfo['paid']) exception('支付已支付!');
  634. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  635. $site_name = SystemConfigService::get('site_name');
  636. if (!$site_name) exception('支付参数缺少:请前往后台设置->系统设置-> 填写 网站名称');
  637. return WechatService::paymentPrepare(null, $orderInfo['order_id'], $orderInfo['pay_price'], 'special', self::getSubstrUTf8($site_name . '-专题购买', 30), '', 'MWEB');
  638. }
  639. /**专题余额支付
  640. * @param $order_id
  641. * @param $uid
  642. * @return bool
  643. * @throws \think\db\exception\DataNotFoundException
  644. * @throws \think\db\exception\ModelNotFoundException
  645. * @throws \think\exception\DbException
  646. */
  647. public static function yuePay($order_id, $uid)
  648. {
  649. $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->where('is_del', 0)->find();
  650. if (!$orderInfo) return self::setErrorInfo('订单不存在!');
  651. if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
  652. if ($orderInfo['pay_type'] != 'yue') return self::setErrorInfo('该订单不能使用余额支付!');
  653. $userInfo = User::getUserData($uid);
  654. if ($userInfo['now_money'] < $orderInfo['pay_price']) return self::setErrorInfo('余额不足' . floatval($orderInfo['pay_price']));
  655. self::beginTrans();
  656. $res1 = false !== User::bcDec($uid, 'now_money', $orderInfo['pay_price'], 'uid');
  657. $res2 = UserBill::expend('购买专题', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], bcsub($userInfo['now_money'], $orderInfo['pay_price'], 2), '余额支付' . floatval($orderInfo['pay_price']) . '元购买专题');
  658. $res3 = self::paySuccess($order_id);
  659. try {
  660. HookService::listen('yue_pay_product', $userInfo, $orderInfo, false, PaymentBehavior::class);
  661. } catch (\Exception $e) {
  662. self::rollbackTrans();
  663. return self::setErrorInfo($e->getMessage());
  664. }
  665. $res = $res1 && $res2 && $res3;
  666. self::checkTrans($res);
  667. return $res;
  668. }
  669. /**
  670. * 微信支付 为 0元时
  671. * @param $order_id
  672. * @param $uid
  673. * @return bool
  674. */
  675. public static function jsPayPrice($order_id, $uid)
  676. {
  677. $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->where('is_del', 0)->find();
  678. if (!$orderInfo) return self::setErrorInfo('订单不存在!');
  679. if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
  680. $userInfo = User::getUserData($uid);
  681. self::beginTrans();
  682. $res1 = UserBill::expend('购买专题', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '支付' . floatval($orderInfo['pay_price']) . '元购买专题');
  683. $res2 = self::paySuccess($order_id);
  684. $res = $res1 && $res2;
  685. self::checkTrans($res);
  686. return $res;
  687. }
  688. /**
  689. * 微信支付 为 0元时
  690. * @param $order_id
  691. * @param $uid
  692. * @return bool
  693. */
  694. public static function jsPayMePrice($order_id, $uid)
  695. {
  696. $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->where('is_del', 0)->find();
  697. if (!$orderInfo) return self::setErrorInfo('订单不存在!');
  698. if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
  699. $userInfo = User::getUserData($uid);
  700. self::beginTrans();
  701. $res1 = UserBill::expend('购买会员', $uid, 'now_money', 'pay_vip', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '支付' . floatval($orderInfo['pay_price']) . '元购买会员');
  702. $res2 = self::payMeSuccess($order_id);
  703. $res = $res1 && $res2;
  704. self::checkTrans($res);
  705. return $res;
  706. }
  707. /**会员微信支付
  708. * @param $orderId
  709. * @param string $field
  710. * @return array|string
  711. * @throws \think\db\exception\DataNotFoundException
  712. * @throws \think\db\exception\ModelNotFoundException
  713. * @throws \think\exception\DbException
  714. */
  715. public static function jsPayMember($orderId, $field = 'order_id')
  716. {
  717. if (is_string($orderId))
  718. $orderInfo = self::where($field, $orderId)->find();
  719. else
  720. $orderInfo = $orderId;
  721. if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  722. if ($orderInfo['paid']) exception('支付已支付!');
  723. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  724. $openid = WechatUser::uidToOpenid($orderInfo['uid']);
  725. return WechatService::jsPay($openid, $orderInfo['order_id'], $orderInfo['pay_price'], 'member', SystemConfigService::get('site_name'));
  726. }
  727. /**
  728. * 微信h5支付
  729. * @param $orderId
  730. * @param string $field
  731. * @return array|string
  732. * @throws \think\db\exception\DataNotFoundException
  733. * @throws \think\db\exception\ModelNotFoundException
  734. * @throws \think\exception\DbException
  735. */
  736. public static function h5PayMember($orderId, $field = 'order_id')
  737. {
  738. if (is_string($orderId))
  739. $orderInfo = self::where($field, $orderId)->find();
  740. else
  741. $orderInfo = $orderId;
  742. if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  743. if ($orderInfo['paid']) exception('支付已支付!');
  744. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  745. $site_name = SystemConfigService::get('site_name');
  746. if (!$site_name) exception('支付参数缺少:请前往后台设置->系统设置-> 填写 网站名称');
  747. return WechatService::paymentPrepare(null, $orderInfo['order_id'], $orderInfo['pay_price'], 'member', self::getSubstrUTf8($site_name . '-会员购买', 30), '', 'MWEB');
  748. }
  749. public static function yuePayMember($order_id, $uid)
  750. {
  751. $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->where('is_del', 0)->find();
  752. if (!$orderInfo) return self::setErrorInfo('订单不存在!');
  753. if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
  754. if ($orderInfo['pay_type'] != 'yue') return self::setErrorInfo('该订单不能使用余额支付!');
  755. $userInfo = User::getUserData($uid);
  756. if ($userInfo['now_money'] < $orderInfo['pay_price']) return self::setErrorInfo('余额不足' . floatval($orderInfo['pay_price']));
  757. self::beginTrans();
  758. $res1 = false !== User::bcDec($uid, 'now_money', $orderInfo['pay_price'], 'uid');
  759. $res3 = self::payMeSuccess($order_id);
  760. $res = $res1 && $res3;
  761. self::checkTrans($res);
  762. return $res;
  763. }
  764. public static function yueRefundAfter($order)
  765. {
  766. }
  767. /**
  768. * 用户申请退款
  769. * @param $uni
  770. * @param $uid
  771. * @param string $refundReasonWap
  772. * @return bool
  773. */
  774. public static function orderApplyRefund($uni, $uid, $data)
  775. {
  776. $order = self::getUserOrderDetail($uid, $uni);
  777. if (!$order) return self::setErrorInfo('支付订单不存在!');
  778. if ($order['refund_status'] == 2) return self::setErrorInfo('订单已退款!');
  779. if ($order['refund_status'] == 1) return self::setErrorInfo('正在申请退款中!');
  780. if ($order['status'] == 1) return self::setErrorInfo('订单当前无法退款!');
  781. self::beginTrans();
  782. $res1 = false !== StoreOrderStatus::status($order['id'], 'apply_refund', '用户申请退款,原因:' . $data['refund_reason']);
  783. $res2 = false !== self::edit(['refund_status' => 1, 'refund_application_time' => time(), 'refund_reason_wap' => $data['refund_reason'], 'refund_reason_wap_img' => json_encode($data['pics']), 'mark' => $data['remarks']], $order['id'], 'id');
  784. $res = $res1 && $res2;
  785. self::checkTrans($res);
  786. if (!$res)
  787. return self::setErrorInfo('申请退款失败!');
  788. else {
  789. return $res;
  790. }
  791. }
  792. /**
  793. * 自动退款
  794. * @param array $order
  795. * */
  796. public static function autoRefundY($order)
  797. {
  798. if (!$order['pink_id']) return true;
  799. $refund_data = [
  800. 'pay_price' => $order['pay_price'],
  801. 'refund_price' => $order['pay_price'],
  802. ];
  803. switch ($order['pay_type']) {
  804. case 'weixin':
  805. if ($order['is_channel']) {
  806. try {
  807. HookService::listen('routine_pay_order_refund', $order['order_id'], $refund_data, true, PaymentBehavior::class);
  808. } catch (\Exception $e) {
  809. return self::setErrorInfo($e->getMessage());
  810. }
  811. } else {
  812. try {
  813. HookService::listen('wechat_pay_order_refund', $order['order_id'], $refund_data, true, PaymentBehavior::class);
  814. } catch (\Exception $e) {
  815. return self::setErrorInfo($e->getMessage());
  816. }
  817. }
  818. break;
  819. case 'yue':
  820. ModelBasic::beginTrans();
  821. $res1 = User::bcInc($order['uid'], 'now_money', $refund_data['pay_price'], 'uid');
  822. $res2 = $res2 = UserBill::income('商品退款', $order['uid'], 'now_money', 'pay_product_refund', $refund_data['pay_price'], $order['id'], $order['pay_price'], '订单退款到余额' . floatval($refund_data['pay_price']) . '元');
  823. try {
  824. HookService::listen('store_order_yue_refund', $order, $refund_data, false, StoreProductBehavior::class);
  825. } catch (\Exception $e) {
  826. ModelBasic::rollbackTrans();
  827. return self::setErrorInfo($e->getMessage());
  828. }
  829. $res = $res1 && $res2;
  830. ModelBasic::checkTrans($res);
  831. if (!$res) return self::setErrorInfo('余额退款失败!');
  832. break;
  833. case 'zhifubao':
  834. AlipayTradeWapService::init()->AliPayRefund($order['order_id'], $order['trade_no'], $order['pay_price'], '拼团失败退款', 'refund');
  835. break;
  836. }
  837. $data = [
  838. 'refund_status' => 2,
  839. 'refund_reason_time' => time(),
  840. 'refund_price' => $order['pay_price'],
  841. 'status' => -1,
  842. ];
  843. self::edit($data, $order['id'], 'id');
  844. StorePink::setRefundPink($order['pink_id']);
  845. HookService::afterListen('store_product_order_refund_y', $data, $order['id'], false, StoreProductBehavior::class);
  846. StoreOrderStatus::status($order['id'], 'refund_price', '自动发起退款,退款给用户' . $order['pay_price'] . '元');
  847. return true;
  848. }
  849. /**
  850. * //TODO 专题支付成功后
  851. * @param $orderId
  852. * @param $notify
  853. * @return bool
  854. */
  855. public static function paySuccess($orderId)
  856. {
  857. $order = self::where('order_id', $orderId)->where('type', 0)->find();
  858. if (!$order) return false;
  859. $resPink = true;
  860. $res2 = true;
  861. $res3 = true;
  862. User::bcInc($order['uid'], 'pay_count', 1, 'uid');
  863. $res1 = self::where('order_id', $orderId)->where('type', 0)->update(['paid' => 1, 'pay_time' => time()]);
  864. if ($res1 && $order['pay_type'] != 'yue') {
  865. $res2 = UserBill::expend('购买专题', $order['uid'], $order['pay_type'], 'pay_product', $order['pay_price'], $order['id'], 0, '支付' . floatval($order['pay_price']) . '元购买专题');
  866. }
  867. if ($res1) {
  868. $res3 = MerchantFlowingWater::setMerchantFlowingWater($order, 0);
  869. }
  870. if ($order['combination_id'] && $res1 && !$order['refund_status']) {
  871. $resPink = StorePink::createPink($order);//创建拼团
  872. } else {
  873. if (!$order['is_gift']) {
  874. //如果是专栏,记录专栏下所有专题购买。
  875. SpecialBuy::setAllBuySpecial($orderId, $order['uid'], $order['cart_id']);
  876. TestPaperObtain::setTestPaper($orderId, $order['uid'], $order['cart_id'], 2);
  877. DataDownloadBuy::setDataDownload($orderId, $order['uid'], $order['cart_id'], 0);
  878. try {
  879. //专题返佣
  880. User::backOrderBrokerage($order);
  881. } catch (\Throwable $e) {
  882. }
  883. }
  884. }
  885. StoreOrderStatus::status($order->id, 'pay_success', '用户付款成功');
  886. $site_url = SystemConfigService::get('site_url');
  887. try {
  888. $wechat_notification_message = SystemConfigService::get('wechat_notification_message');
  889. if ($wechat_notification_message == 1) {
  890. WechatTemplateService::sendTemplate(WechatUser::where('uid', $order['uid'])->value('openid'), WechatTemplateService::ORDER_PAY_SUCCESS, [
  891. 'first' => '亲,您购买的专题已支付成功',
  892. 'keyword1' => $orderId,
  893. 'keyword2' => $order['pay_price'],
  894. 'remark' => '点击查看订单详情'
  895. ], $site_url . Url::build('wap/special/grade_list'));
  896. WechatTemplateService::sendAdminNoticeTemplate([
  897. 'first' => "亲,您有一个新的课程订单",
  898. 'keyword1' => $orderId,
  899. 'keyword2' => $order['pay_price'],
  900. 'remark' => '请及时查看'
  901. ]);
  902. } else {
  903. $data['character_string1']['value'] = $orderId;
  904. $data['amount3']['value'] = $order['pay_price'];
  905. $data['time2']['value'] = date('Y-m-d H:i:s', time());
  906. $data['thing6']['value'] = '您购买的专题已支付成功!';
  907. RoutineTemplate::sendOrderSuccess($data, $order['uid'], $site_url . Url::build('wap/special/grade_list'));
  908. $dataAdmin['character_string1']['value'] = $orderId;
  909. $dataAdmin['amount3']['value'] = $order['pay_price'];
  910. $dataAdmin['time2']['value'] = date('Y-m-d H:i:s', time());
  911. $dataAdmin['thing6']['value'] = '您有一个新的课程订单!';
  912. RoutineTemplate::sendAdminNoticeTemplate($dataAdmin);
  913. }
  914. } catch (\Throwable $e) {
  915. }
  916. $res = $res1 && $resPink && $res2 && $res3;
  917. return false !== $res;
  918. }
  919. /**
  920. * //TODO 会员支付成功后
  921. * @param $orderId
  922. * @param $notify
  923. * @return bool
  924. */
  925. public static function payMeSuccess($orderId)
  926. {
  927. $order = self::where('order_id', $orderId)->where('type', 1)->find();
  928. if (!$order) return false;
  929. $resMer = true;
  930. $res2 = true;
  931. $res1 = self::where('order_id', $orderId)->where('type', 1)->update(['paid' => 1, 'pay_time' => time()]);
  932. $userInfo = User::getUserData($order['uid']);
  933. if ($order['type'] == 1 && $res1 && !$order['refund_status']) {
  934. if ($order['pay_type'] != 'yue') {
  935. $res2 = UserBill::expend('购买会员', $order['uid'], $order['pay_type'], 'pay_vip', $order['pay_price'], $order['id'], 0, '支付' . floatval($order['pay_price']) . '元购买会员');
  936. }
  937. $resMer = MemberShip::getUserMember($order, $userInfo);
  938. try {
  939. //会员返佣
  940. User::backOrderBrokerageMember($order);
  941. } catch (\Throwable $e) {
  942. }
  943. }
  944. $site_url = SystemConfigService::get('site_url');
  945. try {
  946. $wechat_notification_message = SystemConfigService::get('wechat_notification_message');
  947. if ($wechat_notification_message == 1) {
  948. WechatTemplateService::sendTemplate(WechatUser::where('uid', $order['uid'])->value('openid'), WechatTemplateService::ORDER_PAY_SUCCESS, [
  949. 'first' => '亲,您充值会员已支付成功',
  950. 'keyword1' => $orderId,
  951. 'keyword2' => $order['pay_price'],
  952. 'remark' => '点击查看会员详情'
  953. ], $site_url . Url::build('wap/special/member_recharge'));
  954. WechatTemplateService::sendAdminNoticeTemplate([
  955. 'first' => "亲,您有一个新的会员购买订单",
  956. 'keyword1' => $orderId,
  957. 'keyword2' => $order['pay_price'],
  958. 'remark' => '请及时查看'
  959. ]);
  960. } else {
  961. $data['character_string1']['value'] = $orderId;
  962. $data['amount3']['value'] = $order['pay_price'];
  963. $data['time2']['value'] = date('Y-m-d H:i:s', time());
  964. $data['thing6']['value'] = '您充值会员已支付成功!';
  965. RoutineTemplate::sendOrderSuccess($data, $order['uid'], $site_url . Url::build('wap/special/member_recharge'));
  966. $dataAdmin['character_string1']['value'] = $orderId;
  967. $dataAdmin['amount3']['value'] = $order['pay_price'];
  968. $dataAdmin['time2']['value'] = date('Y-m-d H:i:s', time());
  969. $dataAdmin['thing6']['value'] = '您有一个新的会员购买订单!';
  970. RoutineTemplate::sendAdminNoticeTemplate($dataAdmin);
  971. }
  972. } catch (\Throwable $e) {
  973. }
  974. StoreOrderStatus::status($order['id'], 'pay_success', '用户付款成功');
  975. $res = $res1 && $res2 && $resMer;
  976. return false !== $res;
  977. }
  978. /**
  979. * //TODO 商品支付成功后
  980. * @param $orderId
  981. * @param $notify
  982. * @return bool
  983. */
  984. public static function payGoodsSuccess($orderId)
  985. {
  986. $order = self::where('order_id', $orderId)->where('type', 2)->find();
  987. if (!$order) return false;
  988. $res1 = self::where('order_id', $orderId)->where('type', 2)->update(['paid' => 1, 'pay_time' => time()]);
  989. $site_url = SystemConfigService::get('site_url');
  990. $res2 = true;
  991. $res3 = true;
  992. try {
  993. if ($res1 && $order['pay_type'] != 'yue') {
  994. $res2 = UserBill::expend('购买商品', $order['uid'], $order['pay_type'], 'pay_goods', $order['pay_price'], $order['id'], 0, '支付' . floatval($order['pay_price']) . '元购买商品');
  995. }
  996. if ($res1) {
  997. $res3 = MerchantFlowingWater::setMerchantFlowingWater($order, 2);
  998. }
  999. $wechat_notification_message = SystemConfigService::get('wechat_notification_message');
  1000. if ($wechat_notification_message == 1) {
  1001. WechatTemplateService::sendTemplate(WechatUser::where('uid', $order['uid'])->value('openid'), WechatTemplateService::ORDER_PAY_SUCCESS, [
  1002. 'first' => '亲,您购买的商品已支付成功',
  1003. 'keyword1' => $orderId,
  1004. 'keyword2' => $order['pay_price'],
  1005. 'remark' => '点击查看订单详情'
  1006. ], $site_url . Url::build('wap/special/order_store_list'));
  1007. WechatTemplateService::sendAdminNoticeTemplate([
  1008. 'first' => "亲,您有一个新的商品购买订单",
  1009. 'keyword1' => $orderId,
  1010. 'keyword2' => $order['pay_price'],
  1011. 'remark' => '请及时处理'
  1012. ]);
  1013. } else {
  1014. $data['character_string1']['value'] = $orderId;
  1015. $data['amount3']['value'] = $order['pay_price'];
  1016. $data['time2']['value'] = date('Y-m-d H:i:s', time());
  1017. $data['thing6']['value'] = '您购买的商品已支付成功!';
  1018. RoutineTemplate::sendOrderSuccess($data, $order['uid'], $site_url . Url::build('wap/special/order_store_list'));
  1019. $dataAdmin['character_string1']['value'] = $orderId;
  1020. $dataAdmin['amount3']['value'] = $order['pay_price'];
  1021. $dataAdmin['time2']['value'] = date('Y-m-d H:i:s', time());
  1022. $dataAdmin['thing6']['value'] = '您有一个新的商品购买订单!';
  1023. RoutineTemplate::sendAdminNoticeTemplate($dataAdmin);
  1024. }
  1025. $dat['pay_price'] = $order['pay_price'];
  1026. $dat['order_id'] = $orderId;
  1027. SmsTemplate::sendSms($order['uid'], $dat, 'ORDER_PAY_SUCCESS');
  1028. } catch (\Throwable $e) {
  1029. }
  1030. StoreOrderStatus::status($order['id'], 'pay_success', '用户付款成功');
  1031. $res = $res1 && $res2 && $res3;
  1032. return false !== $res;
  1033. }
  1034. /**
  1035. * 计算普通裂变推广人返佣金额
  1036. * @param int $is_promoter 推广人级别
  1037. * @param float $money 返佣金额
  1038. * @return float
  1039. * */
  1040. public static function getBrokerageMoney($is_promoter, $money)
  1041. {
  1042. $is_promoter = !is_int($is_promoter) ? (int)$is_promoter : $is_promoter;
  1043. $systemName = 'store_brokerage_three_[###]x';
  1044. //配置星级字段和设置如: store_brokerage_three_0x store_brokerage_three_1x
  1045. //后台设置字段从零星开始 $is_promoter 应 -1 才能对应字段
  1046. $store_brokerage_three = $is_promoter ? SystemConfigService::get(str_replace('[###]', $is_promoter - 1, $systemName)) : 100;
  1047. //返佣比例为0则不返佣
  1048. $store_brokerage_three = $store_brokerage_three == 0 ? 0 : bcdiv($store_brokerage_three, 100, 2);
  1049. return bcmul($money, $store_brokerage_three, 2);
  1050. }
  1051. /**获取订单详情
  1052. * @param $uid
  1053. * @param $key
  1054. * @return array|false|\PDOStatement|string|\think\Model
  1055. * @throws \think\db\exception\DataNotFoundException
  1056. * @throws \think\db\exception\ModelNotFoundException
  1057. * @throws \think\exception\DbException
  1058. */
  1059. public static function getUserOrderDetail($uid, $key)
  1060. {
  1061. return self::where('order_id|unique', $key)->where('uid', $uid)->where('is_del', 0)->find();
  1062. }
  1063. /**
  1064. * TODO 订单发货
  1065. * @param array $postageData 发货信息
  1066. * @param string $oid orderID
  1067. */
  1068. public static function orderPostageAfter($postageData, $oid)
  1069. {
  1070. $order = self::where('id', $oid)->find();
  1071. $openid = WechatUser::uidToOpenid($order['uid']);
  1072. $url = Url::build('wap/special/order', ['uni' => $order['order_id']], true, true);
  1073. $group = [
  1074. 'first' => '亲,您的订单已发货,请注意查收',
  1075. 'remark' => '点击查看订单详情'
  1076. ];
  1077. if ($postageData['delivery_type'] == 'express') {//发货
  1078. $wechat_notification_message = SystemConfigService::get('wechat_notification_message');
  1079. if ($wechat_notification_message == 1) {
  1080. $group = array_merge($group, [
  1081. 'keyword1' => $order['order_id'],
  1082. 'keyword2' => $postageData['delivery_name'],
  1083. 'keyword3' => $postageData['delivery_id']
  1084. ]);
  1085. WechatTemplateService::sendTemplate($openid, WechatTemplateService::ORDER_POSTAGE_SUCCESS, $group, $url);
  1086. } else {
  1087. $data['character_string2']['value'] = $order['order_id'];
  1088. $data['thing4']['value'] = $postageData['delivery_name'];
  1089. $data['character_string5']['value'] = $postageData['delivery_id'];
  1090. RoutineTemplate::sendOrderGoods($data, $order['uid'], Url::build('wap/special/order', ['uni' => $order['order_id']], true, true));
  1091. }
  1092. $dat['store_name'] = implode(',', StoreOrderCartInfo::getProductNameList($order['id']));
  1093. $dat['order_id'] = $order['order_id'];
  1094. $dat['phone'] = $order['user_phone'];
  1095. SmsTemplate::sendSms($order['uid'], $dat, 'ORDER_POSTAGE_SUCCESS');
  1096. }
  1097. }
  1098. public static function orderTakeAfter($order)
  1099. {
  1100. $openid = WechatUser::uidToOpenid($order['uid']);
  1101. $wechat_notification_message = SystemConfigService::get('wechat_notification_message');
  1102. if ($wechat_notification_message == 1) {
  1103. WechatTemplateService::sendTemplate($openid, WechatTemplateService::ORDER_TAKE_SUCCESS, [
  1104. 'first' => '亲,您的订单已成功签收!',
  1105. 'keyword1' => $order['order_id'],
  1106. 'keyword2' => '已收货',
  1107. 'keyword3' => date('Y/m/d H:i', time()),
  1108. 'keyword4' => implode(',', StoreOrderCartInfo::getProductNameList($order['id'])),
  1109. 'remark' => '点击查看订单详情'
  1110. ], Url::build('wap/special/order', ['uni' => $order['order_id']], true, true));
  1111. } else {
  1112. $data['character_string9']['value'] = $order['order_id'];
  1113. $data['thing2']['value'] = mb_substr(implode(',', StoreOrderCartInfo::getProductNameList($order['id'])), 0, 10, 'utf-8');
  1114. $data['date8']['value'] = date('Y/m/d H:i', time());
  1115. RoutineTemplate::sendReceivingGoods($data, $order['uid'], Url::build('wap/special/order', ['uni' => $order['order_id']], true, true));
  1116. }
  1117. $dat['order_id'] = $order['order_id'];
  1118. $dat['store_name'] = implode(',', StoreOrderCartInfo::getProductNameList($order['id']));
  1119. $dat['phone'] = $order['user_phone'];
  1120. SmsTemplate::sendSms($order['uid'], $dat, 'ORDER_TAKE_SUCCESS');
  1121. }
  1122. /**
  1123. * 删除订单
  1124. * @param $uni
  1125. * @param $uid
  1126. * @return bool
  1127. */
  1128. public static function removeOrder($uni, $uid)
  1129. {
  1130. $order = self::getUserOrderDetail($uid, $uni);
  1131. if (!$order) return self::setErrorInfo('订单不存在!');
  1132. $order = self::tidyOrder($order);
  1133. // if ($order['_status']['_type'] != 0 && $order['_status']['_type'] != -2 && $order['_status']['_type'] != 4)
  1134. // return self::setErrorInfo('该订单无法删除!');
  1135. if (false !== self::edit(['is_del' => 1], $order['id'], 'id') &&
  1136. false !== StoreOrderStatus::status($order['id'], 'remove_order', '删除订单'))
  1137. return true;
  1138. else
  1139. return self::setErrorInfo('订单删除失败!');
  1140. }
  1141. /**
  1142. * //TODO 用户确认收货
  1143. * @param $uni
  1144. * @param $uid
  1145. */
  1146. public static function takeOrder($uni, $uid)
  1147. {
  1148. $order = self::getUserOrderDetail($uid, $uni);
  1149. if (!$order) return self::setErrorInfo('订单不存在!');
  1150. $order = self::tidyOrder($order);
  1151. if ($order['_status']['_type'] != 2) return self::setErrorInfo('订单状态错误!');
  1152. self::beginTrans();
  1153. if (false !== self::edit(['status' => 2], $order['id'], 'id') &&
  1154. false !== StoreOrderStatus::status($order['id'], 'user_take_delivery', '用户已收货')) {
  1155. try {
  1156. HookService::listen('store_product_order_user_take_delivery', $order, $uid, false, StoreProductBehavior::class);
  1157. } catch (\Exception $e) {
  1158. return self::setErrorInfo($e->getMessage());
  1159. }
  1160. self::commitTrans();
  1161. return true;
  1162. } else {
  1163. self::rollbackTrans();
  1164. return false;
  1165. }
  1166. }
  1167. public static function tidyOrder($order, $detail = false, $isPic = false)
  1168. {
  1169. if ($detail == true && isset($order['id'])) {
  1170. $cartInfo = self::getDb('StoreOrderCartInfo')->where('oid', $order['id'])->column('cart_info', 'unique') ?: [];
  1171. foreach ($cartInfo as $k => $cart) {
  1172. $cartInfo[$k] = json_decode($cart, true);
  1173. $cartInfo[$k]['unique'] = $k;
  1174. }
  1175. $order['cartInfo'] = $cartInfo;
  1176. }
  1177. $status = [];
  1178. if (!$order['paid'] && $order['pay_type'] == 'offline' && !$order['status'] >= 2) {
  1179. $status['_type'] = 9;
  1180. $status['_title'] = '线下付款';
  1181. $status['_msg'] = '等待商家处理,请耐心等待';
  1182. $status['_class'] = 'nobuy';
  1183. } else if (!$order['paid']) {
  1184. $status['_type'] = 0;
  1185. $status['_title'] = '未支付';
  1186. $status['_msg'] = '立即支付订单吧';
  1187. $status['_class'] = 'nobuy';
  1188. } else if ($order['refund_status'] == 1) {
  1189. $status['_type'] = -1;
  1190. $status['_title'] = '申请退款中';
  1191. $status['_msg'] = '商家审核中,请耐心等待';
  1192. $status['_class'] = 'state-sqtk';
  1193. } else if ($order['refund_status'] == 2) {
  1194. $status['_type'] = -2;
  1195. $status['_title'] = '已退款';
  1196. $status['_msg'] = '已为您退款,感谢您的支持';
  1197. $status['_class'] = 'state-sqtk';
  1198. } else if (!$order['status']) {
  1199. $status['_type'] = 1;
  1200. $status['_title'] = '未发货';
  1201. $status['_msg'] = '商家未发货,请耐心等待';
  1202. $status['_class'] = 'state-nfh';
  1203. } else if ($order['status'] == 1) {
  1204. $status['_type'] = 2;
  1205. $status['_title'] = '待收货';
  1206. $status['_msg'] = date('m月d日H时i分', StoreOrderStatus::getTime($order['id'], 'delivery_goods')) . '服务商已发货';
  1207. $status['_class'] = 'state-ysh';
  1208. } else if ($order['status'] == 2) {
  1209. $status['_type'] = 3;
  1210. $status['_title'] = '待评价';
  1211. $status['_msg'] = '收货完成,请您评价订单';
  1212. $status['_class'] = 'state-ytk';
  1213. } else if ($order['status'] == 3) {
  1214. $status['_type'] = 4;
  1215. $status['_title'] = '交易完成';
  1216. $status['_msg'] = '交易完成,感谢您的支持';
  1217. $status['_class'] = 'state-ytk';
  1218. }
  1219. if ($order['refund_reason_time']) $order['refund_reason_time'] = date('Y-m-d H:i:s', $order['refund_reason_time']);
  1220. if ($order['refund_application_time']) $order['refund_application_time'] = date('Y-m-d H:i:s', $order['refund_application_time']);
  1221. if (isset($order['pay_type']))
  1222. $status['_payType'] = isset(self::$payType[$order['pay_type']]) ? self::$payType[$order['pay_type']] : '其他方式';
  1223. if (isset($order['delivery_type']))
  1224. $status['_deliveryType'] = isset(self::$deliveryType[$order['delivery_type']]) ? self::$deliveryType[$order['delivery_type']] : '其他方式';
  1225. $order['_status'] = $status;
  1226. if ($isPic) {
  1227. $order_details_images = GroupDataService::getData('order_details_images') ?: [];
  1228. foreach ($order_details_images as $image) {
  1229. if (isset($image['order_status']) && $image['order_status'] == $order['_status']['_type']) {
  1230. $order['status_pic'] = $image['pic'];
  1231. break;
  1232. }
  1233. }
  1234. }
  1235. return $order;
  1236. }
  1237. public static function statusByWhere($status, $model = null)
  1238. {
  1239. $orderId = StorePink::where('uid', User::getActiveUid())->where('status', 1)->column('order_id', 'id');//获取正在拼团的订单编号
  1240. if ($model == null) $model = new self;
  1241. if ('' === $status)
  1242. return $model;
  1243. else if ($status == 0)
  1244. return $model->where('paid', 0)->where('status', 0)->where('refund_status', 0);
  1245. else if ($status == 1)//待发货
  1246. return $model->where('paid', 1)->where('order_id', 'NOT IN', implode(',', $orderId))->where('status', 0)->where('refund_status', 0);
  1247. else if ($status == 2)
  1248. return $model->where('paid', 1)->where('status', 1)->where('refund_status', 0);
  1249. else if ($status == 3)
  1250. return $model->where('paid', 1)->where('status', 2)->where('refund_status', 0);
  1251. else if ($status == 4)
  1252. return $model->where('paid', 1)->where('refund_status', '>', 0);
  1253. else if ($status == -1)
  1254. return $model->where('paid', 1)->where('refund_status', 1);
  1255. else if ($status == -2)
  1256. return $model->where('paid', 1)->where('refund_status', 2);
  1257. else if ($status == 11) {
  1258. return $model->where('order_id', 'IN', implode(',', $orderId));
  1259. } else
  1260. return $model;
  1261. }
  1262. /**商品订单列表
  1263. * @param $uid
  1264. * @param string $status
  1265. * @param int $first
  1266. * @param int $limit
  1267. * @return array
  1268. * @throws \think\db\exception\DataNotFoundException
  1269. * @throws \think\db\exception\ModelNotFoundException
  1270. * @throws \think\exception\DbException
  1271. */
  1272. public static function getUserOrderList($uid, $status = '', $first = 0, $limit = 8)
  1273. {
  1274. $list = self::statusByWhere($status)->where('type', 2)->where('is_del', 0)->where('uid', $uid)
  1275. ->field('is_gift,combination_id,id,order_id,pay_price,total_num,total_price,pay_postage,total_postage,paid,status,refund_status,pay_type,coupon_price,deduction_price,pink_id,delivery_type,refund_reason_time,refund_application_time')
  1276. ->order('add_time DESC')->page($first, $limit)->select()->toArray();
  1277. foreach ($list as $k => $order) {
  1278. $list[$k] = self::tidyOrder($order, true);
  1279. }
  1280. return $list;
  1281. }
  1282. public static function searchUserOrder($uid, $order_id)
  1283. {
  1284. $order = self::where('uid', $uid)->where('order_id', $order_id)->where('is_del', 0)->field('is_gift,combination_id,id,order_id,pay_price,total_num,total_price,pay_postage,total_postage,paid,status,refund_status,pay_type,coupon_price,deduction_price,delivery_type')
  1285. ->order('add_time DESC')->find();
  1286. if (!$order)
  1287. return false;
  1288. else
  1289. return self::tidyOrder($order->toArray(), true);
  1290. }
  1291. public static function orderOver($oid)
  1292. {
  1293. $res = self::edit(['status' => '3'], $oid, 'id');
  1294. if (!$res) exception('评价后置操作失败!');
  1295. StoreOrderStatus::status($oid, 'check_order_over', '用户评价');
  1296. }
  1297. public static function checkOrderOver($oid)
  1298. {
  1299. $uniqueList = StoreOrderCartInfo::where('oid', $oid)->column('unique');
  1300. if (StoreProductReply::where('unique', 'IN', $uniqueList)->where('oid', $oid)->count() == count($uniqueList)) {
  1301. HookService::listen('store_product_order_over', $oid, null, false, StoreProductBehavior::class);
  1302. self::orderOver($oid);
  1303. }
  1304. }
  1305. /**
  1306. * 用户订单数据
  1307. */
  1308. public static function getOrderStatusNum($uid)
  1309. {
  1310. $noBuy = self::where('uid', $uid)->where('paid', 0)->where('type', 2)->where('is_del', 0)->where('refund_status', 0)->count();//未支付订单数量
  1311. $noDelivered = self::where('uid', $uid)->where('paid', 1)->where('type', 2)->where('is_del', 0)->where('status', 0)->where('refund_status', 0)->count();//待发货订单数量
  1312. $noTake = self::where('uid', $uid)->where('paid', 1)->where('type', 2)->where('is_del', 0)->where('status', 1)->where('refund_status', 0)->count();//待收货订单数量
  1313. $noReply = self::where('uid', $uid)->where('paid', 1)->where('type', 2)->where('is_del', 0)->where('status', 2)->where('refund_status', 0)->count();//已完成订单数量
  1314. $sum = self::where('uid', $uid)->where('is_del', 0)->where('type', 2)->count();//订单总数
  1315. $sumPrice = self::where('uid', $uid)->where('paid', 1)->where('type', 2)->where('refund_status', 0)->where('is_del', 0)->sum('pay_price');//订单总消费
  1316. $refund = self::where('uid', $uid)->where('paid', 1)->where('type', 2)->where('is_del', 0)->where('refund_status', '>', 0)->count();//退款订单数量
  1317. return compact('noBuy', 'noDelivered', 'noTake', 'noReply', 'sum', 'sumPrice', 'refund');
  1318. }
  1319. /**购买商品赠送虚拟币
  1320. * @param $order
  1321. * @return bool
  1322. * @throws \Exception
  1323. */
  1324. public static function gainUserGoldNum($order)
  1325. {
  1326. $gold_name = SystemConfigService::get('gold_name');//虚拟币名称
  1327. if ($order['gain_gold_num'] <= 0) return true;
  1328. $userInfo = User::getUserData($order['uid']);
  1329. if (!$userInfo) return false;
  1330. ModelBasic::beginTrans();
  1331. $res1 = false != User::where('uid', $userInfo['uid'])->update(['gold_num' => bcadd($userInfo['gold_num'], $order['gain_gold_num'], 2)]);
  1332. $res2 = false != UserBill::income('购买商品赠送' . $gold_name, $order['uid'], 'gold_num', 'gain', $order['gain_gold_num'], $order['id'], $userInfo['gold_num'], '购买商品赠送' . floatval($order['gain_gold_num']) . $gold_name);
  1333. $res = $res1 && $res2;
  1334. ModelBasic::checkTrans($res);
  1335. return $res;
  1336. }
  1337. /**
  1338. * 获取当前订单中有没有拼团存在
  1339. * @param $pid
  1340. * @return int|string
  1341. */
  1342. public static function getIsOrderPink($pid)
  1343. {
  1344. $uid = User::getActiveUid();
  1345. return self::where('uid', $uid)->where('pink_id', $pid)->where('refund_status', 0)->where('is_del', 0)->count();
  1346. }
  1347. /**
  1348. * 获取order_id
  1349. * @param $pid
  1350. * @return mixed
  1351. */
  1352. public static function getStoreIdPink($pid)
  1353. {
  1354. $uid = User::getActiveUid();
  1355. return self::where('uid', $uid)->where('pink_id', $pid)->where('is_del', 0)->value('order_id');
  1356. }
  1357. /**
  1358. * 删除当前用户拼团未支付的订单
  1359. */
  1360. public static function delCombination()
  1361. {
  1362. self::where('combination', 'GT', 0)->where('paid', 0)->where('uid', User::getActiveUid())->delete();
  1363. }
  1364. public static function getPinkT($pink_id)
  1365. {
  1366. $pink = StorePink::getPinkUserOne($pink_id);
  1367. if (isset($pink['is_refund']) && $pink['is_refund']) {
  1368. if ($pink['is_refund'] != $pink['id']) {
  1369. $id = $pink['is_refund'];
  1370. return self::getPinkT($id);
  1371. } else {
  1372. return self::setErrorInfo('订单已退款');
  1373. }
  1374. }
  1375. return $pink;
  1376. }
  1377. public static function getOrderSpecialInfo($orderId, $uid)
  1378. {
  1379. $is_ok = 0;//判断拼团是否完成
  1380. $userBool = 0;//判断当前用户是否在团内 0未在 1在
  1381. $pinkBool = 0;//判断拼团状态 0未完成 1 已完成 2拼团时间已到,退款中 3拼团已结束,请您参加别的拼团 6 拼团人数已满
  1382. $pink_id = self::where('order_id', $orderId)->value('pink_id');
  1383. $pink = self::getPinkT($pink_id);
  1384. if (!$pink) return self::setErrorInfo('没有查到拼团信息');
  1385. if ($pink['is_refund']) return self::setErrorInfo('订单已退款,无法查看');
  1386. list($pinkAll, $pinkT, $count, $idAll, $uidAll) = StorePink::getPinkMemberAndPinkK($pink);
  1387. if ($pinkT['status'] == 2) {
  1388. $pinkBool = 1;
  1389. } else {
  1390. if (!$count) {//组团完成
  1391. $pinkBool = StorePink::PinkComplete($uidAll, $idAll, $uid, $pinkT);
  1392. } else {//拼团失败 退款
  1393. $pinkBool = StorePink::PinkFail($uid, $idAll, $pinkAll, $pinkT, (int)$count, $pinkBool, $uidAll);
  1394. }
  1395. }
  1396. if (!empty($pinkAll)) {
  1397. foreach ($pinkAll as $v) {
  1398. if ($v['uid'] == $uid) $userBool = 1;
  1399. }
  1400. }
  1401. if ($pinkT['uid'] == $uid) $userBool = 1;
  1402. $data['pinkBool'] = $pinkBool;
  1403. $data['is_ok'] = $is_ok;
  1404. $data['userBool'] = $userBool;
  1405. $data['pinkT'] = $pinkT;
  1406. $data['pinkAll'] = $pinkAll;
  1407. $data['count'] = $count;
  1408. $data['current_pink_order'] = StorePink::getCurrentPink($pink_id);
  1409. $data['special'] = Special::PreWhere()->where('id', self::where('order_id', $pinkT['order_id'])->value('cart_id'))->field(['id', 'image', 'title', 'money', 'pink_money'])->find();
  1410. if (!$data['special']) return self::setErrorInfo('专题未查找到');
  1411. $data['special_id'] = $data['special']['id'];
  1412. return $data;
  1413. }
  1414. /***学习计划支付相关代码********************************************************************/
  1415. /**
  1416. * 创建订单专题订单
  1417. * @param $special
  1418. * @param $pinkId
  1419. * @param $pay_type
  1420. * @param $uid
  1421. * @param $payType
  1422. * @param int $link_pay_uid
  1423. * @param int $total_num
  1424. * @return bool|object
  1425. */
  1426. public static function createPlanOrder($special, $pinkId, $pay_type, $uid, $payType, $link_pay_uid = 0, $total_num = 1){
  1427. if (!array_key_exists($payType, self::$payType)) return self::setErrorInfo('选择支付方式有误!');
  1428. $userInfo = User::getUserData($uid);
  1429. if (!$userInfo) return self::setErrorInfo('用户不存在!');
  1430. $total_price = 0;
  1431. $combination_id = 0;
  1432. //自己买
  1433. $total_price = $special->sales;
  1434. //会员暂时去掉
  1435. // if (isset($userInfo['level']) && $userInfo['level'] > 0 && $special->member_pay_type == 1 && $special->special > 0) {
  1436. // $total_price = $special->member_money;
  1437. // }
  1438. $res = PlanBuy::PayPlan($special->id, $uid);
  1439. if ($res) return self::setErrorInfo('您已获得该学习计划,无需再次购买!');
  1440. $orderInfo = [
  1441. 'uid' => $uid,
  1442. 'mer_id' => 0,
  1443. 'order_id' => self::getNewOrderId(),
  1444. 'cart_id' => $special->id,
  1445. 'total_num' => $total_num,
  1446. 'total_price' => $total_price,
  1447. 'pay_price' => $total_price,
  1448. 'pay_type' => $payType,
  1449. 'type' => 3,
  1450. 'combination_id' => $combination_id,
  1451. 'is_gift' => $pay_type == 1 ? 1 : 0,
  1452. 'pink_time' => 0,
  1453. 'paid' => 0,
  1454. 'pink_id' => $pinkId,
  1455. 'unique' => md5(time() . '' . $uid . $special->id),
  1456. 'cost' => $total_price,
  1457. 'link_pay_uid' => $userInfo['spread_uid'] ? 0 : $link_pay_uid,
  1458. 'spread_uid' => $userInfo['spread_uid'] ? $userInfo['spread_uid'] : 0,
  1459. 'is_del' => 0,
  1460. ];
  1461. $order = self::set($orderInfo);
  1462. if (!$order) return self::setErrorInfo('订单生成失败!');
  1463. StoreOrderStatus::status($order['id'], 'cache_key_create_order', '订单生成');
  1464. return $order;
  1465. }
  1466. /**
  1467. * 学习计划微信支付 为 0元时
  1468. * @param $order_id
  1469. * @param $uid
  1470. * @return bool
  1471. */
  1472. public static function jsPayPlanPrice($order_id, $uid)
  1473. {
  1474. $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->where('is_del', 0)->find();
  1475. if (!$orderInfo) return self::setErrorInfo('订单不存在!');
  1476. if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
  1477. $userInfo = User::getUserData($uid);
  1478. self::beginTrans();
  1479. $res1 = UserBill::expend('购买学习计划', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '支付' . floatval($orderInfo['pay_price']) . '元购买学习计划');
  1480. $res2 = self::payPlanSuccess($order_id);
  1481. $res = $res1 && $res2;
  1482. self::checkTrans($res);
  1483. return $res;
  1484. }
  1485. /**
  1486. * //TODO 支付成功后
  1487. * @param $orderId
  1488. * @param $notify
  1489. * @return bool
  1490. */
  1491. public static function payPlanSuccess($orderId)
  1492. {
  1493. $order = self::where('order_id', $orderId)->where('type', 3)->find();
  1494. if (!$order) return false;
  1495. $resPink = true;
  1496. $res2 = true;
  1497. $res3 = true;
  1498. User::bcInc($order['uid'], 'pay_count', 1, 'uid');
  1499. $res1 = self::where('order_id', $orderId)->where('type', 3)->update(['paid' => 1, 'pay_time' => time()]);
  1500. if ($res1 && $order['pay_type'] != 'yue') {
  1501. $res2 = UserBill::expend('购买学习计划', $order['uid'], $order['pay_type'], 'pay_product', $order['pay_price'], $order['id'], 0, '支付' . floatval($order['pay_price']) . '元购买学习计划');
  1502. }
  1503. if ($res1) {
  1504. $res3 = MerchantFlowingWater::setMerchantFlowingWater($order, 6);
  1505. }
  1506. if ($order['combination_id'] && $res1 && !$order['refund_status']) {
  1507. //$resPink = StorePink::createPink($order);//创建拼团
  1508. } else {
  1509. if (!$order['is_gift']) {
  1510. //如果是专栏,记录专栏下所有专题购买。
  1511. PlanBuy::setAllBuyplan($orderId, $order['uid'], $order['cart_id']);
  1512. //DataDownloadBuy::setDataDownload($orderId, $order['uid'], $order['cart_id'], 0);
  1513. try {
  1514. //专题返佣
  1515. User::backOrderBrokerage($order);
  1516. } catch (\Throwable $e) {
  1517. }
  1518. }
  1519. }
  1520. StoreOrderStatus::status($order->id, 'pay_success', '用户付款成功');
  1521. $site_url = SystemConfigService::get('site_url');
  1522. try {
  1523. $wechat_notification_message = SystemConfigService::get('wechat_notification_message');
  1524. if ($wechat_notification_message == 1) {
  1525. WechatTemplateService::sendTemplate(WechatUser::where('uid', $order['uid'])->value('openid'), WechatTemplateService::ORDER_PAY_SUCCESS, [
  1526. 'first' => '亲,您购买的学习计划已支付成功',
  1527. 'keyword1' => $orderId,
  1528. 'keyword2' => $order['pay_price'],
  1529. 'remark' => '点击查看订单详情'
  1530. ], $site_url . Url::build('wap/studyplan/index'));
  1531. WechatTemplateService::sendAdminNoticeTemplate([
  1532. 'first' => "亲,您有一个新的课程订单",
  1533. 'keyword1' => $orderId,
  1534. 'keyword2' => $order['pay_price'],
  1535. 'remark' => '请及时查看'
  1536. ]);
  1537. } else {
  1538. $data['character_string1']['value'] = $orderId;
  1539. $data['amount3']['value'] = $order['pay_price'];
  1540. $data['time2']['value'] = date('Y-m-d H:i:s', time());
  1541. $data['thing6']['value'] = '您购买的学习计划已支付成功!';
  1542. RoutineTemplate::sendOrderSuccess($data, $order['uid'], $site_url . Url::build('wap/studyplan/index'));
  1543. $dataAdmin['character_string1']['value'] = $orderId;
  1544. $dataAdmin['amount3']['value'] = $order['pay_price'];
  1545. $dataAdmin['time2']['value'] = date('Y-m-d H:i:s', time());
  1546. $dataAdmin['thing6']['value'] = '您有一个新的课程订单!';
  1547. RoutineTemplate::sendAdminNoticeTemplate($dataAdmin);
  1548. }
  1549. } catch (\Throwable $e) {
  1550. }
  1551. $res = $res1 && $resPink && $res2 && $res3;
  1552. return false !== $res;
  1553. }
  1554. /**
  1555. * 学习计划微信h5支付
  1556. * @param $orderId
  1557. * @param string $field
  1558. * @return array|string
  1559. * @throws \think\db\exception\DataNotFoundException
  1560. * @throws \think\db\exception\ModelNotFoundException
  1561. * @throws \think\exception\DbException
  1562. */
  1563. public static function h5PlanPay($orderId, $field = 'order_id')
  1564. {
  1565. if (is_string($orderId))
  1566. $orderInfo = self::where($field, $orderId)->find();
  1567. else
  1568. $orderInfo = $orderId;
  1569. if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  1570. if ($orderInfo['paid']) exception('支付已支付!');
  1571. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  1572. $site_name = SystemConfigService::get('site_name');
  1573. if (!$site_name) exception('支付参数缺少:请前往后台设置->系统设置-> 填写 网站名称');
  1574. return WechatService::paymentPrepare(null, $orderInfo['order_id'], $orderInfo['pay_price'], 'plan', self::getSubstrUTf8($site_name . '-专题购买', 30), '', 'MWEB');
  1575. }
  1576. /**学习计划微信支付
  1577. * @param $orderId
  1578. * @param string $field
  1579. * @return array|string
  1580. * @throws \think\db\exception\DataNotFoundException
  1581. * @throws \think\db\exception\ModelNotFoundException
  1582. * @throws \think\exception\DbException
  1583. */
  1584. public static function jsPlanPay($orderId, $field = 'order_id')
  1585. {
  1586. if (is_string($orderId))
  1587. $orderInfo = self::where($field, $orderId)->find();
  1588. else
  1589. $orderInfo = $orderId;
  1590. if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  1591. if ($orderInfo['paid']) exception('支付已支付!');
  1592. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  1593. $site_name = SystemConfigService::get('site_name');
  1594. $openid = WechatUser::uidToOpenid($orderInfo['uid']);
  1595. return WechatService::jsPay($openid, $orderInfo['order_id'], $orderInfo['pay_price'], 'plan', self::getSubstrUTf8($site_name, 30));
  1596. }
  1597. /**专题余额支付
  1598. * @param $order_id
  1599. * @param $uid
  1600. * @return bool
  1601. * @throws \think\db\exception\DataNotFoundException
  1602. * @throws \think\db\exception\ModelNotFoundException
  1603. * @throws \think\exception\DbException
  1604. */
  1605. public static function yuePlanPay($order_id, $uid)
  1606. {
  1607. $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->where('is_del', 0)->find();
  1608. if (!$orderInfo) return self::setErrorInfo('订单不存在!');
  1609. if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
  1610. if ($orderInfo['pay_type'] != 'yue') return self::setErrorInfo('该订单不能使用余额支付!');
  1611. $userInfo = User::getUserData($uid);
  1612. if ($userInfo['now_money'] < $orderInfo['pay_price']) return self::setErrorInfo('余额不足' . floatval($orderInfo['pay_price']));
  1613. self::beginTrans();
  1614. $res1 = false !== User::bcDec($uid, 'now_money', $orderInfo['pay_price'], 'uid');
  1615. $res2 = UserBill::expend('购买学习计划', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], bcsub($userInfo['now_money'], $orderInfo['pay_price'], 2), '余额支付' . floatval($orderInfo['pay_price']) . '元购买专题');
  1616. $res3 = self::payPlanSuccess($order_id);
  1617. try {
  1618. HookService::listen('yue_pay_product', $userInfo, $orderInfo, false, PaymentBehavior::class);
  1619. } catch (\Exception $e) {
  1620. self::rollbackTrans();
  1621. return self::setErrorInfo($e->getMessage());
  1622. }
  1623. $res = $res1 && $res2 && $res3;
  1624. self::checkTrans($res);
  1625. return $res;
  1626. }
  1627. }