lip 1 month ago
parent
commit
6ec32a0d9e

+ 0 - 1
.htaccess

@@ -1 +0,0 @@
- 

+ 1 - 0
app/admin/controller/Admin.php

@@ -209,6 +209,7 @@ class Admin extends BaseController
             $params = (new AdminValidate())->post()->goCheck('login');
 
             $admin = AdminModel::where('username', $params['username'])->find();
+           
             if (!$admin) {
                 throw new \Exception('账号不存在');
             }

+ 139 - 0
app/admin/controller/Operation.php

@@ -0,0 +1,139 @@
+<?php
+
+namespace app\admin\controller;
+
+use app\BaseController;
+use Carbon\Carbon;
+use Exception;
+use app\admin\model\Operation as OperationModel;
+use app\admin\model\User;
+use app\admin\model\Recharge;
+use app\admin\model\Withdraw;
+
+class Operation extends BaseController
+{
+    /**
+     * 用户报表
+     */
+    function exchangeList()
+    {
+        try {
+            $params = $this->request->param();
+            $page = $params['page'] ?? 1;
+            $limit = $params['limit'] ?? 15;
+
+            $query = new User();
+            $admin_id = $this->admin_id;
+            // if ($admin_id != 1 && Config::adminOpenAllData($admin_id) === false) {
+            //     $user_code = $this->user_code;   
+            //     $query->where('user_code', $user_code);
+            // }
+
+            if (isset($params['user_id'])) {
+                $user_id = $params['user_id'];
+                $query->where(function ($query1) use ($user_id) {
+                    $query1->where('user_id', $user_id)
+                        ->orWhere('realname', 'like', "%{$user_id}%");
+                });
+            }
+
+            $count = $query->count();
+            $list = $query->order("last_login_time",'desc')
+                ->field(['id', 'user_id', 'realname', 'money','remark'])
+                ->limit($limit)
+                ->page($page)
+                ->select();
+            
+            $start = !empty($params['start_time']) ? "{$params['start_time']} 00:00:00" : null;
+            $start = $start ? strtotime($start) : null;
+            
+            $end = !empty($params['end_time']) ? "{$params['end_time']} 23:59:59" : null;
+            $end = $end ? strtotime($end) : null;
+
+            foreach ($list as &$item) {
+                $item['recharge'] = number_format(Recharge::where('user_id', $item['user_id'])
+                    ->where('status', 1)
+                    ->where(function ($query1) use ($start, $end) {
+                        if ($start && $end) {
+                            $query1->where('create_time', '>=', $start)
+                                ->where('create_time', '<=', $end);
+                        }
+                    })
+                    ->sum('amount'), 2);
+                $item['withdraw'] = number_format(Withdraw::where('user_id', $item['user_id'])
+                    ->where('status', 1)
+                    ->where(function ($query1) use ($start, $end) {
+                        if ($start && $end) {
+                            $query1->where('create_time', '>=', $start)
+                                ->where('create_time', '<=', $end);
+                        }
+                    })
+                    ->sum('amount'), 2);
+                $item['price_count'] = '0.00';
+                $item['order_price'] = '0.00';
+            }
+
+        } catch (Exception $e) {
+            return $this->error($e->getMessage());
+        }
+        return $this->success(['count' => $count, 'list' => $list]);
+
+    }
+
+    /**
+     * 运营数据
+     * @apiParam {String{'day','week','month','all'}} type 类型
+     * - day 今日
+     * - week 本周
+     * - month 本月
+     * - all 全部
+     */
+    function index()
+    {
+        try {
+            $params = $this->request->param();
+            
+            $data = [
+                'recharge' => 0,
+                'withdraw' => 0,
+                'total_price' => 0,
+            ];
+            $page = $params['page'] ?? 1;
+            $limit = $params['limit'] ?? 15;
+            $query = new OperationModel;
+            $query1 = new OperationModel;
+            if (!empty($params['start_time'])) {
+                $query->where('date', '>=', $params['start_time'])
+                    ->where('date', '<=', $params['end_time']);
+                $query1->where('date', '>=', $params['start_time'])
+                    ->where('date', '<=', $params['end_time']);
+            } else if ($params['type'] != 'all') {
+                switch ($params['type']) {
+                    case 'day':
+                        $date = date('Y-m-d');
+                        break;
+                    case "week":
+                        $date = Carbon::now()->startOfWeek()->format('Y-m-d');
+                        break;
+                    case "month":
+                        $date = Carbon::now()->firstOfMonth()->format('Y-m-d');
+                        break;
+                }
+                $query->where('date', '>=', $date);
+                $query1->where('date', '>=', $date);
+            }
+            $data['recharge'] = $query1->sum('recharge');
+            $data['withdraw'] = $query1->sum('withdraw');
+            $data['total_price'] = $query1->sum('total_price');
+            $count = $query->count();
+            $list = $query->limit($limit)
+                ->page($page)
+                ->order('date','desc')
+                ->select();
+
+        } catch (Exception $e) {
+            return $this->error($e->getMessage());
+        }
+        return $this->success(['count' => $count, 'list' => $list, 'data' => $data]);
+    }
+}

+ 445 - 0
app/admin/controller/Order.php

