当前位置: 首页 > news >正文

活动系统开发之采用设计模式与非设计模式的区别-非设计模式

1、父类Base.php

<?php
/*** 初始化控制器* User: Administrator* Date: 2022/9/26* Time: 18:00*/
declare (strict_types = 1);
namespace app\controller;
use app\model\common\Token;
use app\BaseController;
use app\BaseError;
use OpenSSL\Encrypt;
use app\model\permission\Role;
use app\model\permission\Menu;
use Redis\Redis;
use app\model\param\Notice as NoticeModel;class Base extends BaseController
{protected $user_id = 0;//用户编号,整个系统内部使用protected $account_avatar = '';//登录用户的头像protected $account_note = '';//登录用户的描述protected $account = '';//登录用户的登录名称protected $key = '';//登录用户权限组标识protected $frontend_butt_list = [];//前端页面权限protected $role_id = '';//登录用户的权限编号protected $rules = [];//登录用户的权限组,内部使用protected $adress_code = [];//管理员地址protected $isUnserialize = true;protected $token = '';//唯一值public function initialize(){parent::initialize(); // TODO: Change the autogenerated stub$this->isLoginAuth();//判断是否登录}//登录验证及其延长登录private function isLoginAuth(){$headInfo = $this->request->header();if(!isset($headInfo['authorization']))throw new BaseError('非法操作!');if(empty($headInfo['authorization']))throw new BaseError('操作异常!');$tokenValue = explode('|', Encrypt::getEncrypt($headInfo['authorization']));//解密 --转换tokenif(count($tokenValue) != 2)throw new BaseError('登录认证权限错误',50034,200);$token = sha1(sha1($tokenValue[0]).strtotime($tokenValue[1]));$res = Token::setToken($token, $headInfo['authorization']);if($res['status'] === false)throw new BaseError($res['info'],50034,200);//赋值错误信息$this->user_id = $res['data']['admin_id'];$this->account_note = $res['data']['account_note'];$this->account_avatar = $res['data']['account_avatar'];$this->account = $res['data']['account'];$this->role_id = $res['data']['role_id'];$this->token = $token;}//验证权限protected function checkRoleMenu($auth){if(empty($this->rules) || empty($this->key) || count($this->frontend_butt_list) == 0) $this->setAuth();if(!in_array($auth, $this->frontend_butt_list))throw new BaseError("权限不足,请联系管理员",50000,200);//赋值错误信息 权限验证}//获取权限protected function getRoleMenu(){if(empty($this->rules) || empty($this->key) || count($this->frontend_butt_list) == 0) $this->setAuth();$data['rules'] = $this->rules;$data['key'] = $this->key;$data['adress_code'] = $this->adress_code;$data['frontend_butt_list'] = $this->frontend_butt_list;return $data;}//设置权限protected function setAuth(){$resRole = Role::dataFind(['id' => $this->role_id],'key,rules,adress_code,status',true);if(empty($resRole) || $resRole['status'] !== 1) throw new BaseError("该用户没有权限",50000,200);//赋值错误信息$rules = explode(',',$resRole['rules']);$frontendButtList = Redis::select(config('cache.stores.redis.cache_db'))->get('platform_frontend_butt_list'.$this->user_id);if(empty($frontendButtList)){$this->isUnserialize = false;$list = Menu::getAll([['id', 'in', $rules], ['status', '=', 1], ['button_type', 'in', [0,1,2,3,4,5]]], 'name','sort DESC,id DESC');if(empty($list))throw new BaseError("该用户没有权限",50000,200);//赋值错误信息$frontendButtList = array_column($list,'name');Redis::select(config('cache.stores.redis.cache_db'))->setex('platform_frontend_butt_list'.$this->user_id,rand(40,80),serialize($frontendButtList));}$this->rules = $rules;$this->key = $resRole['key'];$this->adress_code = json_decode($resRole['adress_code'],true);$this->frontend_butt_list = $this->isUnserialize == true ? unserialize($frontendButtList) : $frontendButtList;}
}

2、模板Template.php

<?php
/*** 模板控制管理*/
namespace app\controller\anxun\admin\activity;
use app\controller\Base;
use app\model\anxun\activity\Template as TemplateModel;
use app\model\anxun\activity\TemplateAnswer as TemplateAnswerModel;
use app\model\anxun\activity\TemplateGame as TemplateGameModel;
use app\model\anxun\activity\TemplatePic as TemplatePicModel;
use app\model\anxun\activity\Activity as ActivityModel;
use app\model\anxun\activity\ActivityFlow as ActivityFlowModel;class Template extends Base
{//   - 支持编辑、启用、禁用、查看链接操作//   - 编辑:若有正在进行中的活动关联了此模板则无法进行编辑//   - 禁用:若有正在进行中的活动关联了此模板则无法进行禁用//   - 查看链接:只有下载图片模板类型有此功能//获取数据public function getList(){$param = $this->request->param();$title = $this->request->param('title');$type = $this->request->param('type');$status = $this->request->param('status');$where = [];if(!empty($title))$where[] = ['title','like','%'.$title.'%'];if(!empty($type))$where[] = ['type','=',$type];if(in_array($status,['0','1']))$where[] = ['status','=',$status];$resList = TemplateModel::getList($where, 'id,title,type,is_ban,template_traffic,status',[$param['currentPage'], $param['currentSize']]);$list = $resList['info'];/*if($list){foreach ($list as $k => $v) {$list[$k]['is_ban'] = $this->check($v['id']);}}*/$res['list'] = $list;$res['meat'] = $resList['page'];return success($res);}//获取所有数据public function getAll(){$where = [];$where[] = ['status','=',1];$type = $this->request->param('type');if(!empty($type))$where[] = ['type','=',$type];$list = TemplateModel::getAll($where,'id,title','id asc');return success($list);}// 详情public function getInfo(){$id = $this->request->param('id');//接收参数if(empty($id)) return error('主键不能为空');$row =  TemplateModel::dataFind(['id' => $id], 'id,title,type,status');if(empty($row)) return error('数据不存在');if($row['type'] == 1){$enswer_row = TemplateAnswerModel::dataFind(['template_id' => $id],'answer_number,solve_number,is_resetting');if(!$enswer_row) return error('答题数据不存在');$row['answer_number'] = $enswer_row['answer_number'];$row['solve_number'] = $enswer_row['solve_number'];$row['is_resetting'] = $enswer_row['is_resetting'];}elseif($row['type'] == 2){$pic_row = TemplatePicModel::dataFind(['template_id' => $id],'type_pic,copywriting,pics');if(!$pic_row) return error('图片数据不存在');$row['type_pic'] = $pic_row['type_pic'];$row['copywriting'] = json_decode($pic_row['copywriting'],true);$row['pics'] = json_decode($pic_row['pics'],true);}else{$game_row = TemplateGameModel::dataFind(['template_id' => $id],'answer_number,solve_number');if(!$game_row) return error('数据不存在');}return success($row);}//添加数据public function saveInfo(){$param = $this->request->param();//接收参数// 模板基础验证$validate = new \app\validate\anxun\admin\activity\Template;if (!$validate->check($param)) return error($validate->getError());//验证参数// 答题验证if($param['type'] == 1){$validate = new \app\validate\anxun\admin\activity\TemplateAnswer;if (!$validate->check($param)) return error($validate->getError());//验证参数}elseif($param['type'] == 2){// 图片验证$validate = new \app\validate\anxun\admin\activity\TemplatePic;if (!$validate->check($param)) return error($validate->getError());//验证参数}$where = [];$time = date('Y-m-d H:i:s', time());$data = ['title' => $param['title'],'type' => $param['type'],'status' => $param['status'],];if($param['id'] == 0){$data['create_time'] = $time;$data['update_time'] = $time;}else{if($this->check($param['id'])){return error('禁止操作,有进行中的活动');}// 删除模板类型TemplateAnswerModel::dataDetele(['template_id' => $param['id']]);TemplateAnswerModel::dataDetele(['template_id' => $param['id']]);TemplateGameModel::dataDetele(['template_id' => $param['id']]);$where = ['id' => $param['id'],];}// 保存基础活动模板$id = TemplateModel::save($data,$where);// 答题if($param['type'] == 1){$answer_data = ['template_id' => $id,'answer_number' => $param['answer_number'],'solve_number' => $param['solve_number'],'is_resetting' => $param['is_resetting'],'create_time' => $time,'update_time' => $time,];TemplateAnswerModel::save($answer_data);// 图片}elseif($param['type'] == 2){$pic_data = ['template_id' => $id,'type_pic' => $param['type_pic'],'copywriting' => json_encode($param['copywriting']),'pics' => json_encode($param['pics'],JSON_UNESCAPED_UNICODE),'create_time' => $time,'update_time' => $time,];TemplatePicModel::save($pic_data);}else{$game_data = ['template_id' => $id,'answer_number' => 1,'solve_number' => 1,'create_time' => $time,'update_time' => $time,];TemplateGameModel::save($game_data);}return success([], '操作成功');}// 修改状态public function saveStatus(){$id = $this->request->param('id');if(empty($id)) return error('主键不能为空');$row =  TemplateModel::dataFind(['id' => $id], 'status');if(empty($row)) return error('数据不存在');if($row['status'] == 1){$data = ['status' => 0,];if($this->check($id)){return error('禁止操作,有进行中的活动');}}else{$data = ['status' => 1,];}TemplateModel::save($data, ['id' => $id]);return success([],'ok');}// 检查是否支持编辑、启用、禁用、查看链接操作private function check($id){$flow_arr = ActivityFlowModel::getAll(['template_id' => $id],'activity_id');if($flow_arr){$where = [];$where[] = ['status','=',1];$where[] = ['start_time','<=',date('Y-m-d H:i:s')];$where[] = ['end_time','>=',date('Y-m-d H:i:s')];$where[] = ['id','in',array_column($flow_arr,'activity_id')];$ret = ActivityModel::dataFind($where,'id');if($ret) return true;}return false;}
}

