基类和工具类
This commit is contained in:
23
app/BaseApp/BaseClient.php
Normal file
23
app/BaseApp/BaseClient.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\BaseApp;
|
||||
|
||||
class BaseClient
|
||||
{
|
||||
private static mixed $_instance;
|
||||
|
||||
|
||||
/**
|
||||
* 获取实例
|
||||
* @return null|static
|
||||
*/
|
||||
public static function getInstance(): null|static
|
||||
{
|
||||
$name = get_called_class();
|
||||
if (!isset(self::$_instance[$name])) {
|
||||
self::$_instance[$name] = new static();
|
||||
}
|
||||
|
||||
return self::$_instance[$name];
|
||||
}
|
||||
}
|
||||
165
app/BaseApp/BaseController.php
Executable file
165
app/BaseApp/BaseController.php
Executable file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace App\BaseApp;
|
||||
|
||||
use App\Service\UtilsService;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class BaseController
|
||||
{
|
||||
protected array $insertField = [];
|
||||
protected array $notRequest = [];
|
||||
protected array $updateField = [];
|
||||
protected $service;
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
* @Method GET
|
||||
* @return JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function list(): JsonResponse
|
||||
{
|
||||
return jok(
|
||||
$this->service->list(),
|
||||
'列表获取成功'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下拉列表
|
||||
* @Method GET
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function option(): mixed
|
||||
{
|
||||
return jok(
|
||||
$this->service->option(),
|
||||
'列表获取成功'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
*
|
||||
* @Method GET
|
||||
* @return JsonResponse
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
public function detail(): JsonResponse
|
||||
{
|
||||
$id = request()->get('id');
|
||||
if (empty($id)) UtilsService::getInstance()->notFound('参数错误');
|
||||
return jok(
|
||||
$this->service->detail($id),
|
||||
'详情获取成功'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建
|
||||
*
|
||||
* @Method POST
|
||||
* @return JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(): JsonResponse
|
||||
{
|
||||
$params = $this->checkRequiredFields(request()->post());
|
||||
return jok(
|
||||
$this->service->create($params),
|
||||
'创建成功'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @Method POST
|
||||
* @return JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(): JsonResponse
|
||||
{
|
||||
$params = $this->checkRequiredFields(request()->post(), 'update');
|
||||
$id = $params['id'];
|
||||
unset($params['id']);
|
||||
return jok(
|
||||
$this->service->update($id, $params),
|
||||
'更新成功'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @Method POST
|
||||
* @return JsonResponse
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete(): JsonResponse
|
||||
{
|
||||
$id = request()->post('ids');
|
||||
if (empty($id)) UtilsService::getInstance()->notFound('参数错误');
|
||||
return jok(
|
||||
$this->service->delete($id),
|
||||
'删除成功'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查必填字段
|
||||
*
|
||||
* @Method NO
|
||||
* @param array $data
|
||||
* @param string $checkType
|
||||
* @param bool $throw
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function checkRequiredFields(array $data = [], string $checkType = 'create', bool $throw = true): array
|
||||
{
|
||||
$checkFields = $checkType == 'create' ? $this->insertField : $this->updateField;
|
||||
|
||||
if (!empty($this->notRequest)) {
|
||||
$checkFields = array_merge($this->notRequest, $checkFields);
|
||||
}
|
||||
|
||||
$requiredFields = [];
|
||||
$result = [];
|
||||
foreach ($checkFields as $fieldName) {
|
||||
$checkValue = $data[$fieldName] ?? '';
|
||||
if (is_array($checkValue)) {
|
||||
$checkValue = json_encode($checkValue);
|
||||
}
|
||||
if (mb_strlen(strval($checkValue)) <= 0 && !in_array($fieldName, $this->notRequest)) {
|
||||
$requiredFields[] = $fieldName;
|
||||
} else {
|
||||
$result[$fieldName] = $checkValue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($throw && $requiredFields) {
|
||||
UtilsService::getInstance()->notFound('未填写的字段: ' . implode(',', $requiredFields));
|
||||
}
|
||||
|
||||
if (!empty($requiredFields)) {
|
||||
return $requiredFields;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
26
app/BaseApp/BaseModel.php
Executable file
26
app/BaseApp/BaseModel.php
Executable file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\BaseApp;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class BaseModel extends Model
|
||||
{
|
||||
protected $connection = 'mysql';
|
||||
public $timestamps = false;
|
||||
public function getCreatedAtAttribute($value): string
|
||||
{
|
||||
if (empty($value)) {
|
||||
return '';
|
||||
}
|
||||
return date('Y-m-d H:i:s', $value);
|
||||
}
|
||||
// 定义访问器,将 created_at 字段格式化为指定格式
|
||||
public function getUpdatedAtAttribute($value): string
|
||||
{
|
||||
if (empty($value)) {
|
||||
return '';
|
||||
}
|
||||
return date('Y-m-d H:i:s', $value);
|
||||
}
|
||||
}
|
||||
70
app/BaseApp/BaseService.php
Executable file
70
app/BaseApp/BaseService.php
Executable file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\BaseApp;
|
||||
|
||||
use App\Models\UserModel;
|
||||
use App\Service\UtilsService;
|
||||
|
||||
class BaseService
|
||||
{
|
||||
|
||||
/**
|
||||
* @var mixed 单例实例,确保该类只有一个全局实例
|
||||
*/
|
||||
private static mixed $_instance;
|
||||
/**
|
||||
* @var object 工具类对象,用于提供通用的功能方法
|
||||
*/
|
||||
protected object $utils;
|
||||
/**
|
||||
* @var int 用户ID,默认值为0,表示未登录状态
|
||||
*/
|
||||
protected int $userId = 0;
|
||||
/**
|
||||
* @var array 用户信息
|
||||
*/
|
||||
protected array $userInfo = [];
|
||||
/**
|
||||
* @var object 数据模型对象,用于数据库操作
|
||||
*/
|
||||
protected $model;
|
||||
|
||||
protected $isAuth = true;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if ($this->isAuth) {
|
||||
// 如果是home的接口可以不执行这个方法
|
||||
if (!\request()->is('api/home/*')) {
|
||||
$this->authUser();
|
||||
}
|
||||
}
|
||||
$this->utils = UtilsService::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实例
|
||||
* @return null|static
|
||||
*/
|
||||
public static function getInstance(): null|static
|
||||
{
|
||||
$name = get_called_class();
|
||||
if (!isset(self::$_instance[$name])) {
|
||||
self::$_instance[$name] = new static();
|
||||
}
|
||||
|
||||
return self::$_instance[$name];
|
||||
}
|
||||
|
||||
private function authUser()
|
||||
{
|
||||
$token = \request()->header('Authorization');
|
||||
$token = explode(' ', $token)[1];
|
||||
$userModel = UserModel::where('session_key', $token)->first();
|
||||
if (!$userModel) {
|
||||
jexpire('token失效');
|
||||
}
|
||||
$this->userId = $userModel->id;
|
||||
$this->userInfo = $userModel->toArray();
|
||||
}
|
||||
}
|
||||
55
app/Enum/ErrorEnum.php
Executable file
55
app/Enum/ErrorEnum.php
Executable file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enum;
|
||||
/**
|
||||
* 状态码定义
|
||||
*/
|
||||
enum ErrorEnum: int
|
||||
{
|
||||
/**
|
||||
* 成功
|
||||
*/
|
||||
case SUCCESS = 0;
|
||||
/**
|
||||
* 登录过期
|
||||
*/
|
||||
case NOT_AUTH = 401;
|
||||
/**
|
||||
* 权限不足
|
||||
*/
|
||||
case NOT_PERMISSION = 403;
|
||||
/**
|
||||
* 未找到资源的错误
|
||||
*/
|
||||
case NOT_FOUND = 404;
|
||||
/**
|
||||
* 失败状态的错误
|
||||
*/
|
||||
case FAIL = 500;
|
||||
/**
|
||||
* 验证失败的错误
|
||||
*/
|
||||
case NOT_VALID = 2001;
|
||||
/**
|
||||
* 不存在的错误
|
||||
*/
|
||||
case NOT_EXIST = 2002;
|
||||
/**
|
||||
* 不存在或已删除的错误
|
||||
*/
|
||||
case NOT_EXIST_OR_DELETED = 2003;
|
||||
|
||||
public function description(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::SUCCESS => '请求成功',
|
||||
self::FAIL => '服务器异常',
|
||||
self::NOT_FOUND => '未找到资源',
|
||||
self::NOT_AUTH => '未授权',
|
||||
self::NOT_PERMISSION => '您没有权限',
|
||||
self::NOT_VALID => '字段验证失败',
|
||||
self::NOT_EXIST => '资源不存在',
|
||||
self::NOT_EXIST_OR_DELETED => '资源被删除',
|
||||
};
|
||||
}
|
||||
}
|
||||
220
app/Service/UtilsService.php
Executable file
220
app/Service/UtilsService.php
Executable file
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Enum\ErrorEnum;
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use Random\RandomException;
|
||||
|
||||
class UtilsService
|
||||
{
|
||||
private static mixed $_instance;
|
||||
|
||||
/**
|
||||
* 获取实例
|
||||
* @return null|static
|
||||
*/
|
||||
public static function getInstance(): null|static
|
||||
{
|
||||
$name = get_called_class();
|
||||
if (!isset(self::$_instance[$name])) {
|
||||
self::$_instance[$name] = new static();
|
||||
}
|
||||
|
||||
return self::$_instance[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* 抛出异常
|
||||
*
|
||||
* @param string $msg
|
||||
* @param ErrorEnum $code
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function errorThrow(string $msg = '请求出了问题!', ErrorEnum $code = ErrorEnum::FAIL): mixed
|
||||
{
|
||||
throw new Exception($msg, $code->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 抛出未找到异常 2000
|
||||
*
|
||||
* @param $msg
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function notFound($msg): mixed
|
||||
{
|
||||
return self::errorThrow($msg, ErrorEnum::NOT_FOUND);
|
||||
}
|
||||
|
||||
/**
|
||||
* 未授权 401
|
||||
*
|
||||
* @param $msg
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function notAuth($msg): mixed
|
||||
{
|
||||
exit(json_encode(['msg' => $msg, 'code' => ErrorEnum::NOT_AUTH->value]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成密码
|
||||
* @param $password
|
||||
* @return string
|
||||
*/
|
||||
public function genPassword($password): string
|
||||
{
|
||||
return password_hash($password, PASSWORD_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码验证
|
||||
*
|
||||
* @param $password
|
||||
* @param $passwordAse
|
||||
* @return bool
|
||||
*/
|
||||
public function checkPassword($password, $passwordAse): bool
|
||||
{
|
||||
// 盐
|
||||
return password_verify($password, $passwordAse);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成OpenId
|
||||
* @return string
|
||||
* @throws RandomException
|
||||
*/
|
||||
public function genOpenId(): string
|
||||
{
|
||||
// 获取当前时间戳(精确到秒)
|
||||
$timestamp = dechex(time());
|
||||
|
||||
// 生成16字节的随机数据,并转换为32个十六进制字符组成的字符串
|
||||
$randomString = bin2hex(random_bytes(16));
|
||||
|
||||
// 结合时间和随机字符串,确保总长度为28个字符
|
||||
return substr($timestamp . $randomString, 0, 28);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归生成树形结构
|
||||
* @param $data
|
||||
* @param int $pid
|
||||
* @return array
|
||||
*/
|
||||
public function tree($data, int $pid = 0): array
|
||||
{
|
||||
$tree = [];
|
||||
foreach ($data as $v) {
|
||||
if ($v['pid'] == $pid) {
|
||||
$v['children'] = $this->tree($data, $v['id']);
|
||||
if (empty($v['children'])) {
|
||||
unset($v['children']);
|
||||
}
|
||||
$tree[] = $v;
|
||||
}
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查手机号格式
|
||||
*
|
||||
* @param string $phone
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function checkPhone(string $phone): bool
|
||||
{
|
||||
$phone = trim($phone);
|
||||
if (preg_match('/^1[3456789]\d{9}$/', $phone)) {
|
||||
return true;
|
||||
} else {
|
||||
self::errorThrow('手机号格式不正确');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成订单号
|
||||
* @param int $type
|
||||
* @return string
|
||||
*/
|
||||
public function genOrderNo(int $type = 0): string
|
||||
{
|
||||
$len = 9999999999;
|
||||
switch ($type) {
|
||||
case 0:
|
||||
return 'DK'. date('Ymd') . str_pad(mt_rand(1, $len), 11, '0', STR_PAD_LEFT);
|
||||
case 1:
|
||||
return 'DD'. date('Ymd') . str_pad(mt_rand(1, $len), 11, '0', STR_PAD_LEFT);
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是开发环境
|
||||
* @return bool
|
||||
*/
|
||||
public static function isDev(): bool
|
||||
{
|
||||
return env('ECS') === 'localhost';
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据身份证号计算年龄
|
||||
* @param string $idno 身份证号(15位或18位)
|
||||
* @return int|false 成功返回年龄,失败返回false
|
||||
*/
|
||||
public function getAgeFromIdNo($idno = '')
|
||||
{
|
||||
// 校验身份证号长度
|
||||
$len = strlen($idno);
|
||||
if (!in_array($len, [15, 18])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 提取出生日期部分
|
||||
if ($len === 18) {
|
||||
$datePart = substr($idno, 6, 8);
|
||||
} else {
|
||||
// 15位身份证补全年份为19XX
|
||||
$datePart = '19' . substr($idno, 6, 6);
|
||||
}
|
||||
|
||||
// 分解年月日
|
||||
$year = substr($datePart, 0, 4);
|
||||
$month = substr($datePart, 4, 2);
|
||||
$day = substr($datePart, 6, 2);
|
||||
|
||||
// 校验年月日是否为数字
|
||||
if (!ctype_digit($year) || !ctype_digit($month) || !ctype_digit($day)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 尝试创建日期对象
|
||||
try {
|
||||
$birthDate = new DateTime("$year-$month-$day");
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$currentDate = new DateTime();
|
||||
|
||||
// 检查出生日期是否在当前日期之前
|
||||
if ($birthDate > $currentDate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 计算年龄差
|
||||
$ageInterval = $currentDate->diff($birthDate);
|
||||
return $ageInterval->y;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user