@@ -0,0 +1,445 @@
+<?php
+
+namespace app\admin\controller;
+
+use app\BaseController;
+use app\admin\model\FundsRecord;
+use app\admin\model\User;
+use app\admin\model\Admin;
+use Exception;
+use app\admin\model\Order as OrderModel;
+use think\facade\Db;
+
+class Order extends BaseController
+{
+    /**
+     * 订单手动退款
+     */
+    public function adminRefund()
+    {
+        $errors = [];
+        DB::beginTransaction();
+        try {
+            $params = $this->request->param();
+            
+            $admin = Admin::where('id', $this->admin_id)->findOrFail();
+            if (!password_verify($params['safe_word'], $admin->payment_password)) throw new Exception('资金密码错误');
+
+            $orderList = OrderModel::whereIn('id', $params['order_id'])->get();
+            foreach ($orderList as $order) {
+                if ($order->return_status != 0 || $order->pay_status != 1) {
+                    continue;
+                }
+                
+                $order->status = 3;
+                $order->return_status = 2;
+                $order->return_operation_time = time();
+                $order->save();
+
+                $user = User::where('user_id', $order->user_id)->findOrFail();
+                if (!$user) continue;
+                if ($user->type == 1) {
+                    FundsRecord::addData([
+                        'transaction_type' => 'return_order',
+                        'amount_change' => $order->amount,
+                        'balance_before' => $user->money,
+                        'balance_after' => bcsub($user->money, $order->amount, 2),
+                        'user_id' => $user->user_id,
+                    ]);
+                    $user->money = bcsub($user->money, $order->amount, 2);
+                    $user->save();
+                }
+            }
+
+            DB::commit();
+        } catch (Exception $e) {
+            DB::rollBack();
+            return $this->error($e->getMessage(), $errors);
+        }
+        return $this->success();
+    }
+
+    /**
+     * @api {post} /order/refund 同意退款
+     * @apiGroup 订单管理
+     */
+    public function refund()
+    {
+        $errors = [];
+        DB::beginTransaction();
+        try {
+            $params = $this->request->param();
+            $orderId = $params['order_id'];
+            $safeWord = $params['safe_word'];
+            $admin = Admin::where('id', $this->admin_id)->findOrFail();
+            if (!password_verify($safeWord, $admin->payment_password)) throw new Exception('资金密码错误');
+            $order = OrderModel::where('id', $orderId)->findOrFail();
+            if (!$order) throw new Exception('订单不存在');
+            if ($order->return_status != 1 || $order->pay_status != 1) {
+                $errors = ['id' => $orderId];
+                throw new Exception("该订单状态无法操作");
+            }
+            
+            $order->status = 3;
+            $order->return_status = 2;
+            $order->return_operation_time = time();
+            $order->save();
+
+            $user = User::where('user_id', $order->user_id)->findOrFail();
+            $balanceAfter = bcadd($user->money, $order->amount, 2);
+            FundsRecord::addData([
+                'transaction_type' => 'return_order',
+                'amount_change' => $order->amount,
+                'balance_before' => $user->money,
+                'balance_after' => $balanceAfter,
+                'user_id' => $user->user_id,
+            ]);
+            $user->money = $balanceAfter;
+            $user->save();
+
+            DB::commit();
+        } catch (Exception $e) {
+            DB::rollBack();
+            return $this->error($e->getMessage(), $errors);
+        }
+        return $this->success();
+
+    }
+
+    /**
+     * 驳回退款申请
+     * @apiGroup 订单管理
+     */
+    public function rejection()
+    {
+        $errors = [];
+        DB::beginTransaction();
+        try {
+            $params = $this->request->param();
+            if (empty($params['failure_msg'])) $params['failure_msg'] = '';
+
+            $order = OrderModel::where('id', $params['order_id'])->first();
+            if (!$order) throw new Exception('订单不存在');
+            if ($order->status != 1 || $order->return_status != 1) {
+                $errors = ['id' => $params['order_id']];
+                throw new Exception("该订单状态无法操作");
+            }
+            $order->return_operation_time = time();
+            $order->failure_msg = $params['failure_msg'];
+            $order->save();
+            DB::commit();
+        } catch (Exception $e) {
+            DB::rollBack();
+            return $this->error($e->getMessage(), $errors);
+        }
+        return $this->success();
+    }
+
+    /**
+     * @api {get} /order/list 订单列表
+     * @apiGroup 订单管理
+     * @apiVersion 1.0.0
+     * @apiUse header
+     * @apiUse lang
+     *
+     * @apiParam {int} [page=1]
+     * @apiParam {int} [limit=15]
+     * @apiParam {String} [id] 订单编号
+     * @apiParam {String} [user_id] 买家ID
+     * @apiParam {String} [store_id] 卖家ID
+     * @apiParam {String} [phone] 手机号
+     * @apiParam {String} [contacts] 收货人
+     * @apiParam {int=0,1} [pay_status] 支付状态 0待支付 1已支付
+     * @apiParam {int=0,1} [profit_status] 利润发放 0未发放 1已发放
+     * @apiParam {String} [start_time] 开始时间
+     * - 格式:`yyyy-mm-dd`
+     * @apiParam {String} [end_time] 开始时间
+     * - 格式:`yyyy-mm-dd`
+     * @apiParam {int=-1,0,1,2,3,4,5,6,7} [type=7] 订单类别
+     * - `7 全部订单`,`0 待付款`,`1 已确认`,`2 待发货`,`3 待收货`,`4 已收货`,`5 已评价`,`6 已退款`,`-1 已取消`
+     * @apiSuccess {String} id 订单编号
+     * @apiSuccess {Object} store 店铺信息
+     * @apiSuccess {String} store.user_id 店铺ID
+     * @apiSuccess {String} store.seller_name 店铺名
+     * @apiSuccess {String} store.seller_img 店铺logo
+     * @apiSuccess {String} store.seller_address 店铺地址
+     * @apiSuccess {String} contacts 收货人姓名
+     * @apiSuccess {String} user_id 买家ID
+     * @apiSuccess {String} store_id 卖家ID
+     * @apiSuccess {String} total_cost 采购价格
+     * @apiSuccess {String} price_count 订单金额
+     * @apiSuccess {String} profit 利润
+     * @apiSuccess {int} pay_status 支付状态 0待支付 1已支付
+     * @apiSuccess {int} status 订单状态
+     * -    -1      已取消
+     * -    0       待付款
+     * -    1       待发货
+     * -    2       待发货
+     * -    3       待收货
+     * -    4       已确认
+     * -    5       已评价
+     *
+     */
+    public function getList(Request $request)
+    {
+        try {
+            $params = request()->validate([
+                'page' => ['nullable', 'integer', 'min:1'],
+                'limit' => ['nullable', 'integer', 'min:1'],
+                'id' => ['nullable', 'string'],
+                'user_id' => ['nullable', 'string'],
+                'store_id' => ['nullable', 'string'],
+                'phone' => ['nullable', 'string'],
+                'contacts' => ['nullable', 'string'],
+                'pay_status' => ['nullable', 'integer', 'in:0,1'],
+                'return_status' => ['nullable', 'integer', 'in:0,1,2,3'],
+                'purchase_status' => ['nullable', 'integer', 'in:0,1,2'],
+                'purchase_amount_status' => ['nullable', 'integer', 'in:0,1'],
+                'profit_status' => ['nullable', 'integer', 'in:0,1'],
+                'status' => ['nullable', 'integer', 'in:0,1,2,3,4,5,6,7,-1'],
+                'start_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:end_time'],
+                'end_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:start_time'],
+                'order_task_id' => ['nullable', 'string'],
+                'type' => ['nullable', 'integer', 'in:1,2'],
+            ]);
+            $page = request()->input('page', 1);
+            $limit = request()->input('limit', 15);
+
+            $admin_id = $request->user->id;
+            if ($admin_id != 1 && Config::adminOpenAllData($admin_id) === false) {
+                $user_code = $request->user->user_code;
+                $query = OrderModel::leftJoin('users', 'orders.user_id', '=', 'users.user_id')
+                    ->leftJoin('users as stores', 'orders.store_id', '=', 'stores.user_id')
+                    ->where(function ($query) use ($user_code){
+                        $query->where('users.user_code', $user_code)
+                            ->orWhere('stores.user_code', $user_code);
+                    });
+            } else {
+                $query = OrderModel::query();
+            }
+           
+            if (!empty($params['start_time'])) {
+                $query = $query->where('orders.created_at', '>=', $params['start_time'] . " 00:00:00")
+                    ->where('orders.created_at', '<=', $params['end_time'] . " 23:59:59");
+            }
+            if (!empty($params['id'])) {
+                $query = $query->where('orders.id', $params['id']);
+            }
+            if (!empty($params['user_id'])) {
+                $query = $query->where('orders.user_id', $params['user_id']);
+            }
+            if (!empty($params['store_id'])) {
+                $query = $query->where('orders.store_id', $params['store_id']);
+            }
+            if (!empty($params['phone'])) {
+                $query = $query->where('orders.phone', $params['phone']);
+            }
+            if (!empty($params['contacts'])) {
+                $query = $query->where('orders.contacts', 'like', '%' . $params['contacts'] . '%');
+            }
+            if (isset($params['status'])) {
+                $query = $query->where('orders.status', $params['status']);
+            }
+            if (isset($params['return_status'])) {
+                $query = $query->where('orders.return_status', $params['return_status']);
+            }
+            if (isset($params['pay_status'])) {
+                $query = $query->where('orders.pay_status', $params['pay_status']);
+            }
+            if (isset($params['profit_status'])) {
+                $query = $query->where('orders.profit_status', $params['profit_status']);
+            }
+            if (isset($params['purchase_status'])) {
+                $query = $query->where('orders.purchase_status', $params['purchase_status']);
+            }
+            if (isset($params['purchase_amount_status'])) {
+                $query = $query->where('orders.purchase_amount_status', $params['purchase_amount_status']);
+            }
+            if (!empty($params['order_task_id'])) {
+                $query = $query->where('orders.order_task_id', $params['order_task_id']);
+            }
+            if (!empty($params['type'])) {
+                $query = $query->where('orders.type', $params['type']);
+            }
+
+            $count = $query->count();
+            $list = $query->with(['store', 'orderLog'])
+                ->select('orders.*')
+                ->forPage($page, $limit)
+                ->orderByDesc('orders.created_at')
+                ->get();
+
+
+        } catch (ValidationException $e) {
+            return $this->error($e->validator->errors()->first());
+        } catch (Exception $e) {
+            return $this->error($e->getMessage());
+        }
+        return $this->success(['count' => $count, 'stateList' => OrderShip::getStateList(), 'list' => $list]);
+
+    }
+
+    //订单详情
+    function info()
+    {
+        try {
+            request()->validate([
+                'order_id' => ['required', 'string', 'min:19', 'max:19'],
+            ]);
+            $orderId = request()->input('order_id');
+            $order = OrderModel::with(['store'])->where('id', $orderId)->first();
+            if (!$order) throw new Exception('订单不存在');
+            $order = $order->toArray();
+            ksort($order);
+            
+            //订单的商品列表
+            $list = OrderItem::where('order_id', $orderId)
+                ->get()->makeHidden(['total_cost', 'system_price', 'profit'])
+                ->toArray();
+            
+            foreach ($list as &$item) {
+                $goodsLanguages = GoodsLanguages::where('goods_id', $item['goods_id'])
+                    ->get()->toArray();
+                $goodsLanguages = Util::getDataByLanguageCode($goodsLanguages, $this->lang);
+                $item['goods_name'] = $goodsLanguages['name'];
+                $sku = GoodsSku::where('sku_id', $item['sku_id'])->first();
+                if (empty($sku)) {
+                    $item['cover_img'] = '';
+                    $item['attributes'] = [];
+                } else {
+                    $sku = $sku->toArray();
+                    $item['cover_img'] = $sku['cover_img'];
+                    $item['attributes'] = AttrValue::getAttr($sku['attr_value_ids'], $this->lang);
+                }
+            }
+            $order['goods'] = $list;
+
+            //退款驳回的原因
+            $order['failure_msg'] = '';
+            if ($order['return_status'] == 3) {
+                $order['failure_msg'] = OrderRefund::where('order_id', $orderId)->pluck('failure_msg')->first();
+            }
+        } catch (ValidationException $e) {
+            return $this->error($e->validator->errors()->first());
+        } catch (Exception $e) {
+            return $this->error($e->getMessage());
+        }
+        $order['stateList'] = OrderShip::getStateList();
+        $order['ship_time'] = OrderShip::where(['order_id' => $orderId, 'state' => 3])->value('created_at');
+        return $this->success($order);
+    }
+
+    /**
+     * @api {post} /order/ship 发货
+     * @apiGroup 订单管理
+     * @apiVersion 1.0.0
+     * @apiUse header
+     * @apiUse lang
+     *
+     * @apiParam {String[]} order_id 订单id
+     */
+    public function ship()
+    {
+        $errors = [];
+        DB::beginTransaction();
+        try {
+            $params = request()->validate([
+                'order_id' => ['required', 'array', 'min:1'],
+                'order_id.*' => ['string', 'min:19', 'max:19'],
+            ]);
+            $orderIds = $params['order_id'];
+
+            foreach ($orderIds as $orderId) {
+                $order = OrderModel::where('id', $orderId)->first();
+                if (!$order) continue;
+                if ($order->pay_status != 1 ) {
+                    continue;
+                    // $errors = ['id' => $orderId];
+                    // throw new Exception("当前订单未支付");
+                }
+                if ($order->purchase_status != 1 ) {
+                    continue;
+                    // $errors = ['id' => $orderId];
+                    // throw new Exception("当前订单未采购");
+                }
+                if ($order->status != 2 ) {
+                    continue;
+                    // $errors = ['id' => $orderId];
+                    // throw new Exception("当前订单未到待发货状态");
+                }
+                if ($order->return_status != 0 ) {
+                    continue;
+                    // $errors = ['id' => $orderId];
+                    // throw new Exception("当前订单已申请退款");
+                }
+                $order->status = 3;
+                $order->ship_state = 3;
+                $order->save();
+                OrderLog::addData([
+                    'order_id' => $order->id,
+                    'state' => 7
+                ]);
+    
+                //记录物流
+                OrderShip::addData($order->id, 3);
+            }
+            DB::commit();
+        } catch (ValidationException $e) {
+            DB::rollBack();
+            return $this->error($e->validator->errors()->first());
+        } catch (Exception $e) {
+            DB::rollBack();
+            return $this->error($e->getMessage(), $errors);
+        }
+        return $this->success();
+    }
+
+    public function updateOrderShip()
+    {
+        try {
+
+            $params = request()->validate([
+                'order_id' => ['required', 'string', 'min:19', 'max:19'],
+                'state' => ['required', 'integer', 'in:4,5,6,7,8,9'],
+            ]);
+            $orderId = $params['order_id'];
+            $state = $params['state'];
+            $order = OrderModel::where('id', $orderId)->first();
+            if (!$order) throw new Exception('订单不存在');
+            if ($order->status < 3 ) {
+                throw new Exception("当前订单未到已发货状态");
+            }   
+            
+            Db::beginTransaction();
+            $order->ship_state = $state;
+            $order->save();
+          
+            OrderShip::addData($order->id, $state);
+            Db::commit();
+        }  catch (ValidationException $e) {
+            return $this->error($e->validator->errors()->first());
+        } catch (Exception $e) {
+            Db::rollBack();
+            return $this->error($e->getMessage());
+        }
+        return $this->success();
+    }
+
+    //查看订单物流
+    public function orderShip()
+    {
+        try {
+            $params = request()->validate([
+                'order_id' => ['required', 'string', 'min:19', 'max:19'],
+            ]);
+            $orderId = $params['order_id'];
+            
+            $ship = OrderModel::getOrderShip($orderId);
+        }  catch (ValidationException $e) {
+            return $this->error($e->validator->errors()->first());
+        } catch (Exception $e) {
+            return $this->error($e->getMessage());
+        }
+        return $this->success($ship);
+    }
+}

