# quickcode-server **Repository Path**: xiaoxiao88122/quickcode-server ## Basic Information - **Project Name**: quickcode-server - **Description**: 基于thinkphp6.0 的快速后台开发框架 - **Primary Language**: PHP - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2023-01-14 - **Last Updated**: 2024-06-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 介绍 项目名称:QuickCode 1.0 关键词:权限控制、代码生成、docker、vue、redis、接口防止重复提交、接口限流、日志id追踪等 > 1、运行环境要求PHP7.4+ > > 2、基于thinkphp6.0开发 > > 3、本项目是 quickcode-web的后端服务,配合食用效果最佳,配套前端项目地址为:https://github.com/johntwo/quickcode-web/tree/master # 快速开始 ## 环境要求 | 环境 | 版本 | |:--------:|:--------------:| | php | 7.4<= & <= 8.0 | | composer | 最新 | ## 安装php依赖 > composer install ## 配置环境 >1. 环境变量值和配置文件对照表 | 环境 | 配置 | 配置文件 | |:---:|:----------:|:---------------:| | 本地 | local | .env.local | | 开发 | dev | .env.dev | | 测试 | beta | .env.beta | | 生产 | production | .env.production | >2. 环境变量优先级 | 位置 | 变量名称 | 备注| 优先级| |:---:|:----------:|:---------------:|:---------------:| | 环境变量 | PHP_ENV | docker环境和原始服务器都有 |1| | nginx | APP_ENV | deploy/环境/conf/nginx/vhost.conf|2| | php.ini | PHP_ENV | deploy/环境/conf/php/php.ini|3| >3. 环境变量设置样例 docker配置 ```yaml #docker-compose 配置样例 environment: - PHP_ENV=local ``` nginx配置 ```ini ;nginx配置样例 location ~ [^/]\.php(/|$) { fastcgi_pass unix:/tmp/php74-cgi.sock; fastcgi_index index.php; include fastcgi.conf; include pathinfo.conf; fastcgi_param APP_ENV local; } ``` php.ini配置 ```ini PHP_ENV = local; ``` ## 初始化数据库 1、配置数据库信息 ```ini [DATABASE] TYPE = mysql HOSTNAME = 127.0.0.1 DATABASE = quickcode USERNAME = root PASSWORD = root HOSTPORT = 3306 CHARSET = utf8mb4 DEBUG = true prefix = qc_ ``` 2、执行初始化脚本 不同环境的执行命令 | 命令 | |:--------------------:| | php think | ```shell #以下命令会根据项目根目录下的 database 中定义的规则初始化数据库 #初始化数据库表 php think migrate:run #初始化数据库数据 php think seed:run ``` ## 接口文档 > 接口文档地址为:http://部署域名/doc ## 提示 > 本框架是一个快速开发管理后台的框架,提示一下,如果想要代码bug少,就要精简代码,减少代码冗余,相同功能的代码尽量保证只有一个调用,这样可以保证统一,按照本框架的设计思路写代码,可以减少不必要的代码错误 # 基础 ## Model(模型) > 基础的增删改需要在模型里面定义好方法,非特殊情况所有相关业务都走这个方法,有利于代码的维护 | 功能 | 方法名 | | --- | ---- | | 新增 | add | | 编辑 | edit | | 删除 | del | > 字段管理请参考thinkphp6.0的官方文档,这里常用到的是只读字段$readonly ## Validate(验证器) > 接口请求的参数验证,需要用验证器,保证全局验证的统一 ## 数据库迁移 > 参照thinkphp6.0中的数据库迁移,文档地址:https://www.kancloud.cn/manual/thinkphp6_0/1118028 # 代码生成 > 基于当前模板有一套代码生成的工具,需要结合 quickcode-web项目来使用,可直接生成前后端的所有代码,你要做的就是建好表就行,有以下几件事情需要注意: > 1、需要现在数据库中先建好表 > > 2、建议只在第一次建表阶段使用代码生成,因为你选择了覆盖文件的话可能会将您的代码覆盖掉 > > 3、代码生成只会在local环境允许使用,其它环境无法使用接口 > > 4、记得代码生成之后需要删除权限树的缓存key,例如admin模块:Authority:Admin # 驱动 ## 支付驱动 (Pay) ### 微信支付 #### 配置 ```ini [pay] driver = wechat drivers-wechat-app_id = '' ;商户id drivers-wechat-mch_id = '' ;商户平台的api key drivers-wechat-key = '' ; 证书路径,退款需要指定绝对路径 drivers-wechat-cert_path = '' ; 证书路径,退款需要指定绝对路径 drivers-wechat-key_path = '' ``` #### 下单 ```php Pay::order([ 'body' => '腾讯充值中心-QQ会员充值', 'out_trade_no' => '201508061253466', 'total_fee' => 1, 'notify_url' => 'http://zktest.free.svipss.top/admin/wechat/payreceive', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 'openid' => 'oj6Mm0ZbBNBXtTggFGhVy9t0TbW4', ]); ``` #### 支付成功验证 ```php Pay::paidNotify(function($message){ // $message 是微信回调的参数,验签通过才会进入这个方法 // 自己的验证逻辑 return true;// 支付成功返回true,否则返回其他String信息即可 }); ``` #### 退款 ```php Pay::refund([ 'transaction_id'=>'4200001376202201057466511986', 'out_refund_no'=>'202103030303', 'total_fee'=>0.01, 'refund_fee'=>0.01, 'notify_url'=>'http://zktest.free.svipss.top/admin/index/refund' ]); ``` #### 退款回调 ```php Pay::refundNotify(function($message, $reqInfo, $fail){ // 其中 $message['req_info'] 获取到的是加密信息 // $reqInfo 为 message['req_info'] 解密后的信息 // 自己的验证逻辑 return true;// 支付成功返回true,否则返回其他String信息即可 }); ``` ## 小程序驱动 (Applet) ### 配置 ```ini [applet] driver = wechat drivers-wechat-appId = '' drivers-wechat-appSecret = '' ``` ### 获取用户信息 ```php Applet::getUserInfo($code); ``` ### 获取手机号码信息 ```php Applet::getUserPhoneNumber($code); ``` ### 获取access_token ```php Applet::getAccessToken(); ``` ## 验证码驱动(Captcha) ### 配置 ```php // +---------------------------------------------------------------------- // | 验证码设置 // +---------------------------------------------------------------------- return [ // 验证码类型 'type' => [ // 登录配置 'login' => [ // 长度 'length' => 6, // 过期时间 秒 'expire' => 900 ], // 注册配置 'register' => [ // 长度 'length' => 6, // 过期时间 秒 'expire' => 900 ], // 修改密码 'change-password' => [ // 长度 'length' => 6, // 过期时间 秒 'expire' => 900 ] ] ]; ``` ### 生成验证码 ```php // login 是验证码类型 17754589605 是验证码对应的key 可以是手机号码和其它任何业务需要的key // 这个方法会返回验证码,和自动按照全局配置的验证码缓存时间进行缓存 Captcha::generate('login','17754589605'); ``` ### 验证验证码 ```php // 方法无返回值,验证不通过会自动抛异常 Captcha::verify('login','17754589605',123456); ``` ## 短信驱动(Sms) ### 配置 ```ini [sms] driver = alibaba drivers-alibaba-accessKeyId= '' drivers-alibaba-accessKeySecret= '' drivers-alibaba-signName= '' drivers-tencent-secretId= '' drivers-tencent-secretKey= '' drivers-tencent-smsSdkAppId= '' drivers-tencent-signName= '' ``` ### 发送短信 ```php // tencent 驱动 Sms::send([ 'phoneNumbers'=>['17751411980'], // 手机号码,可以是数组 最多200个 'templateId'=>'1231241', // 短信模板id 'templateParam'=>['1025','10'] // 模板参数 ]); // alibaba 驱动 Sms::send([ 'phoneNumbers'=>['1775112345','13167221111'], // 手机号码,可以是数组 最多200个 'templateId'=>'SMS_209195440', // 短信模板id 'templateParam'=>['code'=>635486] // 模板参数 ]); ``` ## 公众号驱动(OfficialAccount) ### 配置 ```ini ;公众号配置 [officialaccount] driver = wechat drivers-wechat-appId = '' drivers-wechat-appSecret = '' ``` ### 推送模板消息 ```php /** * url 代表用户点击后跳转的地址 (可不传) * miniprogram 代表用户点击后跳转的小程序 (可不传) * 如果 url 和 miniprogram 字段都传,会优先跳转小程序。 */ OfficialAccount::sendTemplateMessage([ 'touser' => 'oXvp85ww3BXgwwcfVN3czlLocyuI', 'template_id' => 'J2KH7Z2Ku1SE5YhfDsLxYYq7T_CzgvhofaC9p8CMRM4', 'url' => '', 'miniprogram' => [ 'appid' => 'xxxxxxx', 'pagepath' => 'pages/xxx', ], 'data' => [ 'first' => '完善信息', 'keyword1' => '测试活动', 'keyword2' => '2022-01-15 18:00:00', 'remark' => '测试备注', ], ]); ``` ### 获取公众号对象 ```php // \EasyWeChat\OfficialAccount\Application OfficialAccount::getOfficialAccount(); ``` # 接口安全 ## 防止接口重复提交 ### 依赖环境 | 必须环境 | | ------------- | | redis 3.0以上版本 | | 框架默认缓存选择redis | | ###使用方式 | ```php /** * 只需要在路由上面增加 \app\common\middleware\UnDuplicate::class 中间件,即可自动处理数据重复提交的问题 * int expire 超时时间,单位秒,不设置的话默认60s */ Route::post('Index/index$', '/admin/Index/index')->middleware(\app\common\middleware\UnDuplicate::class,['expire'=>10]); ``` ### 原理 > 访问路径、请求参数(post)一模一样的请求,在上一个请求处理完之前(默认60s,如果您的处理时长超过60s,还是会重复处理的,60s还没返回的接口是不合理的)不可再重复请求 ## 接口流控 ### 依赖环境 | 必须环境 | | ------------- | | redis 3.0以上版本 | | 框架默认缓存选择redis | ### 使用方式 ```php /** * 只需要在路由上面增加 \app\common\middleware\RateLimiting::class 中间件,接口则自动增加流控功能 * int limit 一秒内接收的相应次数,默认10次 */ Route::post('Index/index$', '/admin/Index/index')->middleware(\app\common\middleware\RateLimiting::class,['limit'=>10]); ``` ### 功能 > 同一个接口在一秒内能被访问的次数,最低1次 # Docker