zilong 4 年之前
父節點
當前提交
2fbc1a744c

+ 2 - 0
.env.example

xqd
@@ -43,3 +43,5 @@ PUSHER_APP_CLUSTER=mt1
 
 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
 MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
+
+API_HOST=

+ 14 - 0
app/Helpers/functions.php

xqd
@@ -91,3 +91,17 @@ if (!function_exists('get_distance_field')) {
         return 'if(longitude=0 and latitude=0,999999999,round(6378.138*2*asin(sqrt(pow(sin( (' . $latitude . '*pi()/180-latitude*pi()/180)/2),2)+cos(' . $latitude . '*pi()/180)*cos(latitude*pi()/180)* pow(sin((' . $longitude . '*pi()/180-longitude*pi()/180)/2),2)))*1000)) distance';
     }
 }
+
+//构建单号
+if (!function_exists('build_sn')) {
+    function build_sn($id, $len = 2, $prefix = '')
+    {
+        $idx = 0 - $len;
+        $suffix = substr($id, $idx);
+        $suffix = str_pad($suffix, $len, '0', STR_PAD_LEFT);
+
+        $sn = $prefix.substr(date('YmdHis'), 2).$suffix;
+
+        return $sn;
+    }
+}

+ 1 - 1
app/Http/Controllers/Api/V1/DocterController.php

xqd
@@ -98,7 +98,7 @@ class DocterController extends AuthController
         $longitude = !empty($req['longitude']) ? $req['longitude'] : $user['longitude'];
         $distance_field = get_distance_field($latitude, $longitude);
 
