浏览代码

wesmiler 更新订单完成逻辑

wesmiler 1 年之前
父节点
当前提交
5b329de7ab

+ 18 - 0
app/Helpers/common.php

@@ -2162,4 +2162,22 @@ if(!function_exists('getDistance')) {
                         ), 2))) * 1000);
 
     }
+}
+
+if(!function_exists('getParents')){
+    /**
+     * 获取分销上级用户ID
+     * @param $parents
+     * @return array|false
+     */
+    function getParents($parents, $level=3){
+        $parents = $parents? explode(',', $parents) : [];
+        $parents = array_filter($parents);
+        if(empty($parents)){
+            return false;
+        }
+
+        $parents = array_slice($parents, -$level);
+        return array_reverse($parents);
+    }
 }

+ 9 - 8
app/Http/Controllers/Api/v1/MemberBankController.php

@@ -33,10 +33,11 @@ class MemberBankController extends webApp
         $cacheKey = "caches:members:banksNames";
         $datas = RedisService::get($cacheKey);
         if(empty($datas)){
-            $datas = config('payments.banks');
+            $datas = config('payment.banks');
             if($datas){
                 foreach($datas as &$item){
-                    $item['icon'] = get_image_url('/images/icons/banks/icon-'.$item['id'].'.png');
+                    $item['code'] = 'bank-'.$item['id'];
+                    $item['icon'] = get_image_url('/images/icons/banks/icon-'.$item['code'].'.png');
                 }
                 unset($item);
 
@@ -57,11 +58,11 @@ class MemberBankController extends webApp
             return message($params, false);
         }
 
-        if(MemberBankService::make()->saveData($this->userId)){
+        if(MemberBankService::make()->saveData($this->userId, $params)){
             RedisService::clear("caches:members:banks:{$this->userId}");
-            return message(1002, true);
+            return message(MemberBankService::make()->getError(), true);
         }else{
-            return message(1003, false);
+            return message(MemberBankService::make()->getError(), false);
         }
     }
 
@@ -81,13 +82,13 @@ class MemberBankController extends webApp
      * 删除
      * @return array
      */
-    public function del()
+    public function delete()
     {
         if(MemberBankService::make()->delete()){
             RedisService::clear("caches:members:banks:{$this->userId}");
-            return message(1016, true);
+            return message(MemberBankService::make()->getError(), true);
         }else{
-            return message(1017, false);
+            return message(MemberBankService::make()->getError(), false);
         }
     }
 }

+ 62 - 0
app/Http/Controllers/Api/v1/MemberController.php

@@ -82,6 +82,68 @@ class MemberController extends webApp
     }
 
     /**
+     * 设置微信收款码
+     * @return array
+     */
+    public function setWxpay(Request $request)
+    {
+        // 上传单图统一调取方法
+        $result = upload_image($request, 'file','payment');
+        if (!$result['success']) {
+            return message($result['msg'],false,['url'=>'']);
+        }
+
+        // 文件路径
+        $file_path = $result['data']['img_path'];
+        if (!$file_path) {
+            return message('上传失败',false,['url'=>'']);
+        }
+
+        // 网络域名拼接
+        if ($file_path && strpos($file_path, IMG_URL) === false) {
+            $file_path = get_image_url($file_path);
+        }
+
+        $qrcode = $result['data']['img_path'];
+        if(MemberService::make()->saveQrcode($this->userId, ['wxpay'=> $qrcode])){
+            return message(1013,true,['url'=> $file_path,'path'=> $qrcode]);
+        }else{
+            return message(1014,false,['url'=>'']);
+        }
+    }
+
+    /**
+     * 设置支付宝收款码
+     * @return array
+     */
+    public function setAlipay(Request $request)
+    {
+        // 上传单图统一调取方法
+        $result = upload_image($request, 'file','payment');
+        if (!$result['success']) {
+            return message($result['msg'],false,['url'=>'']);
+        }
+
+        // 文件路径
+        $file_path = $result['data']['img_path'];
+        if (!$file_path) {
+            return message('上传失败',false,['url'=>'']);
+        }
+
+        // 网络域名拼接
+        if ($file_path && strpos($file_path, IMG_URL) === false) {
+            $file_path = get_image_url($file_path);
+        }
+
+        $qrcode = $result['data']['img_path'];
+        if(MemberService::make()->saveQrcode($this->userId, ['alipay'=> $qrcode])){
+            return message(1013,true,['url'=> $file_path,'path'=> $qrcode]);
+        }else{
+            return message(1014,false,['url'=>'']);
+        }
+    }
+
+    /**
      * 修改账号信息
      * @param MemberValidator $validator
      * @return array

+ 108 - 0
app/Http/Controllers/Api/v1/OrderController.php

@@ -77,4 +77,112 @@ class OrderController extends webApp
         }
     }
 
+    /**
+     * 申请退款
+     * @return array
+     */
+    public function refund()
+    {
+        $params = request()->all();
+        if(!$result = OrderService::make()->refund($this->userId, $params)){
+            return message(OrderService::make()->getError(), false);
+        }else{
+            return message(OrderService::make()->getError(), true, $result);
+        }
+    }
+
+    /**
+     * 申请退款取消
+     * @return array
+     */
+    public function refundCancel()
+    {
+        $params = request()->all();
+        if(!$result = OrderService::make()->refundCancel($this->userId, $params)){
+            return message(OrderService::make()->getError(), false);
+        }else{
+            return message(OrderService::make()->getError(), true, $result);
+        }
+    }
+
+    /**
+     * 申请退款审核
+     * @return array
+     */
+    public function refundConfirm()
+    {
+        $params = request()->all();
+        if(!$result = OrderService::make()->refundConfirm($this->userId, $params)){
+            return message(OrderService::make()->getError(), false);
+        }else{
+            return message(OrderService::make()->getError(), true, $result);
+        }
+    }
+
+
+    /**
+     * 接单
+     * @return array
+     */
+    public function picker()
+    {
+        if(!$result = OrderService::make()->picker()){
+            return message(OrderService::make()->getError(), false);
+        }else{
+            return message(OrderService::make()->getError(), true, $result);
+        }
+    }
+
+    /**
+     * 发货
+     * @return array
+     */
+    public function delivery()
+    {
+        if(!$result = OrderService::make()->delivery()){
+            return message(OrderService::make()->getError(), false);
+        }else{
+            return message(OrderService::make()->getError(), true, $result);
+        }
+    }
+
+    /**
+     * 服务中/上钟
+     * @return array
+     */
+    public function inService()
+    {
+        if(!$result = OrderService::make()->inService()){
+            return message(OrderService::make()->getError(), false);
+        }else{
+            return message(OrderService::make()->getError(), true, $result);
+        }
+    }
+
+    /**
+     * 订单完成/收货
+     * @return array
+     */
+    public function complete()
+    {
+        $params = request()->all();
+        if(!$result = OrderService::make()->complete($this->userId,$params)){
+            return message(OrderService::make()->getError(), false);
+        }else{
+            return message(OrderService::make()->getError(), true, $result);
+        }
+    }
+
+    /**
+     * 订单删除
+     * @return array
+     */
+    public function delete()
+    {
+        if(!$result = OrderService::make()->delete()){
+            return message(OrderService::make()->getError(), false);
+        }else{
+            return message(OrderService::make()->getError(), true, $result);
+        }
+    }
 }

+ 16 - 10
app/Http/Controllers/Api/v1/TestController.php

@@ -3,6 +3,8 @@
 namespace App\Http\Controllers\Api\v1;
 
 use App\Http\Controllers\Api\webApp;
+use App\Models\OrderModel;
+use App\Services\Api\FinanceService;
 use App\Services\Api\PaymentService;
 use App\Services\SmsService;
 use App\Services\WechatService;
@@ -19,15 +21,19 @@ class TestController extends webApp
 
     public function check()
     {
-        $order = [
-            'total_fee' => 0.01,
-            'type' => 2,
-            'pay_type' => 20,
-            'out_trade_no' => 'DY202307240224480708287',
-            'transaction_id' => '2023072422001475771410050912',
-            'order_no' => 'DY202307240224480708287'
-        ];
-        $result = PaymentService::make()->refund($order, 20);
-        return message(PaymentService::make()->getError(), true, $result);
+        $order = OrderModel::where(['id'=> 21])
+            ->select(['id','user_id','merch_id','source_id','city','pay_money','type','reception_at','coupon_id','status','is_service','refund_status','pay_time'])
+            ->first();
+//        $order = [
+//            'total_fee' => 0.01,
+//            'type' => 2,
+//            'pay_type' => 20,
+//            'out_trade_no' => 'DY202307240224480708287',
+//            'transaction_id' => '2023072422001475771410050912',
+//            'order_no' => 'DY202307240224480708287'
+//        ];
+//        $result = PaymentService::make()->refund($order, 20);
+        $result = FinanceService::make()->settleOrder($order);
+        return message(FinanceService::make()->getError(), true, $result);
     }
 }