3、活动Activity.php

<?php
/*** 活动管理*/
namespace app\controller\anxun\admin\activity;
use app\controller\Base;
use app\model\anxun\activity\Activity as ActivityModel;
use app\model\anxun\activity\ActivityFlow as ActivityFlowModel;
use app\model\anxun\activity\Template as TemplateModel;class Activity extends Base
{protected $php_max_date = '9999-12-31 00:00:00';//获取所有数据public function getList(){$param = $this->request->param();$name = $this->request->param('name');$activity_status = $this->request->param('activity_status');$status = $this->request->param('status');$where = [];if(!empty($name))$where[] = ['name','like','%'.$name.'%'];if(in_array($status,['0','1']))$where[] = ['status','=',$status];// 活动状态 1=进行中,2=已结束,3=未开始if($activity_status == 1){$where[] = ['start_time','<=',date('Y-m-d H:i:s')];$where[] = ['end_time','>=',date('Y-m-d H:i:s')];}elseif($activity_status == 2){$where[] = ['end_time','<',date('Y-m-d H:i:s')];}elseif($activity_status == 3){$where[] = ['start_time','>',date('Y-m-d H:i:s')];}$resList = ActivityModel::getList($where, 'id,name,title,start_time,end_time,update_time,status,attend_count,attend_complete_count',[$param['currentPage'], $param['currentSize']]);$info  =  $resList['info'];if($info){$time = time();foreach ($info as $k => $v) {if($v['end_time'] == $this->php_max_date) $info[$k]['end_time'] = '';$info[$k]['activity_status'] = '';$info[$k]['template_str'] = '';// $info[$k]['attend_count'] = 0;// $info[$k]['attend_complete_count'] = 0;$flow_arr = ActivityFlowModel::getAll(['activity_id' => $v['id']], 'template_id');if($flow_arr){$template_ids = array_column($flow_arr,'template_id');$template_all = TemplateModel::getAll([['id','in',$template_ids]]);if($template_all){$template_titile_arr = array_column($template_all,'title');$info[$k]['template_str'] = implode(',',$template_titile_arr);}}// - 进行中-启用(活动已经开始且状态为启用):编辑、禁用和查看链接操作// - 已结束-启用(到了活动结束时间且状态为启用):查看、禁用和查看链接操作// - 未开始-启用(未到活动开始时间且状态为启用):查看、编辑和查看链接操作// - 进行中-禁用(活动已经开始且状态为禁用):编辑、启用和查看链接操作// - 已结束-禁用(到了活动结束时间且状态为禁用):查看、启用和查看链接操作// - 未开始-禁用(未到活动开始时间且状态为禁用):查看、启用和查看链接操作$start_time = strtotime($v['start_time']);$end_time = strtotime($v['end_time']);// $status = $v['status'];if($time >= $start_time && $time <= $end_time){$activity_status = 1;}elseif( $time > $end_time){$activity_status = 2;}elseif($time < $start_time){$activity_status = 3;}$info[$k]['activity_status'] = $activity_status;unset($info[$k]['flow_json']);}}$res['list'] = $info;$res['meat'] = $resList['page'];return success($res);}// 详情public function getInfo(){$id = $this->request->param('id');//接收参数if(empty($id)) return error('主键不能为空');$row =  ActivityModel::dataFind(['id' => $id], 'id,name,title,status,is_activity_home,start_time,end_time,notes');if(empty($row)) return error('数据不存在');if($row['end_time'] == $this->php_max_date){$row['end_time'] = '';}$row['flow_json'] = [];$flow_json = ActivityFlowModel::getAll(['activity_id' => $id], 'id,activity_id,template_type,template_id');if($flow_json){$row['flow_json'] = $flow_json;}$time = time();if(strtotime($row['start_time']) > $time){$row['activity_status'] = 3;}elseif (!empty($row['end_time']) && strtotime($row['end_time']) < $time){$row['activity_status'] = 2;}else{$row['activity_status'] = 1;}return success($row);}//添加数据public function saveInfo(){$param = $this->request->param();//接收参数// 模板基础验证$validate = new \app\validate\anxun\admin\activity\Activity;if (!$validate->check($param)) return error($validate->getError());//验证参数$where = [];$time = date('Y-m-d H:i:s', time());$data = ['name' => $param['name'],'title' => $param['title'],'start_time' => $param['start_time'] ?: $time,'end_time' => $param['end_time'] ?: $this->php_max_date,'notes' => $param['notes'],'status' => $param['status'],'is_activity_home' => (int)$param['is_activity_home'],];if($param['id'] == 0){$data['create_time'] = $time;$data['update_time'] = $time;}else{$where = ['id' => $param['id'],];}// 保存基础活动模板$id = ActivityModel::save($data,$where);// 先删除活动流程ActivityFlowModel::dataDetele(['activity_id' => $id]);// 保存活动流程foreach ($param['flow_json'] as $k => $v) {$flow_data[] = ['activity_id' => $id,'template_type' => $v['template_type'],'template_id' => $v['template_id'],'create_time' => $time,'update_time' => $time,];}ActivityFlowModel::saveAll($flow_data);return success([], '操作成功');}// 修改状态public function saveStatus(){$id = $this->request->param('id');if(empty($id)) return error('主键不能为空');$row =  ActivityModel::dataFind(['id' => $id], 'status');if(empty($row)) return error('数据不存在');if($row['status'] == 1){$data = ['status' => 0,];}else{$data = ['status' => 1,];}ActivityModel::save($data, ['id' => $id]);return success([],'ok');}
}

