chore: 重写初始提交(清空历史,整理后全量提交)
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
// 这是系统自动生成的公共文件
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
/**
|
||||
* Index 类
|
||||
*
|
||||
* @author ywxapp <admin@ywxapp.cn>
|
||||
*/
|
||||
class Index
|
||||
{
|
||||
|
||||
|
||||
public function index(\think\Request $request)
|
||||
{
|
||||
return json([
|
||||
'name' => 'YwxApp API',
|
||||
'version' => \think\facade\App::version(),
|
||||
'ip' => $request->ip(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\Api\Controller\V1;
|
||||
|
||||
use ywxapp\controller\ApiController;
|
||||
use ywxapp\service\RemoteService;
|
||||
use think\Request;
|
||||
|
||||
/**
|
||||
* 插件商店接口(瘦分发器,不持有市场领域逻辑):
|
||||
*
|
||||
* - 客户机模式(is_market_client()=true,ywxapp.api_url 指向中心站):
|
||||
* 经 RemoteService 代理中心站 /appmall/api/addon/*。
|
||||
* - 中心站模式(api_url 为空/指向本机):
|
||||
* 进程内委托 appmall 插件的 MarketService(订单/授权/收益/支付回调全部在插件侧)。
|
||||
* - 未安装 appmall 插件且非客户机:市场功能不可用,返回明确提示。
|
||||
*
|
||||
* 中心站领域数据(appmarket_* 表)已全部收敛到 addon/appmall,核心不再直接读写。
|
||||
*/
|
||||
class Addon extends ApiController
|
||||
{
|
||||
// notify/payResult 由支付平台回调/跳转,无需登录;info 公开
|
||||
protected $noNeedLogin = ['info', 'notify', 'payResult'];
|
||||
protected $needRight = ['*'];
|
||||
|
||||
/**
|
||||
* 中心站模式下委托的插件市场服务
|
||||
* @var \addon\appmall\service\MarketService|null
|
||||
*/
|
||||
protected $market = null;
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
if (!is_market_client() && class_exists(\addon\appmall\service\MarketService::class)) {
|
||||
$this->market = \addon\appmall\service\MarketService::instance();
|
||||
$this->market->ensureTables();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 本机为中心站但未安装市场插件时的统一出口
|
||||
*/
|
||||
protected function marketUnavailable(): \think\response\Json
|
||||
{
|
||||
return $this->result->error('市场服务不可用:本机未配置中心站地址(ywxapp.api_url),也未安装 appmall 插件', 503);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将插件领域异常转换为 Result 错误响应
|
||||
*/
|
||||
protected function marketError(\Throwable $e): \think\response\Json
|
||||
{
|
||||
$code = (int) $e->getCode();
|
||||
$code = $code >= 400 && $code < 600 ? $code : 500;
|
||||
if ($code === 404) {
|
||||
return $this->result->setStatusCode(404)->error($e->getMessage(), 404);
|
||||
}
|
||||
return $this->result->error($e->getMessage(), $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件信息(支持列表和详情)
|
||||
*/
|
||||
public function info(Request $request): \think\response\Json
|
||||
{
|
||||
if (is_market_client()) {
|
||||
return $this->remoteInfo($request);
|
||||
}
|
||||
if (!$this->market) {
|
||||
return $this->marketUnavailable();
|
||||
}
|
||||
$id = (int) $request->get('id', 0);
|
||||
if ($id > 0) {
|
||||
try {
|
||||
$data = $this->market->info($id, $this->getLoginUid($request) ?? 0);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->marketError($e);
|
||||
}
|
||||
$data['installed'] = is_dir(ADDON_PATH . ($data['addon']['name'] ?? '') . DIRECTORY_SEPARATOR);
|
||||
return $this->result->success($data, '获取成功');
|
||||
}
|
||||
$r = $this->market->lists(
|
||||
max((int) $request->get('page', 1), 1),
|
||||
(int) $request->get('per_page', 15)
|
||||
);
|
||||
$this->result->setCount($r['total']);
|
||||
return $this->result->success(['data' => $r['items']], '获取成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 轻量解析请求中的 JWT,返回用户ID(不触发完整登录副作用)
|
||||
*/
|
||||
protected function getLoginUid(Request $request): ?int
|
||||
{
|
||||
$auth = $request->header('authorization');
|
||||
if (!$auth || !str_starts_with($auth, 'Bearer ')) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
$token = \ywxapp\service\JwtService::instance()->parseAndValidate(substr($auth, 7));
|
||||
$uid = $token->claims()->get('uid');
|
||||
return $uid ? (int) $uid : null;
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起购买:创建/复用待支付订单并拉起支付(或模拟支付直接签发授权)
|
||||
*/
|
||||
public function buy(Request $request)
|
||||
{
|
||||
if (is_market_client()) {
|
||||
return $this->remoteBuy($request);
|
||||
}
|
||||
if (!$this->market) {
|
||||
return $this->marketUnavailable();
|
||||
}
|
||||
$userId = $this->auth->model->uid ?? null;
|
||||
if (empty($userId)) {
|
||||
return $this->result->setStatusCode(401)->error('请先登录后再购买');
|
||||
}
|
||||
try {
|
||||
$r = $this->market->buy(
|
||||
(int) $userId,
|
||||
(int) $request->post('addon_id'),
|
||||
(string) $request->post('method', 'alipay'),
|
||||
(string) $request->root(true)
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->marketError($e);
|
||||
}
|
||||
return $this->result->success($r['data'], $r['message']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付结果查询(前端轮询用)
|
||||
*/
|
||||
public function orderStatus(Request $request): \think\response\Json
|
||||
{
|
||||
if (is_market_client()) {
|
||||
return $this->remoteOrderStatus($request);
|
||||
}
|
||||
if (!$this->market) {
|
||||
return $this->marketUnavailable();
|
||||
}
|
||||
$userId = $this->auth->model->uid ?? null;
|
||||
if (empty($userId)) {
|
||||
return $this->result->setStatusCode(401)->error('请先登录');
|
||||
}
|
||||
try {
|
||||
$data = $this->market->orderStatus((int) $userId, (string) $request->get('trade_no'));
|
||||
} catch (\Throwable $e) {
|
||||
return $this->marketError($e);
|
||||
}
|
||||
return $this->result->success($data, '获取成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付完成落地页(支付宝 return_url 跳转,无需登录,仅展示状态)
|
||||
*/
|
||||
public function payResult(Request $request): \think\response\Json
|
||||
{
|
||||
if (is_market_client()) {
|
||||
$r = RemoteService::instance()->payResult($request->get());
|
||||
return $this->result->success($r['data'] ?? ['status' => 0], $r['message'] ?: '获取成功');
|
||||
}
|
||||
if (!$this->market) {
|
||||
return $this->marketUnavailable();
|
||||
}
|
||||
$r = $this->market->payResult((string) $request->get('out_trade_no', ''));
|
||||
return $this->result->success($r['data'], $r['message']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款 / 吊销授权(买家或运营)
|
||||
* POST /api/v1/addon/refund {trade_no 或 order_id}
|
||||
*/
|
||||
public function refund(Request $request): \think\response\Json
|
||||
{
|
||||
if (is_market_client()) {
|
||||
return $this->remoteRefund($request);
|
||||
}
|
||||
if (!$this->market) {
|
||||
return $this->marketUnavailable();
|
||||
}
|
||||
$userId = $this->auth->model->uid ?? null;
|
||||
if (empty($userId)) {
|
||||
return $this->result->setStatusCode(401)->error('请先登录');
|
||||
}
|
||||
try {
|
||||
$r = $this->market->refund(
|
||||
(int) $userId,
|
||||
(string) $request->post('trade_no', ''),
|
||||
(int) $request->post('order_id', 0)
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->marketError($e);
|
||||
}
|
||||
return $this->result->success($r['data'], $r['message']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的已购插件(买家视角):列出已购付费插件 + 授权状态 + 是否可退款
|
||||
*/
|
||||
public function mine(Request $request): \think\response\Json
|
||||
{
|
||||
if (is_market_client()) {
|
||||
return $this->remoteMine($request);
|
||||
}
|
||||
if (!$this->market) {
|
||||
return $this->marketUnavailable();
|
||||
}
|
||||
$userId = $this->auth->model->uid ?? null;
|
||||
if (empty($userId)) {
|
||||
return $this->result->setStatusCode(401)->error('请先登录');
|
||||
}
|
||||
return $this->result->success($this->market->mine((int) $userId), '获取成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝/微信异步回调:验签 -> 校验金额 -> 订单置已付 -> 生成授权
|
||||
*/
|
||||
public function notify()
|
||||
{
|
||||
if (is_market_client()) {
|
||||
return response(RemoteService::instance()->notify(input()));
|
||||
}
|
||||
if (!$this->market) {
|
||||
return response('fail');
|
||||
}
|
||||
return $this->market->notify((string) input('method', 'alipay'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户下载已购插件(需登录 + 有效授权 + 次数限制)
|
||||
*/
|
||||
public function download(Request $request)
|
||||
{
|
||||
if (is_market_client()) {
|
||||
return $this->remoteDownload($request);
|
||||
}
|
||||
if (!$this->market) {
|
||||
return $this->marketUnavailable();
|
||||
}
|
||||
$userId = $this->auth->model->uid ?? null;
|
||||
if (empty($userId)) {
|
||||
return $this->result->setStatusCode(401)->error('请先登录');
|
||||
}
|
||||
try {
|
||||
$r = $this->market->download((int) $userId, (int) $request->get('addon_id'), $request);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->marketError($e);
|
||||
}
|
||||
return download($r['file'], $r['filename']);
|
||||
}
|
||||
|
||||
// ============ 客户机模式(ywxapp.api_url 指向其他服务器,见 is_market_client())下的代理实现 ============
|
||||
|
||||
/**
|
||||
* 远程:插件详情 / 列表(代理中心站)
|
||||
*/
|
||||
protected function remoteInfo(Request $request): \think\response\Json
|
||||
{
|
||||
$id = (int) $request->get('id', 0);
|
||||
$uid = $this->getLoginUid($request) ?? 0;
|
||||
if ($id > 0) {
|
||||
$r = RemoteService::instance()->info($id, $uid);
|
||||
if (!$r['success']) {
|
||||
return $this->result->setStatusCode(404)->error($r['message'] ?: '获取失败', 404);
|
||||
}
|
||||
$addon = $r['data']['addon'] ?? [];
|
||||
$installed = is_dir(ADDON_PATH . ($addon['name'] ?? '') . DIRECTORY_SEPARATOR);
|
||||
return $this->result->success([
|
||||
'addon' => $addon,
|
||||
'purchased' => $r['data']['purchased'] ?? false,
|
||||
'installed' => $installed,
|
||||
], '获取成功');
|
||||
}
|
||||
// 透传分页/筛选参数给中心站,由服务端完成分页(避免全量拉回后本地切片)
|
||||
$params = [
|
||||
'keyword' => $request->get('keyword', ''),
|
||||
'category' => $request->get('category', ''),
|
||||
'order' => $request->get('order', ''),
|
||||
'page' => max((int) $request->get('page', 1), 1),
|
||||
'page_size' => min(max((int) $request->get('per_page', 15), 1), 50),
|
||||
];
|
||||
$r = RemoteService::instance()->lists($params);
|
||||
if (!$r['success']) {
|
||||
return $this->result->error($r['message'] ?: '获取失败');
|
||||
}
|
||||
// 优先消费中心站服务端分页(Market::lists 在 page>0 时返回 data.list/data.total);
|
||||
// 兼容历史 data.count 键;老中心站未分页时降级为本地切片。
|
||||
if (isset($r['data']['list']) && (isset($r['data']['total']) || isset($r['data']['count']))) {
|
||||
$items = $r['data']['list'];
|
||||
$total = (int) ($r['data']['total'] ?? $r['data']['count']);
|
||||
} else {
|
||||
$rows = $r['data']['list'] ?? [];
|
||||
$perPage = min(max((int) $request->get('per_page', 15), 1), 50);
|
||||
$page = max((int) $request->get('page', 1), 1);
|
||||
$total = count($rows);
|
||||
$items = array_slice($rows, ($page - 1) * $perPage, $perPage);
|
||||
}
|
||||
$this->result->setCount($total);
|
||||
return $this->result->success(['data' => $items], '获取成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程:发起购买(代理中心站)
|
||||
*/
|
||||
protected function remoteBuy(Request $request): \think\response\Json
|
||||
{
|
||||
$userId = $this->auth->model->uid ?? null;
|
||||
if (empty($userId)) {
|
||||
return $this->result->setStatusCode(401)->error('请先登录后再购买');
|
||||
}
|
||||
$addonId = (int) $request->post('addon_id');
|
||||
$method = $request->post('method', 'alipay');
|
||||
$r = RemoteService::instance()->buy($addonId, $userId, $method);
|
||||
if (!$r['success']) {
|
||||
return $this->result->error($r['message'] ?: '购买失败');
|
||||
}
|
||||
return $this->result->success($r['data'] ?? [], $r['message'] ?: '操作成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程:订单状态(代理中心站)
|
||||
*/
|
||||
protected function remoteOrderStatus(Request $request): \think\response\Json
|
||||
{
|
||||
$tradeNo = $request->get('trade_no');
|
||||
$userId = $this->auth->model->uid ?? null;
|
||||
if (empty($userId)) {
|
||||
return $this->result->setStatusCode(401)->error('请先登录');
|
||||
}
|
||||
$r = RemoteService::instance()->orderStatus($tradeNo, $userId);
|
||||
if (!$r['success']) {
|
||||
return $this->result->error($r['message'] ?: '查询失败');
|
||||
}
|
||||
return $this->result->success($r['data'] ?? [], '获取成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程:下载已购插件(代理中心站 /appmall/api/index,付费插件需已购买)
|
||||
*/
|
||||
protected function remoteDownload(Request $request)
|
||||
{
|
||||
$userId = $this->auth->model->uid ?? null;
|
||||
if (empty($userId)) {
|
||||
return $this->result->setStatusCode(401)->error('请先登录');
|
||||
}
|
||||
$addonId = (int) $request->get('addon_id');
|
||||
$r = RemoteService::instance()->info($addonId, $userId);
|
||||
if (!$r['success']) {
|
||||
return $this->result->error($r['message'] ?: '插件信息获取失败');
|
||||
}
|
||||
$addon = $r['data']['addon'] ?? [];
|
||||
$name = $addon['name'] ?? '';
|
||||
$version = $addon['version'] ?? '';
|
||||
if ($name === '' || $version === '') {
|
||||
return $this->result->error('插件信息不完整', 404);
|
||||
}
|
||||
if (!empty($addon['price']) && (float) $addon['price'] > 0 && empty($r['data']['purchased'])) {
|
||||
return $this->result->error('您尚未购买该插件', 403);
|
||||
}
|
||||
try {
|
||||
$domain = (string) $request->domain();
|
||||
$srcFile = RemoteService::instance()->downloadBinary($name, $version, $userId, $domain);
|
||||
} catch (\Exception $e) {
|
||||
return $this->result->error($e->getMessage(), 404);
|
||||
}
|
||||
$tmpDir = root_path() . 'runtime' . DIRECTORY_SEPARATOR . 'addon_download' . DIRECTORY_SEPARATOR;
|
||||
if (!is_dir($tmpDir)) {
|
||||
@mkdir($tmpDir, 0755, true);
|
||||
}
|
||||
$tmpFile = $tmpDir . $name . '-' . $version . '.zip';
|
||||
if (is_file($srcFile)) {
|
||||
copy($srcFile, $tmpFile);
|
||||
@unlink($srcFile);
|
||||
} else {
|
||||
return $this->result->error('下载失败:未获取到文件', 404);
|
||||
}
|
||||
return new \ywxapp\library\StreamZipResponse($tmpFile, $name . '-' . $version . '.zip');
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程:退款 / 吊销授权(代理中心站)
|
||||
*/
|
||||
protected function remoteRefund(Request $request): \think\response\Json
|
||||
{
|
||||
$userId = $this->auth->model->uid ?? null;
|
||||
if (empty($userId)) {
|
||||
return $this->result->setStatusCode(401)->error('请先登录');
|
||||
}
|
||||
$r = RemoteService::instance()->refund(
|
||||
(string) $request->post('trade_no', ''),
|
||||
(int) $request->post('order_id', 0),
|
||||
$userId
|
||||
);
|
||||
if (!$r['success']) {
|
||||
return $this->result->error($r['message'] ?: '退款失败');
|
||||
}
|
||||
return $this->result->success($r['data'] ?? [], $r['message'] ?: '退款成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程:我的已购插件(代理中心站)
|
||||
*/
|
||||
protected function remoteMine(Request $request): \think\response\Json
|
||||
{
|
||||
$userId = $this->auth->model->uid ?? null;
|
||||
if (empty($userId)) {
|
||||
return $this->result->setStatusCode(401)->error('请先登录');
|
||||
}
|
||||
$r = RemoteService::instance()->my($userId);
|
||||
if (!$r['success']) {
|
||||
return $this->result->error($r['message'] ?: '获取失败');
|
||||
}
|
||||
return $this->result->success($r['data'] ?? ['list' => []], $r['message'] ?: '获取成功');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\Api\Controller\V1;
|
||||
|
||||
use think\facade\Validate;
|
||||
use ywxapp\controller\ApiController;
|
||||
use addon\articles\model\Article as ArticleModel;
|
||||
|
||||
class Article extends ApiController
|
||||
{
|
||||
protected $noNeedLogin = ['*'];
|
||||
protected $needRight = ['*'];
|
||||
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
$this->model = new ArticleModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 文章列表
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$page = $this->request->param('page/d', 1);
|
||||
$limit = $this->request->param('limit/d', 15);
|
||||
$list = $this->model->with(['category'])->page($page, $limit)->order('id', 'desc')->select();
|
||||
$this->result->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文章
|
||||
*/
|
||||
public function create(\think\Request $request)
|
||||
{
|
||||
$data = $request->post();
|
||||
if (empty($data['title'])) {
|
||||
$this->result->error('标题不能为空', 404);
|
||||
}
|
||||
$res = $this->model->create($data);
|
||||
if ($res) {
|
||||
event('article_create_after', $res);
|
||||
$this->result->success($res, '创建成功');
|
||||
}
|
||||
$this->result->error('创建失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* 文章详情
|
||||
* @route GET /detail, method:GET
|
||||
* @param int $uid 文章ID
|
||||
*/
|
||||
public function detail(\think\Request $request, int $uid= 0 ) {
|
||||
if (!$uid)
|
||||
$this->result->error('Invalid parameters', 404);
|
||||
$info = $this->model->with(['category', 'tags'])->find($uid);
|
||||
if (! $info) {
|
||||
$this->result->error('文章不存在', 404);
|
||||
}
|
||||
$this->result->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文章
|
||||
* @route PUT /update, method:PUT
|
||||
* @param int $uid 文章ID
|
||||
*/
|
||||
public function update(\think\Request $request, int $uid= 0 ) {
|
||||
if (!$uid)
|
||||
$this->result->error('Invalid parameters', 404);
|
||||
$info = $this->model->find($uid);
|
||||
if (! $info) {
|
||||
$this->result->error('文章不存在', 404);
|
||||
}
|
||||
$data = $request->only(
|
||||
['title', 'cover_image', 'summary', 'content', 'author', 'cid', 'status'],
|
||||
'put'
|
||||
);
|
||||
$info->save($data);
|
||||
event('article_update_after', $info);
|
||||
$this->result->success($info, '更新成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文章(软删除)
|
||||
* @route DELETE /update, method:DELETE
|
||||
* @param int $uid 文章ID
|
||||
*/
|
||||
public function delete(\think\Request $request, int $uid= 0 ) {
|
||||
if (!$uid)
|
||||
$this->result->error('Invalid parameters', 404);
|
||||
$info = $this->model->find($uid);
|
||||
if (! $info) {
|
||||
$this->result->error('文章不存在', 404);
|
||||
}
|
||||
$info->delete();
|
||||
event('article_delete_after', $info);
|
||||
$this->result->success('', '删除成功');
|
||||
}
|
||||
|
||||
|
||||
private function getEncryptPassword($password, $salt = '')
|
||||
{
|
||||
return md5(md5($password) . $salt);
|
||||
}
|
||||
|
||||
|
||||
public function init()
|
||||
{
|
||||
return json(['message' => 'This is version 1 of the API']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare (strict_types = 1);
|
||||
namespace app\api\controller\v1;
|
||||
|
||||
use ywxapp\controller\ApiController;
|
||||
use think\facade\Event;
|
||||
use ywxapp\model\MemberUser as UserModel;
|
||||
use ywxapp\library\Result;
|
||||
use ywxapp\library\Email as EmailLib;
|
||||
|
||||
/**
|
||||
* 邮箱验证码接口.
|
||||
*/
|
||||
class Ems extends ApiController
|
||||
{
|
||||
protected $noNeedLogin = '*';
|
||||
protected $needRight = '*';
|
||||
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送验证码
|
||||
*
|
||||
* @param string $email 邮箱
|
||||
* @param string $event 事件名称
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
$email = $this->request->request('email');
|
||||
$event = $this->request->request('event');
|
||||
$event = $event ? $event : 'register';
|
||||
Event::trigger('email_send', ['email'=>$email, 'event'=>'register'], true);
|
||||
$userinfo = UserModel::getByEmail($email);
|
||||
if ($event == 'register' && $userinfo)
|
||||
Result::instance()->error(('已被注册'));
|
||||
elseif (in_array($event, ['changeemail']) && $userinfo)
|
||||
Result::instance()->error(('已被占用'));
|
||||
elseif (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo)
|
||||
Result::instance()->error(('未注册'));
|
||||
$ret = \ywxapp\library\Email::instance()->sendEmail($email, null, $event);
|
||||
if (!$ret)
|
||||
Result::instance()->error(('发送失败'));
|
||||
|
||||
Result::instance()->success(('发送成功'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测验证码
|
||||
*
|
||||
* @param string $email 邮箱
|
||||
* @param string $event 事件名称
|
||||
* @param string $captcha 验证码
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
$email = $this->request->request('email');
|
||||
$event = $this->request->request('event', 'register');
|
||||
$captcha = $this->request->request('captcha');
|
||||
|
||||
$validate = validate([
|
||||
'email' => 'email',
|
||||
'event' => 'chsAlphaNum',
|
||||
'code' => 'Num',
|
||||
]);
|
||||
if (!$validate->check(['email' => $email, 'event' => $event, 'code' => $captcha]))
|
||||
Result::instance()->error($validate->getError());
|
||||
|
||||
$userinfo = UserModel::where('email', $email)->find();
|
||||
if ($event == 'register' && $userinfo)
|
||||
$this->result->error(('已被注册'));
|
||||
elseif (in_array($event, ['changeemail']) && $userinfo)
|
||||
Result::instance()->error(('已被占用'));
|
||||
elseif (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo)
|
||||
Result::instance()->error(('未注册'));
|
||||
|
||||
$ret = EmailLib::instance()->check($email, $captcha, $event);
|
||||
if (!$ret)
|
||||
Result::instance()->error(('验证码不正确'));
|
||||
|
||||
Result::instance()->success(data: ('验证码正确'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
declare(strict_types=1);
|
||||
namespace app\api\controller\v1;
|
||||
use ywxapp\controller\ApiController;
|
||||
|
||||
use think\Response;
|
||||
|
||||
/**
|
||||
* Example 类
|
||||
*
|
||||
* @author ywxapp <admin@ywxapp.cn>
|
||||
*/
|
||||
class Example extends ApiController
|
||||
{
|
||||
|
||||
public function index(): Response
|
||||
{
|
||||
$user = \ywxapp\model\BackendAdmin::where('id', 1)->findOrEmpty();
|
||||
if (!$user->isEmpty()) {
|
||||
# code...
|
||||
|
||||
$roles = $user->roles;
|
||||
foreach ($roles as $role) {
|
||||
//echo $role->name;
|
||||
// 获取中间表模型
|
||||
// dump($role->pivot);
|
||||
}
|
||||
}
|
||||
return json([
|
||||
'message' => 'This is version 1 of the API',
|
||||
'data' => $user,
|
||||
'role' => $user->roles
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
namespace app\Api\Controller\V1;
|
||||
use ywxapp\controller\ApiController;
|
||||
use ywxapp\library\Result;
|
||||
/**
|
||||
* Index 类
|
||||
*
|
||||
* @author ywxapp <admin@ywxapp.cn>
|
||||
*/
|
||||
class Index extends ApiController
|
||||
{
|
||||
|
||||
|
||||
|
||||
public function init(\think\Request $request)
|
||||
{
|
||||
$result = Result::instance()->success(['name' => 'ThinkPHP', 'version' => '8.0', 'ip' => $request->ip(),'param'=>$request->param()], 'success');
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function index(\think\Request $request)
|
||||
{
|
||||
$result = Result::instance()->success(['name' => 'ThinkPHP', 'version' => '8.0', 'ip' => $request->ip(),'param'=>$request->param()], 'success');
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\Api\Controller\V1;
|
||||
|
||||
use think\facade\Event;
|
||||
use think\exception\ValidateException;
|
||||
use ywxapp\controller\ApiController;
|
||||
use ywxapp\library\Sms as Smslib;
|
||||
use ywxapp\model\Sms as SmsModel;
|
||||
use ywxapp\model\MemberUser as UserModel;
|
||||
use ywxapp\utils\Random;
|
||||
|
||||
/**
|
||||
* Sms 类
|
||||
*
|
||||
* @author ywxapp <admin@ywxapp.cn>
|
||||
*/
|
||||
class Sms extends ApiController
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
return json(['message' => 'SMS API']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送验证码
|
||||
*
|
||||
* @ApiMethod (POST)
|
||||
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
|
||||
* @ApiParams (name="event", type="string", required=true, description="事件名称")
|
||||
* @ApiParams (name="type", type="string", required=false, description="验证类型,auto为自动验证,system为系统验证码")
|
||||
* @ApiParams (name="source_id", type="string", required=false, description="来源ID")
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
$mobile = $this->request->post("mobile");
|
||||
$event = $this->request->post("event", 'register');
|
||||
$type = $this->request->post("type", 'auto');
|
||||
$source_id = $this->request->post("source_id", '');
|
||||
try {
|
||||
validate([
|
||||
'mobile' => 'require|max:11',
|
||||
'event' => 'require|alpha|lower',
|
||||
])->message([
|
||||
'mobile.require' => '手机号必须',
|
||||
'mobile.max' => '手机号最多不能超过11个字符',
|
||||
'event.require' => '事件名称必须',
|
||||
'event.alpha' => '事件名称必须是字母',
|
||||
'event.lower' => '事件名称必须是小写字母',
|
||||
])->check([
|
||||
'mobile' => $mobile,
|
||||
'event' => $event,
|
||||
]);
|
||||
$last = Smslib::get($mobile, $event);
|
||||
if ($last && time() - (int) $last['create_at'] < 60) {
|
||||
$this->result->error('发送频繁');
|
||||
}
|
||||
$ipSendTotal = SmsModel::where(['ip' => $this->request->ip()])->whereTime('create_at', '-1 hours')->count();
|
||||
if ($ipSendTotal >= 5) {
|
||||
$this->result->error('发送频繁');
|
||||
}
|
||||
if ($event) {
|
||||
$userinfo = UserModel::getByMobile($mobile);
|
||||
if ($event == 'register' && $userinfo) {
|
||||
//已被注册
|
||||
$this->result->error('已被注册');
|
||||
} elseif (in_array($event, ['changemobile']) && $userinfo) {
|
||||
//被占用
|
||||
$this->result->error('已被占用');
|
||||
} elseif (in_array($event, ['changepwd', 'resetpwd']) && ! $userinfo) {
|
||||
//未注册
|
||||
$this->result->error('未注册');
|
||||
}
|
||||
}
|
||||
if (! Event::hasListener('SmsSend')) {
|
||||
$this->result->error('请在后台插件管理安装短信验证插件');
|
||||
}
|
||||
$ret = Smslib::send($mobile, null, $event);
|
||||
if ($ret) {
|
||||
$this->result->success('发送成功');
|
||||
} else {
|
||||
$this->result->error('发送失败,请检查短信配置是否正确');
|
||||
}
|
||||
} catch (ValidateException $e) {
|
||||
$this->result->error($e->getError());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测验证码
|
||||
*
|
||||
* @ApiMethod (POST)
|
||||
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
|
||||
* @ApiParams (name="event", type="string", required=true, description="事件名称")
|
||||
* @ApiParams (name="captcha", type="string", required=true, description="验证码")
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
$mobile = $this->request->post("mobile");
|
||||
$event = $this->request->post("event", 'register');
|
||||
$captcha = $this->request->post("captcha");
|
||||
if (! $mobile || ! \think\Validate::regex($mobile, "^1\d{10}$")) {
|
||||
$this->result->error('手机号不正确');
|
||||
}
|
||||
if (! preg_match("/^[a-z0-9_\-]{3,30}\$/i", $event)) {
|
||||
$this->result->error('事件名称错误');
|
||||
}
|
||||
if (! preg_match("/^[a-z0-9]{4,6}\$/i", $captcha)) {
|
||||
$this->result->error('验证码格式错误');
|
||||
}
|
||||
|
||||
if ($event) {
|
||||
$userinfo = UserModel::getByMobile($mobile);
|
||||
if ($event == 'register' && $userinfo) {
|
||||
//已被注册
|
||||
$this->result->error('已被注册');
|
||||
} elseif (in_array($event, ['changemobile']) && $userinfo) {
|
||||
//被占用
|
||||
$this->result->error('已被占用');
|
||||
} elseif (in_array($event, ['changepwd', 'resetpwd']) && ! $userinfo) {
|
||||
//未注册
|
||||
$this->result->error('未注册');
|
||||
}
|
||||
}
|
||||
$ret = Smslib::check($mobile, $captcha, $event);
|
||||
if ($ret) {
|
||||
$this->result->success('成功');
|
||||
} else {
|
||||
$this->result->error('验证码不正确');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\Api\Controller\V1;
|
||||
|
||||
use app\api\validate\Login as LoginValidate;
|
||||
use think\facade\Event;
|
||||
use think\facade\Validate;
|
||||
use ywxapp\controller\ApiController;
|
||||
use ywxapp\model\MemberUser as UserModel;
|
||||
use ywxapp\service\JwtService;
|
||||
|
||||
|
||||
class User extends ApiController
|
||||
{
|
||||
protected $noNeedLogin = ['*'];
|
||||
protected $noNeedVerify = ['*'];
|
||||
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
$this->model = new \ywxapp\model\Members();
|
||||
}
|
||||
|
||||
|
||||
public function index()
|
||||
{
|
||||
return json(['message' => 'This is version 1 of the API']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册会员.
|
||||
* @route put /register, method:put
|
||||
* @param string $username 用户名
|
||||
* @param string $password 密码
|
||||
* @param string $email 邮箱
|
||||
* @param string $mobile 手机号
|
||||
* @param string $code 验证码
|
||||
* @return \think\Response
|
||||
*/
|
||||
|
||||
public function register(\think\Request $request)
|
||||
{
|
||||
$data = $request->param();
|
||||
$validate = validate([
|
||||
'account|账户或手机号' => 'require',
|
||||
'password' => 'alphaDash',
|
||||
'code' => 'number|length:4',
|
||||
'captcha' => 'alphaNum',
|
||||
]);
|
||||
if (! $validate->check($data)) {
|
||||
$this->result->error($validate->getError());
|
||||
}
|
||||
|
||||
$account = $request->param('account');
|
||||
$password = $request->has('password') ? $request->param('password') : md5("xixingwl");
|
||||
$code = $request->param('code');
|
||||
if (Validate::is($account, 'email') && $request->has('code')) {
|
||||
$ret = \ywxapp\library\Sms::instence()->check($account, $code, 'register');
|
||||
if (! $ret) {
|
||||
$this->result->error('Code is incorrect');
|
||||
}
|
||||
|
||||
}
|
||||
if (Validate::is($account, 'mobile') && $request->has('code')) {
|
||||
$ret = \ywxapp\library\Sms::instence()->check($account, $code, 'register');
|
||||
if (! $ret) {
|
||||
$this->result->error('Code is incorrect');
|
||||
}
|
||||
|
||||
}
|
||||
$extend = [];
|
||||
if ($request->param('avatar')) {
|
||||
$extend['avatar'] = $request->param('avatar');
|
||||
}
|
||||
|
||||
if ($request->param('nickname')) {
|
||||
$extend['nickname'] = $request->param('nickname');
|
||||
}
|
||||
|
||||
$this->user->create($account, $password, $extend);
|
||||
$this->result->success(['userinfo' => $this->Member->info]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Member Login.
|
||||
*
|
||||
* @param string $account 账号
|
||||
* @param string $password 密码
|
||||
* @return \think\Response
|
||||
*/
|
||||
|
||||
public function login(\think\Request $request)
|
||||
{
|
||||
|
||||
$data = $this->request->param();
|
||||
try {
|
||||
validate(LoginValidate::class)->check($data);
|
||||
$info = UserModel::where('account', $data['username'])
|
||||
->whereOr('mobile', $data['username'])
|
||||
->whereOr('email', $data['username'])
|
||||
->findOrEmpty();
|
||||
if ($info->isEmpty()) {
|
||||
$this->result->error('用户不存在', 4010);
|
||||
}
|
||||
// 检查账户状态
|
||||
if ($info->status == 0) {
|
||||
$this->result->error('账号已被禁用', 403);
|
||||
}
|
||||
// 检查是否被锁定
|
||||
if ($info->isLocked()) {
|
||||
$lockTime = strtotime($info->lock_time) + 1800 - time();
|
||||
$minutes = ceil($lockTime / 60);
|
||||
$this->result->error("账号被锁定,请 {$minutes} 分钟后重试", 403);
|
||||
}
|
||||
$info->resetPassword($data['password']);
|
||||
// 验证密码
|
||||
if (! $info->checkPassword($data['password'])) {
|
||||
$info->recordLoginFail($this->request->ip()); // 记录失败
|
||||
$this->result->error('密码错误', 4011);
|
||||
}
|
||||
Event::trigger('MemberLog', [
|
||||
'uid' => $info->uid,
|
||||
'action' => 'login',
|
||||
'ip' => $this->request->ip(),
|
||||
'remark' => '用户注册',
|
||||
]);
|
||||
$newClaims = [
|
||||
'uid' => $info->uid,
|
||||
'account' => $info->account,
|
||||
];
|
||||
JwtService::instance()->createToken($newClaims);
|
||||
$this->result->success($info);
|
||||
} catch (ValidateException $e) {
|
||||
$this->result->error($e->getMessage(), 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user detail
|
||||
* @route get /detail, method:get
|
||||
* @param int $uid
|
||||
* @return \think\Response
|
||||
*/
|
||||
|
||||
public function detail(\think\Request $request, int $uid = 0)
|
||||
{
|
||||
if (! $uid) {
|
||||
$this->result->error('Invalid parameters', 404);
|
||||
}
|
||||
|
||||
$this->result->success($this->user->info);
|
||||
}
|
||||
|
||||
/**
|
||||
* update user detail
|
||||
* @route put /update, method:get
|
||||
* @param int $uid
|
||||
* @return \think\Response
|
||||
*/
|
||||
|
||||
public function update(\think\Request $request, int $uid = 0)
|
||||
{
|
||||
if (! $uid) {
|
||||
$this->result->error('Invalid parameters', 404);
|
||||
}
|
||||
|
||||
$this->result->success($this->user->info);
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE user detail
|
||||
* @route DELETE /update, method:DELETE
|
||||
* @param int $uid
|
||||
* @return \think\Response
|
||||
*/
|
||||
|
||||
public function delete(\think\Request $request, int $uid = 0)
|
||||
{
|
||||
if (! $uid) {
|
||||
$this->result->error('Invalid parameters', 404);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function getEncryptPassword($password, $salt = '')
|
||||
{
|
||||
return md5(md5($password) . $salt);
|
||||
}
|
||||
|
||||
|
||||
public function init()
|
||||
{
|
||||
return json(['message' => 'This is version 1 of the API']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
// controller/api/v1/Example.php
|
||||
namespace app\api\controller\v2;
|
||||
|
||||
use think\Response;
|
||||
|
||||
/**
|
||||
* Example 类
|
||||
*
|
||||
* @author ywxapp <admin@ywxapp.cn>
|
||||
*/
|
||||
class Example
|
||||
{
|
||||
|
||||
public function index(): Response
|
||||
{
|
||||
return json(['message' => 'This is version 2 of the API']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
// 这是系统自动生成的event定义文件
|
||||
return [
|
||||
|
||||
];
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
// 这是系统自动生成的middleware定义文件
|
||||
return [];
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\facade\Route;
|
||||
|
||||
// 支持批量添加
|
||||
Route::pattern([
|
||||
'name' => '\w+',
|
||||
'id' => '\d+',
|
||||
]);
|
||||
|
||||
// 一级控制器版本化 API(/api/v1/...、/api/v2/...)
|
||||
//
|
||||
// 插件路由(/<插件>/backend、/<插件>/developer、/<插件>/api 等)统一由
|
||||
// 主应用 ywxapp/service/AppService::loadAddonRoutes() 在 boot 阶段注册,
|
||||
// 本文件【不再】引入插件 route/app.php——否则 think-multi-app 会把 api 当作
|
||||
// 应用名截走并叠加前缀,导致 /api/<插件>/* 或 /api/api/* 恒 404。
|
||||
Route::group(':version', function () {
|
||||
Route::rule(':Controller/:action', ':version.:Controller/:action');
|
||||
})->middleware(\think\middleware\AllowCrossDomain::class)->pattern([
|
||||
'version' => 'v\d+', // 匹配 v1/v2/v3...
|
||||
]);
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\api\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
/**
|
||||
* Login 类
|
||||
*
|
||||
* @author ywxapp <admin@ywxapp.cn>
|
||||
*/
|
||||
class Login extends Validate
|
||||
{
|
||||
/**
|
||||
* 定义验证规则
|
||||
* 格式:'字段名' => ['规则1','规则2'...]
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [
|
||||
'username|用户名' => 'require|max:25',
|
||||
'password|密码' => 'require',
|
||||
//'captcha|验证码' => 'require|captcha',
|
||||
];
|
||||
|
||||
/**
|
||||
* 定义错误信息
|
||||
* 格式:'字段名.规则名' => '错误信息'
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $message = [
|
||||
'username.require' => '请输入用户名',
|
||||
'username.max' => '名称最多不能超过25个字符',
|
||||
'password.require' => '密码错误',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\member\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
/**
|
||||
* Register 类
|
||||
*
|
||||
* @author ywxapp <admin@ywxapp.cn>
|
||||
*/
|
||||
class Register extends Validate
|
||||
{
|
||||
/**
|
||||
* 定义验证规则
|
||||
* 格式:'字段名' => ['规则1','规则2'...]
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [
|
||||
//'username' => 'require|alphaNum|length:4,20|unique:user',
|
||||
'username' => 'require|alphaNum|length:4,20 ',
|
||||
'password' => 'require|length:8,20|confirm',
|
||||
'email' => 'require|email|unique:user',
|
||||
'mobile' => 'require|regex:/^1[3-9]\d{9}$/|unique:user',
|
||||
'captcha' => 'require|captcha'];
|
||||
|
||||
/**
|
||||
* 定义错误信息
|
||||
* 格式:'字段名.规则名' => '错误信息'
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $message = [
|
||||
'username.require' => '用户名不能为空',
|
||||
'username.alphaNum' => '用户名只能包含字母和数字'];
|
||||
}
|
||||
Reference in New Issue
Block a user