Order.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\library\AliPay;
  4. use app\common\library\AliPay3;
  5. use app\common\library\HuijuH5Pay;
  6. use app\common\library\Jiyan;
  7. use think\cache\driver\Redis;
  8. use think\Db;
  9. use think\Exception;
  10. use EasyWeChat\Factory;
  11. use think\Session;
  12. use function Sodium\add;
  13. /**
  14. * @title 订单
  15. * @controller GoodsOrder
  16. * @group base
  17. */
  18. class Order extends Base
  19. {
  20. public function initialize()
  21. {
  22. parent::initialize();
  23. parent::check_login();
  24. }
  25. /**
  26. * @title 生成订单(立即购买 )
  27. * @desc 生成订单(立即购买 )
  28. * @author Gavin
  29. * @url /api/Order/createOrder
  30. * @method POST
  31. * @header name:Authorization require:1 desc:Token
  32. * @param name:id type:int require:1 default:-- desc:藏品id
  33. * @param name:num type:int require:1 default:1 desc:数量
  34. * @param name:pay_type type:string require:1 default:wx desc:wx:微信zfb:支付宝
  35. * @param name:from type:string require:1 default:wx desc:wx:微信公众号h5:网页
  36. *
  37. * @return name:order_no type:int require:0 default:0 desc:订单号
  38. * @return name:pay type:string require:0 default:0 desc:支付信息
  39. */
  40. public function createOrder()
  41. {
  42. $redis = new Redis([ 'select'=> 2]);
  43. $redis_value = $redis->get('order_buy'.$this->uid);
  44. if ($redis_value){
  45. $this->error('请求过快,请稍后重试');
  46. }else{
  47. $redis->set('order_buy'.$this->uid,1,1);
  48. }
  49. $id = input('id');
  50. $num = input('num',1);
  51. $pay_type = input('pay_type','wx');
  52. $from = input('from','wx');
  53. if (!$id || !$num) $this->error('参数错误');
  54. //极验数据
  55. // $lot_number = input('lot_number');
  56. // $captcha_output = input('captcha_output');
  57. // $pass_token = input('pass_token');
  58. // $gen_time = input('gen_time');
  59. // if (!$lot_number || !$captcha_output || !$pass_token || !$gen_time) $this->error('参数错误');
  60. //
  61. // $jy = new Jiyan();
  62. // $result = $jy->jy($lot_number,$captcha_output,$pass_token,$gen_time,2);
  63. // if ($result['result']=='fail') $this->error('校验失败,请稍后重试');
  64. $user = getMemberInfoHash($this->uid); //获取用户信息
  65. if ($user['is_auth']==0) $this->error('请实名认证后购买!');
  66. $coll_info = getCollectionInfoHash($id);
  67. if ($coll_info['is_deleted']==1 || $coll_info['status']==0) $this->error('藏品已下架');
  68. $inventory = getCollectionInventory($id);
  69. if ($coll_info['state']!=1) $this->error('状态错误');
  70. if ($inventory<$num) $this->error('库存不足');
  71. if ($inventory<1) $this->error('还有未支付的订单,您有可能捡漏哦!');
  72. if (!$coll_info['sold_out']) $this->error('已售罄');
  73. $sell_time = strtotime($coll_info['sell_time']);
  74. if ($sell_time>time()) $this->error('商品还未开始售卖!请耐心等待');
  75. //获取用户已经购买数量
  76. $userByCount = getByCount($this->uid,$id);
  77. if ($coll_info['buy_count']<($userByCount+$num)) $this->error('每人限购'.$coll_info['buy_count'].'个');
  78. //获取是否已经铸造hash
  79. //$hashCount = getLenCollection($id);
  80. $hash = Db::name('hash2')->where('goods_id',$id)->where('success',1)->count();
  81. if (!$hash) $this->error('nft未上架,无法购买');
  82. // if (!$hashCount || $hashCount<$num) $this->error('hash未铸造,无法购买');
  83. if ($from=='wx'){
  84. if (!$user['openid']) $this->error('微信未授权,无法购买');
  85. }
  86. //先减掉库存
  87. loseCollectionInventory($id,$num);
  88. //先增加购买数量
  89. IncrByCount($this->uid,$id,$num);
  90. $order_no = get_order_sn();
  91. $total_fee = bcmul($coll_info['price'],$num,2);
  92. $redis_data = [
  93. 'mid'=>$this->uid,
  94. 'c_id'=>$id,
  95. 'order_no'=>$order_no,
  96. 'inventory'=>$coll_info['inventory'],
  97. 'num'=>$num,
  98. 'pro_info'=>json_encode($coll_info),
  99. 'status'=>0,
  100. 'create_at'=>date('Y-m-d H:i:s'),
  101. 'pay_price'=>$total_fee,
  102. 'pay_type'=>$pay_type
  103. ];
  104. $com = true;
  105. $retrun_data['order_no'] = $order_no;
  106. $retrun_data['pay'] = '';
  107. if ($com){
  108. $redis = new Redis();
  109. //收集下单用户id
  110. setCollectionBuyUser($this->uid);
  111. $redis->hMSet('order_not_pay_'.$this->uid,[$order_no=>json_encode($redis_data,true)]); //存入redis
  112. $this->success('成功',$retrun_data);
  113. }else{
  114. //加上库存
  115. addCollectionInventory($id,$num);
  116. //减少用户购买数量
  117. DecrByCount($this->uid,$id,$num);
  118. $this->error('服务器繁忙,请稍后重试');
  119. }
  120. }
  121. /**
  122. * @title 我的订单-待支付、已购买
  123. * @desc 我的订单-待支付、已购买
  124. * @author Gavin
  125. * @url /api/Order/getMyOrderList
  126. * @method POST
  127. * @header name:Authorization require:1 desc:Token
  128. * @param name:status type:int : default:0 desc:0:待支付1:已购买
  129. * @param name:page type:int : default:1 desc:页数
  130. * @param name:page_num type:int : default:20 desc:每页数
  131. *
  132. * @return name:order_no type:string default:-- desc:订单号
  133. * @return name:num type:int default:-- desc:数量
  134. * @return name:pay_price type:string default:-- desc:订单金额
  135. * @return name:status type:int default:-- desc:类型0:待支付1:已支付
  136. * @return name:cancel_time type:string default:-- desc:待支付自动取消时间
  137. * @return name:pay_type type:string default:-- desc:支付方式wx:微信zfb:支付宝
  138. * @return name:create_at type:string default:-- desc:创建时间
  139. * @return name:pro_info@name type:string default:-- desc:藏品名称
  140. * @return name:pro_info@cover type:string default:-- desc:藏品图片
  141. * @return name:pro_info@price type:string default:-- desc:藏品单价
  142. * @return name:pro_info@auth_img type:string default:-- desc:藏品作者头像
  143. * @return name:pro_info@auth_name type:string default:-- desc:藏品作者名称
  144. */
  145. public function getMyOrderList(){
  146. $status = input('status',0);
  147. if ($status==0){
  148. $redis = new Redis();
  149. $key = 'order_not_pay_'.$this->uid;
  150. $count = $redis->hGetLen($key);
  151. $list = $redis->hGetvals($key);
  152. if ($list){
  153. //自动取消分钟数
  154. $cancel_time = getCancelTime();
  155. foreach ($list as $k=>&$v){
  156. $info = json_decode($v,true);
  157. $info['pro_info'] = json_decode($info['pro_info'],true);
  158. $info['cancel_time'] = date('Y-m-d H:i:s',strtotime($info['create_at'])+($cancel_time*60));
  159. $list[$k] = $info;
  160. }
  161. }
  162. }else{
  163. $where = [
  164. 'is_deleted'=>0,
  165. 'status'=>$status,
  166. 'mid'=>$this->uid
  167. ];
  168. $count = Db::name('store_order')->where($where)->count();
  169. $list = Db::name('store_order')
  170. ->where($where)
  171. ->field('id,c_id,order_no,num,pro_info,status,create_at,pay_price,pay_type')
  172. ->order('id desc')
  173. ->limit($this->off_set,$this->page_num)
  174. ->select();
  175. foreach ($list as &$v){
  176. $v['pro_info'] = json_decode($v['pro_info'],true);
  177. }
  178. }
  179. $this->success('成功',compact('count','list'));
  180. }
  181. /**
  182. * @title 待支付、已购买订单详情
  183. * @desc 待支付、已购买订单详情
  184. * @author Gavin
  185. * @url /api/Order/MyOrderListDetail
  186. * @method POST
  187. * @header name:Authorization require:1 desc:Token
  188. * @param name:order_no type:string default:0 desc:订单号
  189. * @param name:type type:int default:1 desc:1:待支付2:已支付
  190. *
  191. * @return name:order_no type:string default:-- desc:订单号
  192. * @return name:num type:int default:-- desc:数量
  193. * @return name:pay_price type:string default:-- desc:订单金额
  194. * @return name:status type:int default:-- desc:类型0:待支付1:已支付
  195. * @return name:cancel_time type:string default:-- desc:待支付自动取消时间
  196. * @return name:create_at type:string default:-- desc:创建时间
  197. * @return name:pay_at type:string default:-- desc:支付时间
  198. * @return name:pay_type type:string default:-- desc:支付方式wx:微信zfb:支付宝
  199. * @return name:pro_info@name type:string default:-- desc:藏品名称
  200. * @return name:pro_info@cover type:string default:-- desc:藏品图片
  201. * @return name:pro_info@price type:string default:-- desc:藏品单价
  202. * @return name:pro_info@auth_img type:string default:-- desc:藏品作者头像
  203. * @return name:pro_info@auth_name type:string default:-- desc:藏品作者名称
  204. */
  205. public function MyOrderListDetail(){
  206. $order_no = input('order_no');
  207. $type = input('type',1);
  208. if (!$order_no) $this->error('参数错误');
  209. if ($type==1){
  210. $redis = new Redis();
  211. $key = 'order_not_pay_'.$this->uid;
  212. $order = $redis->hGet($key,$order_no);
  213. $order = json_decode($order,true);
  214. }else{
  215. $order = Db::name('store_order')
  216. ->where('order_no',$order_no)
  217. ->where('mid',$this->uid)
  218. ->where('is_deleted',0)
  219. ->find();
  220. }
  221. if (!$order) $this->error('订单不存在');
  222. $order['pro_info'] = json_decode($order['pro_info'],true);
  223. //自动取消分钟数
  224. $cancel_time = getCancelTime();
  225. if ($order['status']==0){
  226. $order['cancel_time'] = date('Y-m-d H:i:s',strtotime($order['create_at'])+($cancel_time*60));
  227. }
  228. $this->success('成功',$order);
  229. }
  230. /**
  231. * @title 待支付订单支付
  232. * @desc 待支付订单支付
  233. * @author Gavin
  234. * @url /api/Order/payOrder
  235. * @method POST
  236. * @header name:Authorization require:1 desc:Token
  237. * @param name:order_no type:string require:1 default:-- desc:订单号
  238. * @param name:from type:string require:1 default:wx desc:wx:微信公众号h5:网页
  239. *
  240. * @return name:order_no type:int require:0 default:0 desc:订单号
  241. * @return name:pay type:string require:0 default:0 desc:支付信息
  242. */
  243. public function payOrder(){
  244. $user = getMemberInfoHash($this->uid); //获取用户信息
  245. $order_no = input('order_no'); //订单号
  246. $from = input('from','wx');
  247. if (!$order_no) $this->error('参数错误');
  248. $redis = new Redis();
  249. $key = 'order_not_pay_'.$this->uid;
  250. $order = $redis->hGet($key,$order_no);
  251. if (!$order) $this->error('订单不存在');
  252. $order = json_decode($order,true);
  253. if ($order['status']!=0) $this->error('订单已支付或已取消');
  254. $order_no = $order['order_no'];
  255. $total_fee = $order['pay_price'];
  256. $pay_type = $order['pay_type'];
  257. $body = 'top艺术购买藏品';
  258. $com = true;
  259. switch ($pay_type){
  260. case 'wx':
  261. $config = retrunWxConfig();
  262. $total_fee = $total_fee * 100;
  263. $config['notify_url'] = $this->request->root(true).'/api/Pay/WxOrderNotify';
  264. $app = Factory::payment($config);
  265. $post_data = [
  266. 'body' => $body,
  267. 'out_trade_no' => $order_no,
  268. 'total_fee' => $total_fee,
  269. 'attach'=>$this->uid, //自定义传值
  270. ];
  271. //trade_type SAPI--JSAPI支付(或小程序支付)、NATIVE--Native支付、APP--app支付,MWEB--H5支付
  272. if ($from=='wx'){
  273. $post_data['openid'] = $user['openid'];
  274. $post_data['trade_type'] = 'JSAPI';
  275. }elseif ($from=='h5'){
  276. $post_data['trade_type'] = 'MWEB';
  277. }
  278. $result = $app->order->unify($post_data);
  279. if ($result['return_msg']=='OK'){
  280. if ($result['result_code']=='FAIL'){
  281. $com = false;
  282. }else{
  283. $order1 = $app->jssdk->bridgeConfig($result['prepay_id']);//执行二次签名返回参数
  284. $redis_data['wx_order'] = $order1;
  285. $retrun_data['order_no'] = $order_no;
  286. $retrun_data['pay'] = json_decode($order1,true);
  287. }
  288. }else{
  289. $com = false;
  290. }
  291. break;
  292. case 'zfb':
  293. $order_nos = get_order_sn();
  294. $order['order_no'] = $order_nos;
  295. $redis->hMSet($key,[$order_nos=>json_encode($order,true)]); //存入redis
  296. //存入redis
  297. $redis->hdel($key,$order_no);
  298. $zfb = new AliPay3();
  299. $notify_url = 'https://'.$_SERVER['SERVER_NAME'].'/index.php/api/Pay/alipayOrderNotify';//回调地址
  300. $callback_url = 'https://'.$_SERVER['SERVER_NAME'].'/pages/mine/order-list?num=1';
  301. $order = $zfb->aliPay($body,$total_fee,$order_nos,$notify_url,$this->uid,$callback_url);
  302. $retrun_data['order_no'] = $order_nos;
  303. $retrun_data['pay'] = $order['pay_url'];
  304. break;
  305. case 'ylh5':
  306. $order_nos = get_order_sn();
  307. $order['order_no'] = $order_nos;
  308. $redis->hMSet($key,[$order_nos=>json_encode($order,true)]); //存入redis
  309. //存入redis
  310. $redis->hdel($key,$order_no);
  311. $callback_url = 'https://'.$_SERVER['SERVER_NAME'].'/pages/mine/order-list?num=1';
  312. $huiju = new HuijuH5Pay();
  313. $notify_url = 'https://'.$_SERVER['SERVER_NAME'].'/index.php/api/Pay/ylOrderNotify';//回调地址
  314. $pro_info = json_decode($order['pro_info'],true);
  315. $result = $huiju->ylh5Pay($order_nos,$callback_url,$notify_url,$pro_info['name'],$total_fee,$this->uid,2);
  316. if ($result['ra_Code']=='100'){
  317. $retrun_data['order_no'] = $order_nos;
  318. $retrun_data['pay'] = $result['rc_Result'];
  319. }else{
  320. $com = false;
  321. }
  322. break;
  323. case 'zfbh5':
  324. $order_nos = get_order_sn();
  325. $order['order_no'] = $order_nos;
  326. $redis->hMSet($key,[$order_nos=>json_encode($order,true)]); //存入redis
  327. //存入redis
  328. $redis->hdel($key,$order_no);
  329. $callback_url = 'https://'.$_SERVER['SERVER_NAME'].'/pages/mine/order-list?num=1';
  330. $huiju = new HuijuH5Pay();
  331. $notify_url = 'https://'.$_SERVER['SERVER_NAME'].'/index.php/api/Pay/ylOrderNotify';//回调地址
  332. $pro_info = json_decode($order['pro_info'],true);
  333. $result = $huiju->ylh5Pay($order_nos,$callback_url,$notify_url,$pro_info['name'],$total_fee,$this->uid,1);
  334. if ($result['ra_Code']=='100'){
  335. $retrun_data['order_no'] = $order_nos;
  336. $retrun_data['pay'] = $result['rc_Result'];
  337. }else{
  338. $com = false;
  339. }
  340. break;
  341. }
  342. if ($com){
  343. $this->success('成功',$retrun_data);
  344. }else{
  345. $this->error('调起支付失败,请稍后重试');
  346. }
  347. }
  348. /**
  349. * @title 取消订单
  350. * @desc 取消订单
  351. * @author Gavin
  352. * @url /api/Order/cancelOrder
  353. * @method POST
  354. * @header name:Authorization require:1 desc:Token
  355. * @param name:order_no type:string require:1 default:-- desc:订单号
  356. */
  357. public function cancelOrder(){
  358. $order_no = input('order_no');
  359. if (!$order_no) $this->error('参数错误');
  360. $redis = new Redis();
  361. $key = 'order_not_pay_'.$this->uid;
  362. $order = $redis->hGet($key,$order_no);
  363. if (!$order) $this->error('订单不存在');
  364. $order = json_decode($order,true);
  365. if ($order['status']!=0) $this->error('订单已支付或已取消');
  366. $com = true;
  367. Db::startTrans();
  368. try {
  369. $order['status'] = 2;
  370. $order['cancel_at'] = date('Y-m-d H:i:s');
  371. $order['cancel_state'] = 2;
  372. Db::name('store_order')->insert($order);
  373. Db::commit();
  374. }catch (\Exception $e){
  375. $com=false;
  376. Db::rollback();
  377. }
  378. if ($com){
  379. //加上库存
  380. addCollectionInventory($order['c_id'],$order['num']);
  381. //减少用户购买数量
  382. DecrByCount($this->uid,$order['c_id'],$order['num']);
  383. //删除数据
  384. $redis->hdel($key,$order_no);
  385. $this->success('取消成功');
  386. }else{
  387. $this->error('取消失败,请稍后重试');
  388. }
  389. }
  390. /**
  391. * @title 我的订单-转赠
  392. * @desc 我的订单-转赠
  393. * @author Gavin
  394. * @url /api/Order/getMySendList
  395. * @method POST
  396. * @header name:Authorization require:1 desc:Token
  397. * @param name:page type:int : default:1 desc:页数
  398. * @param name:page_num type:int : default:20 desc:每页数
  399. *
  400. * @return name:order_no type:string default:-- desc:订单号
  401. * @return name:over_time type:string default:-- desc:转赠时间
  402. * @return name:status type:int default:-- desc:类型2:赠出3:获赠
  403. * @return name:send_name type:string default:-- desc:转赠者/受赠者
  404. * @return name:collectors_hash type:string default:-- desc:hash
  405. * @return name:pro_info@name type:string default:-- desc:藏品名称
  406. * @return name:pro_info@price type:string default:-- desc:藏品价格
  407. * @return name:pro_info@price type:string default:-- desc:藏品单价
  408. * @return name:pro_info@auth_img type:string default:-- desc:藏品作者头像
  409. * @return name:pro_info@auth_name type:string default:-- desc:藏品作者名称
  410. */
  411. public function getMySendList(){
  412. $where = [
  413. 'mid'=>$this->uid,
  414. ];
  415. $count = Db::name('store_order_info')->where($where)->whereIn('status','2,3')->count();
  416. $list = Db::name('store_order_info')
  417. ->where($where)
  418. ->whereIn('status','2,3')
  419. ->field('id,order_no,pro_info,over_time,create_at,status,to_mid,collectors_hash')
  420. ->order('id desc')
  421. ->limit($this->off_set,$this->page_num)
  422. ->select();
  423. foreach ($list as &$v){
  424. $v['pro_info'] = json_decode($v['pro_info'],true);
  425. $v['send_name'] = Db::name('store_member')->where('id',$v['to_mid'])->value('name');
  426. }
  427. $this->success('成功',compact('count','list'));
  428. }
  429. /**
  430. * @title 转赠订单详情
  431. * @desc 转赠订单详情
  432. * @author Gavin
  433. * @url /api/Order/getMySendListDetail
  434. * @method POST
  435. * @header name:Authorization require:1 desc:Token
  436. * @param name:order_id type:int : default:1 desc:订单ID
  437. *
  438. * @return name:order_no type:string default:-- desc:订单号
  439. * @return name:over_time type:string default:-- desc:转赠时间
  440. * @return name:status type:int default:-- desc:类型2:赠出3:获赠
  441. * @return name:send_name type:string default:-- desc:转赠者/受赠者
  442. * @return name:collectors_hash type:string default:-- desc:hash
  443. * @return name:pro_info@name type:string default:-- desc:藏品名称
  444. * @return name:pro_info@price type:string default:-- desc:藏品价格
  445. * @return name:pro_info@price type:string default:-- desc:藏品单价
  446. * @return name:pro_info@auth_img type:string default:-- desc:藏品作者头像
  447. * @return name:pro_info@auth_name type:string default:-- desc:藏品作者名称
  448. */
  449. public function getMySendListDetail(){
  450. $order_id = input('order_id'); //订单id
  451. if (!$order_id) $this->error('参数错误');
  452. $order = Db::name('store_order_info')
  453. ->where('id',$order_id)
  454. ->where('mid',$this->uid)
  455. ->find();
  456. if (!$order) $this->error('订单不存在');
  457. $order['pro_info'] = json_decode($order['pro_info'],true);
  458. $order['send_name'] = Db::name('store_member')->where('id',$order['to_mid'])->value('name');
  459. $this->success('成功',$order);
  460. }
  461. function savetest($order_no){
  462. $result['out_trade_no'] = $order_no;
  463. $order = Db::name('store_order')->where('order_no',$result['out_trade_no'])->find();
  464. if ($order['status']==0){
  465. Db::startTrans();
  466. try {
  467. Db::name('store_order')
  468. ->where('order_no',$result['out_trade_no'])
  469. ->update(['status'=>1,'pay_at'=>date('Y-m-d H:i:s'),'return_success_info'=>json_encode($result,true)]);
  470. $array = [];
  471. for ($i=0;$i<$order['num'];$i++){
  472. //获取排名
  473. $rank = getRanking($order['c_id'])+1;
  474. $tag = getTag($order['c_id'],$rank,$order['inventory']);
  475. saveRanking($order['c_id']);
  476. $company = '象寻数字科技(上海)有限公司';
  477. $company_hash = '';
  478. $company_hash_time = '';
  479. $collectors_hash = '';
  480. $date = [
  481. 'order_id'=>$order['id'],
  482. 'order_no'=>get_order_sn(),
  483. 'tag'=>$tag,
  484. 'mid'=>$order['mid'],
  485. 'pro_info'=>$order['pro_info'],
  486. 'company'=>$company,
  487. 'company_hash'=>$company_hash,
  488. 'company_hash_time'=>$company_hash_time,
  489. 'collectors_hash'=>$collectors_hash,
  490. 'collectors_hash_time'=>date('Y-m-d H:i:s')
  491. ];
  492. $array[] = $date;
  493. }
  494. Db::name('store_order_info')->insertAll($array);
  495. Db::commit();
  496. // return true;
  497. } catch (\Exception $e){
  498. Db::rollback();
  499. //return false;
  500. }
  501. }
  502. }
  503. }