4、素材图库MaterialWarehouse.php

<?php
/*** 素材图库控制* User: 龙哥·三年风水* Date: 2024/8/27* Time: 17:55*/
namespace app\controller\anxun\admin\activity;
use app\controller\Base;
use app\model\anxun\activity\MaterialWarehouse as AAMWModel;
class MaterialWarehouse extends Base
{// 列表public function getList(){$param = $this->request->param();$where[] = ['file_category','=',1];if(!empty($param['primary_file_name']))$where[] = ['primary_file_name','like','%'.$param['primary_file_name'].'%'];if(!empty($param['file_name_type']))$where[] = ['file_name_type','=',$param['file_name_type']];$resList = AAMWModel::getList($where, 'id,primary_file_name,file_name_type,file_name_size,encryption_file_name,update_time,status,url,create_time',[$param['currentPage'], $param['currentSize']]);$list  =  $resList['info'];$res['list'] = $list;$res['meat'] = $resList['page'];return success($res);}// 所有public function getAll(){$param = $this->request->param();$where[] = ['file_category','=',1];$where[] = ['status','=',1];if(!empty($param['primary_file_name']))$where[] = ['primary_file_name','like','%'.$param['primary_file_name'].'%'];if(!empty($param['file_name_type']))$where[] = ['file_name_type','=',$param['file_name_type']];$resList = AAMWModel::getList($where, 'id,primary_file_name,file_name_type,url',[$param['currentPage'], $param['currentSize']]);$list  =  $resList['info'];$res['list'] = $list;$res['meat'] = $resList['page'];return success($res);}// 详情public function getInfo(){$id = $this->request->param('id',0);if(empty($id)) return error('主键不能为空');$data = AAMWModel::dataFind([['id','=',$id]],'id,primary_file_name,file_name_type,file_name_size,encryption_file_name,status,url',true);return success($data);}// 保存public function saveInfo(){$param = $this->request->param();$validate = new \app\validate\anxun\admin\activity\MaterialWarehouse;if (!$validate->check($param)) return error($validate->getError());//验证参数$where = empty($param['id']) ? [] : ['id' => $param['id']];$data['primary_file_name'] = $param['primary_file_name'];$data['file_name_type'] = $param['file_name_type'];$data['file_name_size'] = $param['file_name_size'];$data['encryption_file_name'] = $param['encryption_file_name'];$data['url'] = $param['url'];$data['file_category'] = isset($param['file_category']) ? $param['file_category'] : 1;$data['status'] = $param['status'];$data['update_time'] = date('Y-m-d H:i:s',time());if(empty($param['id']))$data['create_time'] = date('Y-m-d H:i:s',time());AAMWModel::save($data,$where);return success([],"操作成功");}// 启禁用public function saveStatus(){$param = $this->request->param();AAMWModel::save(['status' => $param['status']],['id' => $param['id']]);return success([],"操作成功");}
}

5、添加问题及选项内容Question.php

