WIN-2308041133\Administrator há 8 horas atrás
pai
commit
4631a45550

+ 651 - 0
app/api/controller/Recharge.php

@@ -0,0 +1,651 @@
+<?php
+declare (strict_types=1);
+
+namespace app\api\controller;
+
+use app\BaseController;
+use app\Request;
+use app\model\api\RechargeConfig;
+use app\model\api\RechargeOrder;
+use app\model\api\User;
+use app\model\api\UserScoreDetail;
+use library\services\UtilService;
+use library\utils\WxpayV2 as wxpayApi;
+use library\utils\weixinPay as wxpayApiV3;
+use app\model\api\Sys as SysModel;
+use think\db\exception\DbException;
+use think\facade\Db;
+use think\facade\Cache;
+use app\model\api\PayTrade as PayTradeModel;
+
+class Recharge extends BaseController
+{
+    /**
+     * 获取充值配置列表
+     * @param Request $request
+     * @return mixed
+     */
+    public function configList(Request $request)
+    {
+        $rechargeConfig = new RechargeConfig();
+        $list = $rechargeConfig->getShowList();
+        
+        return app('json')->success([
+            'list' => $list
+        ]);
+    }
+    /**
+     * 模板订单提交[第一步]
+     * @param Request $request
+     */
+    public function createOrder(Request $request)
+    {
+        [$price, $pay_type] = UtilService::getMore([
+            ['price', 0],
+            ['pay_type', '', 'empty', '请选择支付方式'],
+        ], $request, true);
+
+        if (!in_array($pay_type, ["wxpay"])) {
+            return app('json')->fail('不支持该支付方式!');
+        }
+
+        $weixinConfig = (new SysModel)->getWeixinConfig();
+//        if(empty($weixinConfig)){
+//            return app('json')->fail('支付配置为空!');
+//        }
+
+        $uid =  $request->user['uid'];
+        // 防重复提交缓存
+        $redis = Cache::store('redis');
+        $key = 'recharge_order_sub_' . $request->user['uid'];
+        $bool = $redis->handler()->exists($key);
+        if ($bool) {
+            return app('json')->fail('请勿重复操作,请稍后再试!');
+        }
+        $redis->set($key, 1, 5); // 5秒缓存
+
+        // 获取系统积分转换比例
+        $sys = (new SysModel())->where("id", 1)->find();
+        $pointsTransformation = isset($sys['points_transformation']) ? intval($sys['points_transformation']) : 10;
+
+        // 获取用户折扣金额(半小时内固定)
+        $cacheKey = 'recharge_discount_' . $request->user['uid'];
+        $discount = $redis->get($cacheKey);
+        if (!$discount) {
+            // 生成随机折扣金额:0.01到1元,保留两位小数
+            $discount = round(mt_rand(1, 100) / 100, 2);
+            $redis->set($cacheKey, $discount, 1800); // 30分钟缓存
+        }
+
+//        $rechargeConfig = new RechargeConfig();
+        $rechargeOrder = new RechargeOrder();
+
+        if ($price <= 0) {
+            return app('json')->fail('充值金额必须大于0');
+        }
+        // 计算积分:根据系统比例计算
+        $integral = intval($price * $pointsTransformation);
+        $giveIntegral = 0;
+        // 计算实际支付金额(原价减去折扣,最低0.01元)
+        $payMoney = max($price - $discount, 0.01);
+        $payMoney = $payMoney <= 0 ? 0 : $payMoney;
+        $nowTime = time();
+
+
+
+        // 主订单数据
+        $save = [];
+        $save['uid'] = $request->user['uid'];
+        $save['order_sn'] = $rechargeOrder->mkOrderSn($uid);
+        $save['recharge_id'] = 0;
+        $save['price'] = $price;
+        $save['integral'] = $integral;
+        $save['give_integral'] = 0;
+        $save['total_integral'] = $integral + $giveIntegral;
+        $save['pay_type'] = $pay_type;
+        $save['discount_amount'] = $discount;
+        $save['paid'] = $payMoney <= 0 ? 1 : 0;
+        $save['pay_time'] = $payMoney <= 0 ? time() : 0;
+        $save['status'] = $payMoney <= 0 ? 1 : 0;
+        $save['add_time'] = $nowTime;
+        $save['update_time'] = $nowTime;
+        $save['order_type'] = 1;
+        $save['remark'] = '用户充值';
+
+        try {
+            Db::startTrans();
+            $o_id = (new RechargeOrder())->insertGetId($save);
+            if (empty($o_id)) {
+                return app('json')->fail("订单提交失败");
+            }
+
+            //微信支付
+            if (empty($request->user['openid'])) {
+                Db::rollback();
+                return app('json')->fail('用户还未绑定微信!');
+            }
+            //清理之前支付凭证 || 防止重复购买
+            $payTrade = (new PayTradeModel)
+                ->where("uid", $request->user["uid"])
+                ->where("o_id", $o_id)
+                ->where("order_type", 1)
+                ->where("type", "temp")
+                ->where("status", 0)
+                ->where("time", "<", time() - 7 * 24 * 60 * 60)
+                ->select()
+                ->toArray();
+            $wxpay = new wxpayApi();
+//            $wxpay = new wxpayApi($weixinConfig);
+
+            foreach ($payTrade as $v) {
+//                if($v['pay_type'] == 'wxpay') {
+//                    $result = $wxpay->closeOrder($v['pay_no']);
+//                }
+                (new PayTradeModel)->where("id", $v['id'])->where("status", 0)->delete();
+            }
+            $mtime = microtime(true) * 10000;
+            $payOn = "T" . date("Ymd") . $mtime . rand(100, 999) . $request->user['uid'];
+            $out_trade_no = "";
+            $payType = $save["pay_type"];
+            //添加交易记录
+            $trade = [
+                'uid' => $request->user['uid'],
+                'o_id' => $o_id,
+                'order_id' => $save["order_id"],
+                'pay_no' => $payOn,
+                'out_trade_no' => empty($out_trade_no) ? $payOn : $out_trade_no,
+                'pay_type' => $payType,
+                'money' => $payMoney,
+                'type' => 'recharge',
+                'd_json' => serialize(['orderId' => $save["order_id"], "give_score" => 0]),
+                'time' => time(),
+                'status' => 0,
+            ];
+            $r = (new PayTradeModel)->insert($trade);
+            if (!$r) {
+                Db::rollback();
+                return app('json')->fail('支付信息获取失败!');
+            }
+            $clictip = get_client_ip();
+            if (empty($clictip)) {
+                $clictip = $request->ip();
+            }
+            $payData = $wxpay->wxmpPay([
+                'body' => "微信小程序充值积分",
+                'out_trade_no' => $payOn,
+                'total' => $payMoney,
+                'openid' => $request->user['openid'],
+                'payer_client_ip' => $clictip,
+            ]);
+            if (empty($payData)) {
+                Db::rollback();
+                return app('json')->fail($wxpay->errorMsg);
+            }
+            Db::commit();
+            $redis->delete($key);
+            return app('json')->success([
+                'jsApiParameters' => $payData,
+                'pay_no' => $payOn,
+                'order_id' => $save["order_id"],
+                "status" => $save['status'],
+                "money" => $payMoney,
+            ]);
+        } catch (DbException $db) {
+            Db::rollback();
+            return app('json')->fail("充值订单生成失败");
+        }
+    }
+    /**
+     * 创建充值订单
+     * @param Request $request
+     * @return mixed
+     */
+//    public function createOrder(Request $request)
+//    {
+//        $post = UtilService::getMore([
+//            ['recharge_id', 0],
+//            ['price', 0],
+//            ['pay_type', 'wxpay']
+//        ], $request);
+//
+//        $uid = $request->uid;
+//        if (!$uid) {
+//            return app('json')->fail('用户未登录');
+//        }
+//
+//        // 验证支付方式
+//        if (!in_array($post['pay_type'], ["wxpay", "balance"])) {
+//            return app('json')->fail('不支持该支付方式!');
+//        }
+//
+//        // 防重复提交缓存
+//        $redis = Cache::store('redis');
+//        $key = 'recharge_order_sub_' . $uid;
+//        $bool = $redis->handler()->exists($key);
+//        if ($bool) {
+//            return app('json')->fail('请勿重复操作,请稍后再试!');
+//        }
+//        $redis->set($key, 1, 5); // 5秒缓存
+//
+//        // 获取系统积分转换比例
+//        $sys = (new SysModel())->where("id", 1)->find();
+//        $pointsTransformation = isset($sys['points_transformation']) ? intval($sys['points_transformation']) : 10;
+//
+//        // 获取用户折扣金额(半小时内固定)
+//        $cacheKey = 'recharge_discount_' . $uid;
+//        $discount = $redis->get($cacheKey);
+//        if (!$discount) {
+//            // 生成随机折扣金额:0.01到1元,保留两位小数
+//            $discount = round(mt_rand(1, 100) / 100, 2);
+//            $redis->set($cacheKey, $discount, 1800); // 30分钟缓存
+//        }
+//
+//        $rechargeConfig = new RechargeConfig();
+//        $rechargeOrder = new RechargeOrder();
+//
+//        $integral = 0;
+//        $giveIntegral = 0;
+//
+//        // 如果是选择充值套餐
+//        if ($post['recharge_id'] > 0) {
+//            $config = $rechargeConfig->getById($post['recharge_id']);
+//            if (!$config || $config['is_show'] != 1) {
+//                return app('json')->fail('充值套餐不存在或已禁用');
+//            }
+//            $price = $config['price'];
+//            $integral = $config['integral'];
+//            $giveIntegral = $config['give_integral'];
+//        } else {
+//            // 自定义金额充值
+//            $price = $post['price'];
+//            if ($price <= 0) {
+//                return app('json')->fail('充值金额必须大于0');
+//            }
+//            // 计算积分:根据系统比例计算
+//            $integral = intval($price * $pointsTransformation);
+//            $giveIntegral = 0;
+//        }
+//
+//        // 计算实际支付金额(原价减去折扣,最低0.01元)
+//        $payMoney = max($price - $discount, 0.01);
+//        $payMoney = $payMoney <= 0 ? 0 : $payMoney;
+//        $nowTime = time();
+//
+//        // 获取用户余额和openid
+//        $userModel = new User();
+//        $userInfo = $userModel->where('uid', $uid)->field('money,openid')->find();
+//        if (!$userInfo) {
+//            return app('json')->fail('用户不存在');
+//        }
+//
+//        // 余额支付验证
+//        if ($post['pay_type'] == "balance" && $payMoney > $userInfo['money']) {
+//            return app('json')->fail("当前余额不足");
+//        }
+//
+//        // 主订单数据
+//        $save = [];
+//        $save['uid'] = $uid;
+//        $save['order_sn'] = $rechargeOrder->mkOrderSn($uid);
+//        $save['recharge_id'] = $post['recharge_id'];
+//        $save['price'] = $price;
+//        $save['integral'] = $integral;
+//        $save['give_integral'] = $giveIntegral;
+//        $save['total_integral'] = $integral + $giveIntegral;
+//        $save['pay_type'] = $post['pay_type'];
+//        $save['discount_amount'] = $discount;
+//        $save['paid'] = $payMoney <= 0 ? 1 : 0;
+//        $save['pay_time'] = $payMoney <= 0 ? time() : 0;
+//        $save['status'] = $payMoney <= 0 ? 1 : 0;
+//        $save['add_time'] = $nowTime;
+//        $save['update_time'] = $nowTime;
+//        $save['remark'] = '用户充值';
+//
+//        // 余额实时支付
+//        if ($post['pay_type'] == "balance") {
+//            $save['paid'] = 1;
+//            $save['pay_time'] = time();
+//            $save['status'] = 1;
+//        }
+//
+//        try {
+//            Db::startTrans();
+//            $o_id = (new RechargeOrder)->insertGetId($save);
+//            if (empty($o_id)) {
+//                Db::rollback();
+//                $redis->delete($key);
+//                return app('json')->fail("订单提交失败");
+//            }
+//
+//            // 不需要支付
+//            if ($payMoney <= 0 && $save['paid'] == 1) {
+//                // 增加用户积分
+//                $this->addUserIntegral($uid, $save['total_integral'], $save['order_sn'], $save['price'], $o_id);
+//                Db::commit();
+//                $redis->delete($key);
+//                return app("json")->success([
+//                    'order_id' => $save['order_sn'],
+//                    'pay_no' => '',
+//                    'price' => $price,
+//                    'money' => $payMoney,
+//                    'discount_amount' => $discount,
+//                    'integral' => $integral,
+//                    'give_integral' => $giveIntegral,
+//                    'total_integral' => $save['total_integral'],
+//                    'pay_type' => $post['pay_type'],
+//                    'status' => $save['paid']
+//                ]);
+//            }
+//
+//            // 余额支付
+//            if ($post['pay_type'] == "balance") {
+//                // 修改用户余额
+//                $userDetail = new \app\model\api\UserDetail();
+//                $res = $userDetail->balancePay($uid, $payMoney, "recharge_pay", ["to_id" => $o_id]);
+//                if (!$res) {
+//                    Db::rollback();
+//                    $redis->delete($key);
+//                    return app('json')->fail("余额支付失败");
+//                }
+//                // 增加用户积分
+//                $this->addUserIntegral($uid, $save['total_integral'], $save['order_sn'], $save['price'], $o_id);
+//                Db::commit();
+//                $redis->delete($key);
+//                return app("json")->success([
+//                    'order_id' => $save['order_sn'],
+//                    'pay_no' => '',
+//                    'price' => $price,
+//                    'money' => $payMoney,
+//                    'discount_amount' => $discount,
+//                    'integral' => $integral,
+//                    'give_integral' => $giveIntegral,
+//                    'total_integral' => $save['total_integral'],
+//                    'pay_type' => $post['pay_type'],
+//                    'status' => $save['paid']
+//                ]);
+//            }
+//
+//            // 微信支付
+//            if (empty($userInfo['openid'])) {
+//                Db::rollback();
+//                $redis->delete($key);
+//                return app('json')->fail('用户还未绑定微信!');
+//            }
+//
+//            // 清理之前支付凭证 || 防止重复购买
+//            $payTrade = (new \app\model\api\PayTrade())
+//                ->where("uid", $uid)
+//                ->where("o_id", $o_id)
+//                ->where("type", "recharge")
+//                ->where("status", 0)
+//                ->where("time", "<", time() - 7 * 24 * 60 * 60)
+//                ->select()
+//                ->toArray();
+//            $wxpay = new wxpayApi();
+//
+//            foreach ($payTrade as $v) {
+//                (new \app\model\api\PayTrade())->where("id", $v['id'])->where("status", 0)->delete();
+//            }
+//
+//            $mtime = microtime(true) * 10000;
+//            $payOn = "R" . date("Ymd") . $mtime . rand(100, 999) . $uid;
+//            $out_trade_no = "";
+//            $payType = $save["pay_type"];
+//
+//            // 添加交易记录
+//            $trade = [
+//                'uid' => $uid,
+//                'o_id' => $o_id,
+//                'order_id' => $save["order_sn"],
+//                'pay_no' => $payOn,
+//                'out_trade_no' => empty($out_trade_no) ? $payOn : $out_trade_no,
+//                'pay_type' => $payType,
+//                'money' => $payMoney,
+//                'type' => 'recharge',
+//                'd_json' => serialize([
+//                    'order_sn' => $save["order_sn"],
+//                    'recharge_id' => $post['recharge_id'],
+//                    'integral' => $integral,
+//                    'give_integral' => $giveIntegral,
+//                    'total_integral' => $integral + $giveIntegral,
+//                    'discount_amount' => $discount
+//                ]),
+//                'time' => time(),
+//                'status' => 0,
+//            ];
+//            $r = (new \app\model\api\PayTrade())->insert($trade);
+//            if (!$r) {
+//                Db::rollback();
+//                $redis->delete($key);
+//                return app('json')->fail('支付信息获取失败!');
+//            }
+//
+//            $clictip = get_client_ip();
+//            if (empty($clictip)) {
+//                $clictip = $request->ip();
+//            }
+//
+//            $payData = $wxpay->wxmpPay([
+//                'body' => "充值积分",
+//                'out_trade_no' => $payOn,
+//                'total' => $payMoney,
+//                'openid' => $userInfo['openid'],
+//                'payer_client_ip' => $clictip,
+//            ]);
+//
+//            if (empty($payData)) {
+//                Db::rollback();
+//                $redis->delete($key);
+//                return app('json')->fail($wxpay->errorMsg);
+//            }
+//
+//            Db::commit();
+//            $redis->delete($key);
+//            return app('json')->success([
+//                'jsApiParameters' => $payData,
+//                'pay_no' => $payOn,
+//                'order_id' => $save["order_sn"],
+//                "status" => $save['paid'],
+//                "money" => $payMoney,
+//                'price' => $price,
+//                'discount_amount' => $discount,
+//                'integral' => $integral,
+//                'give_integral' => $giveIntegral,
+//                'total_integral' => $save['total_integral'],
+//                'pay_type' => $post['pay_type']
+//            ]);
+//        } catch (\think\db\exception\DbException $db) {
+//            Db::rollback();
+//            $redis->delete($key);
+//            return app('json')->fail("订单生成失败");
+//        }
+//    }
+
+    /**
+     * 充值支付
+     * @param Request $request
+     * @return mixed
+     */
+    public function pay(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['order_sn', '']
+        ], $request);
+
+        $uid = $request->uid;
+        if (!$uid) {
+            return app('json')->fail('用户未登录');
+        }
+
+        $rechargeOrder = new RechargeOrder();
+        $orderInfo = $rechargeOrder->getByOrderSn($post['order_sn']);
+        
+        if (!$orderInfo) {
+            return app('json')->fail('订单不存在');
+        }
+        
+        if ($orderInfo['uid'] != $uid) {
+            return app('json')->fail('订单不属于当前用户');
+        }
+        
+        if ($orderInfo['paid'] == 1) {
+            return app('json')->fail('订单已支付');
+        }
+        
+        if ($orderInfo['status'] == -1) {
+            return app('json')->fail('订单已关闭');
+        }
+
+        $payType = $orderInfo['pay_type'];
+        $price = $orderInfo['price'];
+        
+        // 调用支付接口
+        if ($payType == 'wxpay') {
+            // 微信支付
+            $wxpay = new wxpayApi();
+            $payData = $wxpay->pay($price, $orderInfo['order_sn'], '充值积分', $uid);
+            
+            if (!$payData) {
+                return app('json')->fail('支付失败');
+            }
+            
+            return app('json')->success([
+                'jsApiParameters' => $payData,
+                'order_id' => $orderInfo['order_sn']
+            ]);
+        } elseif ($payType == 'alipay') {
+            // 支付宝支付(需要根据项目实际情况实现)
+            return app('json')->fail('支付宝支付暂未开通');
+        } else {
+            return app('json')->fail('支付方式不支持');
+        }
+    }
+
+    /**
+     * 充值订单列表
+     * @param Request $request
+     * @return mixed
+     */
+    public function orderList(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['page', 1],
+            ['pageSize', 20],
+            ['status', ''],
+            ['paid', '']
+        ], $request);
+
+        $uid = $request->uid;
+        if (!$uid) {
+            return app('json')->fail('用户未登录');
+        }
+
+        $where = [];
+        if (!empty($post['status'])) {
+            $where['status'] = $post['status'];
+        }
+        if (!empty($post['paid'])) {
+            $where['paid'] = $post['paid'];
+        }
+
+        $rechargeOrder = new RechargeOrder();
+        $list = $rechargeOrder->getUserList($uid, $where, '*', $post['page'], $post['pageSize']);
+        
+        return app('json')->success([
+            'list' => $list[1],
+            'total' => $list[0],
+            'page' => $post['page'],
+            'pageSize' => $post['pageSize']
+        ]);
+    }
+
+    /**
+     * 充值订单详情
+     * @param Request $request
+     * @return mixed
+     */
+    public function orderDetail(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['order_sn', '']
+        ], $request);
+
+        $uid = $request->uid;
+        if (!$uid) {
+            return app('json')->fail('用户未登录');
+        }
+
+        $rechargeOrder = new RechargeOrder();
+        $orderInfo = $rechargeOrder->getByOrderSn($post['order_sn']);
+        
+        if (!$orderInfo) {
+            return app('json')->fail('订单不存在');
+        }
+        
+        if ($orderInfo['uid'] != $uid) {
+            return app('json')->fail('订单不属于当前用户');
+        }
+
+        return app('json')->success($orderInfo);
+    }
+
+    /**
+     * 增加用户积分(内部调用)
+     * @param int $uid 用户ID
+     * @param int $totalIntegral 总积分
+     * @param string $orderSn 订单号
+     * @param float $price 充值金额
+     * @param int $orderId 订单ID
+     * @return bool
+     */
+    private function addUserIntegral($uid, $totalIntegral, $orderSn, $price, $orderId)
+    {
+        $userModel = new User();
+        $user = $userModel->where('uid', $uid)->find();
+        
+        if ($user) {
+            // 更新用户积分和累计充值金额
+            $userModel->where('uid', $uid)->inc('score', $totalIntegral)->inc('score_in', $totalIntegral)->inc('total_recharge', $price)->update();
+            
+            // 记录积分明细
+            $scoreDetail = new UserScoreDetail();
+            $scoreDetail->incomeScore($uid, $totalIntegral, $orderSn, 'income_score', [
+                'o_id' => $orderId
+            ], $orderId);
+        }
+        
+        // 清除用户折扣缓存,以便下次充值生成新的折扣金额
+        Cache::store('redis')->delete('recharge_discount_' . $uid);
+        
+        return true;
+    }
+
+    /**
+     * 充值成功回调处理(内部调用)
+     * @param string $orderSn 订单号
+     * @param string $paySn 支付流水号
+     * @param string $payJson 支付返回信息
+     * @return bool
+     */
+    public function paySuccess($orderSn, $paySn, $payJson = '')
+    {
+        $rechargeOrder = new RechargeOrder();
+        $orderInfo = $rechargeOrder->getByOrderSn($orderSn);
+        
+        if (!$orderInfo) {
+            return false;
+        }
+        
+        // 更新订单支付状态
+        $updateResult = $rechargeOrder->updatePayStatus($orderSn, $paySn, $payJson);
+        
+        if (!$updateResult) {
+            return false;
+        }
+        
+        // 增加用户积分
+        $this->addUserIntegral($orderInfo['uid'], $orderInfo['total_integral'], $orderSn, $orderInfo['price'], $orderInfo['id']);
+        
+        return true;
+    }
+}

