This commit is contained in:
Aether
2025-09-26 10:41:43 +08:00
parent 26ee79b951
commit 0c7142ad46
14 changed files with 157 additions and 427 deletions

4
.env
View File

@@ -24,6 +24,6 @@ NACOS_HOST=192.168.28.199
NACOS_PORT=8848
NACOS_USERNAME=nacos
NACOS_PASSWORD=nacos
NACOS_NAMESPACE=e42b853c-5195-478b-b5e3-6d49f6a45053
NACOS_GROUP=dev
NACOS_NAMESPACE_ID=e42b853c-5195-478b-b5e3-6d49f6a45053
NACOS_GROUP=api
NACOS_SERVICE_NAME=DataCampusService

View File

@@ -1,98 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use Aether\AetherController;
use Aether\AetherCrudService;
use Aether\AetherResponse;
use App\JsonRpc\Service\CampusService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Throwable;
#[Controller(prefix: '/api/v1')]
class CampusController extends AetherController
{
#[Inject]
protected CampusService $service;
#[Inject]
protected RequestInterface $request;
/**
* 校区列表.
*/
#[GetMapping(path: 'campus/list')]
public function list(RequestInterface $request): array
{
return AetherResponse::success($this->service->list($request->all()));
}
/**
* 获取省份列表.
*/
#[GetMapping(path: 'campus/provinces')]
public function provinces(): array
{
return AetherResponse::success($this->service->getProvinces());
}
/**
* 获取城市列表.
*/
#[GetMapping(path: 'campus/cities')]
public function cities(RequestInterface $request): array
{
return AetherResponse::success($this->service->getCitiesByProvince($request->input('province_id')));
}
/**
* 创建校区.
* @throws Throwable
*/
#[PostMapping(path: 'campus')]
public function create(): array
{
return AetherResponse::success($this->service->create($this->request->all()), '校区创建成功');
}
/**
* 获取校区详情.
*/
#[GetMapping(path: 'campus/{id}')]
public function get(int $id): array
{
return AetherResponse::success($this->service->detail($id));
}
/**
* 更新校区.
* @throws Throwable
*/
#[PutMapping(path: 'campus/{id}')]
public function update(int $id): array
{
return AetherResponse::success($this->service->update($id, $this->request->all()), '校区更新成功');
}
/**
* 删除校区.
* @throws Throwable
*/
#[DeleteMapping(path: 'campus/{id}')]
public function delete(int $id): array
{
return AetherResponse::success($this->service->delete($id), '校区删除成功');
}
protected function getService(): AetherCrudService
{
return $this->service;
}
}

View File

@@ -1,81 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use Aether\AetherController;
use Aether\AetherCrudService;
use Aether\AetherResponse;
use App\JsonRpc\Service\TeacherService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Throwable;
#[Controller(prefix: '/api/v1')]
class TeacherController extends AetherController
{
#[Inject]
protected TeacherService $service;
#[Inject]
protected RequestInterface $request;
/**
* 教师列表.
*/
#[GetMapping(path: 'teacher/list')]
public function list(RequestInterface $request): array
{
return AetherResponse::success($this->service->list($request->all()));
}
/**
* 创建教师.
* @throws Throwable
*/
#[PostMapping(path: 'teacher')]
public function create(): array
{
return AetherResponse::success($this->service->create($this->request->all()), '教师创建成功');
}
/**
* 获取教师详情.
*/
#[GetMapping(path: 'teacher/{id}')]
public function get(int $id): array
{
return AetherResponse::success($this->service->detail($id));
}
/**
* 更新教师.
* @throws Throwable
*/
#[PutMapping(path: 'teacher/{id}')]
public function update(int $id): array
{
return AetherResponse::success($this->service->update($id, $this->request->all()), '教师更新成功');
}
/**
* 删除教师.
* @throws Throwable
*/
#[DeleteMapping(path: 'teacher/{id}')]
public function delete(int $id): array
{
return AetherResponse::success($this->service->delete($id), '教师删除成功');
}
protected function getService(): AetherCrudService
{
return $this->service;
}
}

View File