<?php
/*** 高校资料库问题库* User: 龙哥·三年风水* Date: 2024/9/4* Time: 10:08*/
namespace app\controller\anxun\admin\activity;
use app\controller\Base;
use app\model\anxun\QuestionBank as AQBModel;
use app\model\anxun\QuestionOpt as AQOModel;
use app\model\anxun\QuestionPrize as AQPModel;
use PhpOffice\PhpSpreadsheet\IOFactory;
use think\facade\Filesystem;
class Question extends Base
{// 列表public function getList(){$param = $this->request->param();$where = [];if(!empty($param['title']))$where[] = ['title','like','%'.$param['title'].'%'];if(!empty($param['id']))$where[] = ['id','=',$param['id']];if(!empty($param['status']))$where[] = ['status','=',$param['status'] == 1 ? 1 : 0];$resList = AQBModel::getList($where, 'id,title,option_number,status,create_time,update_time',[$param['currentPage'], $param['currentSize']]);$list  =  $resList['info'];$res['list'] = $list;$res['meat'] = $resList['page'];return success($res);}// 所有public function getAll(){$param = $this->request->param();$where = [];if(!empty($param['title']))$where[] = ['title','like','%'.$param['title'].'%'];$list = AQBModel::getAll($where, 'id,title','id DESC');return success($list);}// 详情public function getInfo(){$id = $this->request->param('id',0);if(empty($id)) return error('主键不能为空');$data = AQBModel::dataFind([['id','=',$id]],'id,title,status',true);if(!empty($data))$data['quest_opt'] = AQOModel::getAll(['bank_id' =>  $id],'content,is_correct','id DESC');return success($data);}// 保存public function saveInfo(){$param = $this->request->param();$validateBank = new \app\validate\anxun\admin\activity\QuestionBank;if (!$validateBank->check($param)) return error($validateBank->getError());//验证参数$validateOpt = new \app\validate\anxun\admin\activity\QuestionOpt;$dataOpt = [];foreach($param['quest_opt'] as $k => $v){$dataOpt[$k]['content'] = $v['content'];$dataOpt[$k]['is_correct'] = $v['is_correct'];if (!$validateOpt->check($dataOpt[$k])) return error($validateOpt->getError());//验证参数$dataOpt[$k]['opt'] = question_bank($k);}if(count($dataOpt) < 2) return error('题目选项最低两个选项');//验证参数$where = empty($param['id']) ? [] : ['id' => $param['id']];$data['title'] = $param['title'];$data['status'] = $param['status'];$data['update_time'] = date('Y-m-d H:i:s',time());$data['option_number'] = count($dataOpt);if(empty($param['id']))$data['create_time'] = date('Y-m-d H:i:s',time());$bankId = AQBModel::save($data,$where);if($param['id'] > 0)AQOModel::dataDetele(['bank_id' => $bankId]);foreach ($dataOpt as $ks => $vs){$dataOpt[$ks]['bank_id'] = $bankId;}AQOModel::dataAllSave($dataOpt);return success([],"操作成功");}// 启禁用public function saveStatus(){$param = $this->request->param();AQBModel::save(['status' => $param['status']],[['id','in',$param['id']]]);return success([],"操作成功");}//获取奖品信息public function getPrizeInfo(){$data = AQPModel::dataFind(['id' => 1],'prize_name,prize_price,postage_price,prize_picture,status',true);return success($data);}//保存产品信息public function savePrizeInfo(){$param = $this->request->param();$validateBank = new \app\validate\anxun\admin\activity\QuestionPrize;if (!$validateBank->check($param)) return error($validateBank->getError());//验证参数$data['prize_name'] = $param['prize_name'];$data['prize_price'] = $param['prize_price'];$data['postage_price'] = $param['postage_price'];$data['prize_picture'] = $param['prize_picture'];$data['status'] = $param['status'];$data['update_time'] = date('Y-m-d H:i:s',time());AQPModel::save($data,['id' => 1]);return success([],"操作成功");}//导入答题public function saveImportInfo(){$file = $this->request->file();$savename = Filesystem::disk('public')->putFile('topic',$file['file'],'md5');$reader = IOFactory::createReader('Xlsx');$reader->setReadDataOnly(true);$filePath = app()->getRootPath().'public/storage/'.$savename;$spreadsheet=$reader->load($filePath);//载入文件$worksheet=$spreadsheet->getActiveSheet();$highestRow=$worksheet->getHighestRow();//总行数for($row=2;$row<=$highestRow;$row++){$questionOpt[$row] = array_filter(explode('|', $worksheet->getCellByColumnAndRow(2, $row)->getValue()), 'remove_empty_values', ARRAY_FILTER_USE_BOTH);$questionOpt[$row] = remove_array_values($questionOpt[$row]);if(count($questionOpt[$row]) < 2)continue;$title[$row] = trim($worksheet->getCellByColumnAndRow(1, $row)->getValue());$bankId[$row] = AQBModel::dataFind([['title','=',$title[$row]]],'id',false);if(empty($bankId[$row])){//添加题目$data[$row]['title'] = $title[$row];$data[$row]['status'] = 1;$data[$row]['option_number'] = count($questionOpt[$row]);$data[$row]['create_time'] = date('Y-m-d H:i:s', time());$data[$row]['update_time'] = date('Y-m-d H:i:s', time());$bankId[$row] = AQBModel::save($data[$row]);$correct[$row] = array_filter(explode(',', $worksheet->getCellByColumnAndRow(3, $row)->getValue()), 'remove_empty_values', ARRAY_FILTER_USE_BOTH);//添加选项foreach($questionOpt[$row] as $k => $v) {$da[$row.$k]['bank_id'] = $bankId[$row];$da[$row.$k]['opt'] = question_bank($k);$da[$row.$k]['content'] = trim($v);foreach ($correct[$row] as $ko => $vo) {$da[$row.$k]['is_correct'] = $da[$row.$k]['opt'] == trim($vo) ? 1 : 0;}AQOModel::save($da[$row.$k]);}}}@unlink($filePath);return success([],'导入成功');}
}

6、前端api空Emptys.php父类

<?php
/*** 全局空处理* User: Administrator* Date: 2022/9/26* Time: 17:24*/
namespace app\controller;
use app\BaseController;
class Emptys extends BaseController
{public function index(){return error('正在开发中,敬请期待!');}
}

7、前端api模板Template.php

<?php
/*** 模板预览* User: 龙哥·三年风水* Date: 2024/8/19* Time: 17:08*/
namespace app\controller\anxun\index;
use app\controller\Emptys;
use app\model\anxun\activity\Template as TemplateModel;
use app\model\anxun\activity\TemplateAnswer as TemplateAnswerModel;
use app\model\anxun\QuestionBank;
use app\model\anxun\QuestionOpt;
use app\model\anxun\activity\TemplatePic as TemplatePicModel;
class Template extends Emptys
{// 模板列表public function getList(){$param = $this->request->param();if(empty($param['type']))return error('类型参数错误');if(empty($param['currentPage']) || empty($param['currentSize']))return error('分页参数错误');$where[] = ['status','=',1];$where[] = ['type','=',$param['type']];if(!empty($param['title']))$where[] = ['title','LIKE','%'.$param['title'].'%'];$resList = TemplateModel::getList($where,'id,title,type,is_ban,template_traffic,status',[$param['currentPage'],$param['currentSize']],'id DESC');$res['list'] = $resList['info'];$res['meat'] = $resList['page'];return success($res,'ok');}//模板详情public function getInfo(){$templateId = $this->request->param('template_id', 0);if(empty($templateId))return error('参数错误');$dataTemplate = TemplateModel::dataFind(['id' => $templateId],'id,title,type,status',true);if(empty($dataTemplate))return error('模板不存在');if($dataTemplate['status'] == 0)return error('模板已下架');if($dataTemplate['type'] == 1){$dataTemplateAnswer = TemplateAnswerModel::dataFind(['template_id' => $templateId],'answer_number,solve_number,is_resetting',true);if(empty($dataTemplateAnswer))return error('模板不存在');$dataTemplate['answer_number'] = $dataTemplateAnswer['answer_number'];$dataTemplate['solve_number'] = $dataTemplateAnswer['solve_number'];$dataTemplate['is_resetting'] = $dataTemplateAnswer['is_resetting'];$allList = QuestionBank::getAll(['status' => 1],'id','create_time DESC');if(count($allList) == 0)return error('没有题目');$answerArr = array_rand(array_column($allList,'id'),$dataTemplateAnswer['answer_number']);$answerList = [];foreach($answerArr as $k => $v){$answerList[$k]['id'] = $v;$answerList[$k]['title'] = QuestionBank::dataFind(['id' => $v],'title',false);$answerList[$k]['opt'] = QuestionOpt::getAll(['bank_id' => $v],'opt,content,is_correct','id DESC');}$dataTemplate['list'] = $answerList;}if($dataTemplate['type'] == 2){$dataTemplatePic = TemplatePicModel::dataFind(['template_id' => $templateId],'copywriting,pics');if(empty($dataTemplatePic)) return error('没有素材');$dataTemplate['copywriting'] = json_decode($dataTemplatePic['copywriting']);$dataTemplate['list'] = json_decode($dataTemplatePic['pics'],true);}TemplateModel::setAdd(['id' => $templateId],'template_traffic');return success($dataTemplate,'ok');}
}

8、前端api活动Activity.php