+ 5 - 2
app/api/controller/User.php

@@ -18,6 +18,7 @@ use app\model\api\ContractComment as ContractCommentModel;
 use app\model\api\ContractRecord as UserContractRecordModel;
 use app\model\api\ContractRecord as UserContractRecordModel;
 use app\model\api\ContractTemplate;
 use app\model\api\ContractTemplate;
 use app\model\api\LikeBookmark;
 use app\model\api\LikeBookmark;
+use app\model\api\Sys;
 use app\model\api\User as UserModel;
 use app\model\api\User as UserModel;
 use app\model\api\UserClock as UserClockModel;
 use app\model\api\UserClock as UserClockModel;
 use app\model\api\UserDetail as UserDetailModel;
 use app\model\api\UserDetail as UserDetailModel;
@@ -492,7 +493,8 @@ class User extends BaseController
             (new UserModel())->where("uid",$save["uid"])->update(["first"=>1]);
             (new UserModel())->where("uid",$save["uid"])->update(["first"=>1]);
             $parent_uid = (new UserModel)->where("uid", $save["uid"])->value("parent_uid");
             $parent_uid = (new UserModel)->where("uid", $save["uid"])->value("parent_uid");
             if ($parent_uid>0){
             if ($parent_uid>0){
-                (new UserScoreDetail())->incomeScore($parent_uid,10,'',"subInfo_score",[],$save["uid"]);
+                $sys = (new Sys())->where("id", 1)->find();
+                (new UserScoreDetail())->incomeScore($parent_uid,$sys['points_share'],'',"subInfo_score",[],$save["uid"],'邀请奖励','邀请用户生成名片奖励积分');
             }
             }
         }
         }
 
 
