Compare commits
30 Commits
caf3f87482
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| edefaa4379 | |||
| 2b767fb17b | |||
| 0d51623bbf | |||
| 8ea4f2bafd | |||
| e68c2dc663 | |||
| 6b4d1e5be3 | |||
| 60faecae99 | |||
| 61acb0de5a | |||
| dabef7a5a0 | |||
| 8a99bcb904 | |||
| 7a08ac219e | |||
| d3bb8380e2 | |||
| 6e963b23b0 | |||
| cd304275b8 | |||
| cbd0b19b91 | |||
| 36658dc184 | |||
| c61357eca1 | |||
| 91a1d06b53 | |||
| 2609d009ed | |||
| 7c8b090940 | |||
| bd26d52fff | |||
| 147b2d3fd5 | |||
| db54446f8b | |||
| 0bfe7786d3 | |||
| ba260c2bf4 | |||
| 44c1e18745 | |||
| 994ecb2488 | |||
| 87ac792634 | |||
| dfb7acab05 | |||
| 02312397b3 |
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];
|
||||
}
|
||||
}
|
||||
170
app/BaseApp/BaseController.php
Executable file
170
app/BaseApp/BaseController.php
Executable file
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
namespace App\BaseApp;
|
||||
|
||||
use App\Service\common\UtilsService;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use function PHPUnit\Framework\isString;
|
||||
|
||||
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) && !empty($checkValue)) {
|
||||
$result[$fieldName] = $checkValue;
|
||||
} else {
|
||||
if ((empty($checkValue) && $checkValue !== 0) && !in_array($fieldName, $this->notRequest)) {
|
||||
$requiredFields[] = $fieldName;
|
||||
} else {
|
||||
if (!empty($checkValue) || $checkValue === 0) {
|
||||
$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);
|
||||
}
|
||||
}
|
||||
322
app/BaseApp/BaseService.php
Executable file
322
app/BaseApp/BaseService.php
Executable file
@@ -0,0 +1,322 @@
|
||||
<?php
|
||||
|
||||
namespace App\BaseApp;
|
||||
|
||||
use App\Models\UserModel;
|
||||
use App\Service\common\JWTService;
|
||||
use App\Service\common\UtilsService;
|
||||
use Exception;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class BaseService
|
||||
{
|
||||
/**
|
||||
* @var mixed 单例实例,确保该类只有一个全局实例
|
||||
*/
|
||||
protected 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;
|
||||
|
||||
/**
|
||||
* @var bool 是否需要验证用户权限
|
||||
*/
|
||||
protected bool $isAuth = true;
|
||||
|
||||
/**
|
||||
* @var array 查询的字段
|
||||
*/
|
||||
protected array $selectField = ['*'];
|
||||
|
||||
/**
|
||||
* @var array 查询条件Between
|
||||
*/
|
||||
protected array $whereBetween = [];
|
||||
|
||||
/**
|
||||
* @var array 排序条件
|
||||
*/
|
||||
protected array $orderBy = [
|
||||
'name' => 'id',
|
||||
'sort' => 'desc',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array 查询条件
|
||||
*/
|
||||
protected array $where = [
|
||||
['deleted_at', '=', 0]
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array 查询条件In
|
||||
*/
|
||||
protected array $whereIn = [];
|
||||
|
||||
/**
|
||||
* @var array 下拉列表字段
|
||||
*/
|
||||
protected array $optionField = ['id', 'name'];
|
||||
|
||||
/**
|
||||
* @var array 下拉列表字段
|
||||
*/
|
||||
protected array $queryField = [];
|
||||
|
||||
/**
|
||||
* @var array 关联加载
|
||||
*/
|
||||
protected array $with = [];
|
||||
|
||||
/**
|
||||
* @var string 时间字段
|
||||
*/
|
||||
protected string $timeField = 'created_at';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if ($this->isAuth) {
|
||||
$this->userInfo = JWTService::getInstance()->getToken()->getUserInfo();
|
||||
$this->userId = $this->userInfo['id'] ?? 0;
|
||||
} else {
|
||||
try {
|
||||
$this->userInfo = JWTService::getInstance()->getToken()->getUserInfo();
|
||||
$this->userId = $this->userInfo['id'] ?? 0;
|
||||
} catch (Exception $e) {
|
||||
$this->userId = 0;
|
||||
}
|
||||
}
|
||||
$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];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取列表数据
|
||||
*
|
||||
* 本函数负责根据设定的条件,从数据库中查询并返回分页后的数据列表
|
||||
* 它会根据空值条件动态地修改查询,以实现灵活的查询需求
|
||||
*
|
||||
* @return array 返回包含分页信息和数据列表的数组
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function getPageList($isArr = true, $isGetWhere = true): array
|
||||
{
|
||||
// 初始化查询条件
|
||||
if ($isGetWhere === true) $this->getWhere();
|
||||
|
||||
// 获取范围查询条件
|
||||
$searchTime = request()->get('search_time');
|
||||
if (!empty($searchTime)) {
|
||||
$this->getWhereBetween($searchTime);
|
||||
}
|
||||
|
||||
// 执行数据库查询,根据条件动态构建查询语句
|
||||
$result = $this->model::when(!empty($this->with), function ($query) {
|
||||
// 如果关联加载条件存在,则添加关联加载
|
||||
$query->with($this->with);
|
||||
})
|
||||
->when(!empty($this->where), function ($query) {
|
||||
// 如果查询条件存在,则添加查询条件
|
||||
$query->where($this->where);
|
||||
})
|
||||
->when(!empty($this->whereIn), function ($query) {
|
||||
// 如果查询条件存在,则添加查询条件
|
||||
$query->whereIn($this->whereIn[0], $this->whereIn[1]);
|
||||
})
|
||||
->when(!empty($this->whereBetween), function ($query) {
|
||||
// 如果范围查询条件存在,则添加范围查询
|
||||
$query->whereBetween($this->whereBetween[0], $this->whereBetween[1]);
|
||||
})
|
||||
->when(!empty($this->orderBy), function ($query) {
|
||||
// 如果排序条件存在,则添加排序条件
|
||||
$query->orderBy($this->orderBy['name'], $this->orderBy['sort']);
|
||||
})
|
||||
->select($this->selectField)
|
||||
// 执行分页查询,每页返回10条记录
|
||||
->paginate(request()->get('pageSize', 20));
|
||||
|
||||
if ($isArr === true) {
|
||||
$result = $result->toArray() ?? [];
|
||||
// 返回分页信息和数据列表
|
||||
return [
|
||||
'page' => $result['current_page'],
|
||||
'size' => $result['per_page'],
|
||||
'page_count' => $result['last_page'],
|
||||
'total' => $result['total'],
|
||||
'items' => $result['data'],
|
||||
];
|
||||
}
|
||||
|
||||
// 返回分页信息和数据列表
|
||||
return [
|
||||
'page' => $result->currentPage(),
|
||||
'size' => $result->perPage(),
|
||||
'page_count' => $result->lastPage(),
|
||||
'total' => $result->total(),
|
||||
'items' => $result->items(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下拉列表数据
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOption(): mixed
|
||||
{
|
||||
$this->getWhere();
|
||||
return $this->model::when(!empty($this->where), function ($query) {
|
||||
$query->where($this->where);
|
||||
})->when(!empty($this->whereIn), function ($query) {
|
||||
$query->where($this->whereIn[0], $this->whereIn[1]);
|
||||
})->orderBy($this->orderBy['name'], $this->orderBy['sort'])->get($this->optionField);
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getDetail($id): mixed
|
||||
{
|
||||
$info = $this->model::with($this->with)->select($this->selectField)->find($id);
|
||||
if (empty($info)) {
|
||||
return $this->utils->notFound('数据不存在');
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @param $params
|
||||
* @return mixed
|
||||
*/
|
||||
public function insert($params): mixed
|
||||
{
|
||||
if (!array_key_exists('created_at', $params)) {
|
||||
$params['created_at'] = time();
|
||||
}
|
||||
// return $this->model::insertGetId($this->utils->truncatedOss($params));
|
||||
return $this->model::insertGetId($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param $id
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function save($id, $params): mixed
|
||||
{
|
||||
if (empty(trim($id))) {
|
||||
$this->utils->errorThrow('参数错误');
|
||||
}
|
||||
$this->where[] = ['id', '=', $id];
|
||||
// 软删除
|
||||
$info = $this->model::where($this->where)->first();
|
||||
if (empty($info)) {
|
||||
return $this->utils->notFound('数据不存在');
|
||||
}
|
||||
if (!array_key_exists('updated_at', $params)) {
|
||||
$params['updated_at'] = time();
|
||||
}
|
||||
// return $this->model::where('id', $id)->update($this->utils->truncatedOss($params));
|
||||
return $this->model::where('id', $id)->update($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param $id
|
||||
* @return mixed|true
|
||||
* @throws Exception
|
||||
*/
|
||||
public function del($id): mixed
|
||||
{
|
||||
// 软删除
|
||||
$info = $this->model::whereIn('id', $id)->get(['id']);
|
||||
if (empty($info)) {
|
||||
return $this->utils->notFound('数据不存在');
|
||||
}
|
||||
if ($this->model::whereIn('id', $id)->update([
|
||||
'deleted_at' => time(),
|
||||
'updated_at' => time()
|
||||
])) {
|
||||
return true;
|
||||
} else {
|
||||
$this->utils->errorThrow('删除失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询条件
|
||||
* @return void
|
||||
*/
|
||||
protected function getWhere(): void
|
||||
{
|
||||
$query = request()->query();
|
||||
if (!empty($this->queryField)) {
|
||||
foreach ($this->queryField as $key => $value) {
|
||||
if (in_array($key, array_keys($query))) {
|
||||
if (!empty($query[$key] ?? '') || $query[$key] == '0') {
|
||||
switch ($value) {
|
||||
case '=':
|
||||
$this->where[] = [$key, $value, $query[$key]];
|
||||
break;
|
||||
case 'like':
|
||||
$this->where[] = [$key, $value, '%' . $query[$key] . '%'];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间范围查询条件
|
||||
* @param $searchTime
|
||||
* @return void
|
||||
*/
|
||||
protected function getWhereBetween($searchTime): void
|
||||
{
|
||||
$this->whereBetween = [$this->timeField, [strtotime($searchTime[0] ?? date('Y-m-01 00:00:00')), strtotime(date('Y-m-d 23:59:59', strtotime($searchTime[1])) ?? date('Y-m-d 23:59:59'))]];
|
||||
}
|
||||
}
|
||||
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 => '资源被删除',
|
||||
};
|
||||
}
|
||||
}
|
||||
22
app/Enum/ProjectFieldTypeEnum.php
Executable file
22
app/Enum/ProjectFieldTypeEnum.php
Executable file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enum;
|
||||
/**
|
||||
* 状态码定义
|
||||
*/
|
||||
enum ProjectFieldTypeEnum: int
|
||||
{
|
||||
case SOLD = 1;
|
||||
case SELECTED = 2;
|
||||
case CAROUSEL = 3;
|
||||
|
||||
|
||||
public function description(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::SELECTED => 'is_selected',
|
||||
self::CAROUSEL => 'is_carousel',
|
||||
self::SOLD => 'is_sold',
|
||||
};
|
||||
}
|
||||
}
|
||||
25
app/Enum/ProjectStatusEnum.php
Executable file
25
app/Enum/ProjectStatusEnum.php
Executable file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enum;
|
||||
/**
|
||||
* 状态码定义
|
||||
*/
|
||||
enum ProjectStatusEnum: int
|
||||
{
|
||||
|
||||
// '状态 0:草稿 1:上架 2:下架 3:重构中'
|
||||
case DRAFT = 0;
|
||||
case ON_SHELF = 1;
|
||||
case OFF_SHELF = 2;
|
||||
case REBUILD = 3;
|
||||
public function description(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::DRAFT => '草稿',
|
||||
self::ON_SHELF => '上架',
|
||||
self::OFF_SHELF => '下架',
|
||||
self::REBUILD => '重构中',
|
||||
default => '未知状态',
|
||||
};
|
||||
}
|
||||
}
|
||||
20
app/Enum/StatusEnum.php
Executable file
20
app/Enum/StatusEnum.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enum;
|
||||
/**
|
||||
* 状态码定义
|
||||
*/
|
||||
enum StatusEnum: int
|
||||
{
|
||||
|
||||
// 状态 0:正常 1:禁用
|
||||
case NORMAL = 0;
|
||||
case DISABLE = 1;
|
||||
public function description(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::NORMAL => '正常',
|
||||
self::DISABLE => '禁用',
|
||||
};
|
||||
}
|
||||
}
|
||||
23
app/Enum/UserStatusEnum.php
Executable file
23
app/Enum/UserStatusEnum.php
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enum;
|
||||
/**
|
||||
* 状态码定义
|
||||
*/
|
||||
enum UserStatusEnum: int
|
||||
{
|
||||
|
||||
// 状态 0:正常 1:冻结 2:封号 3:注销
|
||||
case NORMAL = 0;
|
||||
case DISABLE = 1;
|
||||
case DELETED = 2;
|
||||
public function description(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::NORMAL => '正常',
|
||||
self::DISABLE => '冻结',
|
||||
self::DELETED => '注销',
|
||||
default => '未知',
|
||||
};
|
||||
}
|
||||
}
|
||||
22
app/Http/Controllers/CategoryController.php
Normal file
22
app/Http/Controllers/CategoryController.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\BaseApp\BaseController;
|
||||
use App\Service\CategoryService;
|
||||
use App\Service\LabelService;
|
||||
use App\Service\ProjectService;
|
||||
use App\Service\RoleService;
|
||||
|
||||
class CategoryController extends BaseController
|
||||
{
|
||||
//
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->service = CategoryService::getInstance();
|
||||
$this->insertField = ['name', 'pid', 'value'];
|
||||
$this->updateField = ['id', 'name', 'pid', 'value'];
|
||||
}
|
||||
}
|
||||
35
app/Http/Controllers/CollectionController.php
Normal file
35
app/Http/Controllers/CollectionController.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\BaseApp\BaseController;
|
||||
use App\Service\CollectionService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class CollectionController extends BaseController
|
||||
{
|
||||
//
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->service = CollectionService::getInstance();
|
||||
$this->insertField = ['project_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消收藏
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function unCollection(): JsonResponse
|
||||
{
|
||||
$projectId = request()->post('project_id');
|
||||
if (empty($projectId)) {
|
||||
return jerr('参数错误');
|
||||
}
|
||||
return jok(
|
||||
$this->service->unCollection($projectId),
|
||||
'取消成功'
|
||||
);
|
||||
}
|
||||
}
|
||||
21
app/Http/Controllers/FileController.php
Normal file
21
app/Http/Controllers/FileController.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\BaseApp\BaseController;
|
||||
use App\Service\FileService;
|
||||
use App\Service\ProjectService;
|
||||
use App\Service\RoleService;
|
||||
|
||||
class FileController extends BaseController
|
||||
{
|
||||
//
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->service = FileService::getInstance();
|
||||
$this->insertField = ['url', 's'];
|
||||
$this->updateField = ['id', 'url', 's'];
|
||||
}
|
||||
}
|
||||
51
app/Http/Controllers/HomeController.php
Normal file
51
app/Http/Controllers/HomeController.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\BaseApp\BaseController;
|
||||
use App\Service\HomeService;
|
||||
use App\Service\ProjectService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class HomeController extends BaseController
|
||||
{
|
||||
//
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->service = HomeService::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* 轮播图列表
|
||||
* @Method GET
|
||||
* @return JsonResponse
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function carousel(): JsonResponse
|
||||
{
|
||||
return jok(
|
||||
$this->service->carousel(),
|
||||
'轮播图列表'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目列表
|
||||
* @Method GET
|
||||
* @return JsonResponse
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function projectList(): JsonResponse
|
||||
{
|
||||
return jok(
|
||||
$this->service->projectList(),
|
||||
'项目列表'
|
||||
);
|
||||
}
|
||||
}
|
||||
21
app/Http/Controllers/LabelController.php
Normal file
21
app/Http/Controllers/LabelController.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\BaseApp\BaseController;
|
||||
use App\Service\LabelService;
|
||||
use App\Service\ProjectService;
|
||||
use App\Service\RoleService;
|
||||
|
||||
class LabelController extends BaseController
|
||||
{
|
||||
//
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->service = LabelService::getInstance();
|
||||
$this->insertField = ['name', 'pid', 'value'];
|
||||
$this->updateField = ['id', 'name', 'pid', 'value'];
|
||||
}
|
||||
}
|
||||
57
app/Http/Controllers/LoginController.php
Normal file
57
app/Http/Controllers/LoginController.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\BaseApp\BaseController;
|
||||
use App\Service\LoginService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class LoginController extends BaseController
|
||||
{
|
||||
//
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->service = LoginService::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @Method POST
|
||||
* @return JsonResponse
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function login()
|
||||
{
|
||||
$this->insertField = [
|
||||
'account', 'password', 'remember'
|
||||
];
|
||||
$param = $this->checkRequiredFields(request()->post());
|
||||
|
||||
return jok(
|
||||
$this->service->login($param['account'], $param['password']),
|
||||
'登录成功'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册
|
||||
* @Method POST
|
||||
* @return JsonResponse
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->insertField = [
|
||||
'account', 'password', 'email', 'code'
|
||||
];
|
||||
$param = $this->checkRequiredFields(request()->post());
|
||||
|
||||
return jok(
|
||||
$this->service->register($param['account'], $param['password'], $param['email'], $param['code']),
|
||||
'登录成功'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
63
app/Http/Controllers/ProjectController.php
Normal file
63
app/Http/Controllers/ProjectController.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\BaseApp\BaseController;
|
||||
use App\Service\ProjectService;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class ProjectController extends BaseController
|
||||
{
|
||||
//
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->service = ProjectService::getInstance();
|
||||
|
||||
// $this->insertField = [ 'title', 'features', 'cover', 'labels', 'description', 'category_id', 'video_url', 'price', 'front', 'service', 'deploy', 'status', 'module_image', 'flowchart'];
|
||||
// $this->updateField = [ 'id', 'title', 'features', 'cover', 'labels', 'description', 'category_id', 'video_url', 'price', 'front', 'service', 'deploy', 'status', 'module_image', 'flowchart'];
|
||||
$this->insertField = [ 'title', 'features', 'cover', 'labels', 'description', 'category_id', 'price', 'front', 'service', 'deploy', 'status', 'module_image', 'flowchart'];
|
||||
$this->updateField = [ 'id', 'title', 'features', 'cover', 'labels', 'description', 'category_id', 'price', 'front', 'service', 'deploy', 'status', 'module_image', 'flowchart'];
|
||||
$this->notRequest = ['screenshots', 'preferential_price', 'content', 'video_url'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改项目内容
|
||||
* @Method POST
|
||||
* @return JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function changeContent(): JsonResponse
|
||||
{
|
||||
$id = request()->post('id');
|
||||
$content = request()->post('content');
|
||||
if (empty($id) || empty($content)) {
|
||||
return jerr('参数错误');
|
||||
}
|
||||
return jok(
|
||||
$this->service->changeContent($id, $content),
|
||||
'修改成功'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改项目内容
|
||||
* @Method POST
|
||||
* @return JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function changeType(): JsonResponse
|
||||
{
|
||||
$id = request()->post('id');
|
||||
$type = request()->post('type');
|
||||
if (empty($id) || empty($type)) {
|
||||
return jerr('参数错误');
|
||||
}
|
||||
return jok(
|
||||
$this->service->changeType($id, $type),
|
||||
'修改成功'
|
||||
);
|
||||
}
|
||||
}
|
||||
20
app/Http/Controllers/RoleController.php
Normal file
20
app/Http/Controllers/RoleController.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\BaseApp\BaseController;
|
||||
use App\Service\ProjectService;
|
||||
use App\Service\RoleService;
|
||||
|
||||
class RoleController extends BaseController
|
||||
{
|
||||
//
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->service = RoleService::getInstance();
|
||||
$this->insertField = ['name', 'pid', 'value'];
|
||||
$this->updateField = ['id', 'name', 'pid', 'value'];
|
||||
}
|
||||
}
|
||||
48
app/Http/Controllers/UploadController.php
Normal file
48
app/Http/Controllers/UploadController.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\BaseApp\BaseController;
|
||||
use App\Service\common\UploadService;
|
||||
use App\Service\ProjectService;
|
||||
use App\Service\RoleService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class UploadController extends BaseController
|
||||
{
|
||||
//
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->service = UploadService::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片上传
|
||||
* @Method POST
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function image()
|
||||
{
|
||||
$file = request()->file('file');
|
||||
return jok(
|
||||
$this->service->uploadImage($file),
|
||||
'上传成功'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频上传
|
||||
* @Method POST
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function video()
|
||||
{
|
||||
$file = request()->file('file');
|
||||
return jok(
|
||||
$this->service->uploadVideo($file),
|
||||
'上传成功'
|
||||
);
|
||||
}
|
||||
}
|
||||
89
app/Http/Controllers/UserController.php
Normal file
89
app/Http/Controllers/UserController.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\BaseApp\BaseController;
|
||||
use App\Service\UserService;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class UserController extends BaseController
|
||||
{
|
||||
//
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->service = UserService::getInstance();
|
||||
$this->insertField = [ 'account', 'nick_name', 'password', 'role_id' ];
|
||||
$this->updateField = [ 'id', 'account', 'nick_name', 'role_id' ];
|
||||
$this->notRequest = ['qr_code', 'avatar', 'email', 'status'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
* @Method POST
|
||||
* @return JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function changePassword(): JsonResponse
|
||||
{
|
||||
$this->insertField = ['old_password', 'new_password', 'confirm_password'];
|
||||
$params = $this->checkRequiredFields(request()->post());
|
||||
|
||||
if ($params['old_password'] === $params['new_password']) {
|
||||
return jerr('新密码不能与旧密码相同');
|
||||
} elseif ($params['new_password'] !== $params['confirm_password']) {
|
||||
return jerr('新密码与确认密码不一致');
|
||||
}
|
||||
return jok(
|
||||
$this->service->changePassword($params['old_password'], $params['new_password']),
|
||||
'重置密码成功'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
* @Method POST
|
||||
* @return JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function resetPassword(): JsonResponse
|
||||
{
|
||||
$this->insertField = ['id', 'password', 'new_password'];
|
||||
$params = $this->checkRequiredFields(request()->post());
|
||||
|
||||
return jok(
|
||||
$this->service->resetPassword($params['id'], $params['password'], $params['new_password']),
|
||||
'重置密码成功'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户信息
|
||||
* @Method GET
|
||||
* @return JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function myInfo(): JsonResponse
|
||||
{
|
||||
return jok(
|
||||
$this->service->myInfo(),
|
||||
'获取成功'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户信息
|
||||
* @Method GET
|
||||
* @return JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function userStats(): JsonResponse
|
||||
{
|
||||
return jok(
|
||||
$this->service->userStats(),
|
||||
'获取成功'
|
||||
);
|
||||
}
|
||||
}
|
||||
26
app/Models/CategoryModel.php
Normal file
26
app/Models/CategoryModel.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
/**
|
||||
* 分类表
|
||||
*/
|
||||
class CategoryModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'categories';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 项目
|
||||
* @return HasMany
|
||||
*/
|
||||
public function projects(): HasMany
|
||||
{
|
||||
return $this->hasMany(ProjectModel::class, 'category_id', 'id');
|
||||
}
|
||||
}
|
||||
36
app/Models/CollectionModel.php
Normal file
36
app/Models/CollectionModel.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
/**
|
||||
* 用户收藏表
|
||||
*/
|
||||
class CollectionModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'collection';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 用户关联
|
||||
* @return HasOne
|
||||
*/
|
||||
public function user(): HasOne
|
||||
{
|
||||
return $this->hasOne(UserModel::class, 'id', 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目关联
|
||||
* @return HasOne
|
||||
*/
|
||||
public function project(): HasOne
|
||||
{
|
||||
return $this->hasOne(ProjectModel::class, 'id', 'project_id');
|
||||
}
|
||||
}
|
||||
16
app/Models/FeatureModel.php
Normal file
16
app/Models/FeatureModel.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
|
||||
/**
|
||||
* 核心功能表
|
||||
*/
|
||||
class FeatureModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'features';
|
||||
|
||||
protected $guarded = [];
|
||||
}
|
||||
27
app/Models/FileModel.php
Normal file
27
app/Models/FileModel.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
/**
|
||||
* 用户表
|
||||
*/
|
||||
class FileModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'file';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 角色关联
|
||||
* @return HasOne
|
||||
*/
|
||||
public function user(): HasOne
|
||||
{
|
||||
return $this->hasOne(UserModel::class, 'id', 'user_id');
|
||||
}
|
||||
}
|
||||
26
app/Models/FrameworkModel.php
Normal file
26
app/Models/FrameworkModel.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
/**
|
||||
* 框架表
|
||||
*/
|
||||
class FrameworkModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'frameworks';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 项目关联
|
||||
* @return BelongsToMany
|
||||
*/
|
||||
public function projects()
|
||||
{
|
||||
return $this->belongsToMany(ProjectModel::class, 'project_frameworks_relations', 'framework_id', 'project_id');
|
||||
}
|
||||
}
|
||||
26
app/Models/LabelModel.php
Normal file
26
app/Models/LabelModel.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
/**
|
||||
* 标签表
|
||||
*/
|
||||
class LabelModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'labels';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 项目关联
|
||||
* @return BelongsToMany
|
||||
*/
|
||||
public function projects(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(ProjectModel::class, 'project_labels_relations', 'label_id', 'project_id');
|
||||
}
|
||||
}
|
||||
16
app/Models/OrderItemModel.php
Normal file
16
app/Models/OrderItemModel.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
|
||||
/**
|
||||
* 订单详情表
|
||||
*/
|
||||
class OrderItemModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'order_items';
|
||||
|
||||
protected $guarded = [];
|
||||
}
|
||||
36
app/Models/OrderModel.php
Normal file
36
app/Models/OrderModel.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
/**
|
||||
* 订单表
|
||||
*/
|
||||
class OrderModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'orders';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 用户关联
|
||||
* @return HasOne
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->hasOne(UserModel::class, 'id', 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单详情
|
||||
* @return HasMany
|
||||
*/
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(OrderItemModel::class, 'order_id', 'id');
|
||||
}
|
||||
}
|
||||
16
app/Models/PartnerModel.php
Normal file
16
app/Models/PartnerModel.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
|
||||
/**
|
||||
* 合作伙伴表
|
||||
*/
|
||||
class PartnerModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'partners';
|
||||
|
||||
protected $guarded = [];
|
||||
}
|
||||
16
app/Models/ProjectFrameworksRelationModel.php
Normal file
16
app/Models/ProjectFrameworksRelationModel.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
|
||||
/**
|
||||
* 项目框架关联表
|
||||
*/
|
||||
class ProjectFrameworksRelationModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'project_frameworks_relations';
|
||||
|
||||
protected $guarded = [];
|
||||
}
|
||||
35
app/Models/ProjectLabelRelationModel.php
Normal file
35
app/Models/ProjectLabelRelationModel.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
/**
|
||||
* 项目标签关联表
|
||||
*/
|
||||
class ProjectLabelRelationModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'project_label_relations';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 项目
|
||||
* @return HasOne
|
||||
*/
|
||||
public function project(): HasOne
|
||||
{
|
||||
return $this->hasOne(ProjectModel::class, 'id', 'project_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 标签
|
||||
* @return HasOne
|
||||
*/
|
||||
public function label(): HasOne
|
||||
{
|
||||
return $this->hasOne(LabelModel::class, 'id', 'label_id');
|
||||
}
|
||||
}
|
||||
82
app/Models/ProjectModel.php
Normal file
82
app/Models/ProjectModel.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
/**
|
||||
* 项目表
|
||||
*/
|
||||
class ProjectModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'projects';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 用户关联
|
||||
* @return HasOne
|
||||
*/
|
||||
public function user(): HasOne
|
||||
{
|
||||
return $this->hasOne(UserModel::class, 'id', 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 作者关联
|
||||
* @return HasOne
|
||||
*/
|
||||
public function author(): HasOne
|
||||
{
|
||||
return $this->hasOne(UserModel::class, 'id', 'author_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 标签关联
|
||||
* @return BelongsToMany
|
||||
*/
|
||||
public function labels(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(LabelModel::class, 'project_label_relations', 'project_id', 'label_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 截图关联
|
||||
* @return HasMany
|
||||
*/
|
||||
public function screenshots(): HasMany
|
||||
{
|
||||
return $this->hasMany(ScreenshotModel::class, 'project_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 框架关联
|
||||
* @return BelongsToMany
|
||||
*/
|
||||
public function frameworks(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(FrameworkModel::class, 'project_frameworks_relations', 'project_id', 'framework_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能关联
|
||||
* @return HasMany
|
||||
*/
|
||||
public function features(): HasMany
|
||||
{
|
||||
return $this->hasMany(FeatureModel::class, 'project_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 分类关联
|
||||
* @return HasOne
|
||||
*/
|
||||
public function category(): HasOne
|
||||
{
|
||||
return $this->hasOne(CategoryModel::class, 'id', 'category_id');
|
||||
}
|
||||
}
|
||||
16
app/Models/RoleModel.php
Normal file
16
app/Models/RoleModel.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
|
||||
/**
|
||||
* 角色表
|
||||
*/
|
||||
class RoleModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'roles';
|
||||
|
||||
protected $guarded = [];
|
||||
}
|
||||
16
app/Models/ScreenshotModel.php
Normal file
16
app/Models/ScreenshotModel.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
|
||||
/**
|
||||
* 截图表
|
||||
*/
|
||||
class ScreenshotModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'screenshots';
|
||||
|
||||
protected $guarded = [];
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
}
|
||||
45
app/Models/UserModel.php
Normal file
45
app/Models/UserModel.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
/**
|
||||
* 用户表
|
||||
*/
|
||||
class UserModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'users';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 项目关联 - 上传视角
|
||||
* @return HasMany
|
||||
*/
|
||||
public function projects(): HasMany
|
||||
{
|
||||
return $this->hasMany(ProjectModel::class, 'user_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目关联 - 作者视角
|
||||
* @return HasMany
|
||||
*/
|
||||
public function projectsAuthor(): HasMany
|
||||
{
|
||||
return $this->hasMany(ProjectModel::class, 'author_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色关联
|
||||
* @return HasOne
|
||||
*/
|
||||
public function roles(): HasOne
|
||||
{
|
||||
return $this->hasOne(RoleModel::class, 'id', 'role_id');
|
||||
}
|
||||
}
|
||||
36
app/Models/UserPayModel.php
Normal file
36
app/Models/UserPayModel.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\BaseApp\BaseModel;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
/**
|
||||
* 用户收藏表
|
||||
*/
|
||||
class UserPayModel extends BaseModel
|
||||
{
|
||||
//
|
||||
protected $table = 'user_pay';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 用户关联
|
||||
* @return HasOne
|
||||
*/
|
||||
public function user(): HasOne
|
||||
{
|
||||
return $this->hasOne(UserModel::class, 'id', 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目关联
|
||||
* @return HasOne
|
||||
*/
|
||||
public function project(): HasOne
|
||||
{
|
||||
return $this->hasOne(ProjectModel::class, 'id', 'project_id');
|
||||
}
|
||||
}
|
||||
84
app/Service/CategoryService.php
Normal file
84
app/Service/CategoryService.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\BaseApp\BaseService;
|
||||
use App\Models\CategoryModel;
|
||||
use App\Models\LabelModel;
|
||||
use App\Models\ProjectModel;
|
||||
use App\Models\RoleModel;
|
||||
use App\Models\UserModel;
|
||||
use Exception;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class CategoryService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->selectField = ['id', 'name', 'created_at', 'updated_at', 'deleted_at'];
|
||||
$this->model = CategoryModel::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目列表
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function list(): array
|
||||
{
|
||||
return $this->getPageList();
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
return $this->getDetail($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目下拉列表
|
||||
* @return mixed
|
||||
*/
|
||||
public function option()
|
||||
{
|
||||
$this->optionField = ['id', 'name'];
|
||||
return $this->getOption();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建项目
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create($params): mixed
|
||||
{
|
||||
return $this->insert($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑项目
|
||||
* @param $id
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update($id, $params): mixed
|
||||
{
|
||||
return $this->save($id, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除项目
|
||||
* @param $ids
|
||||
* @return mixed|true
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete($ids): mixed
|
||||
{
|
||||
return $this->del($ids);
|
||||
}
|
||||
|
||||
}
|
||||
112
app/Service/CollectionService.php
Normal file
112
app/Service/CollectionService.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\BaseApp\BaseService;
|
||||
use App\Models\CollectionModel;
|
||||
use App\Models\FileModel;
|
||||
use App\Models\ProjectModel;
|
||||
use App\Models\RoleModel;
|
||||
use App\Models\UserModel;
|
||||
use Exception;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class CollectionService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->selectField = ['id', 'user_id', 'project_id', 'created_at', 'updated_at', 'deleted_at'];
|
||||
$this->model = CollectionModel::class;
|
||||
$this->where[] = ['user_id', '=', $this->userId];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户收藏列表
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function list(): array
|
||||
{
|
||||
$this->with = [
|
||||
'project:id,title,cover,category_id,description,price,preferential_price,front,service,deploy,status,created_at,updated_at',
|
||||
'project.category:id,name',
|
||||
'project.labels:id,name',
|
||||
];
|
||||
return $this->getPageList();
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
return $this->getDetail($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户收藏下拉列表
|
||||
* @return mixed
|
||||
*/
|
||||
public function option()
|
||||
{
|
||||
$this->optionField = ['id', 'url'];
|
||||
return $this->getOption();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建用户收藏
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create($params): mixed
|
||||
{
|
||||
$myCollectionModel = $this->model::where('user_id', $this->userId)->where('project_id', $params['project_id'])->first();
|
||||
if ($myCollectionModel) {
|
||||
if (!empty($myCollectionModel['deleted_at'])) {
|
||||
return $this->model::where('id', $myCollectionModel['id'])->update([
|
||||
'deleted_at' => 0
|
||||
]);
|
||||
}
|
||||
$this->utils->errorThrow('您已收藏过该项目');
|
||||
}
|
||||
$params['user_id'] = $this->userId;
|
||||
return $this->insert($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消收藏
|
||||
* @param $projectId
|
||||
* @return mixed
|
||||
*/
|
||||
public function unCollection($projectId)
|
||||
{
|
||||
return $this->model::where('user_id', $this->userId)->where('project_id', $projectId)->update([
|
||||
'deleted_at' => get_time()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户收藏
|
||||
* @param $id
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update($id, $params): mixed
|
||||
{
|
||||
return $this->save($id, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户收藏
|
||||
* @param $ids
|
||||
* @return mixed|true
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete($ids): mixed
|
||||
{
|
||||
return $this->del($ids);
|
||||
}
|
||||
|
||||
}
|
||||
83
app/Service/FileService.php
Normal file
83
app/Service/FileService.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\BaseApp\BaseService;
|
||||
use App\Models\FileModel;
|
||||
use App\Models\ProjectModel;
|
||||
use App\Models\RoleModel;
|
||||
use App\Models\UserModel;
|
||||
use Exception;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class FileService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->selectField = ['id', 'user_id', 'url', 'type', 'created_at', 'updated_at', 'deleted_at'];
|
||||
$this->model = FileModel::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件列表
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function list(): array
|
||||
{
|
||||
return $this->getPageList();
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
return $this->getDetail($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下拉列表
|
||||
* @return mixed
|
||||
*/
|
||||
public function option()
|
||||
{
|
||||
$this->optionField = ['id', 'url'];
|
||||
return $this->getOption();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create($params): mixed
|
||||
{
|
||||
return $this->insert($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑文件
|
||||
* @param $id
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update($id, $params): mixed
|
||||
{
|
||||
return $this->save($id, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param $ids
|
||||
* @return mixed|true
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete($ids): mixed
|
||||
{
|
||||
return $this->del($ids);
|
||||
}
|
||||
|
||||
}
|
||||
103
app/Service/HomeService.php
Normal file
103
app/Service/HomeService.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\BaseApp\BaseService;
|
||||
use App\Enum\ProjectStatusEnum;
|
||||
use App\Enum\StatusEnum;
|
||||
use App\Models\CollectionModel;
|
||||
use App\Models\FeatureModel;
|
||||
use App\Models\ProjectLabelRelationModel;
|
||||
use App\Models\ProjectModel;
|
||||
use App\Models\ScreenshotModel;
|
||||
use App\Models\UserModel;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class HomeService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->isAuth = false;
|
||||
parent::__construct();
|
||||
$this->selectField = [ 'id', 'user_id', 'title', 'cover', 'category_id', 'is_sold', 'description', 'module_image', 'flowchart', 'content', 'video_url', 'author_id', 'price', 'preferential_price', 'front', 'service', 'deploy', 'status', 'created_at', 'updated_at', 'deleted_at', ];
|
||||
$this->model = ProjectModel::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取精选项目
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function list(): array
|
||||
{
|
||||
$this->where[] = [ 'is_selected', '=', 1 ];
|
||||
$this->where[] = [ 'status', '=', 1 ];
|
||||
$this->with = [
|
||||
'frameworks:id,name',
|
||||
'labels:id,name',
|
||||
'category:id,name',
|
||||
];
|
||||
return $this->getPageList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目列表
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function projectList(): array
|
||||
{
|
||||
$this->queryField = [
|
||||
'title' => 'like'
|
||||
];
|
||||
$this->where[] = [ 'status', '=', 1 ];
|
||||
$this->with = [
|
||||
'frameworks:id,name',
|
||||
'labels:id,name',
|
||||
'category:id,name',
|
||||
];
|
||||
return $this->getPageList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取轮播图
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function carousel(): array
|
||||
{
|
||||
$this->where[] = [ 'is_carousel', '=', 1 ];
|
||||
$this->where[] = [ 'status', '=', 1 ];
|
||||
$this->with = [
|
||||
'frameworks:id,name',
|
||||
'labels:id,name',
|
||||
'category:id,name',
|
||||
];
|
||||
return $this->getPageList();
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
$this->with = [
|
||||
'frameworks:id,name',
|
||||
'labels:id,name',
|
||||
'category:id,name',
|
||||
'screenshots:id,url,project_id',
|
||||
'features:id,project_id,name',
|
||||
'author:id,nick_name,avatar,email'
|
||||
];
|
||||
$result = $this->getDetail($id);
|
||||
if (!empty($this->userId)) {
|
||||
$result['is_collection'] = CollectionModel::where('project_id', $id)->where('user_id', $this->userId)->exists();
|
||||
} else {
|
||||
$result['is_collection'] = false;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
83
app/Service/LabelService.php
Normal file
83
app/Service/LabelService.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\BaseApp\BaseService;
|
||||
use App\Models\LabelModel;
|
||||
use App\Models\ProjectModel;
|
||||
use App\Models\RoleModel;
|
||||
use App\Models\UserModel;
|
||||
use Exception;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class LabelService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->selectField = ['id', 'name', 'created_at', 'updated_at', 'deleted_at'];
|
||||
$this->model = LabelModel::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目列表
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function list(): array
|
||||
{
|
||||
return $this->getPageList();
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
return $this->getDetail($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目下拉列表
|
||||
* @return mixed
|
||||
*/
|
||||
public function option()
|
||||
{
|
||||
$this->optionField = ['id', 'name'];
|
||||
return $this->getOption();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建项目
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create($params): mixed
|
||||
{
|
||||
return $this->insert($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑项目
|
||||
* @param $id
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update($id, $params): mixed
|
||||
{
|
||||
return $this->save($id, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除项目
|
||||
* @param $ids
|
||||
* @return mixed|true
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete($ids): mixed
|
||||
{
|
||||
return $this->del($ids);
|
||||
}
|
||||
|
||||
}
|
||||
135
app/Service/LoginService.php
Normal file
135
app/Service/LoginService.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Models\UserModel;
|
||||
use App\Service\common\JWTService;
|
||||
use App\Service\common\UtilsService;
|
||||
use Exception;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class LoginService
|
||||
{
|
||||
|
||||
/**
|
||||
* @var mixed 单例实例,确保该类只有一个全局实例
|
||||
*/
|
||||
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 $account
|
||||
* @param $password
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function login($account, $password): array
|
||||
{
|
||||
$userModel = UserModel::with(['roles:id,name,value'])->where('account', $account)->first();
|
||||
if (empty($userModel)) {
|
||||
UtilsService::getInstance()->errorThrow('用户或密码错误!');
|
||||
// return $this->register($account, $password);
|
||||
}
|
||||
|
||||
if (!password_verify($password, $userModel->password)) {
|
||||
UtilsService::getInstance()->errorThrow('用户或密码错误!');
|
||||
}
|
||||
|
||||
if ($userModel->ip !== get_ip()) {
|
||||
$ipTable = json_decode($userModel->ip_table, true);
|
||||
if (!in_array(get_ip(), $ipTable)) {
|
||||
$ipTable[] = get_ip();
|
||||
}
|
||||
$update = UserModel::where('id', $userModel->id)->update([
|
||||
'ip' => get_ip(),
|
||||
'ip_table' => json_encode($ipTable),
|
||||
'updated_at' => get_time()
|
||||
]);
|
||||
|
||||
if (!$update) {
|
||||
UtilsService::getInstance()->errorThrow('更新失败!');
|
||||
}
|
||||
|
||||
$userModel = UserModel::where('id', $userModel->id)->first();
|
||||
}
|
||||
$result = [
|
||||
'id' => $userModel->id,
|
||||
'account' => $userModel->account,
|
||||
'nick_name' => $userModel->nick_name,
|
||||
'avatar' => $userModel->avatar,
|
||||
'email' => $userModel->email,
|
||||
'role_name' => $userModel->roles->name,
|
||||
'role_value' => $userModel->roles->value,
|
||||
'ip' => $userModel->ip,
|
||||
'ip_table' => $userModel->ip_table,
|
||||
];
|
||||
$token = JWTService::getInstance()->generateToken($result);
|
||||
$result['token'] = $token;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册
|
||||
* @param $account
|
||||
* @param $password
|
||||
* @param $email
|
||||
* @param $code
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function register($account, $password, $email, $code): array
|
||||
{
|
||||
$userModel = UserModel::where('account', $account)->first();
|
||||
if ($userModel) {
|
||||
UtilsService::getInstance()->errorThrow('账号已被占用!');
|
||||
}
|
||||
|
||||
$createModel = UserModel::create([
|
||||
'account' => $account,
|
||||
'email' => $email,
|
||||
'password' => password_hash($password, PASSWORD_DEFAULT),
|
||||
'nick_name' => '新用户'. Str::random(),
|
||||
'avatar' => 'https://pic.rmb.bdstatic.com/bjh/80852bfe7c321988191838517ba64e309354.jpeg@h_1280',
|
||||
'role_id' => 2,
|
||||
'ip' => get_ip(),
|
||||
'ip_table' => json_encode([get_ip()]),
|
||||
'created_at' => get_time()
|
||||
]);
|
||||
|
||||
if (!$createModel) {
|
||||
UtilsService::getInstance()->errorThrow('注册失败!');
|
||||
}
|
||||
|
||||
$userInfo = UserModel::with(['roles:id,name,value'])->where('id', $createModel->id)->first();
|
||||
|
||||
$result = [
|
||||
'id' => $userInfo->id,
|
||||
'account' => $userInfo->account,
|
||||
'nick_name' => $userInfo->nick_name,
|
||||
'avatar' => $userInfo->avatar,
|
||||
'email' => $userInfo->email?? '',
|
||||
'role_name' => $userInfo->roles->name,
|
||||
'role_value' => $userInfo->roles->value,
|
||||
'ip' => $userInfo->ip,
|
||||
'ip_table' => $userInfo->ip_table,
|
||||
];
|
||||
$token = JWTService::getInstance()->generateToken($result);
|
||||
$result['token'] = $token;
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
288
app/Service/ProjectService.php
Normal file
288
app/Service/ProjectService.php
Normal file
@@ -0,0 +1,288 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\BaseApp\BaseService;
|
||||
use App\Enum\ProjectFieldTypeEnum;
|
||||
use App\Enum\ProjectStatusEnum;
|
||||
use App\Enum\StatusEnum;
|
||||
use App\Models\CollectionModel;
|
||||
use App\Models\FeatureModel;
|
||||
use App\Models\ProjectLabelRelationModel;
|
||||
use App\Models\ProjectModel;
|
||||
use App\Models\ScreenshotModel;
|
||||
use App\Models\UserModel;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class ProjectService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->selectField = [ 'id', 'user_id', 'title', 'is_selected', 'is_carousel', 'module_image', 'is_sold', 'flowchart', 'content', 'cover', 'category_id', 'description', 'video_url', 'author_id', 'price', 'preferential_price', 'front', 'service', 'deploy', 'status', 'created_at', 'updated_at', 'deleted_at', ];
|
||||
$this->model = ProjectModel::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目列表
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function list(): array
|
||||
{
|
||||
$this->with = [
|
||||
'frameworks:id,name',
|
||||
'features:id,project_id,name',
|
||||
'labels:id,name',
|
||||
'category:id,name',
|
||||
'screenshots:id,url,project_id',
|
||||
// 'features:id,project_id,name',
|
||||
'author:id,nick_name,avatar'
|
||||
];
|
||||
$result = $this->getPageList();
|
||||
|
||||
foreach ($result['items'] as &$item) {
|
||||
$item['status_text'] = ProjectStatusEnum::from($item['status'])->description();
|
||||
$item['features_names'] = array_column($item['features'], 'name');
|
||||
$item['label_ids'] = array_column($item['labels'], 'id');
|
||||
$item['screenshots'] = array_column($item['screenshots'], 'url');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
$this->with = [
|
||||
'frameworks:id,name',
|
||||
'labels:id,name',
|
||||
'category:id,name',
|
||||
'screenshots:id,url,project_id',
|
||||
'features:id,project_id,name',
|
||||
'author:id,nick_name,avatar'
|
||||
];
|
||||
|
||||
return $this->getDetail($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目下拉列表
|
||||
* @return mixed
|
||||
*/
|
||||
public function option()
|
||||
{
|
||||
$this->optionField = ['id', 'title'];
|
||||
return $this->getOption();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改项目详细介绍
|
||||
* @param $id
|
||||
* @param $content
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function changeContent($id, $content)
|
||||
{
|
||||
return $this->save($id, ['content' => $content]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建项目
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create($params): mixed
|
||||
{
|
||||
$params['user_id'] = $this->userId;
|
||||
$params['author_id'] = $params['author_id']?? $this->userId;
|
||||
$screenshots = $params['screenshots'];
|
||||
$labels = $params['labels'];
|
||||
$features = $params['features'];
|
||||
if (empty($params['preferential_price'])) {
|
||||
$params['preferential_price'] = $params['price'];
|
||||
}
|
||||
if (empty($params['content'])) {
|
||||
$params['content'] = '';
|
||||
}
|
||||
unset($params['screenshots'], $params['labels'], $params['features']);
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$insertProjectModel = $this->insert($params);
|
||||
|
||||
$labelInsertData = [];
|
||||
foreach ($labels as $label) {
|
||||
if (!empty($label)) {
|
||||
$labelInsertData[] = [
|
||||
'project_id' => $insertProjectModel,
|
||||
'label_id' => $label,
|
||||
'created_at' => get_time()
|
||||
];
|
||||
}
|
||||
}
|
||||
$insertLabelModel = ProjectLabelRelationModel::insert($labelInsertData);
|
||||
|
||||
if (!$insertLabelModel) {
|
||||
$this->utils->errorThrow('标签添加失败');
|
||||
}
|
||||
|
||||
$featureInsertData = [];
|
||||
foreach ($features as $feature) {
|
||||
if (!empty($feature)) {
|
||||
$featureInsertData[] = [
|
||||
'project_id' => $insertProjectModel,
|
||||
'name' => $feature,
|
||||
'created_at' => get_time()
|
||||
];
|
||||
}
|
||||
}
|
||||
$insertFeatureModel = FeatureModel::insert($featureInsertData);
|
||||
if (!$insertFeatureModel) {
|
||||
$this->utils->errorThrow('项目功能添加失败');
|
||||
}
|
||||
|
||||
$screenInsertData = [];
|
||||
foreach ($screenshots as $screenshot) {
|
||||
if (!empty($screenshot)) {
|
||||
$screenInsertData[] = [
|
||||
'project_id' => $insertProjectModel,
|
||||
'url' => $screenshot,
|
||||
'created_at' => get_time()
|
||||
];
|
||||
}
|
||||
}
|
||||
$insertScreenModel = ScreenshotModel::insert($screenInsertData);
|
||||
if (!$insertScreenModel) {
|
||||
$this->utils->errorThrow('项目截图添加失败');
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
} catch (Exception $e) {
|
||||
DB::rollBack();
|
||||
$this->utils->errorThrow($e->getMessage());
|
||||
}
|
||||
|
||||
return $insertProjectModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑项目
|
||||
* @param $id
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update($id, $params): mixed
|
||||
{
|
||||
$params['user_id'] = $this->userId;
|
||||
$params['author_id'] = $params['author_id']?? $this->userId;
|
||||
$screenshots = $params['screenshots']?? [];
|
||||
$labels = $params['labels']?? [];
|
||||
$features = $params['features']?? [];
|
||||
unset($params['screenshots'], $params['labels'], $params['features']);
|
||||
|
||||
if (empty($params['content'])) {
|
||||
$params['content'] = '';
|
||||
}
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
// 更新项目基本信息
|
||||
$updateProjectModel = $this->save($id, $params);
|
||||
|
||||
// 先删除旧的标签关联数据
|
||||
ProjectLabelRelationModel::where('project_id', $id)->delete();
|
||||
$labelInsertData = [];
|
||||
foreach ($labels as $label) {
|
||||
$labelInsertData[] = [
|
||||
'project_id' => $id,
|
||||
'label_id' => $label,
|
||||
'created_at' => get_time()
|
||||
];
|
||||
}
|
||||
if (!empty($labelInsertData)) {
|
||||
$insertLabelModel = ProjectLabelRelationModel::insert($labelInsertData);
|
||||
if (!$insertLabelModel) {
|
||||
$this->utils->errorThrow('标签更新失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 先删除旧的功能数据
|
||||
FeatureModel::where('project_id', $id)->delete();
|
||||
$featureInsertData = [];
|
||||
foreach ($features as $feature) {
|
||||
$featureInsertData[] = [
|
||||
'project_id' => $id,
|
||||
'name' => $feature,
|
||||
'created_at' => get_time()
|
||||
];
|
||||
}
|
||||
if (!empty($featureInsertData)) {
|
||||
$insertFeatureModel = FeatureModel::insert($featureInsertData);
|
||||
if (!$insertFeatureModel) {
|
||||
$this->utils->errorThrow('项目功能更新失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 先删除旧的截图数据
|
||||
ScreenshotModel::where('project_id', $id)->delete();
|
||||
$screenInsertData = [];
|
||||
foreach ($screenshots as $screenshot) {
|
||||
$screenInsertData[] = [
|
||||
'project_id' => $id,
|
||||
'url' => $screenshot,
|
||||
'created_at' => get_time()
|
||||
];
|
||||
}
|
||||
if (!empty($screenInsertData)) {
|
||||
$insertScreenModel = ScreenshotModel::insert($screenInsertData);
|
||||
if (!$insertScreenModel) {
|
||||
$this->utils->errorThrow('项目截图更新失败');
|
||||
}
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
} catch (Exception $e) {
|
||||
DB::rollBack();
|
||||
$this->utils->errorThrow($e->getMessage());
|
||||
}
|
||||
|
||||
return $updateProjectModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除项目
|
||||
* @param $ids
|
||||
* @return mixed|true
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete($ids): mixed
|
||||
{
|
||||
return $this->del($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改项目(是否精选、是否出售、是否为轮播图)
|
||||
* @param $id
|
||||
* @param $type
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function changeType($id, $type): mixed
|
||||
{
|
||||
$field = ProjectFieldTypeEnum::from($type)->description();
|
||||
$this->selectField = [$field];
|
||||
$detail = $this->detail($id);
|
||||
if (empty($detail)) {
|
||||
$this->utils->errorThrow('项目不存在');
|
||||
}
|
||||
$update = $this->save($id, [$field => $detail[$field] === 0? 1 : 0]);
|
||||
if (!$update) {
|
||||
$this->utils->errorThrow('项目状改失败');
|
||||
}
|
||||
return $update;
|
||||
}
|
||||
}
|
||||
82
app/Service/RoleService.php
Normal file
82
app/Service/RoleService.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\BaseApp\BaseService;
|
||||
use App\Models\ProjectModel;
|
||||
use App\Models\RoleModel;
|
||||
use App\Models\UserModel;
|
||||
use Exception;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class RoleService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->selectField = ['id', 'name', 'value', 'pid', 'desc', 'created_at', 'updated_at', 'deleted_at'];
|
||||
$this->model = RoleModel::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目列表
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function list(): array
|
||||
{
|
||||
return $this->getPageList();
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
return $this->getDetail($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目下拉列表
|
||||
* @return mixed
|
||||
*/
|
||||
public function option()
|
||||
{
|
||||
$this->optionField = ['id', 'name'];
|
||||
return $this->getOption();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建项目
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create($params): mixed
|
||||
{
|
||||
return $this->insert($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑项目
|
||||
* @param $id
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update($id, $params): mixed
|
||||
{
|
||||
return $this->save($id, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除项目
|
||||
* @param $ids
|
||||
* @return mixed|true
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete($ids): mixed
|
||||
{
|
||||
return $this->del($ids);
|
||||
}
|
||||
|
||||
}
|
||||
210
app/Service/UserService.php
Normal file
210
app/Service/UserService.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\BaseApp\BaseService;
|
||||
use App\Enum\UserStatusEnum;
|
||||
use App\Models\CollectionModel;
|
||||
use App\Models\RoleModel;
|
||||
use App\Models\UserModel;
|
||||
use App\Models\UserPayModel;
|
||||
use Exception;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class UserService extends BaseService
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->selectField = [ 'id', 'account', 'nick_name', 'avatar', 'email', 'balance', 'is_sys_notifications', 'is_collection_notifications', 'is_marketing_notifications', 'qr_code', 'role_id', 'ip', 'ip_table', 'status', 'last_reset_password_at', 'created_at', 'updated_at', 'deleted_at', ];
|
||||
$this->model = UserModel::class;
|
||||
$this->queryField = [
|
||||
'account' => 'like',
|
||||
'nick_name' => 'like',
|
||||
'email' => 'like',
|
||||
'role_id' => '=',
|
||||
'status' => '=',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function list(): array
|
||||
{
|
||||
$this->with = [
|
||||
'roles'
|
||||
];
|
||||
$result = $this->getPageList();
|
||||
|
||||
foreach ($result['items'] as &$v) {
|
||||
$v['ip_table'] = json_decode($v['ip_table'], true);
|
||||
$v['status_text'] = UserStatusEnum::from($v['status'])->description();
|
||||
$v['last_reset_password_at'] = format_time($v['last_reset_password_at']);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
$result = $this->getDetail($id);
|
||||
$result['ip_table'] = json_decode($result['ip_table'], true);
|
||||
$result['status_text'] = UserStatusEnum::from($result['status'])->description();
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function option()
|
||||
{
|
||||
$this->optionField = ['id', 'nick_name'];
|
||||
return $this->getOption();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建用户
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create($params): mixed
|
||||
{
|
||||
$params['ip_table'] = json_encode([]);
|
||||
$params['password'] = password_hash($params['password'], PASSWORD_DEFAULT);
|
||||
$existsUser = $this->model::where('account', $params['account'])->whereOr('email', $params['email'])->exists();
|
||||
if ($existsUser) {
|
||||
$this->utils->errorThrow('账号或邮箱已存在');
|
||||
}
|
||||
|
||||
return $this->insert($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户
|
||||
* @param $id
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update($id, $params): mixed
|
||||
{
|
||||
return $this->save($id, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* @param $ids
|
||||
* @return mixed|true
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete($ids): mixed
|
||||
{
|
||||
return $this->del($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
* @param $password
|
||||
* @param $newPassword
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function changePassword($password, $newPassword): mixed
|
||||
{
|
||||
$info = $this->model::find($this->userId);
|
||||
if (empty($info)) {
|
||||
return $this->utils->notFound('数据不存在');
|
||||
}
|
||||
if (!password_verify($password, $info['password'])) {
|
||||
return $this->utils->errorThrow('密码错误');
|
||||
}
|
||||
if (password_verify($newPassword, $info['password'])) {
|
||||
return $this->utils->errorThrow('新密码不能与旧密码相同');
|
||||
}
|
||||
$result = $this->model::where('id', $this->userId)->update([
|
||||
'password' => password_hash($newPassword, PASSWORD_DEFAULT),
|
||||
'last_reset_password_at' => get_time()
|
||||
]);
|
||||
if (!$result) {
|
||||
return $this->utils->errorThrow('重置密码失败');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
* @param $id
|
||||
* @param $password
|
||||
* @param $newPassword
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function resetPassword($id, $password, $newPassword): mixed
|
||||
{
|
||||
if ($password !== $newPassword) {
|
||||
return $this->utils->errorThrow('两次密码不一致');
|
||||
}
|
||||
$info = $this->model::find($id);
|
||||
if (empty($info)) {
|
||||
return $this->utils->notFound('数据不存在');
|
||||
}
|
||||
if (password_verify($newPassword, $info['password'])) {
|
||||
return $this->utils->errorThrow('新密码不能与旧密码相同');
|
||||
}
|
||||
$result = $this->model::where('id', $id)->update([
|
||||
'password' => password_hash($newPassword, PASSWORD_DEFAULT),
|
||||
'last_reset_password_at' => get_time()
|
||||
]);
|
||||
if (!$result) {
|
||||
return $this->utils->errorThrow('重置密码失败');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function myInfo(): mixed
|
||||
{
|
||||
$this->with = [
|
||||
'roles'
|
||||
];
|
||||
$result = $this->getDetail($this->userId);
|
||||
$result['created_day_at'] = format_time(strtotime($result['created_at']), 'Y-m-d');
|
||||
$result['account'] = desensitization($result['account']);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户统计
|
||||
* @return array[]
|
||||
*/
|
||||
public function userStats()
|
||||
{
|
||||
$payProject = UserPayModel::where('user_id', $this->userId)->count();
|
||||
$collection = CollectionModel::where('user_id', $this->userId)->count();
|
||||
$role = $this->userInfo['role_name'];
|
||||
return [
|
||||
'pay_project' => [
|
||||
'label' => '已购项目',
|
||||
'value' => $payProject,
|
||||
'icon' => 'shopping-bag'
|
||||
],
|
||||
'collection' => [
|
||||
'label' => '我的收藏',
|
||||
'value' => $collection,
|
||||
'icon' => 'heart'
|
||||
],
|
||||
'role' => [
|
||||
'label' => '用户类型',
|
||||
'value' => $role,
|
||||
'icon' => 'user'
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
112
app/Service/common/JWTService.php
Executable file
112
app/Service/common/JWTService.php
Executable file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service\common;
|
||||
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\Key;
|
||||
use Exception;
|
||||
|
||||
class JWTService
|
||||
{
|
||||
private static mixed $_instance;
|
||||
private string $secretKey = 'cc_spa_jwt_secret_key'; // 请替换为你的密钥
|
||||
|
||||
private string $token;
|
||||
|
||||
/**
|
||||
* 获取实例
|
||||
* @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];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Token
|
||||
* @return $this|null
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getToken(): null|static
|
||||
{
|
||||
$token = request()->bearerToken();
|
||||
if (empty($token)) return UtilsService::getInstance()->notAuth('请先登录');
|
||||
$this->token = $token;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 JWT Token
|
||||
* @param array $data 要嵌入到 token 中的数据
|
||||
* @return string
|
||||
*/
|
||||
public function generateToken(array $data): string
|
||||
{
|
||||
$issuedAt = time();
|
||||
$expirationTime = $issuedAt + config('cc.redis.jwt_ttl', 600000);
|
||||
|
||||
$payload = [
|
||||
'iat' => $issuedAt,
|
||||
'exp' => $expirationTime,
|
||||
'data' => $data
|
||||
];
|
||||
RedisService::getInstance()->init(config('cc.redis.jwt'))->set($data['id'], json_encode($data));
|
||||
return JWT::encode($payload, $this->secretKey, 'HS256');
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 JWT Token
|
||||
* @return object|null 返回解码后的 payload 或者 null 如果验证失败
|
||||
* @throws Exception
|
||||
*/
|
||||
public function parseToken(): ?object
|
||||
{
|
||||
try {
|
||||
if (empty($this->token)) return UtilsService::getInstance()->notAuth('请先登录');
|
||||
return JWT::decode($this->token, new Key($this->secretKey, 'HS256'));
|
||||
} catch (Exception $e) {
|
||||
return UtilsService::getInstance()->notAuth('【1】Token解析失败!请重新登录:'. $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解析 JWT Token
|
||||
* @return array|null 返回解码后的 payload 或者 null 如果验证失败
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getUserInfo(): ?array
|
||||
{
|
||||
try {
|
||||
$jwt = $this->parseToken();
|
||||
$user = RedisService::getInstance()->init(config('cc.redis.jwt'))->get($jwt->data->id);
|
||||
if (empty($user)) return UtilsService::getInstance()->notAuth('登录状态过期');
|
||||
return json_decode($user, true);
|
||||
} catch (Exception $e) {
|
||||
return UtilsService::getInstance()->notAuth('【2】Token解析失败!请重新登录:'. $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 续签 JWT Token
|
||||
* @return string|null 新的 JWT 字符串或者 null 如果原 token 已过期或无效
|
||||
* @throws Exception
|
||||
*/
|
||||
public function refreshToken(): ?string
|
||||
{
|
||||
$decoded = $this->parseToken();
|
||||
if ($decoded === null || !property_exists($decoded, 'data')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->generateToken((array)$decoded->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
94
app/Service/common/RedisService.php
Executable file
94
app/Service/common/RedisService.php
Executable file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service\common;
|
||||
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
|
||||
class RedisService
|
||||
{
|
||||
|
||||
private static mixed $_instance;
|
||||
|
||||
private $prefix = 'default';
|
||||
|
||||
private $redis;
|
||||
|
||||
/**
|
||||
* 获取实例
|
||||
* @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 $prefix
|
||||
* @return RedisService
|
||||
*/
|
||||
public function init(string $prefix = 'default'): static
|
||||
{
|
||||
$this->redis = Redis::class;
|
||||
$this->prefix = $prefix;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存
|
||||
* @param $key
|
||||
* @param $value
|
||||
* @param int $expire
|
||||
* @return true
|
||||
*/
|
||||
public function set($key, $value, int $expire = 0): true
|
||||
{
|
||||
$this->redis::set($this->prefix . $key, $value);
|
||||
if ($expire > 0) {
|
||||
$this->redis::expire($this->prefix . $key, $expire);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 累加
|
||||
* @param $key
|
||||
* @param int $value
|
||||
* @param int $expire
|
||||
* @return true
|
||||
*/
|
||||
public function incr($key, int $value = 1, int $expire = 0): true
|
||||
{
|
||||
$this->redis::incr($this->prefix . $key, $value);
|
||||
if ($expire > 0) {
|
||||
$this->redis::expire($this->prefix . $key, $expire);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存
|
||||
*
|
||||
* @param $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key): mixed
|
||||
{
|
||||
return $this->redis::get($this->prefix . $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
* @param $key
|
||||
* @return bool
|
||||
*/
|
||||
public function del($key): bool
|
||||
{
|
||||
return $this->redis::del($this->prefix . $key);
|
||||
}
|
||||
}
|
||||
89
app/Service/common/UploadService.php
Normal file
89
app/Service/common/UploadService.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service\common;
|
||||
|
||||
use App\BaseApp\BaseService;
|
||||
use App\Models\ProjectModel;
|
||||
use App\Models\RoleModel;
|
||||
use App\Models\UserModel;
|
||||
use App\Service\common\upload\LocalhostStorageService;
|
||||
use App\Service\common\upload\QiniuStorageService;
|
||||
use App\Service\FileService;
|
||||
use Exception;
|
||||
use Illuminate\Support\Str;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class UploadService extends BaseService
|
||||
{
|
||||
private $uploadService;
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->model = RoleModel::class;
|
||||
|
||||
switch (env('ECS')) {
|
||||
case 'aliyun':
|
||||
// $this->uploadService = AliyunStorageService::getInstance();
|
||||
break;
|
||||
case 'qcloud':
|
||||
// $this->uploadService = QcloudStorageService::getInstance();
|
||||
break;
|
||||
case 'qiniu':
|
||||
$this->uploadService = QiniuStorageService::getInstance();
|
||||
break;
|
||||
default:
|
||||
$this->uploadService = LocalhostStorageService::getInstance();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传OSS图片
|
||||
* @param $file
|
||||
* @return array|bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadImage($file): array|bool
|
||||
{
|
||||
// 获取文件后缀
|
||||
$ext = $file->getClientOriginalExtension();
|
||||
$key = 'spa/image/'. date('Ymd') . '/' . 'cc_upload_'. Str::random(). uniqid() . '.' . $ext;
|
||||
$result = $this->uploadService->uploadVideo($file, $key);
|
||||
// $result = [
|
||||
// 'key' => $key,
|
||||
// 'url' => 'https://img2.baidu.com/it/u=1629222614,1358629025&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500&a='. rand(1111111, 9999999)
|
||||
// ];
|
||||
FileService::getInstance()->create([
|
||||
'user_id' => $this->userId,
|
||||
'url' => $result['url'],
|
||||
]);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传OSS视频
|
||||
* @param $file
|
||||
* @return array|bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadVideo($file): array|bool
|
||||
{
|
||||
// 获取文件后缀
|
||||
$ext = $file->getClientOriginalExtension();
|
||||
$key = 'spa/video/'. date('Ymd') . '/' . 'cc_upload_'. Str::random(). uniqid() . '.' . $ext;
|
||||
$result = $this->uploadService->uploadVideo($file, $key);
|
||||
// $result = [
|
||||
// 'key' => $key,
|
||||
// 'url' => 'http://d-jy.nailaoyun.cn//storage/video//20250327/2cc1abf9bd69410ce7c69660daf54260.mp4'
|
||||
// ];
|
||||
FileService::getInstance()->create([
|
||||
'user_id' => $this->userId,
|
||||
'url' => $result['url'],
|
||||
]);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
247
app/Service/common/UtilsService.php
Executable file
247
app/Service/common/UtilsService.php
Executable file
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service\common;
|
||||
|
||||
use App\Enum\ErrorEnum;
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Random\RandomException;
|
||||
use ReflectionClass;
|
||||
|
||||
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
|
||||
{
|
||||
return self::errorThrow($msg, ErrorEnum::NOT_AUTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成密码
|
||||
* @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;
|
||||
}
|
||||
|
||||
public function autoRouteRegister($class): void
|
||||
{
|
||||
foreach ($class as $key => $value) {
|
||||
|
||||
// 获取控制器$value的所有方法
|
||||
$methods = (new ReflectionClass($value))->getMethods();
|
||||
|
||||
// 注册路由
|
||||
foreach ($methods as $method) {
|
||||
// 获取方法注释 @Method
|
||||
$docComment = $method->getDocComment();
|
||||
if ($method->name === '__construct' || preg_match('/@Method\s+(NO)\b/', $docComment, $matches)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$httpMethod = 'any';
|
||||
// 查询 @Method GET 或者 @Method POST
|
||||
if (preg_match('/@Method\s+(GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD|ANY)\b/', $docComment, $matches)) {
|
||||
$httpMethod = $matches[1];
|
||||
}
|
||||
Route::$httpMethod($key . '/' . cc_camel_case_to_dash($method->getName()), [$value, conjunction_symbol_processing($method->name)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
108
app/Service/common/upload/LocalhostStorageService.php
Normal file
108
app/Service/common/upload/LocalhostStorageService.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service\common\upload;
|
||||
|
||||
use App\BaseApp\BaseService;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class LocalhostStorageService extends BaseService
|
||||
{
|
||||
/**
|
||||
* @var mixed 单例实例,确保该类只有一个全局实例
|
||||
*/
|
||||
protected static mixed $_instance;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实例
|
||||
* @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 $filePath 文件本地路径
|
||||
* @param string $key 上传到本地存储的文件名
|
||||
* @return array|bool
|
||||
*/
|
||||
public function uploadImage($filePath, $key): bool|array
|
||||
{
|
||||
return $this->uploadFile($filePath, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传视频
|
||||
*
|
||||
* @param string $filePath 文件本地路径
|
||||
* @param string $key 上传到本地存储的文件名
|
||||
* @return array|bool
|
||||
*/
|
||||
public function uploadVideo($filePath, $key): bool|array
|
||||
{
|
||||
return $this->uploadFile($filePath, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除图片
|
||||
*
|
||||
* @param string $key 本地存储的文件名
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteImage($key): bool
|
||||
{
|
||||
return $this->deleteFile($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除视频
|
||||
*
|
||||
* @param string $key 本地存储的文件名
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteVideo($key): bool
|
||||
{
|
||||
return $this->deleteFile($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*
|
||||
* @param string $filePath 文件本地路径
|
||||
* @param string $key 上传到本地存储的文件名
|
||||
* @return array|bool
|
||||
*/
|
||||
private function uploadFile(string $filePath, string $key): bool|array
|
||||
{
|
||||
if (Storage::put($key, file_get_contents($filePath))) {
|
||||
return [
|
||||
'key' => $key,
|
||||
'url' => asset('/storage/' . $key)
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param string $key 本地存储的文件名
|
||||
* @return bool
|
||||
*/
|
||||
private function deleteFile(string $key): bool
|
||||
{
|
||||
return Storage::delete($key);
|
||||
}
|
||||
}
|
||||
132
app/Service/common/upload/QiniuStorageService.php
Normal file
132
app/Service/common/upload/QiniuStorageService.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service\common\upload;
|
||||
|
||||
use App\BaseApp\BaseService;
|
||||
use Exception;
|
||||
use Qiniu\Auth;
|
||||
use Qiniu\Storage\BucketManager;
|
||||
use Qiniu\Storage\UploadManager;
|
||||
|
||||
class QiniuStorageService extends BaseService
|
||||
{
|
||||
/**
|
||||
* @var mixed 单例实例,确保该类只有一个全局实例
|
||||
*/
|
||||
protected static mixed $_instance;
|
||||
private $accessKey;
|
||||
private $secretKey;
|
||||
private $bucket;
|
||||
private $domain;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->accessKey = config('cc.oss.qiniu.access_key');
|
||||
$this->secretKey = config('cc.oss.qiniu.secret_key');
|
||||
$this->bucket = config('cc.oss.qiniu.bucket');
|
||||
$this->domain = config('cc.oss.qiniu.domain');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取实例
|
||||
* @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 $filePath 文件本地路径
|
||||
* @param string $key 上传到七牛云的文件名
|
||||
* @return array|bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadImage($filePath, $key): bool|array
|
||||
{
|
||||
return $this->uploadFile($filePath, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传视频
|
||||
*
|
||||
* @param string $filePath 文件本地路径
|
||||
* @param string $key 上传到七牛云的文件名
|
||||
* @return array|bool
|
||||
*/
|
||||
public function uploadVideo($filePath, $key): bool|array
|
||||
{
|
||||
return $this->uploadFile($filePath, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除图片
|
||||
*
|
||||
* @param string $key 七牛云存储的文件名
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteImage($key): bool
|
||||
{
|
||||
return $this->deleteFile($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除视频
|
||||
*
|
||||
* @param string $key 七牛云存储的文件名
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteVideo($key): bool
|
||||
{
|
||||
return $this->deleteFile($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*
|
||||
* @param string $filePath 文件本地路径
|
||||
* @param string $key 上传到七牛云的文件名
|
||||
* @return array|bool
|
||||
* @throws Exception
|
||||
*/
|
||||
private function uploadFile(string $filePath, string $key): bool|array
|
||||
{
|
||||
$auth = new Auth($this->accessKey, $this->secretKey);
|
||||
$token = $auth->uploadToken($this->bucket);
|
||||
$uploadMgr = new UploadManager();
|
||||
|
||||
list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
|
||||
if ($err !== null) {
|
||||
return false;
|
||||
} else {
|
||||
return [
|
||||
'key' => $ret['key'],
|
||||
'url' => $this->domain . '/' . $ret['key']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param string $key 七牛云存储的文件名
|
||||
* @return bool
|
||||
*/
|
||||
private function deleteFile(string $key): bool
|
||||
{
|
||||
$auth = new Auth($this->accessKey, $this->secretKey);
|
||||
$bucketMgr = new BucketManager($auth);
|
||||
|
||||
$err = $bucketMgr->delete($this->bucket, $key);
|
||||
return $err === null;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,18 @@
|
||||
<?php
|
||||
|
||||
use App\Enum\ErrorEnum;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Foundation\Configuration\Exceptions;
|
||||
use Illuminate\Foundation\Configuration\Middleware;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
||||
|
||||
return Application::configure(basePath: dirname(__DIR__))
|
||||
->withRouting(
|
||||
web: __DIR__.'/../routes/web.php',
|
||||
api: __DIR__.'/../routes/api.php',
|
||||
commands: __DIR__.'/../routes/console.php',
|
||||
health: '/up',
|
||||
)
|
||||
@@ -14,5 +20,58 @@ return Application::configure(basePath: dirname(__DIR__))
|
||||
//
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions) {
|
||||
//
|
||||
$exceptions->render(function (Throwable $e) {
|
||||
// 判断异常是否为Exception类型
|
||||
if ($e instanceof \Exception) {
|
||||
// \App\Models\new\log\ErrorLogModel::create([
|
||||
// 'type' => 0,
|
||||
// 'content' => json_encode([
|
||||
// 'message' => $e->getMessage(),
|
||||
// 'line' => $e->getLine(),
|
||||
// 'file' => $e->getFile(),
|
||||
// 'trace' => $e->getTraceAsString(),
|
||||
// ]),
|
||||
// 'created_at' => time()
|
||||
// ]);
|
||||
// 使用switch语句判断异常类型
|
||||
switch (true) { // 注意这里使用了 'true' 因为 PHP 不允许在 case 中使用表达式
|
||||
// 如果异常是NotFoundHttpException类型
|
||||
case $e instanceof NotFoundHttpException:
|
||||
// 返回一个自定义的JSON响应,状态码为404,错误信息为"路由未找到"
|
||||
return jInstanceof(ErrorEnum::NOT_FOUND, '路由未找到', $e->getMessage());
|
||||
|
||||
// 如果异常是MethodNotAllowedHttpException类型
|
||||
case $e instanceof MethodNotAllowedHttpException:
|
||||
Log::error($e->getMessage());
|
||||
// 返回一个自定义的JSON响应,状态码为405,错误信息为"请求方式错误"
|
||||
return jInstanceof(405, '请求方式错误', $e->getMessage());
|
||||
|
||||
// 如果异常是UnprocessableEntityHttpException类型
|
||||
case $e instanceof UnprocessableEntityHttpException:
|
||||
Log::warning($e->getMessage());
|
||||
// 返回一个自定义的JSON响应,状态码为422,错误信息为"服务器处理不过来啦"
|
||||
return jInstanceof(422, '服务器处理不过来啦', $e->getMessage());
|
||||
|
||||
// 如果异常是HttpException类型
|
||||
case $e instanceof HttpException:
|
||||
Log::error($e->getMessage());
|
||||
// 返回一个自定义的JSON响应,状态码为异常的状态码,错误信息为"服务器出错啦"
|
||||
return jInstanceof($e->getCode(), ErrorEnum::FAIL->description(), 'ERROR:'. $e->getMessage());
|
||||
|
||||
// 对于所有其他类型的异常,默认返回500内部服务器错误
|
||||
default:
|
||||
Log::critical($e->getMessage()); // 记录更严重的日志级别
|
||||
// 返回一个自定义的JSON响应,状态码为500,错误信息为"内部服务器错误"
|
||||
return jInstanceof($e->getCode(), $e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
return jInstanceof(ErrorEnum::FAIL, '服务器出错啦~', [
|
||||
'message' => $e->getMessage(),
|
||||
'code' => $e->getCode(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'trace' => $e->getTrace(),
|
||||
]);
|
||||
});
|
||||
})->create();
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"firebase/php-jwt": "^6.11",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/tinker": "^2.10.1"
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"qiniu/php-sdk": "^7.14"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.23",
|
||||
|
||||
455
composer.lock
generated
455
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "88970a0117c062eed55fa8728fc43833",
|
||||
"content-hash": "86a39f4473522b8df75d7ae593c3faf0",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
@@ -510,6 +510,69 @@
|
||||
],
|
||||
"time": "2025-03-06T22:45:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "firebase/php-jwt",
|
||||
"version": "v6.11.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/firebase/php-jwt.git",
|
||||
"reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/d1e91ecf8c598d073d0995afa8cd5c75c6e19e66",
|
||||
"reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"guzzlehttp/guzzle": "^7.4",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psr/cache": "^2.0||^3.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-sodium": "Support EdDSA (Ed25519) signatures",
|
||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Firebase\\JWT\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Neuman Vong",
|
||||
"email": "neuman+pear@twilio.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Anant Narayanan",
|
||||
"email": "anant@php.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
|
||||
"homepage": "https://github.com/firebase/php-jwt",
|
||||
"keywords": [
|
||||
"jwt",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/firebase/php-jwt/issues",
|
||||
"source": "https://github.com/firebase/php-jwt/tree/v6.11.1"
|
||||
},
|
||||
"time": "2025-04-09T20:32:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fruitcake/php-cors",
|
||||
"version": "v1.3.0",
|
||||
@@ -1056,16 +1119,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v12.10.2",
|
||||
"version": "v12.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "0f123cc857bc177abe4d417448d4f7164f71802a"
|
||||
"reference": "8f6cd73696068c28f30f5964556ec9d14e5d90d7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/0f123cc857bc177abe4d417448d4f7164f71802a",
|
||||
"reference": "0f123cc857bc177abe4d417448d4f7164f71802a",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/8f6cd73696068c28f30f5964556ec9d14e5d90d7",
|
||||
"reference": "8f6cd73696068c28f30f5964556ec9d14e5d90d7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1267,7 +1330,7 @@
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2025-04-24T14:11:20+00:00"
|
||||
"time": "2025-05-01T16:13:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/prompts",
|
||||
@@ -1457,16 +1520,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
"version": "2.6.2",
|
||||
"version": "2.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/commonmark.git",
|
||||
"reference": "06c3b0bf2540338094575612f4a1778d0d2d5e94"
|
||||
"reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/06c3b0bf2540338094575612f4a1778d0d2d5e94",
|
||||
"reference": "06c3b0bf2540338094575612f4a1778d0d2d5e94",
|
||||
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/6fbb36d44824ed4091adbcf4c7d4a3923cdb3405",
|
||||
"reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1503,7 +1566,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.7-dev"
|
||||
"dev-main": "2.8-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -1560,7 +1623,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-18T21:09:27+00:00"
|
||||
"time": "2025-05-05T12:20:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/config",
|
||||
@@ -2110,17 +2173,80 @@
|
||||
"time": "2025-03-24T10:02:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "3.9.0",
|
||||
"name": "myclabs/php-enum",
|
||||
"version": "1.8.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/CarbonPHP/carbon.git",
|
||||
"reference": "6d16a8a015166fe54e22c042e0805c5363aef50d"
|
||||
"url": "https://github.com/myclabs/php-enum.git",
|
||||
"reference": "e7be26966b7398204a234f8673fdad5ac6277802"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/6d16a8a015166fe54e22c042e0805c5363aef50d",
|
||||
"reference": "6d16a8a015166fe54e22c042e0805c5363aef50d",
|
||||
"url": "https://api.github.com/repos/myclabs/php-enum/zipball/e7be26966b7398204a234f8673fdad5ac6277802",
|
||||
"reference": "e7be26966b7398204a234f8673fdad5ac6277802",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.3 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"squizlabs/php_codesniffer": "1.*",
|
||||
"vimeo/psalm": "^4.6.2 || ^5.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"MyCLabs\\Enum\\": "src/"
|
||||
},
|
||||
"classmap": [
|
||||
"stubs/Stringable.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP Enum contributors",
|
||||
"homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "PHP Enum implementation",
|
||||
"homepage": "https://github.com/myclabs/php-enum",
|
||||
"keywords": [
|
||||
"enum"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/php-enum/issues",
|
||||
"source": "https://github.com/myclabs/php-enum/tree/1.8.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/mnapoli",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-01-14T11:49:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "3.9.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/CarbonPHP/carbon.git",
|
||||
"reference": "ced71f79398ece168e24f7f7710462f462310d4d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/ced71f79398ece168e24f7f7710462f462310d4d",
|
||||
"reference": "ced71f79398ece168e24f7f7710462f462310d4d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2213,7 +2339,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-27T12:57:33+00:00"
|
||||
"time": "2025-05-01T19:51:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
@@ -3074,6 +3200,66 @@
|
||||
},
|
||||
"time": "2025-03-16T03:05:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "qiniu/php-sdk",
|
||||
"version": "v7.14.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/qiniu/php-sdk.git",
|
||||
"reference": "ee752ffa7263ce99fca0bd7340cf13c486a3516c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/qiniu/php-sdk/zipball/ee752ffa7263ce99fca0bd7340cf13c486a3516c",
|
||||
"reference": "ee752ffa7263ce99fca0bd7340cf13c486a3516c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-xml": "*",
|
||||
"myclabs/php-enum": "~1.5.2 || ~1.6.6 || ~1.7.7 || ~1.8.4",
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"paragonie/random_compat": ">=2",
|
||||
"phpunit/phpunit": "^4.8 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4",
|
||||
"squizlabs/php_codesniffer": "^2.3 || ~3.6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Qiniu/functions.php",
|
||||
"src/Qiniu/Http/Middleware/Middleware.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Qiniu\\": "src/Qiniu"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Qiniu",
|
||||
"email": "sdk@qiniu.com",
|
||||
"homepage": "http://www.qiniu.com"
|
||||
}
|
||||
],
|
||||
"description": "Qiniu Resource (Cloud) Storage SDK for PHP",
|
||||
"homepage": "http://developer.qiniu.com/",
|
||||
"keywords": [
|
||||
"cloud",
|
||||
"qiniu",
|
||||
"sdk",
|
||||
"storage"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/qiniu/php-sdk/issues",
|
||||
"source": "https://github.com/qiniu/php-sdk/tree/v7.14.0"
|
||||
},
|
||||
"time": "2024-10-25T08:39:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
"version": "3.0.3",
|
||||
@@ -3362,16 +3548,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.2.5",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "e51498ea18570c062e7df29d05a7003585b19b88"
|
||||
"reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/e51498ea18570c062e7df29d05a7003585b19b88",
|
||||
"reference": "e51498ea18570c062e7df29d05a7003585b19b88",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218",
|
||||
"reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3435,7 +3621,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.2.5"
|
||||
"source": "https://github.com/symfony/console/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -3451,7 +3637,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-12T08:11:12+00:00"
|
||||
"time": "2025-04-07T19:09:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
@@ -3882,16 +4068,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v7.2.5",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-foundation.git",
|
||||
"reference": "371272aeb6286f8135e028ca535f8e4d6f114126"
|
||||
"reference": "6023ec7607254c87c5e69fb3558255aca440d72b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/371272aeb6286f8135e028ca535f8e4d6f114126",
|
||||
"reference": "371272aeb6286f8135e028ca535f8e4d6f114126",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/6023ec7607254c87c5e69fb3558255aca440d72b",
|
||||
"reference": "6023ec7607254c87c5e69fb3558255aca440d72b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3940,7 +4126,7 @@
|
||||
"description": "Defines an object-oriented layer for the HTTP specification",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v7.2.5"
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -3956,20 +4142,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-25T15:54:33+00:00"
|
||||
"time": "2025-04-09T08:14:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
"version": "v7.2.5",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-kernel.git",
|
||||
"reference": "b1fe91bc1fa454a806d3f98db4ba826eb9941a54"
|
||||
"reference": "f9dec01e6094a063e738f8945ef69c0cfcf792ec"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/b1fe91bc1fa454a806d3f98db4ba826eb9941a54",
|
||||
"reference": "b1fe91bc1fa454a806d3f98db4ba826eb9941a54",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/f9dec01e6094a063e738f8945ef69c0cfcf792ec",
|
||||
"reference": "f9dec01e6094a063e738f8945ef69c0cfcf792ec",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4054,7 +4240,7 @@
|
||||
"description": "Provides a structured process for converting a Request into a Response",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-kernel/tree/v7.2.5"
|
||||
"source": "https://github.com/symfony/http-kernel/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4070,20 +4256,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-28T13:32:50+00:00"
|
||||
"time": "2025-05-02T09:04:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mailer",
|
||||
"version": "v7.2.3",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mailer.git",
|
||||
"reference": "f3871b182c44997cf039f3b462af4a48fb85f9d3"
|
||||
"reference": "998692469d6e698c6eadc7ef37a6530a9eabb356"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mailer/zipball/f3871b182c44997cf039f3b462af4a48fb85f9d3",
|
||||
"reference": "f3871b182c44997cf039f3b462af4a48fb85f9d3",
|
||||
"url": "https://api.github.com/repos/symfony/mailer/zipball/998692469d6e698c6eadc7ef37a6530a9eabb356",
|
||||
"reference": "998692469d6e698c6eadc7ef37a6530a9eabb356",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4134,7 +4320,7 @@
|
||||
"description": "Helps sending emails",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mailer/tree/v7.2.3"
|
||||
"source": "https://github.com/symfony/mailer/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4150,20 +4336,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-01-27T11:08:17+00:00"
|
||||
"time": "2025-04-04T09:50:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mime",
|
||||
"version": "v7.2.4",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mime.git",
|
||||
"reference": "87ca22046b78c3feaff04b337f33b38510fd686b"
|
||||
"reference": "706e65c72d402539a072d0d6ad105fff6c161ef1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/87ca22046b78c3feaff04b337f33b38510fd686b",
|
||||
"reference": "87ca22046b78c3feaff04b337f33b38510fd686b",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/706e65c72d402539a072d0d6ad105fff6c161ef1",
|
||||
"reference": "706e65c72d402539a072d0d6ad105fff6c161ef1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4218,7 +4404,7 @@
|
||||
"mime-type"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mime/tree/v7.2.4"
|
||||
"source": "https://github.com/symfony/mime/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4234,11 +4420,11 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-19T08:51:20+00:00"
|
||||
"time": "2025-04-27T13:34:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.31.0",
|
||||
"version": "v1.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
@@ -4297,7 +4483,7 @@
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4317,7 +4503,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-grapheme",
|
||||
"version": "v1.31.0",
|
||||
"version": "v1.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
|
||||
@@ -4375,7 +4561,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0"
|
||||
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4395,16 +4581,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-idn",
|
||||
"version": "v1.31.0",
|
||||
"version": "v1.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
||||
"reference": "c36586dcf89a12315939e00ec9b4474adcb1d773"
|
||||
"reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773",
|
||||
"reference": "c36586dcf89a12315939e00ec9b4474adcb1d773",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3",
|
||||
"reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4458,7 +4644,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0"
|
||||
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.32.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4474,11 +4660,11 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
"time": "2024-09-10T14:38:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-normalizer",
|
||||
"version": "v1.31.0",
|
||||
"version": "v1.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
||||
@@ -4539,7 +4725,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0"
|
||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4559,19 +4745,20 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.31.0",
|
||||
"version": "v1.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341"
|
||||
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
|
||||
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
|
||||
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-iconv": "*",
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"provide": {
|
||||
@@ -4619,7 +4806,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0"
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4635,20 +4822,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
"time": "2024-12-23T08:48:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.31.0",
|
||||
"version": "v1.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8"
|
||||
"reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
||||
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
|
||||
"reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4699,7 +4886,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0"
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4715,11 +4902,11 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
"time": "2025-01-02T08:10:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php83",
|
||||
"version": "v1.31.0",
|
||||
"version": "v1.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php83.git",
|
||||
@@ -4775,7 +4962,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0"
|
||||
"source": "https://github.com/symfony/polyfill-php83/tree/v1.32.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4795,7 +4982,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-uuid",
|
||||
"version": "v1.31.0",
|
||||
"version": "v1.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-uuid.git",
|
||||
@@ -4854,7 +5041,7 @@
|
||||
"uuid"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-uuid/tree/v1.31.0"
|
||||
"source": "https://github.com/symfony/polyfill-uuid/tree/v1.32.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5099,16 +5286,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v7.2.0",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "446e0d146f991dde3e73f45f2c97a9faad773c82"
|
||||
"reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82",
|
||||
"reference": "446e0d146f991dde3e73f45f2c97a9faad773c82",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931",
|
||||
"reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5166,7 +5353,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v7.2.0"
|
||||
"source": "https://github.com/symfony/string/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5182,20 +5369,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-13T13:31:26+00:00"
|
||||
"time": "2025-04-20T20:18:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v7.2.4",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "283856e6981286cc0d800b53bd5703e8e363f05a"
|
||||
"reference": "e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/283856e6981286cc0d800b53bd5703e8e363f05a",
|
||||
"reference": "283856e6981286cc0d800b53bd5703e8e363f05a",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6",
|
||||
"reference": "e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5261,7 +5448,7 @@
|
||||
"description": "Provides tools to internationalize your application",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/translation/tree/v7.2.4"
|
||||
"source": "https://github.com/symfony/translation/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5277,7 +5464,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-13T10:27:23+00:00"
|
||||
"time": "2025-04-07T19:09:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation-contracts",
|
||||
@@ -5433,16 +5620,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v7.2.3",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "82b478c69745d8878eb60f9a049a4d584996f73a"
|
||||
"reference": "9c46038cd4ed68952166cf7001b54eb539184ccb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/82b478c69745d8878eb60f9a049a4d584996f73a",
|
||||
"reference": "82b478c69745d8878eb60f9a049a4d584996f73a",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/9c46038cd4ed68952166cf7001b54eb539184ccb",
|
||||
"reference": "9c46038cd4ed68952166cf7001b54eb539184ccb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5496,7 +5683,7 @@
|
||||
"dump"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v7.2.3"
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5512,7 +5699,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-01-17T11:39:41+00:00"
|
||||
"time": "2025-04-09T08:14:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "tijsverkoyen/css-to-inline-styles",
|
||||
@@ -5571,16 +5758,16 @@
|
||||
},
|
||||
{
|
||||
"name": "vlucas/phpdotenv",
|
||||
"version": "v5.6.1",
|
||||
"version": "v5.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vlucas/phpdotenv.git",
|
||||
"reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2"
|
||||
"reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/a59a13791077fe3d44f90e7133eb68e7d22eaff2",
|
||||
"reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2",
|
||||
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/24ac4c74f91ee2c193fa1aaa5c249cb0822809af",
|
||||
"reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5639,7 +5826,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/vlucas/phpdotenv/issues",
|
||||
"source": "https://github.com/vlucas/phpdotenv/tree/v5.6.1"
|
||||
"source": "https://github.com/vlucas/phpdotenv/tree/v5.6.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5651,7 +5838,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-07-20T21:52:34+00:00"
|
||||
"time": "2025-04-30T23:37:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "voku/portable-ascii",
|
||||
@@ -5923,20 +6110,20 @@
|
||||
},
|
||||
{
|
||||
"name": "hamcrest/hamcrest-php",
|
||||
"version": "v2.0.1",
|
||||
"version": "v2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hamcrest/hamcrest-php.git",
|
||||
"reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3"
|
||||
"reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
|
||||
"reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
|
||||
"url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487",
|
||||
"reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3|^7.0|^8.0"
|
||||
"php": "^7.4|^8.0"
|
||||
},
|
||||
"replace": {
|
||||
"cordoval/hamcrest-php": "*",
|
||||
@@ -5944,8 +6131,8 @@
|
||||
"kodova/hamcrest-php": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/php-file-iterator": "^1.4 || ^2.0",
|
||||
"phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0"
|
||||
"phpunit/php-file-iterator": "^1.4 || ^2.0 || ^3.0",
|
||||
"phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0 || ^8.0 || ^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
@@ -5968,9 +6155,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/hamcrest/hamcrest-php/issues",
|
||||
"source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1"
|
||||
"source": "https://github.com/hamcrest/hamcrest-php/tree/v2.1.1"
|
||||
},
|
||||
"time": "2020-07-09T08:09:16+00:00"
|
||||
"time": "2025-04-30T06:54:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/pail",
|
||||
@@ -6118,16 +6305,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/sail",
|
||||
"version": "v1.41.1",
|
||||
"version": "v1.42.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/sail.git",
|
||||
"reference": "e5692510f1ef8e0f5096cde2b885d558f8d86592"
|
||||
"reference": "2edaaf77f3c07a4099965bb3d7dfee16e801c0f6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/sail/zipball/e5692510f1ef8e0f5096cde2b885d558f8d86592",
|
||||
"reference": "e5692510f1ef8e0f5096cde2b885d558f8d86592",
|
||||
"url": "https://api.github.com/repos/laravel/sail/zipball/2edaaf77f3c07a4099965bb3d7dfee16e801c0f6",
|
||||
"reference": "2edaaf77f3c07a4099965bb3d7dfee16e801c0f6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6177,7 +6364,7 @@
|
||||
"issues": "https://github.com/laravel/sail/issues",
|
||||
"source": "https://github.com/laravel/sail"
|
||||
},
|
||||
"time": "2025-04-22T13:39:39+00:00"
|
||||
"time": "2025-04-29T14:26:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
@@ -6264,16 +6451,16 @@
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.13.0",
|
||||
"version": "1.13.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "024473a478be9df5fdaca2c793f2232fe788e414"
|
||||
"reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414",
|
||||
"reference": "024473a478be9df5fdaca2c793f2232fe788e414",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c",
|
||||
"reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6312,7 +6499,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.0"
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6320,7 +6507,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-12T12:17:51+00:00"
|
||||
"time": "2025-04-29T12:36:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/collision",
|
||||
@@ -6864,16 +7051,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "11.5.18",
|
||||
"version": "11.5.19",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "fc3e887c7f3f9917e1bf61e523413d753db00a17"
|
||||
"reference": "0da1ebcdbc4d5bd2d189cfe02846a89936d8dda5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fc3e887c7f3f9917e1bf61e523413d753db00a17",
|
||||
"reference": "fc3e887c7f3f9917e1bf61e523413d753db00a17",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0da1ebcdbc4d5bd2d189cfe02846a89936d8dda5",
|
||||
"reference": "0da1ebcdbc4d5bd2d189cfe02846a89936d8dda5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6883,7 +7070,7 @@
|
||||
"ext-mbstring": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"myclabs/deep-copy": "^1.13.0",
|
||||
"myclabs/deep-copy": "^1.13.1",
|
||||
"phar-io/manifest": "^2.0.4",
|
||||
"phar-io/version": "^3.2.1",
|
||||
"php": ">=8.2",
|
||||
@@ -6945,7 +7132,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.18"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.19"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6969,7 +7156,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-22T06:09:49+00:00"
|
||||
"time": "2025-05-02T06:56:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
@@ -7951,16 +8138,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v7.2.5",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912"
|
||||
"reference": "0feafffb843860624ddfd13478f481f4c3cd8b23"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
||||
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/0feafffb843860624ddfd13478f481f4c3cd8b23",
|
||||
"reference": "0feafffb843860624ddfd13478f481f4c3cd8b23",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -8003,7 +8190,7 @@
|
||||
"description": "Loads and dumps YAML files",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/yaml/tree/v7.2.5"
|
||||
"source": "https://github.com/symfony/yaml/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -8019,7 +8206,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-03T07:12:39+00:00"
|
||||
"time": "2025-04-04T10:10:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
|
||||
135
config/cc.php
Executable file
135
config/cc.php
Executable file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
return [
|
||||
/*
|
||||
* 过期时间配置
|
||||
*/
|
||||
'time_out' => [
|
||||
// 订单
|
||||
'product_order' => [
|
||||
'over_time' => 24*3600,//秒,自动取消时间
|
||||
// 'over_time' => 3,//秒,自动取消时间
|
||||
'received_time' => 7*24*3600,//自动确认收货时间
|
||||
'forbidden_refund_time' => 30*24*3600, //不允许退款时间
|
||||
'settlement_time' => 0//7*24*3600//订单发货 分账自动结算时间
|
||||
],
|
||||
// 处方
|
||||
'prescription' => [
|
||||
'over_time' => 24*3600 //处方审核自动失效时间
|
||||
// 'over_time' => 0 //处方审核自动失效时间
|
||||
],
|
||||
],
|
||||
/*
|
||||
* redis配置
|
||||
*/
|
||||
'redis' => [
|
||||
'jwt' => 'xk_login_',
|
||||
'jwt_ttl' => 360000,
|
||||
// 'jwt_ttl' => 360,
|
||||
'email' => 'xk_email_',
|
||||
'phone' => 'xk_phone_',
|
||||
'login_out_key' => 'xk_login_out_',
|
||||
'menu_key' => 'xk_menu_',
|
||||
],
|
||||
/*
|
||||
* api白名单
|
||||
*/
|
||||
'api' => [
|
||||
'white_list' => [
|
||||
'/api/admin/login',
|
||||
'/api/admin/register',
|
||||
]
|
||||
],
|
||||
/*
|
||||
* 阿里云oss配置
|
||||
*/
|
||||
'oss' => [
|
||||
'redis_key' => 'xk_oss_url_',
|
||||
'ali' => [
|
||||
'accessKeyId' => env('OSS_ACCESS_KEY_ID'),
|
||||
'accessKeySecret' => env('OSS_ACCESS_KEY_SECRET'),
|
||||
'endpoint' => env('OSS_ENDPOINT'),
|
||||
'bucket' => env('OSS_BUCKET'),
|
||||
'domain' => env('OSS_DOMAIN'),
|
||||
],
|
||||
'qiniu' => [
|
||||
'access_key' => 'RPQlZUd2yrL3kR8CC4BpTGV6FhGr11npBzf6IuCT',
|
||||
'secret_key' => 'b-796uVY1InOKSVecpY8VBpO7Cdubo1Tv4RcOfMY',
|
||||
'bucket' => 'ccspa',
|
||||
'domain' => 'http://o-spa.nailaoyun.cn',
|
||||
]
|
||||
],
|
||||
/*
|
||||
* 短信配置
|
||||
*/
|
||||
'sms' => [
|
||||
'ali' => [
|
||||
'status' => '1',
|
||||
'access_key_id' => env('ALIYUN_SMS_ACCESS_KEY_ID'),
|
||||
'access_key_secret' => env('ALIYUN_SMS_ACCESS_KEY_SECRET'),
|
||||
'sign_name' => env('ALIYUN_SMS_SIGN_NAME'),
|
||||
'captcha' => [
|
||||
"template_id" => "SMS_275060336", // 模板id
|
||||
"template_variable" => "code", //模板变量
|
||||
],
|
||||
"doctor" => [
|
||||
"register" => [ //挂号订单提醒
|
||||
"template_id" => "SMS_462205458",
|
||||
"template_variable" => ""
|
||||
],
|
||||
"prescription_pass" => [
|
||||
"template_id" => "SMS_462260412",
|
||||
"template_variable" => "order"
|
||||
],
|
||||
"prescription_refuse" => [
|
||||
"template_id" => "SMS_462230433",
|
||||
"template_variable" => [
|
||||
"order",
|
||||
"cause"
|
||||
]
|
||||
]
|
||||
],
|
||||
"pharmacist" => [
|
||||
"wait_approval" => [
|
||||
"template_id" => "SMS_462255406",
|
||||
"template_variable" => ""
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
/*
|
||||
* 旧接口配置
|
||||
*/
|
||||
'base_url' => [
|
||||
'old_api' => env('BASE_OLD_API_URL', ''),
|
||||
'old_shop_api' => env('BASE_OLD_SHOP_API_URL', ''),
|
||||
// 微信接口
|
||||
'we_chat_api' => env('BASE_WE_CHAT_API_URL', ''),
|
||||
],
|
||||
/*
|
||||
* 日志配置
|
||||
*/
|
||||
'log' => [
|
||||
// 不添加返回记录的api接口
|
||||
'no_insert' => [
|
||||
'api/admin/auth/login',
|
||||
'api/admin/auth/send-verification-code',
|
||||
'api/admin/auth/my-info',
|
||||
'api/admin/auth/codes',
|
||||
'api/admin/auth/menu',
|
||||
'api/admin/log/api-list',
|
||||
'api/admin/log/ledger-list',
|
||||
'api/admin/log/op-list',
|
||||
'api/admin/log/prescription-list',
|
||||
]
|
||||
],
|
||||
'app' => [
|
||||
'we_chat' => [
|
||||
'app_id' => '',
|
||||
'app_secret' => '',
|
||||
'merchant_id' => '',
|
||||
'merchant_key' => '',
|
||||
'apiclient_cert' => '',
|
||||
'apiclient_key' => ''
|
||||
]
|
||||
],
|
||||
];
|
||||
@@ -32,7 +32,7 @@ return [
|
||||
|
||||
'local' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app/private'),
|
||||
'root' => storage_path('app/public'),
|
||||
'serve' => true,
|
||||
'throw' => false,
|
||||
'report' => false,
|
||||
|
||||
504
config/helpers.php
Executable file
504
config/helpers.php
Executable file
@@ -0,0 +1,504 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* 辅助函数封装
|
||||
*/
|
||||
|
||||
/**
|
||||
* 路由注册封装
|
||||
* 使用 cc_route_register 函数,路由名需要用连词符 "-" 来表示,并且控制器要使用小驼峰的命名规范
|
||||
* @param $router
|
||||
* @param $class
|
||||
* @return void
|
||||
*/
|
||||
|
||||
if ( !function_exists('cc_route_register') ) {
|
||||
function cc_route_register ($router,$class): void
|
||||
{
|
||||
foreach ( $router as [ $method, $router_name ] ) {
|
||||
// ds(Illuminate\Support\Facades\Route::$method( $router_name, [$class, conjunction_symbol_processing($router_name)] ));
|
||||
Illuminate\Support\Facades\Route::$method( $router_name, [$class, conjunction_symbol_processing($router_name)] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动路由注册封装
|
||||
* 使用 cc_auto_route_register 函数,路由名需要用连词符 "-" 来表示,并且控制器要使用小驼峰的命名规范
|
||||
* @param $class
|
||||
* @return void
|
||||
*/
|
||||
if ( !function_exists('cc_auto_route_register') ) {
|
||||
function cc_auto_route_register ($class): void
|
||||
{
|
||||
foreach ($class as $key => $value) {
|
||||
|
||||
// 获取控制器$value的所有方法
|
||||
$methods = (new ReflectionClass($value))->getMethods();
|
||||
|
||||
// 注册路由
|
||||
foreach ($methods as $method) {
|
||||
// 获取方法注释 @Method
|
||||
$docComment = $method->getDocComment();
|
||||
if ($method->name === '__construct' || preg_match('/@Method\s+(NO)\b/', $docComment, $matches)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$httpMethod = 'any';
|
||||
// 查询 @Method GET 或者 @Method POST
|
||||
if (preg_match('/@Method\s+(GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD|ANY)\b/', $docComment, $matches)) {
|
||||
$httpMethod = $matches[1];
|
||||
}
|
||||
Illuminate\Support\Facades\Route::$httpMethod( $key. '/'. cc_camel_case_to_dash($method->getName()), [$value, conjunction_symbol_processing($method->name)] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 无限极分类
|
||||
* @param $data
|
||||
* @param $pid
|
||||
* @return mixed
|
||||
*/
|
||||
if ( !function_exists('tree') ) {
|
||||
function tree($data, $pid = 0, $idField = 'id', $pidField = 'pid'): array
|
||||
{
|
||||
$tree = array();
|
||||
foreach ($data as &$v)
|
||||
{
|
||||
if ($v[$pidField] == $pid)
|
||||
{
|
||||
$v['children'] = tree($data, $v[$idField], $idField, $pidField);
|
||||
if (empty($v['children'])) unset($v['children']);
|
||||
$tree[] = $v;
|
||||
}
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置不关闭
|
||||
* @return true
|
||||
*/
|
||||
if ( !function_exists('cc_set_time_limit') ) {
|
||||
function cc_set_time_limit(): bool {
|
||||
//让程序一直运行
|
||||
set_time_limit(0);
|
||||
//设置程序运行内存
|
||||
ini_set('memory_limit', '1024M');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 获取ip所属地
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
if ( !function_exists('cc_get_ip_lookup') ) {
|
||||
function cc_get_ip_lookup($ip = ''): array {
|
||||
$result = (new GuzzleHttp\Client())->get('https://api.vore.top/api/Weather?ip='. $ip);
|
||||
$weather = json_decode($result->getBody()->getContents(), true);
|
||||
if ( empty($weather) ) {
|
||||
$data = [
|
||||
'weather' => '未知',
|
||||
'temperature' => '未知',
|
||||
'winddirection' => '未知',
|
||||
'reporttime' => '未知',
|
||||
'area' => '未知',
|
||||
'info' => '未知',
|
||||
];
|
||||
} else {
|
||||
$data = [
|
||||
'area' => $weather['data']['ipdata']['area'],
|
||||
'info' => $weather['data']['ipdata']['info'],
|
||||
];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 获取ip
|
||||
*/
|
||||
if (!function_exists('get_ip')) {
|
||||
function get_ip() {
|
||||
return $_SERVER['HTTP_X_FORWARDED_FOR']?? request()->getClientIp();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取操作系统
|
||||
* @return string
|
||||
*/
|
||||
if ( !function_exists('cc_get_os') ) {
|
||||
function cc_get_os(): string {
|
||||
if (!empty($_SERVER['HTTP_USER_AGENT'])) {
|
||||
$os = $_SERVER['HTTP_USER_AGENT'];
|
||||
|
||||
return match (true) {
|
||||
str_contains($os, 'Windows') => 'Windows',
|
||||
str_contains($os, 'Macintosh') => 'Mac',
|
||||
str_contains($os, 'Linux') => 'Linux',
|
||||
str_contains($os, 'Android') => 'Android',
|
||||
str_contains($os, 'iOS') => 'iOS',
|
||||
str_contains($os, 'Api') => 'Api Post',
|
||||
default => 'Unknown',
|
||||
};
|
||||
} else {
|
||||
return "获取访客操作系统信息失败!";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取浏览器
|
||||
* @return string
|
||||
*/
|
||||
if ( !function_exists('cc_get_browser') ) {
|
||||
function cc_get_browser(): string {
|
||||
if (empty($_SERVER['HTTP_USER_AGENT'])) {
|
||||
return "获取浏览器信息失败!";
|
||||
}
|
||||
|
||||
$userAgent = $_SERVER['HTTP_USER_AGENT'];
|
||||
|
||||
foreach ([
|
||||
'MSIE' => 'MSIE',
|
||||
'Edg' => 'Microsoft Edge',
|
||||
'Firefox' => 'Firefox',
|
||||
'Chrome' => 'Chrome',
|
||||
'Safari' => 'Safari',
|
||||
'Opera' => 'Opera',
|
||||
'Api' => 'Api Post',
|
||||
] as $key => $browser) {
|
||||
if (str_contains($userAgent, $key)) {
|
||||
return $browser;
|
||||
}
|
||||
}
|
||||
|
||||
return 'Other';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在二维数组其中某个值相同时,提取指定的字段
|
||||
* @param $arr // 数组
|
||||
* @param $extract // 提取字段
|
||||
* @param $repeat // 重复字段
|
||||
* @param $isUnset // 是否删除未重复的值
|
||||
* @return array
|
||||
*/
|
||||
if ( !function_exists('cc_get_repeat_values') ) {
|
||||
function cc_get_repeat_values($arr, $extract, $repeat , $isUnset = false): array {
|
||||
$key = [];
|
||||
$result = [];
|
||||
$len = count($arr);
|
||||
for ( $i=0; $i<$len; $i++ ) {
|
||||
if ( !in_array($arr[$i][$repeat], $key) ) {
|
||||
if ( !array_key_exists($arr[$i][$repeat], $result) ) $result[$arr[$i][$repeat]] = [];
|
||||
$result[$arr[$i][$repeat]][] = $arr[$i][$extract];
|
||||
continue;
|
||||
}
|
||||
$key[] = $arr[$i][$repeat];
|
||||
}
|
||||
if ( $isUnset === true ) {
|
||||
// 删除未重复的下标
|
||||
foreach ( $result as $k => &$v ) {
|
||||
if ( count($v) <= 1 ) {
|
||||
unset($result[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据脱敏
|
||||
* @param string $str
|
||||
* @param string $type
|
||||
* @return string
|
||||
*/
|
||||
if ( !function_exists('desensitization') ) {
|
||||
|
||||
function desensitization(string $str, string $type = 'phone'): string
|
||||
{
|
||||
if (empty($str)) return '';
|
||||
|
||||
if ($type === 'phone') {
|
||||
if (strlen($str) !== 11) {
|
||||
throw new Exception('手机号格式错误');
|
||||
}
|
||||
return substr($str, 0, 3) . '****' . substr($str, 7);
|
||||
} elseif ($type === 'id_card') {
|
||||
if (strlen($str) !== 18) {
|
||||
throw new Exception('身份证号格式错误');
|
||||
}
|
||||
return substr($str, 0, 6) . '********' . substr($str, 14);
|
||||
} else {
|
||||
throw new Exception('类型错误');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 连赐福转换小驼峰
|
||||
* @param $string
|
||||
* @return string
|
||||
*/
|
||||
if(!function_exists('conjunction_symbol_processing')) {
|
||||
function conjunction_symbol_processing($string): string
|
||||
{
|
||||
$string = str_replace('-', ' ', $string); // 将连字符替换为空格
|
||||
$string = ucwords($string); // 将每个单词的首字母大写
|
||||
$string = str_replace(' ', '', $string); // 空格删除
|
||||
$string[0] = lcfirst($string)[0]; // 首字母小写
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 小驼峰转换-
|
||||
if ( !function_exists('cc_camel_case_to_dash') ) {
|
||||
function cc_camel_case_to_dash($str): string
|
||||
{
|
||||
return strtolower(preg_replace('/([a-z])([A-Z])/', '$1-$2', $str));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将驼峰字符串转化为下划线区分
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
if ( !function_exists('cc_camel_case_to_underscore') ) {
|
||||
function cc_camel_case_to_underscore($str): string
|
||||
{
|
||||
return strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $str));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 身份证脱敏
|
||||
* @return true
|
||||
*/
|
||||
if ( !function_exists('cc_id_card_text') ) {
|
||||
function cc_id_card_text($idCard): string {
|
||||
return substr_replace($idCard, '********', 6, 8 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号脱敏
|
||||
* @return true
|
||||
*/
|
||||
if ( !function_exists('cc_phone_text') ) {
|
||||
function cc_phone_text($phone): string {
|
||||
return substr_replace($phone, '******', 3, 6 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 身份证号验证
|
||||
* @param $id
|
||||
* @return bool
|
||||
*/
|
||||
if ( !function_exists('cc_is_id_card') ) {
|
||||
function cc_is_id_card($id): bool {
|
||||
$id = strtoupper($id);
|
||||
$regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/";
|
||||
$arr_split = array();
|
||||
if (!preg_match($regx, $id)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (15 == strlen($id)) //检查15位
|
||||
{
|
||||
$regx = "/^(\d{6})+(\d{2})+(\d{2})+(\d{2})+(\d{3})$/";
|
||||
@preg_match($regx, $id, $arr_split);
|
||||
//检查生日日期是否正确
|
||||
$dtm_birth = "19" . $arr_split[2] . '/' . $arr_split[3] . '/' . $arr_split[4];
|
||||
if (!strtotime($dtm_birth)) {
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
} else { //检查18位
|
||||
$regx = "/^(\d{6})+(\d{4})+(\d{2})+(\d{2})+(\d{3})([0-9]|X)$/";
|
||||
@preg_match($regx, $id, $arr_split);
|
||||
$dtm_birth = $arr_split[2] . '/' . $arr_split[3] . '/' . $arr_split[4];
|
||||
if (!strtotime($dtm_birth)) //检查生日日期是否正确
|
||||
{
|
||||
return FALSE;
|
||||
} else {
|
||||
//检验18位身份证的校验码是否正确。
|
||||
//校验位按照ISO 7064:1983.MOD 11-2的规定生成,X可以认为是数字10。
|
||||
$arr_int = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
|
||||
$arr_ch = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
|
||||
$sign = 0;
|
||||
for ($i = 0; $i < 17; $i++) {
|
||||
$b = (int) $id[$i];
|
||||
$w = $arr_int[$i];
|
||||
$sign += $b * $w;
|
||||
}
|
||||
$n = $sign % 11;
|
||||
$val_num = $arr_ch[$n];
|
||||
if ($val_num != substr($id, 17, 1)) {
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分割数字
|
||||
*/
|
||||
if (!function_exists('money_format')) {
|
||||
function money_format($number) {
|
||||
return preg_replace("/(?=\B(\d{3})+$)/", ',', $number);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码加密处理
|
||||
* @param $password
|
||||
* @return string
|
||||
*/
|
||||
if (!function_exists('ase_password')) {
|
||||
function ase_password($password): string
|
||||
{
|
||||
return sha1($password. config('cc.configs.ase.slate'));
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前项目启动的地址
|
||||
if (!function_exists('cc_get_project_url')) {
|
||||
function cc_get_project_url(): string
|
||||
{
|
||||
$url = config('cc.configs.project_url');
|
||||
if (empty($url)) {
|
||||
$url = request()->root(true);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密
|
||||
* @param $str
|
||||
* @return mixed|string
|
||||
*/
|
||||
if(!function_exists('ase_encode')) {
|
||||
function ase_encode($str)
|
||||
{
|
||||
if (empty($str)) return $str;
|
||||
return base64_encode(\Illuminate\Support\Str::random(config('ase.len')). base64_encode($str));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
* @param $str
|
||||
* @return false|string
|
||||
*/
|
||||
if (!function_exists('ase_decode')) {
|
||||
function ase_decode($str): bool|string
|
||||
{
|
||||
if (empty($str)) return $str?? '';
|
||||
$result = base64_decode($str);
|
||||
$result = base64_decode(substr($result, config('ase.len')));
|
||||
$pattern = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\xFF]|[\x{E000}-\x{F8FF}]/u';
|
||||
if (preg_match($pattern, $result)) return $str;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取选中的时间段有几天
|
||||
*
|
||||
* @param $startTime
|
||||
* @param $endTime
|
||||
* @return array
|
||||
*/
|
||||
if (!function_exists('get_day_list')) {
|
||||
function get_day_list($startTime, $endTime): array
|
||||
{
|
||||
$day = [];
|
||||
$currentTime = $startTime;
|
||||
while ($currentTime <= $endTime) {
|
||||
$day[] = date('m-d', $currentTime);
|
||||
$currentTime = strtotime('+1 day', $currentTime);
|
||||
}
|
||||
return $day;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取选中的时间段有几个月
|
||||
*
|
||||
* @param $startTime
|
||||
* @param $endTime
|
||||
* @return array
|
||||
*/
|
||||
if (!function_exists('get_month_list')) {
|
||||
function get_month_list($startTime, $endTime): array
|
||||
{
|
||||
$monthList = [];
|
||||
$currentTime = $startTime;
|
||||
while ($currentTime <= $endTime) {
|
||||
$monthList[] = date('Y-m', $currentTime);
|
||||
$currentTime = strtotime('+1 month', $currentTime);
|
||||
}
|
||||
return $monthList;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成32位的uuid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
if (!function_exists('gen_uuid')) {
|
||||
function gen_uuid(): string
|
||||
{
|
||||
$chart = md5(uniqid(rand(), true));
|
||||
$hyphen = chr(45);// "-"
|
||||
return substr($chart, 0, 8) . $hyphen
|
||||
. substr($chart, 8, 4) . $hyphen
|
||||
. substr($chart, 12, 4) . $hyphen
|
||||
. substr($chart, 16, 4) . $hyphen
|
||||
. substr($chart, 20, 12);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
if (!function_exists('get_time')) {
|
||||
function get_time($isString = false, $format = 'Y-m-d H:i:s'): string
|
||||
{
|
||||
return $isString === true ? date($format) : time();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
if (!function_exists('format_time')) {
|
||||
function format_time($time, $format = 'Y-m-d H:i:s'): string
|
||||
{
|
||||
return !empty($time)? date($format, $time) : '';
|
||||
}
|
||||
}
|
||||
112
config/response.php
Executable file
112
config/response.php
Executable file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use JetBrains\PhpStorm\NoReturn;
|
||||
|
||||
# 返回封装
|
||||
|
||||
/**
|
||||
* 请求成功返回
|
||||
* @param $data
|
||||
* @param $msg
|
||||
* @param $code
|
||||
* @return JsonResponse
|
||||
*/
|
||||
if ( !function_exists('jok') ) {
|
||||
function jok($data = [], $msg = '请求成功'): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'code' => 0,
|
||||
'message' => $msg,
|
||||
'result' => $data,
|
||||
'type' => 'success'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求失败返回
|
||||
* @param $data
|
||||
* @param $msg
|
||||
* @param $code
|
||||
* @return JsonResponse
|
||||
*/
|
||||
if ( !function_exists('jerr') ) {
|
||||
#[NoReturn]
|
||||
function jerr($msg = '', $data = [], $code = 500): JsonResponse
|
||||
{
|
||||
exit(json_encode([
|
||||
'code' => $code,
|
||||
'message' => $msg,
|
||||
'result' => $data,
|
||||
'type' => 'error'
|
||||
], JSON_UNESCAPED_UNICODE, JSON_PARTIAL_OUTPUT_ON_ERROR));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常返回(他会阻止后面所有代码的运行)
|
||||
* @param $data
|
||||
* @param $msg
|
||||
* @param $code
|
||||
* @return JsonResponse
|
||||
*/
|
||||
if ( !function_exists('jInstanceof') ) {
|
||||
function jInstanceof($code = 500, $msg = '错误返回', $data = []): JsonResponse
|
||||
{
|
||||
|
||||
// 转换成秒
|
||||
$timeDifference = microtime(true) - LARAVEL_START;
|
||||
|
||||
return response()->json([
|
||||
'code' => $code,
|
||||
'message' => $msg,
|
||||
'result' => $data,
|
||||
'type' => 'error',
|
||||
'interface_info' => [
|
||||
'result_time' => $timeDifference < 1? round($timeDifference * 1000) . ' ms': number_format($timeDifference, 1) . ' s',
|
||||
'ecs' => env('ECS')
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试 (他会阻止后面所有代码的运行)
|
||||
* @param $data
|
||||
* @param $msg
|
||||
* @param $code
|
||||
* @return void
|
||||
*/
|
||||
if ( !function_exists('ds') ) {
|
||||
#[NoReturn]
|
||||
function ds($data = [], $msg = '测试返回'): void
|
||||
{
|
||||
exit(json_encode([
|
||||
'code' => 19522,
|
||||
'message' => $msg,
|
||||
'result' => $data,
|
||||
'type' => 'success'
|
||||
],JSON_UNESCAPED_SLASHES,JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 身份过期返回(他会阻止后面所有代码的运行)
|
||||
* @param $data
|
||||
* @param $msg
|
||||
* @param $code
|
||||
* @return void
|
||||
*/
|
||||
if ( !function_exists('jexpire') ) {
|
||||
#[NoReturn]
|
||||
function jexpire($msg = '身份过期', $data = []): void
|
||||
{
|
||||
exit(json_encode([
|
||||
'code' => 401,
|
||||
'message' => $msg,
|
||||
'result' => $data,
|
||||
'type' => 'jexpire'
|
||||
],JSON_UNESCAPED_SLASHES,JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
}
|
||||
357
public/cc_spa_init.sql
Normal file
357
public/cc_spa_init.sql
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
Navicat Premium Dump SQL
|
||||
|
||||
Source Server : 测试库
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 80404 (8.4.4)
|
||||
Source Host : 101.43.12.11:3306
|
||||
Source Schema : cc_spa
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 80404 (8.4.4)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 07/05/2025 14:54:10
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for categories
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `categories`;
|
||||
CREATE TABLE `categories` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '分类名称',
|
||||
`pid` int NOT NULL DEFAULT 0 COMMENT '父级分类',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '创建时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '更新时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '商品分类' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of categories
|
||||
-- ----------------------------
|
||||
INSERT INTO `categories` VALUES (1, 'Web 应用', 0, 0, 0, 0);
|
||||
INSERT INTO `categories` VALUES (2, '移动端', 0, 0, 0, 0);
|
||||
INSERT INTO `categories` VALUES (3, '微信小程序', 0, 0, 0, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for collection
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `collection`;
|
||||
CREATE TABLE `collection` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`project_id` int NOT NULL DEFAULT 0 COMMENT '项目ID',
|
||||
`user_id` int NOT NULL DEFAULT 0 COMMENT '用户ID',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '注册时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '编辑时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户收藏表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of collection
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for features
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `features`;
|
||||
CREATE TABLE `features` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`project_id` int NOT NULL DEFAULT 0 COMMENT '项目ID',
|
||||
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '说明',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '注册时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '编辑时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '核心功能表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of features
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for file
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `file`;
|
||||
CREATE TABLE `file` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`user_id` int NOT NULL DEFAULT 0 COMMENT '上传者ID',
|
||||
`url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '项目截图地址',
|
||||
`type` int NOT NULL DEFAULT 0 COMMENT '类型 0:图片 1:视频 2:压缩包 3:excel 4:pdf',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '注册时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '编辑时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '文件表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of file
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for frameworks
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `frameworks`;
|
||||
CREATE TABLE `frameworks` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '框架名称',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '创建时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '更新时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '框架表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of frameworks
|
||||
-- ----------------------------
|
||||
INSERT INTO `frameworks` VALUES (1, 'Laravel', 1745829979, 0, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for labels
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `labels`;
|
||||
CREATE TABLE `labels` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '标签名称',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '创建时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '更新时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '标签表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of labels
|
||||
-- ----------------------------
|
||||
INSERT INTO `labels` VALUES (1, 'PHP', 1746424986, 0, 0);
|
||||
INSERT INTO `labels` VALUES (2, 'VUE', 1746424986, 0, 0);
|
||||
INSERT INTO `labels` VALUES (3, 'Golang', 1746424986, 0, 0);
|
||||
INSERT INTO `labels` VALUES (4, 'JAVA', 1746424986, 0, 0);
|
||||
INSERT INTO `labels` VALUES (5, 'HTML', 1746424986, 0, 0);
|
||||
INSERT INTO `labels` VALUES (6, 'Docker', 1746424986, 0, 0);
|
||||
INSERT INTO `labels` VALUES (7, 'Mysql', 1746424986, 0, 0);
|
||||
INSERT INTO `labels` VALUES (8, 'Redis', 1746424986, 0, 0);
|
||||
INSERT INTO `labels` VALUES (9, 'RabbitMQ', 1746424986, 0, 0);
|
||||
INSERT INTO `labels` VALUES (10, 'MongoDB', 1746424986, 0, 0);
|
||||
INSERT INTO `labels` VALUES (11, 'Javascript', 1746424986, 0, 0);
|
||||
INSERT INTO `labels` VALUES (12, 'Type Javascript', 1746424986, 0, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for order_items
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `order_items`;
|
||||
CREATE TABLE `order_items` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`order_id` int NOT NULL DEFAULT 0 COMMENT '订单ID',
|
||||
`project_id` int NOT NULL DEFAULT 0 COMMENT '项目ID',
|
||||
`price` decimal(50, 3) NOT NULL DEFAULT 0.000 COMMENT '价格',
|
||||
`preferential_price` decimal(50, 2) NOT NULL DEFAULT 0.00 COMMENT '优惠价格',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '注册时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '编辑时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '订单详情表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of order_items
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for orders
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `orders`;
|
||||
CREATE TABLE `orders` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '订单号',
|
||||
`user_id` int NOT NULL DEFAULT 0 COMMENT '用户ID',
|
||||
`total_price` decimal(50, 3) NOT NULL DEFAULT 0.000 COMMENT '总价',
|
||||
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态 0:待支付 1:已支付 2:已交付 3:已完成 4:已取消',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '注册时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '编辑时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '订单表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of orders
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for partners
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `partners`;
|
||||
CREATE TABLE `partners` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '合作伙伴名称',
|
||||
`logo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'LOGO',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '创建时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '更新时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '合作伙伴表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of partners
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for project_frameworks_relations
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `project_frameworks_relations`;
|
||||
CREATE TABLE `project_frameworks_relations` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`project_id` int NOT NULL DEFAULT 0 COMMENT '项目ID',
|
||||
`framework_id` int NOT NULL COMMENT '框架ID',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '注册时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '编辑时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '项目框架关联表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of project_frameworks_relations
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for project_label_relations
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `project_label_relations`;
|
||||
CREATE TABLE `project_label_relations` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`project_id` int NOT NULL DEFAULT 0 COMMENT '项目ID',
|
||||
`label_id` int NOT NULL COMMENT '标签ID',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '注册时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '编辑时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 33 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '标签项目关联表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of project_label_relations
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for projects
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `projects`;
|
||||
CREATE TABLE `projects` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`user_id` int NOT NULL DEFAULT 0 COMMENT '用户ID',
|
||||
`title` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '项目标题',
|
||||
`cover` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '项目封面',
|
||||
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '项目简介',
|
||||
`video_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '视频解说地址',
|
||||
`author_id` int NOT NULL DEFAULT 0 COMMENT '开发者',
|
||||
`category_id` int NOT NULL DEFAULT 0 COMMENT '项目分类',
|
||||
`price` decimal(50, 3) NOT NULL DEFAULT 0.000 COMMENT '价格',
|
||||
`preferential_price` decimal(50, 2) NOT NULL DEFAULT 0.00 COMMENT '优惠价格',
|
||||
`front` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '0' COMMENT '前端技术栈',
|
||||
`service` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '0' COMMENT '服务端',
|
||||
`deploy` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '0' COMMENT '部署',
|
||||
`is_selected` tinyint(1) NOT NULL DEFAULT 0 COMMENT '精选 0:否 1:是',
|
||||
`is_carousel` tinyint(1) NOT NULL DEFAULT 0 COMMENT '轮播图 0:否 1:是',
|
||||
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态 0:草稿 1:上架 2:下架 3:重构中',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '注册时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '编辑时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '项目表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of projects
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for roles
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `roles`;
|
||||
CREATE TABLE `roles` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色名称',
|
||||
`value` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色值',
|
||||
`pid` int NOT NULL DEFAULT 0 COMMENT '上级角色',
|
||||
`desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '角色说明',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '创建时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '更新时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of roles
|
||||
-- ----------------------------
|
||||
INSERT INTO `roles` VALUES (1, '超级管理员', 'admin', 0, '站长', 1745829979, 0, 0);
|
||||
INSERT INTO `roles` VALUES (2, '用户', 'user', 0, '普通用户', 1745829980, 0, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for screenshots
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `screenshots`;
|
||||
CREATE TABLE `screenshots` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`project_id` int NOT NULL DEFAULT 0 COMMENT '项目ID',
|
||||
`url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '项目截图地址',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '注册时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '编辑时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '项目截图表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of screenshots
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_pay
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `user_pay`;
|
||||
CREATE TABLE `user_pay` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`project_id` int NOT NULL DEFAULT 0 COMMENT '项目ID',
|
||||
`user_id` int NOT NULL DEFAULT 0 COMMENT '用户ID',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '注册时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '编辑时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户购买表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of user_pay
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for users
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
CREATE TABLE `users` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`account` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '账号',
|
||||
`nick_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '昵称',
|
||||
`avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '头像',
|
||||
`email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '邮箱',
|
||||
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '登录密码',
|
||||
`balance` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '余额',
|
||||
`qr_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '微信二维码地址',
|
||||
`role_id` int NOT NULL DEFAULT 0 COMMENT '角色',
|
||||
`is_sys_notifications` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否接受邮件系统通知 0:不接受 1:接受',
|
||||
`is_collection_notifications` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否接受收藏的项目更新信息 0:不接受 1:接受',
|
||||
`is_marketing_notifications` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否接受营销信息 0:不接受 1:接受',
|
||||
`ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '本次登录ip',
|
||||
`ip_table` json NOT NULL COMMENT '常用登录IP地址列表',
|
||||
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态 0:正常 1:冻结 2:封号 3:注销',
|
||||
`last_reset_password_at` int NOT NULL DEFAULT 0 COMMENT '最后一次修改密码的时间',
|
||||
`created_at` int NOT NULL DEFAULT 0 COMMENT '注册时间',
|
||||
`updated_at` int NOT NULL DEFAULT 0 COMMENT '编辑时间',
|
||||
`deleted_at` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of users
|
||||
-- ----------------------------
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
28
routes/api.php
Normal file
28
routes/api.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use App\Service\common\UtilsService;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
});
|
||||
|
||||
/**
|
||||
* 自动注册路由
|
||||
*/
|
||||
UtilsService::class::getInstance()->autoRouteRegister([
|
||||
'' => \App\Http\Controllers\LoginController::class, // 登录控制器
|
||||
'home' => \App\Http\Controllers\HomeController::class, // 首页控制器
|
||||
]);
|
||||
|
||||
Route::group([], function () {
|
||||
UtilsService::class::getInstance()->autoRouteRegister([
|
||||
'user' => \App\Http\Controllers\UserController::class, // 用户控制器
|
||||
'project' => \App\Http\Controllers\ProjectController::class, // 项目控制器
|
||||
'role' => \App\Http\Controllers\RoleController::class, // 角色控制器
|
||||
'upload' => \App\Http\Controllers\UploadController::class, // 上传控制器
|
||||
'label' => \App\Http\Controllers\LabelController::class, // 标签控制器
|
||||
'category' => \App\Http\Controllers\CategoryController::class, // 分类控制器
|
||||
'collection' => \App\Http\Controllers\CollectionController::class, // 收藏控制器
|
||||
]);
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import laravel from 'laravel-vite-plugin';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
laravel({
|
||||
input: ['resources/css/app.css', 'resources/js/app.js'],
|
||||
refresh: true,
|
||||
}),
|
||||
tailwindcss(),
|
||||
],
|
||||
});
|
||||
Reference in New Issue
Block a user