<?php
/*** 活动管理* User: 龙哥·三年风水* Date: 2024/5/22* Time: 11:48*/
namespace app\controller\anxun\index;
use app\controller\Emptys;
use app\model\anxun\activity\Activity as ActivityModel;
use app\model\anxun\activity\Template as TemplateModel;
use app\model\anxun\activity\TemplatePic as TemplatePicModel;
use app\model\anxun\activity\ActivityFlow as ActivityFlowModel;
use app\model\anxun\activity\ActivityTeam as ActivityTeamModel;
use app\model\anxun\activity\ActivityTeamUser as ActivityTeamUserModel;
use app\model\anxun\activity\TemplateAnswer as TemplateAnswerModel;
use app\model\anxun\activity\TemplateGame as TemplateGameModel;use app\model\common\SmsSend as SmsSendModel;use app\model\anxun\QuestionBank;
use app\model\anxun\QuestionOpt;
use app\model\anxun\QuestionParticipantAnswer as QPAModel;
use app\model\anxun\QuestionParticipantAnswerStatistics as QPASModel;
use Redis\Redis;
use Sms\SmsFactory;class Activity extends Emptys
{protected $php_max_date = '9999-12-31 00:00:00';//活动列表public function getList(){$param = $this->request->param();$where[] = ['status','=',1];if(!empty($param['name']))$where[] = ['name','LIKE','%'.$param['name'].'%'];if(empty($param['currentPage']) || empty($param['currentSize']))return error('分页参数错误');$resList = ActivityModel::getList($where,'id,name,start_time,end_time,attend_count,attend_complete_count,is_activity_home',[$param['currentPage'],$param['currentSize']],'id DESC');$list = $resList['info'];$time = time();foreach ($list as $k => $v){if($time > strtotime($v['end_time']) && $v['end_time'] != $this->php_max_date){$list[$k]['activity_status'] = 2;}elseif ($time > strtotime($v['start_time'])){$list[$k]['activity_status'] = 1;}else{$list[$k]['activity_status'] = 3;}$list[$k]['end_time'] = $v['end_time'] == $this->php_max_date ? '' : $v['end_time'];$templateTypes[$k] = ActivityFlowModel::getAll(['activity_id' => $v['id']],'template_type','id ASC');$list[$k]['template_type'] = $templateTypes[$k][0]['template_type'];}$res['list'] = $list;$res['meat'] = $resList['page'];return success($res,'ok');}//活动首页public function getHome(){$list = [];$resList = ActivityModel::getAll(['status' => 1],'id,name,start_time,end_time,attend_count,attend_complete_count,is_activity_home','id DESC');$time = time();$i=0;foreach ($resList as $v){if(count($list) < 5){if($time > strtotime($v['end_time']) && $v['end_time'] != $this->php_max_date)continue;$list[$i] = $v;$list[$i]['activity_status'] = $time > strtotime($v['start_time']) ? 1 : 3;$list[$i]['end_time'] = $v['end_time'] == $this->php_max_date ? '' : $v['end_time'];$templateTypes[$i] = ActivityFlowModel::getAll(['activity_id' => $v['id']],'template_type','id ASC');$list[$i]['template_type'] = $templateTypes[$i][0]['template_type'];$i++;}}return success($list,'ok');}// 模板图片详情public function getTemplate(){$id = $this->request->param('id', 0);$flow_id = $this->request->param('flow_id', 0);$next_flow = [];if($id && $flow_id){$row = ActivityModel::dataFind(['id'=>$id],'id,name,title,status,start_time,end_time,attend_count,attend_complete_count');try {$this->check_statu($row);} catch (\Exception $e) {return error($e->getMessage());}$flow_arr = ActivityFlowModel::getAll(['activity_id' => $id],'id,activity_id,template_type,template_id');if(!$flow_arr) return error('流程不存在');$template_id = 0;foreach ($flow_arr as $k => $v) {if($v['id'] == $flow_id){$template_id = $v['template_id'];// 判断是否有下一个流程;if(isset($flow_arr[($k+1)])){$next_flow = $flow_arr[($k+1)];}break;}}if(!$template_id) return error('流程不存在');}else{$template_id = $this->request->param('template_id', 0);if(!$template_id) return error('参数错误');}$row = TemplateModel::dataFind(['id' => $template_id],'*');if(!$row) return error('数据不存在');if($row['status'] != 1) return error('禁止展示');if($row['type'] != 2) return error('不是图片展示类型');$pics_row = TemplatePicModel::dataFind(['template_id' => $template_id],'*');if(!$pics_row) return error('数据不存在');$data['title'] = $row['title'];$data['copywriting'] = json_decode($pics_row['copywriting'],true);$data['pics'] = json_decode($pics_row['pics'],true);$data['next_flow'] = $next_flow;return success($data,'ok');}  //获取活动状态public function getInfo(){$id = $this->request->param('id', 0);if (empty($id)) return error('主键参数必须上传');$row = ActivityModel::dataFind(['id'=>$id],'id,name,title,status,start_time,end_time,attend_count,attend_complete_count');if(!$row) return error('活动不存在');$time = time();$start_time = strtotime($row['start_time']);$end_time = strtotime($row['end_time']);if($time >= $start_time && $time <= $end_time){$activity_status = 1;}elseif( $time > $end_time){$activity_status = 2;}elseif($time < $start_time){$activity_status = 3;}$row['activity_status'] = $activity_status;if($row['end_time'] = $this->php_max_date){$row['end_time'] = '';}$flow_json = ActivityFlowModel::getAll(['activity_id' => $id], 'id,activity_id,template_type,template_id','id asc');if($flow_json){$row['flow_json'] = $flow_json;}return success($row,'操作成功');}//获取题目public function getQuestion(){$id = $this->request->param('id', 0);$flow_id = $this->request->param('flow_id', 0);if (empty($id)) return error('参数必须上传');if (empty($flow_id)) return error('参数必须上传');$row = ActivityModel::dataFind(['id'=> $id],'*');try {$this->check_statu($row);} catch (\Exception $e) {return error($e->getMessage());}// 查询活动流程$flow_arr = ActivityFlowModel::getAll(['activity_id' => $id],'id,activity_id,template_type,template_id');if(!$flow_arr) return error('流程不存在');$next_flow = [];$template_id = 0;foreach ($flow_arr as $k => $v) {if($v['id'] == $flow_id){$template_id = $v['template_id'];// 判断是否有下一个流程;if(isset($flow_arr[($k+1)])){$next_flow = $flow_arr[($k+1)];}break;}}if(!$template_id) return error('流程不存在');$flow_row = ActivityFlowModel::dataFind(['activity_id' => $id, 'template_id' => $template_id], 'id,template_type');if(!$flow_row) return error('题库不存在');if($flow_row['template_type'] == 1){$answer_row = TemplateAnswerModel::dataFind(['template_id' => $template_id],'answer_number,solve_number,is_resetting');if(!$answer_row)  return error('题库不存在');}else{$answer_row = TemplateGameModel::dataFind(['template_id' => $template_id],'answer_number,solve_number');if(!$answer_row)  return error('题库不存在');}$key = config('database.connections.anxun.prefix').'activity';$redis = Redis::select(config('cache.stores.redis.data_db_admin'));$number = $redis->smembers($key.'_pk');if(count($number) == 0){$allList = QuestionBank::getAll(['status' => 1],'id','create_time DESC');if(count($allList) == 0)return error('没有题目');foreach($allList as $v){$redis->sadd($key.'_pk',$v['id']);}}$bankList = $redis->srandmember($key.'_pk',$answer_row['answer_number']);$list = [];$statisticData['correct_rate'] = 0;$statisticData['error_rate'] = 0;$statisticData['status'] = 1;$statisticData['create_time'] = date('Y-m-d H:i:s',time());$statisticData['update_time'] = date('Y-m-d H:i:s',time());$statisticsId = QPASModel::save($statisticData,[]);foreach ($bankList as $k => $v){$list[$k]['title'] = QuestionBank::dataFind(['id' => $v],'title',false);$optList[$k] = QuestionOpt::getAll(['bank_id' => $v],'opt,content,is_correct',false);$data[$k]['bank_id'] = $v;foreach ($optList[$k] as $va){if($va['is_correct'] == 1)$data[$k]['correct_answer'] = $va['opt'];}$list[$k]['opt'] = $optList[$k];$data[$k]['statistics_id'] = $statisticsId;$data[$k]['participant_answer'] = '';$data[$k]['is_right'] = 0;$data[$k]['create_time'] = date('Y-m-d H:i:s',time());$data[$k]['update_time'] = date('Y-m-d H:i:s',time());$list[$k]['id'] = QPAModel::save($data[$k],[]);}$data_all['list'] = $list;$data_all['next_flow'] = $next_flow;$data_all['answer'] = $answer_row;return success($data_all,'操作成功');}//提交答案public function setQuestion(){$result = $this->request->param('result');if (empty($result) || count($result) != 10) return error('结果集错误');$correctRate = 0;$errorRate = 0;foreach($result as $k => $v){$correctAnswer[$k] = QPAModel::dataFind(['id' => $v['id']],'correct_answer,statistics_id',true);if(empty($correctAnswer[$k]))return error('结果集错误');if($v['participant_answer'] == $correctAnswer[$k]['correct_answer']){$data[$k]['is_right'] = 1;$correctRate++;}else{$data[$k]['is_right'] = 2;$errorRate++;}$data[$k]['participant_answer'] = $v['participant_answer'];QPAModel::save($data[$k],['id' => $v['id']]);if($k+1 == count($result)){$statisticsData['correct_rate'] = $correctRate;$statisticsData['error_rate'] = $errorRate;$statisticsData['status'] = 0;QPASModel::save($statisticsData,['id' => $correctAnswer[$k]['statistics_id']]);}}return success([],'操作成功');}// 获取活动数据public function getData(){   $id = $this->request->param('id');if(!$id) return error('参数错误');$row = ActivityModel::dataFind(['id' => $id],'title,attend_count,attend_complete_count,end_time');if(!$row) return error('活动不存在');if($row['end_time'] = $this->php_max_date){$row['end_time'] = '';}return success($row,'ok');}// 参与记录public function addLog(){// 记录type = 1 参与 ,type = 2 参与完成$id = $this->request->param('id');$type = $this->request->param('type',1);if (empty($id)) return error('参数必须上传');$row = ActivityModel::dataFind(['id'=> $id],'*');$is_save = true;try {$this->check_statu($row);} catch (\Exception $e) {if($type == 1){$is_save = false;}else{return error($e->getMessage());}}if($is_save){$data = [];if($type == 1){$data = ['attend_count' => ($row['attend_count'] + 1)];}else{$data = ['attend_complete_count' => ($row['attend_complete_count'] + 1)];}ActivityModel::save($data,['id' => $id]);}return success([],'ok');}// 团队报名public function teamSignUp(){$param = $this->request->param();$type = $this->request->param('type',1);// 模板基础验证$param['id'] = 0;$validate = new \app\validate\anxun\index\activity\Team;if (!$validate->check($param)) return error($validate->getError());//验证参数foreach ($param['arr'] as $v) {$validate = new \app\validate\anxun\index\activity\TeamUser;if (!$validate->check($v)) return error('队员的'.$validate->getError());//验证参数}if(isset($param['arr2'])){foreach ($param['arr2'] as $v) {$validate = new \app\validate\anxun\index\activity\TeamUser;if (!$validate->check($v)) return error('替补队员的'.$validate->getError());//验证参数}}// 查询活动$row = ActivityModel::dataFind(['id'=>$param['activity_id']],'id,name,title,status,start_time,end_time,attend_count,attend_complete_count');// 验证活动是否符合try {$this->check_statu($row);} catch (\Exception $e) {return error($e->getMessage());}$flow_row = ActivityFlowModel::dataFind(['activity_id' => $param['activity_id'],'template_type' => 3],'id');if(!$flow_row) return error('流程不存在');$count = ActivityTeamModel::dataNumber(['activity_id' => $param['activity_id']],'id');if($count >= 500) return error('报名团队已满,无法报名');$time = date('Y-m-d H:i:s',time());$team_data['activity_id'] = $param['activity_id'];$team_data['team_name'] = $param['team_name'];$team_data['create_time'] = $time;$team_data['update_time'] = $time;// 数据格式化$team_user_data[] = ['activity_id' => $param['activity_id'],// 'team_id' => $team_id,'type' => 1,'username' => $param['username'],'mobile' => $param['mobile'],'hero_name' => $param['hero_name'],'address' => $param['address'],'honor_name' => $param['honor_name'],];foreach ($param['arr'] as $v) {$team_user_data[] = ['activity_id' => $param['activity_id'],// 'team_id' => $team_id,'type' => 2,'username' => $v['username'],'mobile' => $v['mobile'],'hero_name' => $v['hero_name'],'address' => $v['address'],'honor_name' => $v['honor_name'],];}if(isset($param['arr2'])){foreach ($param['arr2'] as $v) {$team_user_data[] = ['activity_id' => $param['activity_id'],// 'team_id' => $team_id,'type' => 3,'username' => $v['username'],'mobile' => $v['mobile'],'hero_name' => $v['hero_name'],'address' => $v['address'],'honor_name' => $v['honor_name'],];}}// 验证团队成员手机号是否有重复$mobile_arr = array_column($team_user_data,'mobile');$mobile_arr_unique = array_unique($mobile_arr);if(count($mobile_arr) != count($mobile_arr_unique)) return error('提交的手机号有重复,请检查');//  验证该活动,团队名是否已存在$where[] = ['team_name','=',$param['team_name']];$where[] = ['activity_id','=',$param['activity_id']];$ret = ActivityTeamModel::dataFind($where,'id');if($ret) return error('团队名已存在');// 验证该活动,成员手机号是否已存在$where2[] = ['mobile','in',$mobile_arr];$where2[] = ['activity_id','=',$param['activity_id']];$ret = ActivityTeamUserModel::dataFind($where2,'id,mobile');if($ret) return error($ret['mobile'].'号码已被其它团队成员使用');if($type == 2){// 增加团队$team_id = ActivityTeamModel::save($team_data);foreach ($team_user_data as $k => $v) {$team_user_data[$k]['team_id'] = $team_id;}// 增加团队成员ActivityTeamUserModel::saveAll($team_user_data);}return success([],'ok');}// 更新团队信息public function saveTeam(){$param = $this->request->param();$code = $this->request->param('code');// 模板基础验证$validate = new \app\validate\anxun\index\activity\Team;if (!$validate->check($param)) return error($validate->getError());//验证参数foreach ($param['arr'] as $v) {$validate = new \app\validate\anxun\index\activity\TeamUser;if (!$validate->check($v)) return error('队员的'.$validate->getError());//验证参数}if(isset($param['arr2'])){foreach ($param['arr2'] as $v) {$validate = new \app\validate\anxun\index\activity\TeamUser;if (!$validate->check($v)) return error('替补队员的'.$validate->getError());//验证参数}}if(!$code) return error('验证码不能为空');$mobile = ActivityTeamUserModel::dataFind(['team_id' => $param['id']],'mobile',false);if(!$mobile) return error('团队数据不存在');$isSend = Redis::select(config('cache.stores.redis.cache_db'))->get($mobile);// if(empty($isSend))return error('没有可用的验证码');if($code != $isSend)return error('验证码不正确');// 查询活动$row = ActivityModel::dataFind(['id'=>$param['activity_id']],'id,name,title,status,start_time,end_time,attend_count,attend_complete_count');// 验证活动是否符合try {$this->check_statu($row);} catch (\Exception $e) {return error($e->getMessage());}$flow_row = ActivityFlowModel::dataFind(['activity_id' => $param['activity_id'],'template_type' => 3],'id');if(!$flow_row) return error('流程不存在');$ret = ActivityTeamModel::dataFind(['id' => $param['id']],'*');if(!$ret) return error('不存在');$team_id = $param['id'];$time = date('Y-m-d H:i:s',time());$team_data['activity_id'] = $param['activity_id'];$team_data['team_name'] = $param['team_name'];$team_data['create_time'] = $time;$team_data['update_time'] = $time;// 数据格式化$team_user_data[] = ['activity_id' => $param['activity_id'],'team_id' => $team_id,'type' => 1,'username' => $param['username'],'mobile' => $param['mobile'],'hero_name' => $param['hero_name'],'address' => $param['address'],'honor_name' => $param['honor_name'],];foreach ($param['arr'] as $v) {$team_user_data[] = ['activity_id' => $param['activity_id'],'team_id' => $team_id,'type' => 2,'username' => $v['username'],'mobile' => $v['mobile'],'hero_name' => $v['hero_name'],'address' => $v['address'],'honor_name' => $v['honor_name'],];}if(isset($param['arr2'])){foreach ($param['arr2'] as $v) {$team_user_data[] = ['activity_id' => $param['activity_id'],'team_id' => $team_id,'type' => 3,'username' => $v['username'],'mobile' => $v['mobile'],'hero_name' => $v['hero_name'],'address' => $v['address'],'honor_name' => $v['honor_name'],];}}// 验证团队成员手机号是否有重复$mobile_arr = array_column($team_user_data,'mobile');$mobile_arr_unique = array_unique($mobile_arr);if(count($mobile_arr) != count($mobile_arr_unique)) return error('提交的手机号有重复,请检查');//  验证该活动,团队名是否已存在$where[] = ['team_name','=',$param['team_name']];$where[] = ['id','<>',$team_id];$ret = ActivityTeamModel::dataFind($where,'id');if($ret) return error('团队名已存在');// 验证该活动,成员手机号是否已存在$where2[] = ['mobile','in',$mobile_arr];$where2[] = ['team_id','<>',$team_id];$ret = ActivityTeamUserModel::dataFind($where2,'id,mobile');if($ret) return error($ret['mobile'].'号码已被其它团队成员使用');// 增加团队$team_id = ActivityTeamModel::save($team_data,['id' => $param['id']]);// 先清空团队成员数据,后更新ActivityTeamUserModel::dataDetele(['team_id' => $team_id]);// 增加团队成员ActivityTeamUserModel::saveAll($team_user_data);// 更新已使用短信验证码$sms_data['status'] = 0;$sms_where[] = ['mobile', '=', $mobile];$sms_where[] = ['code', '=', $param['code']];SmsSendModel::save($sms_data, $sms_where);// 清除验证码缓存Redis::select(config('cache.stores.redis.cache_db'))->setex($mobile,1,$param['code']);return success([],'ok');}// 团队查询public function getTeam(){$activity_id = $this->request->param('activity_id');$mobile = $this->request->param('mobile');if(!$activity_id) return error('参数不正确');if(!$mobile) return error('手机号不能为空');if(!preg_match('/^1[0-9]\d{9}$/', $mobile)) return error('手机号格式不正确');$where[] = ['activity_id','=',$activity_id];$where[] = ['mobile','=',$mobile];// $where[] = ['type','=',1];$ret = ActivityTeamUserModel::dataFind($where,'*');if(!$ret) return error('不存在');$data = [];$team_data = ActivityTeamModel::dataFind(['id' => $ret['team_id']],'*');$team_user_data = ActivityTeamUserModel::getAll(['team_id' => $ret['team_id']],'*');$data['id'] = $team_data['id'];$data['activity_id'] = $team_data['activity_id'];$data['team_name'] = $team_data['team_name'];$data['username'] = '';$data['mobile'] = '';$data['hero_name'] = '';$data['address'] = '';$data['honor_name'] = '';$data['arr'] = [];// $data['arr2'] = [];foreach ($team_user_data as $k => $v) {if($v['type'] == 1){$data['username'] = $v['username'];$data['mobile'] = $v['mobile'];$data['hero_name'] = $v['hero_name'];$data['address'] = $v['address'];$data['honor_name'] = $v['honor_name'];}elseif($v['type'] == 2){$data['arr'][] = ['username' => $v['username'],'mobile' => $v['mobile'],'hero_name' => $v['hero_name'],'address' => $v['address'],'honor_name' => $v['honor_name'],];}elseif($v['type'] == 3){$data['arr2'][] = ['username' => $v['username'],'mobile' => $v['mobile'],'hero_name' => $v['hero_name'],'address' => $v['address'],'honor_name' => $v['honor_name'],];}}// 判断是否有替补数据// if(isset($data['arr2'])){//     // 判断替补数据是否一名成员,是的话,增加一名替补成员初始化格式字段//     if(count($data['arr2']) == 1){//         $data['arr2'][] = [//             'username' => '',//             'mobile' => '',//             'hero_name' => '',//             'address' => '',//             'honor_name' => ''//         ];//     }// }return success($data,'ok');}// 检测活动状态private function check_statu($row){try {if(!$row) throw new \Exception('活动不存在');if($row['status'] != 1) throw new \Exception('活动已结束');$time = time();$start_time = strtotime($row['start_time']);$end_time = strtotime($row['end_time']);if($time >= $start_time && $time <= $end_time){}else{throw new \Exception('活动未开始或已结束');}} catch (\Exception $e) {throw new \Exception($e->getMessage());}}
}