@@ -649,6 +651,7 @@ class User extends BaseController
             $payTrade = (new PayTradeModel)
             $payTrade = (new PayTradeModel)
                 ->where("uid", $request->user["uid"])
                 ->where("uid", $request->user["uid"])
                 ->where("o_id", $o_id)
                 ->where("o_id", $o_id)
+                ->where("order_type", 0)
                 ->where("type", "temp")
                 ->where("type", "temp")
                 ->where("status", 0)
                 ->where("status", 0)
                 ->where("time", "<", time() - 7 * 24 * 60 * 60)
                 ->where("time", "<", time() - 7 * 24 * 60 * 60)
@@ -661,7 +664,7 @@ class User extends BaseController
 //                if($v['pay_type'] == 'wxpay') {
 //                if($v['pay_type'] == 'wxpay') {
 //                    $result = $wxpay->closeOrder($v['pay_no']);
 //                    $result = $wxpay->closeOrder($v['pay_no']);
 //                }
 //                }
-                (new PayTradeModel)->where("id", $v['id'])->where("status", 0)->delete();
+                (new PayTradeModel)->where("id", $v['id'])->where("status", 0)->where("order_type", 0)->delete();
             }
             }
             $mtime = microtime(true) * 10000;
             $mtime = microtime(true) * 10000;
             $payOn = "T" . date("Ymd") . $mtime . rand(100, 999) . $request->user['uid'];
             $payOn = "T" . date("Ymd") . $mtime . rand(100, 999) . $request->user['uid'];