+ 1 - 1
app/Http/Middleware/WebLogin.php

@@ -28,7 +28,7 @@ class WebLogin extends Middleware
         $controller = class_basename($action['controller']);
         list($controller, $action) = explode('@', $controller);
         $noLoginActs = ['LoginController','TestController','NotifyController','IndexController','ArticleController','TaskController'];
-        $noSignActions = ['UploadController','setAvatar','NotifyController','TestController','TaskController'];
+        $noSignActions = ['UploadController','setAvatar','setWxpay','setAlipay','NotifyController','TestController','TaskController'];
         $token = $request->headers->get('Authorization');
         if (strpos($token, 'Bearer ') !== false) {
             $token = str_replace("Bearer ", null, $token);

+ 1 - 1
app/Models/AccountLogModel.php

@@ -58,7 +58,7 @@ class AccountLogModel extends BaseModel
               `merch_id` int(10) NOT NULL DEFAULT '0' COMMENT '来源商家ID',
               `source_uid` int(10) NOT NULL DEFAULT '0' COMMENT '来源关联用户ID',
               `source_order_no` varchar(30) NOT NULL DEFAULT '' COMMENT '来源订单号',
-              `type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '交易类型:1-服务消费,2-商城消费,3-分销佣金/工资,4-平台调整,5-充值,6-转账,7-消费退款,8-聊天付费,9-招聘付费,10-代理佣金,11-用户提现,12-商家提现,99-其他',
+              `type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '交易类型:1-服务消费,2-商城消费,3-分销佣金/工资/商家收入,4-平台调整,5-充值,6-转账,7-消费退款,8-聊天付费,9-招聘付费,10-代理佣金,11-用户提现,12-商家提现,99-其他',
               `coin_type` tinyint(2) NOT NULL DEFAULT '1' COMMENT '币种账户类型:1-人民币,2-佣金,3-积分,4-余额,5-收益,6-其他',
               `money` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '金额',
               `balance` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '更改前余额',

+ 26 - 0
app/Models/BonusLogModel.php

@@ -0,0 +1,26 @@
+<?php
+// +----------------------------------------------------------------------
+// | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
+// +----------------------------------------------------------------------
+// | 版权所有 2017~2021 LARAVEL研发中心
+// +----------------------------------------------------------------------
+// | 官方网站: http://www.laravel.cn
+// +----------------------------------------------------------------------
+// | Author: laravel开发员 <laravel.qq.com>
+// +----------------------------------------------------------------------
+
+namespace App\Models;
+
+/**
+ * 佣金记录管理-模型
+ * @author laravel开发员
+ * @since 2020/11/11
+ * Class BonusLogModel
+ * @package App\Models
+ */
+class BonusLogModel extends BaseModel
+{
+    // 设置数据表
+    protected $table = 'bonus_log';
+
+}

+ 0 - 2
app/Services/Api/AgentService.php

@@ -103,9 +103,7 @@ class AgentService extends BaseService
 
             // 获取主页统计数据
             if($type == 'home'){
-                // 累计佣金
                 $city = isset($info['city'])? $info['city'] : '';
-                $info['bonus_total'] = OrderService::make()->getCountsByCity($city);
 
                 // 累计订单
                 $info['order_total'] = rand(100, 999);

+ 197 - 13
app/Services/Api/FinanceService.php

@@ -11,8 +11,14 @@
 
 namespace App\Services\Api;
 
+use App\Models\AgentModel;
+use App\Models\BonusLogModel;
 use App\Models\FinanceModel;
+use App\Models\MechanicModel;
+use App\Models\MemberModel;
+use App\Models\MerchantModel;
 use App\Services\BaseService;
+use App\Services\ConfigService;
 
 /**
  * 平台财务管理-服务类
@@ -99,24 +105,202 @@ class FinanceService extends BaseService
 
     /**
      * 分佣计算和记录处理
-     * @param $userInfo 用户信息
-     * @param $order 订单信息
-     * @return bool
+     * @param array $order 订单信息
+     * @param int $userId 操作用户ID
+     * @return array|false
      */
-    public function settleOrder($userInfo, $order)
+    public function settleOrder($order, $userId=0)
     {
-        // TODO 计算平台分佣比例总金额
+        $orderUserId = isset($order['user_id']) ? $order['user_id'] : 0;
+        $orderMerchId = isset($order['merch_id']) ? $order['merch_id'] : 0;
+        $orderMechId = isset($order['source_id']) ? $order['source_id'] : 0;
+        $orderType = isset($order['type']) ? $order['type'] : 0;
+        $city = isset($order['city']) ? $order['city'] : '';
+        $payMoney = isset($order['pay_money']) ? $order['pay_money'] : 0;
+        if($orderUserId<=0 || $orderMerchId<=0 || $payMoney<=0){
+            $this->error = 2640;
+            return false;
+        }
+
+        if(!in_array($orderType, [1,2])){
+            $this->error = 2681;
+            return false;
+        }
+
+        $merchInfo = MerchantModel::where(['id'=> $orderMerchId,'mark'=>1])
+            ->select(['id','user_id','settle_type'])
+            ->first();
+        $merchUserId = isset($merchInfo['user_id'])? $merchInfo['user_id'] : 0;
+        $settleType = isset($merchInfo['settle_type'])? $merchInfo['settle_type'] : 0;
+        $settleType = in_array($settleType,[1,2,3])? $settleType : 1;
+        if($settleType == 2){
+            $settleAt = date('Y-m-d', time() + 7*86400);
+        }else if($settleType == 3){
+            $settleAt = date('Y-m-01', time() + 32*86400);
+        }else{
+            $settleAt = date('Y-m-d', time() + 86400);
+        }
+
+
+        $result = [
+            'user_id'=> $orderUserId,
+            'order_no'=> isset($order['order_no'])? $order['order_no'] : '',
+            'merch_id'=> $orderMerchId,
+            'mech_id'=> $orderType==2?$orderMechId:0,
+            'money'=> $payMoney,
+            'type'=> $orderType,
+            'create_time'=> time(),
+            'update_time'=> time(),
+            'status'=> 1,
+            'settle_at'=> $settleAt,
+            'mark'=> 1,
+        ];
+        // TODO 计算平台分佣总金额
+        $rate1 = ConfigService::make()->getConfigByCode('platform_bonus_rate');
+        $rate1 = $rate1>0 && $rate1<100? $rate1 : 10;
+        $bonusMoneyTotal = moneyFormat($payMoney * $rate1/100, 2);
+        $bonusMoney = $bonusMoneyTotal;
+
+        // TODO 计算平台分佣中,用户上级的二级分销佣金
+        $parents = MemberModel::where(['id'=> $orderUserId,'mark'=>1])->value('parents');
+        $parents = getParents($parents, 3);
+        if($parents){
+            $level1Id = isset($parents[0])? $parents[0] : 0;
+            $checkId = MemberModel::where(['id'=> $level1Id,'mark'=>1])->value('id');
+            // 一级佣金分销佣金,所分佣金不能大于平台剩余总佣金
+            if($level1Id && $checkId){
+                $level1Rate = ConfigService::make()->getConfigByCode('bonus_level_1');
+                $level1Rate = $level1Rate>0 && $level1Rate<100? $level1Rate : 0;
+                $level1Money = moneyFormat($bonusMoneyTotal * $level1Rate/100, 2);
+                if($level1Money>0 && $level1Money<=$bonusMoney){
+                    $result['bonus_level1_id'] = $level1Id;
+                    $result['bonus_level1_money'] = $level1Money;
+                    $bonusMoney = moneyFormat($bonusMoney - $level1Money, 2);
+                }
+            }
+
+            // 二级用户分销佣金,所分佣金不能大于平台剩余总佣金
+            $level2Id = isset($parents[1])? $parents[1] : 0;
+            $checkId = MemberModel::where(['id'=> $level2Id,'mark'=>1])->value('id');
+            if($level2Id && $checkId){
+                $level2Rate = ConfigService::make()->getConfigByCode('bonus_level_2');
+                $level2Rate = $level2Rate>0 && $level2Rate<100? $level2Rate : 0;
+                $level2Money = moneyFormat($bonusMoneyTotal * $level2Rate/100, 2);
+                if($level2Money>0 && $level2Money<=$bonusMoney){
+                    $result['bonus_level2_id'] = $level2Id;
+                    $result['bonus_level2_money'] = $level2Money;
+                    $bonusMoney = moneyFormat($bonusMoney - $level2Money, 2);
+                }
+            }
+
+            // 三级用户分销佣金,所分佣金不能大于平台剩余总佣金
+            $level3Id = isset($parents[2])? $parents[2] : 0;
+            $checkId = MemberModel::where(['id'=> $level3Id,'mark'=>1])->value('id');
+            if($level3Id && $checkId){
+                $level3Rate = ConfigService::make()->getConfigByCode('bonus_level_3');
+                $level3Rate = $level3Rate>0 && $level3Rate<100? $level3Rate : 0;
+                $level3Money = moneyFormat($bonusMoneyTotal * $level3Rate/100, 2);
+                if($level3Money>0 && $level3Money <= $bonusMoney){
+                    $result['bonus_level3_id'] = $level3Id;
+                    $result['bonus_level3_money'] = $level3Money;
+                    $bonusMoney = moneyFormat($bonusMoney - $level3Money, 2);
+                }
+            }
+        }
+
+        // TODO 计算平台分佣中,商家上级的二级分销佣金
+        $parents = MemberModel::where(['id'=> $merchUserId,'mark'=>1])->value('parents');
+        $parents = getParents($parents, 3);
+        if($parents){
+            $level1Id = isset($parents[0])? $parents[0] : 0;
+            $checkId = MemberModel::where(['id'=> $level1Id,'mark'=>1])->value('id');
+            // 一级商家分销佣金,所分佣金不能大于平台剩余总佣金
+            if($level1Id && $checkId){
+                $level1Rate = ConfigService::make()->getConfigByCode('bonus_level_1');
+                $level1Rate = $level1Rate>0 && $level1Rate<100? $level1Rate : 0;
+                $level1Money = moneyFormat($bonusMoneyTotal * $level1Rate/100, 2);
+                if($level1Money>0 && $level1Money<=$bonusMoney){
+                    $result['merch_level1_id'] = $level1Id;
+                    $result['merch_level1_money'] = $level1Money;
+                    $bonusMoney = moneyFormat($bonusMoney - $level1Money, 2);
+                }
+            }
 
-        // TODO 计算平台分佣中,用户上级的二级分销佣金,并分佣
+            // 二级商家分销佣金,所分佣金不能大于平台剩余总佣金
+            $level2Id = isset($parents[1])? $parents[1] : 0;
+            $checkId = MemberModel::where(['id'=> $level2Id,'mark'=>1])->value('id');
+            if($level2Id && $checkId){
+                $level2Rate = ConfigService::make()->getConfigByCode('bonus_level_2');
+                $level2Rate = $level2Rate>0 && $level2Rate<100? $level2Rate : 0;
+                $level2Money = moneyFormat($bonusMoneyTotal * $level2Rate/100, 2);
+                if($level2Money>0 && $level2Money<=$bonusMoney){
+                    $result['merch_level2_id'] = $level2Id;
+                    $result['merch_level2_money'] = $level2Money;
+                    $bonusMoney = moneyFormat($bonusMoney - $level2Money, 2);
+                }
+            }
 
-        // TODO 计算平台分佣中,商家上级的二级分销佣金,并分佣
+            // 三级商家分销佣金,所分佣金不能大于平台剩余总佣金
+            $level3Id = isset($parents[2])? $parents[2] : 0;
+            $checkId = MemberModel::where(['id'=> $level3Id,'mark'=>1])->value('id');
+            if($level3Id && $checkId){
+                $level3Rate = ConfigService::make()->getConfigByCode('bonus_level_3');
+                $level3Rate = $level3Rate>0 && $level3Rate<100? $level3Rate : 0;
+                $level3Money = moneyFormat($bonusMoneyTotal * $level3Rate/100, 2);
+                if($level3Money>0 && $level3Money<=$bonusMoney){
+                    $result['merch_level3_id'] = $level3Id;
+                    $result['merch_level3_money'] = $level3Money;
+                    $bonusMoney = moneyFormat($bonusMoney - $level3Money, 2);
+                }
+            }
+        }
 
         // TODO 计算平台分佣中,代理商分佣佣金
+        if($city && $agentInfo = AgentModel::where(['city'=> $city,'status'=>2,'mark'=>1])->select(['id','user_id','bonus_rate','status'])->first()){
+            $agentRate = ConfigService::make()->getConfigByCode('agent_bonus_rate');
+            $agentRate = $agentRate>0 && $agentRate<100? $agentRate : 5;
+            $agentBonusRate = isset($agentInfo['bonus_rate'])? floatval($agentInfo['bonus_rate']) : 0;
+            $agentRate = $agentBonusRate>0 && $agentBonusRate<100? $agentBonusRate : $agentRate;
+            $agentBonusMoney = moneyFormat($bonusMoneyTotal * $agentRate/100, 2);
+            $agentId = isset($agentInfo['id'])? $agentInfo['id'] : 0;
+            if($agentId>0 && $agentBonusMoney>0 && $agentBonusMoney<=$bonusMoney){
+                $result['agent_id'] = $agentId;
+                $result['agent_money'] = $agentBonusMoney;
+                $bonusMoney = moneyFormat($bonusMoney - $agentBonusMoney, 2);
+            }
+        }
 
-        // TODO  企业分佣比例金额,以及技师所得佣金
+        // TODO 企业分佣总金额
+        $merchBonusMoneyTotal = moneyFormat($payMoney - $bonusMoneyTotal, 2); // 除去平台总分佣就是商家总佣金
+        $merchBonusMoney = $merchBonusMoneyTotal;
 
+        // TODO 扣除技师部分佣金
+        if($orderType == 2 && $orderMechId>0){
+            $mechInfo = MechanicModel::where(['id'=> $orderMechId,'status'=>2,'mark'=>1])
+                ->select(['id','user_id','bonus_rate','status'])
+                ->first();
+            $mechanicRate = ConfigService::make()->getConfigByCode('agent_bonus_rate');
+            $mechanicRate = $mechanicRate>0 && $mechanicRate<100? $mechanicRate : 10;
+            $mechanicBonusRate = isset($mechInfo['bonus_rate'])? floatval($mechInfo['bonus_rate']) : 0;
+            $mechanicRate = $mechanicBonusRate>0 && $mechanicBonusRate<100? $mechanicBonusRate : $mechanicRate;
+            $mechanicBonusMoney = moneyFormat($merchBonusMoneyTotal * $mechanicRate/100, 2);
+            $mechId = isset($mechInfo['id'])? $mechInfo['id'] : 0;
+            if($mechInfo && $mechId>0 && $mechanicBonusMoney>0 && $mechanicBonusMoney<=$merchBonusMoney){
+                $result['mech_id'] = $mechId;
+                $result['mech_money'] = $mechanicBonusMoney;
+                $merchBonusMoney = moneyFormat($merchBonusMoney - $mechanicBonusMoney, 2);
+            }
+        }
 
-        return true;
+        // 剩余平台总佣金和商家总佣金
+        $result['platform_money'] = $bonusMoney;
+        $result['merch_money'] = $merchBonusMoney;
+        if(!BonusLogModel::insertGetId($result)){
+            $this->error = 2684;
+            return false;
+        }
+        $this->error = 1002;
+        return $result;
     }
 
 
@@ -124,15 +308,15 @@ class FinanceService extends BaseService
      * 平台结算
      * @param $money
      * @param int $changeType
-     * @param int $type 类型:1-增加,2-扣除
+     * @param int $type 类型:1-消费,2-佣金,3-充值提现,4-退款,99-其他
      * @return mixed
      */
-    public function settleBonus($money, $changeType = 1, $type = 1)
+    public function saveLog($userId, $money, $changeType = 1, $type = 1)
     {
         $date = date('Y-m-d');
-        $info = $this->model->where(['date'=> $date,'mark'=>1])->first();
+        $info = $this->model->where(['user_id'=> $userId,'date'=> $date,'type'=> $type,'mark'=>1])->first();
         if(!$info){
-            $data = ['date'=> $date,'type'=>1,'create_time'=>time(),'update_time'=> time(),'status'=>1];
+            $data = ['user_id'=>$userId,'date'=> $date,'type'=>$type,'create_time'=>time(),'update_time'=> time(),'status'=>1];
             if($changeType==1){
                 $data['income'] = $money;
             }else{

+ 4 - 1
app/Services/Api/MemberBankService.php

@@ -78,7 +78,9 @@ class MemberBankService extends BaseService
         if ($list) {
             foreach ($list['data'] as &$item) {
                 $item['create_time'] = $item['create_time'] ? datetime($item['create_time'], 'Y-m-d H.i.s') : '';
-                $item['bank_card'] = $item['bank_card'] ? format_bank_card($item['bank_card']) : '';
+                $item['bank_card_text'] = $item['bank_card'] ? format_bank_card($item['bank_card']) : '';
+                $item['name_text'] = $item['bank_name'] ? mb_substr($item['bank_name'],0,1,'utf-8') : '';
+                $item['icon'] = $item['bank_code'] ? get_image_url('/images/icons/banks/icon-'.$item['bank_code'].'.png') : '';
             }
         }
 
@@ -126,6 +128,7 @@ class MemberBankService extends BaseService
             'realname'=> isset($params['realname'])? $params['realname'] : '',
             'bank_name'=> isset($params['bank_name'])? $params['bank_name'] : '',
             'bank_card'=> isset($params['bank_card'])? $params['bank_card'] : '',
+            'bank_code'=> isset($params['bank_code'])? $params['bank_code'] : '',
             'status'=> isset($params['status'])? $params['status'] : 1,
             'update_time'=> time(),
             'mark'=> 1,

+ 36 - 1
app/Services/Api/MemberService.php

@@ -63,7 +63,7 @@ class MemberService extends BaseService
      */
     public function getInfo($where, $type='detail', array $field = [])
     {
-        $defaultField = ['id', 'username', 'realname','mobile', 'nickname','code','parent_id', 'openid','balance','score', 'member_level', 'status', 'avatar'];
+        $defaultField = ['id', 'username', 'realname','mobile', 'nickname','code','parent_id', 'openid','balance','score','wxpay_qrcode','alipay_qrcode', 'member_level', 'status', 'avatar'];
         if($type == 'home'){
             $defaultField = ['id', 'username', 'realname','mobile', 'nickname','code','parent_id', 'openid','balance','score', 'member_level', 'status', 'avatar'];
         }
@@ -77,6 +77,9 @@ class MemberService extends BaseService
         $info = $info ? $info->toArray() : [];
         if ($info && !in_array($type,['auth','check'])) {
             $info['avatar'] = $info['avatar'] ? get_image_url($info['avatar']) : '';
+            $info['wxpay_qrcode'] = $info['wxpay_qrcode'] ? get_image_url($info['wxpay_qrcode']) : '';
+            $info['alipay_qrcode'] = $info['alipay_qrcode'] ? get_image_url($info['alipay_qrcode']) : '';
+            $info['avatar'] = $info['avatar'] ? get_image_url($info['avatar']) : '';
             $info['balance'] = round($info['balance'],2);
             $info['mobile_text'] = $info['mobile'];
             $info['mobile'] = $info['mobile']? format_mobile($info['mobile']):'';
@@ -473,6 +476,38 @@ class MemberService extends BaseService
     }
 
     /**
+     * 修改收款码
+     * @param $userId
+     * @param $params
+     * @return mixed
+     */
+    public function saveQrcode($userId, $params)
+    {
+        if(isset($params['wxpay']) && $params['wxpay']){
+            $qrcode = $this->model->where(['id'=> $userId])->value('wxpay_qrcode');
+            if($this->model->where(['id'=> $userId])->update(['wxpay_qrcode'=> $params['wxpay'],'update_time'=> time()])){
+                if($qrcode && file_exists(ATTACHMENT_PATH.$qrcode)){
+                    @unlink(ATTACHMENT_PATH.$qrcode);
+                }
+                return true;
+            }
+        }
+
+        if(isset($params['alipay']) && $params['alipay']){
+            $qrcode = $this->model->where(['id'=> $userId])->value('alipay_qrcode');
+            if($this->model->where(['id'=> $userId])->update(['alipay_qrcode'=> $params['alipay'],'update_time'=> time()])){
+                if($qrcode && file_exists(ATTACHMENT_PATH.$qrcode)){
+                    @unlink(ATTACHMENT_PATH.$qrcode);
+                }
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+
+    /**
      * 修改账号
      * @param $userId
      * @param $params

+ 738 - 44
app/Services/Api/OrderService.php

@@ -11,13 +11,16 @@
 
 namespace App\Services\Api;
 
+use App\Models\AccountLogModel;
 use App\Models\AccountModel;
 use App\Models\GoodsModel;
 use App\Models\MechanicModel;
 use App\Models\MemberCouponModel;
 use App\Models\MemberModel;
+use App\Models\MerchantModel;
 use App\Models\OrderGoodsModel;
 use App\Models\OrderModel;
+use App\Models\PaymentModel;
 use App\Models\ScoreGoodsModel;
 use App\Services\BaseService;
 use App\Services\ConfigService;
@@ -69,7 +72,6 @@ class OrderService extends BaseService
         $where = ['a.mark' => 1];
         $shopId = isset($params['shop_id']) ? $params['shop_id'] : 0;
         $parentId = isset($params['parent_id']) ? $params['parent_id'] : 0;
-        $type = isset($params['type']) ? $params['type'] : 0;
         if ($shopId > 0) {
             $where['a.shop_id'] = $shopId;
         }
@@ -120,7 +122,7 @@ class OrderService extends BaseService
         if ($list) {
             $refundStatusArr = [1=>'退款中',2=>'已退款',3=>'退款失败'];
             $statusArr = [1=>'待付款',2=>'待发货',3=>'待收货',4=>'已完成',5=>'已退款'];
-            $serviceStatusArr = [1=>'待付款',2=>'待接单',3=>'待收货',4=>'已完成',5=>'已退款'];
+            $serviceStatusArr = [1=>'待付款',2=>'待接单',3=>'待服务',4=>'已完成',5=>'已退款'];
             foreach ($list['data'] as &$item) {
                 $item['create_time'] = $item['create_time'] ? datetime($item['create_time'], 'Y-m-d H:i:s') : '';
                 $item['pay_time'] = $item['pay_time'] ? datetime($item['pay_time'], 'Y-m-d H:i:s') : '';
@@ -142,6 +144,7 @@ class OrderService extends BaseService
                 if($refundStatus){
                     $item['refund_status_text'] = isset($refundStatusArr[$refundStatus])? $refundStatusArr[$refundStatus] : '';
                 }
+
                 $goods = isset($item['goods'])? $item['goods'] : [];
                 if($goods){
                     foreach ($goods as &$v){
@@ -165,6 +168,252 @@ class OrderService extends BaseService
     }
 
     /**
+     * 购买店内商品/结算
+     * @param $userId
+     * @param $params
+     * @return array|false
+     */
+    public function buy($userId, $params)
+    {
+        $goodsId = isset($params['goods_id'])? intval($params['goods_id']) : 0;
+        $sourceId = isset($params['source_id'])? intval($params['source_id']) : 0;
+        $payType = isset($params['pay_type'])? intval($params['pay_type']) : 0;
+        $deliveryType = isset($params['delivery_type'])? intval($params['delivery_type']) : 0;
+        $type = isset($params['type'])? intval($params['type']) : 0;
+        $couponId = isset($params['coupon_id'])? intval($params['coupon_id']) : 0;
+        $num = isset($params['num'])? intval($params['num']) : 0;
+        $day = isset($params['day'])? trim($params['day']) : '';
+        $time = isset($params['time_text'])? trim($params['time_text']) : '';
+        $address = isset($params['address'])? trim($params['address']) : '';
+        $province = isset($params['province'])? trim($params['province']) : '';
+        $city = isset($params['city'])? trim($params['city']) : '';
+        $district = isset($params['district'])? trim($params['district']) : '';
+        $realname = isset($params['realname'])? trim($params['realname']) : '';
+        $mobile = isset($params['mobile'])? trim($params['mobile']) : '';
+        if(empty($goodsId) || empty($sourceId) || $num<=0 || $deliveryType<=0 || $payType<=0 || $type != 2){
+            $this->error = 2501;
+            return false;
+        }
+
+        // 验证收货地址
+        if($deliveryType == 2 && (empty($address) || empty($city) || empty($mobile) || empty($realname))){
+            $this->error = 2601;
+            return false;
+        }
+
+        // 服务信息
+        $goodsInfo = GoodsModel::where(['id'=> $goodsId,'mark'=>1,'status'=>2])
+            ->select(['id as goods_id','goods_name','cate_id','merch_id','type','price','unit','sku','attr','weight','discount','service_fee','thumb','status'])
+            ->first();
+        $goodsInfo = $goodsInfo? $goodsInfo->toArray() : [];
+        $merchId = isset($goodsInfo['merch_id'])? intval($goodsInfo['merch_id']) : 0;
+        $price = isset($goodsInfo['price'])? floatval($goodsInfo['price']) : 0;
+        $discount = isset($goodsInfo['discount'])? floatval($goodsInfo['discount']) : 0;
+        $serviceFee = isset($goodsInfo['service_fee'])? floatval($goodsInfo['service_fee']) : 0;
+        if(empty($goodsInfo) || $merchId<=0){
+            $this->error = 2542;
+            return false;
+        }
+
+        // 验证是否存在该技师已支付未接单订单
+        if($this->model->where(['source_id'=>$sourceId,'user_id'=> $userId,'type'=>2,'mark'=>1])->whereIn('status',[2,3])->value('id')){
+            $this->error = 2612;
+            return false;
+        }
+
+        // 验证技师
+        $mechanicInfo = MechanicModel::where(['id'=> $sourceId,'mark'=>1,'status'=>2])
+            ->select(['id','code','nickname','status','services'])
+            ->first();
+        $mechanicInfo = $mechanicInfo? $mechanicInfo->toArray() : [];
+        $services = isset($mechanicInfo['services']) && $mechanicInfo['services']? explode(',', $mechanicInfo['services']) : [];
+        if(empty($mechanicInfo)){
+            $this->error = 2602;
+            return false;
+        }
+
+        // 技师服务项目
+        if(empty($services) || !in_array($goodsId, $services)){
+            $this->error = 2603;
+            return false;
+        }
+
+        // 技师接单状态
+        if($this->model->where(['source_id'=> $sourceId,'type'=>2,'mark'=>1,'status'=>3])->value('id')){
+            $this->error = 2604;
+            return false;
+        }
+
+        $userInfo = MemberModel::where(['id'=> $userId,'mark'=> 1,'status'=> 1])
+            ->select(['id','openid','nickname','city','balance','parent_id','parents'])
+            ->first();
+        $userInfo = $userInfo? $userInfo->toArray() : [];
+        $userCity = isset($userInfo['city'])? $userInfo['city'] : '';
+        $balance = isset($userInfo['balance'])? floatval($userInfo['balance']) : 0.00;
+        if(empty($userInfo)){
+            $this->error ='2017';
+            return false;
+        }
+
+        // 计算价格
+        $payTotal = $total = moneyFormat($num * $price, 2);
+        if($discount>0 && $discount<100){
+            $payTotal = moneyFormat($payTotal * $discount/10, 2);
+        }
+
+        // 优惠券
+        $couponPrice = 0;
+        if($couponId > 0){
+            $payTotal = MemberCouponService::make()->countTotalByCoupon($userId, $couponId, $payTotal, $merchId, $couponPrice);
+        }
+
+        // 余额支付验证
+        if($payType == 30 && $balance< ($payTotal + $serviceFee)){
+            $this->error ='1029';
+            return false;
+        }
+
+        // 收货地址
+        $addressData =[];
+        if($province){
+            $addressData[] = $province;
+        }
+        if($city){
+            $addressData[] = $city;
+        }
+
+        if($district) {
+            $addressData[] = $district;
+        }
+
+        if($address){
+            $addressData[] = $address;
+        }
+
+        // 订单数据
+        $addressText = $addressData? implode(' ', $addressData) : '';
+        $orderNo = get_order_num('DY');
+        $order = [
+            'user_id'=> $userId,
+            'order_no'=> $orderNo,
+            'merch_id'=> $merchId,
+            'type'=> 2,
+            'source_id'=> $sourceId,
+            'price'=> $goodsInfo['price'],
+            'num'=> $num,
+            'city'=> $city? $city : $userCity,
+            'appoint_time'=> $day.' '.$time,
+            'real_name'=> $realname,
+            'mobile'=> $mobile,
+            'address'=> $addressText,
+            'total'=> $total,
+            'pay_type'=> $payType,
+            'pay_money'=> moneyFormat($payTotal+$serviceFee, 2),
+            'delivery_type'=> $deliveryType,
+            'coupon_id'=> $couponId,
+            'coupon_price'=> $couponPrice,
+            'postage'=> $serviceFee,
+            'create_time'=> time(),
+            'update_time'=> time(),
+            'remark'=> isset($params['remark'])? trim($params['remark']) : '',
+            'status'=> 1,
+            'mark'=> 1,
+        ];
+
+        // 订单商品
+        $orderGoods = $goodsInfo;
+        $orderGoods['order_no'] = $orderNo;
+        $orderGoods['total'] = moneyFormat($goodsInfo['price'] * $num, 2);
+        $orderGoods['num'] = $num;
+        $orderGoods['create_time'] = time();
+        $orderGoods['update_time'] = time();
+        $orderGoods['status'] = 1;
+        $orderGoods['mark'] = 1;
+
+        DB::beginTransaction();
+        // 创建订单
+        if(!$orderId = $this->model->insertGetId($order)){
+            DB::rollBack();
+            $this->error = 2605;
+            return false;
+        }
+
+        // 写入订单商品
+        if(!OrderGoodsModel::insertGetId($orderGoods)){
+            DB::rollBack();
+            $this->error = 2606;
+            return false;
+        }
+
+        // 支付处理
+        $payment = [];
+        $payStatus = 2;
+        switch($payType){
+            case 30: // 余额支付
+                if(PaymentService::make()->ballancePay($userInfo, $order)){
+                    $payStatus = 1;
+                }else{
+                    DB::rollBack();
+                    $this->error = PaymentService::make()->getError();
+                    return false;
+                }
+                break;
+            case 20: // 支付宝
+                $payment = PaymentService::make()->aliPay($userInfo, $order);
+                if(empty($payment)){
+                    DB::rollBack();
+                    $this->error = PaymentService::make()->getError();
+                    return false;
+                }
+                break;
+            case 10: // 微信支付
+                $payment = PaymentService::make()->wechatPay($userInfo, $order);
+                if(empty($payment)){
+                    DB::rollBack();
+                    $this->error = PaymentService::make()->getError();
+                    return false;
+                }
+                break;
+            default:
+                $this->error = 1030;
+                return false;
+        }
+
+        // 更新优惠券状态
+        if($couponId && !MemberCouponModel::where(['id'=> $couponId,'mark'=>1])->update(['status'=> 2,'update_time'=>time()])){
+            DB::rollBack();
+            $this->error = 2613;
+            return false;
+        }
+
+        // 已支付
+        DB::commit();
+        if($payStatus == 1){
+            // 更新订单状态
+            $updateData = ['status'=>2,'pay_status'=> 1,'pay_time'=>date('Y-m-d H:i:s'),'update_time'=>time()];
+            if(!$this->model->where(['id'=> $orderId,'mark'=>1])->update($updateData)){
+                $this->error = 2609;
+                return false;
+            }
+
+            $this->error = 2607;
+            return [
+                'id'=> $orderId,
+                'total'=> $payTotal,
+                'pay_type'=> $payType,
+            ];
+        }else{
+            $this->error = 2608;
+            return [
+                'id'=> $orderId,
+                'payment'=> $payment,
+                'total'=> $payTotal,
+                'pay_type'=> $payType,
+            ];
+        }
+    }
+
+    /**
      * 购买服务
      * @param $userId
      * @param $params
@@ -410,7 +659,6 @@ class OrderService extends BaseService
         }
     }
 
-
     /**
      * 详情
      * @param $id
@@ -418,7 +666,8 @@ class OrderService extends BaseService
      */
     public function getInfo($id, $userId=0)
     {
-        $info = $this->model->with(['merchant','goods'])->from('orders as a')
+        $info = $this->model->with(['merchant','goods'])
+            ->from('orders as a')
             ->leftJoin('member as b', 'b.id', '=', 'a.user_id')
             ->where(['a.id' => $id, 'a.mark' => 1])
             ->select(['a.*', 'b.nickname', 'b.mobile as buy_mobile'])
@@ -455,93 +704,538 @@ class OrderService extends BaseService
         return $info;
     }
 
+    /**
+     * 申请退款
+     * @param $userId
+     * @param $params
+     * @return bool
+     */
+    public function refund($userId, $params)
+    {
+        $id = isset($params['id']) ? $params['id'] : 0;
+        $merchId = isset($params['merch_id']) ? $params['merch_id'] : 0;  // 商家
+        $mechId = isset($params['mech_id']) ? $params['mech_id'] : 0;  //技师
+        $refundRemark = isset($params['remark']) ? $params['remark'] : '';
+        $info = $this->model->where(['id' => $id, 'mark' => 1])
+            ->select(['id','user_id','merch_id','source_id','pay_money','coupon_id','status','refund_status','pay_time'])
+            ->first();
+        $status = isset($info['status']) ? $info['status'] : 0;
+        $orderUserId = isset($info['user_id']) ? $info['user_id'] : 0;
+        $orderMerchId = isset($info['merch_id']) ? $info['merch_id'] : 0;
+        $orderMechId = isset($info['source_id']) ? $info['source_id'] : 0;
+        $refundStatus = isset($info['refund_status']) ? $info['refund_status'] : 0;
+        if (!$id || empty($info)) {
+            $this->error = 2656;
+            return false;
+        }
+
+        // 非法操作
+        if($merchId != $orderMerchId && $userId != $orderUserId && $mechId != $orderMechId){
+            $this->error = 2667;
+            return false;
+        }
+
+        if(!in_array($status, [2,3])){
+            $this->error = 2657;
+            return false;
+        }
+
+        if($refundStatus>0){
+            $this->error = 2664;
+            return false;
+        }
+
+        // 处理
+        if(!$this->model->where(['id'=> $id,'mark'=>1])->update(['status'=> 5,'refund_status'=>1,'refund_remark'=> $refundRemark,'update_time'=>time()])){
+            $this->error = 2665;
+            return false;
+        }
+
+        $this->error = 2666;
+        return true;
+    }
 
     /**
-     * 已发货
+     * 申请退款取消
+     * @param $userId
+     * @param $params
      * @return bool
      */
-    public function deliver()
+    public function refundCancel($userId, $params)
+    {
+        $id = isset($params['id']) ? $params['id'] : 0;
+        $merchId = isset($params['merch_id']) ? $params['merch_id'] : 0;  // 商家
+        $mechId = isset($params['mech_id']) ? $params['mech_id'] : 0;  //技师
+        $info = $this->model->where(['id' => $id, 'mark' => 1])
+            ->select(['id','user_id','merch_id','source_id','pay_money','reception_at','coupon_id','status','refund_status','pay_time'])
+            ->first();
+        $status = isset($info['status']) ? $info['status'] : 0;
+        $orderUserId = isset($info['user_id']) ? $info['user_id'] : 0;
+        $orderMerchId = isset($info['merch_id']) ? $info['merch_id'] : 0;
+        $orderMechId = isset($info['source_id']) ? $info['source_id'] : 0;
+        $refundStatus = isset($info['refund_status']) ? $info['refund_status'] : 0;
+        if (!$id || empty($info)) {
+            $this->error = 2656;
+            return false;
+        }
+
+        // 非法操作
+        if($merchId != $orderMerchId && $userId != $orderUserId && $mechId != $orderMechId){
+            $this->error = 2667;
+            return false;
+        }
+
+        if($status != 5){
+            $this->error = 2668;
+            return false;
+        }
+
+        if($refundStatus<=0){
+            $this->error = 2669;
+            return false;
+        }
+
+        // 处理
+        $updateData = ['status'=> $info['reception_at']? 3:2,'refund_status'=>0,'refund_remark'=> '','update_time'=>time()];
+        if(!$this->model->where(['id'=> $id,'mark'=>1])->update($updateData)){
+            $this->error = 2670;
+            return false;
+        }
+
+        $this->error = 2671;
+        return true;
+    }
+
+    /**
+     * 申请退款审核
+     * @param $userId
+     * @param $params
+     * @return bool
+     * @throws \Yansongda\Pay\Exception\ContainerException
+     * @throws \Yansongda\Pay\Exception\InvalidParamsException
+     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
+     */
+    public function refundConfirm($userId, $params)
+    {
+        $id = isset($params['id']) ? $params['id'] : 0;
+        $checkStatus = isset($params['status']) ? $params['status'] : 0;
+        $remark = isset($params['remark']) ? $params['remark'] : '';
+        $merchId = isset($params['merch_id']) ? $params['merch_id'] : 0;  // 商家
+        $info = $this->model->with(['goods'])
+            ->where(['id' => $id, 'mark' => 1])
+            ->select(['id','user_id','merch_id','source_id','type','pay_money','order_no','pay_type','reception_at','coupon_id','status','refund_status','pay_time'])
+            ->first();
+        $status = isset($info['status']) ? $info['status'] : 0;
+        $orderMerchId = isset($info['merch_id']) ? $info['merch_id'] : 0;
+        $orderType = isset($info['type']) ? $info['type'] : 0;
+        $goods = isset($info['goods']) ? $info['goods'] : [];
+        $refundStatus = isset($info['refund_status']) ? $info['refund_status'] : 0;
+        if (!$id || empty($info)) {
+            $this->error = 2656;
+            return false;
+        }
+
+        // 非法操作
+        if($merchId != $orderMerchId){
+            $this->error = 2667;
+            return false;
+        }
+
+        if($status != 5){
+            $this->error = 2668;
+            return false;
+        }
+
+        if($refundStatus<=0){
+            $this->error = 2669;
+            return false;
+        }
+
+        if(!in_array($checkStatus, [2,3])){
+            $this->error = 2639;
+            return false;
+        }
+
+        // 支付信息
+        $orderNo = isset($info['order_no'])? $info['order_no'] : '';
+        $paymentInfo = PaymentModel::where(['order_no'=> $orderNo,'status'=>1,'mark'=>1])->first();
+        $totalFee = isset($paymentInfo['total_fee'])? $paymentInfo['total_fee'] : 0;
+        if(empty($paymentInfo) || $totalFee<=0){
+            $this->error = 2637;
+            return false;
+        }
+        $order = [
+            'total_fee' => $totalFee,
+            'type' => isset($info['type'])? $info['type'] : 2,
+            'pay_type' => isset($info['pay_type'])? $info['pay_type'] : 0,
+            'out_trade_no' => isset($paymentInfo['out_trade_no'])? $paymentInfo['out_trade_no'] : '',
+            'transaction_id' => isset($paymentInfo['transaction_id'])? $paymentInfo['transaction_id'] : '',
+            'order_no' => $orderNo
+        ];
+
+        // 退款打款请求
+        DB::beginTransaction();
+        // 审核成功,打款
+        if($checkStatus == 2){
+            if(!PaymentService::make()->refund($order, 20)){
+                DB::rollBack();
+                $this->error = 2638;
+                return false;
+            }
+        }
+
+        // 处理
+        $updateData = ['status'=> 5,'refund_status'=> $checkStatus,'refund_result'=> $checkStatus==2? '商家审核退款成功' : $remark,'update_time'=>time()];
+        if(!$this->model->where(['id'=> $id,'mark'=>1])->update($updateData)){
+            DB::rollBack();
+            $this->error = 2676;
+            return false;
+        }
+
+        // 若退款成功,商品库存返还
+        if($goods && $checkStatus == 2 && in_array($orderType, [1,6])){
+            foreach($goods as $item){
+                $goodsId = isset($item['goods_id'])? $item['goods_id'] : 0;
+                $goodsNum = isset($item['num'])? $item['num'] : 0;
+                if($goodsId && $goodsNum && !GoodsModel::where(['id'=> $goodsId])->increment('stock', $goodsNum)){
+                    DB::rollBack();
+                    $this->error = 2680;
+                    return false;
+                }
+            }
+        }
+
+        DB::commit();
+        $this->error = 2677;
+        return true;
+    }
+
+    /**
+     * 发货
+     * @return bool
+     */
+    public function delivery()
     {
         $params = request()->all();
         $id = isset($params['id']) ? $params['id'] : 0;
         $express = isset($params['express']) ? $params['express'] : '';
         $expressNo = isset($params['express_no']) ? $params['express_no'] : '';
-        $info = $this->model->where(['id' => $id, 'mark' => 1])->first();
+        $info = $this->model->where(['id' => $id, 'mark' => 1])
+            ->select(['id','user_id','merch_id','source_id','pay_money','reception_at','coupon_id','status','refund_status','pay_time'])
+            ->first();
         $status = isset($info['status']) ? $info['status'] : 0;
         if (!$id || empty($info)) {
-            $this->error = 2081;
+            $this->error = 2636;
             return false;
         }
 
-        if (!in_array($status, [2, 3])) {
-            $this->error = 2090;
+        if ($status != 2) {
+            $this->error = 2668;
             return false;
         }
 
-        if ($this->model->where(['id' => $id])->update(['status' => 4, 'express' => $express, 'express_no' => $expressNo, 'update_time' => time()])) {
-            $this->error = 2094;
+        if ($this->model->where(['id' => $id])->update(['status' => 3, 'express' => $express, 'express_no' => $expressNo, 'update_time' => time()])) {
+            $this->error = 2672;
             return true;
         } else {
-            $this->error = 2095;
+            $this->error = 2673;
             return false;
         }
     }
 
     /**
-     * 已收货
+     * 接单
      * @return bool
      */
-    public function receive()
+    public function picker()
     {
         $params = request()->all();
         $id = isset($params['id']) ? $params['id'] : 0;
-        $info = $this->model->where(['id' => $id, 'mark' => 1])->first();
+        $mechId = isset($params['mech_id']) ? intval($params['mech_id']) : 0;
+        $info = $this->model->where(['id' => $id, 'mark' => 1])
+            ->select(['id','user_id','merch_id','source_id','pay_money','reception_at','coupon_id','status','refund_status','pay_time'])
+            ->first();
         $status = isset($info['status']) ? $info['status'] : 0;
+        $orderMechId = isset($info['source_id']) ? $info['source_id'] : 0;
         if (!$id || empty($info)) {
-            $this->error = 2081;
+            $this->error = 2636;
             return false;
         }
 
-        if (!in_array($status, [3, 4, 5])) {
-            $this->error = 2082;
+        if($mechId != $orderMechId){
+            $this->error = 2667;
             return false;
         }
 
-        if ($this->model->where(['id' => $id])->update(['status' => 5, 'update_time' => time()])) {
-            $this->error = 2083;
+        if ($status != 2) {
+            $this->error = 2668;
+            return false;
+        }
+
+        // 处理
+        if ($this->model->where(['id' => $id])->update(['status' => 3, 'update_time' => time()])) {
+            $this->error = 2674;
             return true;
         } else {
-            $this->error = 2084;
+            $this->error = 2675;
+            return false;
+        }
+    }
+
+    /**
+     * 接单/上钟
+     * @return bool
+     */
+    public function inService()
+    {
+        $params = request()->all();
+        $id = isset($params['id']) ? $params['id'] : 0;
+        $mechId = isset($params['mech_id']) ? intval($params['mech_id']) : 0;
+        $info = $this->model->where(['id' => $id, 'mark' => 1])
+            ->select(['id','user_id','merch_id','source_id','pay_money','reception_at','coupon_id','status','is_service','refund_status','pay_time'])
+            ->first();
+        $status = isset($info['status']) ? $info['status'] : 0;
+        $isService = isset($info['is_service']) ? $info['is_service'] : 0;
+        $orderMechId = isset($info['source_id']) ? $info['source_id'] : 0;
+        if (!$id || empty($info)) {
+            $this->error = 2636;
+            return false;
+        }
+
+        if($mechId != $orderMechId){
+            $this->error = 2667;
+            return false;
+        }
+
+        if ($status != 3 || $isService == 1) {
+            $this->error = 2668;
+            return false;
+        }
+
+        // 处理
+        if ($this->model->where(['id' => $id])->update(['is_service' => 1, 'update_time' => time()])) {
+            $this->error = 1003;
+            return true;
+        } else {
+            $this->error = 1002;
             return false;
         }
     }
 
     /**
-     * 获取区域订单统计
-     * @param $city
-     * @return array|mixed
+     * 收货/已完成
+     * @return bool
      */
-    public function getCountsByCity($city)
+    public function complete($userId, $params)
     {
-        $cacheKey = "caches:orders:counts:city_" . md5($city);
-        $datas = RedisService::get($cacheKey);
-        if ($datas) {
-            return $datas;
-        }
-
-        $datas = ['count' => 0, 'total' => '0.00'];
-        if ($city) {
-            $count = $this->model->where(['city' => $city, 'status' => 4, 'mark' => 1])
-                ->whereIn('type', [1, 2])
-                ->count('id');
-            $total = $this->model->where(['city' => $city, 'status' => 4, 'mark' => 1])
-                ->whereIn('type', [1, 2])
-                ->sum('pay_money');
-            if ($count > 0) {
-                $datas = ['count' => intval($count), 'total' => floatval($total)];
-                RedisService::set($cacheKey, $datas, rand(5, 10));
+        $id = isset($params['id']) ? $params['id'] : 0;
+        $merchId = isset($params['merch_id']) ? $params['merch_id'] : 0;
+        $info = $this->model->with(['goods'])
+            ->where(['id' => $id, 'mark' => 1])
+            ->select(['id','user_id','merch_id','source_id','city','pay_money','type','reception_at','coupon_id','status','is_service','refund_status','pay_time'])
+            ->first();
+        $status = isset($info['status']) ? $info['status'] : 0;
+        $orderUserId = isset($info['user_id']) ? $info['user_id'] : 0;
+        $orderMerchId = isset($info['merch_id']) ? $info['merch_id'] : 0;
+        $orderMechId = isset($info['source_id']) ? $info['source_id'] : 0;
+        $orderType = isset($info['type']) ? $info['type'] : 0;
+        $payMoney = isset($info['pay_money']) ? $info['pay_money'] : 0;
+        $goods = isset($info['goods'])? $info['goods'] : [];
+        if (!$id || empty($info)) {
+            $this->error = 2636;
+            return false;
+        }
+
+        // 非法操作
+        if($merchId != $orderMerchId && $orderUserId != $userId){
+            $this->error = 2667;
+            return false;
+        }
+
+        // 订单状态
+        if ($status != 3) {
+            $this->error = 2668;
+            return false;
+        }
+
+        // 限制操作订单类型
+        if(!in_array($orderType, [1,2,6])){
+            $this->error = 2681;
+            return false;
+        }
+
+        // TODO 确认数据处理
+        DB::beginTransaction();
+
+        // 更新订单状态
+        if (!$this->model->where(['id' => $id])->update(['status' => 4, 'update_time' => time()])) {
+            DB::rollBack();
+            $this->error = 2678;
+            return false;
+        }
+
+        // 更新商品/服务销量
+        if($goods){
+            foreach($goods as $item){
+                $num = isset($item['num'])? $item['num'] : 0;
+                if($num>0 && !GoodsModel::where(['id'=> $item['goods_id'],'mark'=>1])->update([
+                        'sales'=> DB::raw("sales + {$num}"),'update_time'=> time()
+                    ])){
+                    DB::rollBack();
+                    $this->error = 2679;
+                    return false;
+                }
+
+            }
+        }
+
+        // 服务订单统计处理
+        if($orderType == 2){
+            // 更新技师服务订单,接单统计数据
+            $serviceCount = $this->model->where(['user_id'=> $orderUserId,'source_id'=> $orderMechId,'type'=>2,'status'=>4,'mark'=>1])->count('id');
+            $updateData = ['order_total'=> DB::raw("order_total + 1"),'update_time'=>time()];
+            if($serviceCount<=1){
+                $updateData['service_num'] =  DB::raw("service_num + 1");
+            }
+            if($orderMechId && !MechanicModel::where(['id'=>$orderMechId,'mark'=> 1])->update($updateData)){
+                DB::rollBack();
+                $this->error = 2682;
+                return false;
             }
+
+            // 更新商家服务订单,统计数据
+            $updateData = ['service_order_num'=> DB::raw("service_order_num + 1"),'service_order_total'=> DB::raw("service_order_total + {$payMoney}"),'update_time'=>time()];
+            if($orderMechId && !MerchantModel::where(['id'=>$orderMerchId,'mark'=> 1])->update($updateData)){
+                DB::rollBack();
+                $this->error = 2682;
+                return false;
+            }
+        }
+
+        // 店内订单结算
+        $balance = MerchantModel::where(['id'=> $orderMerchId,'mark'=>1])->value('balance');
+        if ($orderType == 6){
+            // 商家入账
+            $settleRate = ConfigService::make()->getConfigByCode('merch_settle_rate');
+            $settleRate = $settleRate>0? min(100, $settleRate) : 100;
+            $settleMoney = moneyFormat($payMoney * $settleRate/100, 2);
+            $updateData = ['balance'=> DB::raw("balance + {$settleMoney}"),'update_time'=>time()];
+            if($settleMoney>0 && !MerchantModel::where(['id'=> $orderMerchId,'mark'=>1])->update($updateData)){
+                DB::rollBack();
+                $this->error = 2683;
+                return false;
+            }
+
+            // 流水记录
+            $log = [
+                'user_id'=> 0,
+                'merch_id'=> $orderMerchId,
+                'source_uid'=> $orderUserId,
+                'source_order_no'=> isset($info['order_no'])? $info['order_no'] :'',
+                'type'=> 3,
+                'coin_type'=> 2,
+                'money'=> $settleMoney,
+                'balance'=>$balance? $balance : 0.00,
+                'create_time'=> time(),
+                'update_time'=> time(),
+                'remark'=> '商家店内订单收入',
+                'status'=>1,
+                'mark'=>1
+            ];
+            if(!AccountLogModel::insertGetId($log)){
+                DB::rollBack();
+                $this->error = 2641;
+                return false;
+            }
+
+            // 平台抽成入账,财务统计
+            $financeMoney = floatval($payMoney - $settleMoney);
+            if($financeMoney>0){
+                FinanceService::make()->saveLog(0,$financeMoney, 1, 1);
+            }
+        }
+
+        // 服务订单结算
+        else if(in_array($orderType, [1,2])){
+
+            // 计算服务订单分销佣金和代理佣金
+            if(!$result = FinanceService::make()->settleOrder($info, $userId)){
+                DB::rollBack();
+                $this->error = FinanceService::make()->getError();
+                return false;
+            }
+
+            // 商家入账
+            $settleMoney = isset($result['merch_money'])? $result['merch_money'] : 0;
+            $updateData = ['balance'=> DB::raw("balance + {$settleMoney}"),'update_time'=>time()];
+            if($settleMoney>0 && !MerchantModel::where(['id'=> $orderMerchId,'mark'=>1])->update($updateData)){
+                DB::rollBack();
+                $this->error = 2683;
+                return false;
+            }
+
+            $log = [
+                'user_id'=> 0,
+                'merch_id'=> $orderMerchId,
+                'source_uid'=> $orderUserId,
+                'source_order_no'=> isset($info['order_no'])? $info['order_no'] :'',
+                'type'=> 3,
+                'coin_type'=> 2,
+                'money'=> $settleMoney,
+                'balance'=>$balance? $balance : 0.00,
+                'create_time'=> time(),
+                'update_time'=> time(),
+                'remark'=> '商家服务订单收入',
+                'status'=>1,
+                'mark'=>1
+            ];
+            if(!AccountLogModel::insertGetId($log)){
+                DB::rollBack();
+                $this->error = 2641;
+                return false;
+            }
+
+            // 平台入账,财务统计
+            $financeMoney = isset($result['platform_money'])? $result['platform_money'] : 0;
+            if($financeMoney>0){
+                FinanceService::make()->saveLog(0,$financeMoney, 1, 1);
+            }
+
+        }
+
+
+        DB::commit();
+        $this->error = 1002;
+        return true;
+    }
+
+
+    /**
+     * 评论
+     * @return bool
+     */
+    public function comment()
+    {
+        $params = request()->all();
+        $id = isset($params['id']) ? $params['id'] : 0;
+        $info = $this->model->where(['id' => $id, 'mark' => 1])->first();
+        $status = isset($info['status']) ? $info['status'] : 0;
+        if (!$id || empty($info)) {
+            $this->error = 2081;
+            return false;
+        }
+
+        if (!in_array($status, [3, 4, 5])) {
+            $this->error = 2082;
+            return false;
+        }
+
+        if ($this->model->where(['id' => $id])->update(['status' => 5, 'update_time' => time()])) {
+            $this->error = 2083;
+            return true;
+        } else {
+            $this->error = 2084;
+            return false;
         }
-        return $datas;
     }
 }

+ 5 - 4
app/Services/Api/PaymentService.php

@@ -492,7 +492,7 @@ class PaymentService extends BaseService
             case 'buy': // 购买服务
                 break;
             case 'cost': // 店内消费
-                // 商品销量
+                // 商品减库存
                 $goods = OrderGoodsModel::where(['order_no'=> $orderNo,'mark'=>1])
                     ->select(['goods_id','num'])
                     ->get();
@@ -501,7 +501,7 @@ class PaymentService extends BaseService
                         $goodsId = isset($item['goods_id'])? $item['goods_id'] : 0;
                         $goodsNum = isset($item['num'])? $item['num'] : 0;
                         if($goodsId && $goodsNum){
-                            GoodsModel::where(['id'=> $goodsId])->increment('sales', $goodsNum);
+                            GoodsModel::where(['id'=> $goodsId])->decrement('stock', $goodsNum);
                         }
                     }
                 }
@@ -565,10 +565,11 @@ class PaymentService extends BaseService
 
         // 验证订单
         $orderInfo = OrderModel::where(['order_no'=>$orderNo,'mark'=>1])
-            ->select(['id','order_no','user_id','merch_id','status','pay_money','num'])
+            ->select(['id','order_no','user_id','merch_id','status','refund_status','pay_money','num'])
             ->first();
         $userId = isset($orderInfo['user_id'])? $orderInfo['user_id'] : 0;
         $orderStatus = isset($orderInfo['status'])? $orderInfo['status'] : 0;
+        $refundStatus = isset($orderInfo['refund_status'])? $orderInfo['refund_status'] : 0;
         // 验证订单
         if(empty($orderInfo) || $userId<=0){
             $this->error = 2656;
@@ -576,7 +577,7 @@ class PaymentService extends BaseService
         }
 
         // 订单状态
-        if(!in_array($orderStatus, [2,3])){
+        if(!in_array($orderStatus, [2,3,5]) || $refundStatus != 1){
             $this->error = 2657;
             return false;
         }

+ 2 - 1
config/payment.php

@@ -83,7 +83,7 @@ return [
         ['id'=>17, 'name'=>'浦发发展银行银行','status'=>1],
         ['id'=>18, 'name'=>'广西北部湾银行','status'=>1],
         ['id'=>19, 'name'=>'广西农村信用社','status'=>1],
-        ['id'=>20, 'name'=>'广东省农村信用社','status'=>1],
+        ['id'=>20, 'name'=>'广发银行','status'=>1],
         ['id'=>21, 'name'=>'贵州省农村信用社','status'=>1],
         ['id'=>22, 'name'=>'海南省农村信用社','status'=>1],
         ['id'=>23, 'name'=>'湖北省农村信用社','status'=>1],
@@ -94,5 +94,6 @@ return [
         ['id'=>28, 'name'=>'陕西省农村信用社','status'=>1],
         ['id'=>29, 'name'=>'云南省农村信用社','status'=>1],
         ['id'=>30, 'name'=>'江苏省农村信用社','status'=>1],
+        ['id'=>31, 'name'=>'广东省农村信用社','status'=>1],
     ],
 ];

+ 27 - 0
resources/lang/zh-cn/api.php

@@ -141,6 +141,12 @@ return [
     '2633'=> '支付订单处理错误',
     '2634'=> '用户账户入账错误',
     '2635'=> '支付回调处理失败',
+    '2636'=> '订单不存在或参数错误',
+    '2637'=> '订单支付信息错误,请联系客服',
+    '2638'=> '订单退款打款失败,请联系客服',
+    '2639'=> '订单退款审核状态参数错误',
+    '2640'=> '订单参数错误',
+    '2641'=> '商家账户明细处理失败',
 
     // 退款
     '2651'=> '退款金额超出订单金额',
@@ -156,6 +162,27 @@ return [
     '2661'=> '余额退款申请成功',
     '2662'=> '微信退款申请成功',
     '2663'=> '支付宝退款申请成功',
+    '2664'=> '该订单已申请过退款',
+    '2665'=> '申请退款处理失败',
+    '2666'=> '申请退款成功,请等待审核',
+    '2667'=> '无权操作,请核实后重试',
+    '2668'=> '该订单状态不允许操作',
+    '2669'=> '该订单未申请退款,请核对后重试',
+    '2670'=> '订单退款撤销失败',
+    '2671'=> '订单退款撤销成功',
+    '2672'=> '订单发货失败',
+    '2673'=> '订单发货成功',
+    '2674'=> '接单失败',
+    '2675'=> '接单成功',
+    '2676'=> '订单退款失败',
+    '2677'=> '订单退款成功',
+    '2678'=> '订单状态更新失败',
+    '2679'=> '商品销量更新失败',
+    '2680'=> '商品库存处理失败',
+    '2681'=> '订单类型不支持操作',
+    '2682'=> '订单统计数据处理错误',
+    '2683'=> '操作失败,订单结算不成功',
+    '2684'=> '操作失败,订单佣金处理错误',
 
 
     // 视频聊天

+ 10 - 0
routes/api.php

@@ -46,6 +46,8 @@ Route::prefix('v1')->group(function(){
     Route::post('/user/detail', [\App\Http\Controllers\Api\v1\MemberController::class, 'detail']);
     Route::post('/user/homeInfo', [\App\Http\Controllers\Api\v1\MemberController::class, 'homeInfo']);
     Route::post('/user/setAvatar', [\App\Http\Controllers\Api\v1\MemberController::class, 'setAvatar']);
+    Route::post('/user/setWxpay', [\App\Http\Controllers\Api\v1\MemberController::class, 'setWxpay']);
+    Route::post('/user/setAlipay', [\App\Http\Controllers\Api\v1\MemberController::class, 'setAlipay']);
     Route::post('/user/modify', [\App\Http\Controllers\Api\v1\MemberController::class, 'modify']);
     Route::post('/user/updateMap', [\App\Http\Controllers\Api\v1\MemberController::class, 'updateMap']);
     Route::post('/user/barCount', [\App\Http\Controllers\Api\v1\MemberController::class, 'barCount']);
@@ -135,11 +137,19 @@ Route::prefix('v1')->group(function(){
     Route::post('/bank/delete', [\App\Http\Controllers\Api\v1\MemberBankController::class, 'delete']);
 
     // 订单
+    Route::post('/order/index', [\App\Http\Controllers\Api\v1\OrderController::class, 'index']);
     Route::post('/order/list', [\App\Http\Controllers\Api\v1\OrderController::class, 'list']);
     Route::post('/order/info', [\App\Http\Controllers\Api\v1\OrderController::class, 'info']);
     Route::post('/order/service', [\App\Http\Controllers\Api\v1\OrderController::class, 'service']);
     Route::post('/order/buy', [\App\Http\Controllers\Api\v1\OrderController::class, 'buy']);
     Route::post('/order/picker', [\App\Http\Controllers\Api\v1\OrderController::class, 'picker']);
+    Route::post('/order/delivery', [\App\Http\Controllers\Api\v1\OrderController::class, 'delivery']);
+    Route::post('/order/inService', [\App\Http\Controllers\Api\v1\OrderController::class, 'inService']);
+    Route::post('/order/complete', [\App\Http\Controllers\Api\v1\OrderController::class, 'complete']);
+    Route::post('/order/refund', [\App\Http\Controllers\Api\v1\OrderController::class, 'refund']);
+    Route::post('/order/refundConfirm', [\App\Http\Controllers\Api\v1\OrderController::class, 'refundConfirm']);
+    Route::post('/order/refundCancel', [\App\Http\Controllers\Api\v1\OrderController::class, 'refundCancel']);
+    Route::post('/order/delete', [\App\Http\Controllers\Api\v1\OrderController::class, 'delete']);
 
     // 文章
     Route::post('/article/index', [\App\Http\Controllers\Api\v1\ArticleController::class, 'index']);