到此,活动api非设计模式已经结束,如果想看设计模式代码,请点击链接

相关文章:

活动系统开发之采用设计模式与非设计模式的区别-非设计模式

1、父类Base.php <?php /*** 初始化控制器* User: Administrator* Date: 2022/9/26* Time: 18:00*/ declare (strict_types 1); namespace app\controller; use app\model\common\Token; use app\BaseController; use app\BaseError; use OpenSSL\Encrypt; use app\model…...

JVM面试(六)垃圾收集器

目录 概述STW收集器的并发和并行 Serial收集器ParNew收集器Parallel Scavenge收集器Serial Old收集器Parallel Old收集器CMS收集器Garbage First&#xff08;G1&#xff09;收集器 概述 上一章我们分析了垃圾收集算法&#xff0c;那这一章我们来认识一下这些垃圾收集器是如何运…...

固态硬盘装系统有必要分区吗?

前言 现在的新电脑有哪一台是不使用固态硬盘的呢&#xff1f;这个好像很少很少了…… 有个朋友买了一台新的笔记本电脑&#xff0c;开机之后&#xff0c;电脑只有一个分区&#xff08;系统C盘500GB&#xff09;。这时候她想要给笔记本分区…… 这个真的有必要分区吗&#xf…...

网络安全架构师