+ 34 - 0
app/api/route/recharge.php

@@ -0,0 +1,34 @@
+<?php
+// +----------------------------------------------------------------------
+// | [ WE CAN DO IT MORE SIMPLE  ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2018-2020 rights reserved.
+// +----------------------------------------------------------------------
+// | Author: TABLE ME
+// +----------------------------------------------------------------------
+// | Date: 2020-09-05 09:21
+// +----------------------------------------------------------------------
+
+use app\api\middleware\AllowOriginMiddleware;
+use app\api\middleware\SeretKeyMiddleware;
+use app\api\middleware\UserMiddleware;
+use think\facade\Route;
+
+Route::group('recharge', function () {
+
+    // 获取充值配置列表
+    Route::rule('configList', 'Recharge/configList');
+    // 创建充值订单
+    Route::rule('createOrder', 'Recharge/createOrder');
+    // 充值支付
+    Route::rule('pay', 'Recharge/pay');
+    // 充值订单列表
+    Route::rule('orderList', 'Recharge/orderList');
+    // 充值订单详情
+    Route::rule('orderDetail', 'Recharge/orderDetail');
+
+})->middleware([
+    AllowOriginMiddleware::class,
+    SeretKeyMiddleware::class,
+    UserMiddleware::class,
+]);

+ 14 - 0
app/lib/OrderLib.php

