Skip to content

Commit 4524256

Browse files
committed
Release 0.0.1
0 parents  commit 4524256

74 files changed

Lines changed: 5294 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/.idea
2+
/.vscode
3+
/vendor
4+
*.log
5+
.env
6+
/tests/tmp
7+
/tests/.phpunit.result.cache
8+
/config/SALT

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 walkor<walkor@workerman.net> and contributors (see https://github.com/walkor/webman/contributors)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# webman
2+
3+
High performance HTTP Service Framework for PHP based on [Workerman](https://github.com/walkor/workerman).
4+
5+
# Manual (文档)
6+
7+
https://www.workerman.net/doc/webman
8+
9+
# Home page (主页)
10+
https://www.workerman.net/webman
11+
12+
13+
# Benchmarks (压测)
14+
15+
https://www.techempower.com/benchmarks/#section=test&runid=9716e3cd-9e53-433c-b6c5-d2c48c9593c1&hw=ph&test=db&l=zg24n3-1r&a=2
16+
![image](https://user-images.githubusercontent.com/6073368/96447814-120fc980-1245-11eb-938d-6ea408716c72.png)
17+
18+
## LICENSE
19+
20+
MIT

app/client/NodeClient.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace app\client;
4+
5+
use app\model\Node;
6+
7+
class NodeClient
8+
{
9+
public Node $node;
10+
public string $node_token;
11+
12+
public function __construct(Node $node)
13+
{
14+
$this->node = $node;
15+
}
16+
17+
protected function buildUrl($uri)
18+
{
19+
return $this->node->getAddress() . $uri;
20+
}
21+
22+
public function get($uri)
23+
{
24+
$ch = curl_init($this->buildUrl($uri));
25+
curl_setopt_array($ch, [
26+
CURLOPT_RETURNTRANSFER => true,
27+
CURLOPT_HTTPHEADER => [
28+
'Authorization: Bearer ' . $this->node_token
29+
]
30+
]);
31+
$return = json_decode(curl_exec($ch), true);
32+
curl_close($ch);
33+
34+
$this->checkResponse($return);
35+
36+
return $return;
37+
}
38+
39+
public function post($uri, $data): array
40+
{
41+
$ch = curl_init($this->buildUrl($uri));
42+
curl_setopt_array($ch, [
43+
CURLOPT_RETURNTRANSFER => true,
44+
CURLOPT_POST => true,
45+
CURLOPT_POSTFIELDS => json_encode($data),
46+
CURLOPT_HTTPHEADER => [
47+
'Content-type: application/json',
48+
'Authorization: Bearer ' . $this->node->node_token
49+
]
50+
]);
51+
$return = json_decode(curl_exec($ch), true);
52+
curl_close($ch);
53+
54+
$this->checkResponse($return);
55+
56+
return $return;
57+
}
58+
59+
public function put($uri, $data): array
60+
{
61+
$ch = curl_init($this->buildUrl($uri));
62+
curl_setopt_array($ch, [
63+
CURLOPT_RETURNTRANSFER => true,
64+
CURLOPT_CUSTOMREQUEST => 'PUT',
65+
CURLOPT_POSTFIELDS => json_encode($data),
66+
CURLOPT_HTTPHEADER => [
67+
'Content-type: application/json',
68+
'Authorization: Bearer ' . $this->node->node_token
69+
]
70+
]);
71+
$return = json_decode(curl_exec($ch), true);
72+
curl_close($ch);
73+
74+
$this->checkResponse($return);
75+
76+
return $return;
77+
}
78+
79+
protected function checkResponse(array $return)
80+
{
81+
if (!isset($return['code'])) throw new \Exception('节点无响应。', 500);
82+
if ($return['code'] != 200) throw new \Exception('[Node] ' . $return['msg'], $return['code']);
83+
}
84+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
namespace app\controller\Admin;
4+
5+
use app\model\Game;
6+
use app\model\User;
7+
use app\util\Validate;
8+
use Illuminate\Database\Eloquent\ModelNotFoundException;
9+
use support\Db;
10+
use support\Request;
11+
12+
class AdminUserController
13+
{
14+
static public $rules = [
15+
'id' => 'nullable|integer',
16+
'name' => 'required|max:32',
17+
'password' => 'nullable|min:6',
18+
'email' => 'required|max:64',
19+
'is_admin' => 'required|boolean'
20+
];
21+
22+
public function GetList(Request $request)
23+
{
24+
return json([
25+
'code' => 200,
26+
'data' => User::select(['id', 'name', 'email', 'is_admin', 'updated_at', 'created_at'])
27+
->withCount('instances')
28+
->get()
29+
]);
30+
}
31+
32+
public function Create(Request $request)
33+
{
34+
try {
35+
$rules = self::$rules;
36+
$rules['password'] = 'required|min:6';
37+
38+
$data = Validate::Input($request, $rules);
39+
40+
if (User::where('name', $data['name'])->orWhere('email', $data['email'])->first())
41+
throw new \Exception('已存在同名或同邮箱用户。', 400);
42+
43+
$user = new User();
44+
$user->fill($data);
45+
$user->passwd($data['password']);
46+
$user->save();
47+
48+
return json(['code' => 200]);
49+
} catch (\Throwable $th) {
50+
return json(['code' => $th->getCode() ?: 500, 'msg' => $th->getMessage()])->withStatus($th->getCode() ?: 500);
51+
}
52+
}
53+
54+
public function GetDetail(Request $request, Int $userId)
55+
{
56+
try {
57+
return json([
58+
'code' => 200,
59+
'attributes' => User::findOrFail($userId)->makeHidden('password')
60+
]);
61+
} catch (ModelNotFoundException $e) {
62+
return json(['code' => 400, 'msg' => '用户不存在。'])->withStatus(400);
63+
} catch (\Throwable $th) {
64+
return json(['code' => $th->getCode() ?: 500, 'msg' => $th->getMessage()])->withStatus($th->getCode() ?: 500);
65+
}
66+
}
67+
68+
public function Update(Request $request, int $userId)
69+
{
70+
try {
71+
$data = Validate::Input($request, self::$rules);
72+
$user = User::findOrFail($userId)->fill($data);
73+
if ($data['password']) $user->passwd($data['password']);
74+
$user->save();
75+
76+
return json(['code' => 200]);
77+
} catch (ModelNotFoundException $e) {
78+
return json(['code' => 400, 'msg' => '用户不存在。'])->withStatus(400);
79+
} catch (\Throwable $th) {
80+
return json(['code' => $th->getCode() ?: 500, 'msg' => $th->getMessage()])->withStatus($th->getCode() ?: 500);
81+
}
82+
}
83+
84+
public function Delete(Request $request, int $userId)
85+
{
86+
try {
87+
$user = User::withCount(['instances'])->findOrFail($userId);
88+
if ($user->instances_count > 0) throw new \Exception('无法删除拥有实例的用户。', 400);
89+
$user->delete();
90+
91+
// TODO 删除其他用户数据
92+
93+
return json(['code' => 200]);
94+
} catch (ModelNotFoundException $e) {
95+
return json(['code' => 400, 'msg' => '用户不存在。'])->withStatus(400);
96+
} catch (\Throwable $th) {
97+
return json(['code' => $th->getCode() ?: 500, 'msg' => $th->getMessage()])->withStatus($th->getCode() ?: 500);
98+
}
99+
}
100+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
namespace app\controller\Admin;
4+
5+
use app\model\App;
6+
use app\model\Game;
7+
use app\util\Validate;
8+
use Illuminate\Database\Eloquent\ModelNotFoundException;
9+
use support\Request;
10+
11+
class AppController
12+
{
13+
static public $rules = [
14+
'id' => 'nullable|integer',
15+
'game_id' => 'required|integer',
16+
'name' => 'required',
17+
'description' => 'nullable',
18+
'data_path' => 'required|json',
19+
'working_path' => 'required',
20+
'images' => 'required|json',
21+
'config' => 'required',
22+
'startup' => 'required',
23+
'skip_install' => 'required|boolean',
24+
'install_image' => 'required_unless:skip_install,1',
25+
'install_script' => 'required_unless:skip_install,1'
26+
];
27+
28+
public function GetList(Request $request)
29+
{
30+
return json([
31+
'code' => 200,
32+
'data' => App::select(['id', 'game_id', 'name', 'updated_at', 'created_at'])
33+
->withCount('instances')
34+
->withCount('versions')
35+
->with('game:id,name')
36+
->get()
37+
]);
38+
}
39+
40+
public function Create(Request $request)
41+
{
42+
try {
43+
$data = Validate::Input($request, self::$rules);
44+
Game::findOrFail($data['game_id']);
45+
App::create($data);
46+
47+
return json(['code' => 200]);
48+
} catch (ModelNotFoundException $e) {
49+
return json(['code' => 400, 'msg' => '游戏不存在。'])->withStatus(400);
50+
} catch (\Throwable $th) {
51+
return json(['code' => $th->getCode() ?: 500, 'msg' => $th->getMessage()])->withStatus($th->getCode() ?: 500);
52+
}
53+
}
54+
55+
public function GetDetail(Request $request, Int $appId)
56+
{
57+
try {
58+
return json([
59+
'code' => 200,
60+
'attributes' => App::findOrFail($appId)
61+
]);
62+
} catch (ModelNotFoundException $e) {
63+
return json(['code' => 400, 'msg' => '镜像不存在。'])->withStatus(400);
64+
} catch (\Throwable $th) {
65+
return json(['code' => $th->getCode() ?: 500, 'msg' => $th->getMessage()])->withStatus($th->getCode() ?: 500);
66+
}
67+
}
68+
69+
public function Update(Request $request, int $appId)
70+
{
71+
try {
72+
$data = Validate::Input($request, self::$rules);
73+
Game::findOrFail($data['game_id']);
74+
App::findOrFail($appId)->fill($data)->save();
75+
76+
return json(['code' => 200]);
77+
} catch (ModelNotFoundException $e) {
78+
return json(['code' => 400, 'msg' => '游戏或镜像不存在。'])->withStatus(400);
79+
} catch (\Throwable $th) {
80+
return json(['code' => $th->getCode() ?: 500, 'msg' => $th->getMessage()])->withStatus($th->getCode() ?: 500);
81+
}
82+
}
83+
84+
public function Delete(Request $request, int $appId)
85+
{
86+
try {
87+
$app = App::withCount(['instances'])->findOrFail($appId);
88+
if ($app->instances_count > 0) throw new \Exception('无法删除带有实例的镜像。', 400);
89+
$app->delete();
90+
91+
return json(['code' => 200]);
92+
} catch (ModelNotFoundException $e) {
93+
return json(['code' => 400, 'msg' => '镜像不存在。'])->withStatus(400);
94+
} catch (\Throwable $th) {
95+
return json(['code' => $th->getCode() ?: 500, 'msg' => $th->getMessage()])->withStatus($th->getCode() ?: 500);
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)