网络安全架构师负责构建全面的安全框架&#xff0c;以保护组织的数字资产免受侵害&#xff0c;确保组织在数字化转型的同时维持强大的安全防护。 摩根大通的网络安全运营副总裁兼安全架构总监Lester Nichols强调&#xff0c;成为网络安全架构师对现代企业至关重要&#xff0c;…...

如何本地部署Ganache并使用内网穿透配置公网地址远程连接测试网络

目录 前言 1. 安装Ganache 2. 安装cpolar 3. 创建公网地址 4. 公网访问连接 5. 固定公网地址 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊如何本地部署Ganache并使用内网穿透配置公网地址远程连接测试网络&#xff0c;欢迎大家点赞 &a…...

算法岗/开发岗 实况

深信服算法岗一面 第一题 树的直径有哪些解法 两次dfs和树形dp&#xff0c;讲了一下树形dp的思路 因为我的简历写的比较少&#xff0c;所以面试官问我一些个人信息和擅长哪方面。 我说&#xff1a;ACM大一下打到大三&#xff0c;然后去考研。dp写的多一点&#xff0c;还有思维…...

Nginx跨域运行案例:云台控制http请求,通过 http server 代理转发功能,实现跨域运行。(基于大华摄像头WEB无插件开发包)

文章目录 引言I 跨域运行案例开发资源测试/生产环境,Nginx代理转发,实现跨域运行本机开发运行II nginx的location指令Nginx配置中, 获取自定义请求header头Nginx 配置中,获取URL参数引言 背景:全景监控 需求:感知站点由于云台相关操作为 http 请求,http 请求受浏览器…...