@@ -13,6 +13,7 @@ declare (strict_types=1);
 
 
 namespace app\lib;
 namespace app\lib;
 
 
+use app\api\controller\Recharge;
 use app\model\api\PayTrade;
 use app\model\api\PayTrade;
 use app\model\api\Order;
 use app\model\api\Order;
 use app\model\api\ShowTemplateOrder;
 use app\model\api\ShowTemplateOrder;
@@ -83,6 +84,19 @@ class OrderLib
                 PayTrade::commitTrans();
                 PayTrade::commitTrans();
                 return true;
                 return true;
             }
             }
+            //充值订单
+            if($payTradeData["type"]=="recharge"){
+                // 调用充值成功处理
+                $rechargeController = new \app\api\controller\Recharge();
+                $result = $rechargeController->paySuccess($payOn, $payTradeData['transaction_id'] ?? '', $payDataInfo);
+                $result = (new Recharge())->paySuccess($payOn, $payTradeData['transaction_id'] ?? '', $payDataInfo);
+                if (!$result) {
+                    PayTrade::rollbackTrans();
+                    return false;
+                }
+                PayTrade::commitTrans();
+                return true;
+            }
             PayTrade::commitTrans();
             PayTrade::commitTrans();
         } catch (DbException $dbException) {
         } catch (DbException $dbException) {
             PayTrade::rollbackTrans();
             PayTrade::rollbackTrans();

+ 4 - 2
app/model/api/PayTrade.php

@@ -24,7 +24,7 @@ class PayTrade extends BaseModel
      * @param $out_trade_no 其他订单
      * @param $out_trade_no 其他订单
      * @param $djson 额外说明
      * @param $djson 额外说明
      */
      */
-    public function credentials($payType, $uid, $code, $money, $content = '支付凭证', $out_trade_no = '', $djson = [],$admin_id=0)
+    public function credentials($payType, $uid, $code, $money, $content = '支付凭证', $out_trade_no = '', $djson = [],$admin_id=0, $type = '', $o_id = 0)
     {
     {
         $apple_pid = (empty($djson) || empty($djson["apple_pid"])) ? '':$djson["apple_pid"];
         $apple_pid = (empty($djson) || empty($djson["apple_pid"])) ? '':$djson["apple_pid"];
         $payOn = $this->mkPayOn($uid);
         $payOn = $this->mkPayOn($uid);
@@ -50,7 +50,9 @@ class PayTrade extends BaseModel
             'admin_id'     => $admin_id,
             'admin_id'     => $admin_id,
             'apple_pid'    => $apple_pid,
             'apple_pid'    => $apple_pid,
             'i_tuid'       => $i_tuid,
             'i_tuid'       => $i_tuid,
-            'i_uid'        => $i_uid
+            'i_uid'        => $i_uid,
+            'type'         => $type,
+            'o_id'         => $o_id
         ]);
         ]);
         return $bool ? $payOn : null;
         return $bool ? $payOn : null;
 
 

+ 99 - 0
app/model/api/RechargeConfig.php

@@ -0,0 +1,99 @@
+<?php
+declare (strict_types=1);
+
+namespace app\model\api;
+
+use library\basic\BaseModel;
+use think\Model;
+
+/**
+ * @mixin \think\Model
+ */
+class RechargeConfig extends BaseModel
+{
+    /**
+     * 获取充值配置列表
+     * @param array $where 查询条件
+     * @param string $field 查询字段
+     * @param int $page 页码
+     * @param int $pageCount 每页数量
+     * @param string $order 排序
+     * @return array
+     */
+    public function getList($where = [], $field = '*', $page = 1, $pageCount = 20, $order = 'sort asc,id asc')
+    {
+        $data = $this
+            ->where($where)
+            ->field($field)
+            ->order($order)
+            ->paginate(['list_rows' => $pageCount, 'page' => $page])
+            ->toArray();
+        return [$data['total'], $data['data']];
+    }
+
+    /**
+     * 获取显示的充值配置
+     * @return array
+     */
+    public function getShowList()
+    {
+        return $this
+            ->where('is_show', 1)
+            ->order('sort asc,id asc')
+            ->select()
+            ->toArray();
+    }
+
+    /**
+     * 获取默认充值配置
+     * @return array|null
+     */
+    public function getDefault()
+    {
+        return $this
+            ->where('is_default', 1)
+            ->where('is_show', 1)
+            ->find();
+    }
+
+    /**
+     * 根据ID获取充值配置
+     * @param int $id 配置ID
+     * @return array|null
+     */
+    public function getById($id)
+    {
+        return $this->where('id', $id)->find();
+    }
+
+    /**
+     * 保存充值配置
+     * @param array $data 数据
+     * @return bool|int
+     */
+    public function saveData($data)
+    {
+        return $this->insert($data);
+    }
+
+    /**
+     * 更新充值配置
+     * @param int $id 配置ID
+     * @param array $data 数据
+     * @return bool
+     */
+    public function updateConfig($id, $data): bool
+    {
+        return $this->where('id', $id)->update($data) !== false;
+    }
+
+    /**
+     * 删除充值配置
+     * @param int $id 配置ID
+     * @return bool
+     */
+    public function deleteData($id)
+    {
+        return $this->where('id', $id)->delete();
+    }
+}

+ 186 - 0
app/model/api/RechargeOrder.php