-        $data = Docter::with('office', 'qualification')->select(['id', 'type', 'name', 'phone', 'sex', 'birthday', 'avatar', 'status', 'label', 'sign', 'intro', 'office_id', 'qualification_id', 'score', 'service_persons', 'eva_num', 'service_days', 'phone_minutes', 'chat_price', 'phone_price', 'appoint_price', 'is_chat', 'is_phone', 'is_appoint', 'latitude', 'longitude', DB::raw($distance_field)])->where('id', $req['docter_id'])->where('status', 1)->first()->toArray();
+        $data = Docter::with('office', 'qualification', 'evaluate.user')->select(['id', 'type', 'name', 'phone', 'sex', 'birthday', 'avatar', 'status', 'label', 'sign', 'intro', 'office_id', 'qualification_id', 'score', 'service_persons', 'eva_num', 'service_days', 'phone_minutes', 'chat_price', 'phone_price', 'appoint_price', 'is_chat', 'is_phone', 'is_appoint', 'latitude', 'longitude', DB::raw($distance_field)])->where('id', $req['docter_id'])->where('status', 1)->first()->toArray();
 
         $data['organization'] = null;
         if (!empty($req['list_type']) && $req['list_type'] == 3) {

+ 116 - 0
app/Http/Controllers/Api/V1/OrderController.php

xqd
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zilongs
+ * Date: 20-9-30
+ * Time: 下午10:58
+ */
+
+namespace App\Http\Controllers\Api\v1;
+
+use App\Models\Order;
+use App\Models\OrderPatient;
+use App\Models\Patient;
+use App\Models\Payment;
+use App\Models\TimePeriod;
+use App\Models\UserCoupon;
+use DB;
+use EasyWeChat\Factory;
+
+class OrderController extends AuthController
+{
+    public function placeOrder()
+    {
+        $req = request()->post();
+        $this->validate(request(), [
+            'product_type' => 'required|in:1,2,3',
+            'docter_id' => 'required|integer',
+            'patient_id' => 'required|integer',
+            'total_amount' => 'required|integer',
+            'user_coupon_id' => 'integer',
+            'phone' => 'required_if:product_type,1',
+            'phone_minutes' => 'required_if:product_type,1|integer',
+            'symptoms' => 'required_if:product_type,2|max:2000',
+            'medical_imgs' => 'required_if:product_type,2|json|max:3000',
+            'schedule_date' => 'required_if:product_type,3|date',
+            'time_period_id' => 'required_if:product_type,3|integer',
+            'organization_id' => 'required_if:product_type,3|integer'
+        ]);
+        $user = $this->user;
+
+        $discount_amount = 0;
+        if (!empty($req['user_coupon_id'])) {
+            //计算优惠金额
+            $discount_amount = UserCoupon::getDiscountAmount($req['user_coupon_id'], $user['id'], $req['total_amount'], $req['product_type']);
+        }
+        $payment_amount = $req['total_amount'] - $discount_amount;
+
+        DB::beginTransaction();
+        try {
+            //保存订单数据
+            $order = Order::create([
+                'user_id' => $user['id'],
+                'product_type' => $req['product_type'],
+                'docter_id' => $req['docter_id'],
+                'total_amount' => $req['total_amount'],
+                'payment_amount' => $payment_amount,
+                'discount_amount' => $discount_amount,
+            ]);
+            $order_sn = build_sn($order['id']);
+            Order::where('id', $order['id'])->update(['order_sn' => $order_sn]);
+            //保存订单患者信息
+            $addPatient = Patient::select(['name', 'sex', 'avatar', 'birthday', 'relationship', 'info', 'card_type', 'card_number'])->where('id', $req['patient_id'])->first()->toArray();
+            $addPatient['order_id'] = $order['id'];
+            $addPatient['patient_id'] = $req['patient_id'];
+            if ($req['product_type'] == 1) {
+                $addPatient['phone'] = $req['phone'];
+                $addPatient['phone_minutes'] = $req['phone_minutes'];
+            }
+            elseif ($req['product_type'] == 2) {
+                $addPatient['symptoms'] = $req['symptoms'];
+                $addPatient['medical_imgs'] = $req['medical_imgs'];
+            }
+            elseif ($req['product_type'] == 3) {
+                $addPatient['organization_id'] = $req['organization_id'];
+                $addPatient['time_period_id'] = $req['time_period_id'];
+                $timePeriod = TimePeriod::where('id', $req['time_period_id'])->first();
+                $addPatient['appoint_start_time'] = strtotime($req['schedule_date'].' '.$timePeriod['start_time_period'].':00');
+                $addPatient['appoint_end_time'] = strtotime($req['schedule_date'].' '.$timePeriod['end_time_period'].':00');
+            }
+            OrderPatient::create($addPatient);
+            //生成支付交易单
+            $trade_sn = build_sn($order['id'], 3, 'T');
+            $payBody = '超级宝妈-'.config('config.product_type_map')[$req['product_type']];
+            Payment::create([
+                'user_id' => $user['id'],
+                'order_id' => $order['id'],
+                'trade_sn' => $trade_sn,
+                'amount' => $payment_amount,
+                'remark' => $payBody,
+            ]);
+            //请求支付
+            $payment = Factory::payment(config('config.wechat_pay'));
+            $result = $payment->order->unify([
+                'body' => $payBody,
+                'out_trade_no' => $trade_sn,
+                'total_fee' => $payment_amount,
+                'trade_type' => 'JSAPI',
+                'openid' => $user['openid'],
+            ]);
+
+            if (empty($result['prepay_id'])) {
+                $errorMsg = !empty($result['err_code_des']) ? $result['err_code_des'] : $result['return_msg'];
+                return out(null, 702, $errorMsg);
+            }
+
+            $config = $payment->jssdk->bridgeConfig($result['prepay_id'], false);
+
+            DB::commit();
+        } catch (\Exception $e) {
+            DB::rollBack();
+            return out(null, 500, '下单失败,请稍后重试', $e->getMessage());
+        }
+
+        return out($config);
+    }
+}

+ 14 - 0
app/Models/CouponType.php

xqd
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zilongs
+ * Date: 20-9-30
+ * Time: 下午11:44
+ */
+
+namespace App\Models;
+
+class CouponType extends BaseModel
+{
+
+}

+ 5 - 0
app/Models/Docter.php

xqd
@@ -28,4 +28,9 @@ class Docter extends BaseModel
     {
         return $this->belongsToMany(Organization::class);
     }
+
+    public function evaluate()
+    {
+        return $this->hasMany(Evaluate::class)->where('status', 2);
+    }
 }

+ 17 - 0
app/Models/Evaluate.php

xqd
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zilongs
+ * Date: 20-9-30
+ * Time: 下午9:40
+ */
+
+namespace App\Models;
+
+class Evaluate extends BaseModel
+{
+    public function user()
+    {
+        return $this->belongsTo(User::class)->select(['id', 'nickname', 'avatar']);
+    }
+}

+ 14 - 0
app/Models/Order.php

