Cart.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2017 https://www.sapixx.com All rights reserved.
  4. * @license Licensed (http://www.apache.org/licenses/LICENSE-2.0).
  5. * @author pillar<ltmn@qq.com>
  6. * 商城购物车
  7. */
  8. namespace app\fastshop\controller\api\v3;
  9. use app\fastshop\controller\api\Base;
  10. use app\fastshop\model\Item;
  11. use app\fastshop\model\Fare;
  12. use app\fastshop\model\Config;
  13. use app\fastshop\model\Shopping;
  14. use app\fastshop\model\ShoppingCache;
  15. use app\common\facade\WechatPay;
  16. use app\common\model\SystemMemberPayment;
  17. use app\common\model\SystemUserAddress;
  18. use app\common\model\SystemMemberBank;
  19. use think\facade\Request;
  20. use filter\Filter;
  21. class Cart extends Base{
  22. public function initialize() {
  23. parent::initialize();
  24. $this->isUserAuth();
  25. }
  26. /**
  27. * 购物车编辑
  28. */
  29. public function edit(){
  30. $data['item_id'] = Request::param('item_id/d',0);
  31. $data['buy_num'] = Request::param('buy_num/d',1);
  32. $data['sign'] = Request::param('sign');
  33. $rel = $this->apiSign($data);
  34. if($rel['code'] == 200){
  35. if($data['buy_num'] > 5){
  36. return enjson(403,'超过最大购买商品数');
  37. }
  38. //检测SPU是否存在或下架
  39. $spu = Item::where(['id' => $data['item_id'],'is_sale'=>2])->find();
  40. if(empty($spu)){
  41. return enjson(403,'商品已下降');
  42. }
  43. $cart[$data['item_id']] = $data['buy_num'];
  44. return enjson(200,'成功',$cart);
  45. }
  46. return enjson($rel['code'],'签名验证失败');
  47. }
  48. /**
  49. * 读取购物车产品列表
  50. */
  51. public function cartItem(){
  52. if(request()->isPost()){
  53. $cart = Request::param('cart/a',[]);
  54. if (empty($cart)) {
  55. return enjson(204,'没有宝贝');
  56. }
  57. $ids = ids(array_keys($cart),true);
  58. //查找商品SPU
  59. $item = Item::where(['is_sale'=>2,'id' => $ids,'member_miniapp_id' => $this->miniapp_id])
  60. ->field('id,category_id,name,sell_price,market_price,points,repoints,weight,img')
  61. ->select();
  62. if(empty($item)){
  63. return enjson(403,'没有宝贝');
  64. }else{
  65. $data = [];
  66. foreach ($item as $value) {
  67. $num = abs(intval($cart[$value['id']]));
  68. $num = $num <= 0 ? 1: $num;
  69. $data[$value['id']] = [
  70. 'id' => $value['id'],
  71. 'num' => $num,
  72. 'amount' => money($value['sell_price'] * $num), //单个商品价格的总价
  73. 'market_price' => money($value['market_price']),
  74. 'sell_price' => money($value['sell_price']),
  75. 'weight' => $value['weight'],
  76. 'points' => $value['points'],
  77. 'repoints' => $value['repoints'],
  78. 'name' => $value['name'],
  79. 'img' => $value['img']
  80. ];
  81. }
  82. $amount = Fare::realAmount($data,$this->miniapp_id);
  83. return enjson(200,'成功',['item' => $data,'amount' => $amount]);
  84. }
  85. }
  86. }
  87. /**
  88. * ################################
  89. * 判断是否支付了
  90. */
  91. public function isPay($order_no){
  92. $order_no = Filter::filter_escape($order_no);
  93. $order = Shopping::where(['order_no' => $order_no,'paid_at' => 0])->field('id,order_no,paid_no,order_amount')->find();
  94. if(empty($order)){
  95. return enjson(204);
  96. }
  97. return enjson();
  98. }
  99. /**
  100. * 微信商城支付
  101. * @param string $no
  102. * @return void
  103. */
  104. public function doPay(){
  105. $param = [
  106. 'address' => Request::param('address/d',0),
  107. 'ids' => Request::param('ids/s','','htmlspecialchars_decode'),
  108. 'ucode' => Request::param('ucode'),
  109. 'buytype' => Request::param('buytype','wepay'),
  110. 'sign' => Request::param('sign')
  111. ];
  112. $validate = $this->validate($param,'Cart.add_order');
  113. if(true !== $validate){
  114. return enjson(403,$validate);
  115. }
  116. $rel = $this->apiSign($param);
  117. if($rel['code'] != 200){
  118. return enjson(403,'签名失败');
  119. }
  120. $cart = (array)ids(json_decode($param['ids'],true),true); //购买的产品ID和数量
  121. $ids = ids(array_keys($cart),true); //购买的产品ID
  122. if (empty($ids)){
  123. return enjson(403,'购物车是空的');
  124. }
  125. if (empty($ids[0])){
  126. return enjson(403,'购物车是空的');
  127. }
  128. //读取发货地址
  129. $address = SystemUserAddress::where(['user_id'=>$this->user->id,'id' =>$param['address']])->find();
  130. if(empty($address)){
  131. return enjson(403,'请选择收货地址');
  132. }
  133. //支付接口
  134. $payment = SystemMemberPayment::where(['apiname'=>'wepay','member_miniapp_id'=>$this->miniapp_id])->find();
  135. if(empty($payment)){
  136. return enjson(403,'未开通微信支付功能');
  137. }
  138. //读取订单
  139. $item = Item::where(['is_sale'=>2,'id' => $ids,'member_miniapp_id' => $this->miniapp_id])->field('id,sell_price,market_price,points,repoints,weight,name,img')->select();
  140. if($item->isEmpty()){
  141. return enjson(403,'没有宝贝');
  142. }
  143. $data = [];
  144. foreach ($item as $value) {
  145. $num = abs(intval($cart[$value['id']]));
  146. $num = $num <= 0 ? 1: $num;
  147. $data[$value['id']] = [
  148. 'id' => $value['id'],
  149. 'num' => $num,
  150. 'amount' => money($value['sell_price'] * $num), //单个商品价格的总价
  151. 'market_price' => money($value['market_price']),
  152. 'sell_price' => money($value['sell_price']),
  153. 'weight' => $value['weight'],
  154. 'points' => $value['points'],
  155. 'repoints' => $value['repoints'],
  156. 'name' => $value['name'],
  157. 'img' => $value['img'],
  158. ];
  159. }
  160. $amount = Fare::realAmount($data,$this->miniapp_id);
  161. $config = Config::where(['member_miniapp_id' => $this->miniapp_id])->find();
  162. if($param['buytype'] == 'point'){
  163. if($config->payment_type_shop == 0){
  164. return json(['code'=>403,'msg'=>"未开通余额支付功能"]);
  165. }
  166. $point_fee = money($amount['order_amount']*($config->payment_point_shop/100)); //积分付款
  167. if ($point_fee <= 0) {
  168. $param['buytype'] = 'wepay'; //如果积分付款为零0转换为正常的微信全额支付
  169. $order_amount = money($amount['order_amount']);
  170. }else{
  171. $order_amount = money($amount['order_amount'] - $point_fee);
  172. $order_amount = $order_amount <= 0 ? 1 : $order_amount; //如果是100%积分设置最低付款金额
  173. //判断积分够不够
  174. $rel = model('Bank')->isPay($this->user->id,$point_fee,$config->payment_type_shop);
  175. if(!$rel){
  176. return json(['code'=>403,'msg'=>"余额不足,请选择其它支付渠道"]);
  177. }
  178. }
  179. }else{
  180. $order_amount = $amount['order_amount'];
  181. }
  182. $order_amount = $order_amount <= 0 ? 1 :$order_amount;
  183. //判断云收银台
  184. if($config->is_pay_types == 1 && $config->goodpay_tax > 0){
  185. $goodpay_tax = $order_amount*$config->goodpay_tax/100;
  186. $bank_rel = SystemMemberBank::moneyJudge($this->miniapp->member_id,$goodpay_tax);
  187. if($bank_rel){
  188. return ['code'=>0,'message'=>'官方帐号余额不足,请联系管理员'];
  189. }
  190. }
  191. $order_no = $this->user->invite_code.order_no(); //生成的订单号
  192. $order['payment_id'] = $payment['id']; //支付ID
  193. $order['express_name'] = $address['name'];
  194. $order['express_phone'] = $address['telphone'];
  195. $order['express_address'] = $address['address'];
  196. $order['order_amount'] = $amount['order_amount'];
  197. $order['real_amount'] = $amount['real_amount'];
  198. $order['real_freight'] = $amount['real_freight'];
  199. $order['order_no'] = $order_no;
  200. $order['member_miniapp_id'] = $this->miniapp_id;
  201. $order['user_id'] = $this->user->id;
  202. $order['order_starttime'] = time();
  203. $order_id = Shopping::insertGetId($order);
  204. if(empty($order_id)){
  205. return enjson(403,'创建订单失败');
  206. }
  207. //保存订单产品到缓存数据表
  208. foreach ($data as $key => $value) {
  209. $item_data[$key]['order_no'] = $order_no;
  210. $item_data[$key]['item_id'] = $value['id'];
  211. $item_data[$key]['buy_price'] = $value['sell_price'];
  212. $item_data[$key]['buy_nums'] = $value['num'];
  213. $item_data[$key]['name'] = $value['name'];
  214. $item_data[$key]['img'] = $value['img'];
  215. }
  216. ShoppingCache::insertAll($item_data);
  217. //支付方式
  218. if($config->is_pay_types == 1){
  219. //云收银台
  220. $pay_coinfig = json_decode($payment->config);
  221. $ispay = [
  222. 'name' => $this->miniapp->appname.'购买商品',
  223. 'mchid' => $pay_coinfig->mch_id,
  224. 'total_fee' => $order_amount*100,
  225. 'order_no' => $order_no,
  226. 'note' => $this->miniapp_id,
  227. 'notify_url' => $param['buytype'] == 'wepay'? api(3,'fastshop/goodpay/shop',$this->miniapp_id) : api(3,'fastshop/goodpay/shopPoint',$this->miniapp_id),
  228. 'publickey' => uuid(1)
  229. ];
  230. $paydata = $this->makeSign($ispay,$pay_coinfig->key);
  231. }else{
  232. //去请求微信支付接口
  233. $payparm = [
  234. 'openid' => $this->user->miniapp_uid,
  235. 'miniapp_id' => $this->miniapp_id,
  236. 'name' => $this->miniapp->appname.'购买商品',
  237. 'order_no' => $order_no,
  238. 'total_fee' => $order_amount*100,
  239. 'notify_url' => $param['buytype'] == 'wepay'? api(3,'fastshop/notify/shop',$this->miniapp_id) : api(3,'fastshop/notify/shopPoint',$this->miniapp_id),
  240. ];
  241. $ispay = WechatPay::orderPay($payparm);
  242. if($ispay['code'] == 0){
  243. return enjson(403,$ispay['msg']);
  244. }
  245. $paydata = $ispay['data'];
  246. }
  247. return enjson(200,'成功',['type' => $config->is_pay_types,'order' => $paydata]);
  248. }
  249. /**
  250. * 重新支付
  251. * @param string $no
  252. * @return void
  253. */
  254. public function retryPay(){
  255. $param = [
  256. 'order_no' => Request::param('order_no'),
  257. 'buytype' => Request::param('buytype','wepay'),
  258. 'sign' => Request::param('sign')
  259. ];
  260. $rel = $this->apiSign($param);
  261. if($rel['code'] != 200){
  262. return enjson(403,'签名失败');
  263. }
  264. $order = Shopping::where(['order_no' => $param['order_no'],'member_miniapp_id' => $this->miniapp_id,'paid_at' => 0])->find();
  265. if(empty($order)){
  266. return enjson(403,'未找到当前订单信息');
  267. }
  268. //支付接口
  269. $payment = SystemMemberPayment::where(['apiname'=>'wepay','member_miniapp_id'=>$this->miniapp_id])->find();
  270. if(empty($payment)){
  271. return enjson(403,'未开通微信支付功能');
  272. }
  273. //支付方式
  274. $config = Config::where(['member_miniapp_id' => $this->miniapp_id])->find();
  275. if($param['buytype'] == 'point'){
  276. $config = Config::where(['member_miniapp_id' => $this->miniapp_id])->find();
  277. if($config->payment_type_shop == 0){
  278. return json(['code'=>403,'msg'=>"未开通余额支付功能"]);
  279. }
  280. $point_fee = money($order->order_amount*($config->payment_point_shop/100)); //积分付款
  281. if ($point_fee <= 0) {
  282. $param['buytype'] = 'wepay'; //如果积分付款为零0转换为正常的微信全额支付
  283. $order_amount = money($order->order_amount);
  284. }else{
  285. $order_amount = money($order->order_amount - $point_fee);
  286. $order_amount = $order_amount <= 0 ? 1 : $order_amount; //如果是100%积分设置最低付款金额
  287. //判断积分够不够
  288. $rel = model('Bank')->isPay($this->user->id,$point_fee,$config->payment_type_shop);
  289. if(!$rel){
  290. return json(['code'=>403,'msg'=>"余额不足,请选择其它支付渠道"]);
  291. }
  292. }
  293. }else{
  294. $order_amount = $order->order_amount;
  295. }
  296. $order_amount = $order_amount <= 0 ? 1 :$order_amount;
  297. if($config->is_pay_types == 1){
  298. if($config->goodpay_tax > 0){
  299. $goodpay_tax = $order_amount*$config->goodpay_tax/100;
  300. $bank_rel = SystemMemberBank::moneyJudge($this->miniapp->member_id,$goodpay_tax);
  301. if($bank_rel){
  302. return ['code'=>0,'message'=>'官方帐号余额不足,请联系管理员'];
  303. }
  304. }
  305. $pay_coinfig = json_decode($payment->config);
  306. //云收银台
  307. $ispay = [
  308. 'name' => $this->miniapp->appname.'购买商品',
  309. 'mchid' => $pay_coinfig->mch_id,
  310. 'total_fee' => $order_amount*100,
  311. 'order_no' => $order->order_no,
  312. 'note' => $this->miniapp_id,
  313. 'notify_url' => $param['buytype'] == 'wepay'? api(3,'fastshop/goodpay/shop',$this->miniapp_id) : api(3,'fastshop/goodpay/shopPoint',$this->miniapp_id),
  314. 'publickey' => uuid(1)
  315. ];
  316. $paydata = $this->makeSign($ispay,$pay_coinfig->key);
  317. }else{
  318. //去请求微信支付接口
  319. $payparm = [
  320. 'openid' => $this->user->miniapp_uid,
  321. 'miniapp_id' => $this->miniapp_id,
  322. 'name' => $this->miniapp->appname.'购买商品',
  323. 'order_no' => $order->order_no,
  324. 'total_fee' => $order_amount*100,
  325. 'notify_url' => api(3,'fastshop/notify/shop',$this->miniapp_id),
  326. 'notify_url' => $param['buytype'] == 'wepay'? api(3,'fastshop/notify/shop',$this->miniapp_id) : api(3,'fastshop/notify/shopPoint',$this->miniapp_id),
  327. ];
  328. $ispay = WechatPay::orderPay($payparm);
  329. if($ispay['code'] == 0){
  330. return enjson(403,$ispay['msg']);
  331. }
  332. $paydata = $ispay['data'];
  333. }
  334. return enjson(200,'成功',['type' => $config->is_pay_types,'order' => $paydata]);
  335. }
  336. /**
  337. * 关闭订单
  338. */
  339. public function closeorder(){
  340. $rule = [
  341. 'order_no' => Request::param('order_no'),
  342. 'sign' => Request::param('sign')
  343. ];
  344. $rel = $this->apiSign($rule);
  345. if($rel['code'] == 200){
  346. $condition['order_no'] = $rule['order_no'];
  347. $condition['user_id'] = $this->user->id;
  348. $condition['is_del'] = 0;
  349. $rel = Shopping::where($condition)->update(['is_del' => 1]);
  350. if(empty($rel)){
  351. return enjson(403,'关闭失败');
  352. }
  353. return enjson(200,'成功关闭');
  354. }
  355. return enjson(204,'签名失败');
  356. }
  357. /**
  358. * 签收订单
  359. */
  360. public function signOrder($order_no){
  361. $rule = [
  362. 'order_no' => Request::param('order_no'),
  363. 'sign' => Request::param('sign')
  364. ];
  365. $rel = $this->apiSign($rule);
  366. if($rel['code'] == 200){
  367. $condition['order_no'] = Filter::filter_escape($order_no);
  368. $condition['user_id'] = $this->user->id;
  369. $condition['is_del'] = 0;
  370. $condition['paid_at'] = 1;
  371. $condition['express_status'] = 1;
  372. $rel = Shopping::where($condition)->update(['status' => 1]);
  373. if(empty($rel)){
  374. return enjson(403,'未找到当前订单');
  375. }
  376. return enjson(200,'订单签收成功');
  377. }
  378. return enjson(204,'签名失败');
  379. }
  380. /**
  381. * ######################################
  382. * 小程序端用户的订单列表
  383. * 我的产品列表
  384. */
  385. public function order(){
  386. $rule = [
  387. 'types' => Request::param('types',0),
  388. 'page' => Request::param('page',0),
  389. 'sign' => Request::param('sign')
  390. ];
  391. $rel = $this->apiSign($rule);
  392. if($rel['code'] != 200){
  393. return enjson(403,'签名失败');
  394. }
  395. $condition['user_id'] = $this->user->id;
  396. $condition['is_del'] = 0;
  397. switch ($rule['types']) {
  398. case 1:
  399. $condition['paid_at'] = 1;
  400. $condition['express_status'] = 0;
  401. break;
  402. case 2:
  403. $condition['paid_at'] = 1;
  404. $condition['express_status'] = 1;
  405. $condition['status'] = 0;
  406. break;
  407. case 3:
  408. $condition['paid_at'] = 1;
  409. $condition['status'] = 1;
  410. break;
  411. default:
  412. $condition['paid_at'] = 0;
  413. break;
  414. }
  415. $order = Shopping::where($condition)->order('id desc')->paginate(10);
  416. if(empty($order)) {
  417. return enjson(204,'没有订单');
  418. }
  419. $data = Shopping::orderData($order);
  420. return enjson(200,'成功',$data);
  421. }
  422. /**
  423. * 读取购物车预览
  424. */
  425. public function review(){
  426. $param = [
  427. 'order_no' => Request::param('order_no'),
  428. 'sign' => Request::param('sign')
  429. ];
  430. $rel = $this->apiSign($param);
  431. if($rel['code'] != 200){
  432. return enjson(403,$rel['msg']);
  433. }
  434. $condition['user_id'] = $this->user->id;
  435. $condition['is_del'] = 0;
  436. $condition['order_no'] = $param['order_no'];
  437. $order = Shopping::where($condition)->order('id desc')->select();
  438. if(empty($order)) {
  439. return enjson(204,'没有订单');
  440. }
  441. return enjson(200,'成功',Shopping::orderData($order));
  442. }
  443. }