@@ -0,0 +1,186 @@
+<?php
+declare (strict_types=1);
+
+namespace app\model\api;
+
+use library\basic\BaseModel;
+use think\Model;
+
+/**
+ * @mixin \think\Model
+ */
+class RechargeOrder extends BaseModel
+{
+    /**
+     * 生成充值订单号
+     * @param int $uid 用户UID
+     * @return string
+     */
+    public function mkOrderSn($uid)
+    {
+        return 'RO' . time() . rand(1000, 9000) . $uid;
+    }
+
+    /**
+     * 创建充值订单
+     * @param int $uid 用户UID
+     * @param int $rechargeId 充值配置ID(0为自定义充值)
+     * @param float $price 充值金额
+     * @param int $integral 获得积分
+     * @param int $giveIntegral 赠送积分
+     * @param string $payType 支付方式:wxpay/alipay/system
+     * @param int $adminId 管理员ID(后台充值)
+     * @param string $remark 备注
+     * @param float $discount 折扣金额
+     * @return string|null 订单号
+     */
+    public function createOrder($uid, $rechargeId, $price, $integral, $giveIntegral, $payType = 'wxpay', $adminId = 0, $remark = '', $discount = 0)
+    {
+        $orderSn = $this->mkOrderSn($uid);
+        $totalIntegral = $integral + $giveIntegral;
+        
+        $bool = $this->insert([
+            'order_sn' => $orderSn,
+            'uid' => $uid,
+            'recharge_id' => $rechargeId,
+            'price' => $price,
+            'integral' => $integral,
+            'give_integral' => $giveIntegral,
+            'total_integral' => $totalIntegral,
+            'pay_type' => $payType,
+            'paid' => 0,
+            'pay_time' => 0,
+            'remark' => $remark,
+            'admin_id' => $adminId,
+            'discount_amount' => $discount,
+            'status' => 0,
+            'add_time' => time(),
+            'update_time' => time()
+        ]);
+        
+        return $bool ? $orderSn : null;
+    }
+
+    /**
+     * 根据订单号获取订单
+     * @param string $orderSn 订单号
+     * @return array|null
+     */
+    public function getByOrderSn($orderSn)
+    {
+        return $this->where('order_sn', $orderSn)->find();
+    }
+
+    /**
+     * 根据ID获取订单
+     * @param int $id 订单ID
+     * @return array|null
+     */
+    public function getById($id)
+    {
+        return $this->where('id', $id)->find();
+    }
+
+    /**
+     * 更新订单支付状态
+     * @param string $orderSn 订单号
+     * @param string $paySn 支付流水号
+     * @param string $payJson 支付返回信息
+     * @return bool
+     */
+    public function updatePayStatus($orderSn, $paySn, $payJson = '')
+    {
+        return $this->where('order_sn', $orderSn)->update([
+            'paid' => 1,
+            'pay_sn' => $paySn,
+            'pay_json' => $payJson,
+            'pay_time' => time(),
+            'status' => 1,
+            'update_time' => time()
+        ]);
+    }
+
+    /**
+     * 获取用户充值订单列表
+     * @param int $uid 用户UID
+     * @param array $where 查询条件
+     * @param string $field 查询字段
+     * @param int $page 页码
+     * @param int $pageCount 每页数量
+     * @param string $order 排序
+     * @return array
+     */
+    public function getUserList($uid, $where = [], $field = '*', $page = 1, $pageCount = 20, $order = 'add_time desc')
+    {
+        $where['uid'] = $uid;
+        $data = $this
+            ->where($where)
+            ->field($field)
+            ->order($order)
+            ->paginate(['list_rows' => $pageCount, 'page' => $page])
+            ->toArray();
+        return [$data['total'], $data['data']];
+    }
+
+    /**
+     * 获取充值订单列表(后台)
+     * @param array $where 查询条件
+     * @param string $field 查询字段
+     * @param int $page 页码
+     * @param int $pageCount 每页数量
+     * @param string $order 排序
+     * @return array
+     */
+    public function getAdminList($where = [], $field = '*', $page = 1, $pageCount = 20, $order = 'add_time desc')
+    {
+        $data = $this
+            ->alias('ro')
+            ->field($field)
+            ->leftJoin('user u', 'u.uid = ro.uid')
+            ->when(!empty($where), function ($query) use ($where) {
+                if (!empty($where['order_sn'])) {
+                    $query->where('ro.order_sn', $where['order_sn']);
+                }
+                if (!empty($where['uid'])) {
+                    $query->where('ro.uid', $where['uid']);
+                }
+                if (!empty($where['nickname'])) {
+                    $query->whereLike('u.nickname', "%{$where['nickname']}%");
+                }
+                if (!empty($where['mobile'])) {
+                    $query->where('u.mobile', $where['mobile']);
+                }
+                if (!empty($where['pay_type'])) {
+                    $query->where('ro.pay_type', $where['pay_type']);
+                }
+                if (!empty($where['paid'])) {
+                    $query->where('ro.paid', $where['paid']);
+                }
+                if (!empty($where['status'])) {
+                    $query->where('ro.status', $where['status']);
+                }
+                if (!empty($where['time']) && !empty($where['time'][0]) && !empty($where['time'][1])) {
+                    $startTime = strtotime($where['time'][0]);
+                    $endTime = strtotime($where['time'][1]);
+                    $query->whereBetween('ro.add_time', "{$startTime},{$endTime}");
+                }
+            })
+            ->order($order)
+            ->paginate(['list_rows' => $pageCount, 'page' => $page])
+            ->toArray();
+        return [$data['total'], $data['data']];
+    }
+
+    /**
+     * 关闭订单
+     * @param string $orderSn 订单号
+     * @return bool
+     */
+    public function closeOrder($orderSn)
+    {
+        return $this->where('order_sn', $orderSn)->update([
+            'status' => -1,
+            'update_time' => time()
+        ]);
+    }
+}

+ 1 - 0
app/model/api/UserDetail.php

@@ -21,6 +21,7 @@ class UserDetail extends BaseModel
         'tx_apply'        => ['code' => "提现余额",        "content" => "您发起提现,扣除余额:{money}。"],
         'tx_apply'        => ['code' => "提现余额",        "content" => "您发起提现,扣除余额:{money}。"],
         'tx_refund'       => ['code' => "提现失败",        "content" => "提现失败,返还余额:{money}。"],
         'tx_refund'       => ['code' => "提现失败",        "content" => "提现失败,返还余额:{money}。"],
         'show_temp_pay'   => ['code' => "购买皮肤模板",     "content" => "您使用余额支付,扣除余额:{money}。"],
         'show_temp_pay'   => ['code' => "购买皮肤模板",     "content" => "您使用余额支付,扣除余额:{money}。"],
+        'recharge_pay'    => ['code' => "充值余额支付",     "content" => "您使用余额充值,扣除余额:{money}。"],
         
         
         
         
         'show_temp_buy'   => ['code' => "购买皮肤模板消费",  "content" => "{mono},用户消费:{money}。"],
         'show_temp_buy'   => ['code' => "购买皮肤模板消费",  "content" => "{mono},用户消费:{money}。"],

+ 4 - 3
app/model/api/UserScoreDetail.php

@@ -101,14 +101,15 @@ class UserScoreDetail extends BaseModel
      * @return bool
      * @return bool
      * @throws \think\db\exception\DbException
      * @throws \think\db\exception\DbException
      */
      */
