醉梦人间三千年 5 months ago
parent
commit
8bbe668d44

+ 5 - 0
.env

@@ -64,3 +64,8 @@ AWS_BUCKET=
 AWS_USE_PATH_STYLE_ENDPOINT=false
 
 VITE_APP_NAME="${APP_NAME}"
+
+WECHAT_PAY_APPID=your_app_id
+WECHAT_PAY_MCH_ID=your_mch_id
+WECHAT_API_KEY=your_api_key
+WECHAT_PAYMENT_NOTIFY_URL=http://yourdomain.com/api/wechat/notify

+ 6 - 0
app/Http/Controllers/Frontend/Client/Member/AddressController.php

@@ -86,4 +86,10 @@ class AddressController extends Controller
         return self::success($this->service->getDefault());
     }
 
+    public function setDefault(int $id): JsonResponse
+    {
+        $this->service->setDefault($id);
+        return self::success(true);
+    }
+
 }

+ 5 - 0
app/Http/Controllers/Frontend/Client/Member/UserController.php

@@ -69,4 +69,9 @@ class UserController extends Controller
         return response($result->getString())->header('Content-Type', 'image/png');
     }
 
+    public function balance(): JsonResponse
+    {
+        $result = $this->service->getBalancePage();
+        return self::success($result);
+    }
 }

+ 27 - 3
app/Http/Controllers/Frontend/Client/Service/OrderController.php

@@ -20,6 +20,7 @@ use Endroid\QrCode\Builder\Builder;
 use Endroid\QrCode\Writer\PngWriter;
 use Illuminate\Foundation\Application;
 use Illuminate\Http\JsonResponse;
+
 //use SimpleSoftwareIO\QrCode\Facades\QrCode;
 
 class OrderController extends Controller
@@ -54,6 +55,9 @@ class OrderController extends Controller
         return self::success($this->orderService->getOrder($id));
     }
 
+    /**
+     * @throws ApiException
+     */
     public function update(Request $request, int $id): JsonResponse
     {
         $params = $request->all();
@@ -97,13 +101,17 @@ class OrderController extends Controller
     public function end(Request $request): JsonResponse
     {
         $params = $request->all();
-        $this->orderService->updateOrder( [...$params,'status' => 6]);
+        $this->orderService->updateOrder([...$params, 'status' => 6]);
         return self::success(true);
     }
 
-    public function close()
+    /**
+     * @throws ApiException
+     */
+    public function cancel(int $id): JsonResponse
     {
-
+        $this->orderService->cancelOrder($id);
+        return self::success(true);
     }
 
     public function qrCode(Request $request)
@@ -113,6 +121,22 @@ class OrderController extends Controller
         return response($result->getString())->header('Content-Type', 'image/png');
     }
 
+    public function grabList(int $id)
+    {
+        $result = $this->orderService->getGrabList($id);
+        return self::success($result);
+    }
+
+    /**
+     * @throws ApiException
+     */
+    public function setGrab(Request $request, int $id): JsonResponse
+    {
+        $coach_id = $request->integer('coachId', 0);
+        $this->orderService->setGrab($id, $coach_id);
+        return self::success(true);
+    }
+
 }
 
 

+ 1 - 1
app/Http/Requests/Frontend/Client/Member/AddressRequest.php