xqd
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zilongs
+ * Date: 20-9-30
+ * Time: 下午10:56
+ */
+
+namespace App\Models;
+
+class Order extends BaseModel
+{
+
+}

+ 16 - 0
app/Models/OrderPatient.php

xqd
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zilongs
+ * Date: 20-10-1
+ * Time: 上午12:09
+ */
+
+namespace App\Models;
+
+class OrderPatient extends BaseModel
+{
+    protected $casts = [
+        'medical_imgs' => 'json',
+    ];
+}

+ 14 - 0
app/Models/Patient.php

xqd
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zilongs
+ * Date: 20-10-1
+ * Time: 上午12:10
+ */
+
+namespace App\Models;
+
+class Patient extends BaseModel
+{
+
+}

+ 14 - 0
app/Models/Payment.php

xqd
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zilongs
+ * Date: 20-10-1
+ * Time: 上午12:43
+ */
+
+namespace App\Models;
+
+class Payment extends BaseModel
+{
+
+}

+ 56 - 0
app/Models/UserCoupon.php

xqd
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zilongs
+ * Date: 20-9-30
+ * Time: 下午11:25
+ */
+
+namespace App\Models;
+
+class UserCoupon extends BaseModel
+{
+    public static function getDiscountAmount($id, $user_id, $total_amount, $product_type)
+    {
+        $userCoupon = self::where('id', $id)->where('user_id', $user_id)->first();
+        if (empty($userCoupon)) {
+            exit_out(null, 10001, '用户优惠券不存在');
+        }
+        if ($userCoupon['status'] == 2) {
+            exit_out(null, 10002, '该优惠券已被使用,请勿重复使用');
+        }
+        if ($userCoupon['status'] == 3) {
+            exit_out(null, 10003, '该优惠券已过期');
+        }
+        if ($userCoupon['status'] == 1) {
+            if ($userCoupon['expire_type'] == 1) {
+                $expire_time = strtotime($userCoupon['created_at']) + $userCoupon['effective_days']*24*3600;
+            }
+            else {
+                $expire_time = $userCoupon['end_time'];
+            }
+            if ($expire_time < time()) {
+                self::where('id', $id)->update(['status' => 3]);
+                exit_out(null, 10004, '该优惠券已过期');
+            }
+
+            if ($userCoupon['min_consume_amount'] > $total_amount) {
+                exit_out(null, 10005, '未达到该优惠券的最低消费金额');
+            }
+
+            if ($userCoupon['usable_type'] == 2 && !CouponType::where('user_coupon_id', $id)->where('product_type', $product_type)->count()) {
+                exit_out(null, 10006, '该优惠券不支持该类型的订单');
+            }
+        }
+
+        if ($userCoupon['type'] == 1) {
+            $discountAmount = $userCoupon['money'];
+        }
+        else {
+            $discountAmount = floor((1 - $userCoupon['discount']/10)*$total_amount);
+            $discountAmount = $userCoupon['max_reduce_amount'] < $discountAmount ? $userCoupon['max_reduce_amount'] : $discountAmount;
+        }
+
+        return $discountAmount;
+    }
+}

+ 7 - 5
config/config.php

xqd
@@ -12,14 +12,16 @@ return [
     'aes_iv' => 'sfX2ReOCcY22CEUF',
 
     'wechat_small_program' => [
-        'app_id' => 'wxcb8cf16641d45bea',
-        'secret' => 'bec57a111c85846e245db4b88147581c',
+        'app_id' => 'wx92066f7587c34617',
+        'secret' => '3f536fcac0af9e011fa401f1274c5565',
     ],
 
     'wechat_pay' => [
-        'app_id' => 'wxcb8cf16641d45bea',
-        'mch_id' => '1592541921',
-        'key' => 'weixinzhifujuyinzhengxin66666666',
+        'app_id' => 'wx92066f7587c34617',
+        'mch_id' => '1398823402',
+        'key' => 'c1891122765718911227657189112276',
         'notify_url' => env('API_HOST', '').'/api/payCallback/wechatPayNotify'
     ],
+
+    'product_type_map' => [1 => '电话咨询', 2 => '图文咨询', 3 => '门诊预约', 4 => '疫苗接种预约', 5 => '儿保预约', 6 => '服务包', 7 => '充值'],
 ];