-    public function incomeScore($uid, $money, $orderSn="",$code="income_score",$parms=array(),$link_id=0)
+    public function incomeScore($uid, $money, $orderSn="",$code="income_score",$parms=array(),$link_id=0,$title="",$content="")
     {
     {
         try {
         try {
-            $content          = $this->TplParam($this->config[$code]['content'],compact('money'));
+//            $content          = $this->TplParam($this->config[$code]['content'],compact('money'));
             $post['uid']      = $uid;
             $post['uid']      = $uid;
             $post['v']        = $money;
             $post['v']        = $money;
             $post['code']     = $code;
             $post['code']     = $code;
-            $post['title']    = $this->config[$code]['code'];
+//            $post['title']    = $this->config[$code]['code'];
+            $post['title']    = $title;
             $post['content']  = $content;
             $post['content']  = $content;
             $post['type']     = 1;
             $post['type']     = 1;
             $post['time']     = time();
             $post['time']     = time();

+ 417 - 0
app/system/controller/Recharge.php

@@ -0,0 +1,417 @@
+<?php
+declare (strict_types=1);
+
+namespace app\system\controller;
+
+use app\BaseController;
+use app\Request;
+use app\model\api\RechargeConfig;
+use app\model\api\RechargeOrder;
+use app\model\api\User;
+use library\services\UtilService;
+use think\facade\Db;
+
+class Recharge extends BaseController
+{
+    /**
+     * 充值配置列表
+     * @param Request $request
+     * @return mixed
+     */
+    public function configList(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['page', 1],
+            ['pageSize', 20],
+            ['title', ''],
+            ['is_show', '']
+        ], $request);
+
+        $where = [];
+        if (!empty($post['title'])) {
+            $where['title'] = ['like', '%' . $post['title'] . '%'];
+        }
+        if (!empty($post['is_show'])) {
+            $where['is_show'] = $post['is_show'];
+        }
+
+        $rechargeConfig = new RechargeConfig();
+        $list = $rechargeConfig->getList($where, '*', $post['page'], $post['pageSize'], 'sort asc,id asc');
+        
+        return app('json')->success([
+            'list' => $list[1],
+            'total' => $list[0],
+            'page' => $post['page'],
+            'pageSize' => $post['pageSize']
+        ]);
+    }
+
+    /**
+     * 充值配置详情
+     * @param Request $request
+     * @return mixed
+     */
+    public function configDetail(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['id', 0]
+        ], $request);
+
+        if ($post['id'] <= 0) {
+            return app('json')->fail('参数错误');
+        }
+
+        $rechargeConfig = new RechargeConfig();
+        $config = $rechargeConfig->getById($post['id']);
+        
+        if (!$config) {
+            return app('json')->fail('充值配置不存在');
+        }
+
+        return app('json')->success($config);
+    }
+
+    /**
+     * 添加充值配置
+     * @param Request $request
+     * @return mixed
+     */
+    public function configAdd(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['title', ''],
+            ['price', 0],
+            ['integral', 0],
+            ['give_integral', 0],
+            ['sort', 0],
+            ['is_show', 1],
+            ['is_default', 0],
+            ['min_price', 0],
+            ['max_price', 0],
+            ['content', '']
+        ], $request);
+
+        if (empty($post['title'])) {
+            return app('json')->fail('套餐名称不能为空');
+        }
+        if ($post['price'] <= 0) {
+            return app('json')->fail('充值金额必须大于0');
+        }
+        if ($post['integral'] <= 0) {
+            return app('json')->fail('获得积分必须大于0');
+        }
+
+        $rechargeConfig = new RechargeConfig();
+        $data = [
+            'title' => $post['title'],
+            'price' => $post['price'],
+            'integral' => $post['integral'],
+            'give_integral' => $post['give_integral'],
+            'sort' => $post['sort'],
+            'is_show' => $post['is_show'],
+            'is_default' => $post['is_default'],
+            'min_price' => $post['min_price'],
+            'max_price' => $post['max_price'],
+            'content' => $post['content'],
+            'add_time' => time(),
+            'update_time' => time()
+        ];
+
+        $result = $rechargeConfig->saveData($data);
+        
+        if (!$result) {
+            return app('json')->fail('添加失败');
+        }
+
+        return app('json')->success('添加成功');
+    }
+
+    /**
+     * 编辑充值配置
+     * @param Request $request
+     * @return mixed
+     */
+    public function configEdit(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['id', 0],
+            ['title', ''],
+            ['price', 0],
+            ['integral', 0],
+            ['give_integral', 0],
+            ['sort', 0],
+            ['is_show', 1],
+            ['is_default', 0],
+            ['min_price', 0],
+            ['max_price', 0],
+            ['content', '']
+        ], $request);
+
+        if ($post['id'] <= 0) {
+            return app('json')->fail('参数错误');
+        }
+        if (empty($post['title'])) {
+            return app('json')->fail('套餐名称不能为空');
+        }
+        if ($post['price'] <= 0) {
+            return app('json')->fail('充值金额必须大于0');
+        }
+        if ($post['integral'] <= 0) {
+            return app('json')->fail('获得积分必须大于0');
+        }
+
+        $rechargeConfig = new RechargeConfig();
+        $config = $rechargeConfig->getById($post['id']);
+        
+        if (!$config) {
+            return app('json')->fail('充值配置不存在');
+        }
+
+        $data = [
+            'title' => $post['title'],
+            'price' => $post['price'],
+            'integral' => $post['integral'],
+            'give_integral' => $post['give_integral'],
+            'sort' => $post['sort'],
+            'is_show' => $post['is_show'],
+            'is_default' => $post['is_default'],
+            'min_price' => $post['min_price'],
+            'max_price' => $post['max_price'],
+            'content' => $post['content'],
+            'update_time' => time()
+        ];
+
+        $result = $rechargeConfig->updateConfig($post['id'], $data);
+        
+        if (!$result) {
+            return app('json')->fail('编辑失败');
+        }
+
+        return app('json')->success('编辑成功');
+    }
+
+    /**
+     * 删除充值配置
+     * @param Request $request
+     * @return mixed
+     */
+    public function configDelete(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['id', 0]
+        ], $request);
+
+        if ($post['id'] <= 0) {
+            return app('json')->fail('参数错误');
+        }
+
+        $rechargeConfig = new RechargeConfig();
+        $config = $rechargeConfig->getById($post['id']);
+        
+        if (!$config) {
+            return app('json')->fail('充值配置不存在');
+        }
+
+        $result = $rechargeConfig->deleteData($post['id']);
+        
+        if (!$result) {
+            return app('json')->fail('删除失败');
+        }
+
+        return app('json')->success('删除成功');
+    }
+
+    /**
+     * 充值订单列表(后台)
+     * @param Request $request
+     * @return mixed
+     */
+    public function orderList(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['page', 1],
+            ['pageSize', 20],
+            ['order_sn', ''],
+            ['uid', ''],
+            ['nickname', ''],
+            ['mobile', ''],
+            ['pay_type', ''],
+            ['paid', ''],
+            ['status', ''],
+            ['time', []]
+        ], $request);
+
+        $where = [];
+        if (!empty($post['order_sn'])) {
+            $where['order_sn'] = $post['order_sn'];
+        }
+        if (!empty($post['uid'])) {
+            $where['uid'] = $post['uid'];
+        }
+        if (!empty($post['nickname'])) {
+            $where['nickname'] = $post['nickname'];
+        }
+        if (!empty($post['mobile'])) {
+            $where['mobile'] = $post['mobile'];
+        }
+        if (!empty($post['pay_type'])) {
+            $where['pay_type'] = $post['pay_type'];
+        }
+        if (!empty($post['paid'])) {
+            $where['paid'] = $post['paid'];
+        }
+        if (!empty($post['status'])) {
+            $where['status'] = $post['status'];
+        }
+        if (!empty($post['time']) && !empty($post['time'][0]) && !empty($post['time'][1])) {
+            $where['time'] = $post['time'];
+        }
+
+        $rechargeOrder = new RechargeOrder();
+        $list = $rechargeOrder->getAdminList($where, '*', $post['page'], $post['pageSize']);
+        
+        return app('json')->success([
+            'list' => $list[1],
+            'total' => $list[0],
+            'page' => $post['page'],
+            'pageSize' => $post['pageSize']
+        ]);
+    }
+
+    /**
+     * 充值订单详情(后台)
+     * @param Request $request
+     * @return mixed
+     */
+    public function orderDetail(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['id', 0]
+        ], $request);
+
+        if ($post['id'] <= 0) {
+            return app('json')->fail('参数错误');
+        }
+
+        $rechargeOrder = new RechargeOrder();
+        $order = $rechargeOrder->getById($post['id']);
+        
+        if (!$order) {
+            return app('json')->fail('订单不存在');
+        }
+
+        // 获取用户信息
+        $userModel = new User();
+        $user = $userModel->where('uid', $order['uid'])->find();
+        
+        $order['user_info'] = $user ? [
+            'nickname' => $user['nickname'],
+            'mobile' => $user['mobile'],
+            'avatar' => $user['avatar']
+        ] : [];
+
+        return app('json')->success($order);
+    }
+
+    /**
+     * 后台手动充值(系统充值)
+     * @param Request $request
+     * @return mixed
+     */
+    public function systemRecharge(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['uid', 0],
+            ['price', 0],
+            ['integral', 0],
+            ['give_integral', 0],
+            ['remark', '']
+        ], $request);
+
+        if ($post['uid'] <= 0) {
+            return app('json')->fail('用户ID错误');
+        }
+        if ($post['price'] <= 0) {
+            return app('json')->fail('充值金额必须大于0');
+        }
+        if ($post['integral'] <= 0) {
+            return app('json')->fail('获得积分必须大于0');
+        }
+
+        $userModel = new User();
+        $user = $userModel->where('uid', $post['uid'])->find();
+        
+        if (!$user) {
+            return app('json')->fail('用户不存在');
+        }
+
+        $rechargeOrder = new RechargeOrder();
+        $totalIntegral = $post['integral'] + $post['give_integral'];
+        
+        // 创建系统充值订单
+        $orderSn = $rechargeOrder->createOrder($post['uid'], 0, $post['price'], $post['integral'], $post['give_integral'], 'system', $request->admin_id, $post['remark']);
+        
+        if (!$orderSn) {
+            return app('json')->fail('创建订单失败');
+        }
+
+        // 直接完成支付(系统充值无需支付)
+        $updateResult = $rechargeOrder->updatePayStatus($orderSn, 'system_' . time(), '系统充值');
+        
+        if (!$updateResult) {
+            return app('json')->fail('更新订单状态失败');
+        }
+
+        // 增加用户积分
+        $userModel->where('uid', $post['uid'])->inc('score', $totalIntegral)->inc('score_in', $totalIntegral)->inc('total_recharge', $post['price'])->update();
+
+        // 记录积分明细
+        $scoreDetail = new UserScoreDetail();
+        $scoreDetail->incomeScore($post['uid'], $totalIntegral, $orderSn, 'income_score', [
+            'o_id' => $rechargeOrder->getByOrderSn($orderSn)['id']
+        ], $rechargeOrder->getByOrderSn($orderSn)['id']);
+
+        return app('json')->success([
+            'order_sn' => $orderSn,
+            'price' => $post['price'],
+            'integral' => $post['integral'],
+            'give_integral' => $post['give_integral'],
+            'total_integral' => $totalIntegral
+        ]);
+    }
+
+    /**
+     * 关闭充值订单
+     * @param Request $request
+     * @return mixed
+     */
+    public function closeOrder(Request $request)
+    {
+        $post = UtilService::getMore([
+            ['order_sn', '']
+        ], $request);
+
+        if (empty($post['order_sn'])) {
+            return app('json')->fail('订单号不能为空');
+        }
+
+        $rechargeOrder = new RechargeOrder();
+        $order = $rechargeOrder->getByOrderSn($post['order_sn']);
+        
+        if (!$order) {
+            return app('json')->fail('订单不存在');
+        }
+        
+        if ($order['paid'] == 1) {
+            return app('json')->fail('已支付的订单不能关闭');
+        }
+
+        $result = $rechargeOrder->closeOrder($post['order_sn']);
+        
+        if (!$result) {
+            return app('json')->fail('关闭订单失败');
+        }
+
+        return app('json')->success('关闭订单成功');
+    }
+}