【数据分析预备】Pandas

Pandas 构建在NumPy之上&#xff0c;继承了NumPy高性能的数组计算功能&#xff0c;同时提供更多复杂精细的数据处理功能 安装 pip install pandas导入 import pandas as pdSeries 键值对列表 # 创建Series s1 pd.Series([5, 17, 3, 26, 31]) s10 5 1 17 2 3 3 26 4 31 dt…...

MATLAB-基于高斯过程回归GPR的数据回归预测

目录 目录 1 介绍 1. 1 高斯过程的基本概念 1.2 核函数&#xff08;协方差函数&#xff09; 1.3 GPR 的优点 1.4. GPR 的局限 2 运行结果 3 核心代码 1 介绍 高斯过程回归&#xff08;Gaussian Process Regression, GPR&#xff09;是一种强大的非参数贝叶斯方法&…...

欧洲国际眼科盛会,中国眼科专家周进斩获六项屈光大奖

2024年第42届欧洲白内障和屈光外科医生协会(ESCRS)大会由世界青光眼协会(WGA)、欧洲白内障和屈光外科医生协会(ESCRS)主办&#xff0c;于2024年9月6日至10日在西班牙巴塞罗那举行。 这场眼科盛会&#xff0c;汇聚了来自全球130多个国家的上万名眼科医学领域的顶尖专家、学者和临…...

MySQL——数据库的高级操作(二)用户管理(2)创建普通用户

在创建新用户之前&#xff0c;可以通过 SELECT 语句查看 mysql.user 表中有哪些用户&#xff0c;查询结果如下&#xff1a; mysql> USE mysql; Database changed mysql> SELECT Host, User, authentication_string FROM mysql.user; ----------------------------------…...

VIT论文阅读

把图片看成一个个16x16的patch堆起来的 摘要 卷积神经网络不是必备的&#xff0c;一个纯transformer表现也是非常好的 transformer&#xff1f;2500天tpu v3 介绍 大规模上预训练&#xff0c;小规模任务数据集上微调。扩大模型时候还没观察到瓶颈&#xff08;还没出现过拟合…...

Python编程入门必备:def关键字与函数参数

在Python编程中&#xff0c;函数是组织代码、实现代码复用和模块化的基础单元。通过函数&#xff0c;可以将复杂的操作封装成独立的代码块&#xff0c;提高代码的可读性和维护性。本文将详细介绍Python中函数的定义和使用&#xff0c;包括def关键字、函数参数的各种类型以及函数…...

LiveKit的agent介绍

概念 LiveKit核心概念&#xff1a; Room&#xff08;房间&#xff09;Participant&#xff08;参会人&#xff09;Track&#xff08;信息流追踪&#xff09; Agent 架构图 ​ 订阅信息流 ​ agent交互流程 客户端操作 加入房间 房间创建方式 手动 赋予用户创建房间的…...

青龙面板 升级 及其 依赖更新修复 检测and日志删除等

青龙版本升级 先关闭服务 cd qinglong目录 docker-compose down 关闭 docker pull whyour/qinglong:版本号 //版本号自行选择&#xff0c;如果是为了修复错误&#xff0c;建议版本微升&#xff0c;不然就直接latest 启动 docker-compose up -d 进入容器&#xff0…...

坐牢第三十七天(Qt)

作业&#xff1a; 使用qt做一个闹钟 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPixmap> #include <QBitmap> #include <QLabel> //标签类 #include <QLineEdit> //行编辑器类 #include <QPushBu…...

Vidu 全球首发「主体参照」新功能,一键同步角色特征;GPT-4o 实时音频项目负责人离职创业丨 RTE 开发者日报

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE&#xff08;Real-Time Engagement&#xff09; 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…...

电子地图的主要功能与应用

电子地图&#xff0c;即数字地图&#xff0c;是利用计算机技术&#xff0c;以数字方式存储和查阅的地图。它不仅继承了传统纸质地图的基本功能&#xff0c;还通过现代科技手段实现了诸多创新应用。以下是电子地图的主要功能与应用&#xff1a; 一、主要功能 快速存取与显示&…...

基于Java+SpringBoot+Vue+MySQL的西安旅游管理系统网站

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于SpringBootVue的西安旅游管理系统网站【附源码文档】、…...

简单介绍 NVIDIA推出的图形处理单元(GPU)架构“安培架构“

概念 "安培架构"&#xff08;Ampere Architecture&#xff09;是 NVIDIA 推出的一款图形处理单元&#xff08;GPU&#xff09;架构&#xff0c;它是继图灵架构之后的下一代产品。安培架构最初在2020年发布&#xff0c;以其高性能和高效率而闻名&#xff0c;广泛应用…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...