+ 450 - 0
app/admin/controller/Wallet.php

@@ -0,0 +1,450 @@
+<?php
+
+namespace app\admin\controller;
+
+use app\BaseController;
+use app\admin\model\Recharge;
+use app\admin\model\Withdraw;
+use app\admin\model\Admin;
+use app\admin\model\User;
+use app\admin\model\FundsRecord;
+use app\admin\model\DepositAddress;
+use app\admin\validate\WalletValidate;
+use Exception;
+use think\facade\Db;
+
+/**
+ * 用户资金
+ */
+class Wallet extends BaseController
+{
+
+    /**
+     * 充值通过
+     * @apiParam {int} id 充值订单ID
+     * @apiParam {String} safe_word 资金密码
+     */
+    function rechargePass()
+    {
+        $errors = [];
+        Db::startTrans();
+        try {
+            $params = (new WalletValidate())->post()->goCheck('rechargePass');
+            $admin = Admin::where('id', $this->admin_id)->find();
+            if (!password_verify($params['safe_word'], $admin->payment_password)) throw new Exception('资金密码错误');
+            $ro = Recharge::find($params['id']);
+            if ($ro->status != 0) {
+                $errors = ['id' => $ro->order_no];
+                throw new Exception("该订单状态无法操作");
+            }
+            
+            //获取汇率
+            $currency_rate = getBlockChainFee($ro->currency);
+            $ro->currency_rate = $currency_rate;//审核通过时候的汇率
+            $ro->actual_received = bcmul($ro->recharge_amount, $currency_rate, 2);//实际到账的usdt
+            $ro->status = 1;
+            $ro->operation_time = time();
+            $ro->save();
+
+            $user = User::where('user_id', $ro->user_id)->find();
+            $userMoney = bcadd($user->money, $ro->actual_received, 2);
+            FundsRecord::addData([
+                'transaction_type' => 'recharge',
+                'amount_change' => $ro->actual_received,
+                'balance_before' => $user->money,
+                'balance_after' => $userMoney,
+                'user_id' => $user->user_id
+            ]);
+            
+            $user->money = $userMoney;
+            $user->save();
+            DB::commit();
+        } catch (Exception $e) {
+            DB::rollBack();
+            return $this->error($e->getMessage(), $errors);
+        }
+        return $this->success();
+    }
+
+    /**
+     * 充值驳回
+     * @apiParam {int} id 充值订单ID
+     * @apiParam {String{0..200}} operation_remark 驳回原因
+     *
+     */
+    function rechargeRefuse()
+    {
+        $errors = [];
+        DB::beginTransaction();
+        try {
+            $params = (new WalletValidate())->post()->goCheck('rechargeRefuse');
+            $operationRemark = $params['operation_remark'] ?? '';
+            $ro = Recharge::findOrFail($params['id']);
+            if ($ro->status != 0) {
+                $errors = ['id' => $ro->order_no];
+                throw new Exception("该订单状态无法操作");
+            }
+            $ro->status = 2;
+            $ro->operation_remark = $operationRemark;
+            $ro->operation_time = time();
+            $ro->save();
+            DB::commit();
+        } catch (Exception $e) {
+            DB::rollBack();
+            return $this->error($e->getMessage(), $errors);
+        }
+        return $this->success();
+
+    }
+
+    /**
+     * 充值订单
+     */
+    function recharges()
+    {
+        try {
+            $params = $this->request->param();
+   
+            $page = isset($params['page']) ? intval($params['page']) : 1;
+            $limit = isset($params['limit']) ? intval($params['limit']) : 15;
+            
+            $query = Recharge::alias('recharge')->join('user', 'recharge.user_id=user.user_id','left');
+           
+            if (isset($params['start_time'])) {
+                $start_time = strtotime($params['start_time'].' 00:00:00');
+                $query = $query->where('recharge.create_time', '>=', $start_time);
+            }
+            if (isset($params['end_time'])) {
+                $end_time = strtotime($params['end_time'].' 23:59:59');
+                $query = $query->where('recharge.create_time', '<=', $end_time);
+            }
+            if (isset($params['operation_start'])) {
+                $operation_start = strtotime($params['operation_start'].' 00:00:00');
+                $query->where('recharge.operation_time', '>=', $operation_start);
+            }
+            if (isset($params['operation_end'])) {
+                $operation_end = strtotime($params['operation_end'].' 23:59:59');
+                $query->where('recharge.operation_time', '<=', $operation_end);
+            }
+            if (isset($params['status']) && $params['status'] !== null) {
+                $query->where('recharge.status', $params['status']);
+            }
+            if (!empty($params['order_no'])) {
+                $query->where('recharge.order_no', $params['order_no']);
+            }
+            if (!empty($params['currency'])) {
+                $query->where('recharge.currency', $params['currency']);
+            }
+            if (!empty($params['realname'])) {
+                $query = $query->where(function ($query) use ($params) {
+                    $query->where('user.realname', 'like', "%{$params['realname']}%")
+                        ->orWhere('user.user_id', 'like', "%{$params['realname']}%");
+                });
+            }
+
+            $count = $query->count();
+            $list = $query->field(['recharge.*','user.realname', 'user.user_id', 'user.remark','user.phone','user.email'])
+                ->limit($limit)
+                ->page($page)
+                ->order('recharge.create_time','desc')
+                ->select()->toArray();
+
+        } catch (Exception $e) {
+            return $this->error($e->getMessage());
+        }
+        return $this->success(['count' => $count, 'list' => $list]);
+
+    }
+
+    /**
+     * 提现驳回
+     */
+    function withdrawRefuse()
+    {
+        $errors = [];
+        DB::beginTransaction();
+        try {
+            $params = (new WalletValidate())->post()->goCheck('withdrawRefuse');
+            $operationRemark = $params['operation_remark'] ?? '';
+            $wo = Withdraw::findOrFail($params['id']);
+            if ($wo->status != 0) {
+                $errors = ['id' => $wo->order_no];
+                throw new Exception("该订单状态无法操作");
+            }
+            $user = User::where('user_id', $wo->user_id)->find();
+            $userMoney = bcadd($user->money, $wo->deduction_usd, 2);
+            FundsRecord::addData([
+                'transaction_type' => 'withdraw',
+                'amount_change' => $wo->deduction_usd,
+                'balance_before' => $user->money,
+                'balance_after' => $userMoney,
+                'user_id' => $user->user_id
+            ]);
+            $wo->status = 2;
+            $wo->operation_remark = $operationRemark;
+            $wo->operation_time = time();
+            $wo->save();
+            $user->money = $userMoney;
+            $user->save();
+            DB::commit();
+        } catch (Exception $e) {
+            DB::rollBack();
+            return $this->error($e->getMessage(), $errors);
+        }
+        return $this->success();
+
+    }
+
+    /**
+     * @api {post} /wallet/withdrawPass 提现通过
+     * @apiDescription 需要手动打款后来此操作
+     * @apigroup 财务
+     * @apiVersion 1.0.0
+     * @apiUse header
+     * @apiUse lang
+     *
+     * @apiParam {int} id 提现订单的ID
+     * @apiParam {String} safe_word 资金密码
+     */
+    function withdrawPass()
+    {
+        $errors = [];
+        DB::beginTransaction();
+        try {
+            $params = (new WalletValidate())->post()->goCheck('withdrawPass');
+            $safeWord = $params['safe_word'] ?? '';
+            $admin = Admin::where('id', $this->admin_id)->find();
+            if (!password_verify($safeWord, $admin->payment_password)) throw new Exception('资金密码错误');
+            $wo = Withdraw::findOrFail($params['id']);
+            if ($wo->status != 0) {
+                $errors = ['id' => $wo->order_no];
+                throw new Exception("该订单状态无法操作");
+            }
+            $wo->operation_time = date('Y-m-d H:i:s');
+            $wo->status = 1;
+            $wo->save();
+            DB::commit();
+        } catch (Exception $e) {
+            DB::rollBack();
+            return $this->error($e->getMessage(), $errors);
+        }
+        return $this->success();
+    }
+
+    /**
+     *  提现收款地址修改
+     */
+    function updateAddress()
+    {
+        $errors = [];
+        DB::beginTransaction();
+        try {
+            $params = (new WalletValidate())->post()->goCheck('updateAddress');
+            $admin = Admin::where('id', $this->admin_id)->find();
+            if (!password_verify($params['safe_word'], $admin->payment_password)) throw new Exception('资金密码错误');
+            $wo = Withdraw::find($params['id']);
+            if ($wo->status != 0) {
+                $errors = ['id' => $wo->order_no];
+                throw new Exception("该订单状态无法操作");
+            }
+            if ($wo->currency == 'bank') {
+                $wo->bank_card_no = $params['address'];
+            } else {
+                $wo->channel_address = $params['address'];
+            }
+            $wo->save();
+
+            DB::commit();
+        } catch (Exception $e) {
+            DB::rollBack();
+            return $this->error($e->getMessage(), $errors);
+        }
+        return $this->success();
+    }
+
+    /**
+     *  订单类型
+     */
+    public function rechargeAddress()
+    {
+        $list = DepositAddress::select(['currency', 'network_type', 'deposit_address', 'withdraw_fee','is_withdraw'])->get()->toArray();
+        $list[] = [
+            'currency' => '银行卡',
+            'network_type' => 'BANK',
+            'deposit_address' => '',
+            'withdraw_fee' => '0.00',
+            'is_withdraw'   => 0,
+        ];
+        return $this->success($list);
+    }
+
+    /**
+     * @api {get} /wallet/withdraws 提现订单
+     * @apiGroup 财务
+     * @apiVersion 1.0.0
+     * @apiUse header
+     * @apiUse lang
+     *
+     * @apiParam {int} [page=1]
+     * @apiParam {int} [limit=15]
+     *
+     * @apiParam {String} [order_no] 订单号(完整)
+     * @apiParam {String} [username] 用户名、user_id
+     * @apiParam {String} [method] 订单类型
+     * - 通过 <a href="javascript:;" onclick="toMenu('财务','GetWalletRechargeaddress')">订单类型</a> 获取
+     * @apiParam {String} [create_start] 创建开始日期
+     * - 格式:yyyy-mm-dd
+     * @apiParam {String} [create_end] 创建结束日期
+     * - 格式:yyyy-mm-dd
+     * @apiParam {String} [operation_start] 审核开始日期
+     * - 格式:yyyy-mm-dd
+     * @apiParam {String} [operation_end] 审核结束日期
+     * - 格式:yyyy-mm-dd
+     */
+    public function withdraws()
+    {
+        try {
+            $params = $this->request->param();
+            $page = isset($params['page']) ? intval($params['page']) : 1;
+            $limit = isset($params['limit']) ? intval($params['limit']) : 15;
+
+            $query = Withdraw::alias('withdraw')->join('user', 'withdraw.user_id=user.user_id','left');
+           
+            if (isset($params['start_time'])) {
+                $start_time = strtotime($params['start_time'].' 00:00:00');
+                $query = $query->where('withdraw.create_time', '>=', $start_time);
+            }
+            if (isset($params['end_time'])) {
+                $end_time = strtotime($params['end_time'].' 23:59:59');
+                $query = $query->where('withdraw.create_time', '<=', $end_time);
+            }
+            if (isset($params['operation_start'])) {
+                $operation_start = strtotime($params['operation_start'].' 00:00:00');
+                $query->where('withdraw.operation_time', '>=', $operation_start);
+            }
+            if (isset($params['operation_end'])) {
+                $operation_end = strtotime($params['operation_end'].' 23:59:59');
+                $query->where('withdraw.operation_time', '<=', $operation_end);
+            }
+            if (isset($params['status']) && $params['status'] !== null) {
+                $query->where('withdraw.status', $params['status']);
+            }
+            if (!empty($params['order_no'])) {
+                $query->where('withdraw.order_no', $params['order_no']);
+            }
+            if (!empty($params['realname'])) {
+                $query = $query->where(function ($query) use ($params) {
+                    $query->where('user.realname', 'like', "%{$params['realname']}%")
+                        ->orWhere('user.user_id', 'like', "%{$params['realname']}%");
+                });
+            }
+            if (!empty($params['method'])) {
+                if ($params['method'] == '银行卡') $params['method'] = 'bank';
+                $query->where('withdraw.currency', $params['method']);
+            }
+            $count = $query->count();
+            $list = $query->field(['withdraw.*','user.realname', 'user.user_id', 'user.remark','user.phone','user.email'])
+                ->order('withdraw.create_time','desc')
+                ->limit($limit)
+                ->page($page)
+                ->select();
+
+        } catch (Exception $e) {
+            return $this->error($e->getMessage());
+        }
+        return $this->success(['count' => $count, 'list' => $list]);
+    }
+
+    /**
+     *  更改用户余额
+     */
+    public function changeMoney()
+    {
+        DB::startTrans();
+        try {
+            $params = $this->request->param();
+            $admin = request()->user;
+            if (!password_verify($params['payment_password'], $admin->payment_password)) {
+                throw new Exception('资金密码错误');
+            }
+
+            $amount = $params['amount'];
+            $user = User::where('user_id', $params['user_id'])->find();
+            switch ($params['type']) {
+                case "withdraw":
+                    if ($user->money < $amount) {
+                        throw new Exception("余额不足");
+                    }
+                    $balance_after = bcsub($user->money, $amount, 2);
+                    FundsRecord::addData([
+                        'transaction_type' => 'withdraw',
+                        'amount_change' => $amount * -1,
+                        'balance_before' => $user->money,
+                        'balance_after' => $balance_after,
+                        'user_id' => $user->user_id
+                    ]);
+
+                    Withdraw::addData([
+                        'user_id' => $user->user_id,
+                        'currency' => 'USDT',
+                        'network_type' => 'TRC20',
+                        'channel_address' => '',
+                        'amount' => $amount,
+                        'status' => 1,
+                        'remarks' => '',
+                        'actual_received' => $amount,
+                        'operation_time' => time(),
+                        'handling_fee' => 0,
+                        'deduction_usd' => $amount,
+                    ]);
+                    $user->money = $balance_after;
+                    $user->save();
+                    break;
+                case 'recharge':
+                    $balance_after = bcadd($user->money, $amount, 2);
+                    FundsRecord::addData([
+                        'transaction_type' => 'recharge',
+                        'amount_change' => $amount,
+                        'balance_before' => $user->money,
+                        'balance_after' => $balance_after,
+                        'user_id' => $user->user_id
+                    ]);
+                    Recharge::addData([
+                        'currency' => 'USDT',
+                        'network_type' => 'TRC20',
+                        'user_id' => $user->user_id,
+                        'recharge_amount' => $amount,
+                        'actual_received' => $amount,
+                        'payment_receipt' => '',
+                        'status' => 1,
+                        'operation_time' => time(),
+                    ]);
+
+                    $user->money = $balance_after;
+                    $user->save();
+                    break;
+            }
+            DB::commit();
+        } catch (Exception $e) {
+            DB::rollBack();
+            return $this->error($e->getMessage());
+        }
+        return $this->success();
+
+    }
+
+    /**
+     *  用户资金记录
+     */
+    public function fundsRecords()
+    {
+        try {
+            $params = $this->request->param();
+            $data = FundsRecord::getList($params, '');
+        } catch (Exception $e) {
+            return $this->error($e->getMessage());
+        }
+        return $this->success($data);
+    }
+
+}

