Files
yycea/application/api/controller/wdsxh/activity/Verifying.php
2026-03-17 09:56:06 +08:00

318 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// +----------------------------------------------------------------------
// | 麦沃德科技赋能开发者,助力商协会发展
// +----------------------------------------------------------------------
// | Copyright (c) 20172024 www.wdsxh.cn All rights reserved.
// +----------------------------------------------------------------------
// | 沃德商协会系统并不是自由软件,不加密,并不代表开源,未经许可不可自由转售和商用
// +----------------------------------------------------------------------
// | Author: MY WORLD Team <bd@maiwd.cn> www.maiwd.cn
// +----------------------------------------------------------------------
/**
* Class Verifying
* Desc 活动核销
* Create on 2024/3/15 16:27
* Create by wangyafang
*/
namespace app\api\controller\wdsxh\activity;
use addons\wdsxh\library\Encryptor;
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 Verifying extends Api
{
protected $noNeedLogin = [''];
protected $noNeedRight = ['*'];
public function _initialize()
{
parent::_initialize();
}
/**
* Desc 核销活动列表
* Create on 2024/3/14 17:09
* Create by wangyafang
*/
public function activity_list()
{
if(!$this->request->isGet()) {
$this->error('请求类型错误');
}
$wechat_id = (new UserWechat())->where('user_id',$this->auth->id)->value('id');
$where[] = ['exp',Db::raw("FIND_IN_SET($wechat_id,verifying_wechat_ids)")];
$activityModel = new \app\api\model\wdsxh\activity\Activity();
$page = isset($param['page']) ? $param['page'] : '';
$limit = isset($param['limit']) ? $param['limit'] : 10;
$count = $activityModel->where($where)->count();
$data = $activityModel
->where($where)
->page($page,$limit)
->field('id,name,start_time,address,images,organizing_method')
->order('id desc')
->select();
$activityController = new Activity();
foreach ($data as $k=>&$v) {
$v->week = $activityController->getTimeWeek($v['start_time']);
$v->start_time = date('m/d H:i',$v->start_time);
$images = explode(',',$v->images);
$v->images = $images[0];
}
$this->success('请求成功',['total'=>$count,'data'=>$data]);
}
/**
* @notes 扫码核销
* @author wangyafang
* @date 2024/3/15 16:46
*/
public function verifying() {
if(!$this->request->isPost()) {
$this->error('请求类型错误');
}
$wechat_id = $this->request->post('wechat_id');
$activity_id = $this->request->post('activity_id');
$activityObj = (new \app\api\model\wdsxh\activity\Activity())->get($activity_id);
if (!$activityObj) {
$this->error('活动不存在');
}
if ($activityObj['state'] == '3') {
$this->error('活动已结束,无法核销');
}
if ($activityObj['is_verifying'] == '1') {
$user_id = $this->auth->id;
$admin_wechat_id = (new UserWechat())->where('user_id',$user_id)->value('id');
$verifying_wechat_ids_array = explode(',',$activityObj['verifying_wechat_ids']);
if (!in_array($admin_wechat_id,$verifying_wechat_ids_array)) {
$this->error('不是核销管理员,请在后台活动设置为核销管理员');
}
} else {
$this->error('此活动不用核销');
}
$activityApplyObj = (new \app\api\model\wdsxh\activity\ActivityApply())
->where('wechat_id',$wechat_id)
->where('activity_id',$activity_id)
->where('state','2')
->find();
if (!$activityApplyObj) {
$this->error('没有找到报名信息或者未付款,无法核销');
}
if ($activityApplyObj['is_sign_in'] == '1') {
$this->error('已核销');
}
$activityApplyObj->is_sign_in = '1';
$activityApplyObj->save();
$this->success('核销成功');
}
/**
* @notes 核销会员列表
* @author wangyafang
* @date 2024/3/15 16:57
*/
public function verifying_member_list()
{
if(!$this->request->isGet()) {
$this->error('请求类型错误');
}
$param = $this->request->get();
$where = [];
$where['apply.activity_id'] = array('eq',$param['activity_id']);
$where['apply.is_sign_in'] = array('eq',$param['is_sign_in']);
$activityApplyModel = new \app\api\model\wdsxh\activity\ActivityApply();
$page = isset($param['page']) ? $param['page'] : '';
$limit = isset($param['limit']) ? $param['limit'] : 10;
$count = $activityApplyModel->alias('apply')->where($where)->count();
$order = 'apply.id desc';
//todo 活动创建后,会员功能对外功能不可用,非会员无法报名
$data = $activityApplyModel
->alias('apply')
->where($where)
->page($page,$limit)
->field('apply.is_sign_in,wechat.nickname,wechat.avatar')
->join('wdsxh_user_wechat wechat','apply.wechat_id = wechat.id')
->order($order)
->select();
foreach ($data as &$v) {
$v->avatar = wdsxh_full_url($v->avatar);
}
$this->success('请求成功',['total'=>$count,'data'=>$data]);
}
/**
* Desc 自动核销
* Create on 2025/3/8 9:34
* Create by wangyafang
*/
public function self_service_check_in()
{
if(!$this->request->isPost()) {
$this->error('请求类型错误');
}
$validate_value = $this->request->post('validate_value');
$activity_id = $this->request->post('activity_id');
$from_lng = $this->request->post('lng');
$from_lat = $this->request->post('lat');
if (empty($validate_value)) {
$this->error('validate_value参数不能为空');
}
if (empty($activity_id)) {
$this->error('activity_id参数不能为空');
}
if (empty($from_lng)) {
$this->error('纬度不能为空');
}
if (empty($from_lat)) {
$this->error('经度不能为空');
}
try {
$wechat_id = (new UserWechat())->where('user_id',$this->auth->id)->value('id');
$activityObj = (new \app\api\model\wdsxh\activity\Activity())->get($activity_id);
if (!$activityObj) {
$this->error('活动不存在');
}
if ($activityObj['state'] == '3') {
$this->error('活动已结束,无法核销');
}
if ($activityObj['is_verifying'] == '2') {
$this->error('此活动不用核销');
}
if ($activityObj['verification_method'] != 1) {
$this->error('核销方式不是自助签到,无法核销');
}
$activityApplyObj = (new \app\api\model\wdsxh\activity\ActivityApply())
->where('wechat_id',$wechat_id)
->where('activity_id',$activity_id)
->where('state','2')
->find();
if (!$activityApplyObj) {
$this->error('没有找到报名信息或者未付款,无法核销');
}
if ($activityApplyObj['is_sign_in'] == '1') {
$this->error('已核销');
}
$token_key = config('token.key');
$encryptor = new Encryptor(substr($token_key,0,16),substr($token_key,16));
if ($encryptor->encrypt($activity_id) != $validate_value) {// 验证失败,返回错误
$this->error('签到失败,请检查签到二维码是否正确');
}
$distance = $this->calculateDistance($from_lat,$from_lng,$activityObj['latitude'],$activityObj['longitude']);
if ($distance > 1000) {
$this->error('请在1000米内核销');
}
$activityApplyObj->is_sign_in = '1';
$activityApplyObj->save();
$this->success('核销成功');
} catch (ValidateException|PDOException|Exception $e) {
$this->error($e->getMessage());
}
}
/**
* Desc 计算距离
* Create on 2025/3/8 9:55
* Create by wangyafang
*/
private function calculateDistance($lat1, $lon1, $lat2, $lon2) {
$lat1 = floatval($lat1);
$lon1 = floatval($lon1);
$lat2 = floatval($lat2);
$lon2 = floatval($lon2);
// 验证经度和纬度是否在有效范围内
if ($lon1 < -180 || $lon1 > 180) {
$this->error('经度值不在有效范围内');
}
if ($lat1 < -90 || $lat1 > 90) {
$this->error('纬度值不在有效范围内');
}
if ($lon2 < -180 || $lon2 > 180) {
$this->error('经度值不在有效范围内');
}
if ($lat2 < -90 || $lat2 > 90) {
$this->error('纬度值不在有效范围内');
}
// 地球半径(单位:米)
$earthRadius = 6371000;
// 将纬度、经度从度转换为弧度
$latFrom = deg2rad($lat1);
$lonFrom = deg2rad($lon1);
$latTo = deg2rad($lat2);
$lonTo = deg2rad($lon2);
// 计算纬度和经度的差值
$latDelta = $latTo - $latFrom;
$lonDelta = $lonTo - $lonFrom;
// 使用 Haversine 公式计算距离
$angle = 2 * asin(sqrt(
pow(sin($latDelta / 2), 2) +
cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)
));
$distance = $angle * $earthRadius;
return $distance;
}
/**
* Desc 获取核销加密数据
* Create on 2025/4/17 9:58
* Create by wangyafang
*/
public function get_decrypt_data()
{
if(!$this->request->isGet()) {
$this->error('请求类型错误');
}
$validate_value = $this->request->get('validate_value');
if (empty($validate_value)) {
$this->error('validate_value参数不能为空');
}
$token_key = config('token.key');
$encryptor = new Encryptor(substr($token_key,0,16),substr($token_key,16));
$activity_id = $validate_value = $encryptor->decrypt($validate_value);
$wechat_id = (new UserWechat())->where('user_id',$this->auth->id)->value('id');
$apply_id = (new \app\api\model\wdsxh\activity\ActivityApply())->where('activity_id',$activity_id)->where('wechat_id',$wechat_id)->value('id');
if (!$apply_id) {
$apply_id = '';
}
$this->success('请求成功',array('activity_id'=>$validate_value,'apply_id'=>$apply_id));
}
}