Browse Source

老年大学下单支付and更改wallet

panda 4 months ago
parent
commit
f4df42d16f

+ 21 - 0
application/api/controller/Notify.php

@@ -2,6 +2,7 @@
 namespace app\api\controller;
 
 use app\common\controller\Api;
+use app\common\model\PayOrderModel;
 use app\utils\LogUtil;
 use think\Db;
 use addons\epay\library\Service;
@@ -262,4 +263,24 @@ class Notify extends Api
         return $notify_file;
 
     }
+
+    // 老年大学活动报名支付回调
+    public function university_event_wechat()
+    {
+        $pay = Service::checkNotify('wechat');
+        LogUtil::info('老年大学活动 微信支付回调', self::LOG_MODULE,__FUNCTION__, $pay);
+        if (!$pay){
+            LogUtil::info('签名错误', self::LOG_MODULE,__FUNCTION__);
+            return false;
+        }
+        $data = $pay->verify();
+        $out_trade_no = $data['out_trade_no'];
+        [$res,$msg] = PayOrderModel::university_event($out_trade_no);
+        if (!$res){
+            LogUtil::info($msg, self::LOG_MODULE,__FUNCTION__);
+            return false;
+        }
+        LogUtil::info('处理成功', self::LOG_MODULE,__FUNCTION__);
+        return $pay->success();
+    }
 }

+ 152 - 12
application/api/controller/UniversityEvent.php

@@ -2,8 +2,12 @@
 
 namespace app\api\controller;
 
+use addons\epay\library\Service;
 use app\common\controller\Api;
+use app\common\model\PayOrderModel;
 use app\common\model\UniversityEventModel;
+use app\common\model\Wallet;
+use app\utils\CurlUtil;
 use app\utils\Service\Tencent\TencentIm;
 use think\Db;
 
