www.maiwd.cn // +---------------------------------------------------------------------- /** * Class ActivityApply * Desc 活动报名控制器 * Create on 2024/3/11 17:57 * Create by wangyafang */ namespace app\api\controller\wdsxh\activity; use addons\wdsxh\library\Wxapp; use app\api\model\wdsxh\activity\ActivityApplyRecord; use app\api\model\wdsxh\activity\Order; use app\api\model\wdsxh\activity\Refund; use app\api\model\wdsxh\member\Member; use app\api\model\wdsxh\UserWechat; use app\common\controller\Api; use think\Db; use think\Exception; use think\exception\PDOException; use think\exception\ValidateException; class ActivityApply extends Api { protected $noNeedLogin = ['index','notify']; protected $noNeedRight = ['*']; protected $model = null; protected $configObj = null; public function _initialize() { parent::_initialize(); $this->model = new \app\api\model\wdsxh\activity\ActivityApply(); $this->configObj = (new \app\admin\model\wdsxh\Config())->where('id',1)->find(); } /* * desc: 活动取消 * time: 2023-3-30 10:20 * */ public function cancel() { if(!$this->request->isPost()) { $this->error('请求类型错误'); } $id = $this->request->post('id'); $where = array( 'id'=>$id, ); $activityApplyObj = $this->model->where($where)->find(); if (!$activityApplyObj) { $this->error('活动已取消'); } $activityObj = (new \app\api\model\wdsxh\activity\Activity())->where('id',$activityApplyObj['activity_id'])->find(); if ($activityObj && $activityObj['state'] == '2') { $this->error('活动进行中,无法取消'); } if ($activityObj && $activityObj['state'] == '3') { $this->error('活动已结束,无法取消'); } $wechat_id = (new UserWechat())->where('user_id',$this->auth->id)->value('id'); if ($wechat_id != $activityApplyObj['wechat_id']) { $this->error('不是本人,无法取消'); } $result = false; Db::startTrans(); try { $result = $activityApplyObj->delete(); Db::commit(); } catch (ValidateException|PDOException|Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if(false === $result){ $this->error($activityApplyObj->getError()); } $this->success('取消成功'); } /* * desc: 活动提交 * time: 2023-3-11 18:00 * */ public function submit() { if(!$this->request->isPost()) { $this->error('请求类型错误'); } $param = $this->request->post(); $fixed_data = array(); if (isset($_POST['data']) && !empty($_POST['data'])) { $custom_content = $_POST['data']; $param['data'] = json_decode($custom_content, true); $fixed_data = $this->handle_custom_data($param['data']); } $wechat_id = (new UserWechat())->where('user_id',$this->auth->id)->value('id'); $result = $this->validate($param,'app\api\validate\wdsxh\activity\ActivityApply.apply'); if(true !== $result){ // 验证失败 输出错误信息 $this->error($result); } $activityObj = (new \app\api\model\wdsxh\activity\Activity())->where('id',$param['activity_id'])->find(); $current_date = date('Y-m-d',time()); $memberObj = (new Member())->where('wechat_id',$wechat_id) ->where('expire_time','>=',$current_date) ->find(); if ($activityObj['non_member_registration_status'] == '2' && !$memberObj) { $this->error('只有会员才能报名'); } if (!$activityObj) { $this->error('活动不存在'); } if ($activityObj['apply_time'] < time()) { $this->error('活动报名时间已过,无法报名'); } if ($activityObj['state'] == '2') { $this->error('活动进行中,无法报名'); } if ($activityObj['state'] == '3') { $this->error('活动已结束,无法报名'); } $applyObj = $this->model->where(array('wechat_id'=>$wechat_id,'activity_id'=>$param['activity_id'])) ->where('state','<>','4') ->order('id desc')->find(); if($applyObj && $applyObj['state'] == '2'){ $this->error('你已报名过了,不能重复报名'); } if($applyObj && $applyObj['state'] == '3'){ $this->error('你的报名信息正在申请退款处理,暂时无法报名'); } if (!empty($activityObj['apply_limit_number']) && $activityObj['apply_limit_number'] > 0) { $apply_count = $this->model->where('activity_id', $param['activity_id']) ->where('state',2) ->count(); if ($apply_count >= $activityObj['apply_limit_number']) { $this->error('活动报名人数已满,无法报名'); } } //is_verifying 活动是否核销:1=是,2=否 //is_sign_in 签到:1=已签到,2=未签到,3=无需签到 $is_sign_in = $activityObj['is_verifying'] == '1' ? '2' : '3'; if ($applyObj && ($applyObj['state'] == 1 || $applyObj['state'] == 4)) {//已提交报名,但未付款 if ($activityObj['apply_field_state'] == 1 && empty($applyObj['field_data'])) { $this->error('请填写报名信息'); } $apply_id = $applyObj->id; } else {//第一次报名 $apply_data = array( 'activity_id'=> $param['activity_id'], 'wechat_id' => $wechat_id, 'member_id'=>$memberObj ? $memberObj->id : 0, 'is_sign_in'=>$is_sign_in, ); if ($activityObj['apply_field_state'] == 1 && (!isset($_POST['data']) || empty($_POST['data'])) ) { $this->error('请填写报名信息'); } if (isset($_POST['data']) && !empty($_POST['data'])) { $apply_data['field_data'] = $_POST['data']; } $apply_data = array_merge($apply_data, $fixed_data); $apply_data['state'] = $activityObj['fees'] == 0.00 ? 2 : 1; $this->model->data($apply_data); $applyObj = $this->model->allowField(true)->save(); $apply_id = $this->model->id; } if ($applyObj) { $orderModel = new Order(); $activityOrderObj = $orderModel ->where(array('wechat_id'=>$wechat_id,'activity_id'=>$param['activity_id'])) ->where('paid','1') ->find(); $channel = $this->request->header('channel'); $paid = $activityObj['fees'] == 0.00 ? 2 : 1; if ($activityOrderObj) { $activityOrderObj->order_no = wdsxh_create_order(); $activityOrderObj->pay_amount = $activityObj['fees']; $activityOrderObj->channel = $channel; $activityOrderObj->paid = $paid; if ($paid == 2) { $activityOrderObj->pay_time = time(); $activityOrderObj->complete_time = date('Y-m-d H:i:s',time()); } $activityOrderObj->save(); } else { $order_data = array( 'activity_id'=> $param['activity_id'], 'apply_id'=> $apply_id, 'wechat_id' => $wechat_id, 'member_id'=>$memberObj ? $memberObj->id : 0, 'order_no'=> wdsxh_create_order(), 'pay_amount'=>$activityObj['fees'], 'channel'=>$channel, 'paid'=>$paid, ); if ($paid == 2) { $order_data['pay_time'] = time(); $order_data['complete_time'] = date('Y-m-d H:i:s',time()); } $orderModel->data($order_data); $orderModel->allowField(true)->save(); $activityOrderObj = $orderModel; } $applyObj = $this->model->get($apply_id); $applyObj->is_sign_in = $is_sign_in; $applyObj->save(); if($paid == 2){//不付钱 $avtivity_apply_record_data = array( 'activity_id'=> $param['activity_id'], 'wechat_id' => $wechat_id, 'member_id'=>$memberObj ? $memberObj->id : 0, ); $avtivityApplyRecordModel = new ActivityApplyRecord(); $avtivityApplyRecordModel->data($avtivity_apply_record_data); $avtivityApplyRecordModel->allowField(true)->save(); $this->zero_pay($activityObj , $wechat_id , $channel); } else{//微信支付 $this->wx_pay($activityOrderObj , $wechat_id , $channel); } } else { $this->error('创建订单失败'); } } private function zero_pay($activityObj = [] , $wechat_id = '' ,$channel = 1) { $address = $activityObj['organizing_method'] == '1' ? $activityObj['url'] : $activityObj['address']; if ($channel == 1) { //活动报名成功通知 try{ $conf=$this->configObj; $data=[ 'thing1'=>[ 'value'=>$activityObj['name'], ], 'amount3'=>[ 'value'=>$activityObj['fees'], ], 'thing6'=>[ 'value'=>$address, ], 'date7'=>[ 'value'=>date('Y年m月d日 H:i',$activityObj['start_time']), ], 'phone_number8'=>[ 'value'=>$activityObj['mobile'], ] ]; $result = Wxapp::subscribeMessage($conf['applet_activity_apply'],trim(wdsxh_get_openid($wechat_id,$channel)),'/pagesActivity/index/details?id='.$activityObj['id'],$data); }catch (\think\Exception $e){ $this->error($e->getMessage()); } } else {//todo公众号逻辑 } $this->success('报名成功'); } private function wx_pay($activityOrderObj = [] , $wechat_id = '' ,$channel = 1) { if ($channel == 1) {//小程序支付 try{ $openid = wdsxh_get_openid($wechat_id,$channel); $conf=Wxapp::unify('商会活动报名',$activityOrderObj->order_no,$activityOrderObj->pay_amount,$openid,request()->domain().'/api/wdsxh/activity/activity_apply/notify'); }catch (Exception $e){ $this->error($e->getMessage()); } $this->success('报名成功',$conf); } else {//todo 公众号支付 try{ $openid = wdsxh_get_openid($wechat_id,$channel); $conf=Wxapp::unify_wxofficial('商会活动报名',$activityOrderObj->order_no,$activityOrderObj->pay_amount,$openid,request()->domain().'/api/wdsxh/activity/activity_apply/notify'); }catch (Exception $e){ $this->error($e->getMessage()); } $this->success('报名成功',$conf); } } /* * desc: 活动支付回调处理 * time: 2023-3-11 18:00 * */ public function notify() { $pay = Wxapp::getPay(); $response = $pay->handlePaidNotify(function($message, $fail){ $orderObj = Order::where('order_no',$message['out_trade_no'])->find(); if (!$orderObj || $orderObj['paid'] == '2') { return true; } if ($message['return_code'] === 'SUCCESS') { if ($message['result_code'] === 'SUCCESS') { $avtivity_apply_record_data = array( 'activity_id'=> $orderObj['activity_id'], 'wechat_id' => $orderObj['wechat_id'], 'member_id'=>$orderObj['member_id'], ); $avtivityApplyRecordModel = new ActivityApplyRecord(); Db::startTrans(); try { $orderObj['pay_time'] = time(); $orderObj['paid'] = '2'; $orderObj->trade_no = $message['transaction_id']; $orderObj->save(); //处理活动报名 //todo 活动创建后,会员功能对外功能不可用,非会员无法报名 删除where条件 $applyObj = $this->model->where(array('wechat_id'=>$orderObj['wechat_id'],'activity_id'=>$orderObj['activity_id'])) ->where('state','1') ->find(); $applyObj->state = '2'; $applyObj->save(); $avtivityApplyRecordModel->data($avtivity_apply_record_data); $avtivityApplyRecordModel->allowField(true)->save(); Db::commit(); } catch (ValidateException|PDOException|Exception $e) { Db::rollback(); $this->error($e->getMessage()); } $activityObj = (new \app\api\model\wdsxh\activity\Activity())->get($orderObj['activity_id']); $address = $activityObj['organizing_method'] == '1' ? $activityObj['url'] : mb_substr($activityObj['address'],0,20); //活动报名成功通知 try{ $conf=$this->configObj; $data=[ 'thing1'=>[ 'value'=>mb_substr($activityObj['name'],0,20), ], 'amount3'=>[ 'value'=>$orderObj['pay_amount'], ], 'thing6'=>[ 'value'=>$address, ], 'date7'=>[ 'value'=>date('Y年m月d日 H:i',$activityObj['start_time']), ], 'phone_number8'=>[ 'value'=>$activityObj['mobile'], ] ]; $result = Wxapp::subscribeMessage($conf['applet_activity_apply'],trim(wdsxh_get_openid($orderObj['wechat_id'],1)),'/pagesActivity/index/details?id='.$orderObj['activity_id'],$data); }catch (\think\Exception $e){ $this->error($e->getMessage()); } } } else { return $fail('FAIL'); } return true; }); $response->send(); } /* * desc: 删除未支付订单 * time: 2023-4-10 11:58 * */ public function del() { if(!$this->request->isPost()) { $this->error('请求类型错误'); } $id = $this->request->post('id'); $wechat_id = (new UserWechat())->where('user_id',$this->auth->id)->value('id'); $where = array( 'id'=>$id, 'wechat_id'=>$wechat_id, ); $activityApplyObj = $this->model->where($where)->find(); if (!$activityApplyObj) { $this->error('未支付已取消'); } $wechat_id = (new UserWechat())->where('user_id',$this->auth->id)->value('id'); if ($wechat_id != $activityApplyObj['wechat_id']) { $this->error('不是本人,无法取消'); } $activityOrderObj = (new Order())->where('activity_id',$activityApplyObj['activity_id']) ->where('apply_id',$id) ->where('wechat_id',$wechat_id) ->where('paid','1') ->find(); if (!$activityOrderObj) { $this->error('未支付已取消'); } $result = false; Db::startTrans(); try { $result = $activityApplyObj->delete(); $activityOrderObj->delete(); Db::commit(); } catch (ValidateException|PDOException|Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if(false === $result){ $this->error($activityApplyObj->getError()); } $this->success('删除成功'); } /* * desc: 报名活动详情 * time: 2023-6-29 9:03 * */ public function details() { if(!$this->request->isGet()) { $this->error('请求类型错误'); } try { $id = $this->request->get('id'); $apply_id = $this->request->get('apply_id'); $activity = (new \app\api\model\wdsxh\activity\Activity()) ->where('id',$id) ->field(['id', 'images', 'start_time', 'end_time', 'name', 'fees', 'state' => 'activity_state', 'contacts', 'mobile', 'organizing_method', 'url', 'address', 'longitude', 'latitude', 'content', 'refund', 'apply_time', 'activity_auth', 'is_verifying', 'verification_method', 'points_status', 'points' ]) ->find(); if (!$activity) { $this->error('活动不存在'); } $data = $activity->toArray(); // 如果活动未结束,则根据当前时间校验活动状态并更新状态 if ($data['activity_state'] < 3) { $now = time(); // 当前时间小于报名截止时间,状态流转处于:报名中 if ($now < $data['apply_time']) $data['actitity_state_trans'] = 1; // 当前时间大于等于报名截止时间小于开始时间,状态流转处于:未开始 if ($now >= $data['apply_time'] && $now < $data['start_time']) $data['actitity_state_trans'] = 2; // 当前时间大于等于开始时间小于等于结束时间,状态流转处于:进行中 if ($now >= $data['start_time'] && $now <= $data['end_time']) { $data['actitity_state_trans'] = 3; // 如果活动未结束,则根据当前时间校验活动状态并更新状态 if ($data['activity_state'] != 2) { $activity->state = $data['activity_state'] = 2; $activity->save(); } } // 当前时间大于结束时间,状态流转处于:已结束 if ($now > $data['end_time']) { $data['actitity_state_trans'] = 4; // 如果活动已结束,则根据当前时间更新状态 if ($data['activity_state'] != 3) { $activity->state = $data['activity_state'] = 3; $activity->save(); } } } else { // 活动结束,状态流转就一直处理:已结束 $data['actitity_state_trans'] = 4; } if ($data['points_status'] == 2) { unset($data['points']); } $wechat_id = (new UserWechat())->where('user_id',$this->auth->id)->value('id'); $activityObj = (new Order())->where('apply_id',$apply_id)->find(); if (!$activityObj) { $this->error('活动订单不存在'); } $activityApplyObj = (new \app\api\model\wdsxh\activity\ActivityApply()) ->where('wechat_id',$wechat_id) ->where('id',$activityObj['apply_id']) ->where('activity_id',$id) ->find(); if (!$activityApplyObj) { $this->error('报名信息不存在'); } $data['check_in_status'] = $activityApplyObj['check_in_status']; $data['pay_state'] = $activityApplyObj['state']; $data['apply_id'] = $apply_id; $activityRefundObj = (new Refund()) ->where('apply_id',$activityObj['apply_id']) ->where('activity_id',$id) ->where('wechat_id',$wechat_id) ->where('state','3') ->order('id desc') ->find(); $data['reject'] = $activityRefundObj ? $activityRefundObj['reject'] : ''; $activityApplyModel = new \app\api\model\wdsxh\activity\ActivityApply(); $data['apply_count'] = $activityApplyModel->where('activity_id', $id)->where('state',2)->count(); $apply_list = $activityApplyModel->where('activity_id', $id) ->where('state',2) ->alias('apply') ->order('apply.createtime desc') ->join('wdsxh_user_wechat member', 'member.id = apply.wechat_id') ->field('member.avatar member_avatar') ->limit(10) ->select(); if (!empty($apply_list)) { foreach ($apply_list as &$v) { $v->member_avatar = wdsxh_full_url($v->member_avatar); } } $data['apply_list'] = $apply_list; $applyObj = (new \app\api\model\wdsxh\activity\ActivityApply()) ->where('id',$apply_id) ->where('activity_id',$id) ->where('wechat_id',$wechat_id) ->find(); $data['apply_status'] = $applyObj['state'] == 2 ? 1 : 2; $data['is_sign_in'] = $applyObj['is_sign_in']; $this->success('请求成功',$data); } catch (ValidateException|PDOException|Exception $e) { $this->error($e->getMessage()); } } /** * Desc 签到(单纯签到功能不涉核销) * * @param type $param * @return type * Created by jsasg */ public function checked_in() { if(!$this->request->isGet()) { $this->error('请求类型错误'); } if (!$this->auth->isLogin()) { $this->error('请先登录'); } // 活动id $id = $this->request->get('id'); $activity = (new \app\api\model\wdsxh\activity\Activity())->where('id',$id)->find(); if (empty($activity)) { $this->error('活动不存在'); } if (3 == $activity['state'] || time() > $activity['end_time']) { $this->error('活动已结束'); } $wechat_id = (new UserWechat())->where('user_id',$this->auth->id)->value('id'); $activity_apply = $this->model->where('activity_id',$id)->where('wechat_id',$wechat_id)->find(); // 如果用户未报名,不能签到 if(empty($activity_apply)) { $this->error('您还未报名该活动'); } // 如果已签到,不能再次签到 if ('checked_in' == $activity_apply['check_in_status']) { $this->error('您已签到'); } // 设置已签到 $activity_apply->check_in_status = 'checked_in'; $activity_apply->checked_in_at = time(); if ($activity_apply->save()) { $this->success('签到成功'); } $this->error('签到失败'); } private function handle_custom_data($data) { $custom_field = array('name','mobile'); $result = array(); foreach ($data as $v) { if (in_array($v['field'], $custom_field)) { $result[$v['field']] = $v['value']; } } return $result; } }