@@ -22,7 +22,6 @@ class AddressRequest extends Request
     public function rules(): array
     {
         $rules = [
-
             'userName' => ['bail', 'string'],
             'mobile' => ['bail', 'required', 'string'],
             'address' => ['bail', 'required', 'string'],
@@ -32,6 +31,7 @@ class AddressRequest extends Request
             'cityCode' => ['bail', 'required', 'string'],
             'status' => ['bail', 'required', 'integer', Rule::in([0, 1])],
             'sex' => ['bail', 'required', 'integer', Rule::in([0, 1])],
+            'adcode' => ['bail', 'string'],
         ];
 
         $actionName = last(explode('@', Route::current()->getActionName()));

+ 8 - 6
app/Http/Requests/Frontend/Client/Service/OrderRequest.php

@@ -23,23 +23,25 @@ class OrderRequest extends Request
     {
         $rules = [
             'coachId' => ['bail', 'integer'],
-            'projectId' => ['bail', 'required', 'integer'],
+            'projectId' => ['bail', 'integer'],
             'couponId' => ['bail', 'integer'],
             'orderId' => ['bail', 'integer'],
-            'payType' => ['bail', 'required', 'integer'],
+            'payType' => ['bail', 'integer'],
             'useBalance' => ['bail', 'integer'],
+            'remark' => ['bail', 'string'],
+            'addressId' => ['bail', 'integer'],
+            'carType' => ['bail', 'integer']
         ];
 
         $actionName = last(explode('@', Route::current()->getActionName()));
-        if($actionName === 'store'){
-            $rules['addressId'] = ['bail', 'required', 'integer'];
-            $rules['carType'] =  ['bail', 'required', 'integer'];
+        if ($actionName === 'store') {
+
         }
 
         if ($actionName === 'index') {
 
         }
-        if($actionName === 'show'){
+        if ($actionName === 'show') {
 
         }
         if ($actionName === 'apply') {

+ 1 - 0
app/Http/Services/Backend/Server/System/AuthService.php

@@ -35,6 +35,7 @@ class AuthService extends Service
 //        $verifyCodeResult = (new SmsService())->verifyCode($mobile, intval($code));
 //        if(!$verifyCodeResult) return $this->fail('验证码错误!', 400);
 
+
         // 使用账号密码,进行登录
         $user = $this->authenticate($request);
 

+ 3 - 0
app/Http/Services/Frontend/Client/Coach/UserService.php

@@ -99,6 +99,9 @@ class UserService extends Service
         if ($isExists) self::error('用户已经申请');
 
         $params['user_id'] = $user_id;
+        $member = \App\Models\Member\User::query()->find($user_id);
+        $params['nickname'] = $member['nickname'];
+        $params['avatar'] = $member['avatar'];
         // 判断邀请人$input['partner_id']
         $user = self::toModel($params, User::class);
         return User::query()->create($user->getAttributes())->id;

+ 10 - 1
app/Http/Services/Frontend/Client/Member/AddressService.php

@@ -19,7 +19,7 @@ use Illuminate\Support\Facades\DB;
 
 class AddressService extends Service
 {
-    protected array $select_column = ['id', 'user_name', 'mobile', 'address', 'lat', 'lng', 'status'];
+    protected array $select_column = ['id', 'user_name', 'mobile', 'address', 'address_info', 'city_code', 'adcode', 'lat', 'lng', 'status'];
 
     public function getAddressList()
     {
@@ -98,4 +98,13 @@ class AddressService extends Service
         $where = ['user_id' => $user_id, 'status' => 1];
         return Address::query()->where($where)->select($this->select_column)->first();
     }
+
+    public function setDefault(int $id): void
+    {
+        $user_id = Auth::id();
+        // 更改所有地址状态为0
+        Address::query()->where('user_id', $user_id)->update(['status' => 0]);
+        $address = self::toModel(['id' => $id,'status' => 1], Address::class);
+        $address->save();
+    }
 }

+ 10 - 1
app/Http/Services/Frontend/Client/Member/UserService.php

@@ -12,6 +12,7 @@ use App\Http\Requests\Request;
 use App\Http\Services\Frontend\Client\Common\AuthService;
 use App\Http\Services\Service;
 use App\Models\Member\Address;
+use App\Models\Member\Benefit;
 use App\Models\Member\User;
 use Endroid\QrCode\Builder\Builder;
 use Endroid\QrCode\Writer\PngWriter;
@@ -20,7 +21,7 @@ use Illuminate\Support\Facades\DB;
 
 class UserService extends Service
 {
-    protected array $select_column = ['id', 'mobile', 'nickname', 'avatar', 'name', 'sex', 'birthday', 'mark', 'point'];
+    protected array $select_column = ['id', 'mobile', 'nickname', 'avatar', 'name', 'sex', 'birthday', 'mark', 'point','balance'];
 
     public function getUser()
     {
@@ -60,4 +61,12 @@ class UserService extends Service
             ->build();
         return $result;
     }
+
+    public function getBalancePage(): array
+    {
+        $id = Auth::id();
+        $benefitColumn = ['id','type','remark','benefit','balance','created_at'];
+        $benefitPage = Benefit::query()->where('user_id',$id)->select($benefitColumn)->paginate(10);
+        return ['list' => $benefitPage->items(), 'total' => $benefitPage->total()];
+    }
 }

+ 254 - 55
app/Http/Services/Frontend/Client/Service/OrderService.php

@@ -15,16 +15,20 @@ use App\Models\Coach\User;
 use App\Models\Member\Address;
 use App\Models\Member\Benefit;
 use App\Models\Service\Order;
+use App\Models\Service\OrderGrab;
 use App\Models\Service\Project;
 use Endroid\QrCode\Builder\Builder;
 use Endroid\QrCode\Writer\PngWriter;
+use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Str;
 
 class OrderService extends Service
 {
-    protected array $baseColumn = ['id', 'project_name', 'project_icon', 'time_long', 'pay_type', 'pay_price', 'real_address', 'status', 'created_at'];
+    protected array $baseColumn = ['id', 'order_sn', 'user_name', 'mobile', 'coach_id', 'project_name', 'project_icon', 'service_price', 'time_long', 'pay_type', 'pay_price', 'address', 'real_address', 'status', 'created_at'];
+    protected array $infoColumn = ['distance', 'remark', 'car_price', 'material_price', 'coupon_price', 'discount_price', 'balance_price', 'pay_time', 'start_time'];
 
     function buildOrderSN(): string
     {
@@ -38,6 +42,8 @@ class OrderService extends Service
     public function createOrder(array $params)
     {
         $data = ['user_id' => Auth::id()];
+        // 备注
+        $data['remark'] = $params['remark'] ?? '';
         // 用户地址
         $address = Address::query()->where('user_id', $data['user_id'])->find($params['addressId']);
         !$address && self::error('地址信息错误');
@@ -45,13 +51,18 @@ class OrderService extends Service
         $data['real_address'] = $address['addressInfo'];
         $data['address_lat'] = $address['lat'];
         $data['address_lng'] = $address['lng'];
+        $data['mobile'] = $address['mobile'];
+        $data['adcode'] = $address['adcode'];
+        $data['user_name'] = $address['user_name'];
         $data['area_id'] = 0;
 
         // 获取项目信息
         $project = Project::query()->find($params['projectId']);
         $data['project_name'] = $project->title;
+        $data['project_sub_title'] = $project->sub_title;
         $data['project_icon'] = $project->cover;
 
+
         // 优惠卷
 //        if ($params['couponId']) $data['coupon_id'] = $params['couponId'];
 //        $coupon_record_model = new CouponRecord();
@@ -101,100 +112,156 @@ class OrderService extends Service
         try {
             $memberQuery = \App\Models\Member\User::query();
             $member = $memberQuery->lockForUpdate()->find($data['user_id']);
-            $orderPayInfo = $orderModel->buildPayInfo($data['user_id'], $params['projectId'], $address['city_code'], $address['lat'], $address['lng'], $use_balance, $coach_id, $car_type, $coupon_id, $order_id);
+            $orderPayInfo = $orderModel->buildPayInfo($data['user_id'], $params['projectId'], $use_balance, $coach_id, $car_type, $coupon_id, $order_id);
 
             //默认微信
             $payType = $params['pay_type'] ?? 1;
-            $use_balance && !$orderPayInfo['pay_price'] && ($payType = 0);
+
+            $use_balance && !round($orderPayInfo['pay_price'], 2) && ($payType = 0);
 
             // 订单状态
-            $orderStatus = $use_balance && !$orderPayInfo['pay_price'] ? 1 : 0;
-
-            $orderData = [
-                'order_sn' => $this->buildOrderSN(),
-                'pay_type' => $payType,
-                'status' => $orderStatus,
-                ...$data,
-                ...$orderPayInfo,
-                //备注
+            $orderStatus = 0;
+            if ($use_balance && !round($orderPayInfo['pay_price'], 2)) {
+                $orderStatus = 1;
+                $orderPayInfo['pay_time'] = time();
+            }
+
+
+            $orderData = array_merge($data, $orderPayInfo,
+                [
+                    'order_sn' => $this->buildOrderSN(),
+                    'pay_type' => $payType,
+                    'status' => $orderStatus
+                ]);
+
+            //备注
 //            'text' => $params['text'] ?: '',
 //            'car_type' => $car_type,
 //            'channel_id' => $params['channel_id'] ?: 0,
 
-                //目的地地址
-                //加钟
+            //目的地地址
+            //加钟
 //            'add_pid' => $order_id,
 //            'is_add' => $order_id ? 1 : 0,
-            ];
+
+            $orderData['coupon_price'] = $orderData['coupon_price'] * 100;
+            $orderData['discount_price'] = $orderData['discount_price'] * 100;
+            $orderData['material_price'] = $orderData['material_price'] * 100;
+            $orderData['car_price'] = $orderData['car_price'] * 100;
+            $orderData['pay_price'] = $orderData['pay_price'] * 100;
+            $orderData['balance_price'] = $orderData['balance_price'] * 100;
+            // 服务价格
+            $orderData['service_price'] = $orderData['service_price'] * 100;
+
+
             // 创建订单
             $orderId = $orderModel->newQuery()->create($orderData)->id;
 
             // 变更用户余额
-            if ($use_balance && $orderPayInfo['balance_price']) {
+            if ($use_balance && round($orderPayInfo['balance_price'], 2) > 0) {
+
                 Benefit::query()->create([
                     'user_id' => $data['user_id'],
                     'order_id' => $orderId,
                     'type' => 1,
-                    'benefit' => $orderPayInfo['balance_price'] * -1,
-                    'balance' => $member['balance']
+                    'benefit' => round($orderPayInfo['balance_price'], 2) * -100,
+                    'balance' => round($member['balance'], 2) * 100
                 ]);
-                $member->decrement('balance', $orderPayInfo['balance_price']);
+                $member->decrement('balance', round($orderPayInfo['balance_price'], 2) * 100);
             }
 
             DB::commit();
             return $orderId;
         } catch (\Exception $e) {
             DB::rollBack();
-            self::error();
+            self::error($e->getMessage());
         }
     }
 
-    public function getOrderPage(array $data)
+    public function getOrderPage(array $data): array
     {
         $user_id = Auth::id();
         $status = intval($data['status'] ?? 0);
         $where = ['user_id' => $user_id, 'user_del' => 0];
         $statusRange = match ($status) {
-            1 => [0, 1, 2, 3],
-            2 => [4, 5],
-            3 => [5],
-            4 => [6, 7],
-            default => [0, 1, 2, 3, 4, 5, 6, 7]
+//            1 => [0, 1, 2, 3],
+//            2 => [4, 5],
+//            3 => [5],
+//            4 => [6, 7],
+//            default => [0, 1, 2, 3, 4, 5, 6, 7]
+//            0:未支付 1:已支付(待接单) 2:已接单 3:已出发 4:已到达 5:开始服务(服务中) 6:服务结束 7:已撤离 8:已评价 9:取消订单(退款中) 10:已退款
+            // 对应景工UI
+            1 => [0],
+            2 => [1, 2, 3, 4, 5],
+            3 => [6, 7, 8],
+            4 => [7],
+            5 => [9, 10],
+            default => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
         };
-//        $select = ['id', 'project_name', 'project_icon', 'duration', 'paid_type', 'price', 'real_address', 'status', 'created_at', 'refunded_at'];
-        $select = ['id', 'project_name', 'project_icon', 'time_long', 'pay_type', 'pay_price', 'real_address', 'status', 'created_at'];
-        $orderPage = Order::query()->where($where)->whereIn('status', $statusRange)->select($select)->latest()->paginate();
+        $orderPage = Order::query()->with('coach', function ($query) {
+            $query->select('id', 'nickname', 'avatar');
+        })->where($where)->whereIn('status', $statusRange)->select($this->baseColumn)->latest()->paginate(10);
         return ['list' => $orderPage->items(), 'total' => $orderPage->total()];
     }
 
     public function getOrder(int $order_id)
     {
         $user_id = Auth::id();
-        return Order::query()->where('user_id', $user_id)->select($this->baseColumn)->find($order_id);
+        return Order::query()->with('coach', function ($query) {
+            $query->select(['id', 'nickname', 'avatar']);
+        })->with('grab.coach', function ($query) {
+            $query->select(['id', 'nickname', 'avatar']);
+        })->where('user_id', $user_id)->select([...$this->baseColumn, ...$this->infoColumn])->find($order_id);
     }
 
     /**
      * @throws ApiException
      */
-    public function updateOrder(array $data): void
+    public function updateOrder(array $data,int $id): void
     {
-        $order_id = $data['id'];
+        $user_id = Auth::id();
+        $order_id = $id;
         $order = Order::query()->find($order_id);
-        $status = $data['status'];
-        switch ($status) {
-            // 结束订单
-            case 6:
-                $order->status !== 5 && self::error('订单状态有误');
-                // 查询是否存在加钟订单
-                // 判断加钟服务是否完成
-                $order->user_end = 1;
-                $order->end_time = time();
-                break;
-            case 9:
-                !in_array($order->status, [0, 1, 2, 3]) && self::error('订单状态有误');
-                break;
+        if ($order->status === 0) {
+
+            // 用户地址
+            if (isset($data['addressId'])) {
+                $address = Address::query()->where('user_id', $user_id)->find($data['addressId']);
+                !$address && self::error('地址信息错误!');
+                $order['address'] = $address['address'];
+                $order['real_address'] = $address['addressInfo'];
+                $order['address_lat'] = $address['lat'];
+                $order['address_lng'] = $address['lng'];
+                $order['mobile'] = $address['mobile'];
+                $order['adcode'] = $address['adcode'];
+                $order['user_name'] = $address['user_name'];
+            }
+            $orderModel = new Order();
+            $orderPayInfo = $orderModel->buildPayInfo($user_id, $order['project_id'], $data['useBalance'] ?? 0, $data['coachId'], $data['carType'] ?? 0, $data['couponId'] ?? 0);
+            $order->service_price = $orderPayInfo['service_price'] * 100;
+            $order->coupon_price = $orderPayInfo['coupon_price'] * 100;
+            $order->discount_price = $orderPayInfo['discount_price'] * 100;
+            $order->material_price = $orderPayInfo['material_price'] * 100;
+            $order->car_price = $orderPayInfo['car_price'] * 100;
+            $order->pay_price = $orderPayInfo['pay_price'] * 100;
+            $order->balance_price = $orderPayInfo['balance_price'] * 100;
+        } else {
+            $status = $data['status'];
+            switch ($status) {
+                // 结束订单
+                case 6:
+                    $order->status !== 5 && self::error('订单状态有误');
+                    // 查询是否存在加钟订单
+                    // 判断加钟服务是否完成
+                    $order->user_end = 1;
+                    $order->end_time = time();
+                    break;
+                case 9:
+                    !in_array($order->status, [0, 1, 2, 3]) && self::error('订单状态有误');
+                    break;
+            }
+            $order->status = $status;
         }
-        $order->status = $status;
         $order->save();
     }
 
@@ -205,7 +272,13 @@ class OrderService extends Service
         $order->save();
     }
 
-    public function confirmOrder(array $params)
+    /**
+     * Notes :
+     * Method : 确认下单
+     * @param array $params
+     * @return array
+     */
+    public function confirmOrder(array $params): array
     {
         $user_id = Auth::id();
         $projectId = $params['projectId'];
@@ -215,45 +288,141 @@ class OrderService extends Service
         $project = Project::query()->select($projectSelect)->find($projectId);
 
         // 查询用户余额
-        $balance = \App\Models\Member\User::query()->where('id', $user_id)->pluck('balance');
+        $balance = \App\Models\Member\User::query()->where('id', $user_id)->value('balance');
         // 车费
         // 判断技师是否收取车费
 //        $coach = User::query()->find($coachId);
         // 获取技师定位
-        $coachSite = null;
+        $coachUser = null;
         if ($coachId) {
-            $coachSelect = ['latitude', 'longitude'];
-            $coachSite = Site::query()->select($coachSelect)->where('coach_id', $coachId)->first();
+            $coachSelect = ['id', 'nickname', 'avatar'];
+            $coachSiteSelect = ['latitude', 'longitude'];
+            $coachUser = User::query()->where('id', $coachId)->select($coachSelect)->first();
+            $coachUser['site'] = Site::query()->select($coachSiteSelect)->where('coach_id', $coachId)->first();
         }
 
         return [
             'balance' => $balance,
             'project' => $project,
-            'coach' => $coachSite
+            'coach' => $coachUser
         ];
     }
 
     /**
-     * @throws ApiException
+     * Notes :
+     * Method : 计算金额
+     * @param array $params
+     * @return array
      */
     public function computePrice(array $params): array
     {
         $user_id = Auth::id();
+        // 存在订单
+        $order_id = $params['orderId'] ?? 0;
+
         $use_balance = $params['useBalance'] ?? 0;
         $coach_id = $params['coachId'] ?? 0;
         $distance = $params['distance'] ?? 0;
         $car_type = $params['carType'] ?? 0;
         $coupon_id = $params['couponId'] ?? 0;
+        $project_id = $params['projectId'] ?? 0;
 
 //        $member = $memberQuery->find($user_id);
 
         $orderModel = new Order();
-        $orderPayInfo = $orderModel->buildPayInfo($user_id, $params['projectId'], $use_balance, $coach_id, $car_type, $coupon_id, $distance);
-
+        $orderPayInfo = $orderModel->buildPayInfo($user_id, $project_id, $use_balance, $coach_id, $car_type, $coupon_id, $order_id, $distance);
 
         return $orderPayInfo;
     }
 
+    /**
+     * Notes :
+     * Method : 取消订单
+     * @throws ApiException
+     */
+    public function cancelOrder(int $order_id)
+    {
+        $userId = Auth::id();
+        $order = Order::query()->find($order_id);
+        !$order && self::error('无效订单!');
+        $member = \App\Models\Member\User::query()->lockForUpdate()->find($userId);
+        $balance_price = $order['balance_price'] * 100;
+        $pay_price = $order['pay_price'] * 100;
+        $car_price = $order['car_price'] * 100;
+//        $discount_price = $order['discount_price'] * 100;
+//        $coupon_price = $order['coupon_price'] * 100;
+//        $material_price = $order['material_price'] * 100;
+        $service_price = $order['service_price'] * 100;
+
+        // 退款金额
+//        $benefit = $balance_price + $pay_price + $car_price;
+        DB::beginTransaction();
+        try {
+            $benefitData = [
+                'user_id' => $userId,
+                'order_id' => $order_id,
+                'type' => 2,
+                'remark' => '取消订单退款',
+                'benefit' => 0,
+                'balance' => $member['balance'] * 100
+            ];
+            // 订单状态 0:未支付 1:已支付(待接单) 2:已接单 3:已出发 4:已到达 5:开始服务(服务中) 6:服务结束 7:已撤离 8:已评价 9:取消订单(退款中) 10:已退款
+            switch ($order->status) {
+                case 1: // 已支付
+                    $benefit = $balance_price + $pay_price;
+                    $benefitData['benefit'] = $benefit;
+                    Benefit::query()->create($benefitData);
+                    $member->increment('balance', $benefit);
+                    break;
+                case 2: // 已接单
+                    $benefit = $balance_price + $pay_price;
+                    $benefitData['benefit'] = $benefit;
+                    Benefit::query()->create($benefitData);
+                    $member->increment('balance', $benefit);
+
+                    // 扣除20%服务费
+                    $deduct_benefit = $service_price * 0.2;
+                    $benefitData['type'] = 3;
+                    $benefitData['remark'] = '技师已接单,取消订单扣除20%服务费';
+                    $benefitData['benefit'] = $deduct_benefit;
+                    Benefit::query()->create($benefitData);
+                    $member->decrement('balance', $deduct_benefit);
+                    break;
+                case 3: // 已出发
+                    $benefit = $balance_price + $pay_price;
+                    $benefitData['benefit'] = $benefit;
+                    Benefit::query()->create($benefitData);
+                    $member->increment('balance', $benefit);
+
+                    // 扣除50%服务费
+                    $deduct_benefit = $service_price * 0.5;
+                    $benefitData['type'] = 3;
+                    $benefitData['remark'] = '技师已出发,取消订单扣除50%服务费';
+                    $benefitData['benefit'] = $deduct_benefit;
+                    Benefit::query()->create($benefitData);
+                    $member->decrement('balance', $deduct_benefit);
+
+                    // 扣除车费
+                    if ($car_price) {
+                        $benefitData['type'] = 3;
+                        $benefitData['remark'] = '技师已出发,扣除交通费用';
+                        $benefitData['benefit'] = $car_price;
+                        Benefit::query()->create($benefitData);
+                        $member->decrement('balance', $car_price);
+                    }
+                    break;
+                default:
+                    self::error('订单状态错误!');
+            }
+            $order->status = 10;
+            $order->save();
+            DB::commit();
+        } catch (\Exception $e) {
+            DB::rollBack();
+            self::error($e->getMessage());
+        }
+    }
+
     public function qrCode(array $params)
     {
         $result = Builder::create()
@@ -264,4 +433,34 @@ class OrderService extends Service
             ->build();
         return $result;
     }
+
+    public function getGrabList(int $id): array
+    {
+        $orderGrabPage = OrderGrab::query()->with('coach', function ($query) {
+            $query->select('id', 'nickname', 'avatar');
+        })->where('order_id', $id)->select(['id', 'coach_id', 'status', 'created_at'])->paginate(10);
+        return ['list' => $orderGrabPage->items(), 'total' => $orderGrabPage->total()];
+    }
+
+    /**
+     * @throws ApiException
+     */
+    public function setGrab(int $id, int $coach_id): void
+    {
+        DB::beginTransaction();
+        try {
+            OrderGrab::query()->where('order_id', $id)->update(['status' => 0]);
+            $grabCoach = OrderGrab::query()->where('order_id', $id)->where('coach_id', $coach_id)->first();
+            $grabCoach->status = 1;
+            $grabCoach->save();
+//            $order = Order::query()->lockForUpdate()->find($id);
+//            $order['coach_id'] && self::error('已选择技师');
+//            $order['coach_id'] = $coach_id;
+//            $order->save();
+            DB::commit();
+        } catch (\Exception $e) {
+            DB::rollBack();
+            self::error($e->getMessage());
+        }
+    }
 }

+ 42 - 0
app/Http/Services/Frontend/Client/Wechat/PaymentService.php

@@ -0,0 +1,42 @@
+<?php
+/**
+ * @Name
+ * @Description
+ * @Author 刘学玺
+ * @Date 2024/10/17 14:43
+ */
+
+namespace App\Http\Services\Frontend\Client\Wechat;
+
+use App\Http\Services\Service;
+use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
+use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
+use EasyWeChat\Kernel\Exceptions\RuntimeException;
+use EasyWeChat\Pay\Message;
+use Exception;
+use Overtrue\LaravelWeChat\EasyWeChat;
+
+class PaymentService extends Service
+{
+    /**
+     * @throws InvalidArgumentException
+     * @throws InvalidConfigException
+     */
+    public function pay()
+    {
+//        $app = EasyWeChat::pay();
+//
+//        $server = $app->getServer();
+////        $server->prepend()
+//        $server->handlePaid(function (Message $message, \Closure $next) use ($app) {
+//            try {
+//                $app->getValidator()->validate($app->getRequest());
+//                // 验证通过,业务处理
+//            } catch (Exception $e) {
+//                // 验证失败
+//            }
+//            return $next($message);
+//        });
+//        return $server->serve();
+    }
+}

+ 1 - 1
app/Models/Coach/User.php

@@ -53,7 +53,7 @@ class User extends Model
 
     public function info($attribute, $file = ['*']): array
     {
-        gettype($attribute) === "string" && ($attribute = ['id' => $attribute]);
+        (gettype($attribute) === "string" || gettype($attribute) === "integer") && ($attribute = ['id' => $attribute]);
         if (gettype($attribute) === "NULL") return [];
         $data = $this::query()->where($attribute)->first($file);
         return !empty($data) ? $data->toArray() : [];

+ 9 - 0
app/Models/Member/Benefit.php

@@ -43,4 +43,13 @@ class Benefit extends Authenticatable
         return [];
     }
 
+    public function getBalanceAttribute($value): string
+    {
+        return number_format($value / 100, 2, '.', '');
+    }
+
+    public function getBenefitAttribute($value): string
+    {
+        return number_format($value / 100, 2, '.', '');
+    }
 }

+ 1 - 1
app/Models/Member/User.php

@@ -48,7 +48,7 @@ class User extends Authenticatable
 
     public function getBalanceAttribute($value)
     {
-        return number_format($value / 100, 2);
+        return number_format($value / 100, 2, '.', '');
     }
 
     public function coach(): \Illuminate\Database\Eloquent\Relations\HasOne

+ 77 - 15
app/Models/Service/Order.php

@@ -3,6 +3,7 @@
 namespace App\Models\Service;
 
 use App\Models\Coach\User;
+use DateTimeInterface;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Facades\DB;
@@ -18,11 +19,26 @@ class Order extends Model
     protected $appends = [];
 
     protected $casts = [
+        'created_at' => 'datetime',
+        'pay_time' => 'datetime',
+        'start_time' => 'datetime',
         'end_time' => 'datetime'
     ];
 
+    protected function serializeDate(DateTimeInterface $date): string
+    {
+        return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
+    }
+
     public function buildPayInfo($user_id, $project_id, $use_balance = 0, $coach_id = null, $car_type = 0, $coupon_id = 0, $order_id = 0, $distance = 0): array
     {
+        if ($order_id) {
+            $order = Order::query()->find($order_id);
+
+            $project_id = $order['project_id'];
+
+            $use_balance = +$order['balance_price'] > 0 ? 1 : 0;
+        }
 
         $data['project_id'] = $project_id;
 
@@ -30,6 +46,9 @@ class Order extends Model
         // 获取代理项目
         $project = Project::query()->find($data['project_id']);
 
+        // 项目价格
+        $data['service_price'] = number_format($project['price'], 2, '.', '');
+
 //        $coupon_model= new Coupon();
 
         $coach_model = new User();
@@ -39,16 +58,16 @@ class Order extends Model
         // 优惠卷
         $data['coupon_id'] = $coupon_id ?: 0;
         // 优惠金额
-        $data['coupon_price'] = number_format(0, 2);
+        $data['coupon_price'] = number_format(0, 2, '.', '');
 
         // 折扣金额
-        $data['discount_price'] = number_format(0, 2);
+        $data['discount_price'] = number_format(0, 2, '.', '');
 
         // 物料费
-        $data['material_price'] = $project['material_price'] ?? number_format(0, 2);
-
+        $data['material_price'] = number_format(0, 2, '.', '');
+//            $project['material_price']
         // 车费默认值
-        $data['car_price'] = number_format(0, 2);
+        $data['car_price'] = number_format(0, 2, '.', '');
 
         // 选择技师
         if ($coach) {
@@ -66,7 +85,6 @@ class Order extends Model
 //            }
 
 
-
         }
 
         // 距离
@@ -79,12 +97,12 @@ class Order extends Model
             $freeDistance = 3; // 免费公里
             $distanceLen = $distance / 1000;
             $distancePrice = $distanceLen <= $freeDistance ? 0 : ($distanceLen > $baseDistance ? ($distanceLen - $baseDistance) * $carPrice + $baseCarPrice : $baseCarPrice);
-            $data['car_price'] = number_format(round($distancePrice / 100), 2);
+            $data['car_price'] = number_format(+$distancePrice / 100, 2, '.', '');
         }
 
         // 订单支付价
         // 订单总价格
-        $pay_total_price = round($project['price'], 2) + round($data['car_price'], 2) + round($data['material_price'], 2);
+        $pay_total_price = round(+$project['price'], 2) + round(+$data['car_price'], 2) + round(+$data['material_price'], 2);
 
         // 订单总优惠
         $coupon_total_price = intval($data['coupon_price']) + intval($data['discount_price']);
@@ -92,23 +110,22 @@ class Order extends Model
         // 支付金额
         $pay_price = $pay_total_price - $coupon_total_price;
         $pay_price <= 0 && ($pay_price = 0);
-        $data['pay_price'] = number_format($pay_price, 2);
+        $data['pay_price'] = number_format($pay_price, 2, '.', '');
 
         // 余额支付
-        $data['balance_price'] = 0;
+        $data['balance_price'] = number_format(0, 2, '.', '');
         if ($use_balance) {
             // 用户余额
             $memberQuery = \App\Models\Member\User::query();
             $user = $memberQuery->find($user_id);
-
             // 余额抵扣金额
-            $balance_price = round($user['balance'], 2) - round($pay_price, 2);
+            $balance_price = round(+$user['balance'], 2) - round($pay_price, 2);
             if ($balance_price >= 0) {
-                $data['balance_price'] = number_format($pay_price, 2);
-                $data['pay_price'] = number_format(0, 2);
+                $data['balance_price'] = number_format($pay_price, 2, '.', '');
+                $data['pay_price'] = number_format(0, 2, '.', '');
             } else {
                 $data['balance_price'] = $user['balance'];
-                $data['pay_price'] = number_format(abs($balance_price), 2);
+                $data['pay_price'] = number_format(abs($balance_price), 2, '.', '');
             }
         }
 
@@ -120,4 +137,49 @@ class Order extends Model
 
         return $data;
     }
+
+    public function coach(): \Illuminate\Database\Eloquent\Relations\HasOne
+    {
+        return $this->hasOne(User::class, 'id', 'coach_id');
+    }
+
+    public function grab()
+    {
+        return $this->hasOne(OrderGrab::class, 'order_id')->where('status', 1);
+    }
+
+    public function getServicePriceAttribute($value): string
+    {
+        return number_format($value / 100, 2, '.', '');
+    }
+
+    public function getPayPriceAttribute($value): string
+    {
+        return number_format($value / 100, 2, '.', '');
+    }
+
+    public function getMaterialPriceAttribute($value): string
+    {
+        return number_format($value / 100, 2, '.', '');
+    }
+
+    public function getCouponPriceAttribute($value): string
+    {
+        return number_format($value / 100, 2, '.', '');
+    }
+
+    public function getDiscountPriceAttribute($value): string
+    {
+        return number_format($value / 100, 2, '.', '');
+    }
+
+    public function getBalancePriceAttribute($value): string
+    {
+        return number_format($value / 100, 2, '.', '');
+    }
+
+    public function getCarPriceAttribute($value): string
+    {
+        return number_format($value / 100, 2, '.', '');
+    }
 }

+ 33 - 0
app/Models/Service/OrderGrab.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace App\Models\Service;
+
+use App\Models\Coach\User;
+use DateTimeInterface;
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class OrderGrab extends Model
+{
+    use HasFactory;
+
+    protected $table = 'service_order_grab';
+
+    protected $guarded = [];
+
+    protected $appends = [];
+
+    protected $casts = [
+        'created_at' => 'datetime',
+    ];
+
+    protected function serializeDate(DateTimeInterface $date): string
+    {
+        return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
+    }
+
+    public function coach(): \Illuminate\Database\Eloquent\Relations\HasOne
+    {
+        return $this->hasOne(User::class, 'id','coach_id');
+    }
+}

+ 3 - 3
app/Models/Service/Project.php

@@ -24,17 +24,17 @@ class Project extends Model
 
     public function getPriceAttribute($value)
     {
-        return number_format($value / 100, 2);
+        return number_format($value / 100, 2,'.','');
     }
 
     public function getInitPriceAttribute($value)
     {
-        return number_format($value / 100, 2);
+        return number_format($value / 100, 2,'.','');
     }
 
     public function getMaterialPriceAttribute($value)
     {
-        return number_format($value / 100, 2);
+        return number_format($value / 100, 2,'.','');
 
     }
 

+ 9 - 9
config/easywechat.php

@@ -92,13 +92,13 @@ return [
     /*
      * 微信支付
      */
-    // 'pay' => [
-    //     'default' => [
-    //         'app_id'             => env('WECHAT_PAY_APPID', ''),
-    //         'mch_id'             => env('WECHAT_PAY_MCH_ID', 'your-mch-id'),
-    //         'private_key'        => '/data/private/certs/apiclient_key.pem',
-    //         'certificate'        => '/data/private/certs/apiclient_cert.pem',
-    //         'notify_url'         => 'http://example.com/payments/wechat-notify',                           // 默认支付结果通知地址
+     'pay' => [
+         'default' => [
+             'app_id'             => env('WECHAT_PAY_APPID', ''),
+             'mch_id'             => env('WECHAT_PAY_MCH_ID', ''),
+             'private_key'        => '/data/private/certs/apiclient_key.pem',
+             'certificate'        => '/data/private/certs/apiclient_cert.pem',
+             'notify_url'         => env('WECHAT_PAYMENT_NOTIFY_URL',''),                           // 默认支付结果通知地址
     //          /**
     //           * 证书序列号,可通过命令从证书获取:
     //           * `openssl x509 -in application_cert.pem -noout -serial`
@@ -119,8 +119,8 @@ return [
     //          'platform_certs' => [
     //              '/data/private/certs/platform_key.pem',
     //          ],
-    //     ],
-    // ],
+         ],
+     ],
 
     /*
      * 企业微信

+ 5 - 1
database/migrations/2024_09_23_025555_create_service_order_table.php

@@ -18,9 +18,14 @@ return new class extends Migration {
             $table->string('transaction_id')->nullable()->comment('商户订单号');
             $table->bigInteger('project_id')->comment('项目ID');
             $table->bigInteger('area_id')->comment('区域ID');
+            $table->string('adcode')->nullable()->comment('区域ID');
+            $table->string('mobile')->nullable()->comment('联系电话');
+            $table->string('user_name')->nullable()->comment('用户名称');
 //            $table->string('city_code');
 
             $table->string('project_name')->comment('项目名称');
+            $table->string('project_sub_title')->comment('项目子标题');
+
             $table->string('project_icon')->nullable()->comment('项目图标');
 
             $table->integer('pay_price')->default('0')->nullable()->comment('支付金额');
@@ -82,7 +87,6 @@ return new class extends Migration {
             $table->bigInteger('channel_id')->nullable()->comment('渠道ID');
             $table->bigInteger('channel_cate_id')->nullable()->comment('渠道ID');
 
-
             $table->tinyInteger('extend_order')->default(0)->comment('加钟订单');
             $table->tinyInteger('extend_order_id')->default(0)->comment('加钟订单ID');
             $table->bigInteger('store_id')->nullable()->comment('店铺ID');

+ 1 - 0
database/migrations/2024_10_01_025556_create_member_address_table.php

@@ -22,6 +22,7 @@ return new class extends Migration {
             $table->string('address')->nullable()->comment('地址');
             $table->string('address_info')->nullable()->comment('地址详情');
             $table->string('city_code')->nullable();
+            $table->string('adcode')->nullable();
             $table->string('lng')->nullable()->comment('经度');
             $table->string('lat')->nullable()->comment('纬度');
             $table->tinyInteger('status')->default(0)->comment('状态 1:使用 ');

+ 1 - 1
database/migrations/2024_10_01_025556_create_member_benefit_table.php

@@ -15,7 +15,7 @@ return new class extends Migration {
             $table->bigInteger('user_id')->comment('用户ID');
             $table->bigInteger('order_id')->nullable()->comment('订单ID');
             $table->bigInteger('withdraw_id')->nullable()->comment('提现ID');
-            $table->tinyInteger('type')->nullable()->comment('订单类型 1-支付 2-退款 3-扣除 4-提现 5-返还 6-收益 8-赠送');
+            $table->tinyInteger('type')->nullable()->comment('订单类型 1-支付 2-退款 3-扣除 4-提现 5-返还 6-收益 8-赠送 9-交通费');
             $table->text('remark')->nullable()->comment('备注');
             $table->integer('benefit')->default(0)->comment('收益');
             $table->integer('balance')->default(0)->comment('余额');

+ 29 - 0
database/migrations/2024_10_01_025557_create_service_order_grab_table.php

@@ -0,0 +1,29 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration {
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('service_order_grab', function (Blueprint $table) {
+            $table->id();
+            $table->bigInteger('order_id')->comment('订单ID');
+            $table->bigInteger('coach_id')->comment('技师ID');
+            $table->tinyInteger('status')->default(0)->comment('状态 默认0  1选中');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('member_benefit');
+    }
+};

+ 9 - 0
routes/api.php

@@ -55,8 +55,13 @@ Route::prefix('client')->group(function () {
 
         Route::middleware(['auth:sanctum'])->group(function () {
             # 订单
+
+            # 工单 - 查询
+            Route::get('order/grab/{id}', [ClientServiceOrderController::class, 'grabList']);
+            Route::put('order/grab/{id}', [ClientServiceOrderController::class, 'setGrab']);
             Route::get('order/confirm', [ClientServiceOrderController::class, 'confirm']);
             Route::get('order/compute', [ClientServiceOrderController::class, 'compute']);
+            Route::put('order/cancel/{id}',[ClientServiceOrderController::class, 'cancel']);
             Route::get('order/qrCode',[ClientServiceOrderController::class, 'qrCode']);
             Route::resource('order', ClientServiceOrderController::class);
 
@@ -73,9 +78,13 @@ Route::prefix('client')->group(function () {
     });
 
     Route::prefix('member')->middleware(['auth:sanctum'])->group(function () {
+        # 余额明细
+        Route::get('balance', [ClientMemberUserController::class, 'balance']);
         # 邀请码
         Route::get('qrcode', [ClientMemberUserController::class, 'qrcode']);
         Route::get('address/default', [ClientMemberAddressController::class, 'default']);
+        Route::put('address/default/{id}', [ClientMemberAddressController::class, 'setDefault']);
+
         Route::resource('address', ClientMemberAddressController::class);
         Route::post('upload', [ClientMemberToolController::class, "upload"]);
         Route::get('/', [ClientMemberUserController::class, 'show']);