@@ -1,84 +0,0 @@
<?php
declare(strict_types=1);
namespace App\JsonRpc\Service;
use Aether\AetherCrudService;
use Aether\AetherModel;
use Aether\AetherValidator;
use Aether\Exception\BusinessException;
use App\Model\Campus;
use App\Validator\CampusValidator;
use Hyperf\Di\Annotation\Inject;
use Hyperf\RpcServer\Annotation\RpcService;
use MicroService\Contract\CampusServiceInterface;
#[RpcService(
name: 'CampusService',
server: 'jsonrpc-http',
protocol: 'jsonrpc-http',
publishTo: 'nacos'
)]
class CampusService extends AetherCrudService implements CampusServiceInterface
{
#[Inject]
protected Campus $model;
#[Inject]
protected CampusValidator $validator;
public function getCampusById(int $id): array
{
$campus = Campus::find($id);
if (! $campus || $campus->status != 1) {
throw new BusinessException('校区不存在或已禁用', 10001);
}
return $campus->toArray();
}
public function getCampusesByIds(array $ids): array
{
return Campus::whereIn('id', $ids)
->enabled()
->get()
->toArray();
}
public function getCampusesByParentId(int $parentId): array
{
return Campus::where('parent_id', $parentId)
->enabled()
->get()
->toArray();
}
public function getProvinces(): array
{
return Campus::level(1)
->enabled()
->orderBy('name')
->get(['id', 'name', 'province'])
->toArray();
}
public function getCitiesByProvince(string $province): array
{
return Campus::level(2)
->province($province)
->enabled()
->orderBy('name')
->get(['id', 'name', 'city'])
->toArray();
}
protected function getModel(): AetherModel
{
return $this->model;
}
protected function getValidator(): AetherValidator
{
return $this->validator;
}
}

View File

@@ -4,29 +4,66 @@ declare(strict_types=1);
namespace App\JsonRpc\Service;
use Aether\AetherCrudService;
use Aether\AetherModel;
use Aether\AetherValidator;
use Aether\Exception\BusinessException;
use App\Model\Campus;
use App\Model\Teacher;
use App\Validator\TeacherValidator;
use App\Validator\CampusValidator;
use Hyperf\Di\Annotation\Inject;
use Hyperf\RpcServer\Annotation\RpcService;
use MicroService\Contract\TeacherServiceInterface;
use MicroService\Contract\DataServiceInterface;
#[RpcService(
name: 'DataTeacher',
server: 'jsonrpc-http',
protocol: 'jsonrpc-http',
publishTo: 'nacos'
)]
class TeacherService extends AetherCrudService implements TeacherServiceInterface
#[RpcService(name: 'DataService', server: 'jsonrpc-http', protocol: 'jsonrpc-http', publishTo: 'nacos')]
class DataService implements DataServiceInterface
{
#[Inject]
protected Teacher $model;
protected Campus $campusModel;
#[Inject]
protected TeacherValidator $validator;
protected CampusValidator $campusValidator;
public function getCampusById(int $id): array
{
$campus = Campus::find($id);
if (! $campus || $campus->status != 1) {
throw new BusinessException('校区不存在或已禁用', 10001);
}
return $campus->toArray();
}
public function getCampusesByIds(array $ids): array
{
return Campus::whereIn('id', $ids)
->enabled()
->get()
->toArray();
}
public function getCampusesByParentId(int $parentId): array
{
return Campus::where('parent_id', $parentId)
->enabled()
->get()
->toArray();
}
public function getProvinces(): array
{
return Campus::level(1)
->enabled()
->orderBy('name')
->get(['id', 'name', 'province'])
->toArray();
}
public function getCitiesByProvince(string $province): array
{
return Campus::level(2)
->province($province)
->enabled()
->orderBy('name')
->get(['id', 'name', 'city'])
->toArray();
}
public function getTeacherById(int $id): array
{
@@ -96,14 +133,4 @@ class TeacherService extends AetherCrudService implements TeacherServiceInterfac
'list' => $list,
];
}
protected function getModel(): AetherModel
{
return $this->model;
}
protected function getValidator(): AetherValidator
{
return $this->validator;
}
}

View File