+ 39 - 0
app/system/route/recharge.php

@@ -0,0 +1,39 @@
+<?php
+// +----------------------------------------------------------------------
+// | [ WE CAN DO IT MORE SIMPLE  ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2018-2020 rights reserved.
+// +----------------------------------------------------------------------
+// |
+// +----------------------------------------------------------------------
+// | Date: 2020-08-30 14:41
+// +----------------------------------------------------------------------
+
+use think\facade\Route;
+
+Route::group('recharge', function () {
+
+    // 充值配置列表
+    Route::rule('configList', 'Recharge/configList');
+    // 充值配置详情
+    Route::rule('configDetail', 'Recharge/configDetail');
+    // 添加充值配置
+    Route::rule('configAdd', 'Recharge/configAdd');
+    // 编辑充值配置
+    Route::rule('configEdit', 'Recharge/configEdit');
+    // 删除充值配置
+    Route::rule('configDelete', 'Recharge/configDelete');
+    // 充值订单列表
+    Route::rule('orderList', 'Recharge/orderList');
+    // 充值订单详情
+    Route::rule('orderDetail', 'Recharge/orderDetail');
+    // 系统充值(后台手动充值)
+    Route::rule('systemRecharge', 'Recharge/systemRecharge');
+    // 关闭订单
+    Route::rule('closeOrder', 'Recharge/closeOrder');
+
+})->middleware([
+    \app\system\middleware\AllowOriginMiddleware::class,
+    \app\system\middleware\AdminAuthTokenMiddleware::class,
+    \app\system\middleware\AdminCkeckRoleMiddleware::class,
+]);