+ 14 - 0
app/admin/model/DepositAddress.php

@@ -0,0 +1,14 @@
+<?php
+
+namespace app\admin\model;
+
+use app\BaseModel;
+
+class DepositAddress extends BaseModel
+{
+    
+    protected $autoWriteTimestamp = true;
+    protected $createTime = 'create_time';
+    protected $updateTime = 'update_time';
+
+}

+ 82 - 0
app/admin/model/FundsRecord.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace app\admin\model;
+
+use app\BaseModel;
+use think\helper\Str;
+use think\facade\Lang;
+
+class FundsRecord extends BaseModel
+{
+    
+    protected $autoWriteTimestamp = true;
+    protected $createTime = 'create_time';
+    protected $updateTime = 'update_time';
+
+    /**
+     * transaction_type 订单类型
+     * - recharge       充值
+     * - withdraw       提现
+     * - order          投注
+     */
+    public $transaction_type_list = [
+        'recharge'      => '充值',
+        'withdraw'      => '提现',
+        'order'         => '投注',
+        'frozen_money'  => '资金冻结',
+        'return_order'  => '退款',
+    ];
+    
+    public static function addData($data)
+    {
+        $data['transaction_id'] = Str::random(32);
+        return static::create($data);
+    }
+
+    public static function getList($params, $user_code = '') {
+        $query = FundsRecord::alias('funds_record')
+            ->join('user', 'funds_record.user_id=user.user_id','left');
+        if ($user_code != '') {
+            $query = $query->where('user.user_code', $user_code);
+        } 
+        if (!empty($params['user_id'])) {
+            $query->where('funds_record.user_id', $params['user_id']);
+        }
+        if (!empty($params['transaction_type'])) {
+            $query->where('funds_record.transaction_type', $params['transaction_type']);
+        }
+        if (!empty($params['transaction_id'])) {
+            $query->where('funds_record.transaction_id', $params['transaction_id']);     
+        }
+        if (!empty($params['start_time']) ) {
+            $start_time = strtotime($params['start_time'] . " 00:00:00");
+            $query->where('funds_record.create_time', '>=', $start_time);
+        }
+        if (!empty($params['end_time'])) {
+            $end_time = strtotime($params['end_time'] . " 23:59:59");   
+            $query->where('funds_record.create_time', '<=', $end_time);
+        }
+        $params['page'] = $params['page'] ?? 1;
+        $params['limit'] = $params['limit'] ?? 15;
+        $count = $query->count();
+        $list = $query->field(['funds_record.*'])
+                    ->limit($params['limit'])
+                    ->page($params['page'])
+                    ->order('funds_record.id', 'desc')
+                    ->select();
+        return [
+            'transaction_type' => (new FundsRecord)->getTransactionTypeList(),
+            'count' => $count,
+            'list' => $list,
+        ];
+    }
+
+    public function getTransactionTypeList()
+    {
+        $list = $this->transaction_type_list;
+        foreach ($list as $key => &$value) {
+            $value = Lang::get("messages.{$value}");
+        }
+        return $list;
+    }
+}