@@ -1,18 +1,21 @@
<?php
declare(strict_types=1);
/**
use Hyperf\Cache\Driver\RedisDriver;
use Hyperf\Codec\Packer\PhpSerializerPacker;
/*
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @see https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
return [
'default' => [
'driver' => Hyperf\Cache\Driver\RedisDriver::class,
'packer' => Hyperf\Codec\Packer\PhpSerializerPacker::class,
'driver' => RedisDriver::class,
'packer' => PhpSerializerPacker::class,
'prefix' => 'c:',
'skip_cache_results' => [],
],

View File

@@ -1,44 +1,36 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
return [
'generator' => [
'amqp' => [
'consumer' => [
'namespace' => 'App\\Amqp\\Consumer',
'namespace' => 'App\Amqp\Consumer',
],
'producer' => [
'namespace' => 'App\\Amqp\\Producer',
'namespace' => 'App\Amqp\Producer',
],
],
'aspect' => [
'namespace' => 'App\\Aspect',
'namespace' => 'App\Aspect',
],
'command' => [
'namespace' => 'App\\Command',
'namespace' => 'App\Command',
],
'controller' => [
'namespace' => 'App\\Controller',
'namespace' => 'App\Controller',
],
'job' => [
'namespace' => 'App\\Job',
'namespace' => 'App\Job',
],
'listener' => [
'namespace' => 'App\\Listener',
'namespace' => 'App\Listener',
],
'middleware' => [
'namespace' => 'App\\Middleware',
'namespace' => 'App\Middleware',
],
'Process' => [
'namespace' => 'App\\Processes',
'namespace' => 'App\Processes',
],
],
];

View File

@@ -2,20 +2,11 @@
declare(strict_types=1);
use Aether\ApiExceptionHandler;
use Aether\GlobalExceptionHandler;
use Aether\RpcExceptionHandler;
use Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler;
return [
'handler' => [
'http' => [
// HttpExceptionHandler::class,
// ApiExceptionHandler::class,
GlobalExceptionHandler::class,
],
'jsonrpc-http' => [
HttpExceptionHandler::class,
RpcExceptionHandler::class,
],
],

View File

@@ -1,15 +1,18 @@
<?php
declare(strict_types=1);
/**
use Hyperf\Command\Listener\FailToHandleListener;
use Hyperf\ExceptionHandler\Listener\ErrorExceptionHandler;
/*
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @see https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
return [
Hyperf\ExceptionHandler\Listener\ErrorExceptionHandler::class,
Hyperf\Command\Listener\FailToHandleListener::class,
ErrorExceptionHandler::class,
FailToHandleListener::class,
];

View File

@@ -1,10 +1,14 @@
<?php
declare(strict_types=1);
/**
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
/*
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @see https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
@@ -12,14 +16,14 @@ declare(strict_types=1);
return [
'default' => [
'handler' => [
'class' => Monolog\Handler\StreamHandler::class,
'class' => StreamHandler::class,
'constructor' => [
'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
'level' => Monolog\Logger::DEBUG,
'level' => Logger::DEBUG,
],
],
'formatter' => [
'class' => Monolog\Formatter\LineFormatter::class,
'class' => LineFormatter::class,
'constructor' => [
'format' => null,
'dateFormat' => 'Y-m-d H:i:s',

View File

@@ -15,20 +15,6 @@ use function Hyperf\Support\env;
return [
'mode' => SWOOLE_PROCESS,
'servers' => [
// [
// 'name' => 'http',
// 'type' => Server::SERVER_HTTP,
// 'host' => '0.0.0.0',
// 'port' => 9501,
// 'sock_type' => SWOOLE_SOCK_TCP,
// 'callbacks' => [
// Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
// ],
// 'options' => [
// // Whether to enable request lifecycle event
// 'enable_request_lifecycle' => false,
// ],
// ],
[
'name' => 'jsonrpc-http',
'type' => Server::SERVER_HTTP,
@@ -39,7 +25,7 @@ return [
Event::ON_REQUEST => [JsonRpcHttpServer::class, 'onRequest'],
],
'settings' => [
// 'open_eof_split' => true,
'open_eof_split' => true,
'package_eof' => "\r\n",
'package_max_length' => 1024 * 1024 * 2,
],

View File

@@ -1,62 +1,56 @@
<?php
declare(strict_types=1);
use MicroService\Contract\DataServiceInterface;
use function Hyperf\Support\env;
return [
'enable' => true,
'driver' => 'nacos',
'enable' => [
'discovery' => true,
'register' => true,
],
'consumers' => [
// 数据服务消费者配置
[
'name' => 'DataService',
'service' => DataServiceInterface::class,
'registry' => [
'protocol' => 'nacos',
'address' => 'http://192.168.28.199:8848/',
],
'protocol' => 'jsonrpc-http',
'options' => [
'timeout' => 0.5,
],
],
],
'providers' => [
[
'id' => 'hyperf-gateway',
'service' => 'hyperf-gateway',
'protocol' => 'jsonrpc-http',
'load_balancer' => 'random',
'registry' => [
'protocol' => 'nacos',
'address' => 'http://192.168.28.199:8848',
],
],
],
'drivers' => [
'nacos' => [
// nacos server url like https://nacos.hyperf.io, Priority is higher than host:port
// 'url' => '',
// The nacos host info
'host' => env('NACOS_HOST', '127.0.0.1'),
'host' => env('NACOS_HOST', '192.168.28.199'),
'port' => env('NACOS_PORT', 8848),
// The nacos account info
'username' => null,
'password' => null,
// 'username' => null,
// 'password' => null,
'guzzle' => [
'config' => null,
],
'group_name' => 'api',
'namespace_id' => env('NACOS_NAMESPACE', 'dev'),
'group_name' => env('NACOS_GROUP', 'api'),
'namespace_id' => env('NACOS_NAMESPACE_ID', 'dev'),
'heartbeat' => 5,
],
],
'registries' => [
[
'name' => 'DataCampus',
'host' => env('NACOS_HOST', '192.168.28.199'),
'port' => env('NACOS_PORT', 8848),
// 'username' => env('NACOS_USERNAME', 'nacos'),
// 'password' => env('NACOS_PASSWORD', 'nacos'),
'namespace' => env('NACOS_NAMESPACE', 'e42b853c-5195-478b-b5e3-6d49f6a45053'),
'group_name' => env('NACOS_GROUP', 'DEFAULT_GROUP'),
'service_name' => 'DataCampus',
'metadata' => [
'protocol' => 'jsonrpc-http',
'server' => 'jsonrpc-http',
],
'heartbeat' => 5,
'heartbeat_timeout' => 15,
],
[
'name' => 'DataTeacherService',
'host' => env('NACOS_HOST', '192.168.28.199'),
'port' => env('NACOS_PORT', 8848),
// 'username' => env('NACOS_USERNAME', 'nacos'),
// 'password' => env('NACOS_PASSWORD', 'nacos'),
'namespace' => env('NACOS_NAMESPACE', 'e42b853c-5195-478b-b5e3-6d49f6a45053'),
'group_name' => env('NACOS_GROUP', 'DEFAULT_GROUP'),
'service_name' => 'DataTeacherService',
'metadata' => [
'protocol' => 'jsonrpc-http',
'server' => 'jsonrpc-http',
],
'heartbeat' => 5,
'heartbeat_timeout' => 15,
],
],
];

View File

@@ -1,37 +0,0 @@
<?php
declare(strict_types=1);
namespace MicroService\Contract;
interface CampusServiceInterface
{
/**
* 获取校区详情.
* @param int $id 校区ID
*/
public function getCampusById(int $id): array;
/**
* 批量获取校区信息.
* @param array $ids 校区ID列表
*/
public function getCampusesByIds(array $ids): array;
/**
* 根据父ID获取子校区.
* @param int $parentId 父级ID
*/
public function getCampusesByParentId(int $parentId): array;
/**
* 获取省份列表.
*/
public function getProvinces(): array;
/**
* 根据省份获取城市列表.
* @param string $province 省份名称
*/
public function getCitiesByProvince(string $province): array;
}

View File

@@ -1,11 +1,41 @@
<?php
declare(strict_types=1);
namespace MicroService\Contract;
interface TeacherServiceInterface
interface DataServiceInterface
{
// ----------------- 校区服务 -----------------
/**
* 获取校区详情.
* @param int $id 校区ID
*/
public function getCampusById(int $id): array;
/**
* 批量获取校区信息.
* @param array $ids 校区ID列表
*/
public function getCampusesByIds(array $ids): array;
/**
* 根据父ID获取子校区.
* @param int $parentId 父级ID
*/
public function getCampusesByParentId(int $parentId): array;
/**
* 获取省份列表.
*/
public function getProvinces(): array;
/**
* 根据省份获取城市列表.
* @param string $province 省份名称
*/
public function getCitiesByProvince(string $province): array;
// ----------------- 教师服务 -----------------
/**
* 获取教师详情.
* @param int $id 教师ID
@@ -41,4 +71,4 @@ interface TeacherServiceInterface
* @param int $size 每页条数
*/
public function searchTeachers(string $keyword, int $page = 1, int $size = 20): array;
}
}