@@ -19,7 +23,7 @@ class UniversityEvent extends Api
     public function list()
     {
         $user_id = $this->auth->id;
-        $list = UniversityEventModel::with([
+        $list    = UniversityEventModel::with([
             'apply' => function ($query) use ($user_id) {
                 $query->field('id,event_id,user_id')->where('user_id', $user_id)->where('status', 1);
             }
@@ -31,23 +35,23 @@ class UniversityEvent extends Api
             ->select();
         foreach ($list as $k => $v) {
             $list[$k]['start_apply_time'] = date('Y-m-d H:i', $v['start_apply_time']);
-            $list[$k]['end_apply_time'] = date('Y-m-d H:i', $v['end_apply_time']);
-            $list[$k]['start_time'] = date('Y-m-d H:i', $v['start_time']);
-            $list[$k]['apply'] = !empty($v['apply']) ? 1 : 0;
+            $list[$k]['end_apply_time']   = date('Y-m-d H:i', $v['end_apply_time']);
+            $list[$k]['start_time']       = date('Y-m-d H:i', $v['start_time']);
+            $list[$k]['apply']            = !empty($v['apply']) ? 1 : 0;
         }
-        return $this->success('success',$list);
+        return $this->success('success', $list);
     }
 
     // 活动详情
     public function info()
     {
         $params = $this->request->param();
-        if (empty($params['event_id'])){
+        if (empty($params['event_id'])) {
             return $this->error('参数缺失');
         }
         $user_id = $this->auth->id;
 
-        $info = UniversityEventModel::with([
+        $info                     = UniversityEventModel::with([
             'apply' => function ($query) use ($user_id) {
                 $query->field('id,event_id,user_id')->where('user_id', $user_id)->where('status', 1);
             }
@@ -57,12 +61,148 @@ class UniversityEvent extends Api
             ->where('status', 1)
             ->order('id desc')
             ->find();
-        $info['start_apply_time'] = date('Y-m-d H:i', $info['start_apply_time']);
-        $info['end_apply_time'] = date('Y-m-d H:i', $info['end_apply_time']);
-        $info['start_time'] = date('Y-m-d H:i', $info['start_time']);
-        $info['apply'] = !empty($info['apply']) ? 1 : 0;
-        return $this->success('success',$info);
+        $info['start_apply_time'] = date('Y-m-d', $info['start_apply_time']);
+        $info['end_apply_time']   = date('Y-m-d', $info['end_apply_time']);
+        $info['start_time']       = date('Y-m-d', $info['start_time']);
+        $info['apply']            = !empty($info['apply']) ? 1 : 0;
+        return $this->success('success', $info);
     }
 
+    public function apply()
+    {
+        $params = $this->request->param();
+        if (empty($params['event_id'])) {
+            return $this->error('参数缺失');
+        }
+        if (empty($params['pay_type']) || empty($params['platform'])) {
+            return $this->error('请选择支付方式');
+        }
+        if (empty($params['apply_list'])) {
+            return $this->error('请提交报名信息');
+        }
+        foreach ($params['apply_list'] as $k => $v) {
+            if (empty($v['name'])) {
+                return $this->error('报名信息姓名不能为空');
+            }
+            if (empty($v['phone'])) {
+                return $this->error('报名信息手机号不能为空');
+            }
+        }
+        $user_id = $this->auth->id;
+        $info    = UniversityEventModel::with([
+            'apply' => function ($query) use ($user_id) {
+                $query->field('id,event_id,user_id')->where('user_id', $user_id)->where('status', 1);
+            }
+        ])
+            ->field('id,name,price,image,images,start_apply_time,end_apply_time,start_time,address,content')
+            ->where('id', $params['event_id'])
+            ->where('status', 1)
+            ->order('id desc')
+            ->find();
+        if (!$info) {
+            return $this->error('活动不存在');
+        }
+        if (!empty($info['apply'])) {
+            return $this->error('您已报过名了');
+        }
+        $nowTime = time();
+        if ($info['start_apply_time'] > $nowTime) {
+            return $this->error('报名未开始');
+        }
+        if ($info['end_apply_time'] < $nowTime) {
+            return $this->error('报名已结束');
+        }
+        // 开始报名
+        $num  = count($params['apply_list']);
+        $data = [
+            'user_id'     => $user_id,
+            'event_id'    => $params['event_id'],
+            'order_no'    => createUniqueNo('E', $user_id),
+            'pay_amount'  => bcmul($info['price'], $num, 2),
+            'create_time' => $nowTime
+        ];
+        Db::startTrans();
+        $apply_id = Db::name('university_event_apply')->insertGetId($data);
+        if (!$apply_id) {
+            Db::rollback();
+            return $this->error('订单创建失败');
+        }
+        $apply_info = [];
+        foreach ($params['apply_list'] as $k => $v) {
+            $apply_info[] = [
+                'user_id'  => $user_id,
+                'event_id' => $params['event_id'],
+                'order_id' => $apply_id,
+                'order_no' => $data['order_no'],
+                'name'     => $v['name'],
+                'phone'    => $v['phone']
+            ];
+        }
+        if (!Db::name('university_event_info')->insertAll($apply_info)) {
+            Db::rollback();
+            return $this->error('订单创建失败');
+        }
+        Db::commit();
+
+        // 创建支付订单
+        $remark    = '老年大学活动报名';
+        $orderData = [
+            'user_id'      => $user_id,
+            'out_trade_no' => $data['order_no'],
+            'order_amount' => $data['pay_amount'],
+            'pay_type'     => $params['pay_type'],
+            'platform'     => $params['platform'],
+            'table_name'   => 'university_event_apply',
+            'table_id'     => $apply_id,
+            'createtime'   => time(),
+            'args'         => json_encode([
+                'table_id' => $apply_id,
+                'remark'   => $remark
+            ], JSON_UNESCAPED_UNICODE),
+        ];
+        if (!Db::name('pay_order')->insert($orderData)) {
+            return $this->error('订单创建失败');
+        }
+
+        // 拉起支付 余额支付
+        if ($params['pay_type'] == 'wallet') {
+            Db::startTrans();
+            //钱包更新
+            $walletService = new Wallet();
+            if (!$walletService->change($user_id, -$orderData['order_amount'], 'money', 20, $remark, $orderData['table_name'], $orderData['table_id'])) {
+                Db::rollback();
+                return $this->error($walletService->getMessage());
+            }
+            // 支付成功,更改支付金额
+            [$res,$msg] = PayOrderModel::university_event($orderData['out_trade_no']);
+            if (!$res){
+                Db::rollback();
+                return $this->error($msg);
+            }
+            Db::commit();
+            return $this->success('支付成功');
+        }
+
+        // 第三方支付下单
+        $params = [
+            'type'      => $orderData['pay_type'],
+            'orderid'   => $orderData['out_trade_no'],
+            'title'     => $remark,
+            'amount'    => $orderData['order_amount'],
+            'method'    => $orderData['platform'],
+            'notifyurl' => CurlUtil::getHttp("/api/notify/university_event_{$params['pay_type']}"),
+            'returnurl' => '',
+        ];
+        // 如果是小程序则需要添加 openid
+        if ($params['pay_type'] == 'wechat' && $params['platform'] == 'miniapp') {
+            $params['openid'] = $this->auth->mini_openid;
+        }
+        $res = Service::submitOrder($params);
+        if ($params['pay_type'] == 'wechat') {
+            $this->success('success', json_decode($res, true));
+        } else {
+            $this->success('success', $res);
+        }
+    }
 
 }

+ 50 - 0
application/common/model/PayOrderModel.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace app\common\model;
+
+use think\Db;
+use think\Model;
+
+/**
+ * 支付订单
+ */
+class PayOrderModel extends Model
+{
+    // 表名
+    protected $name = 'pay_order';
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = false;
+    // 定义时间戳字段名
+    protected $createTime = false;
+    protected $updateTime = false;
+    protected $deleteTime = false;
+
+
+    /**
+     * 老年大学活动支付回调
+     * @param $out_trade_no
+     * @return array
+     */
+    public static function university_event($out_trade_no)
+    {
+        if (!$info = self::where('out_trade_no',$out_trade_no)->find()){
+            return [false,'未找到订单'];
+        }
+        if ($info['order_status'] == 1){
+            return [true,'订单已支付'];
+        }
+
+        Db::startTrans();
+        //更新订单状态
+        if (!self::where(['id' => $info['id']])->update(['status' => 1])) {
+            Db::rollback();
+            return [false,'订单状态更新失败'];
+        }
+        if (!UniversityEventApplyModel::where('id',$info['table_id'])->update(['status' => 1,'pay_time' => time()])) {
+            Db::rollback();
+            return [false,'活动订单状态更新失败'];
+        }
+        Db::commit();
+        return [true,'操作成功'];
+    }
+}

+ 136 - 50
application/common/model/Wallet.php

@@ -1,29 +1,46 @@
 <?php
+
 namespace app\common\model;
+
 use think\Model;
 use think\Db;
+
 /**
  * 货币模型
  */
 class Wallet extends Model
 {
+    // 日志变动类型
+    const log_type = [
+        1  => '系统调节',//money + -
+        20 => '老年大学活动报名',//money + -
+    ];
+    // 操作钱包余额类型
+    const money_type = [
+        'money' => '余额',
+    ];
+
+    protected $message = '';
+    protected $data    = [];
+
     /**
      * 获取交易类型配置
      * @return mixed
      */
-    public function getlogtype($type = '')
+    public function getLogType($type = '')
     {
-        $conf = config('wallet.logtype');
-        if($type){
+        $conf = self::log_type;
+        if ($type) {
             return $conf[$type] ?: $type;
         }
         return $conf;
     }
 
     //获取钱包名称
-    public function getwalletname($name = ''){
-        $conf = config('wallet.moneyname');
-        if($name){
+    public function getWalletName($name = '')
+    {
+        $conf = self::money_type;
+        if ($name) {
             return $conf[$name] ?: $name;
         }
         return $conf;
@@ -39,11 +56,11 @@ class Wallet extends Model
     {
         //所有钱包余额
         $wallet = Db::name('user_wallet')->lock(true)->where(['user_id' => $user_id])->find();
-        if(!$wallet) {
-            abort(500,'钱包余额获取失败');
+        if (!$wallet) {
+            abort(500, '钱包余额获取失败');
         }
 
-        if($wallet_name) { //返回指定钱包
+        if ($wallet_name) { //返回指定钱包
             return isset($wallet[$wallet_name]) ? $wallet[$wallet_name] : 0;
         } else { //返回所有钱包
             return $wallet;
@@ -67,14 +84,14 @@ class Wallet extends Model
      * @return array[log_table]
      * @return array[log_id]
      */
-    public function lockChangeAccountRemain($user_id,$accountType='money',$number,$logtype='',$remark='',$table='',$table_id=0,$isAdmin=false)
+    public function lockChangeAccountRemain($user_id, $accountType = 'money', $number, $logtype = '', $remark = '', $table = '', $table_id = 0, $isAdmin = false)
     {
         //初始化
         $result = array(
-            'status'=>false,
-            'msg'=>'',
+            'status'    => false,
+            'msg'       => '',
             'log_table' => '',
-            'log_id' => '',
+            'log_id'    => '',
         );
 
         //获取小数点
@@ -82,79 +99,69 @@ class Wallet extends Model
         bcscale($point);
 
         //钱包名称
-        $wallet_name = $this->getwalletname($accountType);
+        $wallet_name = $this->getWalletName($accountType);
 
         //检测
-        $number = floatval( $number );
-        if( $number == 0 )
-        {
+        $number = floatval($number);
+        if ($number == 0) {
             $result['msg'] = '交易金额:0';
             return $result;
         }
-        if(0 === bccomp($number, 0)){
+        if (0 === bccomp($number, 0)) {
             $result['msg'] = '交易金额:0';
             return $result;
         }
 
 
         //检测
-        $wallet = Db::name('user_wallet')->lock(true)->where(['user_id'=>$user_id])->find();
-        if(!$wallet)
-        {
+        $wallet = Db::name('user_wallet')->lock(true)->where(['user_id' => $user_id])->find();
+        if (!$wallet) {
             $result['msg'] = '不存在的用户';
             return $result;
         }
 
-        if(bccomp(bcadd($wallet[$accountType], $number), 0) === -1)
-        {
-            $result['msg'] = $wallet_name.'余额不足!';
+        if (bccomp(bcadd($wallet[$accountType], $number), 0) === -1) {
+            $result['msg'] = $wallet_name . '余额不足!';
             return $result;
-        }
-        else
-        {
-            if(0 !== bccomp($number, 0))
-            {
+        } else {
+            if (0 !== bccomp($number, 0)) {
 
                 //钱币记录
-                $data = array();
-                $data['user_id'] = $user_id;
+                $data             = array();
+                $data['user_id']  = $user_id;
                 $data['log_type'] = $logtype;
 //                $data['money_type'] = $accountType;
-                $data['before'] = $wallet[$accountType];
+                $data['before']       = $wallet[$accountType];
                 $data['change_value'] = $number;
-                $data['remain'] = bcadd($wallet[$accountType], $number);
-                $data['table'] = $table;
-                $data['table_id'] = $table_id;
-                $data['remark'] = $remark;
-                $data['createtime'] = time();
-                $data['updatetime'] = time();
+                $data['remain']       = bcadd($wallet[$accountType], $number);
+                $data['table']        = $table;
+                $data['table_id']     = $table_id;
+                $data['remark']       = $remark;
+                $data['createtime']   = time();
+                $data['updatetime']   = time();
 
                 //新的方式
-                $rs1 = Db::name('user_wallet')->where(['user_id'=>$user_id])->update([$accountType => $data['remain']]);
-
+                $rs1 = Db::name('user_wallet')->where(['user_id' => $user_id])->update([$accountType => $data['remain']]);
 
 
                 /////////////
-                $log_table = 'user_'.$accountType.'_log';
+                $log_table = 'user_' . $accountType . '_log';
 
                 $rs2_id = Db::name($log_table)->insertGetId($data);
 
-                if($rs1 === false || $rs2_id === false){
+                if ($rs1 === false || $rs2_id === false) {
                     $result['msg'] = '更新财务记录失败!';
                     return $result;
                 }
 
-                if( $rs1 !== false && $rs2_id !== false )
-                {
-                    $result['status'] = true;
-                    $result['msg'] = '账户余额已更新!';
+                if ($rs1 !== false && $rs2_id !== false) {
+                    $result['status']    = true;
+                    $result['msg']       = '账户余额已更新!';
                     $result['log_table'] = $log_table;
-                    $result['log_id'] = $rs2_id;
+                    $result['log_id']    = $rs2_id;
 
                     return $result;
-                }
-                else
-                {
+                } else {
                     $result['msg'] = '更新财务记录失败!';
                     return $result;
                 }
@@ -165,7 +172,86 @@ class Wallet extends Model
         }
     }
 
+    /**
+     * 余额变更
+     * @param int $user_id 用户id
+     * @param float $number 金额(正数进账,负数出账)
+     * @param string $accountType 货币类型 self::money_type
+     * @param int $log_type 日志的类型 self::log_type
+     * @param string $remark 备注
+     * @param string $table 来源表
+     * @param int $table_id 表id
+     * @return bool
+     */
+    public function change(int $user_id, float $number, string $accountType = 'money', int $log_type = 0, string $remark = '', string $table = '', int $table_id = 0)
+    {
+        //获取小数点
+        $point = $accountType == 'money' ? 2 : 0;
+        bcscale($point);
+
+        //钱包名称
+        $wallet_name = $this->getWalletName($accountType);
+
+        //检测
+        if ($number == 0 || 0 === bccomp($number, 0)) {
+            return $this->error('交易金额:0');
+        }
+
+        //检测
+        if (!$wallet = Db::name('user_wallet')->lock(true)->where(['user_id' => $user_id])->find()) {
+            return $this->error('不存在的用户');
+        }
+
+        if (bccomp(bcadd($wallet[$accountType], $number), 0) === -1) {
+            return $this->error("{$wallet_name}余额不足!");
+        }
+
+        //钱币记录
+        $data = [
+            'user_id'      => $user_id,
+            'log_type'     => $log_type,
+            'before'       => $wallet[$accountType],
+            'change_value' => $number,
+            'remain'       => bcadd($wallet[$accountType], $number),
+            'table'        => $table,
+            'table_id'     => $table_id,
+            'remark'       => $remark,
+            'createtime'   => time(),
+            'updatetime'   => time(),
+        ];
+        //新的方式
+        $upWallet = Db::name('user_wallet')->where(['user_id' => $user_id])->update([$accountType => $data['remain']]);
+        if ($upWallet === false) {
+            return $this->error("更新账户余额失败!");
+        }
+        if (!Db::name("user_{$accountType}_log")->insertGetId($data)) {
+            return $this->error("更新财务记录失败!");
+        }
+
+        return $this->success("账户余额已更新!");
+    }
+
+    protected function success($message = '', $data = [])
+    {
+        $this->message = $message;
+        $this->data    = $data;
+        return true;
+    }
 
+    protected function error($message = '', $data = [])
+    {
+        $this->message = $message;
+        $this->data    = $data;
+        return false;
+    }
 
+    public function getMessage()
+    {
+        return $this->message;
+    }
 
+    public function getData()
+    {
+        return $this->data;
+    }
 }

+ 2 - 27
application/extra/wallet.php

@@ -4,34 +4,9 @@
  */
 return [
     'logtype' => [
-        1 => '系统调节',//gold + -
-
-
-        10 => '金币充值',//gold +
-        14 => '金币首充赠送',
-
-        15 => '提现',      //money-
-        16 => '提现拒绝返回',  //money+
-
-        21 => '收益兑换金币',//money -
-        22 => '收益兑换金币',//gold +
-
-        31 => '购买装扮消费', //gold -
-        32 => '购买关系卡', //gold -
-        33 => '购买联盟道具', //gold -
-        41 => '签到赠送金币',
-
-
-        53 => '聊天赠送礼物',//gold -
-        54 => '聊天获得礼物',//money +
-
-
-        61 => '完成个人任务',//gold +
-        63 => '邀请注册奖励',//money +
-
+        1 => '系统调节',//money + -
     ],
     'moneyname' => [
         'money'    => '余额',
-    ],
-
+    ]
 ];