+ 13 - 0
app/admin/model/Order.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace app\admin\model;
+
+use app\BaseModel;
+
+class Order extends BaseModel
+{
+    protected $table = 'sport_order';
+    protected $autoWriteTimestamp = true;
+    protected $createTime = 'create_time';
+    protected $updateTime = 'update_time';
+}

+ 15 - 0
app/admin/model/Recharge.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace app\admin\model;
+
+use app\BaseModel;
+
+
+class Recharge extends BaseModel
+{
+    
+    protected $autoWriteTimestamp = true;
+    protected $createTime = 'create_time';
+    protected $updateTime = 'update_time';
+
+}

+ 4 - 2
app/admin/model/User.php

@@ -9,9 +9,11 @@ use app\enterprise\model\{Message,Friend};
 
 class User extends BaseModel
 {
-   use SoftDelete;
+    use softDelete;
+    protected $deleteTime = 'delete_time';
+    protected $defaultSoftDelete = null;
 
-   protected $pk = "user_id";
+   protected $pk = "id";
    
    public static $defaultField = 'user_id,realname,realname as displayName,account,avatar,name_py,email,last_login_ip';
 

+ 15 - 0
app/admin/model/Withdraw.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace app\admin\model;
+
+use app\BaseModel;
+
+
+class Withdraw extends BaseModel
+{
+    
+    protected $autoWriteTimestamp = true;
+    protected $createTime = 'create_time';
+    protected $updateTime = 'update_time';
+
+}

+ 75 - 0
app/admin/validate/WalletValidate.php

@@ -0,0 +1,75 @@
+<?php
+
+
+namespace app\admin\validate;
+
+
+class WalletValidate extends BaseValidate
+{
+
+     /**
+      * 设置校验规则
+      * @var string[]
+      */
+    protected $rule = [
+        'id' => 'require',
+        'safe_word' => 'require',
+        'operation_remark' => 'require|length:0,200',
+        'address' => 'require|length:0,128',
+        'user_id' => 'require',
+        'amount' => 'require|float|min:0.01',
+        'type' => 'require|in:recharge,withdraw',
+        'payment_password' => 'require',
+    ];
+
+    /**
+     * 参数描述
+     * @var string[]
+     */
+    protected $field = [
+        'id' => 'id',
+        'safe_word' => '资金密码',
+        'operation_remark' => '驳回原因',
+        'address' => '提现地址',
+        'user_id' => '用户ID',
+        'amount' => '金额',
+        'type' => '操作类型',
+        'payment_password' => '资金密码',
+    ];
+
+    /**
+     * @notes 充值审核通过
+     */
+    public function sceneRechargePass()
+    {
+        return $this->only(['safe_word', 'id']);
+    }
+
+    public function sceneRechargeRefuse()
+    {
+        return $this->only(['id', 'operation_remark']);
+    }
+
+    /**
+     * @notes 提现审核通过
+     */
+    public function sceneWithdrawPass()
+    {
+        return $this->only(['safe_word', 'id']);
+    } 
+
+    public function sceneWithdrawRefuse()
+    {
+        return $this->only(['id', 'operation_remark']);
+    }
+    
+    public function sceneUpdateAddress()
+    {
+        return $this->only(['id', 'safe_word', 'address']);
+    }
+    public function sceneChangeMoney()
+    {
+        return $this->only(['user_id', 'amount', 'type','payment_password']);
+    }
+
+}

+ 28 - 0
app/common.php

@@ -6,6 +6,34 @@ use \utils\Str;
 use think\facade\Queue;
 use Google\Cloud\Translate\V2\TranslateClient;
 
+function getBlockChainFee($symbol)
+    {
+        try {
+            $symbol = strtoupper($symbol);
+            switch ($symbol) {
+                case "USDT":
+                case "USD":
+                case "USDC":
+                    return 1;
+                    break;
+                default:
+                    $url = "https://api.binance.com/api/v3/ticker/price?symbol={$symbol}USDT";
+                    $response = file_get_contents($url);
+                    if ($response !== FALSE) {
+                        $data = json_decode($response, true);
+                        if (isset($data['price'])) {
+                            return $data['price'];
+                        }
+                        return 1;
+                    }
+                    return 1;
+                    break;
+            }
+        } catch (Exception $e) {
+            return 1;
+        }
+    }
+
 /**
  * 框架内部默认ajax返回
  * @param string $msg      提示信息

+ 10 - 0
app/lang/zh.php

@@ -266,4 +266,14 @@ return [
     '用户已接线' => '用户已接线',
     '菜单不存在' => '菜单不存在',
     '你已被禁止加入该群' => '你已被禁止加入该群',
+    '资金密码错误' => '资金密码错误',
+    '该订单状态无法操作' => '该订单状态无法操作',
+    '驳回原因不能为空' => '驳回原因不能为空',
+    '驳回原因' => '驳回原因',
+    '提现地址' => '提现地址',
+    '充值' => '充值',
+    '提现' => '提现',
+    '投注' => '投注',
+    '资金冻结' => '资金冻结',
+    '退款' => '退款',
 ];

File diff suppressed because it is too large
+ 494 - 91
composer.lock


+ 23 - 0
nginx.htaccess

@@ -0,0 +1,23 @@
+location ~* (runtime|application)/{
+    return 403;
+}
+location / {
+    if (!-e $request_filename){
+        rewrite  ^(.*)$  /index.php?s=$1  last;   break;
+    }
+}
+
+  location ^~ /storage/ {        
+	alias /D:/phpstudy_pro/WWW/sport_admin_api/public/storage/;
+        expires 30d;
+    }
+
+
+location /wss
+{
+    proxy_pass http://127.0.0.1:8282;
+    proxy_http_version 1.1;
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection "Upgrade";
+    proxy_set_header X-Real-IP $remote_addr;
+}

+ 5 - 5
public/index.php

@@ -13,11 +13,11 @@
 namespace think;
 
 require __DIR__ . '/../vendor/autoload.php';
-header('Access-Control-Allow-Origin:*');
-// 响应类型
-header('Access-Control-Allow-Methods:*');
-// 响应头设置
-header('Access-Control-Allow-Headers:x-requested-with,X_Requested_With,content-type,Authorization,clientId,sessionId,cid,X-Im-AppId,X-Im-Sign,X-Im-TimeStamp,accept-language');
+// header('Access-Control-Allow-Origin:*');
+// // 响应类型
+// header('Access-Control-Allow-Methods:*');
+// // 响应头设置
+// header('Access-Control-Allow-Headers:x-requested-with,X_Requested_With,content-type,Authorization,clientId,sessionId,cid,X-Im-AppId,X-Im-Sign,X-Im-TimeStamp,accept-language');
 // 定义配置文件目录和应用目录同级
 define('CONF_PATH', __DIR__.'/../config/');
 define('PUBLIC_PATH', __DIR__.'/');

Some files were not shown because too many files changed in this diff